Loading iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +1 −1 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ public class BaseIconFactory implements AutoCloseable { clear(); } protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { public BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { this(context, fillResIconDpi, iconBitmapSize, false); } Loading iconloaderlib/src/com/android/launcher3/icons/IconProvider.java +98 −50 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ 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; Loading @@ -32,6 +35,7 @@ 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; Loading @@ -45,7 +49,8 @@ import com.android.launcher3.util.SafeCloseable; import org.xmlpull.v1.XmlPullParser; import java.util.Calendar; import java.util.function.BiConsumer; import java.util.Collections; import java.util.Map; import java.util.function.Supplier; /** Loading @@ -53,6 +58,10 @@ import java.util.function.Supplier; */ 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"; Loading @@ -65,7 +74,9 @@ public class IconProvider { private static final String SYSTEM_STATE_SEPARATOR = " "; private static final String THEMED_ICON_MAP_FILE = "grayscale_icon_map"; private ArrayMap<String, ThemeData> mThemedIconMap; private static final Map<String, ThemeData> DISABLED_MAP = Collections.emptyMap(); private Map<String, ThemeData> mThemedIconMap; private final Context mContext; private final ComponentName mCalendar; Loading @@ -81,8 +92,15 @@ public class IconProvider { mClock = parseComponentOrNull(context, R.string.clock_component_name); if (!supportsIconTheme) { // Initialize an empty map if theming is not supported mThemedIconMap = new ArrayMap<>(); mThemedIconMap = DISABLED_MAP; } } /** * Enables or disables icon theme support */ public void setIconThemeSupported(boolean isSupported) { mThemedIconMap = isSupported ? null : DISABLED_MAP; } /** Loading @@ -97,15 +115,6 @@ public class IconProvider { } } /** * Loads the icon for the provided ActivityInfo such that it can be drawn directly * on the UI * @deprecated Use {@link #getIcon} */ public Drawable getIconForUI(ActivityInfo info, UserHandle user) { return getIcon(info); } /** * Loads the icon for the provided LauncherActivityInfo */ Loading Loading @@ -165,7 +174,7 @@ public class IconProvider { return icon; } private ArrayMap<String, ThemeData> getThemedIconMap() { private Map<String, ThemeData> getThemedIconMap() { if (mThemedIconMap != null) { return mThemedIconMap; } Loading Loading @@ -260,60 +269,99 @@ public class IconProvider { return Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1; } /** * Registers a callback to listen for calendar icon changes. * The callback receives the packageName for the calendar icon */ public static SafeCloseable registerIconChangeListener(Context context, BiConsumer<String, UserHandle> callback, Handler handler) { ComponentName calendar = parseComponentOrNull(context, R.string.calendar_component_name); ComponentName clock = parseComponentOrNull(context, R.string.clock_component_name); if (calendar == null && clock == null) { return () -> { }; private static ComponentName parseComponentOrNull(Context context, int resId) { String cn = context.getString(resId); return TextUtils.isEmpty(cn) ? null : ComponentName.unflattenFromString(cn); } BroadcastReceiver receiver = new DateTimeChangeReceiver(callback); final IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED); if (calendar != null) { filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_DATE_CHANGED); /** * 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"); } context.registerReceiver(receiver, filter, null, handler); return () -> context.unregisterReceiver(receiver); /** * Registers a callback to listen for various system dependent icon changes. */ public SafeCloseable registerIconChangeListener(IconChangeListener listener, Handler handler) { return new IconChangeReceiver(listener, handler); } private static class DateTimeChangeReceiver extends BroadcastReceiver { private class IconChangeReceiver extends BroadcastReceiver implements SafeCloseable { private final BiConsumer<String, UserHandle> mCallback; private final IconChangeListener mCallback; private String mIconState; DateTimeChangeReceiver(BiConsumer<String, UserHandle> callback) { IconChangeReceiver(IconChangeListener callback, Handler handler) { mCallback = callback; } mIconState = getSystemIconState(); @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { ComponentName clock = parseComponentOrNull(context, R.string.clock_component_name); if (clock != null) { mCallback.accept(clock.getPackageName(), Process.myUserHandle()); 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); } } ComponentName calendar = parseComponentOrNull(context, R.string.calendar_component_name); if (calendar != null) { @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.accept(calendar.getPackageName(), user); mCallback.onAppIconChanged(mCalendar.getPackageName(), user); } } break; case ACTION_OVERLAY_CHANGED: { String newState = getSystemIconState(); if (!mIconState.equals(newState)) { mIconState = newState; mCallback.onSystemIconStateChanged(mIconState); } break; } } } private static ComponentName parseComponentOrNull(Context context, int resId) { String cn = context.getString(resId); return TextUtils.isEmpty(cn) ? null : ComponentName.unflattenFromString(cn); @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); } } Loading
iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +1 −1 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ public class BaseIconFactory implements AutoCloseable { clear(); } protected BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { public BaseIconFactory(Context context, int fillResIconDpi, int iconBitmapSize) { this(context, fillResIconDpi, iconBitmapSize, false); } Loading
iconloaderlib/src/com/android/launcher3/icons/IconProvider.java +98 −50 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ 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; Loading @@ -32,6 +35,7 @@ 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; Loading @@ -45,7 +49,8 @@ import com.android.launcher3.util.SafeCloseable; import org.xmlpull.v1.XmlPullParser; import java.util.Calendar; import java.util.function.BiConsumer; import java.util.Collections; import java.util.Map; import java.util.function.Supplier; /** Loading @@ -53,6 +58,10 @@ import java.util.function.Supplier; */ 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"; Loading @@ -65,7 +74,9 @@ public class IconProvider { private static final String SYSTEM_STATE_SEPARATOR = " "; private static final String THEMED_ICON_MAP_FILE = "grayscale_icon_map"; private ArrayMap<String, ThemeData> mThemedIconMap; private static final Map<String, ThemeData> DISABLED_MAP = Collections.emptyMap(); private Map<String, ThemeData> mThemedIconMap; private final Context mContext; private final ComponentName mCalendar; Loading @@ -81,8 +92,15 @@ public class IconProvider { mClock = parseComponentOrNull(context, R.string.clock_component_name); if (!supportsIconTheme) { // Initialize an empty map if theming is not supported mThemedIconMap = new ArrayMap<>(); mThemedIconMap = DISABLED_MAP; } } /** * Enables or disables icon theme support */ public void setIconThemeSupported(boolean isSupported) { mThemedIconMap = isSupported ? null : DISABLED_MAP; } /** Loading @@ -97,15 +115,6 @@ public class IconProvider { } } /** * Loads the icon for the provided ActivityInfo such that it can be drawn directly * on the UI * @deprecated Use {@link #getIcon} */ public Drawable getIconForUI(ActivityInfo info, UserHandle user) { return getIcon(info); } /** * Loads the icon for the provided LauncherActivityInfo */ Loading Loading @@ -165,7 +174,7 @@ public class IconProvider { return icon; } private ArrayMap<String, ThemeData> getThemedIconMap() { private Map<String, ThemeData> getThemedIconMap() { if (mThemedIconMap != null) { return mThemedIconMap; } Loading Loading @@ -260,60 +269,99 @@ public class IconProvider { return Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1; } /** * Registers a callback to listen for calendar icon changes. * The callback receives the packageName for the calendar icon */ public static SafeCloseable registerIconChangeListener(Context context, BiConsumer<String, UserHandle> callback, Handler handler) { ComponentName calendar = parseComponentOrNull(context, R.string.calendar_component_name); ComponentName clock = parseComponentOrNull(context, R.string.clock_component_name); if (calendar == null && clock == null) { return () -> { }; private static ComponentName parseComponentOrNull(Context context, int resId) { String cn = context.getString(resId); return TextUtils.isEmpty(cn) ? null : ComponentName.unflattenFromString(cn); } BroadcastReceiver receiver = new DateTimeChangeReceiver(callback); final IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED); if (calendar != null) { filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_DATE_CHANGED); /** * 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"); } context.registerReceiver(receiver, filter, null, handler); return () -> context.unregisterReceiver(receiver); /** * Registers a callback to listen for various system dependent icon changes. */ public SafeCloseable registerIconChangeListener(IconChangeListener listener, Handler handler) { return new IconChangeReceiver(listener, handler); } private static class DateTimeChangeReceiver extends BroadcastReceiver { private class IconChangeReceiver extends BroadcastReceiver implements SafeCloseable { private final BiConsumer<String, UserHandle> mCallback; private final IconChangeListener mCallback; private String mIconState; DateTimeChangeReceiver(BiConsumer<String, UserHandle> callback) { IconChangeReceiver(IconChangeListener callback, Handler handler) { mCallback = callback; } mIconState = getSystemIconState(); @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { ComponentName clock = parseComponentOrNull(context, R.string.clock_component_name); if (clock != null) { mCallback.accept(clock.getPackageName(), Process.myUserHandle()); 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); } } ComponentName calendar = parseComponentOrNull(context, R.string.calendar_component_name); if (calendar != null) { @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.accept(calendar.getPackageName(), user); mCallback.onAppIconChanged(mCalendar.getPackageName(), user); } } break; case ACTION_OVERLAY_CHANGED: { String newState = getSystemIconState(); if (!mIconState.equals(newState)) { mIconState = newState; mCallback.onSystemIconStateChanged(mIconState); } break; } } } private static ComponentName parseComponentOrNull(Context context, int resId) { String cn = context.getString(resId); return TextUtils.isEmpty(cn) ? null : ComponentName.unflattenFromString(cn); @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); } }