Merge changes Ia0ce4c06,I68fbe1a7,Ibc19ae82,If9f3e28c into udc-qpr-dev
* changes: [Decor] Add DebugRoundedCornerDelegate [Decor] Split RoundedCornerResDelegate into impl and interface [Decor] Make ScreenDecorations.mDebug non-final [Decor] Remove unused properties and Tunable
This commit is contained in:
@@ -49,8 +49,11 @@ import kotlin.math.floor
|
||||
* When the HWC of the device supports Composition.DISPLAY_DECORATION, we use this layer to draw
|
||||
* screen decorations.
|
||||
*/
|
||||
class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDecorationSupport) :
|
||||
DisplayCutoutBaseView(context) {
|
||||
class ScreenDecorHwcLayer(
|
||||
context: Context,
|
||||
displayDecorationSupport: DisplayDecorationSupport,
|
||||
private val debug: Boolean,
|
||||
) : DisplayCutoutBaseView(context) {
|
||||
val colorMode: Int
|
||||
private val useInvertedAlphaColor: Boolean
|
||||
private val color: Int
|
||||
@@ -74,7 +77,7 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
throw IllegalArgumentException("Attempting to use unsupported mode " +
|
||||
"${PixelFormat.formatToString(displayDecorationSupport.format)}")
|
||||
}
|
||||
if (DEBUG_COLOR) {
|
||||
if (debug) {
|
||||
color = Color.GREEN
|
||||
bgColor = Color.TRANSPARENT
|
||||
colorMode = ActivityInfo.COLOR_MODE_DEFAULT
|
||||
@@ -106,7 +109,7 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
parent.requestTransparentRegion(this)
|
||||
if (!DEBUG_COLOR) {
|
||||
if (!debug) {
|
||||
viewRootImpl.setDisplayDecoration(true)
|
||||
}
|
||||
|
||||
@@ -143,12 +146,12 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
override fun gatherTransparentRegion(region: Region?): Boolean {
|
||||
region?.let {
|
||||
calculateTransparentRect()
|
||||
if (DEBUG_COLOR) {
|
||||
if (debug) {
|
||||
// Since we're going to draw a rectangle where the layer would
|
||||
// normally be transparent, treat the transparent region as
|
||||
// empty. We still want this method to be called, though, so
|
||||
// that it calculates the transparent rect at the right time
|
||||
// to match !DEBUG_COLOR.
|
||||
// to match ![debug]
|
||||
region.setEmpty()
|
||||
} else {
|
||||
region.op(transparentRect, Region.Op.INTERSECT)
|
||||
@@ -421,8 +424,4 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
|
||||
ipw.println("roundedCornerBottomSize=$roundedCornerBottomSize")
|
||||
ipw.decreaseIndent()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DEBUG_COLOR = ScreenDecorations.DEBUG_COLOR
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.decor.CutoutDecorProviderFactory;
|
||||
import com.android.systemui.decor.DebugRoundedCornerDelegate;
|
||||
import com.android.systemui.decor.DecorProvider;
|
||||
import com.android.systemui.decor.DecorProviderFactory;
|
||||
import com.android.systemui.decor.DecorProviderKt;
|
||||
@@ -78,14 +79,12 @@ import com.android.systemui.decor.FaceScanningProviderFactory;
|
||||
import com.android.systemui.decor.OverlayWindow;
|
||||
import com.android.systemui.decor.PrivacyDotDecorProviderFactory;
|
||||
import com.android.systemui.decor.RoundedCornerDecorProviderFactory;
|
||||
import com.android.systemui.decor.RoundedCornerResDelegate;
|
||||
import com.android.systemui.decor.RoundedCornerResDelegateImpl;
|
||||
import com.android.systemui.log.ScreenDecorationsLogger;
|
||||
import com.android.systemui.qs.SettingObserver;
|
||||
import com.android.systemui.settings.DisplayTracker;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.events.PrivacyDotViewController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
import com.android.systemui.util.concurrency.ThreadFactory;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
@@ -105,19 +104,17 @@ import javax.inject.Inject;
|
||||
* for antialiasing and emulation purposes.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
private static final boolean DEBUG = false;
|
||||
public class ScreenDecorations implements CoreStartable, Dumpable {
|
||||
private static final boolean DEBUG_LOGGING = false;
|
||||
private static final String TAG = "ScreenDecorations";
|
||||
|
||||
public static final String SIZE = "sysui_rounded_size";
|
||||
public static final String PADDING = "sysui_rounded_content_padding";
|
||||
// Provide a way for factory to disable ScreenDecorations to run the Display tests.
|
||||
private static final boolean DEBUG_DISABLE_SCREEN_DECORATIONS =
|
||||
SystemProperties.getBoolean("debug.disable_screen_decorations", false);
|
||||
private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS =
|
||||
SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
|
||||
private static final boolean VERBOSE = false;
|
||||
static final boolean DEBUG_COLOR = DEBUG_SCREENSHOT_ROUNDED_CORNERS;
|
||||
private boolean mDebug = DEBUG_SCREENSHOT_ROUNDED_CORNERS;
|
||||
private int mDebugColor = Color.RED;
|
||||
|
||||
private static final int[] DISPLAY_CUTOUT_IDS = {
|
||||
R.id.display_cutout,
|
||||
@@ -134,7 +131,6 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
protected boolean mIsRegistered;
|
||||
private final Context mContext;
|
||||
private final Executor mMainExecutor;
|
||||
private final TunerService mTunerService;
|
||||
private final SecureSettings mSecureSettings;
|
||||
@VisibleForTesting
|
||||
DisplayTracker.Callback mDisplayListener;
|
||||
@@ -147,9 +143,13 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
public final int mFaceScanningViewId;
|
||||
|
||||
@VisibleForTesting
|
||||
protected RoundedCornerResDelegate mRoundedCornerResDelegate;
|
||||
protected RoundedCornerResDelegateImpl mRoundedCornerResDelegate;
|
||||
@VisibleForTesting
|
||||
protected DecorProviderFactory mRoundedCornerFactory;
|
||||
@VisibleForTesting
|
||||
protected DebugRoundedCornerDelegate mDebugRoundedCornerDelegate =
|
||||
new DebugRoundedCornerDelegate();
|
||||
protected DecorProviderFactory mDebugRoundedCornerFactory;
|
||||
private CutoutDecorProviderFactory mCutoutFactory;
|
||||
private int mProviderRefreshToken = 0;
|
||||
@VisibleForTesting
|
||||
@@ -315,7 +315,6 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
public ScreenDecorations(Context context,
|
||||
@Main Executor mainExecutor,
|
||||
SecureSettings secureSettings,
|
||||
TunerService tunerService,
|
||||
UserTracker userTracker,
|
||||
DisplayTracker displayTracker,
|
||||
PrivacyDotViewController dotViewController,
|
||||
@@ -327,7 +326,6 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
mContext = context;
|
||||
mMainExecutor = mainExecutor;
|
||||
mSecureSettings = secureSettings;
|
||||
mTunerService = tunerService;
|
||||
mUserTracker = userTracker;
|
||||
mDisplayTracker = displayTracker;
|
||||
mDotViewController = dotViewController;
|
||||
@@ -365,16 +363,47 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
mAuthController.addCallback(mAuthControllerCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the value of {@link ScreenDecorations#mDebug}. This operation is heavyweight, since
|
||||
* it requires essentially re-init-ing this screen decorations process with the debug
|
||||
* information taken into account.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected void setDebug(boolean debug) {
|
||||
if (mDebug == debug) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDebug = debug;
|
||||
if (!mDebug) {
|
||||
mDebugRoundedCornerDelegate.removeDebugState();
|
||||
}
|
||||
|
||||
mExecutor.execute(() -> {
|
||||
// Re-trigger all of the screen decorations setup here so that the debug values
|
||||
// can be picked up
|
||||
removeAllOverlays();
|
||||
removeHwcOverlay();
|
||||
startOnScreenDecorationsThread();
|
||||
updateColorInversionDefault();
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isPrivacyDotEnabled() {
|
||||
return mDotFactory.getHasProviders();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private List<DecorProvider> getProviders(boolean hasHwLayer) {
|
||||
@VisibleForTesting
|
||||
protected List<DecorProvider> getProviders(boolean hasHwLayer) {
|
||||
List<DecorProvider> decorProviders = new ArrayList<>(mDotFactory.getProviders());
|
||||
decorProviders.addAll(mFaceScanningFactory.getProviders());
|
||||
if (!hasHwLayer) {
|
||||
decorProviders.addAll(mRoundedCornerFactory.getProviders());
|
||||
if (mDebug && mDebugRoundedCornerFactory.getHasProviders()) {
|
||||
decorProviders.addAll(mDebugRoundedCornerFactory.getProviders());
|
||||
} else {
|
||||
decorProviders.addAll(mRoundedCornerFactory.getProviders());
|
||||
}
|
||||
decorProviders.addAll(mCutoutFactory.getProviders());
|
||||
}
|
||||
return decorProviders;
|
||||
@@ -416,11 +445,13 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
mDisplayMode = mDisplayInfo.getMode();
|
||||
mDisplayUniqueId = mDisplayInfo.uniqueId;
|
||||
mDisplayCutout = mDisplayInfo.displayCutout;
|
||||
mRoundedCornerResDelegate = new RoundedCornerResDelegate(mContext.getResources(),
|
||||
mDisplayUniqueId);
|
||||
mRoundedCornerResDelegate =
|
||||
new RoundedCornerResDelegateImpl(mContext.getResources(), mDisplayUniqueId);
|
||||
mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(
|
||||
getPhysicalPixelDisplaySizeRatio());
|
||||
mRoundedCornerFactory = new RoundedCornerDecorProviderFactory(mRoundedCornerResDelegate);
|
||||
mDebugRoundedCornerFactory =
|
||||
new RoundedCornerDecorProviderFactory(mDebugRoundedCornerDelegate);
|
||||
mCutoutFactory = getCutoutFactory();
|
||||
mHwcScreenDecorationSupport = mContext.getDisplay().getDisplayDecorationSupport();
|
||||
updateHwLayerRoundedCornerDrawable();
|
||||
@@ -444,15 +475,12 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
// - we are trying to redraw. This because WM resized our window and told us to.
|
||||
// - the config change has been dispatched, so WM is no longer deferring layout.
|
||||
mPendingConfigChange = true;
|
||||
if (DEBUG) {
|
||||
if (mRotation != newRotation) {
|
||||
Log.i(TAG, "Rotation changed, deferring " + newRotation
|
||||
+ ", staying at " + mRotation);
|
||||
}
|
||||
if (displayModeChanged(mDisplayMode, newDisplayMode)) {
|
||||
Log.i(TAG, "Resolution changed, deferring " + newDisplayMode
|
||||
+ ", staying at " + mDisplayMode);
|
||||
}
|
||||
if (mRotation != newRotation) {
|
||||
mLogger.logRotationChangeDeferred(mRotation, newRotation);
|
||||
}
|
||||
if (displayModeChanged(mDisplayMode, newDisplayMode)) {
|
||||
mLogger.logDisplayModeChanged(
|
||||
newDisplayMode.getModeId(), mDisplayMode.getModeId());
|
||||
}
|
||||
|
||||
if (mOverlays != null) {
|
||||
@@ -608,12 +636,6 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
return;
|
||||
}
|
||||
|
||||
mMainExecutor.execute(() -> {
|
||||
Trace.beginSection("ScreenDecorations#addTunable");
|
||||
mTunerService.addTunable(this, SIZE);
|
||||
Trace.endSection();
|
||||
});
|
||||
|
||||
// Watch color inversion and invert the overlay as needed.
|
||||
if (mColorInversionSetting == null) {
|
||||
mColorInversionSetting = new SettingObserver(mSecureSettings, mHandler,
|
||||
@@ -632,12 +654,6 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
mUserTracker.addCallback(mUserChangedCallback, mExecutor);
|
||||
mIsRegistered = true;
|
||||
} else {
|
||||
mMainExecutor.execute(() -> {
|
||||
Trace.beginSection("ScreenDecorations#removeTunable");
|
||||
mTunerService.removeTunable(this);
|
||||
Trace.endSection();
|
||||
});
|
||||
|
||||
if (mColorInversionSetting != null) {
|
||||
mColorInversionSetting.setListening(false);
|
||||
}
|
||||
@@ -777,7 +793,8 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
}
|
||||
mScreenDecorHwcWindow = (ViewGroup) LayoutInflater.from(mContext).inflate(
|
||||
R.layout.screen_decor_hwc_layer, null);
|
||||
mScreenDecorHwcLayer = new ScreenDecorHwcLayer(mContext, mHwcScreenDecorationSupport);
|
||||
mScreenDecorHwcLayer =
|
||||
new ScreenDecorHwcLayer(mContext, mHwcScreenDecorationSupport, mDebug);
|
||||
mScreenDecorHwcWindow.addView(mScreenDecorHwcLayer, new FrameLayout.LayoutParams(
|
||||
MATCH_PARENT, MATCH_PARENT, Gravity.TOP | Gravity.START));
|
||||
mWindowManager.addView(mScreenDecorHwcWindow, getHwcWindowLayoutParams());
|
||||
@@ -825,7 +842,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
lp.height = MATCH_PARENT;
|
||||
lp.setTitle("ScreenDecorHwcOverlay");
|
||||
lp.gravity = Gravity.TOP | Gravity.START;
|
||||
if (!DEBUG_COLOR) {
|
||||
if (!mDebug) {
|
||||
lp.setColorMode(ActivityInfo.COLOR_MODE_A8);
|
||||
}
|
||||
return lp;
|
||||
@@ -933,19 +950,42 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
new UserTracker.Callback() {
|
||||
@Override
|
||||
public void onUserChanged(int newUser, @NonNull Context userContext) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "UserSwitched newUserId=" + newUser);
|
||||
}
|
||||
mLogger.logUserSwitched(newUser);
|
||||
// update color inversion setting to the new user
|
||||
mColorInversionSetting.setUserId(newUser);
|
||||
updateColorInversion(mColorInversionSetting.getValue());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Use the current value of {@link ScreenDecorations#mColorInversionSetting} and passes it
|
||||
* to {@link ScreenDecorations#updateColorInversion}
|
||||
*/
|
||||
private void updateColorInversionDefault() {
|
||||
int inversion = 0;
|
||||
if (mColorInversionSetting != null) {
|
||||
inversion = mColorInversionSetting.getValue();
|
||||
}
|
||||
|
||||
updateColorInversion(inversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tint color of screen decoration assets. Defaults to Color.BLACK. In the case of
|
||||
* a color inversion being set, use Color.WHITE (which inverts to black).
|
||||
*
|
||||
* When {@link ScreenDecorations#mDebug} is {@code true}, this value is updated to use
|
||||
* {@link ScreenDecorations#mDebugColor}, and does not handle inversion.
|
||||
*
|
||||
* @param colorsInvertedValue if non-zero, assume that colors are inverted, and use Color.WHITE
|
||||
* for screen decoration tint
|
||||
*/
|
||||
private void updateColorInversion(int colorsInvertedValue) {
|
||||
mTintColor = colorsInvertedValue != 0 ? Color.WHITE : Color.BLACK;
|
||||
if (DEBUG_COLOR) {
|
||||
mTintColor = Color.RED;
|
||||
if (mDebug) {
|
||||
mTintColor = mDebugColor;
|
||||
mDebugRoundedCornerDelegate.setColor(mTintColor);
|
||||
//TODO(b/285941724): update the hwc layer color here too (or disable it in debug mode)
|
||||
}
|
||||
|
||||
updateOverlayProviderViews(new Integer[] {
|
||||
@@ -986,7 +1026,9 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
int oldRotation = mRotation;
|
||||
mPendingConfigChange = false;
|
||||
updateConfiguration();
|
||||
if (DEBUG) Log.i(TAG, "onConfigChanged from rot " + oldRotation + " to " + mRotation);
|
||||
if (oldRotation != mRotation) {
|
||||
mLogger.logRotationChanged(oldRotation, mRotation);
|
||||
}
|
||||
setupDecorations();
|
||||
if (mOverlays != null) {
|
||||
// Updating the layout params ensures that ViewRootImpl will call relayoutWindow(),
|
||||
@@ -1016,6 +1058,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
if (DEBUG_DISABLE_SCREEN_DECORATIONS) {
|
||||
return;
|
||||
}
|
||||
ipw.println("mDebug:" + mDebug);
|
||||
|
||||
ipw.println("mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
|
||||
ipw.println("shouldOptimizeOverlayVisibility:" + shouldOptimizeVisibility());
|
||||
@@ -1071,6 +1114,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
}
|
||||
}
|
||||
mRoundedCornerResDelegate.dump(pw, args);
|
||||
mDebugRoundedCornerDelegate.dump(pw);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -1093,8 +1137,9 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
mRotation = newRotation;
|
||||
mDisplayMode = newMod;
|
||||
mDisplayCutout = newCutout;
|
||||
mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(
|
||||
getPhysicalPixelDisplaySizeRatio());
|
||||
float ratio = getPhysicalPixelDisplaySizeRatio();
|
||||
mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(ratio);
|
||||
mDebugRoundedCornerDelegate.setPhysicalPixelDisplaySizeRatio(ratio);
|
||||
if (mScreenDecorHwcLayer != null) {
|
||||
mScreenDecorHwcLayer.pendingConfigChange = false;
|
||||
mScreenDecorHwcLayer.updateConfiguration(mDisplayUniqueId);
|
||||
@@ -1117,7 +1162,8 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
}
|
||||
|
||||
private boolean hasRoundedCorners() {
|
||||
return mRoundedCornerFactory.getHasProviders();
|
||||
return mRoundedCornerFactory.getHasProviders()
|
||||
|| mDebugRoundedCornerFactory.getHasProviders();
|
||||
}
|
||||
|
||||
private boolean shouldOptimizeVisibility() {
|
||||
@@ -1170,41 +1216,17 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (DEBUG_DISABLE_SCREEN_DECORATIONS) {
|
||||
Log.i(TAG, "ScreenDecorations is disabled");
|
||||
return;
|
||||
}
|
||||
mExecutor.execute(() -> {
|
||||
if (mOverlays == null || !SIZE.equals(key)) {
|
||||
return;
|
||||
}
|
||||
Trace.beginSection("ScreenDecorations#onTuningChanged");
|
||||
try {
|
||||
final int sizeFactor = Integer.parseInt(newValue);
|
||||
mRoundedCornerResDelegate.setTuningSizeFactor(sizeFactor);
|
||||
} catch (NumberFormatException e) {
|
||||
mRoundedCornerResDelegate.setTuningSizeFactor(null);
|
||||
}
|
||||
updateOverlayProviderViews(new Integer[] {
|
||||
R.id.rounded_corner_top_left,
|
||||
R.id.rounded_corner_top_right,
|
||||
R.id.rounded_corner_bottom_left,
|
||||
R.id.rounded_corner_bottom_right
|
||||
});
|
||||
updateHwLayerRoundedCornerExistAndSize();
|
||||
Trace.endSection();
|
||||
});
|
||||
}
|
||||
|
||||
private void updateHwLayerRoundedCornerDrawable() {
|
||||
if (mScreenDecorHwcLayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Drawable topDrawable = mRoundedCornerResDelegate.getTopRoundedDrawable();
|
||||
final Drawable bottomDrawable = mRoundedCornerResDelegate.getBottomRoundedDrawable();
|
||||
Drawable topDrawable = mRoundedCornerResDelegate.getTopRoundedDrawable();
|
||||
Drawable bottomDrawable = mRoundedCornerResDelegate.getBottomRoundedDrawable();
|
||||
if (mDebug && (mDebugRoundedCornerFactory.getHasProviders())) {
|
||||
topDrawable = mDebugRoundedCornerDelegate.getTopRoundedDrawable();
|
||||
bottomDrawable = mDebugRoundedCornerDelegate.getBottomRoundedDrawable();
|
||||
}
|
||||
|
||||
if (topDrawable == null || bottomDrawable == null) {
|
||||
return;
|
||||
@@ -1216,11 +1238,19 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
if (mScreenDecorHwcLayer == null) {
|
||||
return;
|
||||
}
|
||||
mScreenDecorHwcLayer.updateRoundedCornerExistenceAndSize(
|
||||
mRoundedCornerResDelegate.getHasTop(),
|
||||
mRoundedCornerResDelegate.getHasBottom(),
|
||||
mRoundedCornerResDelegate.getTopRoundedSize().getWidth(),
|
||||
mRoundedCornerResDelegate.getBottomRoundedSize().getWidth());
|
||||
if (mDebug && mDebugRoundedCornerFactory.getHasProviders()) {
|
||||
mScreenDecorHwcLayer.updateRoundedCornerExistenceAndSize(
|
||||
mDebugRoundedCornerDelegate.getHasTop(),
|
||||
mDebugRoundedCornerDelegate.getHasBottom(),
|
||||
mDebugRoundedCornerDelegate.getTopRoundedSize().getWidth(),
|
||||
mDebugRoundedCornerDelegate.getBottomRoundedSize().getWidth());
|
||||
} else {
|
||||
mScreenDecorHwcLayer.updateRoundedCornerExistenceAndSize(
|
||||
mRoundedCornerResDelegate.getHasTop(),
|
||||
mRoundedCornerResDelegate.getHasBottom(),
|
||||
mRoundedCornerResDelegate.getTopRoundedSize().getWidth(),
|
||||
mRoundedCornerResDelegate.getBottomRoundedSize().getWidth());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -1247,7 +1277,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
|
||||
paint.setColor(mColor);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
if (DEBUG) {
|
||||
if (DEBUG_LOGGING) {
|
||||
getViewTreeObserver().addOnDrawListener(() -> Log.i(TAG,
|
||||
getWindowTitleByPos(pos) + " drawn in rot " + mRotation));
|
||||
}
|
||||
@@ -1440,7 +1470,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
mView.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
if (mTargetRotation == mRotation
|
||||
&& !displayModeChanged(mDisplayMode, mTargetDisplayMode)) {
|
||||
if (DEBUG) {
|
||||
if (DEBUG_LOGGING) {
|
||||
final String title = mPosition < 0 ? "ScreenDecorHwcLayer"
|
||||
: getWindowTitleByPos(mPosition);
|
||||
Log.i(TAG, title + " already in target rot "
|
||||
@@ -1456,7 +1486,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
// This changes the window attributes - we need to restart the traversal for them to
|
||||
// take effect.
|
||||
updateConfiguration();
|
||||
if (DEBUG) {
|
||||
if (DEBUG_LOGGING) {
|
||||
final String title = mPosition < 0 ? "ScreenDecorHwcLayer"
|
||||
: getWindowTitleByPos(mPosition);
|
||||
Log.i(TAG, title
|
||||
@@ -1491,7 +1521,7 @@ public class ScreenDecorations implements CoreStartable, Tunable , Dumpable {
|
||||
final Display.Mode displayMode = mDisplayInfo.getMode();
|
||||
if ((displayRotation != mRotation || displayModeChanged(mDisplayMode, displayMode))
|
||||
&& !mPendingConfigChange) {
|
||||
if (DEBUG) {
|
||||
if (DEBUG_LOGGING) {
|
||||
if (displayRotation != mRotation) {
|
||||
Log.i(TAG, "Drawing rot " + mRotation + ", but display is at rot "
|
||||
+ displayRotation + ". Restarting draw");
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.systemui.decor
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Path
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.Size
|
||||
import java.io.PrintWriter
|
||||
|
||||
/**
|
||||
* Rounded corner delegate that handles incoming debug commands and can convert them to path
|
||||
* drawables to be shown instead of the system-defined rounded corners.
|
||||
*
|
||||
* These debug corners are expected to supersede the system-defined corners
|
||||
*/
|
||||
class DebugRoundedCornerDelegate : RoundedCornerResDelegate {
|
||||
override var hasTop: Boolean = false
|
||||
private set
|
||||
override var topRoundedDrawable: Drawable? = null
|
||||
private set
|
||||
override var topRoundedSize: Size = Size(0, 0)
|
||||
private set
|
||||
|
||||
override var hasBottom: Boolean = false
|
||||
private set
|
||||
override var bottomRoundedDrawable: Drawable? = null
|
||||
private set
|
||||
override var bottomRoundedSize: Size = Size(0, 0)
|
||||
private set
|
||||
|
||||
override var physicalPixelDisplaySizeRatio: Float = 1f
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
field = value
|
||||
reloadMeasures()
|
||||
}
|
||||
|
||||
var color: Int = Color.RED
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
|
||||
field = value
|
||||
paint.color = field
|
||||
}
|
||||
|
||||
var paint =
|
||||
Paint().apply {
|
||||
color = Color.RED
|
||||
style = Paint.Style.FILL
|
||||
}
|
||||
|
||||
override fun updateDisplayUniqueId(newDisplayUniqueId: String?, newReloadToken: Int?) {
|
||||
// nop -- debug corners draw the same on every display
|
||||
}
|
||||
|
||||
fun applyNewDebugCorners(
|
||||
topCorner: DebugRoundedCornerModel,
|
||||
bottomCorner: DebugRoundedCornerModel,
|
||||
) {
|
||||
hasTop = true
|
||||
topRoundedDrawable = topCorner.toPathDrawable(paint)
|
||||
topRoundedSize = topCorner.size()
|
||||
|
||||
hasBottom = true
|
||||
bottomRoundedDrawable = bottomCorner.toPathDrawable(paint)
|
||||
bottomRoundedSize = bottomCorner.size()
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove accumulated debug state by clearing out the drawables and setting [hasTop] and
|
||||
* [hasBottom] to false.
|
||||
*/
|
||||
fun removeDebugState() {
|
||||
hasTop = false
|
||||
topRoundedDrawable = null
|
||||
topRoundedSize = Size(0, 0)
|
||||
|
||||
hasBottom = false
|
||||
bottomRoundedDrawable = null
|
||||
bottomRoundedSize = Size(0, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Scaling here happens when the display resolution is changed. This logic is exactly the same
|
||||
* as in [RoundedCornerResDelegateImpl]
|
||||
*/
|
||||
private fun reloadMeasures() {
|
||||
topRoundedDrawable?.let { topRoundedSize = Size(it.intrinsicWidth, it.intrinsicHeight) }
|
||||
bottomRoundedDrawable?.let {
|
||||
bottomRoundedSize = Size(it.intrinsicWidth, it.intrinsicHeight)
|
||||
}
|
||||
|
||||
if (physicalPixelDisplaySizeRatio != 1f) {
|
||||
if (topRoundedSize.width != 0) {
|
||||
topRoundedSize =
|
||||
Size(
|
||||
(physicalPixelDisplaySizeRatio * topRoundedSize.width + 0.5f).toInt(),
|
||||
(physicalPixelDisplaySizeRatio * topRoundedSize.height + 0.5f).toInt()
|
||||
)
|
||||
}
|
||||
if (bottomRoundedSize.width != 0) {
|
||||
bottomRoundedSize =
|
||||
Size(
|
||||
(physicalPixelDisplaySizeRatio * bottomRoundedSize.width + 0.5f).toInt(),
|
||||
(physicalPixelDisplaySizeRatio * bottomRoundedSize.height + 0.5f).toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun dump(pw: PrintWriter) {
|
||||
pw.println("DebugRoundedCornerDelegate state:")
|
||||
pw.println(" hasTop=$hasTop")
|
||||
pw.println(" hasBottom=$hasBottom")
|
||||
pw.println(" topRoundedSize(w,h)=(${topRoundedSize.width},${topRoundedSize.height})")
|
||||
pw.println(
|
||||
" bottomRoundedSize(w,h)=(${bottomRoundedSize.width},${bottomRoundedSize.height})"
|
||||
)
|
||||
pw.println(" physicalPixelDisplaySizeRatio=$physicalPixelDisplaySizeRatio")
|
||||
}
|
||||
}
|
||||
|
||||
/** Encapsulates the data coming in from the command line args and turns into a [PathDrawable] */
|
||||
data class DebugRoundedCornerModel(
|
||||
val path: Path,
|
||||
val width: Int,
|
||||
val height: Int,
|
||||
val scaleX: Float,
|
||||
val scaleY: Float,
|
||||
) {
|
||||
fun size() = Size(width, height)
|
||||
|
||||
fun toPathDrawable(paint: Paint) =
|
||||
PathDrawable(
|
||||
path,
|
||||
width,
|
||||
height,
|
||||
scaleX,
|
||||
scaleY,
|
||||
paint,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* PathDrawable accepts paths from the command line via [DebugRoundedCornerModel], and renders them
|
||||
* in the canvas provided by the screen decor rounded corner provider
|
||||
*/
|
||||
class PathDrawable(
|
||||
val path: Path,
|
||||
val width: Int,
|
||||
val height: Int,
|
||||
val scaleX: Float = 1f,
|
||||
val scaleY: Float = 1f,
|
||||
val paint: Paint,
|
||||
) : Drawable() {
|
||||
private var cf: ColorFilter? = null
|
||||
|
||||
override fun draw(canvas: Canvas) {
|
||||
if (scaleX != 1f || scaleY != 1f) {
|
||||
canvas.scale(scaleX, scaleY)
|
||||
}
|
||||
canvas.drawPath(path, paint)
|
||||
}
|
||||
|
||||
override fun getIntrinsicHeight(): Int = height
|
||||
override fun getIntrinsicWidth(): Int = width
|
||||
|
||||
override fun getOpacity(): Int = PixelFormat.OPAQUE
|
||||
|
||||
override fun setAlpha(alpha: Int) {}
|
||||
|
||||
override fun setColorFilter(colorFilter: ColorFilter?) {
|
||||
cf = colorFilter
|
||||
}
|
||||
}
|
||||
@@ -27,44 +27,50 @@ import com.android.systemui.Dumpable
|
||||
import com.android.systemui.R
|
||||
import java.io.PrintWriter
|
||||
|
||||
class RoundedCornerResDelegate(
|
||||
interface RoundedCornerResDelegate {
|
||||
val hasTop: Boolean
|
||||
val topRoundedDrawable: Drawable?
|
||||
val topRoundedSize: Size
|
||||
|
||||
val hasBottom: Boolean
|
||||
val bottomRoundedDrawable: Drawable?
|
||||
val bottomRoundedSize: Size
|
||||
|
||||
var physicalPixelDisplaySizeRatio: Float
|
||||
|
||||
fun updateDisplayUniqueId(newDisplayUniqueId: String?, newReloadToken: Int?)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate for the device-default rounded corners. These will always be loaded from the config
|
||||
* values `R.array.config_roundedCornerTopDrawableArray` and `R.drawable.rounded_corner_top`
|
||||
*/
|
||||
class RoundedCornerResDelegateImpl(
|
||||
private val res: Resources,
|
||||
private var displayUniqueId: String?
|
||||
) : Dumpable {
|
||||
|
||||
private val density: Float
|
||||
get() = res.displayMetrics.density
|
||||
) : RoundedCornerResDelegate, Dumpable {
|
||||
|
||||
private var reloadToken: Int = 0
|
||||
|
||||
var hasTop: Boolean = false
|
||||
override var hasTop: Boolean = false
|
||||
private set
|
||||
|
||||
var hasBottom: Boolean = false
|
||||
override var hasBottom: Boolean = false
|
||||
private set
|
||||
|
||||
var topRoundedDrawable: Drawable? = null
|
||||
override var topRoundedDrawable: Drawable? = null
|
||||
private set
|
||||
|
||||
var bottomRoundedDrawable: Drawable? = null
|
||||
override var bottomRoundedDrawable: Drawable? = null
|
||||
private set
|
||||
|
||||
var topRoundedSize = Size(0, 0)
|
||||
override var topRoundedSize = Size(0, 0)
|
||||
private set
|
||||
|
||||
var bottomRoundedSize = Size(0, 0)
|
||||
override var bottomRoundedSize = Size(0, 0)
|
||||
private set
|
||||
|
||||
var tuningSizeFactor: Int? = null
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
field = value
|
||||
reloadMeasures()
|
||||
}
|
||||
|
||||
var physicalPixelDisplaySizeRatio: Float = 1f
|
||||
override var physicalPixelDisplaySizeRatio: Float = 1f
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
@@ -78,7 +84,7 @@ class RoundedCornerResDelegate(
|
||||
reloadMeasures()
|
||||
}
|
||||
|
||||
fun updateDisplayUniqueId(newDisplayUniqueId: String?, newReloadToken: Int?) {
|
||||
override fun updateDisplayUniqueId(newDisplayUniqueId: String?, newReloadToken: Int?) {
|
||||
if (displayUniqueId != newDisplayUniqueId) {
|
||||
displayUniqueId = newDisplayUniqueId
|
||||
newReloadToken ?.let { reloadToken = it }
|
||||
@@ -122,19 +128,6 @@ class RoundedCornerResDelegate(
|
||||
bottomRoundedSize = Size(it.intrinsicWidth, it.intrinsicHeight)
|
||||
}
|
||||
|
||||
tuningSizeFactor?.let {
|
||||
if (it <= 0) {
|
||||
return
|
||||
}
|
||||
val length: Int = (it * density).toInt()
|
||||
if (topRoundedSize.width > 0) {
|
||||
topRoundedSize = Size(length, length)
|
||||
}
|
||||
if (bottomRoundedSize.width > 0) {
|
||||
bottomRoundedSize = Size(length, length)
|
||||
}
|
||||
}
|
||||
|
||||
if (physicalPixelDisplaySizeRatio != 1f) {
|
||||
if (topRoundedSize.width != 0) {
|
||||
topRoundedSize = Size(
|
||||
|
||||
@@ -21,9 +21,9 @@ import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import androidx.core.graphics.toRectF
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.LogLevel.DEBUG
|
||||
import com.android.systemui.log.LogLevel.ERROR
|
||||
import com.android.systemui.log.LogLevel.INFO
|
||||
import com.android.systemui.log.dagger.ScreenDecorationsLog
|
||||
import com.google.errorprone.annotations.CompileTimeConstant
|
||||
import javax.inject.Inject
|
||||
@@ -164,4 +164,49 @@ constructor(
|
||||
fun cameraProtectionEvent(@CompileTimeConstant cameraProtectionEvent: String) {
|
||||
logBuffer.log(TAG, DEBUG, cameraProtectionEvent)
|
||||
}
|
||||
|
||||
fun logRotationChangeDeferred(currentRot: Int, newRot: Int) {
|
||||
logBuffer.log(
|
||||
TAG,
|
||||
INFO,
|
||||
{
|
||||
int1 = currentRot
|
||||
int2 = newRot
|
||||
},
|
||||
{ "Rotation changed, deferring $int2, staying at $int2" },
|
||||
)
|
||||
}
|
||||
|
||||
fun logRotationChanged(oldRot: Int, newRot: Int) {
|
||||
logBuffer.log(
|
||||
TAG,
|
||||
INFO,
|
||||
{
|
||||
int1 = oldRot
|
||||
int2 = newRot
|
||||
},
|
||||
{ "Rotation changed from $int1 to $int2" }
|
||||
)
|
||||
}
|
||||
|
||||
fun logDisplayModeChanged(currentMode: Int, newMode: Int) {
|
||||
logBuffer.log(
|
||||
TAG,
|
||||
INFO,
|
||||
{
|
||||
int1 = currentMode
|
||||
int2 = newMode
|
||||
},
|
||||
{ "Resolution changed, deferring mode change to $int2, staying at $int1" },
|
||||
)
|
||||
}
|
||||
|
||||
fun logUserSwitched(newUser: Int) {
|
||||
logBuffer.log(
|
||||
TAG,
|
||||
DEBUG,
|
||||
{ int1 = newUser },
|
||||
{ "UserSwitched newUserId=$int1. Updating color inversion setting" },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,8 @@ class ScreenDecorHwcLayerTest : SysuiTestCase() {
|
||||
|
||||
val decorationSupport = DisplayDecorationSupport()
|
||||
decorationSupport.format = PixelFormat.R_8
|
||||
decorHwcLayer = Mockito.spy(ScreenDecorHwcLayer(mContext, decorationSupport))
|
||||
decorHwcLayer =
|
||||
Mockito.spy(ScreenDecorHwcLayer(mContext, decorationSupport, /* debug */ false))
|
||||
whenever(decorHwcLayer.width).thenReturn(displayWidth)
|
||||
whenever(decorHwcLayer.height).thenReturn(displayHeight)
|
||||
whenever(decorHwcLayer.context).thenReturn(mockContext)
|
||||
|
||||
@@ -43,7 +43,6 @@ import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -63,6 +62,7 @@ import android.os.Handler;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
import android.util.PathParser;
|
||||
import android.util.Size;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayCutout;
|
||||
@@ -83,6 +83,7 @@ import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.decor.CornerDecorProvider;
|
||||
import com.android.systemui.decor.CutoutDecorProviderFactory;
|
||||
import com.android.systemui.decor.CutoutDecorProviderImpl;
|
||||
import com.android.systemui.decor.DebugRoundedCornerModel;
|
||||
import com.android.systemui.decor.DecorProvider;
|
||||
import com.android.systemui.decor.DecorProviderFactory;
|
||||
import com.android.systemui.decor.FaceScanningOverlayProviderImpl;
|
||||
@@ -96,7 +97,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.settings.FakeDisplayTracker;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.events.PrivacyDotViewController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.concurrency.FakeThreadFactory;
|
||||
import com.android.systemui.util.settings.FakeSettings;
|
||||
@@ -139,8 +139,6 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private Display mDisplay;
|
||||
@Mock
|
||||
private TunerService mTunerService;
|
||||
@Mock
|
||||
private UserTracker mUserTracker;
|
||||
@Mock
|
||||
private PrivacyDotViewController mDotViewController;
|
||||
@@ -234,7 +232,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer"))));
|
||||
|
||||
mScreenDecorations = spy(new ScreenDecorations(mContext, mExecutor, mSecureSettings,
|
||||
mTunerService, mUserTracker, mDisplayTracker, mDotViewController, mThreadFactory,
|
||||
mUserTracker, mDisplayTracker, mDotViewController, mThreadFactory,
|
||||
mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory,
|
||||
new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")),
|
||||
mAuthController) {
|
||||
@@ -250,12 +248,6 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mExecutor.runAllReady();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
super.onTuningChanged(key, newValue);
|
||||
mExecutor.runAllReady();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateOverlayWindowVisibilityIfViewExists(@Nullable View view) {
|
||||
super.updateOverlayWindowVisibilityIfViewExists(view);
|
||||
@@ -268,9 +260,10 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
}
|
||||
});
|
||||
mScreenDecorations.mDisplayInfo = mDisplayInfo;
|
||||
// Make sure tests are never run starting in debug mode
|
||||
mScreenDecorations.setDebug(false);
|
||||
doReturn(1f).when(mScreenDecorations).getPhysicalPixelDisplaySizeRatio();
|
||||
doNothing().when(mScreenDecorations).updateOverlayProviderViews(any());
|
||||
reset(mTunerService);
|
||||
|
||||
try {
|
||||
mPrivacyDotShowingListener = mScreenDecorations.mPrivacyDotShowingListener.getClass()
|
||||
@@ -464,8 +457,6 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
// No views added.
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, null);
|
||||
// No Tuners tuned.
|
||||
verify(mTunerService, never()).addTunable(any(), any());
|
||||
// No dot controller init
|
||||
verify(mDotViewController, never()).initialize(any(), any(), any(), any());
|
||||
}
|
||||
@@ -497,8 +488,6 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Face scanning doesn't exist
|
||||
verifyFaceScanningViewExists(false);
|
||||
|
||||
// One tunable.
|
||||
verify(mTunerService, times(1)).addTunable(any(), any());
|
||||
// Dot controller init
|
||||
verify(mDotViewController, times(1)).initialize(
|
||||
isA(View.class), isA(View.class), isA(View.class), isA(View.class));
|
||||
@@ -528,8 +517,6 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Face scanning doesn't exist
|
||||
verifyFaceScanningViewExists(false);
|
||||
|
||||
// One tunable.
|
||||
verify(mTunerService, times(1)).addTunable(any(), any());
|
||||
// No dot controller init
|
||||
verify(mDotViewController, never()).initialize(any(), any(), any(), any());
|
||||
}
|
||||
@@ -560,8 +547,6 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Face scanning doesn't exist
|
||||
verifyFaceScanningViewExists(false);
|
||||
|
||||
// One tunable.
|
||||
verify(mTunerService, times(1)).addTunable(any(), any());
|
||||
// Dot controller init
|
||||
verify(mDotViewController, times(1)).initialize(
|
||||
isA(View.class), isA(View.class), isA(View.class), isA(View.class));
|
||||
@@ -1072,19 +1057,90 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
assertEquals(true, providers.get(1).getAlignedBounds().contains(BOUNDS_POSITION_BOTTOM));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDebugRoundedCorners_noDeviceCornersSet() {
|
||||
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
|
||||
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
|
||||
0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
|
||||
|
||||
mScreenDecorations.start();
|
||||
// No rounded corners exist at this point
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, View.VISIBLE);
|
||||
|
||||
// Path from rounded.xml, scaled by 10x to produce 80x80 corners
|
||||
Path debugPath = PathParser.createPathFromPathData("M8,0H0v8C0,3.6,3.6,0,8,0z");
|
||||
// WHEN debug corners are added to the delegate
|
||||
DebugRoundedCornerModel debugCorner = new DebugRoundedCornerModel(
|
||||
debugPath,
|
||||
80,
|
||||
80,
|
||||
10f,
|
||||
10f
|
||||
);
|
||||
mScreenDecorations.mDebugRoundedCornerDelegate
|
||||
.applyNewDebugCorners(debugCorner, debugCorner);
|
||||
|
||||
// AND debug mode is entered
|
||||
mScreenDecorations.setDebug(true);
|
||||
mExecutor.runAllReady();
|
||||
|
||||
// THEN the debug corners provide decor
|
||||
List<DecorProvider> providers = mScreenDecorations.getProviders(false);
|
||||
assertEquals(4, providers.size());
|
||||
|
||||
// Top and bottom overlays contain the debug rounded corners
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDebugRoundedCornersRemoved_noDeviceCornersSet() {
|
||||
// GIVEN a device with no rounded corners defined
|
||||
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
|
||||
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
|
||||
0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
|
||||
|
||||
mScreenDecorations.start();
|
||||
// No rounded corners exist at this point
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, View.VISIBLE);
|
||||
|
||||
// Path from rounded.xml, scaled by 10x to produce 80x80 corners
|
||||
Path debugPath = PathParser.createPathFromPathData("M8,0H0v8C0,3.6,3.6,0,8,0z");
|
||||
// WHEN debug corners are added to the delegate
|
||||
DebugRoundedCornerModel debugCorner = new DebugRoundedCornerModel(
|
||||
debugPath,
|
||||
80,
|
||||
80,
|
||||
10f,
|
||||
10f
|
||||
);
|
||||
mScreenDecorations.mDebugRoundedCornerDelegate
|
||||
.applyNewDebugCorners(debugCorner, debugCorner);
|
||||
|
||||
// AND debug mode is entered
|
||||
mScreenDecorations.setDebug(true);
|
||||
mExecutor.runAllReady();
|
||||
|
||||
// Top and bottom overlays contain the debug rounded corners
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
|
||||
// WHEN debug is exited
|
||||
mScreenDecorations.setDebug(false);
|
||||
mExecutor.runAllReady();
|
||||
|
||||
// THEN the decor is removed
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, View.VISIBLE);
|
||||
assertThat(mScreenDecorations.mDebugRoundedCornerDelegate.getHasBottom()).isFalse();
|
||||
assertThat(mScreenDecorations.mDebugRoundedCornerDelegate.getHasTop()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegistration_From_NoOverlay_To_HasOverlays() {
|
||||
doReturn(false).when(mScreenDecorations).hasOverlays();
|
||||
mScreenDecorations.start();
|
||||
verify(mTunerService, times(0)).addTunable(any(), any());
|
||||
verify(mTunerService, times(1)).removeTunable(any());
|
||||
assertThat(mScreenDecorations.mIsRegistered, is(false));
|
||||
reset(mTunerService);
|
||||
|
||||
doReturn(true).when(mScreenDecorations).hasOverlays();
|
||||
mScreenDecorations.onConfigurationChanged(new Configuration());
|
||||
verify(mTunerService, times(1)).addTunable(any(), any());
|
||||
verify(mTunerService, times(0)).removeTunable(any());
|
||||
assertThat(mScreenDecorations.mIsRegistered, is(true));
|
||||
}
|
||||
|
||||
@@ -1093,14 +1149,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
doReturn(true).when(mScreenDecorations).hasOverlays();
|
||||
|
||||
mScreenDecorations.start();
|
||||
verify(mTunerService, times(1)).addTunable(any(), any());
|
||||
verify(mTunerService, times(0)).removeTunable(any());
|
||||
assertThat(mScreenDecorations.mIsRegistered, is(true));
|
||||
reset(mTunerService);
|
||||
|
||||
mScreenDecorations.onConfigurationChanged(new Configuration());
|
||||
verify(mTunerService, times(0)).addTunable(any(), any());
|
||||
verify(mTunerService, times(0)).removeTunable(any());
|
||||
assertThat(mScreenDecorations.mIsRegistered, is(true));
|
||||
}
|
||||
|
||||
@@ -1109,15 +1160,10 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
doReturn(true).when(mScreenDecorations).hasOverlays();
|
||||
|
||||
mScreenDecorations.start();
|
||||
verify(mTunerService, times(1)).addTunable(any(), any());
|
||||
verify(mTunerService, times(0)).removeTunable(any());
|
||||
assertThat(mScreenDecorations.mIsRegistered, is(true));
|
||||
reset(mTunerService);
|
||||
|
||||
doReturn(false).when(mScreenDecorations).hasOverlays();
|
||||
mScreenDecorations.onConfigurationChanged(new Configuration());
|
||||
verify(mTunerService, times(0)).addTunable(any(), any());
|
||||
verify(mTunerService, times(1)).removeTunable(any());
|
||||
assertThat(mScreenDecorations.mIsRegistered, is(false));
|
||||
}
|
||||
|
||||
@@ -1181,7 +1227,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
when(mFaceScanningProviderFactory.getProviders()).thenReturn(mFaceScanningProviders);
|
||||
when(mFaceScanningProviderFactory.getHasProviders()).thenReturn(true);
|
||||
ScreenDecorations screenDecorations = new ScreenDecorations(mContext, mExecutor,
|
||||
mSecureSettings, mTunerService, mUserTracker, mDisplayTracker, mDotViewController,
|
||||
mSecureSettings, mUserTracker, mDisplayTracker, mDotViewController,
|
||||
mThreadFactory, mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory,
|
||||
new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")), mAuthController);
|
||||
screenDecorations.start();
|
||||
|
||||
@@ -39,7 +39,7 @@ class RoundedCornerDecorProviderFactoryTest : SysuiTestCase() {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
roundedCornerResDelegate = spy(RoundedCornerResDelegate(mContext.resources, null))
|
||||
roundedCornerResDelegate = spy(RoundedCornerResDelegateImpl(mContext.resources, null))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -48,7 +48,7 @@ class RoundedCornerResDelegateTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun testTopAndBottomRoundedCornerExist() {
|
||||
setupResources(radius = 5)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegateImpl(mContext.resources, null)
|
||||
assertEquals(true, roundedCornerResDelegate.hasTop)
|
||||
assertEquals(true, roundedCornerResDelegate.hasBottom)
|
||||
}
|
||||
@@ -56,7 +56,7 @@ class RoundedCornerResDelegateTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun testTopRoundedCornerExist() {
|
||||
setupResources(radiusTop = 10)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegateImpl(mContext.resources, null)
|
||||
assertEquals(true, roundedCornerResDelegate.hasTop)
|
||||
assertEquals(false, roundedCornerResDelegate.hasBottom)
|
||||
}
|
||||
@@ -64,7 +64,7 @@ class RoundedCornerResDelegateTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun testBottomRoundedCornerExist() {
|
||||
setupResources(radiusBottom = 15)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegateImpl(mContext.resources, null)
|
||||
assertEquals(false, roundedCornerResDelegate.hasTop)
|
||||
assertEquals(true, roundedCornerResDelegate.hasBottom)
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class RoundedCornerResDelegateTest : SysuiTestCase() {
|
||||
roundedTopDrawable = getTestsDrawable(R.drawable.rounded3px),
|
||||
roundedBottomDrawable = getTestsDrawable(R.drawable.rounded4px))
|
||||
|
||||
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegateImpl(mContext.resources, null)
|
||||
|
||||
assertEquals(Size(3, 3), roundedCornerResDelegate.topRoundedSize)
|
||||
assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize)
|
||||
@@ -96,7 +96,7 @@ class RoundedCornerResDelegateTest : SysuiTestCase() {
|
||||
roundedTopDrawable = getTestsDrawable(R.drawable.rounded3px),
|
||||
roundedBottomDrawable = getTestsDrawable(R.drawable.rounded4px))
|
||||
|
||||
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegateImpl(mContext.resources, null)
|
||||
|
||||
assertEquals(Size(3, 3), roundedCornerResDelegate.topRoundedSize)
|
||||
assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize)
|
||||
@@ -108,34 +108,13 @@ class RoundedCornerResDelegateTest : SysuiTestCase() {
|
||||
assertEquals(Size(8, 8), roundedCornerResDelegate.bottomRoundedSize)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUpdateTuningSizeFactor() {
|
||||
setupResources(radius = 100,
|
||||
roundedTopDrawable = getTestsDrawable(R.drawable.rounded3px),
|
||||
roundedBottomDrawable = getTestsDrawable(R.drawable.rounded4px))
|
||||
|
||||
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
|
||||
|
||||
val factor = 5
|
||||
roundedCornerResDelegate.tuningSizeFactor = factor
|
||||
val length = (factor * mContext.resources.displayMetrics.density).toInt()
|
||||
|
||||
assertEquals(Size(length, length), roundedCornerResDelegate.topRoundedSize)
|
||||
assertEquals(Size(length, length), roundedCornerResDelegate.bottomRoundedSize)
|
||||
|
||||
roundedCornerResDelegate.tuningSizeFactor = null
|
||||
|
||||
assertEquals(Size(3, 3), roundedCornerResDelegate.topRoundedSize)
|
||||
assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPhysicalPixelDisplaySizeChanged() {
|
||||
setupResources(
|
||||
roundedTopDrawable = getTestsDrawable(R.drawable.rounded4px),
|
||||
roundedBottomDrawable = getTestsDrawable(R.drawable.rounded4px))
|
||||
|
||||
roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null)
|
||||
roundedCornerResDelegate = RoundedCornerResDelegateImpl(mContext.resources, null)
|
||||
assertEquals(Size(4, 4), roundedCornerResDelegate.topRoundedSize)
|
||||
assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user