Fix jank when switching themes
Turning overlays on and off takes time, it also doesn't allow us to have fine control over which view is using which theme. Lock screen colors are now driven by themes. Change-Id: Ie8860d00dbb0705ed76edf60a9d3030618dd21ca Fixes: 63751714 Test: Visual. Set wallpapers, unlock. Test: runtest -x packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java Test: runtest -x tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java Test: systrace
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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().
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -41,4 +41,6 @@
|
||||
<declare-styleable name="CarrierText">
|
||||
<attr name="allCaps" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<attr name="passwordStyle" format="reference" />
|
||||
</resources>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
<attr name="lightIconTheme" format="reference" />
|
||||
<attr name="darkIconTheme" format="reference" />
|
||||
<attr name="wallpaperTextColor" format="color" />
|
||||
<attr name="wallpaperTextColorSecondary" format="color" />
|
||||
<attr name="wallpaperTextColor" format="reference|color" />
|
||||
<attr name="wallpaperTextColorSecondary" format="reference|color" />
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -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,21 +298,26 @@
|
||||
<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:regularColor">?attr/wallpaperTextColor</item>
|
||||
<item name="*android:successColor">?attr/wallpaperTextColor</item>
|
||||
<item name="*android:errorColor">?android:attr/colorError</item>
|
||||
</style>
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.app.AlertDialog;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -470,7 +471,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected int getLayoutIdFor(SecurityMode securityMode) {
|
||||
@VisibleForTesting
|
||||
public int getLayoutIdFor(SecurityMode securityMode) {
|
||||
switch (securityMode) {
|
||||
case Pattern: return R.layout.keyguard_pattern_view;
|
||||
case PIN: return R.layout.keyguard_pin_view;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,12 +391,36 @@ 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -978,9 +978,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() {
|
||||
@@ -993,6 +990,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
final Context context = mContext;
|
||||
updateDisplaySize(); // populates mDisplayMetrics
|
||||
updateResources();
|
||||
updateTheme();
|
||||
|
||||
inflateStatusBarWindow(context);
|
||||
mStatusBarWindow.setService(this);
|
||||
@@ -1200,7 +1198,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));
|
||||
@@ -1305,14 +1302,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 {
|
||||
@@ -4566,24 +4552,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",
|
||||
@@ -4592,18 +4567,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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.TRUST_LISTENER" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package com.android.keyguard;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.UiThreadTest;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class KeyguardSecurityContainerTest extends SysuiTestCase {
|
||||
|
||||
@UiThreadTest
|
||||
@Test
|
||||
public void showSecurityScreen_canInflateAllModes() {
|
||||
KeyguardSecurityContainer keyguardSecurityContainer =
|
||||
new KeyguardSecurityContainer(getContext());
|
||||
|
||||
Context context = getContext();
|
||||
|
||||
for (int theme : new int[] {R.style.Theme_SystemUI, R.style.Theme_SystemUI_Light}) {
|
||||
context.setTheme(theme);
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
KeyguardSecurityModel.SecurityMode[] modes =
|
||||
KeyguardSecurityModel.SecurityMode.values();
|
||||
for (KeyguardSecurityModel.SecurityMode mode : modes) {
|
||||
final int resId = keyguardSecurityContainer.getLayoutIdFor(mode);
|
||||
if (resId == 0) {
|
||||
continue;
|
||||
}
|
||||
inflater.inflate(resId, null /* root */, false /* attach */);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user