Loading packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java +29 −7 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ */ package com.android.systemui.plugins; import android.graphics.Bitmap; import android.graphics.Paint.Style; import android.view.View; Loading @@ -21,13 +22,30 @@ import com.android.systemui.plugins.annotations.ProvidesInterface; import java.util.TimeZone; /** * This plugin is used to replace main clock in keyguard. * Plugin used to replace main clock in keyguard. */ @ProvidesInterface(action = ClockPlugin.ACTION, version = ClockPlugin.VERSION) public interface ClockPlugin extends Plugin { String ACTION = "com.android.systemui.action.PLUGIN_CLOCK"; int VERSION = 1; int VERSION = 2; /** * Get the name of the clock face. * * This name should not be translated. */ String getName(); /** * Get the title of the clock face to be shown in the picker app. */ String getTitle(); /** * Get thumbnail of clock face to be shown in the picker app. */ Bitmap getThumbnail(); /** * Get clock view. Loading Loading @@ -61,19 +79,23 @@ public interface ClockPlugin extends Plugin { */ default void setColorPalette(boolean supportsDarkText, int[] colors) {} /** * Notifies that time tick alarm from doze service fired. */ default void dozeTimeTick() {} /** * Set the amount (ratio) that the device has transitioned to doze. * @param darkAmount Amount of transition to doze: 1f for doze and 0f for awake. */ default void setDarkAmount(float darkAmount) {} /** * Notifies that time tick alarm from doze service fired. * * Implement this method instead of registering a broadcast listener for TIME_TICK. */ default void onTimeTick() {} /** * Notifies that the time zone has changed. * * Implement this method instead of registering a broadcast listener for TIME_ZONE_CHANGED. */ default void onTimeZoneChanged(TimeZone timeZone) {} Loading packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +1 −1 Original line number Diff line number Diff line Loading @@ -279,7 +279,7 @@ public class KeyguardClockSwitch extends RelativeLayout { */ public void dozeTimeTick() { if (mClockPlugin != null) { mClockPlugin.dozeTimeTick(); mClockPlugin.onTimeTick(); } } Loading packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java +44 −13 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.keyguard.clock; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; Loading @@ -30,6 +33,16 @@ import java.util.TimeZone; */ public class BubbleClockController implements ClockPlugin { /** * Resources used to get title and thumbnail. */ private final Resources mResources; /** * LayoutInflater used to inflate custom clock views. */ private final LayoutInflater mLayoutInflater; /** * Custom clock shown on AOD screen and behind stack scroller on lock. */ Loading @@ -48,38 +61,56 @@ public class BubbleClockController implements ClockPlugin { */ private CrossFadeDarkController mDarkController; private BubbleClockController() { } /** * Create a BubbleClockController instance. * * @param layoutInflater Inflater used to inflate custom clock views. */ public static BubbleClockController build(LayoutInflater layoutInflater) { BubbleClockController controller = new BubbleClockController(); controller.createViews(layoutInflater); return controller; public BubbleClockController(Resources res, LayoutInflater inflater) { mResources = res; mLayoutInflater = inflater; } private void createViews(LayoutInflater layoutInflater) { mView = layoutInflater.inflate(R.layout.bubble_clock, null); private void createViews() { mView = mLayoutInflater.inflate(R.layout.bubble_clock, null); mDigitalClock = (TextClock) mView.findViewById(R.id.digital_clock); mAnalogClock = (ImageClock) mView.findViewById(R.id.analog_clock); mLockClockContainer = layoutInflater.inflate(R.layout.digital_clock, null); mLockClockContainer = mLayoutInflater.inflate(R.layout.digital_clock, null); mLockClock = (TextClock) mLockClockContainer.findViewById(R.id.lock_screen_clock); mLockClock.setVisibility(View.GONE); mDarkController = new CrossFadeDarkController(mDigitalClock, mLockClock); } @Override public String getName() { return "bubble"; } @Override public String getTitle() { return mResources.getString(R.string.clock_title_bubble); } @Override public Bitmap getThumbnail() { return BitmapFactory.decodeResource(mResources, R.drawable.bubble_thumbnail); } @Override public View getView() { if (mLockClockContainer == null) { createViews(); } return mLockClockContainer; } @Override public View getBigClockView() { if (mView == null) { createViews(); } return mView; } Loading @@ -103,13 +134,13 @@ public class BubbleClockController implements ClockPlugin { } @Override public void dozeTimeTick() { mAnalogClock.onTimeChanged(); public void setDarkAmount(float darkAmount) { mDarkController.setDarkAmount(darkAmount); } @Override public void setDarkAmount(float darkAmount) { mDarkController.setDarkAmount(darkAmount); public void onTimeTick() { mAnalogClock.onTimeChanged(); } @Override Loading packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +113 −86 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.os.Handler; Loading @@ -31,6 +30,7 @@ import android.os.Looper; import android.provider.Settings; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.MeasureSpec; Loading @@ -39,17 +39,19 @@ import android.view.ViewGroup; import androidx.annotation.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManager.DockEventListener; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.util.InjectionInflationController; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Supplier; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import javax.inject.Inject; import javax.inject.Singleton; Loading @@ -67,23 +69,42 @@ public final class ClockManager { /** * Map from expected value stored in settings to supplier of custom clock face. */ private final Map<String, Supplier<ClockPlugin>> mClocks = new ArrayMap<>(); private final Map<String, ClockPlugin> mClocks = new ArrayMap<>(); @Nullable private ClockPlugin mCurrentClock; private final LayoutInflater mLayoutInflater; private final ContentResolver mContentResolver; private final SettingsWrapper mSettingsWrapper; private final Handler mMainHandler = new Handler(Looper.getMainLooper()); /** * Observe settings changes to know when to switch the clock face. */ private final ContentObserver mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { new ContentObserver(mMainHandler) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); reload(); } }; private final PluginListener<ClockPlugin> mClockPluginListener = new PluginListener<ClockPlugin>() { @Override public void onPluginConnected(ClockPlugin plugin, Context pluginContext) { addClockPlugin(plugin); reload(); } @Override public void onPluginDisconnected(ClockPlugin plugin) { removeClockPlugin(plugin); reload(); } }; private final PluginManager mPluginManager; /** * Observe changes to dock state to know when to switch the clock face. */ Loading Loading @@ -111,59 +132,29 @@ public final class ClockManager { @Inject public ClockManager(Context context, InjectionInflationController injectionInflater, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor) { this(context, injectionInflater, dockManager, colorExtractor, context.getContentResolver(), new SettingsWrapper(context.getContentResolver())); PluginManager pluginManager, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor) { this(context, injectionInflater, pluginManager, dockManager, colorExtractor, context.getContentResolver(), new SettingsWrapper(context.getContentResolver())); } ClockManager(Context context, InjectionInflationController injectionInflater, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor, ContentResolver contentResolver, SettingsWrapper settingsWrapper) { PluginManager pluginManager, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor, ContentResolver contentResolver, SettingsWrapper settingsWrapper) { mPluginManager = pluginManager; mDockManager = dockManager; mColorExtractor = colorExtractor; mContentResolver = contentResolver; mSettingsWrapper = settingsWrapper; Resources res = context.getResources(); mClockInfos.add(ClockInfo.builder() .setName(DEFAULT_CLOCK_ID) .setTitle(res.getString(R.string.clock_title_default)) .setId(DEFAULT_CLOCK_ID) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.default_thumbnail)) .setPreview(() -> getClockPreview(DEFAULT_CLOCK_ID)) .build()); mClockInfos.add(ClockInfo.builder() .setName("bubble") .setTitle(res.getString(R.string.clock_title_bubble)) .setId(BubbleClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.bubble_thumbnail)) .setPreview(() -> getClockPreview(BubbleClockController.class.getName())) .build()); mClockInfos.add(ClockInfo.builder() .setName("stretch") .setTitle(res.getString(R.string.clock_title_stretch)) .setId(StretchAnalogClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.stretch_thumbnail)) .setPreview(() -> getClockPreview(StretchAnalogClockController.class.getName())) .build()); mClockInfos.add(ClockInfo.builder() .setName("type") .setTitle(res.getString(R.string.clock_title_type)) .setId(TypeClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.type_thumbnail)) .setPreview(() -> getClockPreview(TypeClockController.class.getName())) .build()); LayoutInflater layoutInflater = injectionInflater.injectable(LayoutInflater.from(context)); mClocks.put(DEFAULT_CLOCK_ID, () -> DefaultClockController.build(layoutInflater)); mClocks.put(BubbleClockController.class.getName(), () -> BubbleClockController.build(layoutInflater)); mClocks.put(StretchAnalogClockController.class.getName(), () -> StretchAnalogClockController.build(layoutInflater)); mClocks.put(TypeClockController.class.getName(), () -> TypeClockController.build(layoutInflater)); mLayoutInflater = layoutInflater; addClockPlugin(new DefaultClockController(res, layoutInflater)); addClockPlugin(new BubbleClockController(res, layoutInflater)); addClockPlugin(new StretchAnalogClockController(res, layoutInflater)); addClockPlugin(new TypeClockController(res, layoutInflater)); // Store the size of the display for generation of clock preview. DisplayMetrics dm = res.getDisplayMetrics(); Loading Loading @@ -218,6 +209,29 @@ public final class ClockManager { return mContentObserver; } private void addClockPlugin(ClockPlugin plugin) { final String id = plugin.getClass().getName(); mClocks.put(plugin.getClass().getName(), plugin); mClockInfos.add(ClockInfo.builder() .setName(plugin.getName()) .setTitle(plugin.getTitle()) .setId(id) .setThumbnail(() -> plugin.getThumbnail()) .setPreview(() -> getClockPreview(id)) .build()); } private void removeClockPlugin(ClockPlugin plugin) { final String id = plugin.getClass().getName(); mClocks.remove(id); for (int i = 0; i < mClockInfos.size(); i++) { if (id.equals(mClockInfos.get(i).getId())) { mClockInfos.remove(i); break; } } } /** * Generate a realistic preview of a clock face. * @param clockId ID of clock to use for preview, should be obtained from {@link getClockInfos}. Loading @@ -225,12 +239,14 @@ public final class ClockManager { */ @Nullable private Bitmap getClockPreview(String clockId) { FutureTask<Bitmap> task = new FutureTask<>(new Callable<Bitmap>() { @Override public Bitmap call() { Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888); Supplier<ClockPlugin> supplier = mClocks.get(clockId); if (supplier == null) { ClockPlugin plugin = mClocks.get(clockId); if (plugin == null) { return null; } ClockPlugin plugin = supplier.get(); // Use the big clock view for the preview View clockView = plugin.getBigClockView(); Loading @@ -242,10 +258,10 @@ public final class ClockManager { plugin.setDarkAmount(1f); plugin.setTextColor(Color.WHITE); ColorExtractor.GradientColors colors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true); ColorExtractor.GradientColors colors = mColorExtractor.getColors( WallpaperManager.FLAG_LOCK, true); plugin.setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); plugin.dozeTimeTick(); plugin.onTimeTick(); // Draw clock view hierarchy to canvas. Canvas canvas = new Canvas(bitmap); Loading @@ -257,6 +273,21 @@ public final class ClockManager { clockView.draw(canvas); return bitmap; } }); if (Looper.myLooper() == Looper.getMainLooper()) { task.run(); } else { mMainHandler.post(task); } try { return task.get(); } catch (Exception e) { Log.e(TAG, "Error completing task", e); return null; } } private void dispatchVisibilityAggregated(View view, boolean isVisible) { // Similar to View.dispatchVisibilityAggregated implementation. Loading Loading @@ -285,6 +316,7 @@ public final class ClockManager { } private void register() { mPluginManager.addPluginListener(mClockPluginListener, ClockPlugin.class, true); mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE), false, mContentObserver); Loading @@ -297,6 +329,7 @@ public final class ClockManager { } private void unregister() { mPluginManager.removePluginListener(mClockPluginListener); mContentResolver.unregisterContentObserver(mContentObserver); if (mDockManager != null) { mDockManager.removeListener(mDockEventListener); Loading @@ -317,21 +350,15 @@ public final class ClockManager { if (mIsDocked) { final String name = mSettingsWrapper.getDockedClockFace(); if (name != null) { Supplier<ClockPlugin> supplier = mClocks.get(name); if (supplier != null) { plugin = supplier.get(); plugin = mClocks.get(name); if (plugin != null) { return plugin; } } } } final String name = mSettingsWrapper.getLockScreenCustomClockFace(); if (name != null) { Supplier<ClockPlugin> supplier = mClocks.get(name); if (supplier != null) { plugin = supplier.get(); } plugin = mClocks.get(name); } return plugin; } Loading packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java +42 −9 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.keyguard.clock; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; Loading @@ -30,35 +33,62 @@ import java.util.TimeZone; */ public class DefaultClockController implements ClockPlugin { /** * Resources used to get title and thumbnail. */ private final Resources mResources; /** * LayoutInflater used to inflate custom clock views. */ private final LayoutInflater mLayoutInflater; /** * Root view of preview. */ private View mView; /** * Text clock in preview view hierarchy. */ private TextView mTextTime; private TextView mTextDate; private DefaultClockController() {} /** * Date showing below time in preview view hierarchy. */ private TextView mTextDate; /** * Create a DefaultClockController instance. * * @param inflater Inflater used to inflate custom clock views. */ public static DefaultClockController build(LayoutInflater inflater) { DefaultClockController controller = new DefaultClockController(); controller.createViews(inflater); return controller; public DefaultClockController(Resources res, LayoutInflater inflater) { mResources = res; mLayoutInflater = inflater; } private void createViews(LayoutInflater inflater) { mView = inflater.inflate(R.layout.default_clock_preview, null); private void createViews() { mView = mLayoutInflater.inflate(R.layout.default_clock_preview, null); mTextTime = mView.findViewById(R.id.time); mTextDate = mView.findViewById(R.id.date); } @Override public String getName() { return "default"; } @Override public String getTitle() { return mResources.getString(R.string.clock_title_default); } @Override public Bitmap getThumbnail() { return BitmapFactory.decodeResource(mResources, R.drawable.default_thumbnail); } @Override public View getView() { return null; Loading @@ -66,6 +96,9 @@ public class DefaultClockController implements ClockPlugin { @Override public View getBigClockView() { if (mView == null) { createViews(); } return mView; } Loading @@ -82,7 +115,7 @@ public class DefaultClockController implements ClockPlugin { public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {} @Override public void dozeTimeTick() { public void onTimeTick() { } @Override Loading Loading
packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java +29 −7 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ */ package com.android.systemui.plugins; import android.graphics.Bitmap; import android.graphics.Paint.Style; import android.view.View; Loading @@ -21,13 +22,30 @@ import com.android.systemui.plugins.annotations.ProvidesInterface; import java.util.TimeZone; /** * This plugin is used to replace main clock in keyguard. * Plugin used to replace main clock in keyguard. */ @ProvidesInterface(action = ClockPlugin.ACTION, version = ClockPlugin.VERSION) public interface ClockPlugin extends Plugin { String ACTION = "com.android.systemui.action.PLUGIN_CLOCK"; int VERSION = 1; int VERSION = 2; /** * Get the name of the clock face. * * This name should not be translated. */ String getName(); /** * Get the title of the clock face to be shown in the picker app. */ String getTitle(); /** * Get thumbnail of clock face to be shown in the picker app. */ Bitmap getThumbnail(); /** * Get clock view. Loading Loading @@ -61,19 +79,23 @@ public interface ClockPlugin extends Plugin { */ default void setColorPalette(boolean supportsDarkText, int[] colors) {} /** * Notifies that time tick alarm from doze service fired. */ default void dozeTimeTick() {} /** * Set the amount (ratio) that the device has transitioned to doze. * @param darkAmount Amount of transition to doze: 1f for doze and 0f for awake. */ default void setDarkAmount(float darkAmount) {} /** * Notifies that time tick alarm from doze service fired. * * Implement this method instead of registering a broadcast listener for TIME_TICK. */ default void onTimeTick() {} /** * Notifies that the time zone has changed. * * Implement this method instead of registering a broadcast listener for TIME_ZONE_CHANGED. */ default void onTimeZoneChanged(TimeZone timeZone) {} Loading
packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +1 −1 Original line number Diff line number Diff line Loading @@ -279,7 +279,7 @@ public class KeyguardClockSwitch extends RelativeLayout { */ public void dozeTimeTick() { if (mClockPlugin != null) { mClockPlugin.dozeTimeTick(); mClockPlugin.onTimeTick(); } } Loading
packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java +44 −13 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.keyguard.clock; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; Loading @@ -30,6 +33,16 @@ import java.util.TimeZone; */ public class BubbleClockController implements ClockPlugin { /** * Resources used to get title and thumbnail. */ private final Resources mResources; /** * LayoutInflater used to inflate custom clock views. */ private final LayoutInflater mLayoutInflater; /** * Custom clock shown on AOD screen and behind stack scroller on lock. */ Loading @@ -48,38 +61,56 @@ public class BubbleClockController implements ClockPlugin { */ private CrossFadeDarkController mDarkController; private BubbleClockController() { } /** * Create a BubbleClockController instance. * * @param layoutInflater Inflater used to inflate custom clock views. */ public static BubbleClockController build(LayoutInflater layoutInflater) { BubbleClockController controller = new BubbleClockController(); controller.createViews(layoutInflater); return controller; public BubbleClockController(Resources res, LayoutInflater inflater) { mResources = res; mLayoutInflater = inflater; } private void createViews(LayoutInflater layoutInflater) { mView = layoutInflater.inflate(R.layout.bubble_clock, null); private void createViews() { mView = mLayoutInflater.inflate(R.layout.bubble_clock, null); mDigitalClock = (TextClock) mView.findViewById(R.id.digital_clock); mAnalogClock = (ImageClock) mView.findViewById(R.id.analog_clock); mLockClockContainer = layoutInflater.inflate(R.layout.digital_clock, null); mLockClockContainer = mLayoutInflater.inflate(R.layout.digital_clock, null); mLockClock = (TextClock) mLockClockContainer.findViewById(R.id.lock_screen_clock); mLockClock.setVisibility(View.GONE); mDarkController = new CrossFadeDarkController(mDigitalClock, mLockClock); } @Override public String getName() { return "bubble"; } @Override public String getTitle() { return mResources.getString(R.string.clock_title_bubble); } @Override public Bitmap getThumbnail() { return BitmapFactory.decodeResource(mResources, R.drawable.bubble_thumbnail); } @Override public View getView() { if (mLockClockContainer == null) { createViews(); } return mLockClockContainer; } @Override public View getBigClockView() { if (mView == null) { createViews(); } return mView; } Loading @@ -103,13 +134,13 @@ public class BubbleClockController implements ClockPlugin { } @Override public void dozeTimeTick() { mAnalogClock.onTimeChanged(); public void setDarkAmount(float darkAmount) { mDarkController.setDarkAmount(darkAmount); } @Override public void setDarkAmount(float darkAmount) { mDarkController.setDarkAmount(darkAmount); public void onTimeTick() { mAnalogClock.onTimeChanged(); } @Override Loading
packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +113 −86 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.os.Handler; Loading @@ -31,6 +30,7 @@ import android.os.Looper; import android.provider.Settings; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.MeasureSpec; Loading @@ -39,17 +39,19 @@ import android.view.ViewGroup; import androidx.annotation.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManager.DockEventListener; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.util.InjectionInflationController; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Supplier; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import javax.inject.Inject; import javax.inject.Singleton; Loading @@ -67,23 +69,42 @@ public final class ClockManager { /** * Map from expected value stored in settings to supplier of custom clock face. */ private final Map<String, Supplier<ClockPlugin>> mClocks = new ArrayMap<>(); private final Map<String, ClockPlugin> mClocks = new ArrayMap<>(); @Nullable private ClockPlugin mCurrentClock; private final LayoutInflater mLayoutInflater; private final ContentResolver mContentResolver; private final SettingsWrapper mSettingsWrapper; private final Handler mMainHandler = new Handler(Looper.getMainLooper()); /** * Observe settings changes to know when to switch the clock face. */ private final ContentObserver mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { new ContentObserver(mMainHandler) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); reload(); } }; private final PluginListener<ClockPlugin> mClockPluginListener = new PluginListener<ClockPlugin>() { @Override public void onPluginConnected(ClockPlugin plugin, Context pluginContext) { addClockPlugin(plugin); reload(); } @Override public void onPluginDisconnected(ClockPlugin plugin) { removeClockPlugin(plugin); reload(); } }; private final PluginManager mPluginManager; /** * Observe changes to dock state to know when to switch the clock face. */ Loading Loading @@ -111,59 +132,29 @@ public final class ClockManager { @Inject public ClockManager(Context context, InjectionInflationController injectionInflater, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor) { this(context, injectionInflater, dockManager, colorExtractor, context.getContentResolver(), new SettingsWrapper(context.getContentResolver())); PluginManager pluginManager, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor) { this(context, injectionInflater, pluginManager, dockManager, colorExtractor, context.getContentResolver(), new SettingsWrapper(context.getContentResolver())); } ClockManager(Context context, InjectionInflationController injectionInflater, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor, ContentResolver contentResolver, SettingsWrapper settingsWrapper) { PluginManager pluginManager, @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor, ContentResolver contentResolver, SettingsWrapper settingsWrapper) { mPluginManager = pluginManager; mDockManager = dockManager; mColorExtractor = colorExtractor; mContentResolver = contentResolver; mSettingsWrapper = settingsWrapper; Resources res = context.getResources(); mClockInfos.add(ClockInfo.builder() .setName(DEFAULT_CLOCK_ID) .setTitle(res.getString(R.string.clock_title_default)) .setId(DEFAULT_CLOCK_ID) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.default_thumbnail)) .setPreview(() -> getClockPreview(DEFAULT_CLOCK_ID)) .build()); mClockInfos.add(ClockInfo.builder() .setName("bubble") .setTitle(res.getString(R.string.clock_title_bubble)) .setId(BubbleClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.bubble_thumbnail)) .setPreview(() -> getClockPreview(BubbleClockController.class.getName())) .build()); mClockInfos.add(ClockInfo.builder() .setName("stretch") .setTitle(res.getString(R.string.clock_title_stretch)) .setId(StretchAnalogClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.stretch_thumbnail)) .setPreview(() -> getClockPreview(StretchAnalogClockController.class.getName())) .build()); mClockInfos.add(ClockInfo.builder() .setName("type") .setTitle(res.getString(R.string.clock_title_type)) .setId(TypeClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.type_thumbnail)) .setPreview(() -> getClockPreview(TypeClockController.class.getName())) .build()); LayoutInflater layoutInflater = injectionInflater.injectable(LayoutInflater.from(context)); mClocks.put(DEFAULT_CLOCK_ID, () -> DefaultClockController.build(layoutInflater)); mClocks.put(BubbleClockController.class.getName(), () -> BubbleClockController.build(layoutInflater)); mClocks.put(StretchAnalogClockController.class.getName(), () -> StretchAnalogClockController.build(layoutInflater)); mClocks.put(TypeClockController.class.getName(), () -> TypeClockController.build(layoutInflater)); mLayoutInflater = layoutInflater; addClockPlugin(new DefaultClockController(res, layoutInflater)); addClockPlugin(new BubbleClockController(res, layoutInflater)); addClockPlugin(new StretchAnalogClockController(res, layoutInflater)); addClockPlugin(new TypeClockController(res, layoutInflater)); // Store the size of the display for generation of clock preview. DisplayMetrics dm = res.getDisplayMetrics(); Loading Loading @@ -218,6 +209,29 @@ public final class ClockManager { return mContentObserver; } private void addClockPlugin(ClockPlugin plugin) { final String id = plugin.getClass().getName(); mClocks.put(plugin.getClass().getName(), plugin); mClockInfos.add(ClockInfo.builder() .setName(plugin.getName()) .setTitle(plugin.getTitle()) .setId(id) .setThumbnail(() -> plugin.getThumbnail()) .setPreview(() -> getClockPreview(id)) .build()); } private void removeClockPlugin(ClockPlugin plugin) { final String id = plugin.getClass().getName(); mClocks.remove(id); for (int i = 0; i < mClockInfos.size(); i++) { if (id.equals(mClockInfos.get(i).getId())) { mClockInfos.remove(i); break; } } } /** * Generate a realistic preview of a clock face. * @param clockId ID of clock to use for preview, should be obtained from {@link getClockInfos}. Loading @@ -225,12 +239,14 @@ public final class ClockManager { */ @Nullable private Bitmap getClockPreview(String clockId) { FutureTask<Bitmap> task = new FutureTask<>(new Callable<Bitmap>() { @Override public Bitmap call() { Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888); Supplier<ClockPlugin> supplier = mClocks.get(clockId); if (supplier == null) { ClockPlugin plugin = mClocks.get(clockId); if (plugin == null) { return null; } ClockPlugin plugin = supplier.get(); // Use the big clock view for the preview View clockView = plugin.getBigClockView(); Loading @@ -242,10 +258,10 @@ public final class ClockManager { plugin.setDarkAmount(1f); plugin.setTextColor(Color.WHITE); ColorExtractor.GradientColors colors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true); ColorExtractor.GradientColors colors = mColorExtractor.getColors( WallpaperManager.FLAG_LOCK, true); plugin.setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); plugin.dozeTimeTick(); plugin.onTimeTick(); // Draw clock view hierarchy to canvas. Canvas canvas = new Canvas(bitmap); Loading @@ -257,6 +273,21 @@ public final class ClockManager { clockView.draw(canvas); return bitmap; } }); if (Looper.myLooper() == Looper.getMainLooper()) { task.run(); } else { mMainHandler.post(task); } try { return task.get(); } catch (Exception e) { Log.e(TAG, "Error completing task", e); return null; } } private void dispatchVisibilityAggregated(View view, boolean isVisible) { // Similar to View.dispatchVisibilityAggregated implementation. Loading Loading @@ -285,6 +316,7 @@ public final class ClockManager { } private void register() { mPluginManager.addPluginListener(mClockPluginListener, ClockPlugin.class, true); mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE), false, mContentObserver); Loading @@ -297,6 +329,7 @@ public final class ClockManager { } private void unregister() { mPluginManager.removePluginListener(mClockPluginListener); mContentResolver.unregisterContentObserver(mContentObserver); if (mDockManager != null) { mDockManager.removeListener(mDockEventListener); Loading @@ -317,21 +350,15 @@ public final class ClockManager { if (mIsDocked) { final String name = mSettingsWrapper.getDockedClockFace(); if (name != null) { Supplier<ClockPlugin> supplier = mClocks.get(name); if (supplier != null) { plugin = supplier.get(); plugin = mClocks.get(name); if (plugin != null) { return plugin; } } } } final String name = mSettingsWrapper.getLockScreenCustomClockFace(); if (name != null) { Supplier<ClockPlugin> supplier = mClocks.get(name); if (supplier != null) { plugin = supplier.get(); } plugin = mClocks.get(name); } return plugin; } Loading
packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java +42 −9 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.keyguard.clock; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; Loading @@ -30,35 +33,62 @@ import java.util.TimeZone; */ public class DefaultClockController implements ClockPlugin { /** * Resources used to get title and thumbnail. */ private final Resources mResources; /** * LayoutInflater used to inflate custom clock views. */ private final LayoutInflater mLayoutInflater; /** * Root view of preview. */ private View mView; /** * Text clock in preview view hierarchy. */ private TextView mTextTime; private TextView mTextDate; private DefaultClockController() {} /** * Date showing below time in preview view hierarchy. */ private TextView mTextDate; /** * Create a DefaultClockController instance. * * @param inflater Inflater used to inflate custom clock views. */ public static DefaultClockController build(LayoutInflater inflater) { DefaultClockController controller = new DefaultClockController(); controller.createViews(inflater); return controller; public DefaultClockController(Resources res, LayoutInflater inflater) { mResources = res; mLayoutInflater = inflater; } private void createViews(LayoutInflater inflater) { mView = inflater.inflate(R.layout.default_clock_preview, null); private void createViews() { mView = mLayoutInflater.inflate(R.layout.default_clock_preview, null); mTextTime = mView.findViewById(R.id.time); mTextDate = mView.findViewById(R.id.date); } @Override public String getName() { return "default"; } @Override public String getTitle() { return mResources.getString(R.string.clock_title_default); } @Override public Bitmap getThumbnail() { return BitmapFactory.decodeResource(mResources, R.drawable.default_thumbnail); } @Override public View getView() { return null; Loading @@ -66,6 +96,9 @@ public class DefaultClockController implements ClockPlugin { @Override public View getBigClockView() { if (mView == null) { createViews(); } return mView; } Loading @@ -82,7 +115,7 @@ public class DefaultClockController implements ClockPlugin { public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {} @Override public void dozeTimeTick() { public void onTimeTick() { } @Override Loading