diff options
18 files changed, 244 insertions, 192 deletions
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index 68cf5cd74431..477285e63f37 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -29,7 +29,9 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.Tonal; +import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Iterator; /** * Class to process wallpaper colors and generate a tonal palette based on them. @@ -44,7 +46,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener private static final String TAG = "ColorExtractor"; private final SparseArray<GradientColors[]> mGradientColors; - private final ArrayList<OnColorsChangedListener> mOnColorsChangedListeners; + private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners; private final Context mContext; private final ExtractionType mExtractionType; private WallpaperColors mSystemColors; @@ -167,8 +169,17 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener } protected void triggerColorsChanged(int which) { - for (OnColorsChangedListener listener: mOnColorsChangedListeners) { - listener.onColorsChanged(this, which); + ArrayList<WeakReference<OnColorsChangedListener>> references = + new ArrayList<>(mOnColorsChangedListeners); + final int size = references.size(); + for (int i = 0; i < size; i++) { + final WeakReference<OnColorsChangedListener> weakReference = references.get(i); + final OnColorsChangedListener listener = weakReference.get(); + if (listener == null) { + mOnColorsChangedListeners.remove(weakReference); + } else { + listener.onColorsChanged(this, which); + } } } @@ -187,11 +198,20 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener } public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) { - mOnColorsChangedListeners.add(listener); + mOnColorsChangedListeners.add(new WeakReference<>(listener)); } public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener listener) { - mOnColorsChangedListeners.remove(listener); + ArrayList<WeakReference<OnColorsChangedListener>> references = + new ArrayList<>(mOnColorsChangedListeners); + final int size = references.size(); + for (int i = 0; i < size; i++) { + final WeakReference<OnColorsChangedListener> weakReference = references.get(i); + if (weakReference.get() == listener) { + mOnColorsChangedListeners.remove(weakReference); + break; + } + } } public static class GradientColors { diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index e322acc5d731..47ffa5c5ff82 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -208,7 +208,7 @@ android:icon="@drawable/icon" android:process="com.android.systemui" android:supportsRtl="true" - android:theme="@style/systemui_theme" + android:theme="@style/Theme.SystemUI" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true"> <!-- Keep theme in sync with SystemUIApplication.onCreate(). diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml index b821e7e76c60..9fdb00eebe10 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml @@ -43,7 +43,7 @@ android:layout_height="wrap_content" android:layout_width="280dp" android:layout_gravity="center_horizontal" - android:theme="@style/PasswordTheme" + android:theme="?attr/passwordStyle" > <EditText android:id="@+id/passwordEntry" diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml index 802bd308d407..e2ce210efdcb 100644 --- a/packages/SystemUI/res-keyguard/values/attrs.xml +++ b/packages/SystemUI/res-keyguard/values/attrs.xml @@ -41,4 +41,6 @@ <declare-styleable name="CarrierText"> <attr name="allCaps" format="boolean" /> </declare-styleable> + + <attr name="passwordStyle" format="reference" /> </resources> diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml index ea867eed08b4..c6f942356833 100644 --- a/packages/SystemUI/res-keyguard/values/styles.xml +++ b/packages/SystemUI/res-keyguard/values/styles.xml @@ -60,7 +60,13 @@ <item name="android:layout_gravity">center_horizontal|bottom</item> </style> - <style name="PasswordTheme" parent="systemui_theme"> + <style name="PasswordTheme" parent="Theme.SystemUI"> + <item name="android:textColor">?attr/wallpaperTextColor</item> + <item name="android:colorControlNormal">?attr/wallpaperTextColor</item> + <item name="android:colorControlActivated">?attr/wallpaperTextColor</item> + </style> + + <style name="PasswordTheme.Light" parent="Theme.SystemUI.Light"> <item name="android:textColor">?attr/wallpaperTextColor</item> <item name="android:colorControlNormal">?attr/wallpaperTextColor</item> <item name="android:colorControlActivated">?attr/wallpaperTextColor</item> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index daed847c2ac3..27e067a9a5e0 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -16,7 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android"> - <style name="RecentsTheme" parent="RecentsBase"> + <style name="RecentsTheme" parent="@android:style/Theme.Material"> <!-- NoTitle --> <item name="android:windowNoTitle">true</item> <!-- Misc --> @@ -27,13 +27,6 @@ <item name="android:ambientShadowAlpha">0.35</item> </style> - <!-- OverlayManager might replace this style entirely, use RecentsTheme to set a property - that should exist in both light and dark versions of Recents --> - <style name="RecentsBase" parent="@android:style/Theme.Material"> - <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_dark</item> - <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_dark</item> - </style> - <!-- Recents theme --> <style name="RecentsTheme.Wallpaper"> <item name="android:windowBackground">@*android:color/transparent</item> @@ -41,8 +34,13 @@ <item name="android:windowShowWallpaper">true</item> <item name="android:windowDisablePreview">true</item> <item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item> - <item name="wallpaperTextColor">?android:attr/textColorPrimaryInverse</item> - <item name="wallpaperTextColorSecondary">?android:attr/textColorSecondaryInverse</item> + <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item> + </style> + + <style name="RecentsTheme.Wallpaper.Light"> + <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item> </style> <style name="ClearAllButtonDefaultMargins"> @@ -300,22 +298,27 @@ <style name="Animation.StatusBar"> </style> - <!-- Overlay manager may replace this theme --> - <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings" /> - - <style name="systemui_theme" parent="systemui_base"> + <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> <item name="lightIconTheme">@style/DualToneLightTheme</item> <item name="darkIconTheme">@style/DualToneDarkTheme</item> - <item name="wallpaperTextColor">?android:attr/textColorPrimaryInverse</item> - <item name="wallpaperTextColorSecondary">?android:attr/textColorSecondaryInverse</item> - <item name="android:colorControlHighlight">?android:attr/textColorSecondaryInverse</item> + <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item> + <item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item> <item name="*android:lockPatternStyle">@style/LockPatternStyle</item> + <item name="passwordStyle">@style/PasswordTheme</item> + </style> + + <style name="Theme.SystemUI.Light" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> + <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item> + <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item> + <item name="android:colorControlHighlight">@*android:color/primary_text_material_light</item> + <item name="passwordStyle">@style/PasswordTheme.Light</item> </style> <style name="LockPatternStyle"> - <item name="*android:regularColor">?android:attr/textColorPrimaryInverse</item> - <item name="*android:successColor">?android:attr/textColorPrimaryInverse</item> - <item name="*android:errorColor">?android:attr/colorError</item> + <item name="*android:regularColor">?attr/wallpaperTextColor</item> + <item name="*android:successColor">?attr/wallpaperTextColor</item> + <item name="*android:errorColor">?attr/colorError</item> </style> <!-- Overlay manager may replace this theme --> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index fe6eb4b5acfe..9f2dcd958211 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -116,7 +116,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv // Set the application theme that is inherited by all services. Note that setting the // application theme in the manifest does only work for activities. Keep this in sync with // the theme set there. - setTheme(R.style.systemui_theme); + setTheme(R.style.Theme_SystemUI); SystemUIFactory.createFromConfig(this); diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index f2ea6a683e95..c0550b5c52e6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -20,11 +20,11 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.TaskStackBuilder; +import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; @@ -41,12 +41,15 @@ import android.view.ViewTreeObserver.OnPreDrawListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; +import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.LatencyTracker; import com.android.systemui.DejankUtils; +import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent; import com.android.systemui.recents.events.activity.ConfigurationChangedEvent; @@ -100,7 +103,8 @@ import java.util.List; /** * The main Recents activity that is started from RecentsComponent. */ -public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener { +public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener, + ColorExtractor.OnColorsChangedListener { private final static String TAG = "RecentsActivity"; private final static boolean DEBUG = false; @@ -129,6 +133,10 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD private DozeTrigger mIterateTrigger; private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent(); + // Theme and colors + private SysuiColorExtractor mColorExtractor; + private boolean mUsingDarkText; + /** * A common Runnable to finish Recents by launching Home with an animation depending on the * last activity launch state. Generally we always launch home when we exit Recents rather than @@ -329,6 +337,14 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD mPackageMonitor = new RecentsPackageMonitor(); mPackageMonitor.register(this); + // Select theme based on wallpaper colors + mColorExtractor = Dependency.get(SysuiColorExtractor.class); + mColorExtractor.addOnColorsChangedListener(this); + mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK, + WallpaperManager.FLAG_SYSTEM, true).supportsDarkText(); + setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light + : R.style.RecentsTheme_Wallpaper); + // Set the Recents layout setContentView(R.layout.recents); takeKeyEvents(true); @@ -375,13 +391,37 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true)); MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY); - // Make sure we have the right gradient and we're listening for update events - mRecentsView.onStart(); + // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. + ColorExtractor.GradientColors systemColors = mColorExtractor.getColors( + ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true); + // We don't want to interpolate colors because we're defining the initial state. + // Gradient should be set/ready when you open "Recents". + mRecentsView.setScrimColors(systemColors, false); + // Notify of the next draw mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener); } @Override + public void onColorsChanged(ColorExtractor colorExtractor, int which) { + if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { + // Recents doesn't care about the wallpaper being visible or not, it always + // wants to scrim with wallpaper colors + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_SYSTEM, + ColorExtractor.TYPE_DARK, true /* ignoreVis */); + boolean darkText = colors.supportsDarkText(); + if (darkText != mUsingDarkText) { + mUsingDarkText = darkText; + setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light + : R.style.RecentsTheme_Wallpaper); + mRecentsView.reevaluateStyles(); + } + mRecentsView.setScrimColors(colors, true /* animated */); + } + } + + @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -483,12 +523,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD mLastConfig.orientation != newDeviceConfiguration.orientation, mLastConfig.densityDpi != newDeviceConfiguration.densityDpi, numStackTasks > 0)); - int configDiff = mLastConfig.updateFrom(newDeviceConfiguration); - - // Recreate activity if an overlay was enabled/disabled - if ((configDiff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) { - recreate(); - } + mLastConfig.updateFrom(newDeviceConfiguration); } @Override @@ -508,9 +543,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY); Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(false); - // We don't need to update the gradient when we're not visible - mRecentsView.onStop(); - if (!isChangingConfigurations()) { // Workaround for b/22542869, if the RecentsActivity is started again, but without going // through SystemUI, we need to reset the config launch flags to ensure that we do not diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index fd37b17f3cd0..8e094813257c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -21,13 +21,12 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import android.animation.Animator; import android.animation.ObjectAnimator; import android.app.ActivityOptions.OnAnimationStartedListener; -import android.app.WallpaperColors; -import android.app.WallpaperManager; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.util.ArraySet; import android.util.AttributeSet; @@ -43,12 +42,12 @@ import android.widget.FrameLayout; import android.widget.TextView; import com.android.internal.colorextraction.ColorExtractor; +import com.android.internal.colorextraction.drawable.GradientDrawable; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.Dependency; +import com.android.settingslib.Utils; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsActivity; import com.android.systemui.recents.RecentsActivityLaunchState; @@ -83,8 +82,6 @@ import com.android.systemui.stackdivider.WindowManagerProxy; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.phone.ScrimController; -import com.android.internal.colorextraction.drawable.GradientDrawable; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -93,7 +90,7 @@ import java.util.List; * This view is the the top level layout that contains TaskStacks (which are laid out according * to their SpaceNode bounds. */ -public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsChangedListener { +public class RecentsView extends FrameLayout { private static final String TAG = "RecentsView"; @@ -107,6 +104,9 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC private TaskStackView mTaskStackView; private TextView mStackActionButton; private TextView mEmptyView; + private final float mStackButtonShadowRadius; + private final PointF mStackButtonShadowDistance; + private final int mStackButtonShadowColor; private boolean mAwaitingFirstLayout = true; private boolean mLastTaskLaunchedWasFreeform; @@ -117,7 +117,6 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC private float mBusynessFactor; private GradientDrawable mBackgroundScrim; - private final SysuiColorExtractor mColorExtractor; private Animator mBackgroundScrimAnimator; private RecentsTransitionHelper mTransitionHelper; @@ -148,29 +147,51 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f); mBackgroundScrim = new GradientDrawable(context); mBackgroundScrim.setCallback(this); - mColorExtractor = Dependency.get(SysuiColorExtractor.class); - LayoutInflater inflater = LayoutInflater.from(context); + boolean usingDarkText = Color.luminance( + Utils.getColorAttr(mContext, R.attr.wallpaperTextColor)) < 0.5f; + LayoutInflater inflater = LayoutInflater.from(context); mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false); addView(mEmptyView); - boolean usingDarkText = - Color.luminance(mEmptyView.getTextColors().getDefaultColor()) < 0.5f; if (RecentsDebugFlags.Static.EnableStackActionButton) { + if (mStackActionButton != null) { + removeView(mStackActionButton); + } mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button, this, false); - mStackActionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - EventBus.getDefault().send(new DismissAllTaskViewsEvent()); - } - }); - // Disable black shadow if text color is already dark. + mStackActionButton.setOnClickListener( + v -> EventBus.getDefault().send(new DismissAllTaskViewsEvent())); + + mStackButtonShadowRadius = mStackActionButton.getShadowRadius(); + mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(), + mStackActionButton.getShadowDy()); + mStackButtonShadowColor = mStackActionButton.getShadowColor(); + addView(mStackActionButton); + } + + reevaluateStyles(); + } + + public void reevaluateStyles() { + int textColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor); + boolean usingDarkText = Color.luminance(textColor) < 0.5f; + + mEmptyView.setTextColor(textColor); + mEmptyView.setCompoundDrawableTintList(new ColorStateList(new int[][]{ + {android.R.attr.state_enabled}}, new int[]{textColor})); + + if (mStackActionButton != null) { + mStackActionButton.setTextColor(textColor); + // Enable/disable shadow if text color is already dark. if (usingDarkText) { mStackActionButton.setShadowLayer(0, 0, 0, 0); + } else { + mStackActionButton.setShadowLayer(mStackButtonShadowRadius, + mStackButtonShadowDistance.x, mStackButtonShadowDistance.y, + mStackButtonShadowColor); } - addView(mStackActionButton); } // Let's also require dark status and nav bars if the text is dark @@ -369,6 +390,16 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC } } + /** + * Set the color of the scrim. + * + * @param scrimColors Colors to use. + * @param animated Interpolate colors if true. + */ + public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) { + mBackgroundScrim.setColors(scrimColors, animated); + } + @Override protected void onAttachedToWindow() { EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1); @@ -888,29 +919,4 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC mTaskStackView.dump(innerPrefix, writer); } } - - @Override - public void onColorsChanged(ColorExtractor colorExtractor, int which) { - if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { - // Recents doesn't care about the wallpaper being visible or not, it always - // wants to scrim with wallpaper colors - mBackgroundScrim.setColors( - mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, - ColorExtractor.TYPE_DARK, true)); - } - } - - public void onStart() { - mColorExtractor.addOnColorsChangedListener(this); - // Getting system scrim colors ignoring wallpaper visibility since it should never be grey. - ColorExtractor.GradientColors systemColors = mColorExtractor.getColors( - ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true); - // We don't want to interpolate colors because we're defining the initial state. - // Gradient should be set/ready when you open "Recents". - mBackgroundScrim.setColors(systemColors, false); - } - - public void onStop() { - mColorExtractor.removeOnColorsChangedListener(this); - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java index 543666407fb9..d7c6443a6c3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; +import android.annotation.ColorInt; import android.content.Context; import android.content.res.Configuration; import android.util.AttributeSet; @@ -46,6 +47,10 @@ public class DismissView extends StackScrollerDecorView { mDismissButton = (DismissViewButton) findContentView(); } + public void setTextColor(@ColorInt int color) { + mDismissButton.setTextColor(color); + } + public void setOnButtonClickListener(OnClickListener listener) { mContent.setOnClickListener(listener); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java index 92b0890a5d2b..58adde269758 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; +import android.annotation.ColorInt; import android.content.Context; import android.content.res.Configuration; import android.util.AttributeSet; @@ -45,6 +46,10 @@ public class EmptyShadeView extends StackScrollerDecorView { return findViewById(R.id.no_notifications); } + public void setTextColor(@ColorInt int color) { + mEmptyText.setTextColor(color); + } + @Override protected void onFinishInflate() { super.onFinishInflate(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index e90d1c1e27b5..81896f16ae17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -975,9 +975,6 @@ public class StatusBar extends SystemUI implements DemoMode, Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this); Dependency.get(ConfigurationController.class).addCallback(this); - - // Make sure that we're using the correct theme - onOverlayChanged(); } protected void createIconController() { @@ -990,6 +987,7 @@ public class StatusBar extends SystemUI implements DemoMode, final Context context = mContext; updateDisplaySize(); // populates mDisplayMetrics updateResources(); + updateTheme(); inflateStatusBarWindow(context); mStatusBarWindow.setService(this); @@ -1197,7 +1195,6 @@ public class StatusBar extends SystemUI implements DemoMode, }); } - PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); if (!pm.isScreenOn()) { mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); @@ -1302,14 +1299,14 @@ public class StatusBar extends SystemUI implements DemoMode, reevaluateStyles(); } - public void onOverlayChanged() { + private void reinflateViews() { reevaluateStyles(); // Clock and bottom icons mNotificationPanel.onOverlayChanged(); - + // The status bar on the keyguard is a special layout. + mKeyguardStatusBar.onOverlayChanged(); // Recreate Indication controller because internal references changed - // TODO: unregister callbacks before recreating mKeyguardIndicationController = SystemUIFactory.getInstance().createKeyguardIndicationController(mContext, mStatusBarWindow.findViewById(R.id.keyguard_indication_area), @@ -2857,17 +2854,6 @@ public class StatusBar extends SystemUI implements DemoMode, updateTheme(); } - public boolean isUsingDarkText() { - OverlayInfo themeInfo = null; - try { - themeInfo = mOverlayManager.getOverlayInfo("com.android.systemui.theme.lightwallpaper", - mCurrentUserId); - } catch (RemoteException e) { - e.printStackTrace(); - } - return themeInfo != null && themeInfo.isEnabled(); - } - public boolean isUsingDarkTheme() { OverlayInfo themeInfo = null; try { @@ -4562,24 +4548,13 @@ public class StatusBar extends SystemUI implements DemoMode, * Switches theme from light to dark and vice-versa. */ private void updateTheme() { + final boolean inflated = mStackScroller != null; - int which; - if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { - which = WallpaperManager.FLAG_LOCK; - } else { - which = WallpaperManager.FLAG_SYSTEM; - } - - // Gradient defines if text color should be light or dark. - final boolean useDarkText = mColorExtractor.getColors(which, true /* ignoreVisibility */) - .supportsDarkText(); - // And wallpaper defines if QS should be light or dark. + // The system wallpaper defines if QS should be light or dark. WallpaperColors systemColors = mColorExtractor .getWallpaperColors(WallpaperManager.FLAG_SYSTEM); final boolean useDarkTheme = systemColors != null && (systemColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0; - - // Enable/disable dark UI. if (isUsingDarkTheme() != useDarkTheme) { try { mOverlayManager.setEnabled("com.android.systemui.theme.dark", @@ -4588,18 +4563,33 @@ public class StatusBar extends SystemUI implements DemoMode, Log.w(TAG, "Can't change theme", e); } } - // Enable/disable dark text overlay. - if (isUsingDarkText() != useDarkText) { - try { - mOverlayManager.setEnabled("com.android.systemui.theme.lightwallpaper", - useDarkText, mCurrentUserId); - } catch (RemoteException e) { - Log.w(TAG, "Can't change theme", e); + + // Lock wallpaper defines the color of the majority of the views, hence we'll use it + // to set our default theme. + final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true + /* ignoreVisibility */).supportsDarkText(); + final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI; + if (mContext.getThemeResId() != themeResId) { + mContext.setTheme(themeResId); + if (inflated) { + reinflateViews(); } } - // Make sure we have the correct navbar/statusbar colors. - mStatusBarWindowManager.setKeyguardDark(useDarkText); + if (inflated) { + int which; + if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { + which = WallpaperManager.FLAG_LOCK; + } else { + which = WallpaperManager.FLAG_SYSTEM; + } + final boolean useDarkText = mColorExtractor.getColors(which, + true /* ignoreVisibility */).supportsDarkText(); + mStackScroller.updateDecorViews(useDarkText); + + // Make sure we have the correct navbar/statusbar colors. + mStatusBarWindowManager.setKeyguardDark(useDarkText); + } } private void updateDozingState() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 42cebe2632bb..4bbe895da7ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -23,6 +23,7 @@ import android.animation.PropertyValuesHolder; import android.animation.TimeAnimator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.annotation.ColorInt; import android.annotation.FloatRange; import android.annotation.Nullable; import android.content.Context; @@ -44,6 +45,7 @@ import android.util.FloatProperty; import android.util.Log; import android.util.Pair; import android.util.Property; +import android.view.ContextThemeWrapper; import android.view.InputDevice; import android.view.MotionEvent; import android.view.VelocityTracker; @@ -61,6 +63,7 @@ import android.widget.ScrollView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settingslib.Utils; import com.android.systemui.ExpandHelper; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -363,6 +366,7 @@ public class NotificationStackScrollLayout extends ViewGroup return object.getBackgroundFadeAmount(); } }; + private boolean mUsingLightTheme; private boolean mQsExpanded; private boolean mForwardScrollable; private boolean mBackwardScrollable; @@ -3653,6 +3657,23 @@ public class NotificationStackScrollLayout extends ViewGroup mTmpSortedChildren.clear(); } + /** + * Update colors of "dismiss" and "empty shade" views. + * + * @param lightTheme True if light theme should be used. + */ + public void updateDecorViews(boolean lightTheme) { + if (lightTheme == mUsingLightTheme) { + return; + } + mUsingLightTheme = lightTheme; + Context context = new ContextThemeWrapper(mContext, + lightTheme ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI); + final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor); + mDismissView.setTextColor(textColor); + mEmptyShadeView.setTextColor(textColor); + } + public void goToFullShade(long delay) { if (mDismissView != null) { mDismissView.setInvisible(); diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk b/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk deleted file mode 100644 index 4782a166146b..000000000000 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_RRO_THEME := SysuiLightWallpaperTheme -LOCAL_CERTIFICATE := platform - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res - -LOCAL_PACKAGE_NAME := SysuiLightWallpaperThemeOverlay - -include $(BUILD_RRO_PACKAGE) diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml deleted file mode 100644 index 0a8749c64ea2..000000000000 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.systemui.theme.lightwallpaper" - android:versionCode="1" - android:versionName="1.0"> - <overlay android:targetPackage="com.android.systemui" android:priority="2"/> - - <application android:label="@string/sysui_overlay_light" android:hasCode="false"/> -</manifest> diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml deleted file mode 100644 index acc3d16610ec..000000000000 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/** - * Copyright (c) 2017, 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - - <string name="sysui_overlay_light">Light</string> - -</resources> - diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml deleted file mode 100644 index 53912b50df00..000000000000 --- a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> - <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item> - <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item> - </style> - - <style name="RecentsBase" parent="@android:style/Theme.Material"> - <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item> - <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item> - </style> -</resources>
\ No newline at end of file diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java index 0060901578cd..cb6a83d2644b 100644 --- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java +++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java @@ -16,12 +16,14 @@ package com.android.internal.colorextraction; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.mockito.Mockito.any; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Color; @@ -29,7 +31,6 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.internal.colorextraction.types.ExtractionType; import com.android.internal.colorextraction.types.Tonal; @@ -78,10 +79,10 @@ public class ColorExtractorTest { ExtractionType type = (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark, outGradientColorsExtraDark) -> { - outGradientColorsNormal.set(colorsExpectedNormal); - outGradientColorsDark.set(colorsExpectedDark); - outGradientColorsExtraDark.set(colorsExpectedExtraDark); - }; + outGradientColorsNormal.set(colorsExpectedNormal); + outGradientColorsDark.set(colorsExpectedDark); + outGradientColorsExtraDark.set(colorsExpectedExtraDark); + }; ColorExtractor extractor = new ColorExtractor(mContext, type); GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, @@ -92,4 +93,22 @@ public class ColorExtractorTest { colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_EXTRA_DARK); assertEquals("Extracted colors not being used!", colors, colorsExpectedExtraDark); } + + @Test + public void addOnColorsChangedListener_invokesListener() { + ColorExtractor.OnColorsChangedListener mockedListeners = + mock(ColorExtractor.OnColorsChangedListener.class); + ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext)); + extractor.addOnColorsChangedListener(mockedListeners); + + extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null), + WallpaperManager.FLAG_LOCK); + verify(mockedListeners, times(1)).onColorsChanged(any(), + eq(WallpaperManager.FLAG_LOCK)); + + extractor.removeOnColorsChangedListener(mockedListeners); + extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null), + WallpaperManager.FLAG_LOCK); + verifyNoMoreInteractions(mockedListeners); + } } |