From 0053edf2dd96d923d8f22c003eb7be6bc03d259b Mon Sep 17 00:00:00 2001 From: davotoula Date: Sat, 11 Jul 2026 16:49:41 +0100 Subject: [PATCH] refactor: adopt androidx.core KTX helpers (Bitmap/Uri/SharedPreferences) --- .claude/CLAUDE.md | 20 +++++++++++++++++++ .../amethyst/ImageUploadTesting.kt | 3 ++- .../ThumbnailDiskCacheInstrumentedTest.kt | 3 ++- .../amethyst/napplet/NappletBrokerService.kt | 3 ++- .../amethyst/napplet/WebAppNetworkRegistry.kt | 4 ++-- .../calendar/CalendarReminderNotifier.kt | 3 ++- .../service/calendar/CalendarReminderPrefs.kt | 5 +++-- .../service/calendar/CalendarReminderStore.kt | 3 ++- .../ui/note/creators/location/MapPinIcon.kt | 3 ++- .../amethyst/ui/note/types/Ps1Save.kt | 5 ++--- .../screen/loggedIn/browser/WebAppScreen.kt | 6 +++--- .../detail/CalendarEventDetailScreen.kt | 5 +++-- .../commons/blurhash/PlatformImage.android.kt | 3 ++- .../commons/keystorage/SecureKeyStorage.kt | 5 +++-- .../nip64Chess/ChessDismissedGamesStorage.kt | 3 ++- .../napplethost/NappletBrowserActivity.kt | 12 ++++++----- .../napplethost/NappletBrowserService.kt | 3 ++- .../napplethost/NappletHostService.kt | 3 ++- 18 files changed, 63 insertions(+), 29 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 0d3293a869..7225a48c67 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -282,6 +282,26 @@ Do this before considering the task complete. - The only acceptable inline fully-qualified names are: a genuine name collision (prefer `import ... as Alias` instead), or where the language requires it. Comments, KDoc, and string literals are exempt. +- **Prefer the `androidx.core` KTX extension over the raw platform Java call** + when one exists — this is what Android Lint's `UseKtx` flags. Common swaps: + `Bitmap.createBitmap(w, h, cfg)` → `createBitmap(w, h)`, + `Bitmap.createScaledBitmap(src, w, h, f)` → `src.scale(w, h, f)`, + `Uri.parse(s)` → `s.toUri()`, and `prefs.edit()…apply()` → `prefs.edit { }`. + Only adopt the KTX form when it's behaviour-preserving: keep any explicit + argument that differs from the extension's default (a non-`ARGB_8888` + `Bitmap.Config`, `scale(filter = false)`), and leave calls the KTX has no + equivalent for (e.g. the `createBitmap` pixels/matrix overloads, or a + conditional-`apply()` editor loop) untouched. +- **This "prefer the KTX sugar" rule does NOT extend to collection operators.** + The KTX preference is about platform wrappers (`Bitmap`/`Uri`/`SharedPreferences`), + which compile to the identical call. Collections are the opposite: in hot + event/parse paths Quartz deliberately uses raw JVM arrays (`TagArray = + Array>`) and the inline `fast*` operators (`fastForEach`, + `fastAny`, `fastFirstOrNull`, `fastFirstNotNullOfOrNull`, … in + `nip01Core/core/TagArray.kt`) instead of Kotlin `List` + stdlib + `forEach`/`map`/`filter`/`any` — the `fast*` variants allocate no iterator, + no intermediate list, and no lambda object. Don't "modernize" those into + stdlib collection calls; match the surrounding hot-path style. ### Navigation Shell - **Desktop**: Sidebar + main content area diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt index a5f447e654..84ebadec75 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst import android.graphics.Bitmap import android.graphics.Color +import androidx.core.graphics.createBitmap import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.vitorpamplona.amethyst.model.AccountSettings @@ -81,7 +82,7 @@ class ImageUploadTesting { .build() private fun getBitmap(): ByteArray { - val bitmap = Bitmap.createBitmap(200, 300, Bitmap.Config.ARGB_8888) + val bitmap = createBitmap(200, 300) for (x in 0 until bitmap.width) { for (y in 0 until bitmap.height) { bitmap.setPixel(x, y, Color.rgb(Random.nextInt(), Random.nextInt(), Random.nextInt())) diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/service/images/ThumbnailDiskCacheInstrumentedTest.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/service/images/ThumbnailDiskCacheInstrumentedTest.kt index 04f5e861e6..8e5c047041 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/service/images/ThumbnailDiskCacheInstrumentedTest.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/service/images/ThumbnailDiskCacheInstrumentedTest.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.service.images import android.graphics.Bitmap +import androidx.core.graphics.createBitmap import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import org.junit.After @@ -44,7 +45,7 @@ class ThumbnailDiskCacheInstrumentedTest { cacheDir = File(appContext.cacheDir, "thumbnail-test-${UUID.randomUUID()}") cache = ThumbnailDiskCache(cacheDir) sourceFile = File(appContext.cacheDir, "source-${UUID.randomUUID()}.jpg") - val bitmap = Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_8888) + val bitmap = createBitmap(64, 64) sourceFile.outputStream().use { bitmap.compress(Bitmap.CompressFormat.JPEG, 90, it) } bitmap.recycle() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletBrokerService.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletBrokerService.kt index 59f276401d..c08d211060 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletBrokerService.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletBrokerService.kt @@ -32,6 +32,7 @@ import android.os.Messenger import android.os.RemoteException import android.os.SystemClock import android.util.Log +import androidx.core.net.toUri import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.commons.favorites.FavoriteApp import com.vitorpamplona.amethyst.commons.napplet.NappletBroker @@ -359,7 +360,7 @@ class NappletBrokerService : Service() { val intent = Intent(applicationContext, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - data = Uri.parse("nostr:connectedapp?coordinate=" + Uri.encode(coordinate)) + data = ("nostr:connectedapp?coordinate=" + Uri.encode(coordinate)).toUri() } runCatching { applicationContext.startActivity(intent) } .onFailure { Log.w("NappletBrokerService", "Could not open Connected Apps detail", it) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/WebAppNetworkRegistry.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/WebAppNetworkRegistry.kt index 185b780e99..2038417d1a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/WebAppNetworkRegistry.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/WebAppNetworkRegistry.kt @@ -21,7 +21,7 @@ package com.vitorpamplona.amethyst.napplet import android.content.Context -import android.net.Uri +import androidx.core.net.toUri import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore @@ -86,7 +86,7 @@ object WebAppNetworkRegistry { } /** The host key for [url] (e.g. `vitorpamplona.com`), or the raw string if it has no host. */ - fun hostKeyOf(url: String): String = runCatching { Uri.parse(url).host }.getOrNull()?.takeIf { it.isNotBlank() } ?: url + fun hostKeyOf(url: String): String = runCatching { url.toUri().host }.getOrNull()?.takeIf { it.isNotBlank() } ?: url /** Whether the site behind [url] routes through Tor. Defaults to true (Tor) for any site never set. */ fun useTor(url: String): Boolean = modes[hostKeyOf(url)] ?: true diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderNotifier.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderNotifier.kt index c496d512bd..5cc2d5a8fd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderNotifier.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderNotifier.kt @@ -27,6 +27,7 @@ import android.content.Context import android.content.Intent import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat +import androidx.core.net.toUri import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.MainActivity import com.vitorpamplona.amethyst.ui.stringRes @@ -64,7 +65,7 @@ object CalendarReminderNotifier { val tapIntent = Intent(context, MainActivity::class.java).apply { action = Intent.ACTION_VIEW - data = android.net.Uri.parse(deepLink) + data = deepLink.toUri() addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP) } val tapPendingIntent = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderPrefs.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderPrefs.kt index f3dda3056f..737cffdadb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderPrefs.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderPrefs.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.service.calendar import android.content.Context import android.content.SharedPreferences +import androidx.core.content.edit /** * Device-wide preferences for the calendar reminder worker. @@ -40,13 +41,13 @@ class CalendarReminderPrefs( fun isEnabled(): Boolean = prefs.getBoolean(KEY_ENABLED, DEFAULT_ENABLED) fun setEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_ENABLED, enabled).apply() + prefs.edit { putBoolean(KEY_ENABLED, enabled) } } fun leadMinutes(): Int = prefs.getInt(KEY_LEAD_MINUTES, DEFAULT_LEAD_MINUTES) fun setLeadMinutes(minutes: Int) { - prefs.edit().putInt(KEY_LEAD_MINUTES, minutes).apply() + prefs.edit { putInt(KEY_LEAD_MINUTES, minutes) } } companion object { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderStore.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderStore.kt index eb78d56322..81c3ad882f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderStore.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/calendar/CalendarReminderStore.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.service.calendar import android.content.Context import android.content.SharedPreferences +import androidx.core.content.edit /** * Persistent "I've already notified for this event" set. Backed by [SharedPreferences] because @@ -54,7 +55,7 @@ class CalendarReminderStore( eventId: String, eventStartSeconds: Long, ) { - prefs.edit().putLong(keyFor(eventId), eventStartSeconds).apply() + prefs.edit { putLong(keyFor(eventId), eventStartSeconds) } } /** diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/MapPinIcon.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/MapPinIcon.kt index 8e9f422ccc..ba370ddfba 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/MapPinIcon.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/MapPinIcon.kt @@ -25,6 +25,7 @@ import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path +import androidx.core.graphics.createBitmap import kotlin.math.roundToInt /** @@ -57,7 +58,7 @@ fun roadEventPinBitmap( val cx = width / 2f val cy = pad + radius - val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + val bitmap = createBitmap(width, height) val canvas = Canvas(bitmap) // Head circle + pointer drawn as a single path so they share one shadow diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Ps1Save.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Ps1Save.kt index 639c26947c..54d4a4ab25 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Ps1Save.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Ps1Save.kt @@ -20,7 +20,6 @@ */ package com.vitorpamplona.amethyst.ui.note.types -import android.graphics.Bitmap import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -46,6 +45,7 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.core.graphics.createBitmap import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.stringRes @@ -160,8 +160,7 @@ private fun Ps1SaveIconImage(icon: Ps1SaveIcon) { val frames = remember(icon) { icon.frames.map { pixels -> - Bitmap - .createBitmap(Ps1SaveIcon.SIZE, Ps1SaveIcon.SIZE, Bitmap.Config.ARGB_8888) + createBitmap(Ps1SaveIcon.SIZE, Ps1SaveIcon.SIZE) .apply { setPixels(pixels, 0, Ps1SaveIcon.SIZE, 0, 0, Ps1SaveIcon.SIZE, Ps1SaveIcon.SIZE) } .asImageBitmap() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/WebAppScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/WebAppScreen.kt index 9b903b4b33..8265fa2eff 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/WebAppScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/WebAppScreen.kt @@ -20,7 +20,6 @@ */ package com.vitorpamplona.amethyst.ui.screen.loggedIn.browser -import android.net.Uri import android.os.Build import androidx.activity.compose.BackHandler import androidx.annotation.RequiresApi @@ -44,6 +43,7 @@ import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.core.net.toUri import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R @@ -193,14 +193,14 @@ private fun EmbeddedWebAppTab( } /** The host of [url] for the tab title, falling back to the raw string. */ -internal fun hostLabel(url: String): String = runCatching { Uri.parse(url).host }.getOrNull()?.takeIf { it.isNotBlank() } ?: url +internal fun hostLabel(url: String): String = runCatching { url.toUri().host }.getOrNull()?.takeIf { it.isNotBlank() } ?: url /** * The `scheme://host[:port]` origin of [url] — the exact form the sandbox reports for NIP-07 consent, so * it matches the `browser:` permission-ledger key. Null when [url] has no usable scheme/host. */ internal fun browserOrigin(url: String): String? { - val uri = runCatching { Uri.parse(url) }.getOrNull() ?: return null + val uri = runCatching { url.toUri() }.getOrNull() ?: return null val scheme = uri.scheme?.takeIf { it.isNotBlank() } ?: return null val host = uri.host?.takeIf { it.isNotBlank() } ?: return null return "$scheme://$host" + if (uri.port > 0) ":${uri.port}" else "" diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt index e25c76a2be..ad89bdc42b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt @@ -59,6 +59,7 @@ import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.core.net.toUri import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols @@ -582,11 +583,11 @@ private fun LocationRow(location: String) { val trimmed = location.trim() val intent = if (isUrl) { - Intent(Intent.ACTION_VIEW, Uri.parse(trimmed)) + Intent(Intent.ACTION_VIEW, trimmed.toUri()) } else { // `geo:0,0?q=` is the Android geo intent; the user's // installed maps app handles it. - Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=${Uri.encode(trimmed)}")) + Intent(Intent.ACTION_VIEW, "geo:0,0?q=${Uri.encode(trimmed)}".toUri()) } // runCatching swallows ActivityNotFoundException when no handler is // installed — we don't have anywhere useful to fall back to. diff --git a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/blurhash/PlatformImage.android.kt b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/blurhash/PlatformImage.android.kt index 3c494a6904..b8075bca4e 100644 --- a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/blurhash/PlatformImage.android.kt +++ b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/blurhash/PlatformImage.android.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.commons.blurhash import android.graphics.Bitmap +import androidx.core.graphics.scale actual class PlatformImage( val bitmap: Bitmap, @@ -43,7 +44,7 @@ actual class PlatformImage( actual fun scale( width: Int, height: Int, - ): PlatformImage = PlatformImage(Bitmap.createScaledBitmap(bitmap, width, height, false)) + ): PlatformImage = PlatformImage(bitmap.scale(width, height, false)) actual companion object { actual fun create( diff --git a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt index 953525260e..bc603dacb0 100644 --- a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt +++ b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.commons.keystorage import android.content.Context +import androidx.core.content.edit import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKey import kotlinx.coroutines.Dispatchers @@ -86,7 +87,7 @@ actual class SecureKeyStorage private actual constructor() { ) { withContext(Dispatchers.IO) { try { - encryptedPrefs.edit().putString(KEY_PREFIX + npub, privKeyHex).apply() + encryptedPrefs.edit { putString(KEY_PREFIX + npub, privKeyHex) } } catch (e: Exception) { throw SecureStorageException("Failed to save private key", e) } @@ -108,7 +109,7 @@ actual class SecureKeyStorage private actual constructor() { val key = KEY_PREFIX + npub val existed = encryptedPrefs.contains(key) if (existed) { - encryptedPrefs.edit().remove(key).apply() + encryptedPrefs.edit { remove(key) } } existed } catch (e: Exception) { diff --git a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessDismissedGamesStorage.kt b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessDismissedGamesStorage.kt index cba028d6a1..53e63f7e8e 100644 --- a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessDismissedGamesStorage.kt +++ b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/nip64Chess/ChessDismissedGamesStorage.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.commons.nip64Chess import android.content.Context import android.content.SharedPreferences +import androidx.core.content.edit actual class ChessDismissedGamesStorage private actual constructor() { private var prefs: SharedPreferences? = null @@ -48,6 +49,6 @@ actual class ChessDismissedGamesStorage private actual constructor() { userPubkey: String, ids: Set, ) { - prefs?.edit()?.putStringSet(prefsKey(userPubkey), ids)?.apply() + prefs?.edit { putStringSet(prefsKey(userPubkey), ids) } } } diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt index 9088b7f8b7..d7deb5b6f3 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt @@ -54,6 +54,8 @@ import androidx.activity.ComponentActivity import androidx.activity.OnBackPressedCallback import androidx.core.content.ContextCompat import androidx.core.graphics.Insets +import androidx.core.graphics.scale +import androidx.core.net.toUri import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.webkit.JavaScriptReplyProxy @@ -456,7 +458,7 @@ class NappletBrowserActivity : ComponentActivity() { runCatching { val scaled = if (icon.width > ICON_MAX_PX || icon.height > ICON_MAX_PX) { - Bitmap.createScaledBitmap(icon, ICON_MAX_PX, ICON_MAX_PX, true) + icon.scale(ICON_MAX_PX, ICON_MAX_PX) } else { icon } @@ -597,7 +599,7 @@ class NappletBrowserActivity : ComponentActivity() { // Key the persisted choice on the host actually displayed (which may differ from startUrl after // in-page navigation), so the preference sticks to the right site. val liveUrl = if (this::webView.isInitialized) webView.url ?: startUrl else startUrl - val host = runCatching { Uri.parse(liveUrl).host }.getOrNull()?.takeIf { it.isNotBlank() } ?: return + val host = runCatching { liveUrl.toUri().host }.getOrNull()?.takeIf { it.isNotBlank() } ?: return val msg = Message.obtain(null, NappletIpc.MSG_SET_WEB_TOR).apply { data = @@ -613,7 +615,7 @@ class NappletBrowserActivity : ComponentActivity() { private var title: String = "" - private fun barTitle(): String = title.ifBlank { runCatching { Uri.parse(startUrl).host }.getOrNull() ?: getString(CommonsR.string.napplet_untitled) } + private fun barTitle(): String = title.ifBlank { runCatching { startUrl.toUri().host }.getOrNull() ?: getString(CommonsR.string.napplet_untitled) } /** * The top pull-down sheet: a small grabber at the top edge (out of the corner where a site shows its @@ -644,7 +646,7 @@ class NappletBrowserActivity : ComponentActivity() { */ private fun openPermissions() { val liveUrl = if (this::webView.isInitialized) webView.url ?: startUrl else startUrl - val uri = runCatching { Uri.parse(liveUrl) }.getOrNull() ?: return + val uri = runCatching { liveUrl.toUri() }.getOrNull() ?: return val scheme = uri.scheme?.takeIf { it.isNotBlank() } ?: return val host = uri.host?.takeIf { it.isNotBlank() } ?: return val origin = "$scheme://$host" + if (uri.port > 0) ":${uri.port}" else "" @@ -774,6 +776,6 @@ class NappletBrowserActivity : ComponentActivity() { .putExtra(EXTRA_THEME, theme) .putExtra(EXTRA_IS_FAVORITE, isFavorite) // Distinct task identity per URL for documentLaunchMode=intoExisting. - .setData(Uri.parse(url)) + .setData(url.toUri()) } } diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt index 43556385a0..9208f9d275 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt @@ -45,6 +45,7 @@ import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient import androidx.annotation.RequiresApi +import androidx.core.graphics.createBitmap import androidx.privacysandbox.ui.provider.toCoreLibInfo import androidx.webkit.JavaScriptReplyProxy import androidx.webkit.WebMessageCompat @@ -206,7 +207,7 @@ class NappletBrowserService : Service() { val outW = (boxW * zoom).toInt().coerceAtLeast(1) val outH = (boxH * zoom).toInt().coerceAtLeast(1) val t0 = SystemClock.elapsedRealtimeNanos() - val bitmap = Bitmap.createBitmap(outW, outH, Bitmap.Config.ARGB_8888) + val bitmap = createBitmap(outW, outH) val canvas = Canvas(bitmap) canvas.drawColor(tab.bgColor) // Map the source rect (centered on cx,cy in view px) into the zoomed output bitmap. diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt index b2fe56b483..d038a40ec2 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt @@ -45,6 +45,7 @@ import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient import androidx.annotation.RequiresApi +import androidx.core.graphics.createBitmap import androidx.privacysandbox.ui.provider.toCoreLibInfo import androidx.webkit.JavaScriptReplyProxy import androidx.webkit.ProxyConfig @@ -238,7 +239,7 @@ class NappletHostService : Service() { val outW = (boxW * zoom).toInt().coerceAtLeast(1) val outH = (boxH * zoom).toInt().coerceAtLeast(1) val t0 = SystemClock.elapsedRealtimeNanos() - val bitmap = Bitmap.createBitmap(outW, outH, Bitmap.Config.ARGB_8888) + val bitmap = createBitmap(outW, outH) val canvas = Canvas(bitmap) canvas.drawColor(tab.bgColor) canvas.scale(zoom, zoom)