diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-08 16:02:14 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-08 16:02:14 +0000 |
commit | 8e11a158cfd16b18ade99110a89a9e5b46762b19 (patch) | |
tree | e21a512fee75b098efbdf4324d7fbf9e6caa7ed3 | |
parent | 2af3c27486c7d916b23e713146d0145e78a26fac (diff) | |
parent | 6cb0317b2178f30b809ed24026f55ef9a2a36224 (diff) | |
download | systemui-android12-mainline-tzdata2-release.tar.gz |
Snap for 8426163 from 6cb0317b2178f30b809ed24026f55ef9a2a36224 to mainline-tzdata2-releaseandroid-mainline-12.0.0_r112aml_tz2_305400500aml_tz2_305400300aml_tz2_305400100aml_tz2_304500300aml_tz2_303900110aml_tz2_303900102aml_tz2_303800002aml_tz2_303800001aml_tz2_303200001android12-mainline-tzdata2-releaseaml_tz2_305400100
Change-Id: Ie038c554854ac1bf6b7b44c56838140b9f869dd6
24 files changed, 93 insertions, 2113 deletions
diff --git a/iconloaderlib/Android.bp b/iconloaderlib/Android.bp index 6867e6b..f12d16e 100644 --- a/iconloaderlib/Android.bp +++ b/iconloaderlib/Android.bp @@ -12,14 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - android_library { name: "iconloader_base", - sdk_version: "current", - min_sdk_version: "26", + sdk_version: "28", + min_sdk_version: "21", static_libs: [ "androidx.core_core", ], @@ -34,7 +30,7 @@ android_library { android_library { name: "iconloader", sdk_version: "system_current", - min_sdk_version: "26", + min_sdk_version: "21", static_libs: [ "androidx.core_core", ], diff --git a/iconloaderlib/build.gradle b/iconloaderlib/build.gradle index 8410275..d7a62e1 100644 --- a/iconloaderlib/build.gradle +++ b/iconloaderlib/build.gradle @@ -5,7 +5,7 @@ android { buildToolsVersion BUILD_TOOLS_VERSION defaultConfig { - minSdkVersion 26 + minSdkVersion 25 targetSdkVersion 28 versionCode 1 versionName "1.0" diff --git a/iconloaderlib/res/values/attrs.xml b/iconloaderlib/res/values/attrs.xml deleted file mode 100644 index 8f0bd2c..0000000 --- a/iconloaderlib/res/values/attrs.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2021, 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. -*/ ---> -<resources> - <attr name="disabledIconAlpha" format="float" /> - <attr name="loadingIconColor" format="color" /> - -</resources>
\ No newline at end of file diff --git a/iconloaderlib/res/values/colors.xml b/iconloaderlib/res/values/colors.xml index 70582c2..873b2fc 100644 --- a/iconloaderlib/res/values/colors.xml +++ b/iconloaderlib/res/values/colors.xml @@ -18,7 +18,4 @@ --> <resources> <color name="legacy_icon_background">#FFFFFF</color> - - <!-- Yellow 600, used for highlighting "important" conversations in settings & notifications --> - <color name="important_conversation">#f9ab00</color> </resources> diff --git a/iconloaderlib/res/values/config.xml b/iconloaderlib/res/values/config.xml index 893f955..68c2d2e 100644 --- a/iconloaderlib/res/values/config.xml +++ b/iconloaderlib/res/values/config.xml @@ -24,7 +24,4 @@ <bool name="simple_cache_enable_im_memory">false</bool> <string name="cache_db_name" translatable="false">app_icons.db</string> - <string name="calendar_component_name" translatable="false"></string> - <string name="clock_component_name" translatable="false"></string> - </resources>
\ No newline at end of file diff --git a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java index 9ce9975..31a923e 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java @@ -12,7 +12,6 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Rect; import android.graphics.RectF; @@ -20,15 +19,12 @@ import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.graphics.drawable.InsetDrawable; import android.os.Build; import android.os.Process; import android.os.UserHandle; import androidx.annotation.NonNull; -import com.android.launcher3.icons.BitmapInfo.Extender; - /** * This class will be moved to androidx library. There shouldn't be any dependency outside * this package. @@ -59,11 +55,6 @@ public class BaseIconFactory implements AutoCloseable { private Drawable mWrapperIcon; private int mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND; - private Bitmap mUserBadgeBitmap; - - private final Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); - private static final float PLACEHOLDER_TEXT_SIZE = 20f; - private static int PLACEHOLDER_BACKGROUND_COLOR = Color.rgb(240, 240, 240); protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize, boolean shapeDetection) { @@ -77,14 +68,10 @@ public class BaseIconFactory implements AutoCloseable { mCanvas = new Canvas(); mCanvas.setDrawFilter(new PaintFlagsDrawFilter(DITHER_FLAG, FILTER_BITMAP_FLAG)); - mTextPaint.setTextAlign(Paint.Align.CENTER); - mTextPaint.setColor(PLACEHOLDER_BACKGROUND_COLOR); - mTextPaint.setTextSize(context.getResources().getDisplayMetrics().density * - PLACEHOLDER_TEXT_SIZE); clear(); } - public BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { + protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { this(context, fillResIconDpi, iconBitmapSize, false); } @@ -126,28 +113,6 @@ public class BaseIconFactory implements AutoCloseable { return null; } - /** - * Create a placeholder icon using the passed in text. - * - * @param placeholder used for foreground element in the icon bitmap - * @param color used for the foreground text color - * @return - */ - public BitmapInfo createIconBitmap(String placeholder, int color) { - if (!ATLEAST_OREO) return null; - - Bitmap placeholderBitmap = Bitmap.createBitmap(mIconBitmapSize, mIconBitmapSize, - Bitmap.Config.ARGB_8888); - mTextPaint.setColor(color); - Canvas canvas = new Canvas(placeholderBitmap); - canvas.drawText(placeholder, mIconBitmapSize / 2, mIconBitmapSize * 5 / 8, mTextPaint); - AdaptiveIconDrawable drawable = new AdaptiveIconDrawable( - new ColorDrawable(PLACEHOLDER_BACKGROUND_COLOR), - new BitmapDrawable(mContext.getResources(), placeholderBitmap)); - Bitmap icon = createIconBitmap(drawable, 1f); - return BitmapInfo.of(icon, extractColor(icon)); - } - public BitmapInfo createIconBitmap(Bitmap icon) { if (mIconBitmapSize != icon.getWidth() || mIconBitmapSize != icon.getHeight()) { icon = createIconBitmap(new BitmapDrawable(mContext.getResources(), icon), 1f); @@ -156,20 +121,6 @@ public class BaseIconFactory implements AutoCloseable { return BitmapInfo.of(icon, extractColor(icon)); } - /** - * Creates an icon from the bitmap cropped to the current device icon shape - */ - public BitmapInfo createShapedIconBitmap(Bitmap icon, UserHandle user) { - Drawable d = new FixedSizeBitmapDrawable(icon); - if (ATLEAST_OREO) { - float inset = AdaptiveIconDrawable.getExtraInsetFraction(); - inset = inset / (1 + 2 * inset); - d = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), - new InsetDrawable(d, inset, inset, inset, inset)); - } - return createBadgedIconBitmap(d, user, true); - } - public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user, boolean shrinkNonAdaptiveIcons) { return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, false, null); @@ -236,27 +187,10 @@ public class BaseIconFactory implements AutoCloseable { } int color = extractColor(bitmap); return icon instanceof BitmapInfo.Extender - ? ((BitmapInfo.Extender) icon).getExtendedInfo(bitmap, color, this, scale[0], user) + ? ((BitmapInfo.Extender) icon).getExtendedInfo(bitmap, color, this) : BitmapInfo.of(bitmap, color); } - public Bitmap getUserBadgeBitmap(UserHandle user) { - if (mUserBadgeBitmap == null) { - Bitmap bitmap = Bitmap.createBitmap( - mIconBitmapSize, mIconBitmapSize, Bitmap.Config.ARGB_8888); - Drawable badgedDrawable = mPm.getUserBadgedIcon( - new FixedSizeBitmapDrawable(bitmap), user); - if (badgedDrawable instanceof BitmapDrawable) { - mUserBadgeBitmap = ((BitmapDrawable) badgedDrawable).getBitmap(); - } else { - badgedDrawable.setBounds(0, 0, mIconBitmapSize, mIconBitmapSize); - mUserBadgeBitmap = BitmapRenderer.createSoftwareBitmap( - mIconBitmapSize, mIconBitmapSize, badgedDrawable::draw); - } - } - return mUserBadgeBitmap; - } - public Bitmap createScaledBitmapWithoutShadow(Drawable icon, boolean shrinkNonAdaptiveIcons) { RectF iconBounds = new RectF(); float[] scale = new float[1]; @@ -362,11 +296,7 @@ public class BaseIconFactory implements AutoCloseable { int offset = Math.max((int) Math.ceil(BLUR_FACTOR * size), Math.round(size * (1 - scale) / 2 )); icon.setBounds(offset, offset, size - offset, size - offset); - if (icon instanceof BitmapInfo.Extender) { - ((Extender) icon).drawForPersistence(mCanvas); - } else { - icon.draw(mCanvas); - } + icon.draw(mCanvas); } else { if (icon instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; diff --git a/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java b/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java index 06b39b8..d33f9b1 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +++ b/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java @@ -15,37 +15,16 @@ */ package com.android.launcher3.icons; -import static com.android.launcher3.icons.GraphicsUtils.getExpectedBitmapSize; - -import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.UserHandle; -import android.util.Log; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.android.launcher3.icons.ThemedIconDrawable.ThemedBitmapInfo; -import com.android.launcher3.icons.cache.BaseIconCache; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; public class BitmapInfo { public static final Bitmap LOW_RES_ICON = Bitmap.createBitmap(1, 1, Config.ALPHA_8); public static final BitmapInfo LOW_RES_INFO = fromBitmap(LOW_RES_ICON); - public static final String TAG = "BitmapInfo"; - - protected static final byte TYPE_DEFAULT = 1; - protected static final byte TYPE_THEMED = 2; - public final Bitmap icon; public final int color; @@ -65,72 +44,6 @@ public class BitmapInfo { return LOW_RES_ICON == icon; } - /** - * Returns a serialized version of BitmapInfo - */ - @Nullable - public byte[] toByteArray() { - if (isNullOrLowRes()) { - return null; - } - ByteArrayOutputStream out = new ByteArrayOutputStream(getExpectedBitmapSize(icon) + 1); - try { - out.write(TYPE_DEFAULT); - icon.compress(Bitmap.CompressFormat.PNG, 100, out); - out.flush(); - out.close(); - return out.toByteArray(); - } catch (IOException e) { - Log.w(TAG, "Could not write bitmap"); - return null; - } - } - - /** - * Returns a new icon based on the theme of the context - */ - public FastBitmapDrawable newThemedIcon(Context context) { - return newIcon(context); - } - - /** - * Creates a drawable for the provided BitmapInfo - */ - public FastBitmapDrawable newIcon(Context context) { - FastBitmapDrawable drawable = isLowRes() - ? new PlaceHolderIconDrawable(this, context) - : new FastBitmapDrawable(this); - drawable.mDisabledAlpha = GraphicsUtils.getFloat(context, R.attr.disabledIconAlpha, 1f); - return drawable; - } - - /** - * Returns a BitmapInfo previously serialized using {@link #toByteArray()}; - */ - @NonNull - public static BitmapInfo fromByteArray(byte[] data, int color, UserHandle user, - BaseIconCache iconCache, Context context) { - if (data == null) { - return null; - } - BitmapFactory.Options decodeOptions; - if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - decodeOptions = new BitmapFactory.Options(); - decodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE; - } else { - decodeOptions = null; - } - if (data[0] == TYPE_DEFAULT) { - return BitmapInfo.of( - BitmapFactory.decodeByteArray(data, 1, data.length - 1, decodeOptions), - color); - } else if (data[0] == TYPE_THEMED) { - return ThemedBitmapInfo.decode(data, color, decodeOptions, user, iconCache, context); - } else { - return null; - } - } - public static BitmapInfo fromBitmap(@NonNull Bitmap bitmap) { return of(bitmap, 0); } @@ -147,17 +60,13 @@ public class BitmapInfo { /** * Called for creating a custom BitmapInfo */ - BitmapInfo getExtendedInfo(Bitmap bitmap, int color, - BaseIconFactory iconFactory, float normalizationScale, UserHandle user); - - /** - * Called to draw the UI independent of any runtime configurations like time or theme - */ - void drawForPersistence(Canvas canvas); + default BitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory) { + return BitmapInfo.of(bitmap, color); + } /** - * Returns a new icon with theme applied + * Notifies the drawable that it will be drawn directly in the UI, without any preprocessing */ - Drawable getThemedDrawable(Context context); + default void prepareToDrawOnUi() { } } } diff --git a/iconloaderlib/src/com/android/launcher3/icons/ClockDrawableWrapper.java b/iconloaderlib/src/com/android/launcher3/icons/ClockDrawableWrapper.java deleted file mode 100644 index a7894c9..0000000 --- a/iconloaderlib/src/com/android/launcher3/icons/ClockDrawableWrapper.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (C) 2019 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.icons; - -import static com.android.launcher3.icons.ThemedIconDrawable.getColors; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuff.Mode; -import android.graphics.PorterDuffColorFilter; -import android.graphics.Rect; -import android.graphics.drawable.AdaptiveIconDrawable; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; -import android.os.Build; -import android.os.Bundle; -import android.os.Process; -import android.os.SystemClock; -import android.os.UserHandle; -import android.util.Log; -import android.util.TypedValue; - -import androidx.annotation.Nullable; - -import com.android.launcher3.icons.ThemedIconDrawable.ThemeData; - -import java.util.Calendar; -import java.util.concurrent.TimeUnit; -import java.util.function.IntFunction; - -/** - * Wrapper over {@link AdaptiveIconDrawable} to intercept icon flattening logic for dynamic - * clock icons - */ -@TargetApi(Build.VERSION_CODES.O) -public class ClockDrawableWrapper extends AdaptiveIconDrawable implements BitmapInfo.Extender { - - private static final String TAG = "ClockDrawableWrapper"; - - private static final boolean DISABLE_SECONDS = true; - - // Time after which the clock icon should check for an update. The actual invalidate - // will only happen in case of any change. - public static final long TICK_MS = DISABLE_SECONDS ? TimeUnit.MINUTES.toMillis(1) : 200L; - - private static final String LAUNCHER_PACKAGE = "com.android.launcher3"; - private static final String ROUND_ICON_METADATA_KEY = LAUNCHER_PACKAGE - + ".LEVEL_PER_TICK_ICON_ROUND"; - private static final String HOUR_INDEX_METADATA_KEY = LAUNCHER_PACKAGE + ".HOUR_LAYER_INDEX"; - private static final String MINUTE_INDEX_METADATA_KEY = LAUNCHER_PACKAGE - + ".MINUTE_LAYER_INDEX"; - private static final String SECOND_INDEX_METADATA_KEY = LAUNCHER_PACKAGE - + ".SECOND_LAYER_INDEX"; - private static final String DEFAULT_HOUR_METADATA_KEY = LAUNCHER_PACKAGE - + ".DEFAULT_HOUR"; - private static final String DEFAULT_MINUTE_METADATA_KEY = LAUNCHER_PACKAGE - + ".DEFAULT_MINUTE"; - private static final String DEFAULT_SECOND_METADATA_KEY = LAUNCHER_PACKAGE - + ".DEFAULT_SECOND"; - - /* Number of levels to jump per second for the second hand */ - private static final int LEVELS_PER_SECOND = 10; - - public static final int INVALID_VALUE = -1; - - private final AnimationInfo mAnimationInfo = new AnimationInfo(); - private int mTargetSdkVersion; - protected ThemeData mThemeData; - - public ClockDrawableWrapper(AdaptiveIconDrawable base) { - super(base.getBackground(), base.getForeground()); - } - - /** - * Loads and returns the wrapper from the provided package, or returns null - * if it is unable to load. - */ - public static ClockDrawableWrapper forPackage(Context context, String pkg, int iconDpi) { - try { - PackageManager pm = context.getPackageManager(); - ApplicationInfo appInfo = pm.getApplicationInfo(pkg, - PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA); - Resources res = pm.getResourcesForApplication(appInfo); - return forExtras(appInfo, appInfo.metaData, - resId -> res.getDrawableForDensity(resId, iconDpi)); - } catch (Exception e) { - Log.d(TAG, "Unable to load clock drawable info", e); - } - return null; - } - - private static ClockDrawableWrapper fromThemeData(Context context, ThemeData themeData) { - try { - TypedArray ta = themeData.mResources.obtainTypedArray(themeData.mResID); - int count = ta.length(); - Bundle extras = new Bundle(); - for (int i = 0; i < count; i += 2) { - TypedValue v = ta.peekValue(i + 1); - extras.putInt(ta.getString(i), v.type >= TypedValue.TYPE_FIRST_INT - && v.type <= TypedValue.TYPE_LAST_INT - ? v.data : v.resourceId); - } - ta.recycle(); - ClockDrawableWrapper drawable = ClockDrawableWrapper.forExtras( - context.getApplicationInfo(), extras, resId -> { - int[] colors = getColors(context); - Drawable bg = new ColorDrawable(colors[0]); - Drawable fg = themeData.mResources.getDrawable(resId).mutate(); - fg.setTint(colors[1]); - return new AdaptiveIconDrawable(bg, fg); - }); - if (drawable != null) { - return drawable; - } - } catch (Exception e) { - Log.e(TAG, "Error loading themed clock", e); - } - return null; - } - - private static ClockDrawableWrapper forExtras(ApplicationInfo appInfo, Bundle metadata, - IntFunction<Drawable> drawableProvider) { - if (metadata == null) { - return null; - } - int drawableId = metadata.getInt(ROUND_ICON_METADATA_KEY, 0); - if (drawableId == 0) { - return null; - } - - Drawable drawable = drawableProvider.apply(drawableId).mutate(); - if (!(drawable instanceof AdaptiveIconDrawable)) { - return null; - } - - ClockDrawableWrapper wrapper = - new ClockDrawableWrapper((AdaptiveIconDrawable) drawable); - wrapper.mTargetSdkVersion = appInfo.targetSdkVersion; - AnimationInfo info = wrapper.mAnimationInfo; - - info.baseDrawableState = drawable.getConstantState(); - - info.hourLayerIndex = metadata.getInt(HOUR_INDEX_METADATA_KEY, INVALID_VALUE); - info.minuteLayerIndex = metadata.getInt(MINUTE_INDEX_METADATA_KEY, INVALID_VALUE); - info.secondLayerIndex = metadata.getInt(SECOND_INDEX_METADATA_KEY, INVALID_VALUE); - - info.defaultHour = metadata.getInt(DEFAULT_HOUR_METADATA_KEY, 0); - info.defaultMinute = metadata.getInt(DEFAULT_MINUTE_METADATA_KEY, 0); - info.defaultSecond = metadata.getInt(DEFAULT_SECOND_METADATA_KEY, 0); - - LayerDrawable foreground = (LayerDrawable) wrapper.getForeground(); - int layerCount = foreground.getNumberOfLayers(); - if (info.hourLayerIndex < 0 || info.hourLayerIndex >= layerCount) { - info.hourLayerIndex = INVALID_VALUE; - } - if (info.minuteLayerIndex < 0 || info.minuteLayerIndex >= layerCount) { - info.minuteLayerIndex = INVALID_VALUE; - } - if (info.secondLayerIndex < 0 || info.secondLayerIndex >= layerCount) { - info.secondLayerIndex = INVALID_VALUE; - } else if (DISABLE_SECONDS) { - foreground.setDrawable(info.secondLayerIndex, null); - info.secondLayerIndex = INVALID_VALUE; - } - info.applyTime(Calendar.getInstance(), foreground); - return wrapper; - } - - @Override - public ClockBitmapInfo getExtendedInfo(Bitmap bitmap, int color, - BaseIconFactory iconFactory, float normalizationScale, UserHandle user) { - iconFactory.disableColorExtraction(); - AdaptiveIconDrawable background = new AdaptiveIconDrawable( - getBackground().getConstantState().newDrawable(), null); - BitmapInfo bitmapInfo = iconFactory.createBadgedIconBitmap(background, - Process.myUserHandle(), mTargetSdkVersion, false); - - return new ClockBitmapInfo(bitmap, color, normalizationScale, - mAnimationInfo, bitmapInfo.icon, mThemeData); - } - - @Override - public void drawForPersistence(Canvas canvas) { - LayerDrawable foreground = (LayerDrawable) getForeground(); - resetLevel(foreground, mAnimationInfo.hourLayerIndex); - resetLevel(foreground, mAnimationInfo.minuteLayerIndex); - resetLevel(foreground, mAnimationInfo.secondLayerIndex); - draw(canvas); - mAnimationInfo.applyTime(Calendar.getInstance(), (LayerDrawable) getForeground()); - } - - @Override - public Drawable getThemedDrawable(Context context) { - if (mThemeData != null) { - ClockDrawableWrapper drawable = fromThemeData(context, mThemeData); - return drawable == null ? this : drawable; - } - return this; - } - - private void resetLevel(LayerDrawable drawable, int index) { - if (index != INVALID_VALUE) { - drawable.getDrawable(index).setLevel(0); - } - } - - private static class AnimationInfo { - - public ConstantState baseDrawableState; - - public int hourLayerIndex; - public int minuteLayerIndex; - public int secondLayerIndex; - public int defaultHour; - public int defaultMinute; - public int defaultSecond; - - boolean applyTime(Calendar time, LayerDrawable foregroundDrawable) { - time.setTimeInMillis(System.currentTimeMillis()); - - // We need to rotate by the difference from the default time if one is specified. - int convertedHour = (time.get(Calendar.HOUR) + (12 - defaultHour)) % 12; - int convertedMinute = (time.get(Calendar.MINUTE) + (60 - defaultMinute)) % 60; - int convertedSecond = (time.get(Calendar.SECOND) + (60 - defaultSecond)) % 60; - - boolean invalidate = false; - if (hourLayerIndex != INVALID_VALUE) { - final Drawable hour = foregroundDrawable.getDrawable(hourLayerIndex); - if (hour.setLevel(convertedHour * 60 + time.get(Calendar.MINUTE))) { - invalidate = true; - } - } - - if (minuteLayerIndex != INVALID_VALUE) { - final Drawable minute = foregroundDrawable.getDrawable(minuteLayerIndex); - if (minute.setLevel(time.get(Calendar.HOUR) * 60 + convertedMinute)) { - invalidate = true; - } - } - - if (secondLayerIndex != INVALID_VALUE) { - final Drawable second = foregroundDrawable.getDrawable(secondLayerIndex); - if (second.setLevel(convertedSecond * LEVELS_PER_SECOND)) { - invalidate = true; - } - } - - return invalidate; - } - } - - static class ClockBitmapInfo extends BitmapInfo { - - public final float scale; - public final int offset; - public final AnimationInfo animInfo; - public final Bitmap mFlattenedBackground; - - public final ThemeData themeData; - public final ColorFilter bgFilter; - - ClockBitmapInfo(Bitmap icon, int color, float scale, AnimationInfo animInfo, - Bitmap background, ThemeData themeData) { - this(icon, color, scale, animInfo, background, themeData, null); - } - - ClockBitmapInfo(Bitmap icon, int color, float scale, AnimationInfo animInfo, - Bitmap background, ThemeData themeData, ColorFilter bgFilter) { - super(icon, color); - this.scale = scale; - this.animInfo = animInfo; - this.offset = (int) Math.ceil(ShadowGenerator.BLUR_FACTOR * icon.getWidth()); - this.mFlattenedBackground = background; - this.themeData = themeData; - this.bgFilter = bgFilter; - } - - @Override - public FastBitmapDrawable newThemedIcon(Context context) { - if (themeData != null) { - ClockDrawableWrapper wrapper = fromThemeData(context, themeData); - if (wrapper != null) { - int[] colors = getColors(context); - ColorFilter bgFilter = new PorterDuffColorFilter(colors[0], Mode.SRC_ATOP); - return new ClockBitmapInfo(icon, colors[1], scale, - wrapper.mAnimationInfo, mFlattenedBackground, themeData, bgFilter) - .newIcon(context); - } - } - return super.newThemedIcon(context); - } - - @Override - public FastBitmapDrawable newIcon(Context context) { - ClockIconDrawable d = new ClockIconDrawable(this); - d.mDisabledAlpha = GraphicsUtils.getFloat(context, R.attr.disabledIconAlpha, 1f); - return d; - } - - @Nullable - @Override - public byte[] toByteArray() { - return null; - } - - void drawBackground(Canvas canvas, Rect bounds, Paint paint) { - // draw the background that is already flattened to a bitmap - ColorFilter oldFilter = paint.getColorFilter(); - if (bgFilter != null) { - paint.setColorFilter(bgFilter); - } - canvas.drawBitmap(mFlattenedBackground, null, bounds, paint); - paint.setColorFilter(oldFilter); - } - } - - private static class ClockIconDrawable extends FastBitmapDrawable implements Runnable { - - private final Calendar mTime = Calendar.getInstance(); - - private final ClockBitmapInfo mInfo; - - private final AdaptiveIconDrawable mFullDrawable; - private final LayerDrawable mForeground; - - ClockIconDrawable(ClockBitmapInfo clockInfo) { - super(clockInfo); - - mInfo = clockInfo; - mFullDrawable = (AdaptiveIconDrawable) mInfo.animInfo.baseDrawableState - .newDrawable().mutate(); - mForeground = (LayerDrawable) mFullDrawable.getForeground(); - } - - @Override - protected void onBoundsChange(Rect bounds) { - super.onBoundsChange(bounds); - mFullDrawable.setBounds(bounds); - } - - @Override - public void drawInternal(Canvas canvas, Rect bounds) { - if (mInfo == null) { - super.drawInternal(canvas, bounds); - return; - } - mInfo.drawBackground(canvas, bounds, mPaint); - - // prepare and draw the foreground - mInfo.animInfo.applyTime(mTime, mForeground); - - canvas.scale(mInfo.scale, mInfo.scale, - bounds.exactCenterX() + mInfo.offset, bounds.exactCenterY() + mInfo.offset); - canvas.clipPath(mFullDrawable.getIconMask()); - mForeground.draw(canvas); - - reschedule(); - } - - @Override - public boolean isThemed() { - return mInfo.bgFilter != null; - } - - @Override - protected void updateFilter() { - super.updateFilter(); - mFullDrawable.setColorFilter(mPaint.getColorFilter()); - } - - @Override - public void run() { - if (mInfo.animInfo.applyTime(mTime, mForeground)) { - invalidateSelf(); - } else { - reschedule(); - } - } - - @Override - public boolean setVisible(boolean visible, boolean restart) { - boolean result = super.setVisible(visible, restart); - if (visible) { - reschedule(); - } else { - unscheduleSelf(this); - } - return result; - } - - private void reschedule() { - if (!isVisible()) { - return; - } - - unscheduleSelf(this); - final long upTime = SystemClock.uptimeMillis(); - final long step = TICK_MS; /* tick every 200 ms */ - scheduleSelf(this, upTime - ((upTime % step)) + step); - } - - @Override - public ConstantState getConstantState() { - return new ClockConstantState(mInfo, isDisabled()); - } - - private static class ClockConstantState extends FastBitmapConstantState { - - private final ClockBitmapInfo mInfo; - - ClockConstantState(ClockBitmapInfo info, boolean isDisabled) { - super(info.icon, info.color, isDisabled); - mInfo = info; - } - - @Override - public FastBitmapDrawable newDrawable() { - ClockIconDrawable drawable = new ClockIconDrawable(mInfo); - drawable.setIsDisabled(mIsDisabled); - return drawable; - } - } - } -} diff --git a/iconloaderlib/src/com/android/launcher3/icons/FastBitmapDrawable.java b/iconloaderlib/src/com/android/launcher3/icons/FastBitmapDrawable.java deleted file mode 100644 index 4aa2846..0000000 --- a/iconloaderlib/src/com/android/launcher3/icons/FastBitmapDrawable.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright (C) 2008 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.icons; - -import android.animation.ObjectAnimator; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.util.Property; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; - -import androidx.annotation.Nullable; - -public class FastBitmapDrawable extends Drawable { - - private static final Interpolator ACCEL = new AccelerateInterpolator(); - private static final Interpolator DEACCEL = new DecelerateInterpolator(); - - private static final float PRESSED_SCALE = 1.1f; - - private static final float DISABLED_DESATURATION = 1f; - private static final float DISABLED_BRIGHTNESS = 0.5f; - - public static final int CLICK_FEEDBACK_DURATION = 200; - - private static ColorFilter sDisabledFColorFilter; - - protected final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG); - protected Bitmap mBitmap; - protected final int mIconColor; - - @Nullable private ColorFilter mColorFilter; - - private boolean mIsPressed; - protected boolean mIsDisabled; - float mDisabledAlpha = 1f; - - // Animator and properties for the fast bitmap drawable's scale - private static final Property<FastBitmapDrawable, Float> SCALE - = new Property<FastBitmapDrawable, Float>(Float.TYPE, "scale") { - @Override - public Float get(FastBitmapDrawable fastBitmapDrawable) { - return fastBitmapDrawable.mScale; - } - - @Override - public void set(FastBitmapDrawable fastBitmapDrawable, Float value) { - fastBitmapDrawable.mScale = value; - fastBitmapDrawable.invalidateSelf(); - } - }; - private ObjectAnimator mScaleAnimation; - private float mScale = 1; - - private int mAlpha = 255; - - public FastBitmapDrawable(Bitmap b) { - this(b, Color.TRANSPARENT); - } - - public FastBitmapDrawable(BitmapInfo info) { - this(info.icon, info.color); - } - - protected FastBitmapDrawable(Bitmap b, int iconColor) { - this(b, iconColor, false); - } - - protected FastBitmapDrawable(Bitmap b, int iconColor, boolean isDisabled) { - mBitmap = b; - mIconColor = iconColor; - setFilterBitmap(true); - setIsDisabled(isDisabled); - } - - @Override - public final void draw(Canvas canvas) { - if (mScale != 1f) { - int count = canvas.save(); - Rect bounds = getBounds(); - canvas.scale(mScale, mScale, bounds.exactCenterX(), bounds.exactCenterY()); - drawInternal(canvas, bounds); - canvas.restoreToCount(count); - } else { - drawInternal(canvas, getBounds()); - } - } - - protected void drawInternal(Canvas canvas, Rect bounds) { - canvas.drawBitmap(mBitmap, null, bounds, mPaint); - } - - /** - * Returns the primary icon color - */ - public int getIconColor() { - return mIconColor; - } - - /** - * Returns if this represents a themed icon - */ - public boolean isThemed() { - return false; - } - - @Override - public void setColorFilter(ColorFilter cf) { - mColorFilter = cf; - updateFilter(); - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Override - public void setAlpha(int alpha) { - if (mAlpha != alpha) { - mAlpha = alpha; - mPaint.setAlpha(alpha); - invalidateSelf(); - } - } - - @Override - public void setFilterBitmap(boolean filterBitmap) { - mPaint.setFilterBitmap(filterBitmap); - mPaint.setAntiAlias(filterBitmap); - } - - @Override - public int getAlpha() { - return mAlpha; - } - - public void resetScale() { - if (mScaleAnimation != null) { - mScaleAnimation.cancel(); - mScaleAnimation = null; - } - mScale = 1; - invalidateSelf(); - } - - public float getAnimatedScale() { - return mScaleAnimation == null ? 1 : mScale; - } - - @Override - public int getIntrinsicWidth() { - return mBitmap.getWidth(); - } - - @Override - public int getIntrinsicHeight() { - return mBitmap.getHeight(); - } - - @Override - public int getMinimumWidth() { - return getBounds().width(); - } - - @Override - public int getMinimumHeight() { - return getBounds().height(); - } - - @Override - public boolean isStateful() { - return true; - } - - @Override - public ColorFilter getColorFilter() { - return mPaint.getColorFilter(); - } - - @Override - protected boolean onStateChange(int[] state) { - boolean isPressed = false; - for (int s : state) { - if (s == android.R.attr.state_pressed) { - isPressed = true; - break; - } - } - if (mIsPressed != isPressed) { - mIsPressed = isPressed; - - if (mScaleAnimation != null) { - mScaleAnimation.cancel(); - mScaleAnimation = null; - } - - if (mIsPressed) { - // Animate when going to pressed state - mScaleAnimation = ObjectAnimator.ofFloat(this, SCALE, PRESSED_SCALE); - mScaleAnimation.setDuration(CLICK_FEEDBACK_DURATION); - mScaleAnimation.setInterpolator(ACCEL); - mScaleAnimation.start(); - } else { - if (isVisible()) { - mScaleAnimation = ObjectAnimator.ofFloat(this, SCALE, 1f); - mScaleAnimation.setDuration(CLICK_FEEDBACK_DURATION); - mScaleAnimation.setInterpolator(DEACCEL); - mScaleAnimation.start(); - } else { - mScale = 1f; - invalidateSelf(); - } - } - return true; - } - return false; - } - - public void setIsDisabled(boolean isDisabled) { - if (mIsDisabled != isDisabled) { - mIsDisabled = isDisabled; - updateFilter(); - } - } - - protected boolean isDisabled() { - return mIsDisabled; - } - - private ColorFilter getDisabledColorFilter() { - if (sDisabledFColorFilter == null) { - sDisabledFColorFilter = getDisabledFColorFilter(mDisabledAlpha); - } - return sDisabledFColorFilter; - } - - /** - * Updates the paint to reflect the current brightness and saturation. - */ - protected void updateFilter() { - mPaint.setColorFilter(mIsDisabled ? getDisabledColorFilter() : mColorFilter); - invalidateSelf(); - } - - @Override - public ConstantState getConstantState() { - return new FastBitmapConstantState(mBitmap, mIconColor, mIsDisabled); - } - - public static ColorFilter getDisabledFColorFilter(float disabledAlpha) { - ColorMatrix tempBrightnessMatrix = new ColorMatrix(); - ColorMatrix tempFilterMatrix = new ColorMatrix(); - - tempFilterMatrix.setSaturation(1f - DISABLED_DESATURATION); - float scale = 1 - DISABLED_BRIGHTNESS; - int brightnessI = (int) (255 * DISABLED_BRIGHTNESS); - float[] mat = tempBrightnessMatrix.getArray(); - mat[0] = scale; - mat[6] = scale; - mat[12] = scale; - mat[4] = brightnessI; - mat[9] = brightnessI; - mat[14] = brightnessI; - mat[18] = disabledAlpha; - tempFilterMatrix.preConcat(tempBrightnessMatrix); - return new ColorMatrixColorFilter(tempBrightnessMatrix); - } - - protected static class FastBitmapConstantState extends ConstantState { - protected final Bitmap mBitmap; - protected final int mIconColor; - protected final boolean mIsDisabled; - - public FastBitmapConstantState(Bitmap bitmap, int color, boolean isDisabled) { - mBitmap = bitmap; - mIconColor = color; - mIsDisabled = isDisabled; - } - - @Override - public FastBitmapDrawable newDrawable() { - return new FastBitmapDrawable(mBitmap, mIconColor, mIsDisabled); - } - - @Override - public int getChangingConfigurations() { - return 0; - } - } -} diff --git a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java index 17b0016..22f1f23 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java +++ b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java @@ -15,16 +15,10 @@ */ package com.android.launcher3.icons; -import android.content.Context; -import android.content.res.TypedArray; import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.Path; import android.graphics.Rect; import android.graphics.Region; import android.graphics.RegionIterator; -import android.graphics.drawable.AdaptiveIconDrawable; -import android.graphics.drawable.ColorDrawable; import android.util.Log; import androidx.annotation.ColorInt; @@ -57,7 +51,10 @@ public class GraphicsUtils { * Compresses the bitmap to a byte array for serialization. */ public static byte[] flattenBitmap(Bitmap bitmap) { - ByteArrayOutputStream out = new ByteArrayOutputStream(getExpectedBitmapSize(bitmap)); + // Try go guesstimate how much space the icon will take when serialized + // to avoid unnecessary allocations/copies during the write (4 bytes per pixel). + int size = bitmap.getWidth() * bitmap.getHeight() * 4; + ByteArrayOutputStream out = new ByteArrayOutputStream(size); try { bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); out.flush(); @@ -69,14 +66,6 @@ public class GraphicsUtils { } } - /** - * Try go guesstimate how much space the icon will take when serialized to avoid unnecessary - * allocations/copies during the write (4 bytes per pixel). - */ - static int getExpectedBitmapSize(Bitmap bitmap) { - return bitmap.getWidth() * bitmap.getHeight() * 4; - } - public static int getArea(Region r) { RegionIterator itr = new RegionIterator(r); int area = 0; @@ -93,35 +82,4 @@ public class GraphicsUtils { public static void noteNewBitmapCreated() { sOnNewBitmapRunnable.run(); } - - - /** - * Returns the default path to be used by an icon - */ - public static Path getShapePath(int size) { - AdaptiveIconDrawable drawable = new AdaptiveIconDrawable( - new ColorDrawable(Color.BLACK), new ColorDrawable(Color.BLACK)); - drawable.setBounds(0, 0, size, size); - return new Path(drawable.getIconMask()); - } - - /** - * Returns the color associated with the attribute - */ - public static int getAttrColor(Context context, int attr) { - TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); - int colorAccent = ta.getColor(0, 0); - ta.recycle(); - return colorAccent; - } - - /** - * Returns the alpha corresponding to the theme attribute {@param attr} - */ - public static float getFloat(Context context, int attr, float defValue) { - TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); - float value = ta.getFloat(0, defValue); - ta.recycle(); - return value; - } } diff --git a/iconloaderlib/src/com/android/launcher3/icons/IconProvider.java b/iconloaderlib/src/com/android/launcher3/icons/IconProvider.java deleted file mode 100644 index 449c0da..0000000 --- a/iconloaderlib/src/com/android/launcher3/icons/IconProvider.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2019 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.icons; - -import static android.content.Intent.ACTION_DATE_CHANGED; -import static android.content.Intent.ACTION_TIMEZONE_CHANGED; -import static android.content.Intent.ACTION_TIME_CHANGED; -import static android.content.res.Resources.ID_NULL; - -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.LauncherActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.Resources; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Handler; -import android.os.PatternMatcher; -import android.os.Process; -import android.os.UserHandle; -import android.os.UserManager; -import android.text.TextUtils; -import android.util.ArrayMap; -import android.util.Log; - -import com.android.launcher3.icons.ThemedIconDrawable.ThemeData; -import com.android.launcher3.util.SafeCloseable; - -import org.xmlpull.v1.XmlPullParser; - -import java.util.Calendar; -import java.util.Collections; -import java.util.Map; -import java.util.function.Supplier; - -/** - * Class to handle icon loading from different packages - */ -public class IconProvider { - - private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED"; - private static final int CONFIG_ICON_MASK_RES_ID = Resources.getSystem().getIdentifier( - "config_icon_mask", "string", "android"); - - private static final String TAG_ICON = "icon"; - private static final String ATTR_PACKAGE = "package"; - private static final String ATTR_DRAWABLE = "drawable"; - - private static final String TAG = "IconProvider"; - private static final boolean DEBUG = false; - - private static final String ICON_METADATA_KEY_PREFIX = ".dynamic_icons"; - - private static final String SYSTEM_STATE_SEPARATOR = " "; - private static final String THEMED_ICON_MAP_FILE = "grayscale_icon_map"; - - private static final Map<String, ThemeData> DISABLED_MAP = Collections.emptyMap(); - - private Map<String, ThemeData> mThemedIconMap; - - private final Context mContext; - private final ComponentName mCalendar; - private final ComponentName mClock; - - static final int ICON_TYPE_DEFAULT = 0; - static final int ICON_TYPE_CALENDAR = 1; - static final int ICON_TYPE_CLOCK = 2; - - public IconProvider(Context context) { - this(context, false); - } - - public IconProvider(Context context, boolean supportsIconTheme) { - mContext = context; - mCalendar = parseComponentOrNull(context, R.string.calendar_component_name); - mClock = parseComponentOrNull(context, R.string.clock_component_name); - if (!supportsIconTheme) { - // Initialize an empty map if theming is not supported - mThemedIconMap = DISABLED_MAP; - } - } - - /** - * Enables or disables icon theme support - */ - public void setIconThemeSupported(boolean isSupported) { - mThemedIconMap = isSupported ? null : DISABLED_MAP; - } - - /** - * Adds any modification to the provided systemState for dynamic icons. This system state - * is used by caches to check for icon invalidation. - */ - public String getSystemStateForPackage(String systemState, String packageName) { - if (mCalendar != null && mCalendar.getPackageName().equals(packageName)) { - return systemState + SYSTEM_STATE_SEPARATOR + getDay(); - } else { - return systemState; - } - } - - /** - * Loads the icon for the provided LauncherActivityInfo - */ - public Drawable getIcon(LauncherActivityInfo info, int iconDpi) { - return getIconWithOverrides(info.getApplicationInfo().packageName, info.getUser(), iconDpi, - () -> info.getIcon(iconDpi)); - } - - /** - * Loads the icon for the provided activity info - */ - public Drawable getIcon(ActivityInfo info) { - return getIcon(info, mContext.getResources().getConfiguration().densityDpi); - } - - /** - * Loads the icon for the provided activity info - */ - public Drawable getIcon(ActivityInfo info, int iconDpi) { - return getIconWithOverrides(info.applicationInfo.packageName, - UserHandle.getUserHandleForUid(info.applicationInfo.uid), - iconDpi, () -> loadActivityInfoIcon(info, iconDpi)); - } - - private Drawable getIconWithOverrides(String packageName, UserHandle user, int iconDpi, - Supplier<Drawable> fallback) { - Drawable icon = null; - - int iconType = ICON_TYPE_DEFAULT; - if (mCalendar != null && mCalendar.getPackageName().equals(packageName)) { - icon = loadCalendarDrawable(iconDpi); - iconType = ICON_TYPE_CALENDAR; - } else if (mClock != null - && mClock.getPackageName().equals(packageName) - && Process.myUserHandle().equals(user)) { - icon = loadClockDrawable(iconDpi); - iconType = ICON_TYPE_CLOCK; - } - if (icon == null) { - icon = fallback.get(); - iconType = ICON_TYPE_DEFAULT; - } - - ThemeData td = getThemedIconMap().get(packageName); - return td != null ? td.wrapDrawable(icon, iconType) : icon; - } - - private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { - final int iconRes = ai.getIconResource(); - Drawable icon = null; - // Get the preferred density icon from the app's resources - if (density != 0 && iconRes != 0) { - try { - final Resources resources = mContext.getPackageManager() - .getResourcesForApplication(ai.applicationInfo); - icon = resources.getDrawableForDensity(iconRes, density); - } catch (NameNotFoundException | Resources.NotFoundException exc) { } - } - // Get the default density icon - if (icon == null) { - icon = ai.loadIcon(mContext.getPackageManager()); - } - return icon; - } - - private Map<String, ThemeData> getThemedIconMap() { - if (mThemedIconMap != null) { - return mThemedIconMap; - } - ArrayMap<String, ThemeData> map = new ArrayMap<>(); - try { - Resources res = mContext.getResources(); - int resID = res.getIdentifier(THEMED_ICON_MAP_FILE, "xml", mContext.getPackageName()); - if (resID != 0) { - XmlResourceParser parser = res.getXml(resID); - final int depth = parser.getDepth(); - - int type; - - while ((type = parser.next()) != XmlPullParser.START_TAG - && type != XmlPullParser.END_DOCUMENT); - - while (((type = parser.next()) != XmlPullParser.END_TAG || - parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { - if (type != XmlPullParser.START_TAG) { - continue; - } - if (TAG_ICON.equals(parser.getName())) { - String pkg = parser.getAttributeValue(null, ATTR_PACKAGE); - int iconId = parser.getAttributeResourceValue(null, ATTR_DRAWABLE, 0); - if (iconId != 0 && !TextUtils.isEmpty(pkg)) { - map.put(pkg, new ThemeData(res, iconId)); - } - } - } - } - } catch (Exception e) { - Log.e(TAG, "Unable to parse icon map", e); - } - mThemedIconMap = map; - return mThemedIconMap; - } - - private Drawable loadCalendarDrawable(int iconDpi) { - PackageManager pm = mContext.getPackageManager(); - try { - final Bundle metadata = pm.getActivityInfo( - mCalendar, - PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA) - .metaData; - final Resources resources = pm.getResourcesForApplication(mCalendar.getPackageName()); - final int id = getDynamicIconId(metadata, resources); - if (id != ID_NULL) { - if (DEBUG) Log.d(TAG, "Got icon #" + id); - return resources.getDrawableForDensity(id, iconDpi, null /* theme */); - } - } catch (PackageManager.NameNotFoundException e) { - if (DEBUG) { - Log.d(TAG, "Could not get activityinfo or resources for package: " - + mCalendar.getPackageName()); - } - } - return null; - } - - private Drawable loadClockDrawable(int iconDpi) { - return ClockDrawableWrapper.forPackage(mContext, mClock.getPackageName(), iconDpi); - } - - /** - * @param metadata metadata of the default activity of Calendar - * @param resources from the Calendar package - * @return the resource id for today's Calendar icon; 0 if resources cannot be found. - */ - private int getDynamicIconId(Bundle metadata, Resources resources) { - if (metadata == null) { - return ID_NULL; - } - String key = mCalendar.getPackageName() + ICON_METADATA_KEY_PREFIX; - final int arrayId = metadata.getInt(key, ID_NULL); - if (arrayId == ID_NULL) { - return ID_NULL; - } - try { - return resources.obtainTypedArray(arrayId).getResourceId(getDay(), ID_NULL); - } catch (Resources.NotFoundException e) { - if (DEBUG) { - Log.d(TAG, "package defines '" + key + "' but corresponding array not found"); - } - return ID_NULL; - } - } - - /** - * @return Today's day of the month, zero-indexed. - */ - static int getDay() { - return Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1; - } - - private static ComponentName parseComponentOrNull(Context context, int resId) { - String cn = context.getString(resId); - return TextUtils.isEmpty(cn) ? null : ComponentName.unflattenFromString(cn); - } - - /** - * Returns a string representation of the current system icon state - */ - public String getSystemIconState() { - return (CONFIG_ICON_MASK_RES_ID == ID_NULL - ? "" : mContext.getResources().getString(CONFIG_ICON_MASK_RES_ID)) - + (mThemedIconMap == DISABLED_MAP ? ",no-theme" : ",with-theme"); - } - - /** - * Registers a callback to listen for various system dependent icon changes. - */ - public SafeCloseable registerIconChangeListener(IconChangeListener listener, Handler handler) { - return new IconChangeReceiver(listener, handler); - } - - private class IconChangeReceiver extends BroadcastReceiver implements SafeCloseable { - - private final IconChangeListener mCallback; - private String mIconState; - - IconChangeReceiver(IconChangeListener callback, Handler handler) { - mCallback = callback; - mIconState = getSystemIconState(); - - - IntentFilter packageFilter = new IntentFilter(ACTION_OVERLAY_CHANGED); - packageFilter.addDataScheme("package"); - packageFilter.addDataSchemeSpecificPart("android", PatternMatcher.PATTERN_LITERAL); - mContext.registerReceiver(this, packageFilter, null, handler); - - if (mCalendar != null || mClock != null) { - final IntentFilter filter = new IntentFilter(ACTION_TIMEZONE_CHANGED); - if (mCalendar != null) { - filter.addAction(Intent.ACTION_TIME_CHANGED); - filter.addAction(ACTION_DATE_CHANGED); - } - mContext.registerReceiver(this, filter, null, handler); - } - } - - @Override - public void onReceive(Context context, Intent intent) { - switch (intent.getAction()) { - case ACTION_TIMEZONE_CHANGED: - if (mClock != null) { - mCallback.onAppIconChanged(mClock.getPackageName(), Process.myUserHandle()); - } - // follow through - case ACTION_DATE_CHANGED: - case ACTION_TIME_CHANGED: - if (mCalendar != null) { - for (UserHandle user - : context.getSystemService(UserManager.class).getUserProfiles()) { - mCallback.onAppIconChanged(mCalendar.getPackageName(), user); - } - } - break; - case ACTION_OVERLAY_CHANGED: { - String newState = getSystemIconState(); - if (!mIconState.equals(newState)) { - mIconState = newState; - mCallback.onSystemIconStateChanged(mIconState); - } - break; - } - } - } - - @Override - public void close() { - mContext.unregisterReceiver(this); - } - } - - /** - * Listener for receiving icon changes - */ - public interface IconChangeListener { - - /** - * Called when the icon for a particular app changes - */ - void onAppIconChanged(String packageName, UserHandle user); - - /** - * Called when the global icon state changed, which can typically affect all icons - */ - void onSystemIconStateChanged(String iconState); - } -} diff --git a/iconloaderlib/src/com/android/launcher3/icons/PlaceHolderIconDrawable.java b/iconloaderlib/src/com/android/launcher3/icons/PlaceHolderIconDrawable.java deleted file mode 100644 index 5f3343e..0000000 --- a/iconloaderlib/src/com/android/launcher3/icons/PlaceHolderIconDrawable.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.icons; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Path; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffColorFilter; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; - -import androidx.core.graphics.ColorUtils; - -/** - * Subclass which draws a placeholder icon when the actual icon is not yet loaded - */ -public class PlaceHolderIconDrawable extends FastBitmapDrawable { - - // Path in [0, 100] bounds. - private final Path mProgressPath; - - public PlaceHolderIconDrawable(BitmapInfo info, Context context) { - super(info); - - mProgressPath = GraphicsUtils.getShapePath(100); - mPaint.setColor(ColorUtils.compositeColors( - GraphicsUtils.getAttrColor(context, R.attr.loadingIconColor), info.color)); - } - - @Override - protected void drawInternal(Canvas canvas, Rect bounds) { - int saveCount = canvas.save(); - canvas.translate(bounds.left, bounds.top); - canvas.scale(bounds.width() / 100f, bounds.height() / 100f); - canvas.drawPath(mProgressPath, mPaint); - canvas.restoreToCount(saveCount); - } - - /** Updates this placeholder to {@code newIcon} with animation. */ - public void animateIconUpdate(Drawable newIcon) { - int placeholderColor = mPaint.getColor(); - int originalAlpha = Color.alpha(placeholderColor); - - ValueAnimator iconUpdateAnimation = ValueAnimator.ofInt(originalAlpha, 0); - iconUpdateAnimation.setDuration(375); - iconUpdateAnimation.addUpdateListener(valueAnimator -> { - int newAlpha = (int) valueAnimator.getAnimatedValue(); - int newColor = ColorUtils.setAlphaComponent(placeholderColor, newAlpha); - - newIcon.setColorFilter(new PorterDuffColorFilter(newColor, PorterDuff.Mode.SRC_ATOP)); - }); - iconUpdateAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - newIcon.setColorFilter(null); - } - }); - iconUpdateAnimation.start(); - } - -} diff --git a/iconloaderlib/src/com/android/launcher3/icons/RoundDrawableWrapper.java b/iconloaderlib/src/com/android/launcher3/icons/RoundDrawableWrapper.java deleted file mode 100644 index e569c1e..0000000 --- a/iconloaderlib/src/com/android/launcher3/icons/RoundDrawableWrapper.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2021 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.icons; - -import android.graphics.Canvas; -import android.graphics.Path; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.DrawableWrapper; - -/** - * A drawable which clips rounded corner around a child drawable - */ -public class RoundDrawableWrapper extends DrawableWrapper { - - private final RectF mTempRect = new RectF(); - private final Path mClipPath = new Path(); - private final float mRoundedCornersRadius; - - public RoundDrawableWrapper(Drawable dr, float radius) { - super(dr); - mRoundedCornersRadius = radius; - } - - @Override - protected void onBoundsChange(Rect bounds) { - mTempRect.set(getBounds()); - mClipPath.reset(); - mClipPath.addRoundRect(mTempRect, mRoundedCornersRadius, - mRoundedCornersRadius, Path.Direction.CCW); - super.onBoundsChange(bounds); - } - - @Override - public final void draw(Canvas canvas) { - int saveCount = canvas.save(); - canvas.clipPath(mClipPath); - super.draw(canvas); - canvas.restoreToCount(saveCount); - } -} diff --git a/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java index e24f353..7702727 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java +++ b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java @@ -32,17 +32,14 @@ import android.graphics.RectF; * Utility class to add shadows to bitmaps. */ public class ShadowGenerator { - - public static final boolean ENABLE_SHADOWS = true; - - public static final float BLUR_FACTOR = 1.5f/48; + public static final float BLUR_FACTOR = 0.5f/48; // Percent of actual icon size public static final float KEY_SHADOW_DISTANCE = 1f/48; - private static final int KEY_SHADOW_ALPHA = 10; + private static final int KEY_SHADOW_ALPHA = 61; // Percent of actual icon size private static final float HALF_DISTANCE = 0.5f; - private static final int AMBIENT_SHADOW_ALPHA = 7; + private static final int AMBIENT_SHADOW_ALPHA = 30; private final int mIconSize; @@ -63,20 +60,17 @@ public class ShadowGenerator { public synchronized void recreateIcon(Bitmap icon, BlurMaskFilter blurMaskFilter, int ambientAlpha, int keyAlpha, Canvas out) { - if (ENABLE_SHADOWS) { - int[] offset = new int[2]; - mBlurPaint.setMaskFilter(blurMaskFilter); - Bitmap shadow = icon.extractAlpha(mBlurPaint, offset); - - // Draw ambient shadow - mDrawPaint.setAlpha(ambientAlpha); - out.drawBitmap(shadow, offset[0], offset[1], mDrawPaint); - - // Draw key shadow - mDrawPaint.setAlpha(keyAlpha); - out.drawBitmap(shadow, offset[0], offset[1] + KEY_SHADOW_DISTANCE * mIconSize, - mDrawPaint); - } + int[] offset = new int[2]; + mBlurPaint.setMaskFilter(blurMaskFilter); + Bitmap shadow = icon.extractAlpha(mBlurPaint, offset); + + // Draw ambient shadow + mDrawPaint.setAlpha(ambientAlpha); + out.drawBitmap(shadow, offset[0], offset[1], mDrawPaint); + + // Draw key shadow + mDrawPaint.setAlpha(keyAlpha); + out.drawBitmap(shadow, offset[0], offset[1] + KEY_SHADOW_DISTANCE * mIconSize, mDrawPaint); // Draw the icon mDrawPaint.setAlpha(255); @@ -90,18 +84,15 @@ public class ShadowGenerator { public static float getScaleForBounds(RectF bounds) { float scale = 1; - if (ENABLE_SHADOWS) { - // For top, left & right, we need same space. - float minSide = Math.min(Math.min(bounds.left, bounds.right), bounds.top); - if (minSide < BLUR_FACTOR) { - scale = (HALF_DISTANCE - BLUR_FACTOR) / (HALF_DISTANCE - minSide); - } + // For top, left & right, we need same space. + float minSide = Math.min(Math.min(bounds.left, bounds.right), bounds.top); + if (minSide < BLUR_FACTOR) { + scale = (HALF_DISTANCE - BLUR_FACTOR) / (HALF_DISTANCE - minSide); + } - float bottomSpace = BLUR_FACTOR + KEY_SHADOW_DISTANCE; - if (bounds.bottom < bottomSpace) { - scale = Math.min(scale, - (HALF_DISTANCE - bottomSpace) / (HALF_DISTANCE - bounds.bottom)); - } + float bottomSpace = BLUR_FACTOR + KEY_SHADOW_DISTANCE; + if (bounds.bottom < bottomSpace) { + scale = Math.min(scale, (HALF_DISTANCE - bottomSpace) / (HALF_DISTANCE - bounds.bottom)); } return scale; } @@ -124,13 +115,8 @@ public class ShadowGenerator { } public Builder setupBlurForSize(int height) { - if (ENABLE_SHADOWS) { - shadowBlur = height * 1f / 24; - keyShadowDistance = height * 1f / 16; - } else { - shadowBlur = 0; - keyShadowDistance = 0; - } + shadowBlur = height * 1f / 24; + keyShadowDistance = height * 1f / 16; return this; } @@ -155,17 +141,15 @@ public class ShadowGenerator { Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); p.setColor(color); - if (ENABLE_SHADOWS) { - // Key shadow - p.setShadowLayer(shadowBlur, 0, keyShadowDistance, - setColorAlphaBound(Color.BLACK, keyShadowAlpha)); - c.drawRoundRect(bounds, radius, radius, p); + // Key shadow + p.setShadowLayer(shadowBlur, 0, keyShadowDistance, + setColorAlphaBound(Color.BLACK, keyShadowAlpha)); + c.drawRoundRect(bounds, radius, radius, p); - // Ambient shadow - p.setShadowLayer(shadowBlur, 0, 0, - setColorAlphaBound(Color.BLACK, ambientShadowAlpha)); - c.drawRoundRect(bounds, radius, radius, p); - } + // Ambient shadow + p.setShadowLayer(shadowBlur, 0, 0, + setColorAlphaBound(Color.BLACK, ambientShadowAlpha)); + c.drawRoundRect(bounds, radius, radius, p); if (Color.alpha(color) < 255) { // Clear any content inside the pill-rect for translucent fill. diff --git a/iconloaderlib/src/com/android/launcher3/icons/ThemedIconDrawable.java b/iconloaderlib/src/com/android/launcher3/icons/ThemedIconDrawable.java deleted file mode 100644 index b2e554b..0000000 --- a/iconloaderlib/src/com/android/launcher3/icons/ThemedIconDrawable.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2021 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.icons; - -import static android.content.res.Configuration.UI_MODE_NIGHT_MASK; -import static android.content.res.Configuration.UI_MODE_NIGHT_YES; -import static android.content.res.Resources.ID_NULL; - -import static com.android.launcher3.icons.GraphicsUtils.getExpectedBitmapSize; -import static com.android.launcher3.icons.IconProvider.ICON_TYPE_CALENDAR; -import static com.android.launcher3.icons.IconProvider.ICON_TYPE_CLOCK; - -import android.content.Context; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.drawable.AdaptiveIconDrawable; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.InsetDrawable; -import android.os.Process; -import android.os.UserHandle; -import android.util.Log; - -import androidx.annotation.Nullable; - -import com.android.launcher3.icons.BitmapInfo.Extender; -import com.android.launcher3.icons.cache.BaseIconCache; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Class to handle monochrome themed app icons - */ -@SuppressWarnings("NewApi") -public class ThemedIconDrawable extends FastBitmapDrawable { - - public static final String TAG = "ThemedIconDrawable"; - - final ThemedBitmapInfo bitmapInfo; - final int colorFg, colorBg; - - // The foreground/monochrome icon for the app - private final Drawable mMonochromeIcon; - private final AdaptiveIconDrawable mBgWrapper; - private final Rect mBadgeBounds; - - protected ThemedIconDrawable(ThemedConstantState constantState) { - super(constantState.mBitmap, constantState.colorFg, constantState.mIsDisabled); - bitmapInfo = constantState.bitmapInfo; - colorBg = constantState.colorBg; - colorFg = constantState.colorFg; - - mMonochromeIcon = bitmapInfo.mThemeData.loadMonochromeDrawable(colorFg); - mBgWrapper = new AdaptiveIconDrawable(new ColorDrawable(colorBg), null); - mBadgeBounds = bitmapInfo.mUserBadge == null ? null : - new Rect(0, 0, bitmapInfo.mUserBadge.getWidth(), bitmapInfo.mUserBadge.getHeight()); - - } - - @Override - protected void onBoundsChange(Rect bounds) { - super.onBoundsChange(bounds); - mBgWrapper.setBounds(bounds); - mMonochromeIcon.setBounds(bounds); - } - - @Override - protected void drawInternal(Canvas canvas, Rect bounds) { - int count = canvas.save(); - canvas.scale(bitmapInfo.mNormalizationScale, bitmapInfo.mNormalizationScale, - bounds.exactCenterX(), bounds.exactCenterY()); - mPaint.setColor(colorBg); - canvas.drawPath(mBgWrapper.getIconMask(), mPaint); - mMonochromeIcon.draw(canvas); - canvas.restoreToCount(count); - if (mBadgeBounds != null) { - canvas.drawBitmap(bitmapInfo.mUserBadge, mBadgeBounds, getBounds(), mPaint); - } - } - - @Override - public boolean isThemed() { - return true; - } - - @Override - public ConstantState getConstantState() { - return new ThemedConstantState(bitmapInfo, colorBg, colorFg, mIsDisabled); - } - - static class ThemedConstantState extends FastBitmapConstantState { - - final ThemedBitmapInfo bitmapInfo; - final int colorFg, colorBg; - - public ThemedConstantState(ThemedBitmapInfo bitmapInfo, - int colorBg, int colorFg, boolean isDisabled) { - super(bitmapInfo.icon, bitmapInfo.color, isDisabled); - this.bitmapInfo = bitmapInfo; - this.colorBg = colorBg; - this.colorFg = colorFg; - } - - @Override - public FastBitmapDrawable newDrawable() { - return new ThemedIconDrawable(this); - } - } - - public static class ThemedBitmapInfo extends BitmapInfo { - - final ThemeData mThemeData; - final float mNormalizationScale; - final Bitmap mUserBadge; - - public ThemedBitmapInfo(Bitmap icon, int color, ThemeData themeData, - float normalizationScale, Bitmap userBadge) { - super(icon, color); - mThemeData = themeData; - mNormalizationScale = normalizationScale; - mUserBadge = userBadge; - } - - @Override - public FastBitmapDrawable newThemedIcon(Context context) { - int[] colors = getColors(context); - FastBitmapDrawable drawable = new ThemedConstantState(this, colors[0], colors[1], false) - .newDrawable(); - drawable.mDisabledAlpha = GraphicsUtils.getFloat(context, R.attr.disabledIconAlpha, 1f); - return drawable; - } - - @Nullable - public byte[] toByteArray() { - if (isNullOrLowRes()) { - return null; - } - String resName = mThemeData.mResources.getResourceName(mThemeData.mResID); - ByteArrayOutputStream out = new ByteArrayOutputStream( - getExpectedBitmapSize(icon) + 3 + resName.length()); - try { - DataOutputStream dos = new DataOutputStream(out); - dos.writeByte(TYPE_THEMED); - dos.writeFloat(mNormalizationScale); - dos.writeUTF(resName); - icon.compress(Bitmap.CompressFormat.PNG, 100, dos); - - dos.flush(); - dos.close(); - return out.toByteArray(); - } catch (IOException e) { - Log.w(TAG, "Could not write bitmap"); - return null; - } - } - - static ThemedBitmapInfo decode(byte[] data, int color, - BitmapFactory.Options decodeOptions, UserHandle user, BaseIconCache iconCache, - Context context) { - try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data))) { - dis.readByte(); // type - float normalizationScale = dis.readFloat(); - - String resName = dis.readUTF(); - int resId = context.getResources() - .getIdentifier(resName, "drawable", context.getPackageName()); - if (resId == ID_NULL) { - return null; - } - - Bitmap userBadgeBitmap = null; - if (!Process.myUserHandle().equals(user)) { - try (BaseIconFactory iconFactory = iconCache.getIconFactory()) { - userBadgeBitmap = iconFactory.getUserBadgeBitmap(user); - } - } - - ThemeData themeData = new ThemeData(context.getResources(), resId); - Bitmap icon = BitmapFactory.decodeStream(dis, null, decodeOptions); - return new ThemedBitmapInfo(icon, color, themeData, normalizationScale, - userBadgeBitmap); - } catch (IOException e) { - return null; - } - } - } - - public static class ThemeData { - - final Resources mResources; - final int mResID; - - public ThemeData(Resources resources, int resID) { - mResources = resources; - mResID = resID; - } - - Drawable loadMonochromeDrawable(int accentColor) { - Drawable d = mResources.getDrawable(mResID).mutate(); - d.setTint(accentColor); - d = new InsetDrawable(d, .2f); - return d; - } - - public Drawable wrapDrawable(Drawable original, int iconType) { - if (!(original instanceof AdaptiveIconDrawable)) { - return original; - } - AdaptiveIconDrawable aid = (AdaptiveIconDrawable) original; - String resourceType = mResources.getResourceTypeName(mResID); - if (iconType == ICON_TYPE_CALENDAR && "array".equals(resourceType)) { - TypedArray ta = mResources.obtainTypedArray(mResID); - int id = ta.getResourceId(IconProvider.getDay(), ID_NULL); - ta.recycle(); - return id == ID_NULL ? original - : new ThemedAdaptiveIcon(aid, new ThemeData(mResources, id)); - } else if (iconType == ICON_TYPE_CLOCK && "array".equals(resourceType)) { - ((ClockDrawableWrapper) original).mThemeData = this; - return original; - } else if ("drawable".equals(resourceType)) { - return new ThemedAdaptiveIcon(aid, this); - } else { - return original; - } - } - } - - static class ThemedAdaptiveIcon extends AdaptiveIconDrawable implements Extender { - - protected final ThemeData mThemeData; - - public ThemedAdaptiveIcon(AdaptiveIconDrawable parent, ThemeData themeData) { - super(parent.getBackground(), parent.getForeground()); - mThemeData = themeData; - } - - @Override - public BitmapInfo getExtendedInfo(Bitmap bitmap, int color, BaseIconFactory iconFactory, - float normalizationScale, UserHandle user) { - Bitmap userBadge = Process.myUserHandle().equals(user) - ? null : iconFactory.getUserBadgeBitmap(user); - return new ThemedBitmapInfo(bitmap, color, mThemeData, normalizationScale, userBadge); - } - - @Override - public void drawForPersistence(Canvas canvas) { - draw(canvas); - } - - @Override - public Drawable getThemedDrawable(Context context) { - int[] colors = getColors(context); - Drawable bg = new ColorDrawable(colors[0]); - float inset = getExtraInsetFraction() / (1 + 2 * getExtraInsetFraction()); - Drawable fg = new InsetDrawable(mThemeData.loadMonochromeDrawable(colors[1]), inset); - return new AdaptiveIconDrawable(bg, fg); - } - } - - /** - * Get an int array representing background and foreground colors for themed icons - */ - public static int[] getColors(Context context) { - Resources res = context.getResources(); - int[] colors = new int[2]; - if ((res.getConfiguration().uiMode & UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES) { - colors[0] = res.getColor(android.R.color.system_neutral1_800); - colors[1] = res.getColor(android.R.color.system_accent1_100); - } else { - colors[0] = res.getColor(android.R.color.system_accent1_100); - colors[1] = res.getColor(android.R.color.system_neutral2_700); - } - return colors; - } -} diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java index d685737..4c634cb 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java +++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java @@ -32,6 +32,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; @@ -48,6 +49,8 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; +import com.android.launcher3.icons.BitmapRenderer; +import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.SQLiteCacheHelper; @@ -91,6 +94,7 @@ public abstract class BaseIconCache { protected String mSystemState = ""; private final String mDbFileName; + private final BitmapFactory.Options mDecodeOptions; private final Looper mBgLooper; public BaseIconCache(Context context, String dbFileName, Looper bgLooper, @@ -118,6 +122,13 @@ public abstract class BaseIconCache { }; } + if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + mDecodeOptions = new BitmapFactory.Options(); + mDecodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE; + } else { + mDecodeOptions = null; + } + updateSystemState(); mIconDpi = iconDpi; mIconDb = new IconDB(context, dbFileName, iconPixelSize); @@ -137,7 +148,7 @@ public abstract class BaseIconCache { /** * Opens and returns an icon factory. The factory is recycled by the caller. */ - public abstract BaseIconFactory getIconFactory(); + protected abstract BaseIconFactory getIconFactory(); public void updateIconParams(int iconDpi, int iconPixelSize) { mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize)); @@ -385,7 +396,7 @@ public abstract class BaseIconCache { } if (icon != null) { BaseIconFactory li = getIconFactory(); - entry.bitmap = li.createShapedIconBitmap(icon, user); + entry.bitmap = li.createIconBitmap(icon); li.close(); } if (!TextUtils.isEmpty(title) && entry.bitmap.icon != null) { @@ -479,14 +490,14 @@ public abstract class BaseIconCache { } if (!lowRes) { + byte[] data = c.getBlob(2); try { - entry.bitmap = BitmapInfo.fromByteArray( - c.getBlob(2), entry.bitmap.color, cacheKey.user, this, mContext); - } catch (Exception e) { - return false; - } + entry.bitmap = BitmapInfo.of( + BitmapFactory.decodeByteArray(data, 0, data.length, mDecodeOptions), + entry.bitmap.color); + } catch (Exception e) { } } - return entry.bitmap != null; + return true; } } catch (SQLiteException e) { Log.d(TAG, "Error reading icon cache", e); @@ -510,7 +521,7 @@ public abstract class BaseIconCache { * Cache class to store the actual entries on disk */ public static final class IconDB extends SQLiteCacheHelper { - private static final int RELEASE_VERSION = 31; + private static final int RELEASE_VERSION = 27; public static final String TABLE_NAME = "icons"; public static final String COLUMN_ROWID = "rowid"; @@ -553,7 +564,8 @@ public abstract class BaseIconCache { private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName, @Nullable String keywords) { ContentValues values = new ContentValues(); - values.put(IconDB.COLUMN_ICON, bitmapInfo.toByteArray()); + values.put(IconDB.COLUMN_ICON, + bitmapInfo.isLowRes() ? null : GraphicsUtils.flattenBitmap(bitmapInfo.icon)); values.put(IconDB.COLUMN_ICON_COLOR, bitmapInfo.color); values.put(IconDB.COLUMN_LABEL, label); diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/HandlerRunnable.java b/iconloaderlib/src/com/android/launcher3/icons/cache/HandlerRunnable.java index 3dfb384..ee52934 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/cache/HandlerRunnable.java +++ b/iconloaderlib/src/com/android/launcher3/icons/cache/HandlerRunnable.java @@ -17,36 +17,19 @@ package com.android.launcher3.icons.cache; import android.os.Handler; -import java.util.concurrent.Executor; -import java.util.function.Consumer; -import java.util.function.Supplier; - /** * A runnable that can be posted to a {@link Handler} which can be canceled. */ -public class HandlerRunnable<T> implements Runnable { - - private final Handler mWorkerHandler; - private final Supplier<T> mTask; +public abstract class HandlerRunnable implements Runnable { - private final Executor mCallbackExecutor; - private final Consumer<T> mCallback; + private final Handler mHandler; private final Runnable mEndRunnable; private boolean mEnded = false; private boolean mCanceled = false; - public HandlerRunnable(Handler workerHandler, Supplier<T> task, Executor callbackExecutor, - Consumer<T> callback) { - this(workerHandler, task, callbackExecutor, callback, () -> { }); - } - - public HandlerRunnable(Handler workerHandler, Supplier<T> task, Executor callbackExecutor, - Consumer<T> callback, Runnable endRunnable) { - mWorkerHandler = workerHandler; - mTask = task; - mCallbackExecutor = callbackExecutor; - mCallback = callback; + public HandlerRunnable(Handler handler, Runnable endRunnable) { + mHandler = handler; mEndRunnable = endRunnable; } @@ -54,26 +37,31 @@ public class HandlerRunnable<T> implements Runnable { * Cancels this runnable from being run, only if it has not already run. */ public void cancel() { - mWorkerHandler.removeCallbacks(this); + mHandler.removeCallbacks(this); + // TODO: This can actually cause onEnd to be called twice if the handler is already running + // this runnable + // NOTE: This is currently run on whichever thread the caller is run on. mCanceled = true; - mCallbackExecutor.execute(this::onEnd); + onEnd(); } - @Override - public void run() { - T value = mTask.get(); - mCallbackExecutor.execute(() -> { - if (!mCanceled) { - mCallback.accept(value); - } - onEnd(); - }); + /** + * @return whether this runnable was canceled. + */ + protected boolean isCanceled() { + return mCanceled; } - private void onEnd() { + /** + * To be called by the implemention of this runnable. The end callback is done on whichever + * thread the caller is calling from. + */ + public void onEnd() { if (!mEnded) { mEnded = true; - mEndRunnable.run(); + if (mEndRunnable != null) { + mEndRunnable.run(); + } } } } diff --git a/iconloaderlib/src/com/android/launcher3/util/SafeCloseable.java b/iconloaderlib/src/com/android/launcher3/util/SafeCloseable.java deleted file mode 100644 index ba8ee04..0000000 --- a/iconloaderlib/src/com/android/launcher3/util/SafeCloseable.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2019 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; - -/** - * Extension of closeable which does not throw an exception - */ -public interface SafeCloseable extends AutoCloseable { - - @Override - void close(); -} diff --git a/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java b/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java index cc4ad7b..1337975 100644 --- a/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java +++ b/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java @@ -88,7 +88,7 @@ public class SimpleIconCache extends BaseIconCache { } @Override - public BaseIconFactory getIconFactory() { + protected BaseIconFactory getIconFactory() { return IconFactory.obtain(mContext); } diff --git a/searchuilib/.gitignore b/searchuilib/.gitignore deleted file mode 100644 index 6213826..0000000 --- a/searchuilib/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.iml -.project -.classpath -.project.properties -gen/ -bin/ -.idea/ -.gradle/ -local.properties -gradle/ -build/ -gradlew* -.DS_Store diff --git a/searchuilib/Android.bp b/searchuilib/Android.bp deleted file mode 100644 index 2b25616..0000000 --- a/searchuilib/Android.bp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2020 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 { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -android_library { - name: "search_ui", - - sdk_version: "current", - min_sdk_version: "26", - - srcs: [ - "src/**/*.java", - ], -} diff --git a/searchuilib/AndroidManifest.xml b/searchuilib/AndroidManifest.xml deleted file mode 100644 index 6c6c5f6..0000000 --- a/searchuilib/AndroidManifest.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 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. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.app.search"> -</manifest> diff --git a/searchuilib/build.gradle b/searchuilib/build.gradle deleted file mode 100644 index 4f372e3..0000000 --- a/searchuilib/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion COMPILE_SDK - buildToolsVersion BUILD_TOOLS_VERSION - - defaultConfig { - minSdkVersion 25 - targetSdkVersion 28 - versionCode 1 - versionName "1.0" - } - - sourceSets { - main { - java.srcDirs = ['src'] - manifest.srcFile 'AndroidManifest.xml' - } - } - - lintOptions { - abortOnError false - } - - tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } -} - -dependencies { - implementation "androidx.core:core:${ANDROID_X_VERSION}" -} diff --git a/searchuilib/src/com/android/app/search/LayoutType.java b/searchuilib/src/com/android/app/search/LayoutType.java deleted file mode 100644 index cf27e2b..0000000 --- a/searchuilib/src/com/android/app/search/LayoutType.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2020 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.app.search; - -/** - * Constants to be used with {@link SearchTarget}. - */ -public class LayoutType { - - // ------ - // | icon | - // ------ - // text - public static final String ICON_SINGLE_VERTICAL_TEXT = "icon"; - - // Below three layouts (to be deprecated) and two layouts render - // {@link SearchTarget}s in following layout. - // ------ ------ ------ - // | | title |(opt)| |(opt)| - // | icon | subtitle (optional) | icon| | icon| - // ------ ------ ------ - @Deprecated - public static final String ICON_SINGLE_HORIZONTAL_TEXT = "icon_text_row"; - @Deprecated - public static final String ICON_DOUBLE_HORIZONTAL_TEXT = "icon_texts_row"; - @Deprecated - public static final String ICON_DOUBLE_HORIZONTAL_TEXT_BUTTON = "icon_texts_button"; - - // will replace ICON_DOUBLE_* ICON_SINGLE_* layouts - public static final String ICON_HORIZONTAL_TEXT = "icon_row"; - public static final String HORIZONTAL_MEDIUM_TEXT = "icon_row_medium"; - public static final String SMALL_ICON_HORIZONTAL_TEXT = "short_icon_row"; - - // This layout creates square thumbnail image (currently 3 column) - public static final String THUMBNAIL = "thumbnail"; - - // This layout contains an icon and slice - public static final String ICON_SLICE = "slice"; - - // Widget bitmap preview - public static final String WIDGET_PREVIEW = "widget_preview"; - - // Live widget search result - public static final String WIDGET_LIVE = "widget_live"; - - // Layout type used to display people tiles using shortcut info - public static final String PEOPLE_TILE = "people_tile"; - - // text based header to group various layouts in low confidence section of the results. - public static final String TEXT_HEADER = "header"; - - // horizontal bar to be inserted between fallback search results and low confidence section - public static final String DIVIDER = "divider"; - - // horizontal bar to be inserted between fallback search results and low confidence section - public static final String EMPTY_DIVIDER = "empty_divider"; - - // layout representing quick calculations - public static final String CALCULATOR = "calculator"; -} |