Loading iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.kt +16 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.launcher3.icons import android.content.Context import android.graphics.Bitmap import android.graphics.Bitmap.CompressFormat.PNG import android.graphics.BitmapFactory import android.graphics.BitmapFactory.Options import android.graphics.BlendMode import android.graphics.BlendModeColorFilter import android.graphics.Canvas Loading @@ -35,7 +37,6 @@ import android.graphics.RegionIterator import android.util.Log import androidx.annotation.ColorInt import androidx.core.graphics.ColorUtils.compositeColors import com.android.launcher3.icons.GraphicsUtils.resize import com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR import com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR import java.io.ByteArrayOutputStream Loading Loading @@ -73,6 +74,20 @@ object GraphicsUtils { } } /** Tries to decode the [ByteArray] into a [Bitmap] consuming any parsing errors */ fun ByteArray.parseBitmapSafe(config: Bitmap.Config): Bitmap? = try { BitmapFactory.decodeByteArray( /* data= */ this, /* offset= */ 0, /* length= */ size, Options().apply { inPreferredConfig = config }, ) } catch (e: Exception) { Log.e(TAG, "Error parsing persisted bitmap", e) null } /** * Try go guesstimate how much space the icon will take when serialized to avoid unnecessary * allocations/copies during the write (4 bytes per pixel). Loading iconloaderlib/src/com/android/launcher3/icons/ThemedBitmap.kt +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ interface IconThemeController { ): ThemedBitmap fun decode( data: ByteArray, bytes: ByteArray, info: BitmapInfo, factory: BaseIconFactory, sourceHint: SourceHint, Loading iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.kt +26 −39 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ import android.content.pm.LauncherApps import android.content.pm.PackageManager import android.content.pm.PackageManager.NameNotFoundException import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteException import android.database.sqlite.SQLiteReadOnlyDatabaseException import android.graphics.Bitmap import android.graphics.Bitmap.Config.HARDWARE Loading Loading @@ -93,7 +91,7 @@ constructor( @JvmField val workerHandler = Handler(bgLooper) @JvmField protected var iconDb = IconDB(context, dbFileName, iconPixelSize) @JvmField protected var iconDb = createIconDb(iconPixelSize) private var defaultIcon: BitmapInfo? = null private val userFlagOpMap = SparseArray<FlagOp>() Loading Loading @@ -133,7 +131,7 @@ constructor( userFlagOpMap.clear() iconDb.clear() iconDb.close() iconDb = IconDB(context, dbFileName, iconPixelSize) iconDb = createIconDb(iconPixelSize) cache.clear() } catch (e: SQLiteReadOnlyDatabaseException) { // This is known to happen during repeated backup and restores, if the Launcher is in Loading Loading @@ -486,28 +484,22 @@ constructor( lookupFlags: CacheLookupFlag, cachingLogic: CachingLogic<*>, ): Boolean { var c: Cursor? = null Trace.beginSection("loadIconIndividually") try { c = iconDb.query( return iconDb.querySingleEntry( lookupFlags.toLookupColumns(), "$COLUMN_COMPONENT = ? AND $COLUMN_USER = ?", arrayOf( cacheKey.componentName.flattenToString(), getSerialNumberForUser(cacheKey.user).toString(), ), ) if (c.moveToNext()) { return updateTitleAndIconLocked(cacheKey, entry, c, lookupFlags, cachingLogic) false, ) { updateTitleAndIconLocked(cacheKey, entry, it, lookupFlags, cachingLogic) } } catch (e: SQLiteException) { Log.d(TAG, "Error reading icon cache", e) } finally { c?.close() Trace.endSection() } return false } private fun updateTitleAndIconLocked( Loading Loading @@ -561,7 +553,7 @@ constructor( if (themeController != null && monoIconData != null) { entry.bitmap.themedBitmap = themeController.decode( data = monoIconData, bytes = monoIconData, info = entry.bitmap, factory = factory, sourceHint = Loading Loading @@ -614,18 +606,15 @@ constructor( Log.d(TAG, message, e) } /** Cache class to store the actual entries on disk */ class IconDB(context: Context, dbFileName: String?, iconPixelSize: Int) : /** Creates a cache class to store the actual entries on disk */ private fun createIconDb(iconPixelSize: Int) = SQLiteCacheHelper( context, dbFileName, (RELEASE_VERSION shl 16) + iconPixelSize, TABLE_NAME, ) { override fun onCreateTable(db: SQLiteDatabase) { db.execSQL( ("CREATE TABLE IF NOT EXISTS $TABLE_NAME (" + "CREATE TABLE IF NOT EXISTS $TABLE_NAME (" + "$COLUMN_COMPONENT TEXT NOT NULL, " + "$COLUMN_USER INTEGER NOT NULL, " + "$COLUMN_FRESHNESS_ID TEXT, " + Loading @@ -635,9 +624,7 @@ constructor( "$COLUMN_FLAGS INTEGER NOT NULL DEFAULT 0, " + "$COLUMN_LABEL TEXT, " + "PRIMARY KEY ($COLUMN_COMPONENT, $COLUMN_USER) " + ");") ) } ");" } companion object { Loading iconloaderlib/src/com/android/launcher3/icons/mono/MonoIconThemeController.kt +3 −3 Original line number Diff line number Diff line Loading @@ -111,16 +111,16 @@ class MonoIconThemeController( } override fun decode( data: ByteArray, bytes: ByteArray, info: BitmapInfo, factory: BaseIconFactory, sourceHint: SourceHint, ): ThemedBitmap { val icon = info.icon if (data.size != icon.height * icon.width) return ThemedBitmap.NOT_SUPPORTED if (bytes.size != icon.height * icon.width) return ThemedBitmap.NOT_SUPPORTED var monoBitmap = Bitmap.createBitmap(icon.width, icon.height, ALPHA_8) monoBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(data)) monoBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(bytes)) val hwMonoBitmap = monoBitmap.copy(HARDWARE, false /*isMutable*/) if (hwMonoBitmap != null) { Loading iconloaderlib/src/com/android/launcher3/util/NoLocaleSQLiteHelper.javadeleted 100644 → 0 +0 −58 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.util; import static android.database.sqlite.SQLiteDatabase.NO_LOCALIZED_COLLATORS; import android.content.Context; import android.content.ContextWrapper; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteDatabase.OpenParams; import android.database.sqlite.SQLiteOpenHelper; import android.os.Build; /** * Extension of {@link SQLiteOpenHelper} which avoids creating default locale table by * A context wrapper which creates databases without support for localized collators. */ public abstract class NoLocaleSQLiteHelper extends SQLiteOpenHelper { private static final boolean ATLEAST_P = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P; public NoLocaleSQLiteHelper(Context context, String name, int version) { super(ATLEAST_P ? context : new NoLocalContext(context), name, null, version); if (ATLEAST_P) { setOpenParams(new OpenParams.Builder().addOpenFlags(NO_LOCALIZED_COLLATORS).build()); } } private static class NoLocalContext extends ContextWrapper { public NoLocalContext(Context base) { super(base); } @Override public SQLiteDatabase openOrCreateDatabase( String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler) { return super.openOrCreateDatabase( name, mode | Context.MODE_NO_LOCALIZED_COLLATORS, factory, errorHandler); } } } Loading
iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.kt +16 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.launcher3.icons import android.content.Context import android.graphics.Bitmap import android.graphics.Bitmap.CompressFormat.PNG import android.graphics.BitmapFactory import android.graphics.BitmapFactory.Options import android.graphics.BlendMode import android.graphics.BlendModeColorFilter import android.graphics.Canvas Loading @@ -35,7 +37,6 @@ import android.graphics.RegionIterator import android.util.Log import androidx.annotation.ColorInt import androidx.core.graphics.ColorUtils.compositeColors import com.android.launcher3.icons.GraphicsUtils.resize import com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR import com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR import java.io.ByteArrayOutputStream Loading Loading @@ -73,6 +74,20 @@ object GraphicsUtils { } } /** Tries to decode the [ByteArray] into a [Bitmap] consuming any parsing errors */ fun ByteArray.parseBitmapSafe(config: Bitmap.Config): Bitmap? = try { BitmapFactory.decodeByteArray( /* data= */ this, /* offset= */ 0, /* length= */ size, Options().apply { inPreferredConfig = config }, ) } catch (e: Exception) { Log.e(TAG, "Error parsing persisted bitmap", e) null } /** * Try go guesstimate how much space the icon will take when serialized to avoid unnecessary * allocations/copies during the write (4 bytes per pixel). Loading
iconloaderlib/src/com/android/launcher3/icons/ThemedBitmap.kt +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ interface IconThemeController { ): ThemedBitmap fun decode( data: ByteArray, bytes: ByteArray, info: BitmapInfo, factory: BaseIconFactory, sourceHint: SourceHint, Loading
iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.kt +26 −39 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ import android.content.pm.LauncherApps import android.content.pm.PackageManager import android.content.pm.PackageManager.NameNotFoundException import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteException import android.database.sqlite.SQLiteReadOnlyDatabaseException import android.graphics.Bitmap import android.graphics.Bitmap.Config.HARDWARE Loading Loading @@ -93,7 +91,7 @@ constructor( @JvmField val workerHandler = Handler(bgLooper) @JvmField protected var iconDb = IconDB(context, dbFileName, iconPixelSize) @JvmField protected var iconDb = createIconDb(iconPixelSize) private var defaultIcon: BitmapInfo? = null private val userFlagOpMap = SparseArray<FlagOp>() Loading Loading @@ -133,7 +131,7 @@ constructor( userFlagOpMap.clear() iconDb.clear() iconDb.close() iconDb = IconDB(context, dbFileName, iconPixelSize) iconDb = createIconDb(iconPixelSize) cache.clear() } catch (e: SQLiteReadOnlyDatabaseException) { // This is known to happen during repeated backup and restores, if the Launcher is in Loading Loading @@ -486,28 +484,22 @@ constructor( lookupFlags: CacheLookupFlag, cachingLogic: CachingLogic<*>, ): Boolean { var c: Cursor? = null Trace.beginSection("loadIconIndividually") try { c = iconDb.query( return iconDb.querySingleEntry( lookupFlags.toLookupColumns(), "$COLUMN_COMPONENT = ? AND $COLUMN_USER = ?", arrayOf( cacheKey.componentName.flattenToString(), getSerialNumberForUser(cacheKey.user).toString(), ), ) if (c.moveToNext()) { return updateTitleAndIconLocked(cacheKey, entry, c, lookupFlags, cachingLogic) false, ) { updateTitleAndIconLocked(cacheKey, entry, it, lookupFlags, cachingLogic) } } catch (e: SQLiteException) { Log.d(TAG, "Error reading icon cache", e) } finally { c?.close() Trace.endSection() } return false } private fun updateTitleAndIconLocked( Loading Loading @@ -561,7 +553,7 @@ constructor( if (themeController != null && monoIconData != null) { entry.bitmap.themedBitmap = themeController.decode( data = monoIconData, bytes = monoIconData, info = entry.bitmap, factory = factory, sourceHint = Loading Loading @@ -614,18 +606,15 @@ constructor( Log.d(TAG, message, e) } /** Cache class to store the actual entries on disk */ class IconDB(context: Context, dbFileName: String?, iconPixelSize: Int) : /** Creates a cache class to store the actual entries on disk */ private fun createIconDb(iconPixelSize: Int) = SQLiteCacheHelper( context, dbFileName, (RELEASE_VERSION shl 16) + iconPixelSize, TABLE_NAME, ) { override fun onCreateTable(db: SQLiteDatabase) { db.execSQL( ("CREATE TABLE IF NOT EXISTS $TABLE_NAME (" + "CREATE TABLE IF NOT EXISTS $TABLE_NAME (" + "$COLUMN_COMPONENT TEXT NOT NULL, " + "$COLUMN_USER INTEGER NOT NULL, " + "$COLUMN_FRESHNESS_ID TEXT, " + Loading @@ -635,9 +624,7 @@ constructor( "$COLUMN_FLAGS INTEGER NOT NULL DEFAULT 0, " + "$COLUMN_LABEL TEXT, " + "PRIMARY KEY ($COLUMN_COMPONENT, $COLUMN_USER) " + ");") ) } ");" } companion object { Loading
iconloaderlib/src/com/android/launcher3/icons/mono/MonoIconThemeController.kt +3 −3 Original line number Diff line number Diff line Loading @@ -111,16 +111,16 @@ class MonoIconThemeController( } override fun decode( data: ByteArray, bytes: ByteArray, info: BitmapInfo, factory: BaseIconFactory, sourceHint: SourceHint, ): ThemedBitmap { val icon = info.icon if (data.size != icon.height * icon.width) return ThemedBitmap.NOT_SUPPORTED if (bytes.size != icon.height * icon.width) return ThemedBitmap.NOT_SUPPORTED var monoBitmap = Bitmap.createBitmap(icon.width, icon.height, ALPHA_8) monoBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(data)) monoBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(bytes)) val hwMonoBitmap = monoBitmap.copy(HARDWARE, false /*isMutable*/) if (hwMonoBitmap != null) { Loading
iconloaderlib/src/com/android/launcher3/util/NoLocaleSQLiteHelper.javadeleted 100644 → 0 +0 −58 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.util; import static android.database.sqlite.SQLiteDatabase.NO_LOCALIZED_COLLATORS; import android.content.Context; import android.content.ContextWrapper; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteDatabase.OpenParams; import android.database.sqlite.SQLiteOpenHelper; import android.os.Build; /** * Extension of {@link SQLiteOpenHelper} which avoids creating default locale table by * A context wrapper which creates databases without support for localized collators. */ public abstract class NoLocaleSQLiteHelper extends SQLiteOpenHelper { private static final boolean ATLEAST_P = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P; public NoLocaleSQLiteHelper(Context context, String name, int version) { super(ATLEAST_P ? context : new NoLocalContext(context), name, null, version); if (ATLEAST_P) { setOpenParams(new OpenParams.Builder().addOpenFlags(NO_LOCALIZED_COLLATORS).build()); } } private static class NoLocalContext extends ContextWrapper { public NoLocalContext(Context base) { super(base); } @Override public SQLiteDatabase openOrCreateDatabase( String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler) { return super.openOrCreateDatabase( name, mode | Context.MODE_NO_LOCALIZED_COLLATORS, factory, errorHandler); } } }