Merge "To fix the test case fail" into tm-qpr-dev
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 449729e..48df9e6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -3933,6 +3933,9 @@
* processes to reclaim memory; the system will take care of restarting
* these processes in the future as needed.
*
+ * <p class="note">Third party applications can only use this API to kill their own processes.
+ * </p>
+ *
* @param packageName The name of the package whose processes are to
* be killed.
*/
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index d53ad17..e27af17 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -61,7 +61,6 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -181,9 +180,6 @@
private final ArrayList<Engine> mActiveEngines
= new ArrayList<Engine>();
- private Handler mBackgroundHandler;
- private HandlerThread mBackgroundThread;
-
static final class WallpaperCommand {
String action;
int x;
@@ -202,6 +198,14 @@
*/
public class Engine {
IWallpaperEngineWrapper mIWallpaperEngine;
+ final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
+ final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
+
+ // 2D matrix [x][y] to represent a page of a portion of a window
+ EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
+ Bitmap mLastScreenshot;
+ int mLastWindowPage = -1;
+ private boolean mResetWindowPages;
// Copies from mIWallpaperEngine.
HandlerCaller mCaller;
@@ -263,27 +267,11 @@
final Object mLock = new Object();
boolean mOffsetMessageEnqueued;
-
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
float mPendingXOffset;
float mPendingYOffset;
float mPendingXOffsetStep;
float mPendingYOffsetStep;
-
- /**
- * local color extraction related fields
- * to be used by the background thread only (except the atomic boolean)
- */
- final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
- final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
- private long mLastProcessLocalColorsTimestamp;
- private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
- private int mPixelCopyCount = 0;
- // 2D matrix [x][y] to represent a page of a portion of a window
- EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
- Bitmap mLastScreenshot;
- private boolean mResetWindowPages;
-
boolean mPendingSync;
MotionEvent mPendingMove;
boolean mIsInAmbientMode;
@@ -292,8 +280,12 @@
private long mLastColorInvalidation;
private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
+ // used to throttle processLocalColors
+ private long mLastProcessLocalColorsTimestamp;
+ private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
private final Supplier<Long> mClockFunction;
private final Handler mHandler;
+
private Display mDisplay;
private Context mDisplayContext;
private int mDisplayState;
@@ -833,7 +825,7 @@
+ "was not established.");
}
mResetWindowPages = true;
- processLocalColors();
+ processLocalColors(mPendingXOffset, mPendingXOffsetStep);
} catch (RemoteException e) {
Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
}
@@ -1372,7 +1364,7 @@
resetWindowPages();
mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
Integer.MAX_VALUE);
- processLocalColors();
+ processLocalColors(mPendingXOffset, mPendingXOffsetStep);
}
reposition();
reportEngineShown(shouldWaitForEngineShown());
@@ -1517,7 +1509,7 @@
if (!mDestroyed) {
mVisible = visible;
reportVisibility();
- if (mReportedVisible) processLocalColors();
+ if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep);
} else {
AnimationHandler.requestAnimatorsEnabled(visible, this);
}
@@ -1601,41 +1593,31 @@
}
// setup local color extraction data
- processLocalColors();
+ processLocalColors(xOffset, xOffsetStep);
}
/**
* Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of
* {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls.
*/
- private void processLocalColors() {
+ private void processLocalColors(float xOffset, float xOffsetStep) {
if (mProcessLocalColorsPending.compareAndSet(false, true)) {
final long now = mClockFunction.get();
final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp;
final long timeToWait = Math.max(0,
PROCESS_LOCAL_COLORS_INTERVAL_MS - timeSinceLastColorProcess);
- mBackgroundHandler.postDelayed(() -> {
+ mHandler.postDelayed(() -> {
mLastProcessLocalColorsTimestamp = now + timeToWait;
mProcessLocalColorsPending.set(false);
- processLocalColorsInternal();
+ processLocalColorsInternal(xOffset, xOffsetStep);
}, timeToWait);
}
}
- private void processLocalColorsInternal() {
+ private void processLocalColorsInternal(float xOffset, float xOffsetStep) {
// implemented by the wallpaper
if (supportsLocalColorExtraction()) return;
- assertBackgroundThread();
- float xOffset;
- float xOffsetStep;
- float wallpaperDimAmount;
- synchronized (mLock) {
- xOffset = mPendingXOffset;
- xOffsetStep = mPendingXOffsetStep;
- wallpaperDimAmount = mWallpaperDimAmount;
- }
-
if (DEBUG) {
Log.d(TAG, "processLocalColors " + xOffset + " of step "
+ xOffsetStep);
@@ -1698,7 +1680,7 @@
xPage = mWindowPages.length - 1;
}
current = mWindowPages[xPage];
- updatePage(current, xPage, xPages, wallpaperDimAmount);
+ updatePage(current, xPage, xPages, finalXOffsetStep);
Trace.endSection();
}
@@ -1718,23 +1700,16 @@
}
}
- /**
- * Must be called with the surface lock held.
- * Must not be called if the surface is not valid.
- * Will unlock the surface when done using it.
- */
void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
- float wallpaperDimAmount) {
-
- assertBackgroundThread();
-
+ float xOffsetStep) {
// in case the clock is zero, we start with negative time
long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION;
long lapsed = current - currentPage.getLastUpdateTime();
// Always update the page when the last update time is <= 0
// This is important especially when the device first boots
- if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) return;
-
+ if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) {
+ return;
+ }
Surface surface = mSurfaceHolder.getSurface();
if (!surface.isValid()) return;
boolean widthIsLarger = mSurfaceSize.x > mSurfaceSize.y;
@@ -1750,42 +1725,33 @@
Bitmap screenShot = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
final Bitmap finalScreenShot = screenShot;
- final String pixelCopySectionName = "WallpaperService#pixelCopy";
- final int pixelCopyCount = mPixelCopyCount++;
- Trace.beginAsyncSection(pixelCopySectionName, pixelCopyCount);
- try {
- PixelCopy.request(surface, screenShot, (res) -> {
- Trace.endAsyncSection(pixelCopySectionName, pixelCopyCount);
- if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
- if (res != PixelCopy.SUCCESS) {
- Bitmap lastBitmap = currentPage.getBitmap();
- // assign the last bitmap taken for now
- currentPage.setBitmap(mLastScreenshot);
- Bitmap lastScreenshot = mLastScreenshot;
- if (lastScreenshot != null && !lastScreenshot.isRecycled()
- && !Objects.equals(lastBitmap, lastScreenshot)) {
- updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
- }
- } else {
- mLastScreenshot = finalScreenShot;
- // going to hold this lock for a while
- currentPage.setBitmap(finalScreenShot);
- currentPage.setLastUpdateTime(current);
- updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
+ Trace.beginSection("WallpaperService#pixelCopy");
+ PixelCopy.request(surface, screenShot, (res) -> {
+ Trace.endSection();
+ if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
+ if (res != PixelCopy.SUCCESS) {
+ Bitmap lastBitmap = currentPage.getBitmap();
+ // assign the last bitmap taken for now
+ currentPage.setBitmap(mLastScreenshot);
+ Bitmap lastScreenshot = mLastScreenshot;
+ if (lastScreenshot != null && !lastScreenshot.isRecycled()
+ && !Objects.equals(lastBitmap, lastScreenshot)) {
+ updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
}
- }, mBackgroundHandler);
- } catch (IllegalArgumentException e) {
- // this can potentially happen if the surface is invalidated right between the
- // surface.isValid() check and the PixelCopy operation.
- // in this case, stop: we'll compute colors on the next processLocalColors call.
- Log.i(TAG, "Cancelling processLocalColors: exception caught during PixelCopy");
- }
+ } else {
+ mLastScreenshot = finalScreenShot;
+ // going to hold this lock for a while
+ currentPage.setBitmap(finalScreenShot);
+ currentPage.setLastUpdateTime(current);
+ updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
+ }
+ }, mHandler);
+
}
// locked by the passed page
- private void updatePageColors(
- EngineWindowPage page, int pageIndx, int numPages, float wallpaperDimAmount) {
+ private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
+ float xOffsetStep) {
if (page.getBitmap() == null) return;
- assertBackgroundThread();
Trace.beginSection("WallpaperService#updatePageColors");
if (DEBUG) {
Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas "
@@ -1807,7 +1773,7 @@
Log.e(TAG, "Error creating page local color bitmap", e);
continue;
}
- WallpaperColors color = WallpaperColors.fromBitmap(target, wallpaperDimAmount);
+ WallpaperColors color = WallpaperColors.fromBitmap(target, mWallpaperDimAmount);
target.recycle();
WallpaperColors currentColor = page.getColors(area);
@@ -1824,26 +1790,17 @@
+ " local color callback for area" + area + " for page " + pageIndx
+ " of " + numPages);
}
- mHandler.post(() -> {
- try {
- mConnection.onLocalWallpaperColorsChanged(area, color,
- mDisplayContext.getDisplayId());
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
- }
- });
+ try {
+ mConnection.onLocalWallpaperColorsChanged(area, color,
+ mDisplayContext.getDisplayId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
+ }
}
}
Trace.endSection();
}
- private void assertBackgroundThread() {
- if (!mBackgroundHandler.getLooper().isCurrentThread()) {
- throw new IllegalStateException(
- "ProcessLocalColors should be called from the background thread");
- }
- }
-
private RectF generateSubRect(RectF in, int pageInx, int numPages) {
float minLeft = (float) (pageInx) / (float) (numPages);
float maxRight = (float) (pageInx + 1) / (float) (numPages);
@@ -1868,6 +1825,7 @@
if (supportsLocalColorExtraction()) return;
if (!mResetWindowPages) return;
mResetWindowPages = false;
+ mLastWindowPage = -1;
for (int i = 0; i < mWindowPages.length; i++) {
mWindowPages[i].setLastUpdateTime(0L);
}
@@ -1893,10 +1851,12 @@
if (DEBUG) {
Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions);
}
- mBackgroundHandler.post(() -> {
+ mHandler.post(() -> {
mLocalColorsToAdd.addAll(regions);
- processLocalColors();
+ processLocalColors(mPendingXOffset, mPendingYOffset);
});
+
+
}
/**
@@ -1906,7 +1866,7 @@
*/
public void removeLocalColorsAreas(@NonNull List<RectF> regions) {
if (supportsLocalColorExtraction()) return;
- mBackgroundHandler.post(() -> {
+ mHandler.post(() -> {
float step = mPendingXOffsetStep;
mLocalColorsToAdd.removeAll(regions);
mLocalColorAreas.removeAll(regions);
@@ -2537,9 +2497,6 @@
@Override
public void onCreate() {
Trace.beginSection("WPMS.onCreate");
- mBackgroundThread = new HandlerThread("DefaultWallpaperLocalColorExtractor");
- mBackgroundThread.start();
- mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
super.onCreate();
Trace.endSection();
}
@@ -2552,7 +2509,6 @@
mActiveEngines.get(i).detach();
}
mActiveEngines.clear();
- mBackgroundThread.quitSafely();
Trace.endSection();
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 02027e4..293f9082 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -823,6 +823,11 @@
/** @hide */
public final void destroy() {
mDestroyed = true;
+ onDestroy();
+ }
+
+ /** @hide */
+ protected void onDestroy() {
}
/** @hide */
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index d8afe50..e7217de 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -33,6 +33,7 @@
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_ALL_APPS;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNLOCK_ENTRANCE_ANIMATION;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_OCCLUSION;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_APPEAR;
@@ -231,6 +232,7 @@
public static final int CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS = 66;
public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE = 67;
public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME = 68;
+ public static final int CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION = 70;
private static final int NO_STATSD_LOGGING = -1;
@@ -308,6 +310,8 @@
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
+ NO_STATSD_LOGGING,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION,
};
private static volatile InteractionJankMonitor sInstance;
@@ -396,7 +400,8 @@
CUJ_RECENTS_SCROLLING,
CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS,
CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE,
- CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME
+ CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
+ CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -917,6 +922,8 @@
return "LAUNCHER_CLOSE_ALL_APPS_SWIPE";
case CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME:
return "LAUNCHER_CLOSE_ALL_APPS_TO_HOME";
+ case CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION:
+ return "LOCKSCREEN_CLOCK_MOVE_ANIMATION";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3a0e09d..6fed26c 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -81,7 +81,6 @@
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
-import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
@@ -202,7 +201,6 @@
public static final int RESET_REASON_ADB_COMMAND = 2;
public static final int RESET_REASON_FULL_CHARGE = 3;
public static final int RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE = 4;
- public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5;
protected Clock mClock;
@@ -389,89 +387,6 @@
}
}
- /** Provide BatteryStatsImpl configuration choices */
- public static class BatteryStatsConfig {
- static final int RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG = 1 << 0;
- static final int RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG = 1 << 1;
-
- private final int mFlags;
-
- private BatteryStatsConfig(Builder builder) {
- int flags = 0;
- if (builder.mResetOnUnplugHighBatteryLevel) {
- flags |= RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG;
- }
- if (builder.mResetOnUnplugAfterSignificantCharge) {
- flags |= RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG;
- }
- mFlags = flags;
- }
-
- /**
- * Returns whether a BatteryStats reset should occur on unplug when the battery level is
- * high.
- */
- boolean shouldResetOnUnplugHighBatteryLevel() {
- return (mFlags & RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG)
- == RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG;
- }
-
- /**
- * Returns whether a BatteryStats reset should occur on unplug if the battery charge a
- * significant amount since it has been plugged in.
- */
- boolean shouldResetOnUnplugAfterSignificantCharge() {
- return (mFlags & RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG)
- == RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG;
- }
-
- /**
- * Builder for BatteryStatsConfig
- */
- public static class Builder {
- private boolean mResetOnUnplugHighBatteryLevel;
- private boolean mResetOnUnplugAfterSignificantCharge;
- public Builder() {
- mResetOnUnplugHighBatteryLevel = true;
- mResetOnUnplugAfterSignificantCharge = true;
- }
-
- /**
- * Build the BatteryStatsConfig.
- */
- public BatteryStatsConfig build() {
- return new BatteryStatsConfig(this);
- }
-
- /**
- * Set whether a BatteryStats reset should occur on unplug when the battery level is
- * high.
- */
- public Builder setResetOnUnplugHighBatteryLevel(boolean reset) {
- mResetOnUnplugHighBatteryLevel = reset;
- return this;
- }
-
- /**
- * Set whether a BatteryStats reset should occur on unplug if the battery charge a
- * significant amount since it has been plugged in.
- */
- public Builder setResetOnUnplugAfterSignificantCharge(boolean reset) {
- mResetOnUnplugAfterSignificantCharge = reset;
- return this;
- }
- }
-
- }
-
- /** Handles calls to AlarmManager */
- public interface AlarmInterface {
- /** Schedule an RTC alarm */
- void schedule(long rtcTimeMs, long windowLengthMs);
- /** Cancel the previously scheduled alarm */
- void cancel();
- }
-
private final PlatformIdleStateCallback mPlatformIdleStateCallback;
private final Runnable mDeferSetCharging = new Runnable() {
@@ -802,7 +717,6 @@
protected boolean mHaveBatteryLevel = false;
protected boolean mRecordingHistory = false;
int mNumHistoryItems;
- private long mBatteryPluggedInRealTimeMs = 0;
private static final int HISTORY_TAG_INDEX_LIMIT = 0x7ffe;
private static final int MAX_HISTORY_TAG_STRING_LENGTH = 1024;
@@ -1545,13 +1459,6 @@
@GuardedBy("this")
protected final Constants mConstants;
- @VisibleForTesting
- @GuardedBy("this")
- protected BatteryStatsConfig mBatteryStatsConfig = new BatteryStatsConfig.Builder().build();
-
- @VisibleForTesting
- protected AlarmInterface mLongPlugInAlarmInterface = null;
-
/*
* Holds a SamplingTimer associated with each Resource Power Manager state and voter,
* recording their times when on-battery (regardless of screen state).
@@ -1718,13 +1625,12 @@
public BatteryStatsImpl(Clock clock, File historyDirectory) {
init(clock);
mStartClockTimeMs = clock.currentTimeMillis();
+ mCheckinFile = null;
mDailyFile = null;
if (historyDirectory == null) {
- mCheckinFile = null;
mStatsFile = null;
mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
} else {
- mCheckinFile = new AtomicFile(new File(historyDirectory, "batterystats-checkin.bin"));
mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
mBatteryStatsHistory = new BatteryStatsHistory(this, historyDirectory, mHistoryBuffer);
}
@@ -12642,27 +12548,6 @@
}
/**
- * Injects BatteryStatsConfig
- */
- public void setBatteryStatsConfig(BatteryStatsConfig config) {
- synchronized (this) {
- mBatteryStatsConfig = config;
- }
- }
-
- /**
- * Injects a LongPlugInAlarmHandler
- */
- public void setLongPlugInAlarmInterface(AlarmInterface longPlugInAlarmInterface) {
- synchronized (this) {
- mLongPlugInAlarmInterface = longPlugInAlarmInterface;
- if (!mOnBattery) {
- scheduleNextResetWhilePluggedInCheck();
- }
- }
- }
-
- /**
* Starts tracking CPU time-in-state for threads of the system server process,
* keeping a separate account of threads receiving incoming binder calls.
*/
@@ -13134,12 +13019,12 @@
}
@GuardedBy("this")
- public void resetAllStatsAndHistoryLocked(int reason) {
+ public void resetAllStatsCmdLocked() {
final long mSecUptime = mClock.uptimeMillis();
long uptimeUs = mSecUptime * 1000;
long mSecRealtime = mClock.elapsedRealtime();
long realtimeUs = mSecRealtime * 1000;
- resetAllStatsLocked(mSecUptime, mSecRealtime, reason);
+ resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND);
mDischargeStartLevel = mHistoryCur.batteryLevel;
pullPendingStateUpdatesLocked();
addHistoryRecordLocked(mSecRealtime, mSecUptime);
@@ -15613,73 +15498,6 @@
}
/**
- * Might reset battery stats if conditions are met. Assumed the device is currently plugged in.
- */
- @GuardedBy("this")
- public void maybeResetWhilePluggedInLocked() {
- final long elapsedRealtimeMs = mClock.elapsedRealtime();
- if (shouldResetWhilePluggedInLocked(elapsedRealtimeMs)) {
- Slog.i(TAG,
- "Resetting due to long plug in duration. elapsed time = " + elapsedRealtimeMs
- + " ms, last plug in time = " + mBatteryPluggedInRealTimeMs
- + " ms, last reset time = " + mRealtimeStartUs / 1000);
- resetAllStatsAndHistoryLocked(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION);
- }
-
- scheduleNextResetWhilePluggedInCheck();
- }
-
- @GuardedBy("this")
- private void scheduleNextResetWhilePluggedInCheck() {
- if (mLongPlugInAlarmInterface != null) {
- final long timeoutMs = mClock.currentTimeMillis()
- + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS
- * DateUtils.HOUR_IN_MILLIS;
- Calendar nextAlarm = Calendar.getInstance();
- nextAlarm.setTimeInMillis(timeoutMs);
-
- // Find the 2 AM the same day as the end of the minimum duration.
- // This logic does not handle a Daylight Savings transition, or a timezone change
- // while the alarm has been set. The need to reset after a long period while plugged
- // in is not strict enough to warrant a well architected out solution.
- nextAlarm.set(Calendar.MILLISECOND, 0);
- nextAlarm.set(Calendar.SECOND, 0);
- nextAlarm.set(Calendar.MINUTE, 0);
- nextAlarm.set(Calendar.HOUR_OF_DAY, 2);
- long nextTimeMs = nextAlarm.getTimeInMillis();
- if (nextTimeMs < timeoutMs) {
- // The 2AM on the day of the timeout, move on the next day.
- nextTimeMs += DateUtils.DAY_IN_MILLIS;
- }
- mLongPlugInAlarmInterface.schedule(nextTimeMs, DateUtils.HOUR_IN_MILLIS);
- }
- }
-
-
- @GuardedBy("this")
- private boolean shouldResetWhilePluggedInLocked(long elapsedRealtimeMs) {
- if (mNoAutoReset) return false;
- if (!mSystemReady) return false;
-
- final long pluggedInThresholdMs = mBatteryPluggedInRealTimeMs
- + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS
- * DateUtils.HOUR_IN_MILLIS;
- if (elapsedRealtimeMs >= pluggedInThresholdMs) {
- // The device has been plugged in for a long time.
- final long resetThresholdMs = mRealtimeStartUs / 1000
- + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS
- * DateUtils.HOUR_IN_MILLIS;
- if (elapsedRealtimeMs >= resetThresholdMs) {
- // And it has been a long time since the last reset.
- return true;
- }
- }
-
- return false;
- }
-
-
- /**
* Notifies BatteryStatsImpl that the system server is ready.
*/
public void onSystemReady() {
@@ -15687,32 +15505,6 @@
}
@GuardedBy("this")
- private boolean shouldResetOnUnplugLocked(int batteryStatus, int batteryLevel) {
- if (mNoAutoReset) return false;
- if (!mSystemReady) return false;
- if (mBatteryStatsConfig.shouldResetOnUnplugHighBatteryLevel()) {
- // Allow resetting due to currently being at high battery level
- if (batteryStatus == BatteryManager.BATTERY_STATUS_FULL) return true;
- if (batteryLevel >= 90) return true;
- }
- if (mBatteryStatsConfig.shouldResetOnUnplugAfterSignificantCharge()) {
- // Allow resetting after a significant charge (from a very low level to a now very
- // high level).
- if (mDischargePlugLevel < 20 && batteryLevel >= 80) return true;
- }
- if (getHighDischargeAmountSinceCharge() >= 200) {
- // Reset the stats if battery got partially charged and discharged repeatedly without
- // ever reaching the full charge.
- // This reset is done in order to prevent stats sessions from going on forever.
- // Exceedingly long battery sessions would lead to an overflow of
- // data structures such as mWakeupReasonStats.
- return true;
- }
-
- return false;
- }
-
- @GuardedBy("this")
protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime,
final boolean onBattery, final int oldStatus, final int level, final int chargeUah) {
boolean doWrite = false;
@@ -15724,10 +15516,23 @@
final long realtimeUs = mSecRealtime * 1000;
final int screenState = mScreenState;
if (onBattery) {
+ // We will reset our status if we are unplugging after the
+ // battery was last full, or the level is at 100, or
+ // we have gone through a significant charge (from a very low
+ // level to a now very high level).
+ // Also, we will reset the stats if battery got partially charged
+ // and discharged repeatedly without ever reaching the full charge.
+ // This reset is done in order to prevent stats sessions from going on forever.
+ // Exceedingly long battery sessions would lead to an overflow of
+ // data structures such as mWakeupReasonStats.
boolean reset = false;
- if (shouldResetOnUnplugLocked(oldStatus, level)) {
+ if (!mNoAutoReset && mSystemReady
+ && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
+ || level >= 90
+ || (mDischargeCurrentLevel < 20 && level >= 80)
+ || getHighDischargeAmountSinceCharge() >= 200)) {
Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
- + " dischargeLevel=" + mDischargePlugLevel
+ + " dischargeLevel=" + mDischargeCurrentLevel
+ " lowAmount=" + getLowDischargeAmountSinceCharge()
+ " highAmount=" + getHighDischargeAmountSinceCharge());
// Before we write, collect a snapshot of the final aggregated
@@ -15784,9 +15589,6 @@
mInitStepMode = mCurStepMode;
mModStepMode = 0;
pullPendingStateUpdatesLocked();
- if (mLongPlugInAlarmInterface != null) {
- mLongPlugInAlarmInterface.cancel();
- }
mHistoryCur.batteryLevel = (byte)level;
mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
@@ -15818,7 +15620,6 @@
mLastChargingStateLevel = level;
mOnBattery = mOnBatteryInternal = false;
pullPendingStateUpdatesLocked();
- mBatteryPluggedInRealTimeMs = mSecRealtime;
mHistoryCur.batteryLevel = (byte)level;
mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
@@ -15836,7 +15637,6 @@
mMaxChargeStepLevel = level;
mInitStepMode = mCurStepMode;
mModStepMode = 0;
- scheduleNextResetWhilePluggedInCheck();
}
if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) {
if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) {
@@ -16851,8 +16651,6 @@
public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb";
public static final String KEY_BATTERY_CHARGED_DELAY_MS =
"battery_charged_delay_ms";
- public static final String KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS =
- "reset_while_plugged_in_minimum_duration_hours";
private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000;
@@ -16865,8 +16663,6 @@
private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64;
private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/
private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */
- // Little less than 2 days
- private static final int DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 47;
public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME;
/* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an
@@ -16882,8 +16678,6 @@
public int MAX_HISTORY_FILES;
public int MAX_HISTORY_BUFFER; /*Bytes*/
public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS;
- public int RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS =
- DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -16960,11 +16754,6 @@
DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB
: DEFAULT_MAX_HISTORY_BUFFER_KB)
* 1024;
-
- RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = mParser.getInt(
- KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS,
- DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS);
-
updateBatteryChargedDelayMsLocked();
}
}
@@ -17019,8 +16808,6 @@
pw.println(MAX_HISTORY_BUFFER/1024);
pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("=");
pw.println(BATTERY_CHARGED_DELAY_MS);
- pw.print(KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); pw.print("=");
- pw.println(RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS);
}
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index bb69192f..e603e2ed 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -295,6 +295,7 @@
private boolean mClosingActionMenu;
private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
+ private int mAudioMode = AudioManager.MODE_NORMAL;
private MediaController mMediaController;
private AudioManager mAudioManager;
@@ -317,6 +318,8 @@
}
};
+ private AudioManager.OnModeChangedListener mOnModeChangedListener;
+
private Transition mEnterTransition = null;
private Transition mReturnTransition = USE_DEFAULT_TRANSITION;
private Transition mExitTransition = null;
@@ -1950,9 +1953,9 @@
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
- // If we have a session send it the volume command, otherwise
- // use the suggested stream.
- if (mMediaController != null) {
+ // If we have a session and no active phone call send it the volume command,
+ // otherwise use the suggested stream.
+ if (mMediaController != null && !isActivePhoneCallOngoing()) {
getMediaSessionManager().dispatchVolumeKeyEventToSessionAsSystemService(event,
mMediaController.getSessionToken());
} else {
@@ -2003,6 +2006,11 @@
return false;
}
+ private boolean isActivePhoneCallOngoing() {
+ return mAudioMode == AudioManager.MODE_IN_CALL
+ || mAudioMode == AudioManager.MODE_IN_COMMUNICATION;
+ }
+
private KeyguardManager getKeyguardManager() {
if (mKeyguardManager == null) {
mKeyguardManager = (KeyguardManager) getContext().getSystemService(
@@ -2326,6 +2334,14 @@
}
}
+ @Override
+ protected void onDestroy() {
+ if (mOnModeChangedListener != null) {
+ getAudioManager().removeOnModeChangedListener(mOnModeChangedListener);
+ mOnModeChangedListener = null;
+ }
+ }
+
private class PanelMenuPresenterCallback implements MenuPresenter.Callback {
@Override
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
@@ -3208,6 +3224,15 @@
@Override
public void setMediaController(MediaController controller) {
mMediaController = controller;
+ if (controller != null && mOnModeChangedListener == null) {
+ mAudioMode = getAudioManager().getMode();
+ mOnModeChangedListener = mode -> mAudioMode = mode;
+ getAudioManager().addOnModeChangedListener(getContext().getMainExecutor(),
+ mOnModeChangedListener);
+ } else if (mOnModeChangedListener != null) {
+ getAudioManager().removeOnModeChangedListener(mOnModeChangedListener);
+ mOnModeChangedListener = null;
+ }
}
@Override
diff --git a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
index 83309fc..4d1234f 100644
--- a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
@@ -255,6 +255,7 @@
if (writeToFile) {
writeProtoLogToFileLocked();
logAndPrintln(pw, "Log written to " + mLogFile + ".");
+ mBuffer.resetBuffer();
}
if (mProtoLogEnabled) {
logAndPrintln(pw, "ERROR: logging was re-enabled while waiting for flush.");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 31903e2..0e95e30 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3154,7 +3154,11 @@
android:protectionLevel="normal" />
<!-- Allows an application to call
- {@link android.app.ActivityManager#killBackgroundProcesses}.
+ {@link android.app.ActivityManager#killBackgroundProcesses}.
+
+ <p class="note">Third party applications can only use this API to kill their own
+ processes.</p>
+
<p>Protection level: normal
-->
<permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 58c8b29..dafa0ad 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6092,9 +6092,4 @@
<!-- Whether to show weather on the lock screen by default. -->
<bool name="config_lockscreenWeatherEnabledByDefault">false</bool>
-
- <!-- Whether to reset Battery Stats on unplug when the battery level is high. -->
- <bool name="config_batteryStatsResetOnUnplugHighBatteryLevel">true</bool>
- <!-- Whether to reset Battery Stats on unplug if the battery was significantly charged -->
- <bool name="config_batteryStatsResetOnUnplugAfterSignificantCharge">true</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8addca2..591ba5f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4903,7 +4903,4 @@
<!-- Whether to show weather on the lockscreen by default. -->
<java-symbol type="bool" name="config_lockscreenWeatherEnabledByDefault" />
-
- <java-symbol type="bool" name="config_batteryStatsResetOnUnplugHighBatteryLevel" />
- <java-symbol type="bool" name="config_batteryStatsResetOnUnplugAfterSignificantCharge" />
</resources>
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsResetTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsResetTest.java
deleted file mode 100644
index 9c2d332..0000000
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsResetTest.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * 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.internal.os;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.os.BatteryManager;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class BatteryStatsResetTest {
-
- private static final int BATTERY_NOMINAL_VOLTAGE_MV = 3700;
- private static final int BATTERY_CAPACITY_UAH = 4_000_000;
- private static final int BATTERY_CHARGE_RATE_SECONDS_PER_LEVEL = 100;
-
- private MockClock mMockClock;
- private MockBatteryStatsImpl mBatteryStatsImpl;
-
-
- /**
- * Battery status. Must be one of the following:
- * {@link BatteryManager#BATTERY_STATUS_UNKNOWN}
- * {@link BatteryManager#BATTERY_STATUS_CHARGING}
- * {@link BatteryManager#BATTERY_STATUS_DISCHARGING}
- * {@link BatteryManager#BATTERY_STATUS_NOT_CHARGING}
- * {@link BatteryManager#BATTERY_STATUS_FULL}
- */
- private int mBatteryStatus;
- /**
- * Battery health. Must be one of the following:
- * {@link BatteryManager#BATTERY_HEALTH_UNKNOWN}
- * {@link BatteryManager#BATTERY_HEALTH_GOOD}
- * {@link BatteryManager#BATTERY_HEALTH_OVERHEAT}
- * {@link BatteryManager#BATTERY_HEALTH_DEAD}
- * {@link BatteryManager#BATTERY_HEALTH_OVER_VOLTAGE}
- * {@link BatteryManager#BATTERY_HEALTH_UNSPECIFIED_FAILURE}
- * {@link BatteryManager#BATTERY_HEALTH_COLD}
- */
- private int mBatteryHealth;
- /**
- * Battery plug type. Can be the union of any number of the following flags:
- * {@link BatteryManager#BATTERY_PLUGGED_AC}
- * {@link BatteryManager#BATTERY_PLUGGED_USB}
- * {@link BatteryManager#BATTERY_PLUGGED_WIRELESS}
- * {@link BatteryManager#BATTERY_PLUGGED_DOCK}
- *
- * Zero means the device is unplugged.
- */
- private int mBatteryPlugType;
- private int mBatteryLevel;
- private int mBatteryTemp;
- private int mBatteryVoltageMv;
- private int mBatteryChargeUah;
- private int mBatteryChargeFullUah;
- private long mBatteryChargeTimeToFullSeconds;
-
- @Before
- public void setUp() {
- final Context context = InstrumentationRegistry.getContext();
-
- mMockClock = new MockClock();
- mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock, context.getFilesDir());
- mBatteryStatsImpl.onSystemReady();
-
-
- // Set up the battery state. Start off with a fully charged plugged in battery.
- mBatteryStatus = BatteryManager.BATTERY_STATUS_FULL;
- mBatteryHealth = BatteryManager.BATTERY_HEALTH_GOOD;
- mBatteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
- mBatteryLevel = 100;
- mBatteryTemp = 70; // Arbitrary reasonable temperature.
- mBatteryVoltageMv = BATTERY_NOMINAL_VOLTAGE_MV;
- mBatteryChargeUah = BATTERY_CAPACITY_UAH;
- mBatteryChargeFullUah = BATTERY_CAPACITY_UAH;
- mBatteryChargeTimeToFullSeconds = 0;
- }
-
- @Test
- public void testResetOnUnplug_highBatteryLevel() {
- mBatteryStatsImpl.setBatteryStatsConfig(
- new BatteryStatsImpl.BatteryStatsConfig.Builder()
- .setResetOnUnplugHighBatteryLevel(true)
- .build());
-
- long expectedResetTimeUs = 0;
-
- unplugBattery();
- dischargeToLevel(60);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(80);
- unplugBattery();
- // Reset should not occur until battery level above 90.
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(95);
- // Reset should not occur until unplug.
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- unplugBattery();
- // Reset should occur on unplug now that battery level is high (>=90)
- expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // disable high battery level reset on unplug.
- mBatteryStatsImpl.setBatteryStatsConfig(
- new BatteryStatsImpl.BatteryStatsConfig.Builder()
- .setResetOnUnplugHighBatteryLevel(false)
- .build());
-
- dischargeToLevel(60);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(95);
- unplugBattery();
- // Reset should not occur since the high battery level logic has been disabled.
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
- }
-
- @Test
- public void testResetOnUnplug_significantCharge() {
- mBatteryStatsImpl.setBatteryStatsConfig(
- new BatteryStatsImpl.BatteryStatsConfig.Builder()
- .setResetOnUnplugAfterSignificantCharge(true)
- .build());
- long expectedResetTimeUs = 0;
-
- unplugBattery();
- // Battery level dropped below 20%.
- dischargeToLevel(15);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(50);
- unplugBattery();
- // Reset should not occur until battery level above 80
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(85);
- unplugBattery();
- // Reset should not occur because the charge session did not go from 20% to 80%
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Battery level dropped below 20%.
- dischargeToLevel(15);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(85);
- unplugBattery();
- // Reset should occur after significant charge amount.
- expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // disable reset on unplug after significant charge.
- mBatteryStatsImpl.setBatteryStatsConfig(
- new BatteryStatsImpl.BatteryStatsConfig.Builder()
- .setResetOnUnplugAfterSignificantCharge(false)
- .build());
-
- // Battery level dropped below 20%.
- dischargeToLevel(15);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(85);
- unplugBattery();
- // Reset should not occur after significant charge amount.
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
- }
-
- @Test
- public void testResetOnUnplug_manyPartialCharges() {
- long expectedResetTimeUs = 0;
-
- unplugBattery();
- // Cumulative battery discharged: 60%.
- dischargeToLevel(40);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(80);
- unplugBattery();
- // Reset should not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Cumulative battery discharged: 100%.
- dischargeToLevel(40);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(80);
- unplugBattery();
- // Reset should not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Cumulative battery discharged: 140%.
- dischargeToLevel(40);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(80);
- unplugBattery();
- // Reset should not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Cumulative battery discharged: 180%.
- dischargeToLevel(40);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(80);
- unplugBattery();
- // Reset should not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Cumulative battery discharged: 220%.
- dischargeToLevel(40);
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- chargeToLevel(80);
- unplugBattery();
- // Should reset after >200% of cumulative battery discharge
- expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
- }
-
- @Test
- public void testResetWhilePluggedIn_longPlugIn() {
- // disable high battery level reset on unplug.
- mBatteryStatsImpl.setBatteryStatsConfig(
- new BatteryStatsImpl.BatteryStatsConfig.Builder()
- .setResetOnUnplugHighBatteryLevel(false)
- .setResetOnUnplugAfterSignificantCharge(false)
- .build());
- long expectedResetTimeUs = 0;
-
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset should not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Increment time a day
- incTimeMs(24L * 60L * 60L * 1000L);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset should still not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Increment time a day
- incTimeMs(24L * 60L * 60L * 1000L);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset 47 hour threshold crossed, reset should occur.
- expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Increment time a day
- incTimeMs(24L * 60L * 60L * 1000L);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset should not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Increment time a day
- incTimeMs(24L * 60L * 60L * 1000L);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset another 47 hour threshold crossed, reset should occur.
- expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Increment time a day
- incTimeMs(24L * 60L * 60L * 1000L);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset should not occur
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- unplugBattery();
- plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
-
- // Increment time a day
- incTimeMs(24L * 60L * 60L * 1000L);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset should not occur, since unplug occurred recently.
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
-
- // Increment time a day
- incTimeMs(24L * 60L * 60L * 1000L);
- mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
- // Reset another 47 hour threshold crossed, reset should occur.
- expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
- assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
- }
-
- private void dischargeToLevel(int targetLevel) {
- mBatteryStatus = BatteryManager.BATTERY_STATUS_DISCHARGING;
- for (int level = mBatteryLevel - 1; level >= targetLevel; level--) {
- prepareBatteryLevel(level);
- incTimeMs(5000); // Arbitrary discharge rate.
- updateBatteryState();
- }
- }
-
- private void chargeToLevel(int targetLevel) {
- mBatteryStatus = BatteryManager.BATTERY_STATUS_CHARGING;
- for (int level = mBatteryLevel + 1; level <= targetLevel; level++) {
- if (level >= 100) mBatteryStatus = BatteryManager.BATTERY_STATUS_FULL;
- prepareBatteryLevel(level);
- incTimeMs(BATTERY_CHARGE_RATE_SECONDS_PER_LEVEL * 1000);
- updateBatteryState();
- }
- }
-
- private void unplugBattery() {
- mBatteryPlugType = 0;
- updateBatteryState();
- }
-
- private void plugBattery(int type) {
- mBatteryPlugType |= type;
- updateBatteryState();
- }
-
- private void prepareBatteryLevel(int level) {
- mBatteryLevel = level;
- mBatteryChargeUah = mBatteryLevel * mBatteryChargeFullUah / 100;
- mBatteryChargeTimeToFullSeconds =
- (100 - mBatteryLevel) * BATTERY_CHARGE_RATE_SECONDS_PER_LEVEL;
- }
-
- private void incTimeMs(long milliseconds) {
- mMockClock.realtime += milliseconds;
- mMockClock.uptime += milliseconds / 2; // Arbitrary slower uptime accumulation
- mMockClock.currentTime += milliseconds;
- }
-
- private void updateBatteryState() {
- mBatteryStatsImpl.setBatteryStateLocked(mBatteryStatus, mBatteryHealth, mBatteryPlugType,
- mBatteryLevel, mBatteryTemp, mBatteryVoltageMv, mBatteryChargeUah,
- mBatteryChargeFullUah, mBatteryChargeTimeToFullSeconds,
- mMockClock.elapsedRealtime(), mMockClock.uptimeMillis(),
- mMockClock.currentTimeMillis());
- }
-}
-
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
index ae2d1af..2742861 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
@@ -342,7 +342,7 @@
Context context = InstrumentationRegistry.getContext();
BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
mStatsRule.setCurrentTime(5 * MINUTE_IN_MS);
- batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ batteryStats.resetAllStatsCmdLocked();
BatteryUsageStatsStore batteryUsageStatsStore = new BatteryUsageStatsStore(context,
batteryStats, new File(context.getCacheDir(), "BatteryUsageStatsProviderTest"),
@@ -357,14 +357,14 @@
batteryStats.noteFlashlightOffLocked(APP_UID,
20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
mStatsRule.setCurrentTime(25 * MINUTE_IN_MS);
- batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ batteryStats.resetAllStatsCmdLocked();
batteryStats.noteFlashlightOnLocked(APP_UID,
30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
batteryStats.noteFlashlightOffLocked(APP_UID,
50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
mStatsRule.setCurrentTime(55 * MINUTE_IN_MS);
- batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ batteryStats.resetAllStatsCmdLocked();
// This section should be ignored because the timestamp is out or range
batteryStats.noteFlashlightOnLocked(APP_UID,
@@ -372,7 +372,7 @@
batteryStats.noteFlashlightOffLocked(APP_UID,
70 * MINUTE_IN_MS, 70 * MINUTE_IN_MS);
mStatsRule.setCurrentTime(75 * MINUTE_IN_MS);
- batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ batteryStats.resetAllStatsCmdLocked();
// This section should be ignored because it represents the current stats session
batteryStats.noteFlashlightOnLocked(APP_UID,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
index 11b9047..c9729fa 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
@@ -84,7 +84,7 @@
mMockClock.realtime = 1_000_000;
mMockClock.uptime = 1_000_000;
- mBatteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ mBatteryStats.resetAllStatsCmdLocked();
final long[] timestamps = mBatteryUsageStatsStore.listBatteryUsageStatsTimestamps();
assertThat(timestamps).hasLength(1);
@@ -114,7 +114,7 @@
final int numberOfSnapshots =
(int) (MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES / snapshotFileSize);
for (int i = 0; i < numberOfSnapshots + 2; i++) {
- mBatteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ mBatteryStats.resetAllStatsCmdLocked();
mMockClock.realtime += 10_000_000;
mMockClock.uptime += 10_000_000;
@@ -141,7 +141,7 @@
mMockClock.currentTime += 10_000_000;
prepareBatteryStats();
- mBatteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ mBatteryStats.resetAllStatsCmdLocked();
}
assertThat(getDirectorySize(mStoreDirectory)).isNotEqualTo(0);
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
index 9167382..c6e634c 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
@@ -17,6 +17,6 @@
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
- <corners android:radius="20dp" />
+ <corners android:radius="@dimen/caption_menu_corner_radius" />
<stroke android:width="1dp" android:color="#b3b3b3"/>
</shape>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
index f6e3f2e..f9aeb6a 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
@@ -21,7 +21,6 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/desktop_mode_decor_menu_background"
- android:elevation="@dimen/caption_menu_elevation"
android:divider="?android:attr/dividerHorizontal"
android:showDividers="middle"
android:dividerPadding="18dip">
@@ -63,38 +62,46 @@
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.5" />
- <Button
+ <ImageButton
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/fullscreen_button"
android:contentDescription="@string/fullscreen_text"
- android:background="@drawable/caption_fullscreen_button"/>
+ android:src="@drawable/caption_fullscreen_button"
+ android:scaleType="fitCenter"
+ android:background="?android:selectableItemBackgroundBorderless"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
- <Button
+ <ImageButton
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/split_screen_button"
android:contentDescription="@string/split_screen_text"
- android:background="@drawable/caption_split_screen_button"/>
+ android:src="@drawable/caption_split_screen_button"
+ android:scaleType="fitCenter"
+ android:background="?android:selectableItemBackgroundBorderless"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
- <Button
+ <ImageButton
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/floating_button"
android:contentDescription="@string/float_button_text"
- android:background="@drawable/caption_floating_button"/>
+ android:src="@drawable/caption_floating_button"
+ android:scaleType="fitCenter"
+ android:background="?android:selectableItemBackgroundBorderless"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
- <Button
+ <ImageButton
style="@style/CaptionWindowingButtonStyle"
android:id="@+id/desktop_button"
android:contentDescription="@string/desktop_text"
- android:background="@drawable/caption_desktop_button"/>
+ android:src="@drawable/caption_desktop_button"
+ android:scaleType="fitCenter"
+ android:background="?android:selectableItemBackgroundBorderless"/>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
index e8edad1..413cfd7 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -16,9 +16,7 @@
<com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:color/system_neutral1_900">
+ style="@style/LetterboxDialog">
<!-- The background of the top-level layout acts as the background dim. -->
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml
index ba9852c..5aff415 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_restart_dialog_layout.xml
@@ -16,14 +16,10 @@
<com.android.wm.shell.compatui.RestartDialogLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:color/system_neutral1_900">
+ style="@style/LetterboxDialog">
<!-- The background of the top-level layout acts as the background dim. -->
- <!--TODO (b/266288912): Resolve overdraw warning -->
-
<!-- Vertical margin will be set dynamically since it depends on task bounds.
Setting the alpha of the dialog container to 0, since it shouldn't be visible until the
enter animation starts. -->
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 6e750a3..965ab15 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -41,6 +41,9 @@
<color name="letterbox_education_accent_primary">@android:color/system_accent1_100</color>
<color name="letterbox_education_text_secondary">@android:color/system_neutral2_200</color>
+ <!-- Letterbox Dialog -->
+ <color name="letterbox_dialog_background">@android:color/system_neutral1_900</color>
+
<!-- GM2 colors -->
<color name="GM2_grey_200">#E8EAED</color>
<color name="GM2_grey_700">#5F6368</color>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 336c156..680ad51 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -370,6 +370,10 @@
<dimen name="freeform_resize_corner">44dp</dimen>
- <dimen name="caption_menu_elevation">4dp</dimen>
+ <!-- The radius of the caption menu shadow. -->
+ <dimen name="caption_menu_shadow_radius">4dp</dimen>
+
+ <!-- The radius of the caption menu corners. -->
+ <dimen name="caption_menu_corner_radius">20dp</dimen>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 0a0c49f..bc2e71d 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -38,11 +38,9 @@
</style>
<style name="CaptionWindowingButtonStyle">
- <item name="android:layout_width">32dp</item>
- <item name="android:layout_height">32dp</item>
+ <item name="android:layout_width">40dp</item>
+ <item name="android:layout_height">40dp</item>
<item name="android:padding">4dp</item>
- <item name="android:layout_marginTop">5dp</item>
- <item name="android:layout_marginBottom">5dp</item>
</style>
<style name="CaptionMenuButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless">
@@ -80,6 +78,12 @@
<item name="android:textColor">@color/tv_pip_edu_text</item>
</style>
+ <style name="LetterboxDialog" parent="@android:style/Theme.Holo">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:background">@color/letterbox_dialog_background</item>
+ </style>
+
<style name="RestartDialogTitleText">
<item name="android:textSize">24sp</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 71e15c1..c08085e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -61,6 +61,7 @@
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.notification.NotificationListenerService;
@@ -125,6 +126,15 @@
private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
private static final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
+ // TODO(b/256873975) Should use proper flag when available to shell/launcher
+ /**
+ * Whether bubbles are showing in the bubble bar from launcher. This is only available
+ * on large screens and {@link BubbleController#isShowingAsBubbleBar()} should be used
+ * to check all conditions that indicate if the bubble bar is in use.
+ */
+ private static final boolean BUBBLE_BAR_ENABLED =
+ SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
+
private final Context mContext;
private final BubblesImpl mImpl = new BubblesImpl();
private Bubbles.BubbleExpandListener mExpandListener;
@@ -150,9 +160,6 @@
private final ShellExecutor mBackgroundExecutor;
- // Whether or not we should show bubbles pinned at the bottom of the screen.
- private boolean mIsBubbleBarEnabled;
-
private BubbleLogger mLogger;
private BubbleData mBubbleData;
@Nullable private BubbleStackView mStackView;
@@ -533,10 +540,10 @@
mDataRepository.removeBubblesForUser(removedUserId, parentUserId);
}
- // TODO(b/256873975): Should pass this into the constructor once flags are available to shell.
- /** Sets whether the bubble bar is enabled (i.e. bubbles pinned to bottom on large screens). */
- public void setBubbleBarEnabled(boolean enabled) {
- mIsBubbleBarEnabled = enabled;
+ /** Whether bubbles are showing in the bubble bar. */
+ public boolean isShowingAsBubbleBar() {
+ // TODO(b/269670598): should also check that we're in gesture nav
+ return BUBBLE_BAR_ENABLED && mBubblePositioner.isLargeScreen();
}
/** Whether this userId belongs to the current user. */
@@ -605,12 +612,6 @@
mStackView.setUnbubbleConversationCallback(mSysuiProxy::onUnbubbleConversation);
}
- if (mIsBubbleBarEnabled && mBubblePositioner.isLargeScreen()) {
- mBubblePositioner.setUsePinnedLocation(true);
- } else {
- mBubblePositioner.setUsePinnedLocation(false);
- }
-
addToWindowManagerMaybe();
}
@@ -1852,13 +1853,6 @@
}
@Override
- public void setBubbleBarEnabled(boolean enabled) {
- mMainExecutor.execute(() -> {
- BubbleController.this.setBubbleBarEnabled(enabled);
- });
- }
-
- @Override
public void onNotificationPanelExpandedChanged(boolean expanded) {
mMainExecutor.execute(
() -> BubbleController.this.onNotificationPanelExpandedChanged(expanded));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 6230d22..3fd0967 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -283,7 +283,7 @@
}
boolean isShowingOverflow() {
- return mShowingOverflow && (isExpanded() || mPositioner.showingInTaskbar());
+ return mShowingOverflow && isExpanded();
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 07c5852..5ea2450 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -18,9 +18,6 @@
import static android.view.View.LAYOUT_DIRECTION_RTL;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.IntDef;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -39,8 +36,6 @@
import com.android.launcher3.icons.IconNormalizer;
import com.android.wm.shell.R;
-import java.lang.annotation.Retention;
-
/**
* Keeps track of display size, configuration, and specific bubble sizes. One place for all
* placement and positioning calculations to refer to.
@@ -50,15 +45,6 @@
? "BubblePositioner"
: BubbleDebugConfig.TAG_BUBBLES;
- @Retention(SOURCE)
- @IntDef({TASKBAR_POSITION_NONE, TASKBAR_POSITION_RIGHT, TASKBAR_POSITION_LEFT,
- TASKBAR_POSITION_BOTTOM})
- @interface TaskbarPosition {}
- public static final int TASKBAR_POSITION_NONE = -1;
- public static final int TASKBAR_POSITION_RIGHT = 0;
- public static final int TASKBAR_POSITION_LEFT = 1;
- public static final int TASKBAR_POSITION_BOTTOM = 2;
-
/** When the bubbles are collapsed in a stack only some of them are shown, this is how many. **/
public static final int NUM_VISIBLE_WHEN_RESTING = 2;
/** Indicates a bubble's height should be the maximum available space. **/
@@ -108,15 +94,9 @@
private int mOverflowHeight;
private int mMinimumFlyoutWidthLargeScreen;
- private PointF mPinLocation;
private PointF mRestingStackPosition;
private int[] mPaddings = new int[4];
- private boolean mShowingInTaskbar;
- private @TaskbarPosition int mTaskbarPosition = TASKBAR_POSITION_NONE;
- private int mTaskbarIconSize;
- private int mTaskbarSize;
-
public BubblePositioner(Context context, WindowManager windowManager) {
mContext = context;
mWindowManager = windowManager;
@@ -153,27 +133,11 @@
+ " insets: " + insets
+ " isLargeScreen: " + mIsLargeScreen
+ " isSmallTablet: " + mIsSmallTablet
- + " bounds: " + bounds
- + " showingInTaskbar: " + mShowingInTaskbar);
+ + " bounds: " + bounds);
}
updateInternal(mRotation, insets, bounds);
}
- /**
- * Updates position information to account for taskbar state.
- *
- * @param taskbarPosition which position the taskbar is displayed in.
- * @param showingInTaskbar whether the taskbar is being shown.
- */
- public void updateForTaskbar(int iconSize,
- @TaskbarPosition int taskbarPosition, boolean showingInTaskbar, int taskbarSize) {
- mShowingInTaskbar = showingInTaskbar;
- mTaskbarIconSize = iconSize;
- mTaskbarPosition = taskbarPosition;
- mTaskbarSize = taskbarSize;
- update();
- }
-
@VisibleForTesting
public void updateInternal(int rotation, Insets insets, Rect bounds) {
mRotation = rotation;
@@ -232,10 +196,6 @@
R.dimen.bubbles_flyout_min_width_large_screen);
mMaxBubbles = calculateMaxBubbles();
-
- if (mShowingInTaskbar) {
- adjustForTaskbar();
- }
}
/**
@@ -260,30 +220,6 @@
return mDefaultMaxBubbles;
}
- /**
- * Taskbar insets appear as navigationBar insets, however, unlike navigationBar this should
- * not inset bubbles UI as bubbles floats above the taskbar. This adjust the available space
- * and insets to account for the taskbar.
- */
- // TODO(b/171559950): When the insets are reported correctly we can remove this logic
- private void adjustForTaskbar() {
- // When bar is showing on edges... subtract that inset because we appear on top
- if (mShowingInTaskbar && mTaskbarPosition != TASKBAR_POSITION_BOTTOM) {
- WindowInsets metricInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
- Insets navBarInsets = metricInsets.getInsetsIgnoringVisibility(
- WindowInsets.Type.navigationBars());
- int newInsetLeft = mInsets.left;
- int newInsetRight = mInsets.right;
- if (mTaskbarPosition == TASKBAR_POSITION_LEFT) {
- mPositionRect.left -= navBarInsets.left;
- newInsetLeft -= navBarInsets.left;
- } else if (mTaskbarPosition == TASKBAR_POSITION_RIGHT) {
- mPositionRect.right += navBarInsets.right;
- newInsetRight -= navBarInsets.right;
- }
- mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);
- }
- }
/**
* @return a rect of available screen space accounting for orientation, system bars and cutouts.
@@ -327,14 +263,12 @@
* to the left or right side.
*/
public boolean showBubblesVertically() {
- return isLandscape() || mShowingInTaskbar || mIsLargeScreen;
+ return isLandscape() || mIsLargeScreen;
}
/** Size of the bubble. */
public int getBubbleSize() {
- return (mShowingInTaskbar && mTaskbarIconSize > 0)
- ? mTaskbarIconSize
- : mBubbleSize;
+ return mBubbleSize;
}
/** The amount of padding at the top of the screen that the bubbles avoid when being placed. */
@@ -699,9 +633,6 @@
/** The position the bubble stack should rest at when collapsed. */
public PointF getRestingPosition() {
- if (mPinLocation != null) {
- return mPinLocation;
- }
if (mRestingStackPosition == null) {
return getDefaultStartPosition();
}
@@ -713,9 +644,6 @@
* is being shown.
*/
public PointF getDefaultStartPosition() {
- if (mPinLocation != null) {
- return mPinLocation;
- }
// Start on the left if we're in LTR, right otherwise.
final boolean startOnLeft =
mContext.getResources().getConfiguration().getLayoutDirection()
@@ -730,7 +658,6 @@
1 /* default starts with 1 bubble */));
}
-
/**
* Returns the region that the stack position must stay within. This goes slightly off the left
* and right sides of the screen, below the status bar/cutout and above the navigation bar.
@@ -751,39 +678,6 @@
}
/**
- * @return whether the bubble stack is pinned to the taskbar.
- */
- public boolean showingInTaskbar() {
- return mShowingInTaskbar;
- }
-
- /**
- * @return the taskbar position if set.
- */
- public int getTaskbarPosition() {
- return mTaskbarPosition;
- }
-
- public int getTaskbarSize() {
- return mTaskbarSize;
- }
-
- /**
- * In some situations bubbles will be pinned to a specific onscreen location. This sets whether
- * bubbles should be pinned or not.
- */
- public void setUsePinnedLocation(boolean usePinnedLocation) {
- if (usePinnedLocation) {
- mShowingInTaskbar = true;
- mPinLocation = new PointF(mPositionRect.right - mBubbleSize,
- mPositionRect.bottom - mBubbleSize);
- } else {
- mPinLocation = null;
- mShowingInTaskbar = false;
- }
- }
-
- /**
* Navigation bar has an area where system gestures can be started from.
*
* @return {@link Rect} for system navigation bar gesture zone
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index f2afefe..15f8eac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -680,8 +680,6 @@
// Re-show the expanded view if we hid it.
showExpandedViewIfNeeded();
- } else if (mPositioner.showingInTaskbar()) {
- mStackAnimationController.snapStackBack();
} else {
// Fling the stack to the edge, and save whether or not it's going to end up on
// the left side of the screen.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index df43257..a5deac5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -257,11 +257,6 @@
*/
void onUserRemoved(int removedUserId);
- /**
- * Sets whether bubble bar should be enabled or not.
- */
- void setBubbleBarEnabled(boolean enabled);
-
/** Listener to find out about stack expansion / collapse events. */
interface BubbleExpandListener {
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
index 0ee0ea6..5533842 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java
@@ -417,23 +417,9 @@
}
/**
- * Snaps the stack back to the previous resting position.
- */
- public void snapStackBack() {
- if (mLayout == null) {
- return;
- }
- PointF p = getStackPositionAlongNearestHorizontalEdge();
- springStackAfterFling(p.x, p.y);
- }
-
- /**
* Where the stack would be if it were snapped to the nearest horizontal edge (left or right).
*/
public PointF getStackPositionAlongNearestHorizontalEdge() {
- if (mPositioner.showingInTaskbar()) {
- return mPositioner.getRestingPosition();
- }
final PointF stackPos = getStackPosition();
final boolean onLeft = mLayout.isFirstChildXLeftOfCenter(stackPos.x);
final RectF bounds = mPositioner.getAllowableStackPositionRegion(getBubbleCount());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index a673384..7d3e7ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -204,7 +204,7 @@
// and exit, since exit itself can trigger a number of changes that update the stages.
private boolean mShouldUpdateRecents;
private boolean mExitSplitScreenOnHide;
- private boolean mIsSplitEntering;
+ private boolean mIsDividerRemoteAnimating;
private boolean mIsDropEntering;
private boolean mIsExiting;
@@ -881,7 +881,7 @@
// Set false to avoid record new bounds with old task still on top;
mShouldUpdateRecents = false;
- mIsSplitEntering = true;
+ mIsDividerRemoteAnimating = true;
if (mSplitRequest == null) {
mSplitRequest = new SplitRequest(mainTaskId,
mainPendingIntent != null ? mainPendingIntent.getIntent() : null,
@@ -974,7 +974,7 @@
}
private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
- mIsSplitEntering = false;
+ mIsDividerRemoteAnimating = false;
mShouldUpdateRecents = true;
mSplitRequest = null;
// If any stage has no child after animation finished, it means that split will display
@@ -1240,7 +1240,7 @@
}
});
mShouldUpdateRecents = false;
- mIsSplitEntering = false;
+ mIsDividerRemoteAnimating = false;
mSplitLayout.getInvisibleBounds(mTempRect1);
if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) {
@@ -1573,7 +1573,7 @@
&& !ENABLE_SHELL_TRANSITIONS) {
// Clear the divider remote animating flag as the divider will be re-rendered to apply
// the new rotation config.
- mIsSplitEntering = false;
+ mIsDividerRemoteAnimating = false;
mSplitLayout.update(null /* t */);
onLayoutSizeChanged(mSplitLayout);
}
@@ -1623,9 +1623,9 @@
}
void onChildTaskAppeared(StageListenerImpl stageListener, int taskId) {
+ // Handle entering split screen while there is a split pair running in the background.
if (stageListener == mSideStageListener && !isSplitScreenVisible() && isSplitActive()
- && !mIsSplitEntering) {
- // Handle entring split case here if split already running background.
+ && mSplitRequest == null) {
if (mIsDropEntering) {
mSplitLayout.resetDividerPosition();
} else {
@@ -1717,7 +1717,7 @@
mDividerVisible = visible;
sendSplitVisibilityChanged();
- if (mIsSplitEntering) {
+ if (mIsDividerRemoteAnimating) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
" Skip animating divider bar due to it's remote animating.");
return;
@@ -1737,7 +1737,7 @@
" Skip animating divider bar due to divider leash not ready.");
return;
}
- if (mIsSplitEntering) {
+ if (mIsDividerRemoteAnimating) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
" Skip animating divider bar due to it's remote animating.");
return;
@@ -1805,7 +1805,8 @@
mSplitLayout.flingDividerToDismiss(
mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT,
EXIT_REASON_APP_FINISHED);
- } else if (!isSplitScreenVisible() && !mIsSplitEntering) {
+ } else if (!isSplitScreenVisible() && mSplitRequest == null) {
+ // Dismiss split screen in the background once any sides of the split become empty.
exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED);
}
} else if (isSideStage && hasChildren && !mMainStage.isActive()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 0779f1d..72da108 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -74,6 +74,8 @@
private boolean mDesktopActive;
private AdditionalWindow mHandleMenu;
private final int mHandleMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
+ private final int mHandleMenuShadowRadiusId = R.dimen.caption_menu_shadow_radius;
+ private final int mHandleMenuCornerRadiusId = R.dimen.caption_menu_corner_radius;
private PointF mHandleMenuPosition = new PointF();
DesktopModeWindowDecoration(
@@ -353,19 +355,16 @@
.windowConfiguration.getBounds().width();
final int menuWidth = loadDimensionPixelSize(resources, mHandleMenuWidthId);
final int menuHeight = loadDimensionPixelSize(resources, mCaptionMenuHeightId);
-
- // Elevation gives the appearance of a changed x/y coordinate; this is to fix that
- int elevationOffset = 2 * loadDimensionPixelSize(resources,
- R.dimen.caption_menu_elevation);
+ final int shadowRadius = loadDimensionPixelSize(resources, mHandleMenuShadowRadiusId);
+ final int cornerRadius = loadDimensionPixelSize(resources, mHandleMenuCornerRadiusId);
final int x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
- - mResult.mDecorContainerOffsetX - elevationOffset;
- final int y =
- mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY - elevationOffset;
+ - mResult.mDecorContainerOffsetX;
+ final int y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
mHandleMenuPosition.set(x, y);
String namePrefix = "Caption Menu";
mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t, x, y,
- menuWidth, menuHeight, 2 * elevationOffset);
+ menuWidth, menuHeight, shadowRadius, cornerRadius);
mSyncQueue.runInSync(transaction -> {
transaction.merge(t);
t.close();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index ae685ad..133826f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -391,11 +391,12 @@
* @param yPos y position of new window
* @param width width of new window
* @param height height of new window
- * @param cropPadding padding to add to window crop to ensure shadows display properly
- * @return
+ * @param shadowRadius radius of the shadow of the new window
+ * @param cornerRadius radius of the corners of the new window
+ * @return the {@link AdditionalWindow} that was added.
*/
AdditionalWindow addWindow(int layoutId, String namePrefix, SurfaceControl.Transaction t,
- int xPos, int yPos, int width, int height, int cropPadding) {
+ int xPos, int yPos, int width, int height, int shadowRadius, int cornerRadius) {
final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
SurfaceControl windowSurfaceControl = builder
.setName(namePrefix + " of Task=" + mTaskInfo.taskId)
@@ -404,9 +405,10 @@
.build();
View v = LayoutInflater.from(mDecorWindowContext).inflate(layoutId, null);
- t.setPosition(
- windowSurfaceControl, xPos, yPos)
- .setWindowCrop(windowSurfaceControl, width + cropPadding, height + cropPadding)
+ t.setPosition(windowSurfaceControl, xPos, yPos)
+ .setWindowCrop(windowSurfaceControl, width, height)
+ .setShadowRadius(windowSurfaceControl, shadowRadius)
+ .setCornerRadius(windowSurfaceControl, cornerRadius)
.show(windowSurfaceControl);
final WindowManager.LayoutParams lp =
new WindowManager.LayoutParams(width, height,
diff --git a/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml b/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
index fac0461..47a116b 100644
--- a/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml
@@ -20,6 +20,7 @@
package="com.android.wm.shell.tests">
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+ <uses-permission android:name="android.permission.VIBRATE"/>
<application android:debuggable="true" android:largeHeap="true">
<uses-library android:name="android.test.mock" />
diff --git a/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml b/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
index 27d40b2..aa1b241 100644
--- a/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
@@ -24,4 +24,6 @@
<dimen name="test_window_decor_bottom_outset">40dp</dimen>
<dimen name="test_window_decor_shadow_radius">5dp</dimen>
<dimen name="test_window_decor_resize_handle">10dp</dimen>
+ <dimen name="test_caption_menu_shadow_radius">4dp</dimen>
+ <dimen name="test_caption_menu_corner_radius">20dp</dimen>
</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index b80edce..7e39b5b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -108,6 +108,8 @@
private SurfaceControl.Transaction mMockSurfaceControlAddWindowT;
private WindowDecoration.RelayoutParams mRelayoutParams = new WindowDecoration.RelayoutParams();
private int mCaptionMenuWidthId;
+ private int mCaptionMenuShadowRadiusId;
+ private int mCaptionMenuCornerRadiusId;
@Before
public void setUp() {
@@ -118,6 +120,8 @@
mRelayoutParams.mLayoutResId = 0;
mRelayoutParams.mCaptionHeightId = R.dimen.test_freeform_decor_caption_height;
mCaptionMenuWidthId = R.dimen.test_freeform_decor_caption_menu_width;
+ mCaptionMenuShadowRadiusId = R.dimen.test_caption_menu_shadow_radius;
+ mCaptionMenuCornerRadiusId = R.dimen.test_caption_menu_corner_radius;
mRelayoutParams.mShadowRadiusId = R.dimen.test_window_decor_shadow_radius;
doReturn(mMockSurfaceControlViewHost).when(mMockSurfaceControlViewHostFactory)
@@ -431,7 +435,19 @@
verify(additionalWindowSurfaceBuilder).setParent(decorContainerSurface);
verify(additionalWindowSurfaceBuilder).build();
verify(mMockSurfaceControlAddWindowT).setPosition(additionalWindowSurface, 20, 40);
- verify(mMockSurfaceControlAddWindowT).setWindowCrop(additionalWindowSurface, 442, 74);
+ final int width = WindowDecoration.loadDimensionPixelSize(
+ mContext.getResources(), mCaptionMenuWidthId);
+ final int height = WindowDecoration.loadDimensionPixelSize(
+ mContext.getResources(), mRelayoutParams.mCaptionHeightId);
+ verify(mMockSurfaceControlAddWindowT).setWindowCrop(additionalWindowSurface, width, height);
+ final int shadowRadius = WindowDecoration.loadDimensionPixelSize(mContext.getResources(),
+ mCaptionMenuShadowRadiusId);
+ verify(mMockSurfaceControlAddWindowT)
+ .setShadowRadius(additionalWindowSurface, shadowRadius);
+ final int cornerRadius = WindowDecoration.loadDimensionPixelSize(mContext.getResources(),
+ mCaptionMenuCornerRadiusId);
+ verify(mMockSurfaceControlAddWindowT)
+ .setCornerRadius(additionalWindowSurface, cornerRadius);
verify(mMockSurfaceControlAddWindowT).show(additionalWindowSurface);
verify(mMockSurfaceControlViewHostFactory, Mockito.times(2))
.create(any(), eq(defaultDisplay), any());
@@ -559,13 +575,15 @@
int y = mRelayoutParams.mCaptionY;
int width = loadDimensionPixelSize(resources, mCaptionMenuWidthId);
int height = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionHeightId);
+ int shadowRadius = loadDimensionPixelSize(resources, mCaptionMenuShadowRadiusId);
+ int cornerRadius = loadDimensionPixelSize(resources, mCaptionMenuCornerRadiusId);
String name = "Test Window";
WindowDecoration.AdditionalWindow additionalWindow =
addWindow(R.layout.desktop_mode_decor_handle_menu, name,
mMockSurfaceControlAddWindowT,
x - mRelayoutResult.mDecorContainerOffsetX,
y - mRelayoutResult.mDecorContainerOffsetY,
- width, height, 10);
+ width, height, shadowRadius, cornerRadius);
return additionalWindow;
}
}
diff --git a/packages/SettingsLib/DeviceStateRotationLock/OWNERS b/packages/SettingsLib/DeviceStateRotationLock/OWNERS
new file mode 100644
index 0000000..091df26
--- /dev/null
+++ b/packages/SettingsLib/DeviceStateRotationLock/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/packages/SettingsLib/src/com/android/settingslib/devicestate/OWNERS
\ No newline at end of file
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt
index 40a5e97..c49a487 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt
@@ -26,7 +26,7 @@
* currently not attached or visible).
*
* @param cujType the CUJ type from the [com.android.internal.jank.InteractionJankMonitor]
- * associated to the launch that will use this controller.
+ * associated to the launch that will use this controller.
*/
fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller?
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt
index 9668066..3417ffd 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt
@@ -75,7 +75,7 @@
* - Get the associated [Context].
* - Compute whether we are expanding fully above the launch container.
* - Get to overlay to which we initially put the window background layer, until the opening
- * window is made visible (see [openingWindowSyncView]).
+ * window is made visible (see [openingWindowSyncView]).
*
* This container can be changed to force this [Controller] to animate the expanding view
* inside a different location, for instance to ensure correct layering during the
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
index b98b9221..ed8e705 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
@@ -24,7 +24,7 @@
* Set whether this view should block/postpone all calls to [View.setVisibility]. This ensures
* that this view:
* - remains invisible during the launch animation given that it is ghosted and already drawn
- * somewhere else.
+ * somewhere else.
* - remains invisible as long as a dialog expanded from it is shown.
* - restores its expected visibility once the dialog expanded from it is dismissed.
*
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
index 0e2d23b..6946e6b 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
@@ -182,9 +182,9 @@
* Represents a TransitionInfo object as an array of old-style targets
*
* @param wallpapers If true, this will return wallpaper targets; otherwise it returns
- * non-wallpaper targets.
+ * non-wallpaper targets.
* @param leashMap Temporary map of change leash -> launcher leash. Is an output, so should
- * be populated by this function. If null, it is ignored.
+ * be populated by this function. If null, it is ignored.
*/
fun wrapTargets(
info: TransitionInfo,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt
index a96f893..b89a8b0 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt
@@ -6,6 +6,7 @@
/**
* Interpolate alpha for notification background scrim during shade expansion.
+ *
* @param fraction Shade expansion fraction
*/
@JvmStatic
@@ -16,6 +17,7 @@
/**
* Interpolate alpha for shade content during shade expansion.
+ *
* @param fraction Shade expansion fraction
*/
@JvmStatic
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
index 341784e..468a8b1 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
@@ -161,7 +161,6 @@
* This API is useful to continue animation from the middle of the state. For example, if you
* animate weight from 200 to 400, then if you want to move back to 200 at the half of the
* animation, it will look like
- *
* <pre> <code>
* ```
* val interp = TextInterpolator(layout)
@@ -497,7 +496,9 @@
count,
layout.textDirectionHeuristic,
paint
- ) { _, _, glyphs, _ -> runs.add(glyphs) }
+ ) { _, _, glyphs, _ ->
+ runs.add(glyphs)
+ }
out.add(runs)
if (lineNo > 0) {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
index 0b842ad..5ed723b 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
@@ -25,7 +25,6 @@
/**
* Shader class that renders an expanding ripple effect. The ripple contains three elements:
- *
* 1. an expanding filled [RippleShape] that appears in the beginning and quickly fades away
* 2. an expanding ring that appears throughout the effect
* 3. an expanding ring-shaped area that reveals noise over #2.
@@ -311,6 +310,7 @@
* Parameters used for fade in and outs of the ripple.
*
* <p>Note that all the fade in/ outs are "linear" progression.
+ *
* ```
* (opacity)
* 1
@@ -325,6 +325,7 @@
* fadeIn fadeOut
* Start & End Start & End
* ```
+ *
* <p>If no fade in/ out is needed, set [fadeInStart] and [fadeInEnd] to 0; [fadeOutStart] and
* [fadeOutEnd] to 1.
*/
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
index 79bc2f4..89871fa7 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
@@ -30,12 +30,14 @@
* Noise move speed variables.
*
* Its sign determines the direction; magnitude determines the speed. <ul>
+ *
* ```
* <li> [noiseMoveSpeedX] positive: right to left; negative: left to right.
* <li> [noiseMoveSpeedY] positive: bottom to top; negative: top to bottom.
* <li> [noiseMoveSpeedZ] its sign doesn't matter much, as it moves in Z direction. Use it
* to add turbulence in place.
* ```
+ *
* </ul>
*/
val noiseMoveSpeedX: Float = 0f,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/util/AnimatorExtensions.kt b/packages/SystemUI/animation/src/com/android/systemui/util/AnimatorExtensions.kt
new file mode 100644
index 0000000..35dbb89
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/util/AnimatorExtensions.kt
@@ -0,0 +1,80 @@
+/*
+ * 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.util
+
+import androidx.core.animation.Animator
+
+/**
+ * Add an action which will be invoked when the animation has ended.
+ *
+ * @return the [Animator.AnimatorListener] added to the Animator
+ * @see Animator.end
+ */
+inline fun Animator.doOnEnd(
+ crossinline action: (animator: Animator) -> Unit
+): Animator.AnimatorListener = addListener(onEnd = action)
+
+/**
+ * Add an action which will be invoked when the animation has started.
+ *
+ * @return the [Animator.AnimatorListener] added to the Animator
+ * @see Animator.start
+ */
+inline fun Animator.doOnStart(
+ crossinline action: (animator: Animator) -> Unit
+): Animator.AnimatorListener = addListener(onStart = action)
+
+/**
+ * Add an action which will be invoked when the animation has been cancelled.
+ *
+ * @return the [Animator.AnimatorListener] added to the Animator
+ * @see Animator.cancel
+ */
+inline fun Animator.doOnCancel(
+ crossinline action: (animator: Animator) -> Unit
+): Animator.AnimatorListener = addListener(onCancel = action)
+
+/**
+ * Add an action which will be invoked when the animation has repeated.
+ *
+ * @return the [Animator.AnimatorListener] added to the Animator
+ */
+inline fun Animator.doOnRepeat(
+ crossinline action: (animator: Animator) -> Unit
+): Animator.AnimatorListener = addListener(onRepeat = action)
+
+/**
+ * Add a listener to this Animator using the provided actions.
+ *
+ * @return the [Animator.AnimatorListener] added to the Animator
+ */
+inline fun Animator.addListener(
+ crossinline onEnd: (animator: Animator) -> Unit = {},
+ crossinline onStart: (animator: Animator) -> Unit = {},
+ crossinline onCancel: (animator: Animator) -> Unit = {},
+ crossinline onRepeat: (animator: Animator) -> Unit = {}
+): Animator.AnimatorListener {
+ val listener =
+ object : Animator.AnimatorListener {
+ override fun onAnimationRepeat(animator: Animator) = onRepeat(animator)
+ override fun onAnimationEnd(animator: Animator) = onEnd(animator)
+ override fun onAnimationCancel(animator: Animator) = onCancel(animator)
+ override fun onAnimationStart(animator: Animator) = onStart(animator)
+ }
+ addListener(listener)
+ return listener
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DemotingTestWithoutBugDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DemotingTestWithoutBugDetector.kt
new file mode 100644
index 0000000..f64ea45
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DemotingTestWithoutBugDetector.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.internal.systemui.lint
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import org.jetbrains.uast.UAnnotation
+import org.jetbrains.uast.UElement
+
+class DemotingTestWithoutBugDetector : Detector(), SourceCodeScanner {
+ override fun getApplicableUastTypes(): List<Class<out UElement>> {
+ return listOf(UAnnotation::class.java)
+ }
+
+ override fun createUastHandler(context: JavaContext): UElementHandler {
+ return object : UElementHandler() {
+ override fun visitAnnotation(node: UAnnotation) {
+ if (node.qualifiedName !in DEMOTING_ANNOTATION) {
+ return
+ }
+ val bugId = node.findAttributeValue("bugId")!!.evaluate() as Int
+ if (bugId <= 0) {
+ val location = context.getLocation(node)
+ val message = "Please attach a bug id to track demoted test"
+ context.report(ISSUE, node, location, message)
+ }
+ }
+ }
+ }
+
+ companion object {
+ val DEMOTING_ANNOTATION =
+ listOf("androidx.test.filters.FlakyTest", "android.platform.test.annotations.FlakyTest")
+
+ @JvmField
+ val ISSUE: Issue =
+ Issue.create(
+ id = "DemotingTestWithoutBug",
+ briefDescription = "Demoting a test without attaching a bug.",
+ explanation =
+ """
+ Annotations (`@FlakyTest`) demote tests to an unmonitored \
+ test suite. Please set the `bugId` field in such annotations to track \
+ the test status.
+ """,
+ category = Category.TESTING,
+ priority = 8,
+ severity = Severity.WARNING,
+ implementation =
+ Implementation(
+ DemotingTestWithoutBugDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+ }
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
index 84f7050..387b67d 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
@@ -39,7 +39,8 @@
RegisterReceiverViaContextDetector.ISSUE,
SoftwareBitmapDetector.ISSUE,
NonInjectedServiceDetector.ISSUE,
- StaticSettingsProviderDetector.ISSUE
+ StaticSettingsProviderDetector.ISSUE,
+ DemotingTestWithoutBugDetector.ISSUE
)
override val api: Int
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetectorTest.kt
index a4b59fd..a5f832a 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetectorTest.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/CleanArchitectureDependencyViolationDetectorTest.kt
@@ -64,7 +64,8 @@
class BadClass(
private val viewModel: ViewModel,
)
- """.trimIndent()
+ """
+ .trimIndent()
)
)
.issues(
@@ -98,7 +99,8 @@
class BadClass(
private val repository: Repository,
)
- """.trimIndent()
+ """
+ .trimIndent()
)
)
.issues(
@@ -136,7 +138,8 @@
private val interactor: Interactor,
private val viewmodel: ViewModel,
)
- """.trimIndent()
+ """
+ .trimIndent()
)
)
.issues(
@@ -176,7 +179,8 @@
class BadClass(
private val interactor: Interactor,
)
- """.trimIndent()
+ """
+ .trimIndent()
)
)
.issues(
@@ -207,7 +211,8 @@
data class Model(
private val name: String,
)
- """.trimIndent()
+ """
+ .trimIndent()
)
private val REPOSITORY_FILE =
TestFiles.kotlin(
@@ -228,7 +233,8 @@
return models
}
}
- """.trimIndent()
+ """
+ .trimIndent()
)
private val INTERACTOR_FILE =
TestFiles.kotlin(
@@ -245,7 +251,8 @@
return repository.getModels()
}
}
- """.trimIndent()
+ """
+ .trimIndent()
)
private val VIEW_MODEL_FILE =
TestFiles.kotlin(
@@ -262,7 +269,8 @@
return interactor.getModels().map { model -> model.name }
}
}
- """.trimIndent()
+ """
+ .trimIndent()
)
private val NON_CLEAN_ARCHITECTURE_FILE =
TestFiles.kotlin(
@@ -282,7 +290,8 @@
)
}
}
- """.trimIndent()
+ """
+ .trimIndent()
)
private val LEGITIMATE_FILES =
arrayOf(
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DemotingTestWithoutBugDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DemotingTestWithoutBugDetectorTest.kt
new file mode 100644
index 0000000..557c300
--- /dev/null
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DemotingTestWithoutBugDetectorTest.kt
@@ -0,0 +1,151 @@
+/*
+ * 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.internal.systemui.lint
+
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestFiles
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+
+class DemotingTestWithoutBugDetectorTest : SystemUILintDetectorTest() {
+
+ override fun getDetector(): Detector = DemotingTestWithoutBugDetector()
+ override fun getIssues(): List<Issue> = listOf(DemotingTestWithoutBugDetector.ISSUE)
+
+ @Test
+ fun testMarkFlaky_withBugId() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import androidx.test.filters.FlakyTest;
+
+ @FlakyTest(bugId = 123)
+ public class TestClass {
+ public void testCase() {}
+ }
+ """
+ )
+ .indented(),
+ *stubs
+ )
+ .issues(DemotingTestWithoutBugDetector.ISSUE)
+ .run()
+ .expectClean()
+
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.platform.test.annotations.FlakyTest;
+
+ @FlakyTest(bugId = 123)
+ public class TestClass {
+ public void testCase() {}
+ }
+ """
+ )
+ .indented(),
+ *stubs
+ )
+ .issues(DemotingTestWithoutBugDetector.ISSUE)
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun testMarkFlaky_withoutBugId() {
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import androidx.test.filters.FlakyTest;
+
+ @FlakyTest
+ public class TestClass {
+ public void testCase() {}
+ }
+ """
+ )
+ .indented(),
+ *stubs
+ )
+ .issues(DemotingTestWithoutBugDetector.ISSUE)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:4: Warning: Please attach a bug id to track demoted test [DemotingTestWithoutBug]
+ @FlakyTest
+ ~~~~~~~~~~
+ 0 errors, 1 warnings
+ """
+ )
+
+ lint()
+ .files(
+ TestFiles.java(
+ """
+ package test.pkg;
+ import android.platform.test.annotations.FlakyTest;
+
+ @FlakyTest
+ public class TestClass {
+ public void testCase() {}
+ }
+ """
+ )
+ .indented(),
+ *stubs
+ )
+ .issues(DemotingTestWithoutBugDetector.ISSUE)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:4: Warning: Please attach a bug id to track demoted test [DemotingTestWithoutBug]
+ @FlakyTest
+ ~~~~~~~~~~
+ 0 errors, 1 warnings
+ """
+ )
+ }
+
+ private val filtersFlakyTestStub: TestFile =
+ java(
+ """
+ package androidx.test.filters;
+
+ public @interface FlakyTest {
+ int bugId() default -1;
+ }
+ """
+ )
+ private val annotationsFlakyTestStub: TestFile =
+ java(
+ """
+ package android.platform.test.annotations;
+
+ public @interface FlakyTest {
+ int bugId() default -1;
+ }
+ """
+ )
+ private val stubs = arrayOf(filtersFlakyTestStub, annotationsFlakyTestStub)
+}
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DumpableNotRegisteredDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DumpableNotRegisteredDetectorTest.kt
index 3d6cbc7..95b7005 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DumpableNotRegisteredDetectorTest.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DumpableNotRegisteredDetectorTest.kt
@@ -37,7 +37,8 @@
class SomeClass() {
}
- """.trimIndent()
+ """
+ .trimIndent()
),
*stubs,
)
@@ -67,7 +68,8 @@
pw.println("testDump");
}
}
- """.trimIndent()
+ """
+ .trimIndent()
),
*stubs,
)
@@ -97,7 +99,8 @@
pw.println("testDump");
}
}
- """.trimIndent()
+ """
+ .trimIndent()
),
*stubs,
)
@@ -127,7 +130,8 @@
pw.println("testDump");
}
}
- """.trimIndent()
+ """
+ .trimIndent()
),
*stubs,
)
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/SystemUiController.kt b/packages/SystemUI/compose/core/src/com/android/compose/SystemUiController.kt
index a02954a..08ab146 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/SystemUiController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/SystemUiController.kt
@@ -78,11 +78,10 @@
* Set the status bar color.
*
* @param color The **desired** [Color] to set. This may require modification if running on an
- * API level that only supports white status bar icons.
+ * API level that only supports white status bar icons.
* @param darkIcons Whether dark status bar icons would be preferable.
* @param transformColorForLightContent A lambda which will be invoked to transform [color] if
- * dark icons were requested but are not available. Defaults to applying a black scrim.
- *
+ * dark icons were requested but are not available. Defaults to applying a black scrim.
* @see statusBarDarkContentEnabled
*/
fun setStatusBarColor(
@@ -95,16 +94,15 @@
* Set the navigation bar color.
*
* @param color The **desired** [Color] to set. This may require modification if running on an
- * API level that only supports white navigation bar icons. Additionally this will be ignored
- * and [Color.Transparent] will be used on API 29+ where gesture navigation is preferred or the
- * system UI automatically applies background protection in other navigation modes.
+ * API level that only supports white navigation bar icons. Additionally this will be ignored
+ * and [Color.Transparent] will be used on API 29+ where gesture navigation is preferred or
+ * the system UI automatically applies background protection in other navigation modes.
* @param darkIcons Whether dark navigation bar icons would be preferable.
* @param navigationBarContrastEnforced Whether the system should ensure that the navigation bar
- * has enough contrast when a fully transparent background is requested. Only supported on API
- * 29+.
+ * has enough contrast when a fully transparent background is requested. Only supported on API
+ * 29+.
* @param transformColorForLightContent A lambda which will be invoked to transform [color] if
- * dark icons were requested but are not available. Defaults to applying a black scrim.
- *
+ * dark icons were requested but are not available. Defaults to applying a black scrim.
* @see navigationBarDarkContentEnabled
* @see navigationBarContrastEnforced
*/
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
index cfc38df..d4a81f9 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
@@ -255,7 +255,9 @@
.onGloballyPositioned {
controller.boundsInComposeViewRoot.value = it.boundsInRoot()
}
- ) { wrappedContent(controller.expandable) }
+ ) {
+ wrappedContent(controller.expandable)
+ }
}
else -> {
val clickModifier =
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
index edb10c7d..767756e 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
@@ -156,9 +156,9 @@
* Create a [LaunchAnimator.Controller] that is going to be used to drive an activity or dialog
* animation. This controller will:
* 1. Compute the start/end animation state using [boundsInComposeViewRoot] and the location of
- * composeViewRoot on the screen.
+ * composeViewRoot on the screen.
* 2. Update [animatorState] with the current animation state if we are animating, or null
- * otherwise.
+ * otherwise.
*/
private fun launchController(): LaunchAnimator.Controller {
return object : LaunchAnimator.Controller {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/pager/Pager.kt b/packages/SystemUI/compose/core/src/com/android/compose/pager/Pager.kt
index eb9d625..a80a1f9 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/pager/Pager.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/pager/Pager.kt
@@ -86,21 +86,20 @@
/**
* A horizontally scrolling layout that allows users to flip between items to the left and right.
*
- * @sample com.google.accompanist.sample.pager.HorizontalPagerSample
- *
* @param count the number of pages.
* @param modifier the modifier to apply to this layout.
* @param state the state object to be used to control or observe the pager's state.
* @param reverseLayout reverse the direction of scrolling and layout, when `true` items will be
- * composed from the end to the start and [PagerState.currentPage] == 0 will mean the first item is
- * located at the end.
+ * composed from the end to the start and [PagerState.currentPage] == 0 will mean the first item
+ * is located at the end.
* @param itemSpacing horizontal spacing to add between items.
* @param flingBehavior logic describing fling behavior.
* @param key the scroll position will be maintained based on the key, which means if you add/remove
- * items before the current visible item the item with the given key will be kept as the first
- * visible one.
+ * items before the current visible item the item with the given key will be kept as the first
+ * visible one.
* @param content a block which describes the content. Inside this block you can reference
- * [PagerScope.currentPage] and other properties in [PagerScope].
+ * [PagerScope.currentPage] and other properties in [PagerScope].
+ * @sample com.google.accompanist.sample.pager.HorizontalPagerSample
*/
@ExperimentalPagerApi
@Composable
@@ -134,21 +133,20 @@
/**
* A vertically scrolling layout that allows users to flip between items to the top and bottom.
*
- * @sample com.google.accompanist.sample.pager.VerticalPagerSample
- *
* @param count the number of pages.
* @param modifier the modifier to apply to this layout.
* @param state the state object to be used to control or observe the pager's state.
* @param reverseLayout reverse the direction of scrolling and layout, when `true` items will be
- * composed from the bottom to the top and [PagerState.currentPage] == 0 will mean the first item is
- * located at the bottom.
+ * composed from the bottom to the top and [PagerState.currentPage] == 0 will mean the first item
+ * is located at the bottom.
* @param itemSpacing vertical spacing to add between items.
* @param flingBehavior logic describing fling behavior.
* @param key the scroll position will be maintained based on the key, which means if you add/remove
- * items before the current visible item the item with the given key will be kept as the first
- * visible one.
+ * items before the current visible item the item with the given key will be kept as the first
+ * visible one.
* @param content a block which describes the content. Inside this block you can reference
- * [PagerScope.currentPage] and other properties in [PagerScope].
+ * [PagerScope.currentPage] and other properties in [PagerScope].
+ * @sample com.google.accompanist.sample.pager.VerticalPagerSample
*/
@ExperimentalPagerApi
@Composable
@@ -246,7 +244,9 @@
// Constraint the content to be <= than the size of the pager.
.fillParentMaxHeight()
.wrapContentSize()
- ) { pagerScope.content(page) }
+ ) {
+ pagerScope.content(page)
+ }
}
}
} else {
@@ -272,7 +272,9 @@
// Constraint the content to be <= than the size of the pager.
.fillParentMaxWidth()
.wrapContentSize()
- ) { pagerScope.content(page) }
+ ) {
+ pagerScope.content(page)
+ }
}
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/pager/PagerState.kt b/packages/SystemUI/compose/core/src/com/android/compose/pager/PagerState.kt
index 2e6ae78..1822a68 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/pager/PagerState.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/pager/PagerState.kt
@@ -198,7 +198,7 @@
*
* @param page the page to animate to. Must be between 0 and [pageCount] (inclusive).
* @param pageOffset the percentage of the page width to offset, from the start of [page]. Must
- * be in the range 0f..1f.
+ * be in the range 0f..1f.
*/
suspend fun animateScrollToPage(
@IntRange(from = 0) page: Int,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/pager/SnappingFlingBehavior.kt b/packages/SystemUI/compose/core/src/com/android/compose/pager/SnappingFlingBehavior.kt
index 23122de..9814029 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/pager/SnappingFlingBehavior.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/pager/SnappingFlingBehavior.kt
@@ -44,11 +44,11 @@
/**
* Create and remember a snapping [FlingBehavior] to be used with [LazyListState].
*
- * TODO: move this to a new module and make it public
- *
* @param lazyListState The [LazyListState] to update.
* @param decayAnimationSpec The decay animation spec to use for decayed flings.
* @param snapAnimationSpec The animation spec to use when snapping.
+ *
+ * TODO: move this to a new module and make it public
*/
@Composable
internal fun rememberSnappingFlingBehavior(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
index 3eeadae..a74e56b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
@@ -60,7 +60,7 @@
*
* @param viewModel the [PeopleViewModel] that should be composed.
* @param onResult the callback called with the result of this screen. Callers should usually finish
- * the Activity/Fragment/View hosting this Composable once a result is available.
+ * the Activity/Fragment/View hosting this Composable once a result is available.
*/
@Composable
fun PeopleScreen(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
index 3f590df..0484ff4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
@@ -79,7 +79,9 @@
containerColor = androidColors.colorAccentPrimary,
contentColor = androidColors.textColorOnAccent,
)
- ) { Text(stringResource(R.string.got_it)) }
+ ) {
+ Text(stringResource(R.string.got_it))
+ }
}
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
index c120876..0d88075 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
@@ -51,7 +51,7 @@
*
* Supported operations:
* - Query - to know which slots are available, query the [SlotTable.URI] [Uri]. The result
- * set will contain rows with the [SlotTable.Columns] columns.
+ * set will contain rows with the [SlotTable.Columns] columns.
*/
object SlotTable {
const val TABLE_NAME = "slots"
@@ -74,8 +74,8 @@
*
* Supported operations:
* - Query - to know about all the affordances that are available on the device, regardless
- * of which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result
- * set will contain rows, each with the columns specified in [AffordanceTable.Columns].
+ * of which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result
+ * set will contain rows, each with the columns specified in [AffordanceTable.Columns].
*/
object AffordanceTable {
const val TABLE_NAME = "affordances"
@@ -128,14 +128,14 @@
*
* Supported operations:
* - Insert - to insert an affordance and place it in a slot, insert values for the columns
- * into the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the system.
- * Selecting a new affordance for a slot that is already full will automatically remove the
- * oldest affordance from the slot.
+ * into the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the
+ * system. Selecting a new affordance for a slot that is already full will automatically
+ * remove the oldest affordance from the slot.
* - Query - to know which affordances are set on which slots, query the
- * [SelectionTable.URI] [Uri]. The result set will contain rows, each of which with the
- * columns from [SelectionTable.Columns].
+ * [SelectionTable.URI] [Uri]. The result set will contain rows, each of which with the
+ * columns from [SelectionTable.Columns].
* - Delete - to unselect an affordance, removing it from a slot, delete from the
- * [SelectionTable.URI] [Uri], passing in values for each column.
+ * [SelectionTable.URI] [Uri], passing in values for each column.
*/
object SelectionTable {
const val TABLE_NAME = "selections"
@@ -160,7 +160,7 @@
*
* Supported operations:
* - Query - to know the values of flags, query the [FlagsTable.URI] [Uri]. The result set will
- * contain rows, each of which with the columns from [FlagsTable.Columns].
+ * contain rows, each of which with the columns from [FlagsTable.Columns].
*/
object FlagsTable {
const val TABLE_NAME = "flags"
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
index 943d799..8a6fc5d 100644
--- a/packages/SystemUI/ktfmt_includes.txt
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -1,28 +1,20 @@
+packages/SystemUI
-packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
-packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
--packages/SystemUI/checks/src/com/android/internal/systemui/lint/BindServiceViaContextDetector.kt
-packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt
--packages/SystemUI/checks/src/com/android/internal/systemui/lint/GetMainLooperViaContextDetector.kt
-packages/SystemUI/checks/src/com/android/internal/systemui/lint/RegisterReceiverViaContextDetector.kt
-packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt
--packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
--packages/SystemUI/checks/tests/com/android/systemui/lint/BindServiceViaContextDetectorTest.kt
--packages/SystemUI/checks/tests/com/android/systemui/lint/BroadcastSentViaContextDetectorTest.kt
--packages/SystemUI/checks/tests/com/android/systemui/lint/GetMainLooperViaContextDetectorTest.kt
--packages/SystemUI/checks/tests/com/android/systemui/lint/RegisterReceiverViaContextDetectorTest.kt
--packages/SystemUI/checks/tests/com/android/systemui/lint/SoftwareBitmapDetectorTest.kt
+-packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+-packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
-packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainerController.kt
+-packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/View.kt
-packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
-packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt
-packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt
-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSerializer.kt
-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt
-packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionDarkness.kt
-packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt
-packages/SystemUI/shared/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerManager.kt
-packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/SmartspaceState.kt
@@ -35,8 +27,6 @@
-packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
-packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
-packages/SystemUI/src/com/android/keyguard/KeyguardBiometricLockoutLogger.kt
--packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
--packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt
-packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
-packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt
-packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
@@ -65,12 +55,10 @@
-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
-packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt
-packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt
--packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt
@@ -80,7 +68,6 @@
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt
--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
-packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
@@ -93,8 +80,6 @@
-packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
-packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
-packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
--packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
--packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt
-packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
-packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt
-packages/SystemUI/src/com/android/systemui/controls/ControlsMetricsLogger.kt
@@ -102,7 +87,6 @@
-packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt
-packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt
-packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt
--packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
-packages/SystemUI/src/com/android/systemui/controls/controller/ControlInfo.kt
-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
@@ -132,6 +116,7 @@
-packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt
-packages/SystemUI/src/com/android/systemui/controls/management/ManagementPageIndicator.kt
-packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/start/ControlsStartable.kt
-packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
-packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
-packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
@@ -162,7 +147,6 @@
-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
-packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt
--packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
-packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
-packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
-packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
@@ -172,20 +156,16 @@
-packages/SystemUI/src/com/android/systemui/dump/LogBufferEulogizer.kt
-packages/SystemUI/src/com/android/systemui/dump/LogBufferFreezer.kt
-packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
+-packages/SystemUI/src/com/android/systemui/flags/Flags.kt
-packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
-packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
-packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
--packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+-packages/SystemUI/src/com/android/systemui/keyguard/LifecycleScreenStatusProvider.kt
+-packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
+-packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt
+-packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
-packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt
--packages/SystemUI/src/com/android/systemui/log/LogLevel.kt
--packages/SystemUI/src/com/android/systemui/log/LogMessage.kt
--packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt
--packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt
--packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
--packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
--packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
-packages/SystemUI/src/com/android/systemui/media/MediaProjectionCaptureTarget.kt
--packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt
-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt
-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
@@ -202,6 +182,11 @@
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorResultHandler.kt
+-packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt
+-packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt
+-packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt
+-packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDevicePolicyResolver.kt
-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -220,8 +205,6 @@
-packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt
-packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
-packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
--packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
--packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
-packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
-packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
-packages/SystemUI/src/com/android/systemui/qs/QSExpansionPathInterpolator.kt
@@ -237,7 +220,6 @@
-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialogEventLogger.kt
-packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
--packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
-packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt
-packages/SystemUI/src/com/android/systemui/qs/tileimpl/IgnorableChildLinearLayout.kt
-packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -245,10 +227,6 @@
-packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
-packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
-packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
--packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt
--packages/SystemUI/src/com/android/systemui/ripple/RippleShaderUtilLibrary.kt
--packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt
--packages/SystemUI/src/com/android/systemui/ripple/SdfShaderLibrary.kt
-packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
-packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
@@ -259,23 +237,21 @@
-packages/SystemUI/src/com/android/systemui/settings/UserContentResolverProvider.kt
-packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt
-packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
--packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
-packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt
-packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
-packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessMirrorHandler.kt
-packages/SystemUI/src/com/android/systemui/settings/brightness/MirroredBrightnessController.kt
-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
--packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
-packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt
--packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt
-packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
-packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
-packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+-packages/SystemUI/src/com/android/systemui/shade/ShadeHeightLogger.kt
-packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+-packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
-packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
-packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
--packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
-packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
-packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
-packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
@@ -284,10 +260,8 @@
-packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
-packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt
--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBarWifiView.kt
-packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
-packages/SystemUI/src/com/android/systemui/statusbar/DisableFlagsLogger.kt
--packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
-packages/SystemUI/src/com/android/systemui/statusbar/LockScreenShadeOverScroller.kt
-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
@@ -311,10 +285,12 @@
-packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
-packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
-packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/StatusBarEventsModule.kt
-packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
-packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt
-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureHandler.kt
-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeUpGestureLogger.kt
@@ -325,7 +301,6 @@
-packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClickerLogger.kt
--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.kt
@@ -396,6 +371,9 @@
-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiChromeViewBinder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiDebug.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/fsi/FsiTaskViewConfig.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -403,6 +381,7 @@
-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractor.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/ViewPipeline.kt
@@ -444,13 +423,10 @@
-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallFlags.kt
-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLogger.kt
--packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt
--packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/ShadeStateListener.kt
--packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserInfoTracker.kt
-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
--packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
--packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherFeatureController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/model/ConnectivitySlots.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
-packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -470,19 +446,17 @@
-packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt
-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
--packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
-packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+-packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
-packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarRootView.kt
-packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
-packages/SystemUI/src/com/android/systemui/toast/ToastLogger.kt
-packages/SystemUI/src/com/android/systemui/tv/TVSystemUICoreStartableModule.kt
+-packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
-packages/SystemUI/src/com/android/systemui/unfold/FoldStateLogger.kt
-packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
--packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt
--packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
-packages/SystemUI/src/com/android/systemui/unfold/UnfoldProgressProvider.kt
-packages/SystemUI/src/com/android/systemui/user/UserCreator.kt
--packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
-packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
-packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
-packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt
@@ -509,7 +483,6 @@
-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
-packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
--packages/SystemUI/src/com/android/systemui/util/collection/RingBuffer.kt
-packages/SystemUI/src/com/android/systemui/util/concurrency/Execution.kt
-packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt
-packages/SystemUI/src/com/android/systemui/util/drawable/DrawableSize.kt
@@ -517,6 +490,7 @@
-packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
-packages/SystemUI/src/com/android/systemui/util/kotlin/IpcSerializer.kt
-packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt
+-packages/SystemUI/src/com/android/systemui/util/recycler/HorizontalSpacerItemDecoration.kt
-packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
-packages/SystemUI/src/com/android/systemui/util/wrapper/RotationPolicyWrapper.kt
-packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
@@ -525,7 +499,6 @@
-packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
-packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
-packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
--packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
-packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
@@ -550,7 +523,6 @@
-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
--packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
-packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
@@ -569,7 +541,6 @@
-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
--packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt
@@ -579,8 +550,8 @@
-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
--packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
-packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
-packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
@@ -596,13 +567,16 @@
-packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
-packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/lifecycle/InstantTaskExecutorRule.kt
--packages/SystemUI/tests/src/com/android/systemui/log/LogBufferTest.kt
-packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
-packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt
@@ -610,7 +584,6 @@
-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentDisableFlagsLoggerTest.kt
@@ -641,36 +614,29 @@
-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/ripple/RippleViewTest.kt
-packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordDialogTest.kt
-packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
--packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt
--packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
--packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
--packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
--packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
-packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/DisableFlagsLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -683,10 +649,12 @@
-packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandRegistryTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
@@ -719,7 +687,6 @@
-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
@@ -733,8 +700,7 @@
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/ShadeExpansionStateManagerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
@@ -744,7 +710,6 @@
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerOldImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/VariableDateViewControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
@@ -753,40 +718,36 @@
-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
--packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
-packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
-packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt
--packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
-packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
-packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
-packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
-packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
--packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/FakeSharedPreferencesTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/FloatingContentCoordinatorTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/ListenerSetTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt
--packages/SystemUI/tests/src/com/android/systemui/util/collection/RingBufferTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/drawable/DrawableSizeTest.kt
-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/IpcSerializerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/SuspendUtilTests.kt
-packages/SystemUI/tests/src/com/android/systemui/util/view/ViewUtilTest.kt
--packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/util/FakeSharedPreferences.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/SizeScreenStatusProvider.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
--packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldMain.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
--packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
--packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
index e99b214..3e34885 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
@@ -35,7 +35,6 @@
* as the result of taking a bug report).
*
* You can dump the entire buffer at any time by running:
- *
* ```
* $ adb shell dumpsys activity service com.android.systemui/.SystemUIService <bufferName>
* ```
@@ -46,13 +45,11 @@
* locally (usually for debugging purposes).
*
* To enable logcat echoing for an entire buffer:
- *
* ```
* $ adb shell settings put global systemui/buffer/<bufferName> <level>
* ```
*
* To enable logcat echoing for a specific tag:
- *
* ```
* $ adb shell settings put global systemui/tag/<tag> <level>
* ```
@@ -64,10 +61,10 @@
* LogBufferFactory.
*
* @param name The name of this buffer, printed when the buffer is dumped and in some other
- * situations.
+ * situations.
* @param maxSize The maximum number of messages to keep in memory at any one time. Buffers start
- * out empty and grow up to [maxSize] as new messages are logged. Once the buffer's size reaches the
- * maximum, it behaves like a ring buffer.
+ * out empty and grow up to [maxSize] as new messages are logged. Once the buffer's size reaches
+ * the maximum, it behaves like a ring buffer.
*/
class LogBuffer
@JvmOverloads
@@ -116,22 +113,22 @@
* initializer stored and converts it to a human-readable log message.
*
* @param tag A string of at most 23 characters, used for grouping logs into categories or
- * subjects. If this message is echoed to logcat, this will be the tag that is used.
+ * subjects. If this message is echoed to logcat, this will be the tag that is used.
* @param level Which level to log the message at, both to the buffer and to logcat if it's
- * echoed. In general, a module should split most of its logs into either INFO or DEBUG level.
- * INFO level should be reserved for information that other parts of the system might care
- * about, leaving the specifics of code's day-to-day operations to DEBUG.
+ * echoed. In general, a module should split most of its logs into either INFO or DEBUG level.
+ * INFO level should be reserved for information that other parts of the system might care
+ * about, leaving the specifics of code's day-to-day operations to DEBUG.
* @param messageInitializer A function that will be called immediately to store relevant data
- * on the log message. The value of `this` will be the LogMessage to be initialized.
+ * on the log message. The value of `this` will be the LogMessage to be initialized.
* @param messagePrinter A function that will be called if and when the message needs to be
- * dumped to logcat or a bug report. It should read the data stored by the initializer and
- * convert it to a human-readable string. The value of `this` will be the LogMessage to be
- * printed. **IMPORTANT:** The printer should ONLY ever reference fields on the LogMessage and
- * NEVER any variables in its enclosing scope. Otherwise, the runtime will need to allocate a
- * new instance of the printer for each call, thwarting our attempts at avoiding any sort of
- * allocation.
+ * dumped to logcat or a bug report. It should read the data stored by the initializer and
+ * convert it to a human-readable string. The value of `this` will be the LogMessage to be
+ * printed. **IMPORTANT:** The printer should ONLY ever reference fields on the LogMessage and
+ * NEVER any variables in its enclosing scope. Otherwise, the runtime will need to allocate a
+ * new instance of the printer for each call, thwarting our attempts at avoiding any sort of
+ * allocation.
* @param exception Provide any exception that need to be logged. This is saved as
- * [LogMessage.exception]
+ * [LogMessage.exception]
*/
@JvmOverloads
inline fun log(
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt
index faf1b78..7a125ac 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogcatEchoTrackerDebug.kt
@@ -28,7 +28,6 @@
* Version of [LogcatEchoTracker] for debuggable builds
*
* The log level of individual buffers or tags can be controlled via global settings:
- *
* ```
* # Echo any message to <bufferName> of <level> or higher
* $ adb shell settings put global systemui/buffer/<bufferName> <level>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/util/RingBuffer.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/util/RingBuffer.kt
index 68d7890..4773f54 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/util/RingBuffer.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/util/RingBuffer.kt
@@ -30,7 +30,7 @@
*
* @param maxSize The maximum size the buffer can grow to before it begins functioning as a ring.
* @param factory A function that creates a fresh instance of T. Used by the buffer while it's
- * growing to [maxSize].
+ * growing to [maxSize].
*/
class RingBuffer<T>(private val maxSize: Int, private val factory: () -> T) : Iterable<T> {
diff --git a/packages/SystemUI/res-product/values/strings.xml b/packages/SystemUI/res-product/values/strings.xml
index b71caef..87b206c 100644
--- a/packages/SystemUI/res-product/values/strings.xml
+++ b/packages/SystemUI/res-product/values/strings.xml
@@ -122,6 +122,12 @@
Try again in <xliff:g id="number">%3$d</xliff:g> seconds.
</string>
+ <!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, to locate the sensor (tablet) for accessibility (not shown on the screen). [CHAR LIMIT=NONE]-->
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet">The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.\n\nPressing the power button turns off the screen.</string>
+ <!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, to locate the sensor (device) for accessibility (not shown on the screen). [CHAR LIMIT=NONE]-->
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device">The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.\n\nPressing the power button turns off the screen.</string>
+ <!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, to locate the sensor (default) for accessibility (not shown on the screen). [CHAR LIMIT=NONE]-->
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default">The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.\n\nPressing the power button turns off the screen.</string>
<!-- Text shown when viewing global actions while phone is locked and additional controls are hidden [CHAR LIMIT=NONE] -->
<string name="global_action_lock_message" product="default">Unlock your phone for more options</string>
@@ -134,4 +140,7 @@
<string name="media_transfer_playing_this_device" product="default">Playing on this phone</string>
<!-- Text informing the user that their media is now playing on this tablet device. [CHAR LIMIT=50] -->
<string name="media_transfer_playing_this_device" product="tablet">Playing on this tablet</string>
+
+
+
</resources>
diff --git a/packages/SystemUI/res/drawable/qs_media_rec_scrim.xml b/packages/SystemUI/res/drawable/qs_media_rec_scrim.xml
new file mode 100644
index 0000000..de0a620
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_media_rec_scrim.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <!-- gradient from 25% in the center to 100% at edges -->
+ <gradient
+ android:type="radial"
+ android:gradientRadius="40%p"
+ android:startColor="#AE000000"
+ android:endColor="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_recommendation_view.xml b/packages/SystemUI/res/layout/media_recommendation_view.xml
index c54c4e4..a4aeba1 100644
--- a/packages/SystemUI/res/layout/media_recommendation_view.xml
+++ b/packages/SystemUI/res/layout/media_recommendation_view.xml
@@ -22,9 +22,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:translationZ="0dp"
- android:scaleType="centerCrop"
+ android:scaleType="matrix"
android:adjustViewBounds="true"
android:clipToOutline="true"
+ android:layerType="hardware"
android:background="@drawable/bg_smartspace_media_item"/>
<!-- App icon -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bf949a0..9ce3f38 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -576,7 +576,7 @@
<dimen name="qs_tile_margin_horizontal">8dp</dimen>
<dimen name="qs_tile_margin_vertical">@dimen/qs_tile_margin_horizontal</dimen>
<dimen name="qs_tile_margin_top_bottom">4dp</dimen>
- <dimen name="qs_brightness_margin_top">12dp</dimen>
+ <dimen name="qs_brightness_margin_top">8dp</dimen>
<dimen name="qs_brightness_margin_bottom">16dp</dimen>
<dimen name="qqs_layout_margin_top">16dp</dimen>
<dimen name="qqs_layout_padding_bottom">24dp</dimen>
@@ -628,7 +628,7 @@
<dimen name="qs_header_row_min_height">48dp</dimen>
<dimen name="qs_header_non_clickable_element_height">24dp</dimen>
- <dimen name="new_qs_header_non_clickable_element_height">20dp</dimen>
+ <dimen name="new_qs_header_non_clickable_element_height">24dp</dimen>
<dimen name="qs_footer_padding">20dp</dimen>
<dimen name="qs_security_footer_height">88dp</dimen>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index 6354752..763930d 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -30,9 +30,6 @@
<bool name="flag_charging_ripple">false</bool>
- <!-- Whether to show chipbar UI whenever the device is unlocked by ActiveUnlock. -->
- <bool name="flag_active_unlock_chipbar">true</bool>
-
<!-- Whether the user switcher chip shows in the status bar. When true, the multi user
avatar will no longer show on the lockscreen -->
<bool name="flag_user_switcher_chip">false</bool>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 4ab0d01..8be5998 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -405,12 +405,6 @@
<!-- Message shown when the system-provided fingerprint dialog is shown, asking for authentication -->
<string name="fingerprint_dialog_touch_sensor">Touch the fingerprint sensor</string>
- <!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, to locate the sensor (tablet) for accessibility (not shown on the screen). [CHAR LIMIT=NONE]-->
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet">The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.\n\nPressing the power button turns off the screen.</string>
- <!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, to locate the sensor (device) for accessibility (not shown on the screen). [CHAR LIMIT=NONE]-->
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device">The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.\n\nPressing the power button turns off the screen.</string>
- <!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, to locate the sensor (default) for accessibility (not shown on the screen). [CHAR LIMIT=NONE]-->
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default">The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.\n\nPressing the power button turns off the screen.</string>
<!-- Message shown to inform the user a face cannot be recognized and fingerprint should instead be used.[CHAR LIMIT=50] -->
<string name="fingerprint_dialog_use_fingerprint_instead">Can\u2019t recognize face. Use fingerprint instead.</string>
<!-- Message shown to inform the user a face cannot be recognized and fingerprint should instead be used.[CHAR LIMIT=50] -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Evaluator.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Evaluator.kt
index 23742c5..454294f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Evaluator.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Evaluator.kt
@@ -87,7 +87,7 @@
* Helper for evaluating 3-valued logical AND/OR.
*
* @param returnValueIfAnyMatches AND returns false if any value is false. OR returns true if
- * any value is true.
+ * any value is true.
*/
private fun threeValuedAndOrOr(
conditions: Collection<Condition>,
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 6bfaf5e..b2add4f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -18,7 +18,6 @@
import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.ActivityTaskManager.getService;
import android.annotation.NonNull;
@@ -45,6 +44,7 @@
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
+import android.view.Display;
import android.view.IRecentsAnimationController;
import android.view.IRecentsAnimationRunner;
import android.view.RemoteAnimationTarget;
@@ -112,6 +112,13 @@
}
/**
+ * @see #getRunningTasks(boolean , int)
+ */
+ public ActivityManager.RunningTaskInfo[] getRunningTasks(boolean filterOnlyVisibleRecents) {
+ return getRunningTasks(filterOnlyVisibleRecents, Display.INVALID_DISPLAY);
+ }
+
+ /**
* We ask for {@link #NUM_RECENT_ACTIVITIES_REQUEST} activities because when in split screen,
* we'll get back 2 activities for each split app and one for launcher. Launcher might be more
* "recently" used than one of the split apps so if we only request 2 tasks, then we might miss
@@ -120,10 +127,12 @@
* @return an array of up to {@link #NUM_RECENT_ACTIVITIES_REQUEST} running tasks
* filtering only for tasks that can be visible in the recent tasks list.
*/
- public ActivityManager.RunningTaskInfo[] getRunningTasks(boolean filterOnlyVisibleRecents) {
+ public ActivityManager.RunningTaskInfo[] getRunningTasks(boolean filterOnlyVisibleRecents,
+ int displayId) {
// Note: The set of running tasks from the system is ordered by recency
List<ActivityManager.RunningTaskInfo> tasks =
- mAtm.getTasks(NUM_RECENT_ACTIVITIES_REQUEST, filterOnlyVisibleRecents);
+ mAtm.getTasks(NUM_RECENT_ACTIVITIES_REQUEST,
+ filterOnlyVisibleRecents, /* keepInExtras= */ false, displayId);
return tasks.toArray(new RunningTaskInfo[tasks.size()]);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
index e0cf7b6..d8085b9 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
@@ -132,6 +132,7 @@
/**
* UiEvents that are logged to identify why face auth is being triggered.
+ *
* @param extraInfo is logged as the position. See [UiEventLogger#logWithInstanceIdAndPosition]
*/
enum class FaceAuthUiEvent
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index c1fae9e..33bea02 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -69,6 +69,7 @@
private Interpolator mLinearOutSlowInInterpolator;
private Interpolator mFastOutLinearInInterpolator;
+ private DisappearAnimationListener mDisappearAnimationListener;
public KeyguardPasswordView(Context context) {
this(context, null);
@@ -186,9 +187,13 @@
return;
}
Insets shownInsets = controller.getShownStateInsets();
- Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0,
- (int) (-shownInsets.bottom / 4
- * anim.getAnimatedFraction())));
+ int dist = (int) (-shownInsets.bottom / 4
+ * anim.getAnimatedFraction());
+ Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0, dist));
+ if (mDisappearAnimationListener != null) {
+ mDisappearAnimationListener.setTranslationY(-dist);
+ }
+
controller.setInsetsAndAlpha(insets,
(float) animation.getAnimatedValue(),
anim.getAnimatedFraction());
@@ -209,6 +214,7 @@
controller.finish(false);
runOnFinishImeAnimationRunnable();
finishRunnable.run();
+ mDisappearAnimationListener = null;
Trace.endSection();
});
}
@@ -286,4 +292,19 @@
}
});
}
+
+ /**
+ * Listens to the progress of the disappear animation and handles it.
+ */
+ interface DisappearAnimationListener {
+ void setTranslationY(int transY);
+ }
+
+ /**
+ * Set an instance of the disappear animation listener to this class. This will be
+ * removed when the animation completes.
+ */
+ public void setDisappearAnimationListener(DisappearAnimationListener listener) {
+ mDisappearAnimationListener = listener;
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index c6f0eee..66d5d09 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -173,6 +173,17 @@
private @Mode int mCurrentMode = MODE_UNINITIALIZED;
private int mWidth = -1;
+ /**
+ * This callback is used to animate KeyguardSecurityContainer and its child views based on
+ * the interaction with the ime. After
+ * {@link WindowInsetsAnimation.Callback#onPrepare(WindowInsetsAnimation)},
+ * {@link #onApplyWindowInsets} is called where we
+ * set the bottom padding to be the height of the keyboard. We use this padding to determine
+ * the delta of vertical distance for y-translation animations.
+ * Note that bottom padding is not set when the disappear animation is started because
+ * we are deferring the y translation logic to the animator in
+ * {@link KeyguardPasswordView#startDisappearAnimation(Runnable)}
+ */
private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
@@ -213,7 +224,6 @@
continue;
}
interpolatedFraction = animation.getInterpolatedFraction();
-
final int paddingBottom = (int) MathUtils.lerp(
start, end,
interpolatedFraction);
@@ -568,13 +578,21 @@
*/
public void startDisappearAnimation(SecurityMode securitySelection) {
mDisappearAnimRunning = true;
- mViewMode.startDisappearAnimation(securitySelection);
+ if (securitySelection == SecurityMode.Password
+ && mSecurityViewFlipper.getSecurityView() instanceof KeyguardPasswordView) {
+ ((KeyguardPasswordView) mSecurityViewFlipper.getSecurityView())
+ .setDisappearAnimationListener(this::setTranslationY);
+ } else {
+ mViewMode.startDisappearAnimation(securitySelection);
+ }
}
/**
* This will run when the bouncer shows in all cases except when the user drags the bouncer up.
*/
public void startAppearAnimation(SecurityMode securityMode) {
+ setTranslationY(0f);
+ setAlpha(1f);
updateChildren(0 /* translationY */, 1f /* alpha */);
mViewMode.startAppearAnimation(securityMode);
}
@@ -623,7 +641,13 @@
int inset = max(bottomInset, imeInset);
int paddingBottom = max(inset, getContext().getResources()
.getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin));
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom);
+ // If security mode is password, we rely on the animation value of defined in
+ // KeyguardPasswordView to determine the y translation animation.
+ // This means that we will prevent the WindowInsetsAnimationCallback from setting any y
+ // translation values by preventing the setting of the padding here.
+ if (!mDisappearAnimRunning) {
+ setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom);
+ }
return insets.inset(0, 0, 0, inset);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index be01377..b27cca4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -676,7 +676,10 @@
public void onTrustManagedChanged(boolean managed, int userId) {
Assert.isMainThread();
mUserTrustIsManaged.put(userId, managed);
- mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
+ boolean trustUsuallyManaged = mTrustManager.isTrustUsuallyManaged(userId);
+ mLogger.logTrustUsuallyManagedUpdated(userId, mUserTrustIsUsuallyManaged.get(userId),
+ trustUsuallyManaged, "onTrustManagedChanged");
+ mUserTrustIsUsuallyManaged.put(userId, trustUsuallyManaged);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -864,7 +867,10 @@
private void reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId) {
mBackgroundExecutor.execute(
- () -> mLockPatternUtils.reportSuccessfulBiometricUnlock(isStrongBiometric, userId));
+ () -> {
+ mLogger.logReportSuccessfulBiometricUnlock(isStrongBiometric, userId);
+ mLockPatternUtils.reportSuccessfulBiometricUnlock(isStrongBiometric, userId);
+ });
}
private void handleFingerprintAuthFailed() {
@@ -2372,8 +2378,12 @@
updateSecondaryLockscreenRequirement(user);
List<UserInfo> allUsers = mUserManager.getUsers();
for (UserInfo userInfo : allUsers) {
+ boolean trustUsuallyManaged = mTrustManager.isTrustUsuallyManaged(userInfo.id);
+ mLogger.logTrustUsuallyManagedUpdated(userInfo.id,
+ mUserTrustIsUsuallyManaged.get(userInfo.id),
+ trustUsuallyManaged, "init from constructor");
mUserTrustIsUsuallyManaged.put(userInfo.id,
- mTrustManager.isTrustUsuallyManaged(userInfo.id));
+ trustUsuallyManaged);
}
updateAirplaneModeState();
@@ -2413,10 +2423,12 @@
}
private void updateFaceEnrolled(int userId) {
- mIsFaceEnrolled = whitelistIpcs(
+ Boolean isFaceEnrolled = whitelistIpcs(
() -> mFaceManager != null && mFaceManager.isHardwareDetected()
&& mFaceManager.hasEnrolledTemplates(userId)
&& mBiometricEnabledForUser.get(userId));
+ mIsFaceEnrolled = isFaceEnrolled;
+ mLogger.logFaceEnrolledUpdated(mIsFaceEnrolled, isFaceEnrolled);
}
public boolean isFaceSupported() {
@@ -2495,11 +2507,13 @@
// If this message exists, we should not authenticate again until this message is
// consumed by the handler
if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
+ mLogger.logHandlerHasAuthContinueMsgs(action);
return;
}
// don't start running fingerprint until they're registered
if (!mAuthController.areAllFingerprintAuthenticatorsRegistered()) {
+ mLogger.d("All FP authenticators not registered, skipping FP listening state update");
return;
}
final boolean shouldListenForFingerprint = shouldListenForFingerprint(isUdfpsSupported());
@@ -3071,8 +3085,12 @@
@VisibleForTesting
boolean isUnlockWithFingerprintPossible(int userId) {
// TODO (b/242022358), make this rely on onEnrollmentChanged event and update it only once.
- mIsUnlockWithFingerprintPossible.put(userId, mFpm != null && mFpm.isHardwareDetected()
- && !isFingerprintDisabled(userId) && mFpm.hasEnrolledTemplates(userId));
+ boolean fpEnrolled = mFpm != null && mFpm.isHardwareDetected()
+ && !isFingerprintDisabled(userId) && mFpm.hasEnrolledTemplates(userId);
+ mLogger.logFpEnrolledUpdated(userId,
+ mIsUnlockWithFingerprintPossible.getOrDefault(userId, false),
+ fpEnrolled);
+ mIsUnlockWithFingerprintPossible.put(userId, fpEnrolled);
return mIsUnlockWithFingerprintPossible.get(userId);
}
@@ -3188,7 +3206,10 @@
void handleUserSwitching(int userId, CountDownLatch latch) {
Assert.isMainThread();
clearBiometricRecognized();
- mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
+ boolean trustUsuallyManaged = mTrustManager.isTrustUsuallyManaged(userId);
+ mLogger.logTrustUsuallyManagedUpdated(userId, mUserTrustIsUsuallyManaged.get(userId),
+ trustUsuallyManaged, "userSwitching");
+ mUserTrustIsUsuallyManaged.put(userId, trustUsuallyManaged);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt
index bc0bd8c..20f9007 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/BiometricUnlockLogger.kt
@@ -16,6 +16,7 @@
package com.android.keyguard.logging
+import android.hardware.biometrics.BiometricSourceType
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.dagger.BiometricLog
import com.android.systemui.plugins.log.LogBuffer
@@ -157,6 +158,36 @@
}
)
}
+
+ fun deferringAuthenticationDueToSleep(
+ userId: Int,
+ biometricSourceType: BiometricSourceType,
+ alreadyPendingAuth: Boolean
+ ) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = userId
+ str1 = biometricSourceType.name
+ bool2 = alreadyPendingAuth
+ },
+ {
+ "onBiometricAuthenticated, deferring auth: userId: $int1, " +
+ "biometricSourceType: $str1, " +
+ "goingToSleep: true, " +
+ "mPendingAuthentication != null: $bool2"
+ }
+ )
+ }
+
+ fun finishedGoingToSleepWithPendingAuth() {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ "onFinishedGoingToSleep with pendingAuthenticated != null"
+ )
+ }
}
private fun wakeAndUnlockModeToString(mode: Int): String {
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
index 379c78a..51aca07 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
@@ -16,6 +16,7 @@
package com.android.keyguard.logging
+import com.android.systemui.biometrics.AuthRippleController
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController
import com.android.systemui.log.dagger.KeyguardLog
import com.android.systemui.plugins.log.LogBuffer
@@ -120,4 +121,29 @@
"type=${KeyguardIndicationRotateTextViewController.indicationTypeToString(type)}"
}
}
+
+ fun notShowingUnlockRipple(keyguardNotShowing: Boolean, unlockNotAllowed: Boolean) {
+ buffer.log(
+ AuthRippleController.TAG,
+ LogLevel.DEBUG,
+ {
+ bool1 = keyguardNotShowing
+ bool2 = unlockNotAllowed
+ },
+ { "Not showing unlock ripple: keyguardNotShowing: $bool1, unlockNotAllowed: $bool2" }
+ )
+ }
+
+ fun showingUnlockRippleAt(x: Int, y: Int, context: String) {
+ buffer.log(
+ AuthRippleController.TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = x
+ int2 = y
+ str1 = context
+ },
+ { "Showing unlock ripple with center (x, y): ($int1, $int2), context: $str1" }
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index e53f6ad..2403d11 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -26,6 +26,7 @@
import com.android.keyguard.KeyguardListenModel
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.keyguard.TrustGrantFlags
+import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel
import com.android.systemui.plugins.log.LogLevel.DEBUG
@@ -33,18 +34,15 @@
import com.android.systemui.plugins.log.LogLevel.INFO
import com.android.systemui.plugins.log.LogLevel.VERBOSE
import com.android.systemui.plugins.log.LogLevel.WARNING
-import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
import com.google.errorprone.annotations.CompileTimeConstant
import javax.inject.Inject
private const val TAG = "KeyguardUpdateMonitorLog"
-/**
- * Helper class for logging for [com.android.keyguard.KeyguardUpdateMonitor]
- */
-class KeyguardUpdateMonitorLogger @Inject constructor(
- @KeyguardUpdateMonitorLog private val logBuffer: LogBuffer
-) {
+/** Helper class for logging for [com.android.keyguard.KeyguardUpdateMonitor] */
+class KeyguardUpdateMonitorLogger
+@Inject
+constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) {
fun d(@CompileTimeConstant msg: String) = log(msg, DEBUG)
fun e(@CompileTimeConstant msg: String) = log(msg, ERROR)
@@ -56,15 +54,16 @@
fun log(@CompileTimeConstant msg: String, level: LogLevel) = logBuffer.log(TAG, level, msg)
fun logActiveUnlockTriggered(reason: String?) {
- logBuffer.log("ActiveUnlock", DEBUG,
- { str1 = reason },
- { "initiate active unlock triggerReason=$str1" })
+ logBuffer.log(
+ "ActiveUnlock",
+ DEBUG,
+ { str1 = reason },
+ { "initiate active unlock triggerReason=$str1" }
+ )
}
fun logAuthInterruptDetected(active: Boolean) {
- logBuffer.log(TAG, DEBUG,
- { bool1 = active },
- { "onAuthInterruptDetected($bool1)" })
+ logBuffer.log(TAG, DEBUG, { bool1 = active }, { "onAuthInterruptDetected($bool1)" })
}
fun logBroadcastReceived(action: String?) {
@@ -72,9 +71,12 @@
}
fun logDeviceProvisionedState(deviceProvisioned: Boolean) {
- logBuffer.log(TAG, DEBUG,
- { bool1 = deviceProvisioned },
- { "DEVICE_PROVISIONED state = $bool1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { bool1 = deviceProvisioned },
+ { "DEVICE_PROVISIONED state = $bool1" }
+ )
}
fun logException(ex: Exception, @CompileTimeConstant logMsg: String) {
@@ -82,46 +84,56 @@
}
fun logFaceAcquired(acquireInfo: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = acquireInfo },
- { "Face acquired acquireInfo=$int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = acquireInfo }, { "Face acquired acquireInfo=$int1" })
}
fun logFaceAuthDisabledForUser(userId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = userId },
- { "Face authentication disabled by DPM for userId: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = userId },
+ { "Face authentication disabled by DPM for userId: $int1" }
+ )
}
fun logFaceAuthError(msgId: Int, originalErrMsg: String) {
- logBuffer.log(TAG, DEBUG, {
- str1 = originalErrMsg
- int1 = msgId
- }, { "Face error received: $str1 msgId= $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = originalErrMsg
+ int1 = msgId
+ },
+ { "Face error received: $str1 msgId= $int1" }
+ )
}
fun logFaceAuthForWrongUser(authUserId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = authUserId },
- { "Face authenticated for wrong user: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = authUserId },
+ { "Face authenticated for wrong user: $int1" }
+ )
}
fun logFaceAuthHelpMsg(msgId: Int, helpMsg: String?) {
- logBuffer.log(TAG, DEBUG, {
- int1 = msgId
- str1 = helpMsg
- }, { "Face help received, msgId: $int1 msg: $str1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = msgId
+ str1 = helpMsg
+ },
+ { "Face help received, msgId: $int1 msg: $str1" }
+ )
}
fun logFaceAuthRequested(reason: String?) {
- logBuffer.log(TAG, DEBUG, {
- str1 = reason
- }, { "requestFaceAuth() reason=$str1" })
+ logBuffer.log(TAG, DEBUG, { str1 = reason }, { "requestFaceAuth() reason=$str1" })
}
fun logFaceAuthSuccess(userId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = userId },
- { "Face auth succeeded for user $int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = userId }, { "Face auth succeeded for user $int1" })
}
fun logFaceLockoutReset(@LockoutMode mode: Int) {
@@ -133,21 +145,30 @@
}
fun logFaceUnlockPossible(isFaceUnlockPossible: Boolean) {
- logBuffer.log(TAG, DEBUG,
- { bool1 = isFaceUnlockPossible },
- {"isUnlockWithFacePossible: $bool1"})
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { bool1 = isFaceUnlockPossible },
+ { "isUnlockWithFacePossible: $bool1" }
+ )
}
fun logFingerprintAuthForWrongUser(authUserId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = authUserId },
- { "Fingerprint authenticated for wrong user: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = authUserId },
+ { "Fingerprint authenticated for wrong user: $int1" }
+ )
}
fun logFingerprintDisabledForUser(userId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = userId },
- { "Fingerprint disabled by DPM for userId: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = userId },
+ { "Fingerprint disabled by DPM for userId: $int1" }
+ )
}
fun logFingerprintLockoutReset(@LockoutMode mode: Int) {
@@ -155,16 +176,24 @@
}
fun logFingerprintRunningState(fingerprintRunningState: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = fingerprintRunningState },
- { "fingerprintRunningState: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = fingerprintRunningState },
+ { "fingerprintRunningState: $int1" }
+ )
}
fun logFingerprintSuccess(userId: Int, isStrongBiometric: Boolean) {
- logBuffer.log(TAG, DEBUG, {
- int1 = userId
- bool1 = isStrongBiometric
- }, {"Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1"})
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = userId
+ bool1 = isStrongBiometric
+ },
+ { "Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1" }
+ )
}
fun logFaceDetected(userId: Int, isStrongBiometric: Boolean) {
@@ -182,29 +211,42 @@
}
fun logFingerprintError(msgId: Int, originalErrMsg: String) {
- logBuffer.log(TAG, DEBUG, {
- str1 = originalErrMsg
- int1 = msgId
- }, { "Fingerprint error received: $str1 msgId= $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = originalErrMsg
+ int1 = msgId
+ },
+ { "Fingerprint error received: $str1 msgId= $int1" }
+ )
}
fun logInvalidSubId(subId: Int) {
- logBuffer.log(TAG, INFO,
- { int1 = subId },
- { "Previously active sub id $int1 is now invalid, will remove" })
+ logBuffer.log(
+ TAG,
+ INFO,
+ { int1 = subId },
+ { "Previously active sub id $int1 is now invalid, will remove" }
+ )
}
fun logPrimaryKeyguardBouncerChanged(
- primaryBouncerIsOrWillBeShowing: Boolean,
- primaryBouncerFullyShown: Boolean
+ primaryBouncerIsOrWillBeShowing: Boolean,
+ primaryBouncerFullyShown: Boolean
) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = primaryBouncerIsOrWillBeShowing
- bool2 = primaryBouncerFullyShown
- }, {
- "handlePrimaryBouncerChanged " +
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = primaryBouncerIsOrWillBeShowing
+ bool2 = primaryBouncerFullyShown
+ },
+ {
+ "handlePrimaryBouncerChanged " +
"primaryBouncerIsOrWillBeShowing=$bool1 primaryBouncerFullyShown=$bool2"
- })
+ }
+ )
}
fun logKeyguardListenerModel(model: KeyguardListenModel) {
@@ -212,98 +254,134 @@
}
fun logKeyguardShowingChanged(showing: Boolean, occluded: Boolean, visible: Boolean) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = showing
- bool2 = occluded
- bool3 = visible
- }, {
- "keyguardShowingChanged(showing=$bool1 occluded=$bool2 visible=$bool3)"
- })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = showing
+ bool2 = occluded
+ bool3 = visible
+ },
+ { "keyguardShowingChanged(showing=$bool1 occluded=$bool2 visible=$bool3)" }
+ )
}
fun logMissingSupervisorAppError(userId: Int) {
- logBuffer.log(TAG, ERROR,
- { int1 = userId },
- { "No Profile Owner or Device Owner supervision app found for User $int1" })
+ logBuffer.log(
+ TAG,
+ ERROR,
+ { int1 = userId },
+ { "No Profile Owner or Device Owner supervision app found for User $int1" }
+ )
}
fun logPhoneStateChanged(newState: String?) {
- logBuffer.log(TAG, DEBUG,
- { str1 = newState },
- { "handlePhoneStateChanged($str1)" })
+ logBuffer.log(TAG, DEBUG, { str1 = newState }, { "handlePhoneStateChanged($str1)" })
}
fun logRegisterCallback(callback: KeyguardUpdateMonitorCallback?) {
- logBuffer.log(TAG, VERBOSE,
- { str1 = "$callback" },
- { "*** register callback for $str1" })
+ logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** register callback for $str1" })
}
fun logRetryingAfterFaceHwUnavailable(retryCount: Int) {
- logBuffer.log(TAG, WARNING,
- { int1 = retryCount },
- { "Retrying face after HW unavailable, attempt $int1" })
+ logBuffer.log(
+ TAG,
+ WARNING,
+ { int1 = retryCount },
+ { "Retrying face after HW unavailable, attempt $int1" }
+ )
}
fun logRetryAfterFpErrorWithDelay(msgId: Int, errString: String?, delay: Int) {
- logBuffer.log(TAG, DEBUG, {
- int1 = msgId
- int2 = delay
- str1 = "$errString"
- }, {
- "Fingerprint scheduling retry auth after $int2 ms due to($int1) -> $str1"
- })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = msgId
+ int2 = delay
+ str1 = "$errString"
+ },
+ { "Fingerprint scheduling retry auth after $int2 ms due to($int1) -> $str1" }
+ )
}
fun logRetryAfterFpHwUnavailable(retryCount: Int) {
- logBuffer.log(TAG, WARNING,
- { int1 = retryCount },
- { "Retrying fingerprint attempt: $int1" })
+ logBuffer.log(
+ TAG,
+ WARNING,
+ { int1 = retryCount },
+ { "Retrying fingerprint attempt: $int1" }
+ )
}
fun logSendPrimaryBouncerChanged(
primaryBouncerIsOrWillBeShowing: Boolean,
primaryBouncerFullyShown: Boolean,
) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = primaryBouncerIsOrWillBeShowing
- bool2 = primaryBouncerFullyShown
- }, {
- "sendPrimaryBouncerChanged primaryBouncerIsOrWillBeShowing=$bool1 " +
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = primaryBouncerIsOrWillBeShowing
+ bool2 = primaryBouncerFullyShown
+ },
+ {
+ "sendPrimaryBouncerChanged primaryBouncerIsOrWillBeShowing=$bool1 " +
"primaryBouncerFullyShown=$bool2"
- })
+ }
+ )
}
fun logServiceStateChange(subId: Int, serviceState: ServiceState?) {
- logBuffer.log(TAG, DEBUG, {
- int1 = subId
- str1 = "$serviceState"
- }, { "handleServiceStateChange(subId=$int1, serviceState=$str1)" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = subId
+ str1 = "$serviceState"
+ },
+ { "handleServiceStateChange(subId=$int1, serviceState=$str1)" }
+ )
}
fun logServiceStateIntent(action: String?, serviceState: ServiceState?, subId: Int) {
- logBuffer.log(TAG, VERBOSE, {
- str1 = action
- str2 = "$serviceState"
- int1 = subId
- }, { "action $str1 serviceState=$str2 subId=$int1" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ str1 = action
+ str2 = "$serviceState"
+ int1 = subId
+ },
+ { "action $str1 serviceState=$str2 subId=$int1" }
+ )
}
fun logSimState(subId: Int, slotId: Int, state: Int) {
- logBuffer.log(TAG, DEBUG, {
- int1 = subId
- int2 = slotId
- long1 = state.toLong()
- }, { "handleSimStateChange(subId=$int1, slotId=$int2, state=$long1)" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = subId
+ int2 = slotId
+ long1 = state.toLong()
+ },
+ { "handleSimStateChange(subId=$int1, slotId=$int2, state=$long1)" }
+ )
}
fun logSimStateFromIntent(action: String?, extraSimState: String?, slotId: Int, subId: Int) {
- logBuffer.log(TAG, VERBOSE, {
- str1 = action
- str2 = extraSimState
- int1 = slotId
- int2 = subId
- }, { "action $str1 state: $str2 slotId: $int1 subid: $int2" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ str1 = action
+ str2 = extraSimState
+ int1 = slotId
+ int2 = subId
+ },
+ { "action $str1 state: $str2 slotId: $int1 subid: $int2" }
+ )
}
fun logSimUnlocked(subId: Int) {
@@ -311,78 +389,98 @@
}
fun logStartedListeningForFace(faceRunningState: Int, faceAuthUiEvent: FaceAuthUiEvent) {
- logBuffer.log(TAG, VERBOSE, {
- int1 = faceRunningState
- str1 = faceAuthUiEvent.reason
- str2 = faceAuthUiEvent.extraInfoToString()
- }, { "startListeningForFace(): $int1, reason: $str1 $str2" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ int1 = faceRunningState
+ str1 = faceAuthUiEvent.reason
+ str2 = faceAuthUiEvent.extraInfoToString()
+ },
+ { "startListeningForFace(): $int1, reason: $str1 $str2" }
+ )
}
fun logStartedListeningForFaceFromWakeUp(faceRunningState: Int, @WakeReason pmWakeReason: Int) {
- logBuffer.log(TAG, VERBOSE, {
- int1 = faceRunningState
- str1 = PowerManager.wakeReasonToString(pmWakeReason)
- }, { "startListeningForFace(): $int1, reason: wakeUp-$str1" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ int1 = faceRunningState
+ str1 = PowerManager.wakeReasonToString(pmWakeReason)
+ },
+ { "startListeningForFace(): $int1, reason: wakeUp-$str1" }
+ )
}
fun logStoppedListeningForFace(faceRunningState: Int, faceAuthReason: String) {
- logBuffer.log(TAG, VERBOSE, {
- int1 = faceRunningState
- str1 = faceAuthReason
- }, { "stopListeningForFace(): currentFaceRunningState: $int1, reason: $str1" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ int1 = faceRunningState
+ str1 = faceAuthReason
+ },
+ { "stopListeningForFace(): currentFaceRunningState: $int1, reason: $str1" }
+ )
}
fun logSubInfo(subInfo: SubscriptionInfo?) {
- logBuffer.log(TAG, VERBOSE,
- { str1 = "$subInfo" },
- { "SubInfo:$str1" })
+ logBuffer.log(TAG, VERBOSE, { str1 = "$subInfo" }, { "SubInfo:$str1" })
}
fun logTimeFormatChanged(newTimeFormat: String?) {
- logBuffer.log(TAG, DEBUG,
- { str1 = newTimeFormat },
- { "handleTimeFormatUpdate timeFormat=$str1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { str1 = newTimeFormat },
+ { "handleTimeFormatUpdate timeFormat=$str1" }
+ )
}
fun logUdfpsPointerDown(sensorId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = sensorId },
- { "onUdfpsPointerDown, sensorId: $int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerDown, sensorId: $int1" })
}
fun logUdfpsPointerUp(sensorId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = sensorId },
- { "onUdfpsPointerUp, sensorId: $int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerUp, sensorId: $int1" })
}
fun logUnexpectedFaceCancellationSignalState(faceRunningState: Int, unlockPossible: Boolean) {
- logBuffer.log(TAG, ERROR, {
- int1 = faceRunningState
- bool1 = unlockPossible
- }, {
- "Cancellation signal is not null, high chance of bug in " +
- "face auth lifecycle management. " +
- "Face state: $int1, unlockPossible: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ ERROR,
+ {
+ int1 = faceRunningState
+ bool1 = unlockPossible
+ },
+ {
+ "Cancellation signal is not null, high chance of bug in " +
+ "face auth lifecycle management. " +
+ "Face state: $int1, unlockPossible: $bool1"
+ }
+ )
}
fun logUnexpectedFpCancellationSignalState(
fingerprintRunningState: Int,
unlockPossible: Boolean
) {
- logBuffer.log(TAG, ERROR, {
- int1 = fingerprintRunningState
- bool1 = unlockPossible
- }, {
- "Cancellation signal is not null, high chance of bug in " +
- "fp auth lifecycle management. FP state: $int1, unlockPossible: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ ERROR,
+ {
+ int1 = fingerprintRunningState
+ bool1 = unlockPossible
+ },
+ {
+ "Cancellation signal is not null, high chance of bug in " +
+ "fp auth lifecycle management. FP state: $int1, unlockPossible: $bool1"
+ }
+ )
}
fun logUnregisterCallback(callback: KeyguardUpdateMonitorCallback?) {
- logBuffer.log(TAG, VERBOSE,
- { str1 = "$callback" },
- { "*** unregister callback for $str1" })
+ logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** unregister callback for $str1" })
}
fun logUserRequestedUnlock(
@@ -390,75 +488,173 @@
reason: String?,
dismissKeyguard: Boolean
) {
- logBuffer.log("ActiveUnlock", DEBUG, {
- str1 = requestOrigin?.name
- str2 = reason
- bool1 = dismissKeyguard
- }, { "reportUserRequestedUnlock origin=$str1 reason=$str2 dismissKeyguard=$bool1" })
+ logBuffer.log(
+ "ActiveUnlock",
+ DEBUG,
+ {
+ str1 = requestOrigin?.name
+ str2 = reason
+ bool1 = dismissKeyguard
+ },
+ { "reportUserRequestedUnlock origin=$str1 reason=$str2 dismissKeyguard=$bool1" }
+ )
}
fun logTrustGrantedWithFlags(
- flags: Int,
- newlyUnlocked: Boolean,
- userId: Int,
- message: String?
+ flags: Int,
+ newlyUnlocked: Boolean,
+ userId: Int,
+ message: String?
) {
- logBuffer.log(TAG, DEBUG, {
- int1 = flags
- bool1 = newlyUnlocked
- int2 = userId
- str1 = message
- }, { "trustGrantedWithFlags[user=$int2] newlyUnlocked=$bool1 " +
- "flags=${TrustGrantFlags(int1)} message=$str1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = flags
+ bool1 = newlyUnlocked
+ int2 = userId
+ str1 = message
+ },
+ {
+ "trustGrantedWithFlags[user=$int2] newlyUnlocked=$bool1 " +
+ "flags=${TrustGrantFlags(int1)} message=$str1"
+ }
+ )
}
- fun logTrustChanged(
- wasTrusted: Boolean,
- isNowTrusted: Boolean,
- userId: Int
- ) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = wasTrusted
- bool2 = isNowTrusted
- int1 = userId
- }, { "onTrustChanged[user=$int1] wasTrusted=$bool1 isNowTrusted=$bool2" })
+ fun logTrustChanged(wasTrusted: Boolean, isNowTrusted: Boolean, userId: Int) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = wasTrusted
+ bool2 = isNowTrusted
+ int1 = userId
+ },
+ { "onTrustChanged[user=$int1] wasTrusted=$bool1 isNowTrusted=$bool2" }
+ )
}
fun logKeyguardStateUpdate(
- secure: Boolean,
- canDismissLockScreen: Boolean,
- trusted: Boolean,
- trustManaged: Boolean
-
+ secure: Boolean,
+ canDismissLockScreen: Boolean,
+ trusted: Boolean,
+ trustManaged: Boolean
) {
- logBuffer.log("KeyguardState", DEBUG, {
- bool1 = secure
- bool2 = canDismissLockScreen
- bool3 = trusted
- bool4 = trustManaged
- }, { "#update secure=$bool1 canDismissKeyguard=$bool2" +
- " trusted=$bool3 trustManaged=$bool4" })
+ logBuffer.log(
+ "KeyguardState",
+ DEBUG,
+ {
+ bool1 = secure
+ bool2 = canDismissLockScreen
+ bool3 = trusted
+ bool4 = trustManaged
+ },
+ {
+ "#update secure=$bool1 canDismissKeyguard=$bool2" +
+ " trusted=$bool3 trustManaged=$bool4"
+ }
+ )
}
fun logSkipUpdateFaceListeningOnWakeup(@WakeReason pmWakeReason: Int) {
- logBuffer.log(TAG, VERBOSE, {
- str1 = PowerManager.wakeReasonToString(pmWakeReason)
- }, { "Skip updating face listening state on wakeup from $str1"})
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { str1 = PowerManager.wakeReasonToString(pmWakeReason) },
+ { "Skip updating face listening state on wakeup from $str1" }
+ )
}
fun logTaskStackChangedForAssistant(assistantVisible: Boolean) {
- logBuffer.log(TAG, VERBOSE, {
- bool1 = assistantVisible
- }, {
- "TaskStackChanged for ACTIVITY_TYPE_ASSISTANT, assistant visible: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { bool1 = assistantVisible },
+ { "TaskStackChanged for ACTIVITY_TYPE_ASSISTANT, assistant visible: $bool1" }
+ )
}
fun logAssistantVisible(assistantVisible: Boolean) {
- logBuffer.log(TAG, VERBOSE, {
- bool1 = assistantVisible
- }, {
- "Updating mAssistantVisible to new value: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { bool1 = assistantVisible },
+ { "Updating mAssistantVisible to new value: $bool1" }
+ )
+ }
+
+ fun logReportSuccessfulBiometricUnlock(isStrongBiometric: Boolean, userId: Int) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = isStrongBiometric
+ int1 = userId
+ },
+ { "reporting successful biometric unlock: isStrongBiometric: $bool1, userId: $int1" }
+ )
+ }
+
+ fun logHandlerHasAuthContinueMsgs(action: Int) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = action },
+ {
+ "MSG_BIOMETRIC_AUTHENTICATION_CONTINUE already queued up, " +
+ "ignoring updating FP listening state to $int1"
+ }
+ )
+ }
+
+ fun logFaceEnrolledUpdated(oldValue: Boolean, newValue: Boolean) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = oldValue
+ bool2 = newValue
+ },
+ { "Face enrolled state changed: old: $bool1, new: $bool2" }
+ )
+ }
+
+ fun logFpEnrolledUpdated(userId: Int, oldValue: Boolean, newValue: Boolean) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = userId
+ bool1 = oldValue
+ bool2 = newValue
+ },
+ { "Fp enrolled state changed for userId: $int1 old: $bool1, new: $bool2" }
+ )
+ }
+
+ fun logTrustUsuallyManagedUpdated(
+ userId: Int,
+ oldValue: Boolean,
+ newValue: Boolean,
+ context: String
+ ) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = userId
+ bool1 = oldValue
+ bool2 = newValue
+ str1 = context
+ },
+ {
+ "trustUsuallyManaged changed for " +
+ "userId: $int1 " +
+ "old: $bool1, " +
+ "new: $bool2 " +
+ "context: $context"
+ }
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index ce42534..0002ae9 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -38,7 +38,6 @@
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
-import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -347,10 +346,9 @@
}
if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
updatePercentText();
- addView(mBatteryPercentView,
- new ViewGroup.LayoutParams(
- LayoutParams.WRAP_CONTENT,
- LayoutParams.MATCH_PARENT));
+ addView(mBatteryPercentView, new LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.MATCH_PARENT));
}
} else {
if (showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index d68fcd0..8f6b5c9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -26,6 +26,7 @@
import androidx.annotation.VisibleForTesting
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.keyguard.logging.KeyguardLogger
import com.android.settingslib.Utils
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
@@ -74,6 +75,7 @@
private val udfpsControllerProvider: Provider<UdfpsController>,
private val statusBarStateController: StatusBarStateController,
private val featureFlags: FeatureFlags,
+ private val logger: KeyguardLogger,
rippleView: AuthRippleView?
) : ViewController<AuthRippleView>(rippleView), KeyguardStateController.Callback,
WakefulnessLifecycle.Observer {
@@ -120,8 +122,11 @@
}
fun showUnlockRipple(biometricSourceType: BiometricSourceType) {
- if (!keyguardStateController.isShowing ||
- !keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(biometricSourceType)) {
+ val keyguardNotShowing = !keyguardStateController.isShowing
+ val unlockNotAllowed = !keyguardUpdateMonitor
+ .isUnlockingWithBiometricAllowed(biometricSourceType)
+ if (keyguardNotShowing || unlockNotAllowed) {
+ logger.notShowingUnlockRipple(keyguardNotShowing, unlockNotAllowed)
return
}
@@ -138,6 +143,7 @@
Math.max(it.y, centralSurfaces.displayHeight.toInt() - it.y)
)
)
+ logger.showingUnlockRippleAt(it.x, it.y, "FP sensor radius: $udfpsRadius")
showUnlockedRipple()
}
} else if (biometricSourceType == BiometricSourceType.FACE) {
@@ -155,6 +161,7 @@
Math.max(it.y, centralSurfaces.displayHeight.toInt() - it.y)
)
)
+ logger.showingUnlockRippleAt(it.x, it.y, "Face unlock ripple")
showUnlockedRipple()
}
}
@@ -391,5 +398,6 @@
companion object {
const val RIPPLE_ANIMATION_DURATION: Long = 1533
+ const val TAG = "AuthRippleController"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
index fabc1c1..e16121d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt
@@ -49,8 +49,8 @@
/**
* @property messagesToDefer messages that shouldn't show immediately when received, but may be
- * shown later if the message is the most frequent acquiredInfo processed and meets [threshold]
- * percentage of all passed acquired frames.
+ * shown later if the message is the most frequent acquiredInfo processed and meets [threshold]
+ * percentage of all passed acquired frames.
*/
open class BiometricMessageDeferral(
private val messagesToDefer: Set<Int>,
@@ -127,8 +127,9 @@
/**
* Get the most frequent deferred message that meets the [threshold] percentage of processed
* frames.
+ *
* @return null if no acquiredInfo have been deferred OR deferred messages didn't meet the
- * [threshold] percentage.
+ * [threshold] percentage.
*/
fun getDeferredMessage(): CharSequence? {
mostFrequentAcquiredInfoToDefer?.let {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index ac6a22c..f7d87fc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -492,7 +492,9 @@
displayManager,
handler,
BiometricDisplayListener.SensorType.SideFingerprint(sensorProps)
- ) { onOrientationChanged(reason) }
+ ) {
+ onOrientationChanged(reason)
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
index addbee9..71cb35f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.kt
@@ -347,6 +347,7 @@
/**
* Overrides non-bouncer show logic in shouldPauseAuth to still show icon.
+ *
* @return whether the udfpsBouncer has been newly shown or hidden
*/
private fun showUdfpsBouncer(show: Boolean): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index bc0f995..f83885b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -38,6 +38,7 @@
public class FalsingDataProvider {
private static final long MOTION_EVENT_AGE_MS = 1000;
+ private static final long DROP_EVENT_THRESHOLD_MS = 50;
private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
private final int mWidthPixels;
@@ -60,6 +61,7 @@
private float mAngle = 0;
private MotionEvent mFirstRecentMotionEvent;
private MotionEvent mLastMotionEvent;
+ private boolean mDropLastEvent;
private boolean mJustUnlockedWithFace;
private boolean mA11YAction;
@@ -95,6 +97,12 @@
// Ensure prior gesture was completed. May be a no-op.
completePriorGesture();
}
+
+ // Drop the gesture closing event if it is close in time to a previous ACTION_MOVE event.
+ // The reason is that the closing ACTION_UP event of a swipe can be a bit offseted from the
+ // previous ACTION_MOVE event and when it happens, it makes some classifiers fail.
+ mDropLastEvent = shouldDropEvent(motionEvent);
+
mRecentMotionEvents.addAll(motionEvents);
FalsingClassifier.logVerbose("Size: " + mRecentMotionEvents.size());
@@ -129,6 +137,7 @@
mPriorMotionEvents = mRecentMotionEvents;
mRecentMotionEvents = new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
}
+ mDropLastEvent = false;
mA11YAction = false;
}
@@ -150,8 +159,18 @@
return mYdpi;
}
+ /**
+ * Get the {@link MotionEvent}s of the most recent gesture.
+ *
+ * Note that this list may not include the last recorded event.
+ * @see #mDropLastEvent
+ */
public List<MotionEvent> getRecentMotionEvents() {
- return mRecentMotionEvents;
+ if (!mDropLastEvent || mRecentMotionEvents.isEmpty()) {
+ return mRecentMotionEvents;
+ } else {
+ return mRecentMotionEvents.subList(0, mRecentMotionEvents.size() - 1);
+ }
}
public List<MotionEvent> getPriorMotionEvents() {
@@ -169,7 +188,12 @@
return mFirstRecentMotionEvent;
}
- /** Get the last recorded {@link MotionEvent}. */
+ /**
+ * Get the last {@link MotionEvent} of the most recent gesture.
+ *
+ * Note that this may be the event prior to the last recorded event.
+ * @see #mDropLastEvent
+ */
public MotionEvent getLastMotionEvent() {
recalculateData();
return mLastMotionEvent;
@@ -236,12 +260,13 @@
return;
}
- if (mRecentMotionEvents.isEmpty()) {
+ List<MotionEvent> recentMotionEvents = getRecentMotionEvents();
+ if (recentMotionEvents.isEmpty()) {
mFirstRecentMotionEvent = null;
mLastMotionEvent = null;
} else {
- mFirstRecentMotionEvent = mRecentMotionEvents.get(0);
- mLastMotionEvent = mRecentMotionEvents.get(mRecentMotionEvents.size() - 1);
+ mFirstRecentMotionEvent = recentMotionEvents.get(0);
+ mLastMotionEvent = recentMotionEvents.get(recentMotionEvents.size() - 1);
}
calculateAngleInternal();
@@ -249,6 +274,17 @@
mDirty = false;
}
+ private boolean shouldDropEvent(MotionEvent event) {
+ if (mRecentMotionEvents.size() < 3) return false;
+
+ MotionEvent lastEvent = mRecentMotionEvents.get(mRecentMotionEvents.size() - 1);
+ boolean isCompletingGesture = event.getActionMasked() == MotionEvent.ACTION_UP
+ && lastEvent.getActionMasked() == MotionEvent.ACTION_MOVE;
+ boolean isRecentEvent =
+ event.getEventTime() - lastEvent.getEventTime() < DROP_EVENT_THRESHOLD_MS;
+ return isCompletingGesture && isRecentEvent;
+ }
+
private void calculateAngleInternal() {
if (mRecentMotionEvents.size() < 2) {
mAngle = Float.MAX_VALUE;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
index e5da389..addd8e2 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
@@ -183,7 +183,7 @@
@Override
public List<MotionEvent> subList(int fromIndex, int toIndex) {
- throw new UnsupportedOperationException();
+ return mMotionEvents.subList(fromIndex, toIndex);
}
class Iter implements ListIterator<MotionEvent> {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index c214f53..2501be9 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -263,10 +263,11 @@
@Override // ClipboardListener.ClipboardOverlay
public void setClipData(ClipData data, String source) {
ClipboardModel model = ClipboardModel.fromClipData(mContext, mClipboardUtils, data, source);
- if (mExitAnimator != null && mExitAnimator.isRunning()) {
+ boolean wasExiting = (mExitAnimator != null && mExitAnimator.isRunning());
+ if (wasExiting) {
mExitAnimator.cancel();
}
- boolean shouldAnimate = !model.dataMatches(mClipboardModel);
+ boolean shouldAnimate = !model.dataMatches(mClipboardModel) || wasExiting;
mClipboardModel = model;
mClipboardLogger.setClipSource(mClipboardModel.getSource());
if (shouldAnimate) {
@@ -313,15 +314,19 @@
mOnPreviewTapped = this::editText;
break;
case IMAGE:
- if (model.isSensitive() || model.loadThumbnail(mContext) != null) {
- mView.showImagePreview(
- model.isSensitive() ? null : model.loadThumbnail(mContext));
- mView.setEditAccessibilityAction(true);
- mOnPreviewTapped = () -> editImage(model.getUri());
- } else {
- // image loading failed
- mView.showDefaultTextPreview();
- }
+ mBgExecutor.execute(() -> {
+ if (model.isSensitive() || model.loadThumbnail(mContext) != null) {
+ mView.post(() -> {
+ mView.showImagePreview(
+ model.isSensitive() ? null : model.loadThumbnail(mContext));
+ mView.setEditAccessibilityAction(true);
+ });
+ mOnPreviewTapped = () -> editImage(model.getUri());
+ } else {
+ // image loading failed
+ mView.post(mView::showDefaultTextPreview);
+ }
+ });
break;
case URI:
case OTHER:
@@ -363,15 +368,15 @@
private void classifyText(ClipboardModel model) {
mBgExecutor.execute(() -> {
- Optional<RemoteAction> remoteAction = mClipboardUtils.getAction(
- model.getText(), model.getTextLinks(), model.getSource());
+ Optional<RemoteAction> remoteAction =
+ mClipboardUtils.getAction(model.getTextLinks(), model.getSource());
if (model.equals(mClipboardModel)) {
remoteAction.ifPresent(action -> {
mClipboardLogger.logUnguarded(CLIPBOARD_OVERLAY_ACTION_SHOWN);
- mView.setActionChip(action, () -> {
+ mView.post(() -> mView.setActionChip(action, () -> {
mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_ACTION_TAPPED);
animateOut();
- });
+ }));
});
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
index a85f8b9..25caaea 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java
@@ -39,6 +39,9 @@
class ClipboardOverlayUtils {
+ // minimum proportion of entire text an entity must take up, to be considered for smart actions
+ private static final float MINIMUM_ENTITY_PROPORTION = .8f;
+
private final TextClassifier mTextClassifier;
@Inject
@@ -65,19 +68,23 @@
return false;
}
- public Optional<RemoteAction> getAction(CharSequence text, TextLinks textLinks, String source) {
- return getActions(text, textLinks).stream().filter(remoteAction -> {
+ public Optional<RemoteAction> getAction(TextLinks textLinks, String source) {
+ return getActions(textLinks).stream().filter(remoteAction -> {
ComponentName component = remoteAction.getActionIntent().getIntent().getComponent();
return component != null && !TextUtils.equals(source, component.getPackageName());
}).findFirst();
}
- private ArrayList<RemoteAction> getActions(CharSequence text, TextLinks textLinks) {
+ private ArrayList<RemoteAction> getActions(TextLinks textLinks) {
ArrayList<RemoteAction> actions = new ArrayList<>();
for (TextLinks.TextLink link : textLinks.getLinks()) {
- TextClassification classification = mTextClassifier.classifyText(
- text, link.getStart(), link.getEnd(), null);
- actions.addAll(classification.getActions());
+ // skip classification for incidental entities
+ if (link.getEnd() - link.getStart()
+ >= textLinks.getText().length() * MINIMUM_ENTITY_PROPORTION) {
+ TextClassification classification = mTextClassifier.classifyText(
+ textLinks.getText(), link.getStart(), link.getEnd(), null);
+ actions.addAll(classification.getActions());
+ }
}
return actions;
}
@@ -92,9 +99,13 @@
private ArrayList<RemoteAction> getActions(ClipData.Item item) {
ArrayList<RemoteAction> actions = new ArrayList<>();
for (TextLinks.TextLink link : item.getTextLinks().getLinks()) {
- TextClassification classification = mTextClassifier.classifyText(
- item.getText(), link.getStart(), link.getEnd(), null);
- actions.addAll(classification.getActions());
+ // skip classification for incidental entities
+ if (link.getEnd() - link.getStart()
+ >= item.getText().length() * MINIMUM_ENTITY_PROPORTION) {
+ TextClassification classification = mTextClassifier.classifyText(
+ item.getText(), link.getStart(), link.getEnd(), null);
+ actions.addAll(classification.getActions());
+ }
}
return actions;
}
diff --git a/packages/SystemUI/src/com/android/systemui/common/coroutine/ChannelExt.kt b/packages/SystemUI/src/com/android/systemui/common/coroutine/ChannelExt.kt
index a0b19dc..c0e1717 100644
--- a/packages/SystemUI/src/com/android/systemui/common/coroutine/ChannelExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/coroutine/ChannelExt.kt
@@ -26,7 +26,6 @@
/**
* Convenience wrapper around [SendChannel.trySend] that also logs on failure. This is the
* equivalent of calling:
- *
* ```
* sendChannel.trySend(element).onFailure {
* Log.e(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
index b3c18fb..3744344 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
@@ -86,6 +86,7 @@
*
* When the favorites for that application are returned, they will be removed from the auxiliary
* file immediately, so they won't be retrieved again.
+ *
* @param componentName the name of the service that provided the controls
* @return a list of structures with favorites
*/
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index 72c3a94..217f4d8 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -84,7 +84,7 @@
private val BIND_FLAGS_PANEL = Context.BIND_AUTO_CREATE or Context.BIND_NOT_PERCEPTIBLE
}
- private val intent = Intent().apply {
+ private val intent = Intent(ControlsProviderService.SERVICE_CONTROLS).apply {
component = componentName
putExtra(CALLBACK_BUNDLE, Bundle().apply {
putBinder(CALLBACK_TOKEN, token)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
index bb2e2d7..06d4a08 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt
@@ -38,7 +38,6 @@
/**
* Manager to display a dialog to prompt user to enable controls related Settings:
- *
* * [Settings.Secure.LOCKSCREEN_SHOW_CONTROLS]
* * [Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS]
*/
@@ -46,20 +45,19 @@
/**
* Shows the corresponding dialog. In order for a dialog to appear, the following must be true
- *
* * At least one of the Settings in [ControlsSettingsRepository] are `false`.
* * The dialog has not been seen by the user too many times (as defined by
- * [MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG]).
+ * [MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG]).
*
* When the dialogs are shown, the following outcomes are possible:
* * User cancels the dialog by clicking outside or going back: we register that the dialog was
- * seen but the settings don't change.
+ * seen but the settings don't change.
* * User responds negatively to the dialog: we register that the user doesn't want to change
- * the settings (dialog will not appear again) and the settings don't change.
+ * the settings (dialog will not appear again) and the settings don't change.
* * User responds positively to the dialog: the settings are set to `true` and the dialog will
- * not appear again.
+ * not appear again.
* * SystemUI closes the dialogs (for example, the activity showing it is closed). In this case,
- * we don't modify anything.
+ * we don't modify anything.
*
* Of those four scenarios, only the first three will cause [onAttemptCompleted] to be called.
* It will also be called if the dialogs are not shown.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index fb01691..cb2d673 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -29,6 +29,7 @@
import com.android.systemui.settings.brightness.BrightnessDialog;
import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity;
import com.android.systemui.tuner.TunerActivity;
+import com.android.systemui.usb.UsbAccessoryUriActivity;
import com.android.systemui.usb.UsbConfirmActivity;
import com.android.systemui.usb.UsbDebuggingActivity;
import com.android.systemui.usb.UsbDebuggingSecondaryUserActivity;
@@ -94,6 +95,12 @@
@ClassKey(UsbConfirmActivity.class)
public abstract Activity bindUsbConfirmActivity(UsbConfirmActivity activity);
+ /** Inject into UsbAccessoryUriActivity. */
+ @Binds
+ @IntoMap
+ @ClassKey(UsbAccessoryUriActivity.class)
+ public abstract Activity bindUsbAccessoryUriActivity(UsbAccessoryUriActivity activity);
+
/** Inject into CreateUserActivity. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index f0ee443..cedc226a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -75,6 +75,7 @@
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.connectivity.ConnectivityModule;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
@@ -256,9 +257,7 @@
abstract FingerprintInteractiveToAuthProvider optionalFingerprintInteractiveToAuthProvider();
@BindsOptionalOf
- //TODO(b/269430792 remove full qualifier. Full qualifier is used to avoid merge conflict.)
- abstract com.android.systemui.statusbar.events.SystemStatusAnimationScheduler
- optionalSystemStatusAnimationScheduler();
+ abstract SystemStatusAnimationScheduler optionalSystemStatusAnimationScheduler();
@SysUISingleton
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
index 84f83f1..45ff963 100644
--- a/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
+++ b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
@@ -128,7 +128,6 @@
*
* This is equivalent of creating a listener manually and adding an event handler for the given
* command, like so:
- *
* ```
* class Demoable {
* private val demoHandler = object : DemoMode {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
index c3bd5d9..ca1cef3 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
@@ -184,6 +184,7 @@
/**
* Ends the dream content and dream overlay animations, if they're currently running.
+ *
* @see [AnimatorSet.end]
*/
fun endAnimations() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index 73c2289..a7b3bbc 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -254,7 +254,10 @@
mCurrentScrimController = mScrimManager.getCurrentController();
session.registerCallback(() -> {
- mVelocityTracker.recycle();
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
mScrimManager.removeCallback(mScrimManagerCallback);
mCapture = null;
mNotificationShadeWindowController.setForcePluginOpen(false, this);
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 7809b63..858d76b94 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -157,12 +157,6 @@
val CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES =
unreleasedFlag(216, "customizable_lock_screen_quick_affordances", teamfood = true)
- /** Shows chipbar UI whenever the device is unlocked by ActiveUnlock (watch). */
- // TODO(b/256513609): Tracking Bug
- @JvmField
- val ACTIVE_UNLOCK_CHIPBAR =
- resourceBooleanFlag(217, R.bool.flag_active_unlock_chipbar, "active_unlock_chipbar")
-
/**
* Migrates control of the LightRevealScrim's reveal effect and amount from legacy code to the
* new KeyguardTransitionRepository.
@@ -272,8 +266,7 @@
/** Enables new QS Edit Mode visual refresh */
// TODO(b/269787742): Tracking Bug
@JvmField
- val ENABLE_NEW_QS_EDIT_MODE =
- unreleasedFlag(510, "enable_new_qs_edit_mode", teamfood = false)
+ val ENABLE_NEW_QS_EDIT_MODE = unreleasedFlag(510, "enable_new_qs_edit_mode", teamfood = false)
// 600- status bar
@@ -359,7 +352,7 @@
val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE = releasedFlag(910, "media_ttt_receiver_success_ripple")
// TODO(b/263512203): Tracking Bug
- val MEDIA_EXPLICIT_INDICATOR = unreleasedFlag(911, "media_explicit_indicator", teamfood = true)
+ val MEDIA_EXPLICIT_INDICATOR = unreleasedFlag(911, "media_explicit_indicator")
// TODO(b/265813373): Tracking Bug
val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE = releasedFlag(912, "media_ttt_dismiss_gesture")
@@ -392,6 +385,9 @@
// TODO(b/265045965): Tracking Bug
val SHOW_LOWLIGHT_ON_DIRECT_BOOT = releasedFlag(1003, "show_lowlight_on_direct_boot")
+ @JvmField
+ val ENABLE_LOW_LIGHT_CLOCK_UNDOCKED = unreleasedFlag(1004, "enable_low_light_clock_undocked")
+
// 1100 - windowing
@Keep
@JvmField
@@ -445,7 +441,9 @@
)
// TODO(b/256873975): Tracking Bug
- @JvmField @Keep val WM_BUBBLE_BAR = unreleasedFlag(1111, "wm_bubble_bar")
+ @JvmField
+ @Keep
+ val WM_BUBBLE_BAR = sysPropBooleanFlag(1111, "persist.wm.debug.bubble_bar", default = false)
// TODO(b/260271148): Tracking bug
@Keep
@@ -468,7 +466,7 @@
@Keep
@JvmField
val ENABLE_PIP_SIZE_LARGE_SCREEN =
- sysPropBooleanFlag(1114, "persist.wm.debug.enable_pip_size_large_screen", default = false)
+ sysPropBooleanFlag(1114, "persist.wm.debug.enable_pip_size_large_screen", default = true)
// TODO(b/265998256): Tracking bug
@Keep
@@ -551,7 +549,7 @@
// 1500 - chooser aka sharesheet
// TODO(b/254512507): Tracking Bug
- val CHOOSER_UNBUNDLED = releasedFlag(1500, "chooser_unbundled")
+ val CHOOSER_UNBUNDLED = unreleasedFlag(1500, "chooser_unbundled")
// TODO(b/266983432) Tracking Bug
val SHARESHEET_CUSTOM_ACTIONS =
@@ -639,11 +637,6 @@
@JvmField
val OUTPUT_SWITCHER_DEVICE_STATUS = unreleasedFlag(2502, "output_switcher_device_status")
- // TODO(b/20911786): Tracking Bug
- @JvmField
- val OUTPUT_SWITCHER_SHOW_API_ENABLED =
- releasedFlag(2503, "output_switcher_show_api_enabled", teamfood = true)
-
// 2700 - unfold transitions
// TODO(b/265764985): Tracking Bug
@Keep
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index e80e71c..03b45b5 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -2054,6 +2054,10 @@
|| Intent.ACTION_SCREEN_OFF.equals(action)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (!SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
+ // These broadcasts are usually received when locking the device, swiping up to
+ // home (which collapses the shade), etc. In those cases, we usually don't want
+ // to animate this dialog back into the view, so we disable the exit animations.
+ mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISMISS, reason));
}
} else if (TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt
index b0f9c4e..d078688 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt
@@ -21,6 +21,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyboard.backlight.ui.KeyboardBacklightDialogCoordinator
import javax.inject.Inject
/** A [CoreStartable] that launches components interested in physical keyboard interaction. */
@@ -28,11 +29,12 @@
class PhysicalKeyboardCoreStartable
@Inject
constructor(
+ private val keyboardBacklightDialogCoordinator: KeyboardBacklightDialogCoordinator,
private val featureFlags: FeatureFlags,
) : CoreStartable {
override fun start() {
if (featureFlags.isEnabled(Flags.KEYBOARD_BACKLIGHT_INDICATOR)) {
- // TODO(b/268645743) start listening for keyboard backlight brightness
+ keyboardBacklightDialogCoordinator.startListening()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractor.kt
new file mode 100644
index 0000000..65e70b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractor.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.keyboard.backlight.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyboard.data.repository.KeyboardRepository
+import com.android.systemui.keyboard.shared.model.BacklightModel
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+
+/** Allows listening to changes to keyboard backlight level */
+@SysUISingleton
+class KeyboardBacklightInteractor
+@Inject
+constructor(
+ private val keyboardRepository: KeyboardRepository,
+) {
+
+ /** Emits current backlight level as [BacklightModel] or null if keyboard is not connected */
+ val backlight: Flow<BacklightModel?> =
+ keyboardRepository.keyboardConnected.flatMapLatest { connected ->
+ if (connected) keyboardRepository.backlight else flowOf(null)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinator.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinator.kt
new file mode 100644
index 0000000..85d0379
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinator.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.keyboard.backlight.ui
+
+import android.content.Context
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyboard.backlight.ui.view.KeyboardBacklightDialog
+import com.android.systemui.keyboard.backlight.ui.viewmodel.BacklightDialogViewModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/**
+ * Based on the state produced from [BacklightDialogViewModel] shows or hides keyboard backlight
+ * indicator
+ */
+@SysUISingleton
+class KeyboardBacklightDialogCoordinator
+@Inject
+constructor(
+ @Application private val applicationScope: CoroutineScope,
+ private val context: Context,
+ private val viewModel: BacklightDialogViewModel,
+) {
+
+ var dialog: KeyboardBacklightDialog? = null
+
+ fun startListening() {
+ applicationScope.launch {
+ viewModel.dialogContent.collect { dialogViewModel ->
+ if (dialogViewModel != null) {
+ if (dialog == null) {
+ dialog = KeyboardBacklightDialog(context, dialogViewModel)
+ // pass viewModel and show
+ }
+ } else {
+ dialog?.dismiss()
+ dialog = null
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
new file mode 100644
index 0000000..b68a2a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.keyboard.backlight.ui.view
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import com.android.systemui.keyboard.backlight.ui.viewmodel.BacklightDialogContentViewModel
+
+class KeyboardBacklightDialog(context: Context, val viewModel: BacklightDialogContentViewModel) :
+ Dialog(context) {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ // TODO(b/268650355) Implement the dialog
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogContentViewModel.kt
similarity index 68%
copy from packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt
copy to packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogContentViewModel.kt
index ea15a9f..3ef0ca3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogContentViewModel.kt
@@ -15,10 +15,6 @@
*
*/
-package com.android.systemui.keyboard.data.model
+package com.android.systemui.keyboard.backlight.ui.viewmodel
-/**
- * Model for current state of keyboard backlight brightness. [level] indicates current level of
- * backlight brightness and [maxLevel] its max possible value.
- */
-data class BacklightModel(val level: Int, val maxLevel: Int)
+data class BacklightDialogContentViewModel(val currentValue: Int, val maxValue: Int)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModel.kt
new file mode 100644
index 0000000..86abca5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModel.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.keyboard.backlight.ui.viewmodel
+
+import android.view.accessibility.AccessibilityManager
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyboard.backlight.domain.interactor.KeyboardBacklightInteractor
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
+import javax.inject.Inject
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.map
+
+/**
+ * Responsible for dialog visibility and content - emits [BacklightDialogContentViewModel] if dialog
+ * should be shown and hidden otherwise
+ */
+@SysUISingleton
+class BacklightDialogViewModel
+@Inject
+constructor(
+ interactor: KeyboardBacklightInteractor,
+ private val accessibilityManagerWrapper: AccessibilityManagerWrapper,
+) {
+
+ private val timeoutMillis: Long
+ get() =
+ accessibilityManagerWrapper
+ .getRecommendedTimeoutMillis(
+ DEFAULT_DIALOG_TIMEOUT_MILLIS,
+ AccessibilityManager.FLAG_CONTENT_ICONS
+ )
+ .toLong()
+
+ val dialogContent: Flow<BacklightDialogContentViewModel?> =
+ interactor.backlight
+ .filterNotNull()
+ .map { BacklightDialogContentViewModel(it.level, it.maxLevel) }
+ .timeout(timeoutMillis, emitAfterTimeout = null)
+
+ private fun <T> Flow<T>.timeout(timeoutMillis: Long, emitAfterTimeout: T): Flow<T> {
+ return flatMapLatest {
+ flow {
+ emit(it)
+ delay(timeoutMillis)
+ emit(emitAfterTimeout)
+ }
+ }
+ }
+
+ private companion object {
+ const val DEFAULT_DIALOG_TIMEOUT_MILLIS = 3000
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
index 70faf40..9449ece 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
@@ -23,7 +23,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.keyboard.data.model.BacklightModel
+import com.android.systemui.keyboard.shared.model.BacklightModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shared/model/BacklightModel.kt
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt
rename to packages/SystemUI/src/com/android/systemui/keyboard/shared/model/BacklightModel.kt
index ea15a9f..4a32f79 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shared/model/BacklightModel.kt
@@ -15,7 +15,7 @@
*
*/
-package com.android.systemui.keyboard.data.model
+package com.android.systemui.keyboard.shared.model
/**
* Model for current state of keyboard backlight brightness. [level] indicates current level of
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d914bf5..85554ac 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1920,20 +1920,24 @@
// If the keyguard is already showing, see if we don't need to bother re-showing it. Check
// flags in both files to account for the hiding animation which results in a delay and
- // discrepancy between flags.
+ // discrepancy between flags. If we're in the middle of hiding, do not short circuit so that
+ // we explicitly re-set state.
if (mShowing && mKeyguardStateController.isShowing()) {
- if (mPM.isInteractive()) {
+ if (mPM.isInteractive() && !mHiding) {
// It's already showing, and we're not trying to show it while the screen is off.
// We can simply reset all of the views.
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing (instead, resetting) because it is "
+ + "already showing, we're interactive, and we were not previously hiding. "
+ + "It should be safe to short-circuit here.");
resetStateLocked();
return;
} else {
- // We are trying to show the keyguard while the screen is off - this results from
- // race conditions involving locking while unlocking. Don't short-circuit here and
- // ensure the keyguard is fully re-shown.
+ // We are trying to show the keyguard while the screen is off or while we were in
+ // the middle of hiding - this results from race conditions involving locking while
+ // unlocking. Don't short-circuit here and ensure the keyguard is fully re-shown.
Log.e(TAG,
- "doKeyguard: already showing, but re-showing since we're not interactive");
+ "doKeyguard: already showing, but re-showing because we're interactive or "
+ + "were in the middle of hiding.");
}
}
@@ -2427,11 +2431,19 @@
if (DEBUG) Log.d(TAG, "handleShow");
}
- mHiding = false;
mKeyguardExitAnimationRunner = null;
mWakeAndUnlocking = false;
setPendingLock(false);
- setShowingLocked(true);
+
+ // Force if we we're showing in the middle of hiding, to ensure we end up in the correct
+ // state.
+ setShowingLocked(true, mHiding /* force */);
+ if (mHiding) {
+ Log.d(TAG, "Forcing setShowingLocked because mHiding=true, which means we're "
+ + "showing in the middle of hiding.");
+ }
+ mHiding = false;
+
mKeyguardViewControllerLazy.get().show(options);
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index be73f85..ef0c9a1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -134,7 +134,9 @@
.flowOn(backgroundDispatcher)
.distinctUntilChanged()
.onEach { settingsValue = it }
- ) { callbackFlowValue, _ -> callbackFlowValue }
+ ) { callbackFlowValue, _ ->
+ callbackFlowValue
+ }
override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
return if (controller.isZenAvailable) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
index 0066785..356a8fb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
@@ -102,7 +102,8 @@
// setup).
emit(Unit)
}
- ) { _, _ -> }
+ ) { _, _ ->
+ }
.flatMapLatest {
conflatedCallbackFlow {
// We want to instantiate a new SharedPreferences instance each time either the
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
index 0e85347..86e5cd7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
@@ -53,6 +53,7 @@
val primaryBouncerScrimmed: StateFlow<Boolean>
/**
* Set how much of the notification panel is showing on the screen.
+ *
* ```
* 0f = panel fully hidden = bouncer fully showing
* 1f = panel fully showing = bouncer fully hidden
@@ -134,6 +135,7 @@
override val primaryBouncerScrimmed = _primaryBouncerScrimmed.asStateFlow()
/**
* Set how much of the notification panel is showing on the screen.
+ *
* ```
* 0f = panel fully hidden = bouncer fully showing
* 1f = panel fully showing = bouncer fully hidden
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
index 0140529..eae40d6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
@@ -50,6 +50,7 @@
/**
* Sets the correct bouncer states to show the alternate bouncer if it can show.
+ *
* @return whether alternateBouncer is visible
*/
fun show(): Boolean {
@@ -74,6 +75,7 @@
* Sets the correct bouncer states to hide the bouncer. Should only be called through
* StatusBarKeyguardViewManager until ScrimController is refactored to use
* alternateBouncerInteractor.
+ *
* @return true if the alternate bouncer was newly hidden, else false.
*/
fun hide(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 310f44d..e6568f2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -71,8 +71,7 @@
isPrimaryBouncerShowing,
lastStartedTransitionStep,
wakefulnessState,
- isAodAvailable
- ) ->
+ isAodAvailable) ->
if (
!isAlternateBouncerShowing &&
!isPrimaryBouncerShowing &&
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index dfbe1c2..568cc0f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -119,7 +119,7 @@
* Notifies that a quick affordance has been "triggered" (clicked) by the user.
*
* @param configKey The configuration key corresponding to the [KeyguardQuickAffordanceModel] of
- * the affordance that was clicked
+ * the affordance that was clicked
* @param expandable An optional [Expandable] for the activity- or dialog-launch animation
*/
fun onQuickAffordanceTriggered(
@@ -198,9 +198,9 @@
*
* @param slotId The ID of the slot.
* @param affordanceId The ID of the affordance to remove; if `null`, removes all affordances
- * from the slot.
+ * from the slot.
* @return `true` if the affordance was successfully removed; `false` otherwise (for example, if
- * the affordance was not on the slot to begin with).
+ * the affordance was not on the slot to begin with).
*/
suspend fun unselect(slotId: String, affordanceId: String?): Boolean {
check(isUsingRepository)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
index ca1e27c..38b9d50 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
@@ -47,6 +47,7 @@
duration: Duration,
onStep: (Float) -> Float,
startTime: Duration = 0.milliseconds,
+ onStart: (() -> Unit)? = null,
onCancel: (() -> Float)? = null,
onFinish: (() -> Float)? = null,
interpolator: Interpolator = LINEAR,
@@ -73,6 +74,7 @@
// the ViewModels of the last update
STARTED -> {
isComplete = false
+ onStart?.invoke()
max(0f, min(1f, value))
}
// Always send a final value of 1. Because of rounding, [value] may never be
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index ab009f4..2a9060f6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -342,7 +342,13 @@
if (viewModel.isClickable) {
if (viewModel.useLongPress) {
view.setOnTouchListener(
- OnTouchListener(view, viewModel, messageDisplayer, vibratorHelper)
+ OnTouchListener(
+ view,
+ viewModel,
+ messageDisplayer,
+ vibratorHelper,
+ falsingManager,
+ )
)
} else {
view.setOnClickListener(OnClickListener(viewModel, checkNotNull(falsingManager)))
@@ -371,6 +377,7 @@
private val viewModel: KeyguardQuickAffordanceViewModel,
private val messageDisplayer: (Int) -> Unit,
private val vibratorHelper: VibratorHelper?,
+ private val falsingManager: FalsingManager?,
) : View.OnTouchListener {
private val longPressDurationMs = ViewConfiguration.getLongPressTimeout().toLong()
@@ -395,7 +402,14 @@
.scaleY(PRESSED_SCALE)
.setDuration(longPressDurationMs)
.withEndAction {
- dispatchClick(viewModel.configKey)
+ if (
+ falsingManager
+ ?.isFalseLongTap(
+ FalsingManager.MODERATE_PENALTY
+ ) == false
+ ) {
+ dispatchClick(viewModel.configKey)
+ }
cancel()
}
}
@@ -421,7 +435,8 @@
// the pointer performs a click.
if (
viewModel.configKey != null &&
- distanceMoved(event) <= ViewConfiguration.getTouchSlop()
+ distanceMoved(event) <= ViewConfiguration.getTouchSlop() &&
+ falsingManager?.isFalseTap(FalsingManager.NO_PENALTY) == false
) {
dispatchClick(viewModel.configKey)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
index ef3f242..8671753 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
@@ -34,7 +34,7 @@
* @param viewModel The view-model that models the UI state.
* @param onSingleTap A callback to invoke when the system decides that there was a single tap.
* @param falsingManager [FalsingManager] for making sure the long-press didn't just happen in
- * the user's pocket.
+ * the user's pocket.
*/
@JvmStatic
fun bind(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index e7184f7..ab9e6a4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -135,7 +135,7 @@
*
* @param initiallySelectedSlotId The ID of the initial slot to render as the selected one.
* @param shouldHighlightSelectedAffordance Whether the selected quick affordance should be
- * highlighted (while all others are dimmed to make the selected one stand out).
+ * highlighted (while all others are dimmed to make the selected one stand out).
*/
fun enablePreviewMode(
initiallySelectedSlotId: String?,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index 0890791..92038e2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -21,6 +21,7 @@
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.statusbar.SysuiStatusBarStateController
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
@@ -34,6 +35,7 @@
@Inject
constructor(
private val interactor: KeyguardTransitionInteractor,
+ private val statusBarStateController: SysuiStatusBarStateController,
) {
private val transitionAnimation =
KeyguardTransitionAnimationFlow(
@@ -41,6 +43,8 @@
transitionFlow = interactor.primaryBouncerToGoneTransition,
)
+ private var leaveShadeOpen: Boolean = false
+
/** Bouncer container alpha */
val bouncerAlpha: Flow<Float> =
transitionAnimation.createFlow(
@@ -48,11 +52,18 @@
onStep = { 1f - it },
)
- /** Scrim alpha */
- val scrimAlpha: Flow<Float> =
+ /** Scrim behind alpha */
+ val scrimBehindAlpha: Flow<Float> =
transitionAnimation.createFlow(
duration = TO_GONE_DURATION,
interpolator = EMPHASIZED_ACCELERATE,
- onStep = { 1f - it },
+ onStart = { leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() },
+ onStep = {
+ if (leaveShadeOpen) {
+ 1f
+ } else {
+ 1f - it
+ }
+ },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
index d69ac7f..34a6740 100644
--- a/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
@@ -47,13 +47,13 @@
* fresh one.
*
* @param coroutineContext An optional [CoroutineContext] to replace the dispatcher [block] is
- * invoked on.
+ * invoked on.
* @param block The block of code that should be run when the view becomes attached. It can end up
- * being invoked multiple times if the view is reattached after being detached.
+ * being invoked multiple times if the view is reattached after being detached.
* @return A [DisposableHandle] to invoke when the caller of the function destroys its [View] and is
- * no longer interested in the [block] being run the next time its attached. Calling this is an
- * optional optimization as the logic will be properly cleaned up and destroyed each time the view
- * is detached. Using this is not *thread-safe* and should only be used on the main thread.
+ * no longer interested in the [block] being run the next time its attached. Calling this is an
+ * optional optimization as the logic will be properly cleaned up and destroyed each time the view
+ * is detached. Using this is not *thread-safe* and should only be used on the main thread.
*/
@MainThread
fun View.repeatWhenAttached(
@@ -125,7 +125,6 @@
* The implementation requires the caller to call [onCreate] and [onDestroy] when the view is
* attached to or detached from a view hierarchy. After [onCreate] and before [onDestroy] is called,
* the implementation monitors window state in the following way
- *
* * If the window is not visible, we are in the [Lifecycle.State.CREATED] state
* * If the window is visible but not focused, we are in the [Lifecycle.State.STARTED] state
* * If the window is visible and focused, we are in the [Lifecycle.State.RESUMED] state
diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
index f7349a2..647e3a1 100644
--- a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
@@ -16,7 +16,6 @@
* Helper class for logging for [com.android.keyguard.faceauth.KeyguardFaceAuthManager]
*
* To enable logcat echoing for an entire buffer:
- *
* ```
* adb shell settings put global systemui/buffer/KeyguardFaceAuthManagerLog <logLevel>
*
diff --git a/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt b/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt
index 5acaa46..edc278d 100644
--- a/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/ScreenDecorationsLogger.kt
@@ -33,7 +33,6 @@
* Helper class for logging for [com.android.systemui.ScreenDecorations]
*
* To enable logcat echoing for an entire buffer:
- *
* ```
* adb shell settings put global systemui/buffer/ScreenDecorationsLog <logLevel>
*
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
index 1712dab..29f273a 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
@@ -29,7 +29,6 @@
*
* Some parts of System UI maintain a lot of pieces of state at once.
* [com.android.systemui.plugins.log.LogBuffer] allows us to easily log change events:
- *
* - 10-10 10:10:10.456: state2 updated to newVal2
* - 10-10 10:11:00.000: stateN updated to StateN(val1=true, val2=1)
* - 10-10 10:11:02.123: stateN updated to StateN(val1=true, val2=2)
@@ -37,7 +36,6 @@
* - 10-10 10:11:06.000: stateN updated to StateN(val1=false, val2=3)
*
* However, it can sometimes be more useful to view the state changes in table format:
- *
* - timestamp--------- | state1- | state2- | ... | stateN.val1 | stateN.val2
* - -------------------------------------------------------------------------
* - 10-10 10:10:10.123 | val1--- | val2--- | ... | false------ | 0-----------
@@ -56,23 +54,18 @@
* individual fields.
*
* How it works:
- *
* 1) Create an instance of this buffer via [TableLogBufferFactory].
- *
* 2) For any states being logged, implement [Diffable]. Implementing [Diffable] allows the state to
- * only log the fields that have *changed* since the previous update, instead of always logging all
- * fields.
- *
+ * only log the fields that have *changed* since the previous update, instead of always logging
+ * all fields.
* 3) Each time a change in a state happens, call [logDiffs]. If your state is emitted using a
- * [Flow], you should use the [logDiffsForTable] extension function to automatically log diffs any
- * time your flow emits a new value.
+ * [Flow], you should use the [logDiffsForTable] extension function to automatically log diffs
+ * any time your flow emits a new value.
*
* When a dump occurs, there will be two dumps:
- *
* 1) The change events under the dumpable name "$name-changes".
- *
* 2) This class will coalesce all the diffs into a table format and log them under the dumpable
- * name "$name-table".
+ * name "$name-table".
*
* @param maxSize the maximum size of the buffer. Must be > 0.
*/
@@ -99,11 +92,10 @@
* The [newVal] object's method [Diffable.logDiffs] will be used to fetch the diffs.
*
* @param columnPrefix a prefix that will be applied to every column name that gets logged. This
- * ensures that all the columns related to the same state object will be grouped together in the
- * table.
- *
+ * ensures that all the columns related to the same state object will be grouped together in
+ * the table.
* @throws IllegalArgumentException if [columnPrefix] or column name contain "|". "|" is used as
- * the separator token for parsing, so it can't be present in any part of the column name.
+ * the separator token for parsing, so it can't be present in any part of the column name.
*/
@Synchronized
fun <T : Diffable<T>> logDiffs(columnPrefix: String, prevVal: T, newVal: T) {
@@ -117,7 +109,7 @@
* Logs change(s) to the buffer using [rowInitializer].
*
* @param rowInitializer a function that will be called immediately to store relevant data on
- * the row.
+ * the row.
*/
@Synchronized
fun logChange(columnPrefix: String, rowInitializer: (TableRowLogger) -> Unit) {
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
index 7ccc43c..06668d3 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
@@ -38,7 +38,6 @@
*
* @param name a unique table name
* @param maxSize the buffer max size. See [adjustMaxSize]
- *
* @return a new [TableLogBuffer] registered with [DumpManager]
*/
fun create(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarViewModel.kt
index a057c9f..2509f21 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarViewModel.kt
@@ -187,6 +187,7 @@
/**
* Handle request to change the current position in the media track.
+ *
* @param position Place to seek to in the track.
*/
@AnyThread
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt
index 0b57175..ae03f27 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt
@@ -52,6 +52,7 @@
* Indicates if all the data is valid.
*
* TODO(b/230333302): Make MediaControlPanel more flexible so that we can display fewer than
+ *
* ```
* [NUM_REQUIRED_RECOMMENDATIONS].
* ```
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt
index 97717a6..207df6b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt
@@ -329,9 +329,8 @@
* Return the time since last active for the most-recent media.
*
* @param sortedEntries userEntries sorted from the earliest to the most-recent.
- *
* @return The duration in milliseconds from the most-recent media's last active timestamp to
- * the present. MAX_VALUE will be returned if there is no media.
+ * the present. MAX_VALUE will be returned if there is no media.
*/
private fun timeSinceActiveForMostRecentMedia(
sortedEntries: SortedMap<String, MediaData>
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index e70a2f3..6023bc2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -525,8 +525,8 @@
* through the internal listener pipeline.
*
* @param immediately indicates should apply the UI changes immediately, otherwise wait until
- * the next refresh-round before UI becomes visible. Should only be true if the update is
- * initiated by user's interaction.
+ * the next refresh-round before UI becomes visible. Should only be true if the update is
+ * initiated by user's interaction.
*/
private fun notifySmartspaceMediaDataRemoved(key: String, immediately: Boolean) {
internalListeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) }
@@ -535,6 +535,7 @@
/**
* Called whenever the player has been paused or stopped for a while, or swiped from QQS. This
* will make the player not active anymore, hiding it from QQS and Keyguard.
+ *
* @see MediaData.active
*/
internal fun setTimedOut(key: String, timedOut: Boolean, forceUpdate: Boolean = false) {
@@ -1023,6 +1024,7 @@
* @param packageName Package name for the media app
* @param controller MediaController for the current session
* @return a Pair consisting of a list of media actions, and a list of ints representing which
+ *
* ```
* of those actions should be shown in the compact player
* ```
@@ -1126,6 +1128,7 @@
* [PlaybackState.ACTION_SKIP_TO_NEXT]
* @return
* ```
+ *
* A [MediaAction] with correct values set, or null if the state doesn't support it
*/
private fun getStandardAction(
@@ -1226,6 +1229,7 @@
}
/**
* Load a bitmap from a URI
+ *
* @param uri the uri to load
* @return bitmap, or null if couldn't be loaded
*/
@@ -1519,15 +1523,13 @@
* notification key) or vice versa.
*
* @param immediately indicates should apply the UI changes immediately, otherwise wait
- * until the next refresh-round before UI becomes visible. True by default to take in place
- * immediately.
- *
+ * until the next refresh-round before UI becomes visible. True by default to take in
+ * place immediately.
* @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI
- * displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace
- * signal.
- *
+ * displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace
+ * signal.
* @param isSsReactivated indicates resume media card is reactivated by Smartspace
- * recommendation signal
+ * recommendation signal
*/
fun onMediaDataLoaded(
key: String,
@@ -1542,8 +1544,8 @@
* Called whenever there's new Smartspace media data loaded.
*
* @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true,
- * it will be prioritized as the first card. Otherwise, it will show up as the last card as
- * default.
+ * it will be prioritized as the first card. Otherwise, it will show up as the last card
+ * as default.
*/
fun onSmartspaceMediaDataLoaded(
key: String,
@@ -1558,8 +1560,8 @@
* Called whenever a previously existing Smartspace media data was removed.
*
* @param immediately indicates should apply the UI changes immediately, otherwise wait
- * until the next refresh-round before UI becomes visible. True by default to take in place
- * immediately.
+ * until the next refresh-round before UI becomes visible. True by default to take in
+ * place immediately.
*/
fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean = true) {}
}
@@ -1568,7 +1570,7 @@
* Converts the pass-in SmartspaceTarget to SmartspaceMediaData
*
* @return An empty SmartspaceMediaData with the valid target Id is returned if the
- * SmartspaceTarget's data is invalid.
+ * SmartspaceTarget's data is invalid.
*/
private fun toSmartspaceMediaData(target: SmartspaceTarget): SmartspaceMediaData {
var dismissIntent: Intent? = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
index 6a512be..120704c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
@@ -408,9 +408,9 @@
* [LocalMediaManager.DeviceCallback.onAboutToConnectDeviceAdded] for more information.
*
* @property fullMediaDevice a full-fledged [MediaDevice] object representing the device. If
- * non-null, prefer using [fullMediaDevice] over [backupMediaDeviceData].
+ * non-null, prefer using [fullMediaDevice] over [backupMediaDeviceData].
* @property backupMediaDeviceData a backup [MediaDeviceData] object containing the minimum
- * information required to display the device. Only use if [fullMediaDevice] is null.
+ * information required to display the device. Only use if [fullMediaDevice] is null.
*/
private data class AboutToConnectDevice(
val fullMediaDevice: MediaDevice? = null,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt
index 878962d..a1d9214 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt
@@ -60,6 +60,7 @@
/**
* Callback representing that a media object is now expired:
+ *
* @param key Media control unique identifier
* @param timedOut True when expired for {@code PAUSED_MEDIA_TIMEOUT} for active media,
* ```
@@ -70,6 +71,7 @@
/**
* Callback representing that a media object [PlaybackState] has changed.
+ *
* @param key Media control unique identifier
* @param state The new [PlaybackState]
*/
@@ -77,6 +79,7 @@
/**
* Callback representing that the [MediaSession] for an active control has been destroyed
+ *
* @param key Media control unique identifier
*/
lateinit var sessionCallback: (String) -> Unit
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
index 2af21c4..92e0c85 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
@@ -297,6 +297,7 @@
/**
* Add the component to the saved list of media browser services, checking for duplicates and
* removing older components that exceed the maximum limit
+ *
* @param componentName
*/
private fun updateResumptionList(componentName: ComponentName) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserLogger.kt
index 335ce1d..095cf09 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserLogger.kt
@@ -52,10 +52,12 @@
* event.
*
* @param isBrowserConnected true if there's a currently connected
+ *
* ```
* [android.media.browse.MediaBrowser] and false otherwise.
* @param componentName
* ```
+ *
* the component name for the [ResumeMediaBrowser] that triggered this log.
*/
fun logSessionDestroyed(isBrowserConnected: Boolean, componentName: ComponentName) =
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/AnimationBindHandler.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/AnimationBindHandler.kt
index d2793bc..f5cc043 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/AnimationBindHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/AnimationBindHandler.kt
@@ -24,10 +24,12 @@
* and conflicts due to media notifications arriving at any time during an animation. It does this
* in two parts.
* - Exit animations fired as a result of user input are tracked. When these are running, any
+ *
* ```
* bind actions are delayed until the animation completes (and then fired in sequence).
* ```
* - Continuous animations are tracked using their rebind id. Later calls using the same
+ *
* ```
* rebind id will be totally ignored to prevent the continuous animation from restarting.
* ```
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt
index 4827a16..2b42604 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/ColorSchemeTransition.kt
@@ -201,7 +201,9 @@
animatingColorTransitionFactory(
loadDefaultColor(R.attr.textColorSecondary),
::textSecondaryFromScheme
- ) { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) }
+ ) { textSecondary ->
+ mediaViewHolder.artistText.setTextColor(textSecondary)
+ }
val textTertiary =
animatingColorTransitionFactory(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt
index 9f86cd8..3669493 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt
@@ -159,6 +159,7 @@
/**
* Cross fade background.
+ *
* @see setTintList
* @see backgroundColor
*/
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 6cf051a..680a8b6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -853,10 +853,12 @@
* @param startLocation the start location of our state or -1 if this is directly set
* @param endLocation the ending location of our state.
* @param progress the progress of the transition between startLocation and endlocation. If
+ *
* ```
* this is not a guided transformation, this will be 1.0f
* @param immediately
* ```
+ *
* should this state be applied immediately, canceling all animations?
*/
fun setCurrentState(
@@ -1100,17 +1102,17 @@
*
* @param eventId UI event id (e.g. 800 for SMARTSPACE_CARD_SEEN)
* @param instanceId id to uniquely identify a card, e.g. each headphone generates a new
- * instanceId
+ * instanceId
* @param uid uid for the application that media comes from
* @param surfaces list of display surfaces the media card is on (e.g. lockscreen, shade) when
- * the event happened
+ * the event happened
* @param interactedSubcardRank the rank for interacted media item for recommendation card, -1
- * for tapping on card but not on any media item, 0 for first media item, 1 for second, etc.
+ * for tapping on card but not on any media item, 0 for first media item, 1 for second, etc.
* @param interactedSubcardCardinality how many media items were shown to the user when there is
- * user interaction
+ * user interaction
* @param rank the rank for media card in the media carousel, starting from 0
* @param receivedLatencyMillis latency in milliseconds for card received events. E.g. latency
- * between headphone connection to sysUI displays media recommendation card
+ * between headphone connection to sysUI displays media recommendation card
* @param isSwipeToDismiss whether is to log swipe-to-dismiss event
*/
fun logSmartspaceCardReported(
@@ -1371,6 +1373,7 @@
/**
* Removes media player given the key.
+ *
* @param isDismissed determines whether the media player is removed from the carousel.
*/
fun removeMediaPlayer(key: String, isDismissed: Boolean = false) =
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 4ab93da..4ddff53 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -31,12 +31,15 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@@ -62,7 +65,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
-import androidx.appcompat.content.res.AppCompatResources;
import androidx.constraintlayout.widget.ConstraintSet;
import com.android.internal.annotations.VisibleForTesting;
@@ -145,6 +147,12 @@
private static final int SMARTSPACE_CARD_CLICK_EVENT = 760;
protected static final int SMARTSPACE_CARD_DISMISS_EVENT = 761;
+ private static final float REC_MEDIA_COVER_SCALE_FACTOR = 1.25f;
+ private static final float MEDIA_SCRIM_START_ALPHA = 0.25f;
+ private static final float MEDIA_REC_SCRIM_START_ALPHA = 0.15f;
+ private static final float MEDIA_PLAYER_SCRIM_END_ALPHA = 0.9f;
+ private static final float MEDIA_REC_SCRIM_END_ALPHA = 1.0f;
+
private static final Intent SETTINGS_INTENT = new Intent(ACTION_MEDIA_CONTROLS_SETTINGS);
// Buttons to show in small player when using semantic actions
@@ -776,7 +784,7 @@
WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon);
if (wallpaperColors != null) {
mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
- artwork = addGradientToIcon(artworkIcon, mutableColorScheme, width, height);
+ artwork = addGradientToPlayerAlbum(artworkIcon, mutableColorScheme, width, height);
isArtworkBound = true;
} else {
// If there's no artwork, use colors from the app icon
@@ -866,8 +874,9 @@
Trace.beginAsyncSection(traceName, traceCookie);
// Capture width & height from views in foreground for artwork scaling in background
- int width = mRecommendationViewHolder.getMediaCoverContainers().get(0).getMeasuredWidth();
- int height = mRecommendationViewHolder.getMediaCoverContainers().get(0).getMeasuredHeight();
+ int width = mContext.getResources().getDimensionPixelSize(R.dimen.qs_media_rec_album_width);
+ int height = mContext.getResources().getDimensionPixelSize(
+ R.dimen.qs_media_rec_album_height_expanded);
mBackgroundExecutor.execute(() -> {
// Album art
@@ -877,7 +886,8 @@
WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon);
if (wallpaperColors != null) {
mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
- artwork = addGradientToIcon(artworkIcon, mutableColorScheme, width, height);
+ artwork = addGradientToRecommendationAlbum(artworkIcon, mutableColorScheme, width,
+ height);
} else {
artwork = new ColorDrawable(Color.TRANSPARENT);
}
@@ -886,6 +896,11 @@
// Bind the artwork drawable to media cover.
ImageView mediaCover =
mRecommendationViewHolder.getMediaCoverItems().get(itemIndex);
+ // Rescale media cover
+ Matrix coverMatrix = new Matrix(mediaCover.getImageMatrix());
+ coverMatrix.postScale(REC_MEDIA_COVER_SCALE_FACTOR, REC_MEDIA_COVER_SCALE_FACTOR,
+ 0.5f * width, 0.5f * height);
+ mediaCover.setImageMatrix(coverMatrix);
mediaCover.setImageDrawable(artwork);
// Set up the app icon.
@@ -907,40 +922,62 @@
// This method should be called from a background thread. WallpaperColors.fromBitmap takes a
// good amount of time. We do that work on the background executor to avoid stalling animations
// on the UI Thread.
- private WallpaperColors getWallpaperColor(Icon artworkIcon) {
+ @VisibleForTesting
+ protected WallpaperColors getWallpaperColor(Icon artworkIcon) {
if (artworkIcon != null) {
if (artworkIcon.getType() == Icon.TYPE_BITMAP
|| artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
// Avoids extra processing if this is already a valid bitmap
- return WallpaperColors
- .fromBitmap(artworkIcon.getBitmap());
+ Bitmap artworkBitmap = artworkIcon.getBitmap();
+ if (artworkBitmap.isRecycled()) {
+ Log.d(TAG, "Cannot load wallpaper color from a recycled bitmap");
+ return null;
+ }
+ return WallpaperColors.fromBitmap(artworkBitmap);
} else {
Drawable artworkDrawable = artworkIcon.loadDrawable(mContext);
if (artworkDrawable != null) {
- return WallpaperColors
- .fromDrawable(artworkIcon.loadDrawable(mContext));
+ return WallpaperColors.fromDrawable(artworkDrawable);
}
}
}
return null;
}
- private LayerDrawable addGradientToIcon(
- Icon artworkIcon,
- ColorScheme mutableColorScheme,
- int width,
- int height
- ) {
+ @VisibleForTesting
+ protected LayerDrawable addGradientToPlayerAlbum(Icon artworkIcon,
+ ColorScheme mutableColorScheme, int width, int height) {
Drawable albumArt = getScaledBackground(artworkIcon, width, height);
- GradientDrawable gradient = (GradientDrawable) AppCompatResources
- .getDrawable(mContext, R.drawable.qs_media_scrim);
+ GradientDrawable gradient = (GradientDrawable) mContext.getDrawable(
+ R.drawable.qs_media_scrim).mutate();
+ return setupGradientColorOnDrawable(albumArt, gradient, mutableColorScheme,
+ MEDIA_SCRIM_START_ALPHA, MEDIA_PLAYER_SCRIM_END_ALPHA);
+ }
+
+ @VisibleForTesting
+ protected LayerDrawable addGradientToRecommendationAlbum(Icon artworkIcon,
+ ColorScheme mutableColorScheme, int width, int height) {
+ // First try scaling rec card using bitmap drawable.
+ // If returns null, set drawable bounds.
+ Drawable albumArt = getScaledRecommendationCover(artworkIcon, width, height);
+ if (albumArt == null) {
+ albumArt = getScaledBackground(artworkIcon, width, height);
+ }
+ GradientDrawable gradient = (GradientDrawable) mContext.getDrawable(
+ R.drawable.qs_media_rec_scrim).mutate();
+ return setupGradientColorOnDrawable(albumArt, gradient, mutableColorScheme,
+ MEDIA_REC_SCRIM_START_ALPHA, MEDIA_REC_SCRIM_END_ALPHA);
+ }
+
+ private LayerDrawable setupGradientColorOnDrawable(Drawable albumArt, GradientDrawable gradient,
+ ColorScheme mutableColorScheme, float startAlpha, float endAlpha) {
gradient.setColors(new int[] {
ColorUtilKt.getColorWithAlpha(
MediaColorSchemesKt.backgroundStartFromScheme(mutableColorScheme),
- 0.25f),
+ startAlpha),
ColorUtilKt.getColorWithAlpha(
MediaColorSchemesKt.backgroundEndFromScheme(mutableColorScheme),
- 0.9f),
+ endAlpha),
});
return new LayerDrawable(new Drawable[] { albumArt, gradient });
}
@@ -1586,6 +1623,29 @@
}
/**
+ * Scale artwork to fill the background of media covers in recommendation card.
+ */
+ @UiThread
+ private Drawable getScaledRecommendationCover(Icon artworkIcon, int width, int height) {
+ if (width == 0 || height == 0) {
+ return null;
+ }
+ if (artworkIcon != null) {
+ Bitmap bitmap;
+ if (artworkIcon.getType() == Icon.TYPE_BITMAP
+ || artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
+ Bitmap artworkBitmap = artworkIcon.getBitmap();
+ if (artworkBitmap != null) {
+ bitmap = Bitmap.createScaledBitmap(artworkIcon.getBitmap(), width,
+ height, false);
+ return new BitmapDrawable(mContext.getResources(), bitmap);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
* Get the current media controller
*
* @return the controller
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index 45bc425..7fc7bdb 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -417,8 +417,8 @@
* Calculate the alpha of the view when given a cross-fade progress.
*
* @param crossFadeProgress The current cross fade progress. 0.5f means it's just switching
- * between the start and the end location and the content is fully faded, while 0.75f means that
- * we're halfway faded in again in the target state.
+ * between the start and the end location and the content is fully faded, while 0.75f means
+ * that we're halfway faded in again in the target state.
*/
private fun calculateAlphaFromCrossFade(crossFadeProgress: Float): Float {
if (crossFadeProgress <= 0.5f) {
@@ -628,6 +628,7 @@
*
* @param forceNoAnimation optional parameter telling the system not to animate
* @param forceStateUpdate optional parameter telling the system to update transition state
+ *
* ```
* even if location did not change
* ```
@@ -943,7 +944,7 @@
/**
* @return the current transformation progress if we're in a guided transformation and -1
- * otherwise
+ * otherwise
*/
private fun getTransformationProgress(): Float {
if (skipQqsOnExpansion) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt
index 455b7de..be570b4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt
@@ -126,6 +126,7 @@
* remeasurings later on.
*
* @param location the location this host name has. Used to identify the host during
+ *
* ```
* transitions.
* ```
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index b9b0459..0788e61 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -348,14 +348,17 @@
* bottom of UMO reach the bottom of this group It will change to alpha 1.0 when the visible
* bottom of UMO reach the top of the group below e.g.Album title, artist title and play-pause
* button will change alpha together.
+ *
* ```
* And their alpha becomes 1.0 when the visible bottom of UMO reach the top of controls,
* including progress bar, next button, previous button
* ```
+ *
* widgetGroupIds: a group of widgets have same state during UMO is squished,
* ```
* e.g. Album title, artist title and play-pause button
* ```
+ *
* groupEndPosition: the height of UMO, when the height reaches this value,
* ```
* widgets in this group should have 1.0 as alpha
@@ -363,6 +366,7 @@
* visible when the height of UMO reaches the top of controls group
* (progress bar, previous button and next button)
* ```
+ *
* squishedViewState: hold the widgetState of each widget, which will be modified
* squishFraction: the squishFraction of UMO
*/
@@ -665,7 +669,7 @@
*
* @param location Target
* @param locationWhenHidden Location that will be used when the target is not
- * [MediaHost.visible]
+ * [MediaHost.visible]
* @return State require for executing a transition, and also the respective [MediaHost].
*/
private fun obtainViewStateForLocation(@MediaLocation location: Int): TransitionViewState? {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
index e35575b..b5b1f0f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java
@@ -23,8 +23,6 @@
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.CommandQueue;
import javax.inject.Inject;
@@ -37,26 +35,19 @@
private final CommandQueue mCommandQueue;
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
- private final FeatureFlags mFeatureFlags;
@Inject
public MediaOutputSwitcherDialogUI(
Context context,
CommandQueue commandQueue,
- MediaOutputDialogFactory mediaOutputDialogFactory,
- FeatureFlags featureFlags) {
+ MediaOutputDialogFactory mediaOutputDialogFactory) {
mCommandQueue = commandQueue;
mMediaOutputDialogFactory = mediaOutputDialogFactory;
- mFeatureFlags = featureFlags;
}
@Override
public void start() {
- if (mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_SHOW_API_ENABLED)) {
- mCommandQueue.addCallback(this);
- } else {
- Log.w(TAG, "Show media output switcher is not enabled.");
- }
+ mCommandQueue.addCallback(this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
index 720c44a..ee93c37 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -43,7 +43,7 @@
*
* @param appPackageName the package name of the app playing the media.
* @param onPackageNotFoundException a function run if a
- * [PackageManager.NameNotFoundException] occurs.
+ * [PackageManager.NameNotFoundException] occurs.
* @param isReceiver indicates whether the icon is displayed in a receiver view.
*/
fun getIconInfoFromPackageName(
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
index 7a77c47..01398cf 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
@@ -70,6 +70,8 @@
RECENT_IGNORE_UNAVAILABLE,
userTracker.userId,
backgroundExecutor
- ) { tasks -> continuation.resume(tasks) }
+ ) { tasks ->
+ continuation.resume(tasks)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
index 6ab0da6..75a0c68 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
@@ -33,8 +33,8 @@
* launched, creating a new shortcut for [CreateNoteTaskShortcutActivity], and will finish.
*
* @see <a
- * href="https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#custom-pinned">Creating
- * a custom shortcut activity</a>
+ * href="https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#custom-pinned">Creating
+ * a custom shortcut activity</a>
*/
internal class CreateNoteTaskShortcutActivity @Inject constructor() : ComponentActivity() {
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
index 62c99da..fb09c55 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
@@ -26,8 +26,7 @@
@Module
interface QRCodeScannerModule {
- /**
- */
+ /** */
@Binds
@IntoMap
@StringKey(QRCodeScannerTile.TILE_SPEC)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
index e86bd7a..9f93e49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -76,7 +76,8 @@
this(tileServices, handler, userTracker, new TileLifecycleManager(handler,
tileServices.getContext(), tileServices,
new PackageManagerAdapter(tileServices.getContext()), broadcastDispatcher,
- new Intent().setComponent(component), userTracker.getUserHandle()));
+ new Intent(TileService.ACTION_QS_TILE).setComponent(component),
+ userTracker.getUserHandle()));
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt
index 03bb7a0..8387c1d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt
@@ -71,8 +71,8 @@
/**
* Show the device monitoring dialog, expanded from [expandable] if it's not null.
*
- * Important: [quickSettingsContext] *must* be the [Context] associated to the [Quick Settings
- * fragment][com.android.systemui.qs.QSFragment].
+ * Important: [quickSettingsContext] *must* be the [Context] associated to the
+ * [Quick Settings fragment][com.android.systemui.qs.QSFragment].
*/
fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index fbf32b3..f170ac1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -196,9 +196,9 @@
* Observe the device monitoring dialog requests and show the dialog accordingly. This function
* will suspend indefinitely and will need to be cancelled to stop observing.
*
- * Important: [quickSettingsContext] must be the [Context] associated to the [Quick Settings
- * fragment][com.android.systemui.qs.QSFragment], and the call to this function must be
- * cancelled when that fragment is destroyed.
+ * Important: [quickSettingsContext] must be the [Context] associated to the
+ * [Quick Settings fragment][com.android.systemui.qs.QSFragment], and the call to this function
+ * must be cancelled when that fragment is destroyed.
*/
suspend fun observeDeviceMonitoringDialogRequests(quickSettingsContext: Context) {
footerActionsInteractor.deviceMonitoringDialogRequests.collect {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 25ff308b..019ca52 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -631,7 +631,9 @@
final NavigationBarView navBarView =
mNavBarControllerLazy.get().getNavigationBarView(mContext.getDisplayId());
final NotificationPanelViewController panelController =
- mCentralSurfacesOptionalLazy.get().get().getNotificationPanelViewController();
+ mCentralSurfacesOptionalLazy.get()
+ .map(CentralSurfaces::getNotificationPanelViewController)
+ .orElse(null);
if (SysUiState.DEBUG) {
Log.d(TAG_OPS, "Updating sysui state flags: navBarFragment=" + navBarFragment
+ " navBarView=" + navBarView + " panelController=" + panelController);
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index dd21be9..30509e2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -124,8 +124,9 @@
/**
* Starts screen capture after some countdown
+ *
* @param captureTarget target to capture (could be e.g. a task) or null to record the whole
- * screen
+ * screen
*/
private fun requestScreenCapture(captureTarget: MediaProjectionCaptureTarget?) {
val userContext = userContextProvider.userContext
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt
index 310baaf..a8f99be 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt
@@ -70,7 +70,7 @@
/**
* @return an ACTION_EDIT intent for the given URI, directed to config_screenshotEditor if
- * available.
+ * available.
*/
fun createEditIntent(uri: Uri, context: Context): Intent {
val editIntent = Intent(Intent.ACTION_EDIT)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
index 1b728b8..236213c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
@@ -44,7 +44,7 @@
/**
* @return a populated WorkProfileFirstRunData object if a work profile first run message should
- * be shown
+ * be shown
*/
fun onScreenshotTaken(userHandle: UserHandle?): WorkProfileFirstRunData? {
if (userHandle == null) return null
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index e53eea9..3be2417 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -23,6 +23,7 @@
import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION;
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
@@ -71,6 +72,7 @@
import android.provider.Settings;
import android.transition.ChangeBounds;
import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
@@ -98,6 +100,7 @@
import androidx.constraintlayout.widget.ConstraintSet;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.policy.SystemBarUtils;
@@ -353,6 +356,7 @@
private final NotificationGutsManager mGutsManager;
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private final QuickSettingsController mQsController;
+ private final InteractionJankMonitor mInteractionJankMonitor;
private long mDownTime;
private boolean mTouchSlopExceededBeforeDown;
@@ -642,6 +646,19 @@
step.getTransitionState() == TransitionState.RUNNING;
};
+ private final TransitionListenerAdapter mKeyguardStatusAlignmentTransitionListener =
+ new TransitionListenerAdapter() {
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ mInteractionJankMonitor.end(CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
+ }
+ };
+
@Inject
public NotificationPanelViewController(NotificationPanelView view,
@Main Handler handler,
@@ -706,6 +723,7 @@
NotificationStackSizeCalculator notificationStackSizeCalculator,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
ShadeTransitionController shadeTransitionController,
+ InteractionJankMonitor interactionJankMonitor,
SystemClock systemClock,
KeyguardBottomAreaViewModel keyguardBottomAreaViewModel,
KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
@@ -720,6 +738,7 @@
DumpManager dumpManager,
KeyguardLongPressViewModel keyguardLongPressViewModel,
KeyguardInteractor keyguardInteractor) {
+ mInteractionJankMonitor = interactionJankMonitor;
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
public void onKeyguardFadingAwayChanged() {
@@ -1540,6 +1559,7 @@
int statusConstraint = shouldBeCentered ? PARENT_ID : R.id.qs_edge_guideline;
constraintSet.connect(R.id.keyguard_status_view, END, statusConstraint, END);
if (animate) {
+ mInteractionJankMonitor.begin(mView, CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION);
ChangeBounds transition = new ChangeBounds();
if (mSplitShadeEnabled) {
// Excluding media from the transition on split-shade, as it doesn't transition
@@ -1563,6 +1583,7 @@
// The clock container can sometimes be null. If it is, just fall back to the
// old animation rather than setting up the custom animations.
if (clockContainerView == null || clockContainerView.getChildCount() == 0) {
+ transition.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(
mNotificationContainerParent, transition);
} else {
@@ -1581,10 +1602,11 @@
adapter.setDuration(KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION);
adapter.addTarget(clockView);
set.addTransition(adapter);
-
+ set.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(mNotificationContainerParent, set);
}
} else {
+ transition.addListener(mKeyguardStatusAlignmentTransitionListener);
TransitionManager.beginDelayedTransition(
mNotificationContainerParent, transition);
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
index a1767cc..f4b1cc5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
@@ -107,7 +107,7 @@
*
* @param fraction the fraction from the expansion in [0, 1]
* @param expanded whether the panel is currently expanded; this is independent from the
- * fraction as the panel also might be expanded if the fraction is 0.
+ * fraction as the panel also might be expanded if the fraction is 0.
* @param tracking whether we're currently tracking the user's gesture.
*/
fun onPanelExpansionChanged(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
index 37773e9..b79f32a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -70,9 +70,9 @@
*
* [header] is a [MotionLayout] that has two transitions:
* * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait
- * handheld device configuration.
+ * handheld device configuration.
* * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] for all other
- * configurations
+ * configurations
*/
@CentralSurfacesScope
class ShadeHeaderController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
index 62c225b..df8c6ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt
@@ -148,7 +148,8 @@
qsDragFraction: $qsTransitionFraction
qsSquishFraction: $qsSquishTransitionFraction
isTransitioningToFullShade: $isTransitioningToFullShade
- """.trimIndent()
+ """
+ .trimIndent()
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index f0d064b..9a9503c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -572,8 +572,7 @@
entry.setGroupExpansionChanging(true)
userId = entry.sbn.userId
}
- var fullShadeNeedsBouncer = (!lockScreenUserManager.userAllowsPrivateNotificationsInPublic(
- lockScreenUserManager.getCurrentUserId()) ||
+ var fullShadeNeedsBouncer = (
!lockScreenUserManager.shouldShowLockscreenNotifications() ||
falsingCollector.shouldEnforceBouncer())
if (keyguardBypassController.bypassEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProvider.kt
index 42b874f..7297ae6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProvider.kt
@@ -74,7 +74,7 @@
/**
* @return a context with the MCC/MNC [Configuration] values corresponding to this
- * subscriptionId
+ * subscriptionId
*/
fun getMobileContextForSub(subId: Int, context: Context): Context {
if (demoModeController.isInDemoMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt
index 64b7ac9..5fa83ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt
@@ -39,6 +39,7 @@
* - Simple prioritization: Privacy > Battery > connectivity (encoded in [StatusEvent])
* - Only schedules a single event, and throws away lowest priority events
* ```
+ *
* There are 4 basic stages of animation at play here:
* ```
* 1. System chrome animation OUT
@@ -46,6 +47,7 @@
* 3. Chip animation OUT; potentially into a dot
* 4. System chrome animation IN
* ```
+ *
* Thus we can keep all animations synchronized with two separate ValueAnimators, one for system
* chrome and the other for the chip. These can animate from 0,1 and listeners can parameterize
* their respective views based on the progress of the animator. Interpolation differences TBD
@@ -168,7 +170,7 @@
* 3. Update the scheduler state so that clients know where we are
* 4. Maybe: provide scaffolding such as: dot location, margins, etc
* 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we
- * collect all of the animators and run them together.
+ * collect all of the animators and run them together.
*/
private fun runChipAnimation() {
statusBarWindowController.setForceStatusBarVisible(true)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
index a35617c..6deef2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
@@ -315,6 +315,7 @@
/**
* State object for a `Roundable` class.
+ *
* @param targetView Will handle the [AnimatableProperty]
* @param roundable Target of the radius animation
* @param maxRadius Max corner radius in pixels
@@ -436,7 +437,6 @@
* This is the most convenient way to define a new [SourceType].
*
* For example:
- *
* ```kotlin
* private val SECTION = SourceType.from("Section")
* ```
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 39e4000..4522e41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -443,6 +443,7 @@
CancellationSignal cancellationSignal = new CancellationSignal();
cancellationSignal.setOnCancelListener(
() -> runningInflations.values().forEach(CancellationSignal::cancel));
+
return cancellationSignal;
}
@@ -783,6 +784,7 @@
public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress>
implements InflationCallback, InflationTask {
+ private static final long IMG_PRELOAD_TIMEOUT_MS = 1000L;
private final NotificationEntry mEntry;
private final Context mContext;
private final boolean mInflateSynchronously;
@@ -876,7 +878,7 @@
recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight,
mUsesIncreasedHeadsUpHeight, packageContext);
InflatedSmartReplyState previousSmartReplyState = mRow.getExistingSmartReplyState();
- return inflateSmartReplyViews(
+ InflationProgress result = inflateSmartReplyViews(
inflationProgress,
mReInflateFlags,
mEntry,
@@ -884,6 +886,11 @@
packageContext,
previousSmartReplyState,
mSmartRepliesInflater);
+
+ // wait for image resolver to finish preloading
+ mRow.getImageResolver().waitForPreloadedImages(IMG_PRELOAD_TIMEOUT_MS);
+
+ return result;
} catch (Exception e) {
mError = e;
return null;
@@ -918,6 +925,9 @@
mCallback.handleInflationException(mRow.getEntry(),
new InflationException("Couldn't inflate contentViews" + e));
}
+
+ // Cancel any image loading tasks, not useful any more
+ mRow.getImageResolver().cancelRunningTasks();
}
@Override
@@ -944,6 +954,9 @@
// Notify the resolver that the inflation task has finished,
// try to purge unnecessary cached entries.
mRow.getImageResolver().purgeCache();
+
+ // Cancel any image loading tasks that have not completed at this point
+ mRow.getImageResolver().cancelRunningTasks();
}
private static class RtlEnabledContext extends ContextWrapper {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
index 41eeada0..fe0b312 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
@@ -22,8 +22,11 @@
import android.util.Log;
import java.util.Set;
+import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* A cache for inline images of image messages.
@@ -56,12 +59,13 @@
}
@Override
- public Drawable get(Uri uri) {
+ public Drawable get(Uri uri, long timeoutMs) {
Drawable result = null;
try {
- result = mCache.get(uri).get();
- } catch (InterruptedException | ExecutionException ex) {
- Log.d(TAG, "get: Failed get image from " + uri);
+ result = mCache.get(uri).get(timeoutMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException
+ | TimeoutException | CancellationException ex) {
+ Log.d(TAG, "get: Failed get image from " + uri + " " + ex);
}
return result;
}
@@ -72,6 +76,15 @@
mCache.entrySet().removeIf(entry -> !wantedSet.contains(entry.getKey()));
}
+ @Override
+ public void cancelRunningTasks() {
+ mCache.forEach((key, value) -> {
+ if (value.getStatus() != AsyncTask.Status.FINISHED) {
+ value.cancel(true);
+ }
+ });
+ }
+
private static class PreloadImageTask extends AsyncTask<Uri, Void, Drawable> {
private final NotificationInlineImageResolver mResolver;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
index b05e64ab..c620f44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
@@ -23,6 +23,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.util.Log;
import com.android.internal.R;
@@ -45,6 +46,9 @@
public class NotificationInlineImageResolver implements ImageResolver {
private static final String TAG = NotificationInlineImageResolver.class.getSimpleName();
+ // Timeout for loading images from ImageCache when calling from UI thread
+ private static final long MAX_UI_THREAD_TIMEOUT_MS = 100L;
+
private final Context mContext;
private final ImageCache mImageCache;
private Set<Uri> mWantedUriSet;
@@ -123,17 +127,25 @@
return null;
}
+ /**
+ * Loads an image from the Uri.
+ * This method is synchronous and is usually called from the Main thread.
+ * It will time-out after MAX_UI_THREAD_TIMEOUT_MS.
+ *
+ * @param uri Uri of the target image.
+ * @return drawable of the image, null if loading failed/timeout
+ */
@Override
public Drawable loadImage(Uri uri) {
- return hasCache() ? loadImageFromCache(uri) : resolveImage(uri);
+ return hasCache() ? loadImageFromCache(uri, MAX_UI_THREAD_TIMEOUT_MS) : resolveImage(uri);
}
- private Drawable loadImageFromCache(Uri uri) {
+ private Drawable loadImageFromCache(Uri uri, long timeoutMs) {
// if the uri isn't currently cached, try caching it first
if (!mImageCache.hasEntry(uri)) {
mImageCache.preload((uri));
}
- return mImageCache.get(uri);
+ return mImageCache.get(uri, timeoutMs);
}
/**
@@ -208,6 +220,30 @@
}
/**
+ * Wait for a maximum timeout for images to finish preloading
+ * @param timeoutMs total timeout time
+ */
+ void waitForPreloadedImages(long timeoutMs) {
+ if (!hasCache()) {
+ return;
+ }
+ Set<Uri> preloadedUris = getWantedUriSet();
+ if (preloadedUris != null) {
+ // Decrement remaining timeout after each image check
+ long endTimeMs = SystemClock.elapsedRealtime() + timeoutMs;
+ preloadedUris.forEach(
+ uri -> loadImageFromCache(uri, endTimeMs - SystemClock.elapsedRealtime()));
+ }
+ }
+
+ void cancelRunningTasks() {
+ if (!hasCache()) {
+ return;
+ }
+ mImageCache.cancelRunningTasks();
+ }
+
+ /**
* A interface for internal cache implementation of this resolver.
*/
interface ImageCache {
@@ -216,7 +252,7 @@
* @param uri The uri of the image.
* @return Drawable of the image.
*/
- Drawable get(Uri uri);
+ Drawable get(Uri uri, long timeoutMs);
/**
* Set the image resolver that actually resolves image from specified uri.
@@ -241,6 +277,11 @@
* Purge unnecessary entries in the cache.
*/
void purge();
+
+ /**
+ * Cancel all unfinished image loading tasks
+ */
+ void cancelRunningTasks();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
index 548d1a1..8b6d6a4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
@@ -25,9 +25,10 @@
/**
* This method looks for views that can be rounded (and implement [Roundable]) during a
* notification swipe.
+ *
* @return The [Roundable] targets above/below the [viewSwiped] (if available). The
- * [RoundableTargets.before] and [RoundableTargets.after] parameters can be `null` if there is
- * no above/below notification or the notification is not part of the same section.
+ * [RoundableTargets.before] and [RoundableTargets.after] parameters can be `null` if there is
+ * no above/below notification or the notification is not part of the same section.
*/
fun findRoundableTargets(
viewSwiped: ExpandableNotificationRow,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 993c4e2..573347c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -398,6 +398,9 @@
boolean isStrongBiometric) {
Trace.beginSection("BiometricUnlockController#onBiometricAuthenticated");
if (mUpdateMonitor.isGoingToSleep()) {
+ mLogger.deferringAuthenticationDueToSleep(userId,
+ biometricSourceType,
+ mPendingAuthenticated != null);
mPendingAuthenticated = new PendingAuthenticated(userId, biometricSourceType,
isStrongBiometric);
Trace.endSection();
@@ -813,6 +816,7 @@
public void onFinishedGoingToSleep() {
Trace.beginSection("BiometricUnlockController#onFinishedGoingToSleep");
if (mPendingAuthenticated != null) {
+ mLogger.finishedGoingToSleepWithPendingAuth();
PendingAuthenticated pendingAuthenticated = mPendingAuthenticated;
// Post this to make sure it's executed after the device is fully locked.
mHandler.post(() -> onBiometricAuthenticated(pendingAuthenticated.userId,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index b88531e..ae715b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -429,7 +429,6 @@
}
dispatchAlwaysOnEvent();
- mScreenOffAnimationController.onAlwaysOnChanged(getAlwaysOn());
}
@Override
@@ -469,6 +468,7 @@
for (Callback callback : mCallbacks) {
callback.onAlwaysOnChange();
}
+ mScreenOffAnimationController.onAlwaysOnChanged(getAlwaysOn());
}
private boolean getPostureSpecificBool(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 753032c..3268032 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -59,7 +59,7 @@
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.fragment.StatusBarIconBlocklistKt;
-import com.android.systemui.statusbar.phone.fragment.StatusBarSystemEventAnimator;
+import com.android.systemui.statusbar.phone.fragment.StatusBarSystemEventDefaultAnimator;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -75,6 +75,8 @@
import javax.inject.Inject;
+import kotlin.Unit;
+
/** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */
public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> {
private static final String TAG = "KeyguardStatusBarViewController";
@@ -123,7 +125,8 @@
public void onDensityOrFontScaleChanged() {
mView.loadDimens();
// The animator is dependent on resources for offsets
- mSystemEventAnimator = new StatusBarSystemEventAnimator(mView, getResources());
+ mSystemEventAnimator =
+ getSystemEventAnimator(mSystemEventAnimator.isAnimationRunning());
}
@Override
@@ -248,7 +251,8 @@
private int mStatusBarState;
private boolean mDozing;
private boolean mShowingKeyguardHeadsUp;
- private StatusBarSystemEventAnimator mSystemEventAnimator;
+ private StatusBarSystemEventDefaultAnimator mSystemEventAnimator;
+ private float mSystemEventAnimatorAlpha = 1;
/**
* The alpha value to be set on the View. If -1, this value is to be ignored.
@@ -324,7 +328,7 @@
mView.setKeyguardUserAvatarEnabled(
!mStatusBarUserChipViewModel.getChipEnabled());
- mSystemEventAnimator = new StatusBarSystemEventAnimator(mView, r);
+ mSystemEventAnimator = getSystemEventAnimator(/* isAnimationRunning */ false);
mDisableStateTracker = new DisableStateTracker(
/* mask1= */ DISABLE_SYSTEM_INFO,
@@ -480,6 +484,10 @@
* (1.0f - mKeyguardHeadsUpShowingAmount);
}
+ if (mSystemEventAnimator.isAnimationRunning()) {
+ newAlpha = Math.min(newAlpha, mSystemEventAnimatorAlpha);
+ }
+
boolean hideForBypass =
mFirstBypassAttempt && mKeyguardUpdateMonitor.shouldListenForFace()
|| mDelayShowingKeyguardStatusBar;
@@ -488,7 +496,7 @@
&& !mDozing
&& !hideForBypass
&& !mDisableStateTracker.isDisabled()
- ? View.VISIBLE : View.INVISIBLE;
+ ? View.VISIBLE : View.INVISIBLE;
updateViewState(newAlpha, newVisibility);
}
@@ -614,4 +622,15 @@
updateBlockedIcons();
}
};
+
+ private StatusBarSystemEventDefaultAnimator getSystemEventAnimator(boolean isAnimationRunning) {
+ return new StatusBarSystemEventDefaultAnimator(getResources(), (alpha) -> {
+ mSystemEventAnimatorAlpha = alpha;
+ updateViewState();
+ return Unit.INSTANCE;
+ }, (translationX) -> {
+ mView.setTranslationX(translationX);
+ return Unit.INSTANCE;
+ }, isAnimationRunning);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index c01137a..8fd9675 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -62,6 +62,7 @@
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -205,6 +206,7 @@
private final ScreenOffAnimationController mScreenOffAnimationController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final SysuiStatusBarStateController mStatusBarStateController;
private GradientColors mColors;
private boolean mNeedsDrawableColorUpdate;
@@ -261,25 +263,17 @@
private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private CoroutineDispatcher mMainDispatcher;
- private boolean mIsBouncerToGoneTransitionStarted = false;
private boolean mIsBouncerToGoneTransitionRunning = false;
private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
private final Consumer<Float> mScrimAlphaConsumer =
(Float alpha) -> {
- mScrimInFront.setViewAlpha(0f);
- mNotificationsScrim.setViewAlpha(0f);
+ mScrimInFront.setViewAlpha(mInFrontAlpha);
+ mNotificationsScrim.setViewAlpha(mNotificationsAlpha);
+ mBehindAlpha = alpha;
mScrimBehind.setViewAlpha(alpha);
};
- final Consumer<TransitionStep> mPrimaryBouncerToGoneTransition =
- (TransitionStep step) -> {
- mIsBouncerToGoneTransitionRunning =
- step.getTransitionState() == TransitionState.RUNNING;
- mIsBouncerToGoneTransitionStarted =
- step.getTransitionState() == TransitionState.STARTED;
- if (mIsBouncerToGoneTransitionStarted) {
- transitionTo(ScrimState.UNLOCKED);
- }
- };
+
+ Consumer<TransitionStep> mPrimaryBouncerToGoneTransition;
@Inject
public ScrimController(
@@ -298,6 +292,7 @@
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel,
KeyguardTransitionInteractor keyguardTransitionInteractor,
+ SysuiStatusBarStateController sysuiStatusBarStateController,
@Main CoroutineDispatcher mainDispatcher) {
mScrimStateListener = lightBarController::setScrimState;
mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
@@ -305,6 +300,7 @@
mKeyguardStateController = keyguardStateController;
mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mStatusBarStateController = sysuiStatusBarStateController;
mKeyguardVisibilityCallback = new KeyguardVisibilityCallback();
mHandler = handler;
mMainExecutor = mainExecutor;
@@ -380,9 +376,31 @@
state.prepare(state);
}
+ // Directly control transition to UNLOCKED scrim state from PRIMARY_BOUNCER, and make sure
+ // to report back that keyguard has faded away. This fixes cases where the scrim state was
+ // rapidly switching on unlock, due to shifts in state in CentralSurfacesImpl
+ mPrimaryBouncerToGoneTransition =
+ (TransitionStep step) -> {
+ TransitionState state = step.getTransitionState();
+
+ mIsBouncerToGoneTransitionRunning = state == TransitionState.RUNNING;
+
+ if (state == TransitionState.STARTED) {
+ setExpansionAffectsAlpha(false);
+ transitionTo(ScrimState.UNLOCKED);
+ }
+
+ if (state == TransitionState.FINISHED || state == TransitionState.CANCELED) {
+ setExpansionAffectsAlpha(true);
+ if (mKeyguardStateController.isKeyguardFadingAway()) {
+ mStatusBarKeyguardViewManager.onKeyguardFadedAway();
+ }
+ }
+ };
+
collectFlow(behindScrim, mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition(),
mPrimaryBouncerToGoneTransition, mMainDispatcher);
- collectFlow(behindScrim, mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha(),
+ collectFlow(behindScrim, mPrimaryBouncerToGoneTransitionViewModel.getScrimBehindAlpha(),
mScrimAlphaConsumer, mMainDispatcher);
}
@@ -830,11 +848,10 @@
mBehindAlpha = 0;
mNotificationsAlpha = 0;
} else {
+ // Behind scrim will finish fading in at 30% expansion.
float behindFraction = MathUtils
.constrainedMap(0f, 1f, 0f, 0.3f, mPanelExpansionFraction);
- if (!mIsBouncerToGoneTransitionStarted) {
- mBehindAlpha = behindFraction * mDefaultScrimAlpha;
- }
+ mBehindAlpha = behindFraction * mDefaultScrimAlpha;
// Delay fade-in of notification scrim a bit further, to coincide with the
// behind scrim finishing fading in.
// Also to coincide with the view starting to fade in, otherwise the empty
@@ -1083,7 +1100,8 @@
mBehindAlpha = 1;
}
// Prevent notification scrim flicker when transitioning away from keyguard.
- if (mKeyguardStateController.isKeyguardGoingAway()) {
+ if (mKeyguardStateController.isKeyguardGoingAway()
+ && !mStatusBarStateController.leaveOpenOnKeyguardHide()) {
mNotificationsAlpha = 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
index c04ea36..5903fa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
@@ -26,19 +26,39 @@
import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_OUT
import com.android.systemui.statusbar.events.SystemStatusAnimationCallback
import com.android.systemui.util.animation.AnimationUtil.Companion.frames
+import com.android.systemui.util.doOnCancel
+import com.android.systemui.util.doOnEnd
+
+/**
+ * An implementation of [StatusBarSystemEventDefaultAnimator], applying the onAlphaChanged and
+ * onTranslationXChanged callbacks directly to the provided animatedView.
+ */
+class StatusBarSystemEventAnimator @JvmOverloads constructor(
+ val animatedView: View,
+ resources: Resources,
+ isAnimationRunning: Boolean = false
+) : StatusBarSystemEventDefaultAnimator(
+ resources = resources,
+ onAlphaChanged = animatedView::setAlpha,
+ onTranslationXChanged = animatedView::setTranslationX,
+ isAnimationRunning = isAnimationRunning
+)
/**
* Tied directly to [SystemStatusAnimationScheduler]. Any StatusBar-like thing (keyguard, collapsed
- * status bar fragment), can just feed this an animatable view to get the default system status
- * animation.
+ * status bar fragment), can use this Animator to get the default system status animation. It simply
+ * needs to implement the onAlphaChanged and onTranslationXChanged callbacks.
*
* This animator relies on resources, and should be recreated whenever resources are updated. While
* this class could be used directly as the animation callback, it's probably best to forward calls
* to it so that it can be recreated at any moment without needing to remove/add callback.
*/
-class StatusBarSystemEventAnimator(
- val animatedView: View,
- resources: Resources
+
+open class StatusBarSystemEventDefaultAnimator @JvmOverloads constructor(
+ resources: Resources,
+ private val onAlphaChanged: (Float) -> Unit,
+ private val onTranslationXChanged: (Float) -> Unit,
+ var isAnimationRunning: Boolean = false
) : SystemStatusAnimationCallback {
private val translationXIn: Int = resources.getDimensionPixelSize(
R.dimen.ongoing_appops_chip_animation_in_status_bar_translation_x)
@@ -46,18 +66,19 @@
R.dimen.ongoing_appops_chip_animation_out_status_bar_translation_x)
override fun onSystemEventAnimationBegin(): Animator {
+ isAnimationRunning = true
val moveOut = ValueAnimator.ofFloat(0f, 1f).apply {
duration = 23.frames
interpolator = STATUS_BAR_X_MOVE_OUT
addUpdateListener {
- animatedView.translationX = -(translationXIn * animatedValue as Float)
+ onTranslationXChanged(-(translationXIn * animatedValue as Float))
}
}
val alphaOut = ValueAnimator.ofFloat(1f, 0f).apply {
duration = 8.frames
interpolator = null
addUpdateListener {
- animatedView.alpha = animatedValue as Float
+ onAlphaChanged(animatedValue as Float)
}
}
@@ -67,13 +88,13 @@
}
override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
- animatedView.translationX = translationXOut.toFloat()
+ onTranslationXChanged(translationXOut.toFloat())
val moveIn = ValueAnimator.ofFloat(1f, 0f).apply {
duration = 23.frames
startDelay = 7.frames
interpolator = STATUS_BAR_X_MOVE_IN
addUpdateListener {
- animatedView.translationX = translationXOut * animatedValue as Float
+ onTranslationXChanged(translationXOut * animatedValue as Float)
}
}
val alphaIn = ValueAnimator.ofFloat(0f, 1f).apply {
@@ -81,13 +102,14 @@
startDelay = 11.frames
interpolator = null
addUpdateListener {
- animatedView.alpha = animatedValue as Float
+ onAlphaChanged(animatedValue as Float)
}
}
val animatorSet = AnimatorSet()
animatorSet.playTogether(moveIn, alphaIn)
-
+ animatorSet.doOnEnd { isAnimationRunning = false }
+ animatorSet.doOnCancel { isAnimationRunning = false }
return animatorSet
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt
index 8c82fba..f4e3eab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt
@@ -45,7 +45,7 @@
* 1. Define a new `private val` wrapping the key using [BooleanCarrierConfig]
* 2. Define a public `val` exposing the wrapped flow using [BooleanCarrierConfig.config]
* 3. Add the new [BooleanCarrierConfig] to the list of tracked configs, so they are properly
- * updated when a new carrier config comes down
+ * updated when a new carrier config comes down
*/
class SystemUiCarrierConfig
internal constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index b3d5b1e..53a208c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -353,8 +353,8 @@
* True if the checked subId is in the list of current subs or the active mobile data subId
*
* @param checkedSubs the list to validate [subId] against. To invalidate the cache, pass in the
- * new subscription list. Otherwise use [subscriptions.value] to validate a subId against the
- * current known subscriptions
+ * new subscription list. Otherwise use [subscriptions.value] to validate a subId against the
+ * current known subscriptions
*/
private fun checkSub(subId: Int, checkedSubs: List<SubscriptionModel>): Boolean {
if (activeMobileDataSubscriptionId.value == subId) return true
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index 7b0f952..4caf2b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -92,7 +92,8 @@
* 1. The default network name, if one is configured
* 2. A derived name based off of the intent [ACTION_SERVICE_PROVIDERS_UPDATED]
* 3. Or, in the case where the repository sends us the default network name, we check for an
- * override in [connectionInfo.operatorAlphaShort], a value that is derived from [ServiceState]
+ * override in [connectionInfo.operatorAlphaShort], a value that is derived from
+ * [ServiceState]
*/
val networkName: StateFlow<NetworkNameModel>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
index 24cd930..8e103f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModel.kt
@@ -25,7 +25,7 @@
* allows the mobile icon to change some view parameters at different locations
*
* @param commonImpl for convenience, this class wraps a base interface that can provides all of the
- * common implementations between locations. See [MobileIconViewModel]
+ * common implementations between locations. See [MobileIconViewModel]
*/
abstract class LocationBasedMobileViewModel(
val commonImpl: MobileIconViewModelCommon,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
index e0e0ed7..b129617 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
@@ -41,7 +41,6 @@
* or the [WifiRepositoryImpl]'s prod implementation, based on the current demo mode value. In this
* way, downstream clients can all consist of real implementations and not care about which
* repository is responsible for the data. Graphically:
- *
* ```
* RealRepository
* │
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.kt
index bdb656b..1e223b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.kt
@@ -146,7 +146,7 @@
*
* @param guestUserId id of the guest user to remove
* @param targetUserId id of the user to switch to after guest is removed. If
- * `UserHandle.USER_NULL`, then switch immediately to the newly created guest user.
+ * `UserHandle.USER_NULL`, then switch immediately to the newly created guest user.
*/
fun removeGuestUser(guestUserId: Int, targetUserId: Int) {
userInteractor.removeGuestUser(
@@ -160,9 +160,9 @@
*
* @param guestUserId user id of the guest user to exit
* @param targetUserId user id of the guest user to exit, set to UserHandle#USER_NULL when
- * target user id is not known
+ * target user id is not known
* @param forceRemoveGuestOnExit true: remove guest before switching user, false: remove guest
- * only if its ephemeral, else keep guest
+ * only if its ephemeral, else keep guest
*/
fun exitGuestUser(guestUserId: Int, targetUserId: Int, forceRemoveGuestOnExit: Boolean) {
userInteractor.exitGuestUser(guestUserId, targetUserId, forceRemoveGuestOnExit)
diff --git a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
index e092f01..8e2b05c 100644
--- a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
@@ -66,7 +66,7 @@
private fun switchToManagedProfile() {
try {
applicationContext.startActivityAsUser(
- Intent(Intent.ACTION_DIAL, phoneNumber),
+ Intent(Intent.ACTION_CALL, phoneNumber),
ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle(),
UserHandle.of(managedProfileUserId)
)
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TouchableRegionViewController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TouchableRegionViewController.kt
index 60241a9..cf0184f 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TouchableRegionViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TouchableRegionViewController.kt
@@ -27,7 +27,7 @@
* pass through to the window below.
*
* @param touchableRegionSetter a function that, given the view and an out rect, fills the rect with
- * the touchable region of this view.
+ * the touchable region of this view.
*/
class TouchableRegionViewController(
view: View,
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarAnimator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarAnimator.kt
index 01a81de..1612388 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarAnimator.kt
@@ -35,7 +35,7 @@
* Animates [innerView] and its children into view.
*
* @return true if the animation was successfully started and false if the animation can't be
- * run for any reason.
+ * run for any reason.
*
* See [ViewHierarchyAnimator.animateAddition].
*/
@@ -55,7 +55,7 @@
* Animates [innerView] and its children out of view.
*
* @return true if the animation was successfully started and false if the animation can't be
- * run for any reason.
+ * run for any reason.
*
* See [ViewHierarchyAnimator.animateRemoval].
*/
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index fe46318..125cc76 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -28,10 +28,10 @@
* A container for all the state needed to display a chipbar via [ChipbarCoordinator].
*
* @property startIcon the icon to display at the start of the chipbar (on the left in LTR locales;
- * on the right in RTL locales).
+ * on the right in RTL locales).
* @property text the text to display.
* @property endItem an optional end item to display at the end of the chipbar (on the right in LTR
- * locales; on the left in RTL locales).
+ * locales; on the left in RTL locales).
* @property vibrationEffect an optional vibration effect when the chipbar is displayed
* @property allowSwipeToDismiss true if users are allowed to swipe up to dismiss this chipbar.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
index d5d3efd..3a7ac9c 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
@@ -31,6 +31,9 @@
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+
+import javax.inject.Inject;
/**
* If the attached USB accessory has a URL associated with it, and that URL is valid,
@@ -46,13 +49,27 @@
private UsbAccessory mAccessory;
private Uri mUri;
+ private final DeviceProvisionedController mDeviceProvisionedController;
+
+ @Inject
+ UsbAccessoryUriActivity(DeviceProvisionedController deviceProvisionedController) {
+ mDeviceProvisionedController = deviceProvisionedController;
+ }
+
@Override
public void onCreate(Bundle icicle) {
- getWindow().addSystemFlags(
+ getWindow().addSystemFlags(
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
- super.onCreate(icicle);
+ super.onCreate(icicle);
- Intent intent = getIntent();
+ // Don't show this dialog during Setup Wizard
+ if (!mDeviceProvisionedController.isDeviceProvisioned()) {
+ Log.e(TAG, "device not provisioned");
+ finish();
+ return;
+ }
+
+ Intent intent = getIntent();
mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
String uriString = intent.getStringExtra("uri");
mUri = (uriString == null ? null : Uri.parse(uriString));
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt
index 2080614..42cd5bc 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt
@@ -297,7 +297,7 @@
* to create a new one.
*
* @return The multi-user user ID of the newly created guest user, or [UserHandle.USER_NULL] if
- * the guest couldn't be created.
+ * the guest couldn't be created.
*/
@UserIdInt
private suspend fun createInBackground(): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
index 81ae6e8..c72853e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
@@ -115,6 +115,17 @@
}
/**
+ * Provide a Long running Executor.
+ */
+ @Provides
+ @SysUISingleton
+ @LongRunning
+ public static DelayableExecutor provideLongRunningDelayableExecutor(
+ @LongRunning Looper looper) {
+ return new ExecutorImpl(looper);
+ }
+
+ /**
* Provide a Background-Thread Executor.
*/
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
index 8b925b7..b962148 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
@@ -35,7 +35,7 @@
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.LongRunning;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -61,17 +61,16 @@
private final UserTracker mUserTracker;
// used for most tasks (call canvas.drawBitmap, load/unload the bitmap)
- @Background
- private final DelayableExecutor mBackgroundExecutor;
+ @LongRunning
+ private final DelayableExecutor mLongExecutor;
// wait at least this duration before unloading the bitmap
private static final int DELAY_UNLOAD_BITMAP = 2000;
@Inject
- public ImageWallpaper(@Background DelayableExecutor backgroundExecutor,
- UserTracker userTracker) {
+ public ImageWallpaper(@LongRunning DelayableExecutor longExecutor, UserTracker userTracker) {
super();
- mBackgroundExecutor = backgroundExecutor;
+ mLongExecutor = longExecutor;
mUserTracker = userTracker;
}
@@ -105,7 +104,7 @@
setFixedSizeAllowed(true);
setShowForAllUsers(true);
mWallpaperLocalColorExtractor = new WallpaperLocalColorExtractor(
- mBackgroundExecutor,
+ mLongExecutor,
new WallpaperLocalColorExtractor.WallpaperLocalColorExtractorCallback() {
@Override
public void onColorsProcessed(List<RectF> regions,
@@ -202,7 +201,7 @@
}
private void drawFrame() {
- mBackgroundExecutor.execute(this::drawFrameSynchronized);
+ mLongExecutor.execute(this::drawFrameSynchronized);
}
private void drawFrameSynchronized() {
@@ -257,7 +256,7 @@
}
private void unloadBitmapIfNotUsed() {
- mBackgroundExecutor.execute(this::unloadBitmapIfNotUsedSynchronized);
+ mLongExecutor.execute(this::unloadBitmapIfNotUsedSynchronized);
}
private void unloadBitmapIfNotUsedSynchronized() {
@@ -341,7 +340,7 @@
* - the mini bitmap from color extractor is recomputed
* - the DELAY_UNLOAD_BITMAP has passed
*/
- mBackgroundExecutor.executeDelayed(
+ mLongExecutor.executeDelayed(
this::unloadBitmapIfNotUsedSynchronized, DELAY_UNLOAD_BITMAP);
}
// even if the bitmap cannot be loaded, call reportEngineShown
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
index 988fd71..1e8446f 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
@@ -29,7 +29,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.LongRunning;
import com.android.systemui.util.Assert;
import java.io.FileDescriptor;
@@ -66,8 +66,8 @@
private final List<RectF> mPendingRegions = new ArrayList<>();
private final Set<RectF> mProcessedRegions = new ArraySet<>();
- @Background
- private final Executor mBackgroundExecutor;
+ @LongRunning
+ private final Executor mLongExecutor;
private final WallpaperLocalColorExtractorCallback mWallpaperLocalColorExtractorCallback;
@@ -101,13 +101,13 @@
/**
* Creates a new color extractor.
- * @param backgroundExecutor the executor on which the color extraction will be performed
+ * @param longExecutor the executor on which the color extraction will be performed
* @param wallpaperLocalColorExtractorCallback an interface to handle the callbacks from
* the color extractor.
*/
- public WallpaperLocalColorExtractor(@Background Executor backgroundExecutor,
+ public WallpaperLocalColorExtractor(@LongRunning Executor longExecutor,
WallpaperLocalColorExtractorCallback wallpaperLocalColorExtractorCallback) {
- mBackgroundExecutor = backgroundExecutor;
+ mLongExecutor = longExecutor;
mWallpaperLocalColorExtractorCallback = wallpaperLocalColorExtractorCallback;
}
@@ -117,7 +117,7 @@
* not recomputed.
*/
public void setDisplayDimensions(int displayWidth, int displayHeight) {
- mBackgroundExecutor.execute(() ->
+ mLongExecutor.execute(() ->
setDisplayDimensionsSynchronized(displayWidth, displayHeight));
}
@@ -144,7 +144,7 @@
* @param bitmap the new wallpaper
*/
public void onBitmapChanged(@NonNull Bitmap bitmap) {
- mBackgroundExecutor.execute(() -> onBitmapChangedSynchronized(bitmap));
+ mLongExecutor.execute(() -> onBitmapChangedSynchronized(bitmap));
}
private void onBitmapChangedSynchronized(@NonNull Bitmap bitmap) {
@@ -167,7 +167,7 @@
* @param pages the total number of pages of the launcher
*/
public void onPageChanged(int pages) {
- mBackgroundExecutor.execute(() -> onPageChangedSynchronized(pages));
+ mLongExecutor.execute(() -> onPageChangedSynchronized(pages));
}
private void onPageChangedSynchronized(int pages) {
@@ -194,7 +194,7 @@
*/
public void addLocalColorsAreas(@NonNull List<RectF> regions) {
if (regions.size() > 0) {
- mBackgroundExecutor.execute(() -> addLocalColorsAreasSynchronized(regions));
+ mLongExecutor.execute(() -> addLocalColorsAreasSynchronized(regions));
} else {
Log.w(TAG, "Attempt to add colors with an empty list");
}
@@ -218,7 +218,7 @@
* @param regions The areas of interest in our wallpaper (in screen pixel coordinates)
*/
public void removeLocalColorAreas(@NonNull List<RectF> regions) {
- mBackgroundExecutor.execute(() -> removeLocalColorAreasSynchronized(regions));
+ mLongExecutor.execute(() -> removeLocalColorAreasSynchronized(regions));
}
private void removeLocalColorAreasSynchronized(@NonNull List<RectF> regions) {
@@ -236,7 +236,7 @@
* Clean up the memory (in particular, the mini bitmap) used by this class.
*/
public void cleanUp() {
- mBackgroundExecutor.execute(this::cleanUpSynchronized);
+ mLongExecutor.execute(this::cleanUpSynchronized);
}
private void cleanUpSynchronized() {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index 5d896cb..56df3e1 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -25,7 +25,6 @@
import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
-import static com.android.systemui.flags.Flags.WM_BUBBLE_BAR;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
@@ -358,7 +357,6 @@
});
}
};
- mBubbles.setBubbleBarEnabled(featureFlags.isEnabled(WM_BUBBLE_BAR));
mBubbles.setSysuiProxy(mSysuiProxy);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 1bbc199..531006d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -37,6 +37,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -160,6 +161,29 @@
}
@Test
+ public void testOnApplyWindowInsets_disappearAnimation_paddingNotSet() {
+ int paddingBottom = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin);
+ int imeInsetAmount = paddingBottom + 1;
+ int systemBarInsetAmount = 0;
+ initMode(MODE_DEFAULT);
+
+ Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
+ Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
+
+ WindowInsets insets = new WindowInsets.Builder()
+ .setInsets(ime(), imeInset)
+ .setInsetsIgnoringVisibility(systemBars(), systemBarInset)
+ .build();
+
+ ensureViewFlipperIsMocked();
+ mKeyguardSecurityContainer.startDisappearAnimation(
+ KeyguardSecurityModel.SecurityMode.Password);
+ mKeyguardSecurityContainer.onApplyWindowInsets(insets);
+ assertThat(mKeyguardSecurityContainer.getPaddingBottom()).isNotEqualTo(imeInsetAmount);
+ }
+
+ @Test
public void testDefaultViewMode() {
initMode(MODE_ONE_HANDED);
initMode(MODE_DEFAULT);
@@ -376,6 +400,17 @@
assertThat(mKeyguardSecurityContainer.getScaleY()).isEqualTo(1);
}
+ @Test
+ public void testDisappearAnimationPassword() {
+ ensureViewFlipperIsMocked();
+ KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class);
+ when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView);
+
+ mKeyguardSecurityContainer
+ .startDisappearAnimation(KeyguardSecurityModel.SecurityMode.Password);
+ verify(keyguardPasswordView).setDisappearAnimationListener(any());
+ }
+
private BackEvent createBackEvent(float touchX, float progress) {
return new BackEvent(0, 0, progress, BackEvent.EDGE_LEFT);
}
@@ -446,4 +481,12 @@
mUserSwitcherController, () -> {
}, mFalsingA11yDelegate);
}
+
+ private void ensureViewFlipperIsMocked() {
+ mSecurityViewFlipper = mock(KeyguardSecurityViewFlipper.class);
+ KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class);
+ when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView);
+ mKeyguardSecurityContainer.mSecurityViewFlipper = mSecurityViewFlipper;
+ }
+
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index b765ab3..a245c01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -25,7 +25,9 @@
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.logcatLogBuffer
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -109,6 +111,7 @@
udfpsControllerProvider,
statusBarStateController,
featureFlags,
+ KeyguardLogger(logcatLogBuffer(AuthRippleController.TAG)),
rippleView
)
controller.init()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 6333a68..3ec49b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -354,7 +354,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_0 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_90() =
@@ -362,7 +364,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_90 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_180() =
@@ -370,7 +374,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_180 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_180() =
@@ -379,7 +385,9 @@
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_180 },
windowInsets = insetsForSmallNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_180() =
@@ -388,7 +396,9 @@
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_180 },
windowInsets = insetsForLargeNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_270() =
@@ -396,7 +406,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_0() =
@@ -404,7 +416,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_0 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_90() =
@@ -412,7 +426,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_90 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForXAlignedSensor_InReverseDefaultRotation_90() =
@@ -421,7 +437,9 @@
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_90 },
windowInsets = insetsForSmallNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForXAlignedSensor_InReverseDefaultRotation_90() =
@@ -430,7 +448,9 @@
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_90 },
windowInsets = insetsForLargeNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_180() =
@@ -438,7 +458,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForXAlignedSensor_InReverseDefaultRotation_270() =
@@ -446,7 +468,9 @@
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_270 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_0() =
@@ -454,7 +478,9 @@
deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_0 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_90() =
@@ -462,7 +488,9 @@
deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_90 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_180() =
@@ -480,7 +508,9 @@
deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_270() =
@@ -489,7 +519,9 @@
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 },
windowInsets = insetsForSmallNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_270() =
@@ -498,7 +530,9 @@
isReverseDefaultRotation = false,
{ rotation = Surface.ROTATION_270 },
windowInsets = insetsForLargeNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_0() =
@@ -506,7 +540,9 @@
deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_0 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_90() =
@@ -524,7 +560,9 @@
deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarCollapsedDownForYAlignedSensor_InReverseDefaultRotation_180() =
@@ -533,7 +571,9 @@
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 },
windowInsets = insetsForSmallNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun hidesSfpsIndicatorWhenOccludingTaskbarForYAlignedSensor_InReverseDefaultRotation_180() =
@@ -542,7 +582,9 @@
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_180 },
windowInsets = insetsForLargeNavbar()
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = false)
+ }
@Test
fun showsSfpsIndicatorWithTaskbarForYAlignedSensor_InReverseDefaultRotation_270() =
@@ -550,7 +592,9 @@
deviceConfig = DeviceConfig.Y_ALIGNED,
isReverseDefaultRotation = true,
{ rotation = Surface.ROTATION_270 }
- ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
+ ) {
+ verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
+ }
@Test
fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_0() =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
index faa5db4..ab6d5b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
@@ -94,7 +94,9 @@
mClassifier.onTouchEvent(appendMoveEvent(1, 16, 3));
mClassifier.onTouchEvent(appendMoveEvent(1, 17, 300));
mClassifier.onTouchEvent(appendMoveEvent(1, 18, 301));
- mClassifier.onTouchEvent(appendUpEvent(1, 19, 501));
+ mClassifier.onTouchEvent(appendMoveEvent(1, 19, 501));
+ mClassifier.onTouchEvent(appendUpEvent(1, 19, 501)); //event will be dropped
+
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index 2edc3d3..8eadadf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -75,16 +75,17 @@
}
@Test
- public void test_trackMotionEvents() {
+ public void test_trackMotionEvents_dropUpEvent() {
mDataProvider.onMotionEvent(appendDownEvent(2, 9));
mDataProvider.onMotionEvent(appendMoveEvent(4, 7));
- mDataProvider.onMotionEvent(appendUpEvent(6, 5));
+ mDataProvider.onMotionEvent(appendMoveEvent(6, 5));
+ mDataProvider.onMotionEvent(appendUpEvent(0, 0)); // event will be dropped
List<MotionEvent> motionEventList = mDataProvider.getRecentMotionEvents();
assertThat(motionEventList.size()).isEqualTo(3);
assertThat(motionEventList.get(0).getActionMasked()).isEqualTo(MotionEvent.ACTION_DOWN);
assertThat(motionEventList.get(1).getActionMasked()).isEqualTo(MotionEvent.ACTION_MOVE);
- assertThat(motionEventList.get(2).getActionMasked()).isEqualTo(MotionEvent.ACTION_UP);
+ assertThat(motionEventList.get(2).getActionMasked()).isEqualTo(MotionEvent.ACTION_MOVE);
assertThat(motionEventList.get(0).getEventTime()).isEqualTo(1L);
assertThat(motionEventList.get(1).getEventTime()).isEqualTo(2L);
assertThat(motionEventList.get(2).getEventTime()).isEqualTo(3L);
@@ -97,6 +98,28 @@
}
@Test
+ public void test_trackMotionEvents_keepUpEvent() {
+ mDataProvider.onMotionEvent(appendDownEvent(2, 9));
+ mDataProvider.onMotionEvent(appendMoveEvent(4, 7));
+ mDataProvider.onMotionEvent(appendUpEvent(0, 0, 100));
+ List<MotionEvent> motionEventList = mDataProvider.getRecentMotionEvents();
+
+ assertThat(motionEventList.size()).isEqualTo(3);
+ assertThat(motionEventList.get(0).getActionMasked()).isEqualTo(MotionEvent.ACTION_DOWN);
+ assertThat(motionEventList.get(1).getActionMasked()).isEqualTo(MotionEvent.ACTION_MOVE);
+ assertThat(motionEventList.get(2).getActionMasked()).isEqualTo(MotionEvent.ACTION_UP);
+ assertThat(motionEventList.get(0).getEventTime()).isEqualTo(1L);
+ assertThat(motionEventList.get(1).getEventTime()).isEqualTo(2L);
+ assertThat(motionEventList.get(2).getEventTime()).isEqualTo(100);
+ assertThat(motionEventList.get(0).getX()).isEqualTo(2f);
+ assertThat(motionEventList.get(1).getX()).isEqualTo(4f);
+ assertThat(motionEventList.get(2).getX()).isEqualTo(0f);
+ assertThat(motionEventList.get(0).getY()).isEqualTo(9f);
+ assertThat(motionEventList.get(1).getY()).isEqualTo(7f);
+ assertThat(motionEventList.get(2).getY()).isEqualTo(0f);
+ }
+
+ @Test
public void test_trackRecentMotionEvents() {
mDataProvider.onMotionEvent(appendDownEvent(2, 9, 1));
mDataProvider.onMotionEvent(appendMoveEvent(4, 7, 800));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
index c343c20..ae2b8bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
@@ -68,6 +68,15 @@
}
@Test
+ public void testPass_dropClosingUpEvent() {
+ appendMoveEvent(0, 0);
+ appendMoveEvent(0, 100);
+ appendMoveEvent(0, 200);
+ appendUpEvent(0, 180); // this event would push us over the maxDevianceY
+ assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
+ }
+
+ @Test
public void testPass_fewTouchesHorizontal() {
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
appendMoveEvent(0, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
index 2099281..c2fb904 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
@@ -446,7 +446,7 @@
mFeatureFlags.set(CLIPBOARD_REMOTE_BEHAVIOR, true);
when(mClipboardUtils.isRemoteCopy(any(Context.class), any(ClipData.class), anyString()))
.thenReturn(true);
- when(mClipboardUtils.getAction(any(CharSequence.class), any(TextLinks.class), anyString()))
+ when(mClipboardUtils.getAction(any(TextLinks.class), anyString()))
.thenReturn(Optional.of(Mockito.mock(RemoteAction.class)));
when(mClipboardOverlayView.post(any(Runnable.class))).thenAnswer(new Answer<Object>() {
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
index aea6be3..3d8f04e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.when;
@@ -77,6 +78,74 @@
@Test
public void test_getAction_noLinks_returnsEmptyOptional() {
+ Optional<RemoteAction> action =
+ mClipboardUtils.getAction(Mockito.mock(TextLinks.class), "abc");
+
+ assertTrue(action.isEmpty());
+ }
+
+ @Test
+ public void test_getAction_returnsFirstLink() {
+ TextLinks links = getFakeTextLinksBuilder().build();
+ RemoteAction actionA = constructRemoteAction("abc");
+ RemoteAction actionB = constructRemoteAction("def");
+ TextClassification classificationA = Mockito.mock(TextClassification.class);
+ when(classificationA.getActions()).thenReturn(Lists.newArrayList(actionA));
+ TextClassification classificationB = Mockito.mock(TextClassification.class);
+ when(classificationB.getActions()).thenReturn(Lists.newArrayList(actionB));
+ when(mTextClassifier.classifyText(anyString(), anyInt(), anyInt(), isNull())).thenReturn(
+ classificationA, classificationB);
+
+ RemoteAction result = mClipboardUtils.getAction(links, "test").orElse(null);
+
+ assertEquals(actionA, result);
+ }
+
+ @Test
+ public void test_getAction_skipsMatchingComponent() {
+ TextLinks links = getFakeTextLinksBuilder().build();
+ RemoteAction actionA = constructRemoteAction("abc");
+ RemoteAction actionB = constructRemoteAction("def");
+ TextClassification classificationA = Mockito.mock(TextClassification.class);
+ when(classificationA.getActions()).thenReturn(Lists.newArrayList(actionA));
+ TextClassification classificationB = Mockito.mock(TextClassification.class);
+ when(classificationB.getActions()).thenReturn(Lists.newArrayList(actionB));
+ when(mTextClassifier.classifyText(anyString(), anyInt(), anyInt(), isNull())).thenReturn(
+ classificationA, classificationB);
+
+ RemoteAction result = mClipboardUtils.getAction(links, "abc").orElse(null);
+
+ assertEquals(actionB, result);
+ }
+
+ @Test
+ public void test_getAction_skipsShortEntity() {
+ TextLinks.Builder textLinks = new TextLinks.Builder("test text of length 22");
+ final Map<String, Float> scores = new ArrayMap<>();
+ scores.put(TextClassifier.TYPE_EMAIL, 1f);
+ textLinks.addLink(20, 22, scores);
+ textLinks.addLink(0, 22, scores);
+
+ RemoteAction actionA = constructRemoteAction("abc");
+ RemoteAction actionB = constructRemoteAction("def");
+ TextClassification classificationA = Mockito.mock(TextClassification.class);
+ when(classificationA.getActions()).thenReturn(Lists.newArrayList(actionA));
+ TextClassification classificationB = Mockito.mock(TextClassification.class);
+ when(classificationB.getActions()).thenReturn(Lists.newArrayList(actionB));
+ when(mTextClassifier.classifyText(anyString(), eq(20), eq(22), isNull())).thenReturn(
+ classificationA);
+ when(mTextClassifier.classifyText(anyString(), eq(0), eq(22), isNull())).thenReturn(
+ classificationB);
+
+ RemoteAction result = mClipboardUtils.getAction(textLinks.build(), "test").orElse(null);
+
+ assertEquals(actionB, result);
+ }
+
+ // TODO(b/267162944): Next four tests (marked "legacy") are obsolete once
+ // CLIPBOARD_MINIMIZED_LAYOUT flag is released and removed
+ @Test
+ public void test_getAction_noLinks_returnsEmptyOptional_legacy() {
ClipData.Item item = new ClipData.Item("no text links");
item.setTextLinks(Mockito.mock(TextLinks.class));
@@ -86,8 +155,8 @@
}
@Test
- public void test_getAction_returnsFirstLink() {
- when(mClipDataItem.getTextLinks()).thenReturn(getFakeTextLinks());
+ public void test_getAction_returnsFirstLink_legacy() {
+ when(mClipDataItem.getTextLinks()).thenReturn(getFakeTextLinksBuilder().build());
when(mClipDataItem.getText()).thenReturn("");
RemoteAction actionA = constructRemoteAction("abc");
RemoteAction actionB = constructRemoteAction("def");
@@ -98,14 +167,14 @@
when(mTextClassifier.classifyText(anyString(), anyInt(), anyInt(), isNull())).thenReturn(
classificationA, classificationB);
- RemoteAction result = mClipboardUtils.getAction(mClipDataItem, "def").orElse(null);
+ RemoteAction result = mClipboardUtils.getAction(mClipDataItem, "test").orElse(null);
assertEquals(actionA, result);
}
@Test
- public void test_getAction_skipsMatchingComponent() {
- when(mClipDataItem.getTextLinks()).thenReturn(getFakeTextLinks());
+ public void test_getAction_skipsMatchingComponent_legacy() {
+ when(mClipDataItem.getTextLinks()).thenReturn(getFakeTextLinksBuilder().build());
when(mClipDataItem.getText()).thenReturn("");
RemoteAction actionA = constructRemoteAction("abc");
RemoteAction actionB = constructRemoteAction("def");
@@ -122,6 +191,33 @@
}
@Test
+ public void test_getAction_skipsShortEntity_legacy() {
+ TextLinks.Builder textLinks = new TextLinks.Builder("test text of length 22");
+ final Map<String, Float> scores = new ArrayMap<>();
+ scores.put(TextClassifier.TYPE_EMAIL, 1f);
+ textLinks.addLink(20, 22, scores);
+ textLinks.addLink(0, 22, scores);
+
+ when(mClipDataItem.getTextLinks()).thenReturn(textLinks.build());
+ when(mClipDataItem.getText()).thenReturn(textLinks.build().getText());
+
+ RemoteAction actionA = constructRemoteAction("abc");
+ RemoteAction actionB = constructRemoteAction("def");
+ TextClassification classificationA = Mockito.mock(TextClassification.class);
+ when(classificationA.getActions()).thenReturn(Lists.newArrayList(actionA));
+ TextClassification classificationB = Mockito.mock(TextClassification.class);
+ when(classificationB.getActions()).thenReturn(Lists.newArrayList(actionB));
+ when(mTextClassifier.classifyText(anyString(), eq(20), eq(22), isNull())).thenReturn(
+ classificationA);
+ when(mTextClassifier.classifyText(anyString(), eq(0), eq(22), isNull())).thenReturn(
+ classificationB);
+
+ RemoteAction result = mClipboardUtils.getAction(mClipDataItem, "test").orElse(null);
+
+ assertEquals(actionB, result);
+ }
+
+ @Test
public void test_extra_withPackage_returnsTrue() {
PersistableBundle b = new PersistableBundle();
b.putBoolean(ClipDescription.EXTRA_IS_REMOTE_DEVICE, true);
@@ -184,12 +280,12 @@
return action;
}
- private static TextLinks getFakeTextLinks() {
- TextLinks.Builder textLinks = new TextLinks.Builder("test");
+ private static TextLinks.Builder getFakeTextLinksBuilder() {
+ TextLinks.Builder textLinks = new TextLinks.Builder("test text of length 22");
final Map<String, Float> scores = new ArrayMap<>();
scores.put(TextClassifier.TYPE_EMAIL, 1f);
- textLinks.addLink(0, 0, scores);
- textLinks.addLink(0, 0, scores);
- return textLinks.build();
+ textLinks.addLink(0, 22, scores);
+ textLinks.addLink(0, 22, scores);
+ return textLinks;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt
index 0c9986d..5a613aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt
@@ -104,7 +104,9 @@
controlsSettingsRepository,
userTracker,
activityStarter
- ) { context, _ -> TestableAlertDialog(context).also { dialog = it } }
+ ) { context, _ ->
+ TestableAlertDialog(context).also { dialog = it }
+ }
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt
index dbaf94f..483ab3b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt
@@ -37,7 +37,9 @@
context,
layoutId = 0,
labels.zip(ids).map { OverflowMenuAdapter.MenuItem(it.first, it.second) }
- ) { true }
+ ) {
+ true
+ }
ids.forEachIndexed { index, id -> assertThat(adapter.getItemId(index)).isEqualTo(id) }
}
@@ -51,7 +53,9 @@
context,
layoutId = 0,
labels.zip(ids).map { OverflowMenuAdapter.MenuItem(it.first, it.second) }
- ) { position -> position == 0 }
+ ) { position ->
+ position == 0
+ }
assertThat(adapter.isEnabled(0)).isTrue()
assertThat(adapter.isEnabled(1)).isFalse()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index 3a168d4..d6dbd73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -450,6 +450,15 @@
swipeToPosition(0f, Direction.DOWN, 0);
}
+ @Test
+ public void testTouchSessionOnRemovedCalledTwice() {
+ mTouchHandler.onSessionStart(mTouchSession);
+ ArgumentCaptor<DreamTouchHandler.TouchSession.Callback> onRemovedCallbackCaptor =
+ ArgumentCaptor.forClass(DreamTouchHandler.TouchSession.Callback.class);
+ verify(mTouchSession).registerCallback(onRemovedCallbackCaptor.capture());
+ onRemovedCallbackCaptor.getValue().onRemoved();
+ onRemovedCallbackCaptor.getValue().onRemoved();
+ }
private void swipeToPosition(float percent, Direction direction, float velocityY) {
Mockito.clearInvocations(mTouchSession);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractorTest.kt
new file mode 100644
index 0000000..ec94cde
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractorTest.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.keyboard.backlight.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
+import com.android.systemui.keyboard.shared.model.BacklightModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyboardBacklightInteractorTest : SysuiTestCase() {
+
+ private val keyboardRepository = FakeKeyboardRepository()
+ private lateinit var underTest: KeyboardBacklightInteractor
+
+ @Before
+ fun setUp() {
+ underTest = KeyboardBacklightInteractor(keyboardRepository)
+ }
+
+ @Test
+ fun emitsNull_whenKeyboardJustConnected() = runTest {
+ val latest by collectLastValue(underTest.backlight)
+ keyboardRepository.setKeyboardConnected(true)
+
+ assertThat(latest).isNull()
+ }
+
+ @Test
+ fun emitsBacklight_whenKeyboardConnectedAndBacklightChanged() = runTest {
+ keyboardRepository.setKeyboardConnected(true)
+ keyboardRepository.setBacklight(BacklightModel(1, 5))
+
+ assertThat(underTest.backlight.first()).isEqualTo(BacklightModel(1, 5))
+ }
+
+ @Test
+ fun emitsNull_afterKeyboardDisconnecting() = runTest {
+ val latest by collectLastValue(underTest.backlight)
+ keyboardRepository.setKeyboardConnected(true)
+ keyboardRepository.setBacklight(BacklightModel(1, 5))
+
+ keyboardRepository.setKeyboardConnected(false)
+
+ assertThat(latest).isNull()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModelTest.kt
new file mode 100644
index 0000000..ec05d10
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModelTest.kt
@@ -0,0 +1,102 @@
+/*
+ * 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.keyboard.backlight.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.backlight.domain.interactor.KeyboardBacklightInteractor
+import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
+import com.android.systemui.keyboard.shared.model.BacklightModel
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class BacklightDialogViewModelTest : SysuiTestCase() {
+
+ private val keyboardRepository = FakeKeyboardRepository()
+ private lateinit var underTest: BacklightDialogViewModel
+ @Mock private lateinit var accessibilityManagerWrapper: AccessibilityManagerWrapper
+ private val timeoutMillis = 3000L
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(accessibilityManagerWrapper.getRecommendedTimeoutMillis(any(), any()))
+ .thenReturn(timeoutMillis.toInt())
+ underTest =
+ BacklightDialogViewModel(
+ KeyboardBacklightInteractor(keyboardRepository),
+ accessibilityManagerWrapper
+ )
+ keyboardRepository.setKeyboardConnected(true)
+ }
+
+ @Test
+ fun emitsViewModel_whenBacklightChanged() = runTest {
+ keyboardRepository.setBacklight(BacklightModel(1, 5))
+
+ assertThat(underTest.dialogContent.first()).isEqualTo(BacklightDialogContentViewModel(1, 5))
+ }
+
+ @Test
+ fun emitsNull_afterTimeout() = runTest {
+ val latest by collectLastValue(underTest.dialogContent)
+ keyboardRepository.setBacklight(BacklightModel(1, 5))
+
+ assertThat(latest).isEqualTo(BacklightDialogContentViewModel(1, 5))
+ advanceTimeBy(timeoutMillis + 1)
+ assertThat(latest).isNull()
+ }
+
+ @Test
+ fun emitsNull_after5secDelay_fromLastBacklightChange() = runTest {
+ val latest by collectLastValue(underTest.dialogContent)
+ keyboardRepository.setKeyboardConnected(true)
+
+ keyboardRepository.setBacklight(BacklightModel(1, 5))
+ assertThat(latest).isEqualTo(BacklightDialogContentViewModel(1, 5))
+
+ advanceTimeBy(timeoutMillis * 2 / 3)
+ // timeout yet to pass, no new emission
+ keyboardRepository.setBacklight(BacklightModel(2, 5))
+ assertThat(latest).isEqualTo(BacklightDialogContentViewModel(2, 5))
+
+ advanceTimeBy(timeoutMillis * 2 / 3)
+ // timeout refreshed because of last `setBacklight`, still content present
+ assertThat(latest).isEqualTo(BacklightDialogContentViewModel(2, 5))
+
+ advanceTimeBy(timeoutMillis * 2 / 3)
+ // finally timeout reached and null emitted
+ assertThat(latest).isNull()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
index d2db910..f9493d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
@@ -62,7 +62,9 @@
fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockModel.WAKE_AND_UNLOCK)
runCurrent()
- values.assertEffectsMatchPredicates({ it == DEFAULT_REVEAL_EFFECT },)
+ values.assertEffectsMatchPredicates(
+ { it == DEFAULT_REVEAL_EFFECT },
+ )
// We got a source but still have no sensor locations, so should be sticking with
// the default effect.
@@ -71,14 +73,18 @@
)
runCurrent()
- values.assertEffectsMatchPredicates({ it == DEFAULT_REVEAL_EFFECT },)
+ values.assertEffectsMatchPredicates(
+ { it == DEFAULT_REVEAL_EFFECT },
+ )
// We got a location for the face sensor, but we unlocked with fingerprint.
val faceLocation = Point(250, 0)
fakeKeyguardRepository.setFaceSensorLocation(faceLocation)
runCurrent()
- values.assertEffectsMatchPredicates({ it == DEFAULT_REVEAL_EFFECT },)
+ values.assertEffectsMatchPredicates(
+ { it == DEFAULT_REVEAL_EFFECT },
+ )
// Now we have fingerprint sensor locations, and wake and unlock via fingerprint.
val fingerprintLocation = Point(500, 500)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
new file mode 100644
index 0000000..2a91799
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
@@ -0,0 +1,109 @@
+/*
+ * 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.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.util.mockito.whenever
+import com.google.common.collect.Range
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() {
+ private lateinit var underTest: PrimaryBouncerToGoneTransitionViewModel
+ private lateinit var repository: FakeKeyguardTransitionRepository
+ @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ repository = FakeKeyguardTransitionRepository()
+ val interactor = KeyguardTransitionInteractor(repository)
+ underTest = PrimaryBouncerToGoneTransitionViewModel(interactor, statusBarStateController)
+ }
+
+ @Test
+ fun scrimBehindAlpha_leaveShadeOpen() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val job = underTest.scrimBehindAlpha.onEach { values.add(it) }.launchIn(this)
+
+ whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(true)
+
+ repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+ repository.sendTransitionStep(step(0.3f))
+ repository.sendTransitionStep(step(0.6f))
+ repository.sendTransitionStep(step(1f))
+
+ assertThat(values.size).isEqualTo(4)
+ values.forEach { assertThat(it).isEqualTo(1f) }
+
+ job.cancel()
+ }
+
+ @Test
+ fun scrimBehindAlpha_doNotLeaveShadeOpen() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val job = underTest.scrimBehindAlpha.onEach { values.add(it) }.launchIn(this)
+
+ whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false)
+
+ repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+ repository.sendTransitionStep(step(0.3f))
+ repository.sendTransitionStep(step(0.6f))
+ repository.sendTransitionStep(step(1f))
+
+ assertThat(values.size).isEqualTo(4)
+ values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
+ assertThat(values[3]).isEqualTo(0f)
+
+ job.cancel()
+ }
+
+ private fun step(
+ value: Float,
+ state: TransitionState = TransitionState.RUNNING
+ ): TransitionStep {
+ return TransitionStep(
+ from = KeyguardState.PRIMARY_BOUNCER,
+ to = KeyguardState.GONE,
+ value = value,
+ transitionState = state,
+ ownerName = "PrimaryBouncerToGoneTransitionViewModelTest"
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index 55a33b6..fd353af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -27,6 +27,7 @@
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
+import android.graphics.Matrix
import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.Drawable
@@ -78,6 +79,8 @@
import com.android.systemui.media.controls.pipeline.MediaDataManager
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.media.dialog.MediaOutputDialogFactory
+import com.android.systemui.monet.ColorScheme
+import com.android.systemui.monet.Style
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.NotificationLockscreenUserManager
@@ -214,6 +217,7 @@
@Mock private lateinit var recSubtitleMock2: TextView
@Mock private lateinit var recSubtitleMock3: TextView
@Mock private lateinit var coverItem: ImageView
+ @Mock private lateinit var matrix: Matrix
private lateinit var coverItem1: ImageView
private lateinit var coverItem2: ImageView
private lateinit var coverItem3: ImageView
@@ -700,6 +704,46 @@
}
@Test
+ fun addTwoPlayerGradients_differentStates() {
+ // Setup redArtwork and its color scheme.
+ val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+ val redCanvas = Canvas(redBmp)
+ redCanvas.drawColor(Color.RED)
+ val redArt = Icon.createWithBitmap(redBmp)
+ val redWallpaperColor = player.getWallpaperColor(redArt)
+ val redColorScheme = ColorScheme(redWallpaperColor, true, Style.CONTENT)
+
+ // Setup greenArt and its color scheme.
+ val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+ val greenCanvas = Canvas(greenBmp)
+ greenCanvas.drawColor(Color.GREEN)
+ val greenArt = Icon.createWithBitmap(greenBmp)
+ val greenWallpaperColor = player.getWallpaperColor(greenArt)
+ val greenColorScheme = ColorScheme(greenWallpaperColor, true, Style.CONTENT)
+
+ // Add gradient to both icons.
+ val redArtwork = player.addGradientToPlayerAlbum(redArt, redColorScheme, 10, 10)
+ val greenArtwork = player.addGradientToPlayerAlbum(greenArt, greenColorScheme, 10, 10)
+
+ // They should have different constant states as they have different gradient color.
+ assertThat(redArtwork.getDrawable(1).constantState)
+ .isNotEqualTo(greenArtwork.getDrawable(1).constantState)
+ }
+
+ @Test
+ fun getWallpaperColor_recycledBitmap_notCrashing() {
+ // Setup redArt icon.
+ val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+ val redArt = Icon.createWithBitmap(redBmp)
+
+ // Recycle bitmap of redArt icon.
+ redArt.bitmap.recycle()
+
+ // get wallpaperColor without illegal exception.
+ player.getWallpaperColor(redArt)
+ }
+
+ @Test
fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() {
useRealConstraintSets()
@@ -2092,6 +2136,7 @@
.thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
whenever(recommendationViewHolder.mediaSubtitles)
.thenReturn(listOf(recSubtitleMock1, recSubtitleMock2, recSubtitleMock3))
+ whenever(coverItem.imageMatrix).thenReturn(matrix)
val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
@@ -2127,6 +2172,7 @@
verify(recCardTitle).setTextColor(any<Int>())
verify(recAppIconItem, times(3)).setImageDrawable(any(Drawable::class.java))
verify(coverItem, times(3)).setImageDrawable(any(Drawable::class.java))
+ verify(coverItem, times(3)).imageMatrix = any()
}
@Test
@@ -2189,6 +2235,34 @@
}
@Test
+ fun addTwoRecommendationGradients_differentStates() {
+ // Setup redArtwork and its color scheme.
+ val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+ val redCanvas = Canvas(redBmp)
+ redCanvas.drawColor(Color.RED)
+ val redArt = Icon.createWithBitmap(redBmp)
+ val redWallpaperColor = player.getWallpaperColor(redArt)
+ val redColorScheme = ColorScheme(redWallpaperColor, true, Style.CONTENT)
+
+ // Setup greenArt and its color scheme.
+ val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+ val greenCanvas = Canvas(greenBmp)
+ greenCanvas.drawColor(Color.GREEN)
+ val greenArt = Icon.createWithBitmap(greenBmp)
+ val greenWallpaperColor = player.getWallpaperColor(greenArt)
+ val greenColorScheme = ColorScheme(greenWallpaperColor, true, Style.CONTENT)
+
+ // Add gradient to both icons.
+ val redArtwork = player.addGradientToRecommendationAlbum(redArt, redColorScheme, 10, 10)
+ val greenArtwork =
+ player.addGradientToRecommendationAlbum(greenArt, greenColorScheme, 10, 10)
+
+ // They should have different constant states as they have different gradient color.
+ assertThat(redArtwork.getDrawable(1).constantState)
+ .isNotEqualTo(greenArtwork.getDrawable(1).constantState)
+ }
+
+ @Test
fun onButtonClick_touchRippleFlagEnabled_playsTouchRipple() {
fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
val semanticActions =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
index 4fc9ca7..85e8d07 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
@@ -70,8 +70,7 @@
context,
appPackageName = null,
isReceiver = false,
- ) {
- }
+ ) {}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -86,8 +85,7 @@
context,
appPackageName = null,
isReceiver = true,
- ) {
- }
+ ) {}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -119,8 +117,7 @@
context,
appPackageName = "fakePackageName",
isReceiver = false,
- ) {
- }
+ ) {}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -135,8 +132,7 @@
context,
appPackageName = "fakePackageName",
isReceiver = true,
- ) {
- }
+ ) {}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -154,7 +150,9 @@
context,
appPackageName = "fakePackageName",
isReceiver = false
- ) { exceptionTriggered = true }
+ ) {
+ exceptionTriggered = true
+ }
assertThat(exceptionTriggered).isTrue()
}
@@ -167,7 +165,9 @@
context,
appPackageName = "fakePackageName",
isReceiver = true
- ) { exceptionTriggered = true }
+ ) {
+ exceptionTriggered = true
+ }
assertThat(exceptionTriggered).isTrue()
}
@@ -179,8 +179,7 @@
context,
PACKAGE_NAME,
isReceiver = false,
- ) {
- }
+ ) {}
assertThat(iconInfo.isAppIcon).isTrue()
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))
@@ -194,8 +193,7 @@
context,
PACKAGE_NAME,
isReceiver = true,
- ) {
- }
+ ) {}
assertThat(iconInfo.isAppIcon).isTrue()
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 52b0b6a..4f469f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -551,6 +551,7 @@
mNotificationStackSizeCalculator,
mUnlockedScreenOffAnimationController,
mShadeTransitionController,
+ mInteractionJankMonitor,
systemClock,
mKeyguardBottomAreaViewModel,
mKeyguardBottomAreaInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index d99cdd51..ab615f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -211,16 +211,6 @@
}
@Test
- fun testTriggeringBouncerWhenPrivateNotificationsArentAllowed() {
- whenever(lockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
- false)
- transitionController.goToLockedShade(null)
- verify(statusbarStateController, never()).setState(anyInt())
- verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
- verify(mCentralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
- }
-
- @Test
fun testTriggeringBouncerNoNotificationsOnLockscreen() {
whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
transitionController.goToLockedShade(null)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index eb5edbc..f5b7ca8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -180,6 +180,7 @@
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
mDozeParameters.onTuningChanged(Settings.Secure.DOZE_ALWAYS_ON, "1");
+ verify(mScreenOffAnimationController).onAlwaysOnChanged(false);
assertThat(mDozeParameters.getAlwaysOn()).isFalse();
}
@@ -196,13 +197,16 @@
mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
verify(callback, times(2)).onAlwaysOnChange();
+ verify(mScreenOffAnimationController, times(2)).onAlwaysOnChanged(false);
assertThat(mDozeParameters.getAlwaysOn()).isFalse();
+ reset(mScreenOffAnimationController);
reset(callback);
when(mBatteryController.isAodPowerSave()).thenReturn(false);
mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
verify(callback).onAlwaysOnChange();
+ verify(mScreenOffAnimationController).onAlwaysOnChanged(true);
assertThat(mDozeParameters.getAlwaysOn()).isTrue();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 180d9f8..e1fba81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -67,6 +67,7 @@
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
import com.android.systemui.scrim.ScrimView;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.FakeConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -127,6 +128,7 @@
@Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@Mock private CoroutineDispatcher mMainDispatcher;
+ @Mock private SysuiStatusBarStateController mSysuiStatusBarStateController;
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@@ -240,7 +242,8 @@
when(mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition())
.thenReturn(emptyFlow());
- when(mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha()).thenReturn(emptyFlow());
+ when(mPrimaryBouncerToGoneTransitionViewModel.getScrimBehindAlpha())
+ .thenReturn(emptyFlow());
mScrimController = new ScrimController(mLightBarController,
mDozeParameters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
@@ -251,6 +254,7 @@
mStatusBarKeyguardViewManager,
mPrimaryBouncerToGoneTransitionViewModel,
mKeyguardTransitionInteractor,
+ mSysuiStatusBarStateController,
mMainDispatcher);
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
@@ -884,6 +888,7 @@
mStatusBarKeyguardViewManager,
mPrimaryBouncerToGoneTransitionViewModel,
mKeyguardTransitionInteractor,
+ mSysuiStatusBarStateController,
mMainDispatcher);
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
@@ -1664,6 +1669,16 @@
assertThat(mScrimController.getState()).isEqualTo(ScrimState.UNLOCKED);
}
+ @Test
+ public void primaryBouncerToGoneOnFinishCallsKeyguardFadedAway() {
+ when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true);
+ mScrimController.mPrimaryBouncerToGoneTransition.accept(
+ new TransitionStep(KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, 0f,
+ TransitionState.FINISHED, "ScrimControllerTest"));
+
+ verify(mStatusBarKeyguardViewManager).onKeyguardFadedAway();
+ }
+
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
mScrimController.setRawPanelExpansionFraction(expansion);
finishAnimationsImmediately();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index 00ce412..b072dee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -239,6 +239,7 @@
* list2 = [false, true]
* list3 = [a, b, c]
* ```
+ *
* We'll generate test cases for:
*
* Test (1, false, a) Test (2, false, a) Test (3, false, a) Test (1, true, a) Test (1,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
index 85cfef7..fd368eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
@@ -16,22 +16,24 @@
package com.android.systemui.unfold.updates
+import android.content.Context
+import android.hardware.display.DisplayManager
+import android.os.Looper
import android.testing.AndroidTestingRunner
-import android.view.IRotationWatcher
-import android.view.IWindowManager
+import android.view.Display
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListener
-import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.utils.os.FakeHandler
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Captor
import org.mockito.Mock
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
@@ -42,19 +44,23 @@
private lateinit var rotationChangeProvider: RotationChangeProvider
- @Mock lateinit var windowManagerInterface: IWindowManager
+ @Mock lateinit var displayManager: DisplayManager
@Mock lateinit var listener: RotationListener
- @Captor lateinit var rotationWatcher: ArgumentCaptor<IRotationWatcher>
- private val fakeExecutor = FakeExecutor(FakeSystemClock())
+ @Mock lateinit var display: Display
+ @Captor lateinit var displayListener: ArgumentCaptor<DisplayManager.DisplayListener>
+ private val fakeHandler = FakeHandler(Looper.getMainLooper())
+
+ private lateinit var spyContext: Context
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
- rotationChangeProvider =
- RotationChangeProvider(windowManagerInterface, context, fakeExecutor)
+ spyContext = spy(context)
+ whenever(spyContext.display).thenReturn(display)
+ rotationChangeProvider = RotationChangeProvider(displayManager, spyContext, fakeHandler)
rotationChangeProvider.addCallback(listener)
- fakeExecutor.runAllReady()
- verify(windowManagerInterface).watchRotation(rotationWatcher.capture(), anyInt())
+ fakeHandler.dispatchQueuedMessages()
+ verify(displayManager).registerDisplayListener(displayListener.capture(), any())
}
@Test
@@ -70,15 +76,16 @@
verify(listener).onRotationChanged(42)
rotationChangeProvider.removeCallback(listener)
- fakeExecutor.runAllReady()
+ fakeHandler.dispatchQueuedMessages()
sendRotationUpdate(43)
- verify(windowManagerInterface).removeRotationWatcher(any())
+ verify(displayManager).unregisterDisplayListener(any())
verifyNoMoreInteractions(listener)
}
private fun sendRotationUpdate(newRotation: Int) {
- rotationWatcher.value.onRotationChanged(newRotation)
- fakeExecutor.runAllReady()
+ whenever(display.rotation).thenReturn(newRotation)
+ displayListener.allValues.forEach { it.onDisplayChanged(display.displayId) }
+ fakeHandler.dispatchQueuedMessages()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
index 31cce4f..468c5a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/ImageWallpaperTest.java
@@ -88,7 +88,7 @@
@Mock
private Bitmap mWallpaperBitmap;
FakeSystemClock mFakeSystemClock = new FakeSystemClock();
- FakeExecutor mFakeBackgroundExecutor = new FakeExecutor(mFakeSystemClock);
+ FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
@Before
public void setUp() throws Exception {
@@ -125,7 +125,7 @@
@Test
public void testBitmapWallpaper_normal() {
- // Will use a image wallpaper with dimensions DISPLAY_WIDTH x DISPLAY_WIDTH.
+ // Will use an image wallpaper with dimensions DISPLAY_WIDTH x DISPLAY_WIDTH.
// Then we expect the surface size will be also DISPLAY_WIDTH x DISPLAY_WIDTH.
int bitmapSide = DISPLAY_WIDTH;
testSurfaceHelper(
@@ -137,7 +137,7 @@
@Test
public void testBitmapWallpaper_low_resolution() {
- // Will use a image wallpaper with dimensions BMP_WIDTH x BMP_HEIGHT.
+ // Will use an image wallpaper with dimensions BMP_WIDTH x BMP_HEIGHT.
// Then we expect the surface size will be also BMP_WIDTH x BMP_HEIGHT.
testSurfaceHelper(LOW_BMP_WIDTH /* bitmapWidth */,
LOW_BMP_HEIGHT /* bitmapHeight */,
@@ -161,13 +161,13 @@
ImageWallpaper.CanvasEngine spyEngine = getSpyEngine();
spyEngine.onCreate(mSurfaceHolder);
spyEngine.onSurfaceRedrawNeeded(mSurfaceHolder);
- assertThat(mFakeBackgroundExecutor.numPending()).isAtLeast(1);
+ assertThat(mFakeExecutor.numPending()).isAtLeast(1);
int n = 0;
- while (mFakeBackgroundExecutor.numPending() >= 1) {
+ while (mFakeExecutor.numPending() >= 1) {
n++;
assertThat(n).isAtMost(10);
- mFakeBackgroundExecutor.runNextReady();
+ mFakeExecutor.runNextReady();
mFakeSystemClock.advanceTime(1000);
}
@@ -176,7 +176,7 @@
}
private ImageWallpaper createImageWallpaper() {
- return new ImageWallpaper(mFakeBackgroundExecutor, mUserTracker) {
+ return new ImageWallpaper(mFakeExecutor, mUserTracker) {
@Override
public Engine onCreateEngine() {
return new CanvasEngine() {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt
index 9b4f496..c2947b4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt
@@ -29,6 +29,7 @@
/**
* Collect [flow] in a new [Job] and return a getter for the last collected value.
+ *
* ```
* fun myTest() = runTest {
* // ...
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/data/repository/FakeKeyboardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/data/repository/FakeKeyboardRepository.kt
new file mode 100644
index 0000000..4e43546
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/data/repository/FakeKeyboardRepository.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.keyboard.data.repository
+
+import com.android.systemui.keyboard.shared.model.BacklightModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filterNotNull
+
+class FakeKeyboardRepository : KeyboardRepository {
+
+ private val _keyboardConnected = MutableStateFlow(false)
+ override val keyboardConnected: Flow<Boolean> = _keyboardConnected
+
+ private val _backlightState: MutableStateFlow<BacklightModel?> = MutableStateFlow(null)
+ // filtering to make sure backlight doesn't have default initial value
+ override val backlight: Flow<BacklightModel> = _backlightState.filterNotNull()
+
+ fun setBacklight(state: BacklightModel) {
+ _backlightState.value = state
+ }
+
+ fun setKeyboardConnected(connected: Boolean) {
+ _keyboardConnected.value = connected
+ }
+}
diff --git a/packages/SystemUI/unfold/Android.bp b/packages/SystemUI/unfold/Android.bp
index 180b611..2e0a946 100644
--- a/packages/SystemUI/unfold/Android.bp
+++ b/packages/SystemUI/unfold/Android.bp
@@ -35,6 +35,7 @@
],
kotlincflags: ["-Xjvm-default=enable"],
java_version: "1.8",
+ sdk_version: "current",
min_sdk_version: "current",
plugins: ["dagger2-compiler"],
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index 068347c..a079668 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -19,8 +19,8 @@
import android.content.ContentResolver
import android.content.Context
import android.hardware.SensorManager
+import android.hardware.display.DisplayManager
import android.os.Handler
-import android.view.IWindowManager
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.dagger.UnfoldMain
import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
@@ -61,7 +61,7 @@
@BindsInstance @UnfoldMain executor: Executor,
@BindsInstance @UnfoldSingleThreadBg singleThreadBgExecutor: Executor,
@BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
- @BindsInstance windowManager: IWindowManager,
+ @BindsInstance displayManager: DisplayManager,
@BindsInstance contentResolver: ContentResolver = context.contentResolver
): UnfoldSharedComponent
}
@@ -84,8 +84,9 @@
@BindsInstance context: Context,
@BindsInstance config: UnfoldTransitionConfig,
@BindsInstance @UnfoldMain executor: Executor,
+ @BindsInstance @UnfoldMain handler: Handler,
@BindsInstance @UnfoldSingleThreadBg singleThreadBgExecutor: Executor,
- @BindsInstance windowManager: IWindowManager,
+ @BindsInstance displayManager: DisplayManager,
@BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
): RemoteUnfoldSharedComponent
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index 8eb79df..1839919 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -19,8 +19,8 @@
import android.content.Context
import android.hardware.SensorManager
+import android.hardware.display.DisplayManager
import android.os.Handler
-import android.view.IWindowManager
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.updates.FoldProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
@@ -47,7 +47,7 @@
mainExecutor: Executor,
singleThreadBgExecutor: Executor,
tracingTagPrefix: String,
- windowManager: IWindowManager,
+ displayManager: DisplayManager,
): UnfoldSharedComponent =
DaggerUnfoldSharedComponent.factory()
.create(
@@ -61,7 +61,7 @@
mainExecutor,
singleThreadBgExecutor,
tracingTagPrefix,
- windowManager,
+ displayManager,
)
/**
@@ -73,16 +73,18 @@
context: Context,
config: UnfoldTransitionConfig,
mainExecutor: Executor,
+ mainHandler: Handler,
singleThreadBgExecutor: Executor,
tracingTagPrefix: String,
- windowManager: IWindowManager,
+ displayManager: DisplayManager,
): RemoteUnfoldSharedComponent =
DaggerRemoteUnfoldSharedComponent.factory()
.create(
context,
config,
mainExecutor,
+ mainHandler,
singleThreadBgExecutor,
- windowManager,
+ displayManager,
tracingTagPrefix,
)
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index d19b414..28e4936 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -16,7 +16,6 @@
package com.android.systemui.unfold.progress
import android.os.Trace
-import android.os.Trace.TRACE_TAG_APP
import android.util.Log
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FloatPropertyCompat
@@ -110,7 +109,7 @@
if (DEBUG) {
Log.d(TAG, "onFoldUpdate = ${update.name()}")
- Trace.traceCounter(Trace.TRACE_TAG_APP, "fold_update", update)
+ Trace.setCounter("fold_update", update.toLong())
}
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 82fd225..d653fc7 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -119,7 +119,7 @@
"lastHingeAngle: $lastHingeAngle, " +
"lastHingeAngleBeforeTransition: $lastHingeAngleBeforeTransition"
)
- Trace.traceCounter(Trace.TRACE_TAG_APP, "hinge_angle", angle.toInt())
+ Trace.setCounter( "hinge_angle", angle.toLong())
}
val currentDirection =
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
index 0cf8224..ce8f1a1 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
@@ -17,36 +17,32 @@
package com.android.systemui.unfold.updates
import android.content.Context
+import android.hardware.display.DisplayManager
+import android.os.Handler
import android.os.RemoteException
-import android.view.IRotationWatcher
-import android.view.IWindowManager
-import android.view.Surface.Rotation
import com.android.systemui.unfold.dagger.UnfoldMain
import com.android.systemui.unfold.util.CallbackController
-import java.util.concurrent.Executor
import javax.inject.Inject
/**
- * Allows to subscribe to rotation changes.
- *
- * This is needed as rotation updates from [IWindowManager] are received in a binder thread, while
- * most of the times we want them in the main one. Updates are provided for the display associated
+ * Allows to subscribe to rotation changes. Updates are provided for the display associated
* to [context].
*/
class RotationChangeProvider
@Inject
constructor(
- private val windowManagerInterface: IWindowManager,
+ private val displayManager: DisplayManager,
private val context: Context,
- @UnfoldMain private val mainExecutor: Executor,
+ @UnfoldMain private val mainHandler: Handler,
) : CallbackController<RotationChangeProvider.RotationListener> {
private val listeners = mutableListOf<RotationListener>()
- private val rotationWatcher = RotationWatcher()
+ private val displayListener = RotationDisplayListener()
+ private var lastRotation: Int? = null
override fun addCallback(listener: RotationListener) {
- mainExecutor.execute {
+ mainHandler.post {
if (listeners.isEmpty()) {
subscribeToRotation()
}
@@ -55,17 +51,18 @@
}
override fun removeCallback(listener: RotationListener) {
- mainExecutor.execute {
+ mainHandler.post {
listeners -= listener
if (listeners.isEmpty()) {
unsubscribeToRotation()
+ lastRotation = null
}
}
}
private fun subscribeToRotation() {
try {
- windowManagerInterface.watchRotation(rotationWatcher, context.displayId)
+ displayManager.registerDisplayListener(displayListener, mainHandler)
} catch (e: RemoteException) {
throw e.rethrowFromSystemServer()
}
@@ -73,7 +70,7 @@
private fun unsubscribeToRotation() {
try {
- windowManagerInterface.removeRotationWatcher(rotationWatcher)
+ displayManager.unregisterDisplayListener(displayListener)
} catch (e: RemoteException) {
throw e.rethrowFromSystemServer()
}
@@ -82,12 +79,25 @@
/** Gets notified of rotation changes. */
fun interface RotationListener {
/** Called once rotation changes. */
- fun onRotationChanged(@Rotation newRotation: Int)
+ fun onRotationChanged(newRotation: Int)
}
- private inner class RotationWatcher : IRotationWatcher.Stub() {
- override fun onRotationChanged(rotation: Int) {
- mainExecutor.execute { listeners.forEach { it.onRotationChanged(rotation) } }
+ private inner class RotationDisplayListener : DisplayManager.DisplayListener {
+
+ override fun onDisplayChanged(displayId: Int) {
+ val display = context.display ?: return
+
+ if (displayId == display.displayId) {
+ val currentRotation = display.rotation
+ if (lastRotation == null || lastRotation != currentRotation) {
+ listeners.forEach { it.onRotationChanged(currentRotation) }
+ lastRotation = currentRotation
+ }
+ }
}
+
+ override fun onDisplayAdded(displayId: Int) {}
+
+ override fun onDisplayRemoved(displayId: Int) {}
}
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
index 06ca153..ce5c5f9 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
@@ -79,10 +79,9 @@
companion object {
fun ContentResolver.areAnimationsEnabled(): Boolean {
val animationScale =
- Settings.Global.getStringForUser(
+ Settings.Global.getString(
this,
Settings.Global.ANIMATOR_DURATION_SCALE,
- this.userId
)
?.toFloatOrNull()
?: 1f
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
index b7bab3e..f9751d9 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
@@ -47,6 +47,7 @@
/**
* Sets the source for the unfold transition progress updates. Replaces current provider if it
* is already set
+ *
* @param provider transition provider that emits transition progress updates
*/
fun setSourceProvider(provider: UnfoldTransitionProgressProvider?) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d78fe86..f0dac260 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3831,8 +3831,20 @@
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+ final int callingAppId = UserHandle.getAppId(callingUid);
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ ProcessRecord proc;
+ synchronized (mPidsSelfLocked) {
+ proc = mPidsSelfLocked.get(callingPid);
+ }
+ final boolean hasKillAllPermission = PERMISSION_GRANTED == checkPermission(
+ android.Manifest.permission.FORCE_STOP_PACKAGES, callingPid, callingUid)
+ || UserHandle.isCore(callingUid)
+ || (proc != null && proc.info.isSystemApp());
+
+ userId = mUserController.handleIncomingUser(callingPid, callingUid,
userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
final int[] userIds = mUserController.expandUserId(userId);
@@ -3847,7 +3859,7 @@
targetUserId));
} catch (RemoteException e) {
}
- if (appId == -1) {
+ if (appId == -1 || (!hasKillAllPermission && appId != callingAppId)) {
Slog.w(TAG, "Invalid packageName: " + packageName);
return;
}
@@ -3875,6 +3887,22 @@
throw new SecurityException(msg);
}
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+
+ ProcessRecord proc;
+ synchronized (mPidsSelfLocked) {
+ proc = mPidsSelfLocked.get(callingPid);
+ }
+ if (callingUid >= FIRST_APPLICATION_UID
+ && (proc == null || !proc.info.isSystemApp())) {
+ final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
+ + callingPid + ", uid=" + callingUid + " is not allowed";
+ Slog.w(TAG, msg);
+ // Silently return to avoid existing apps from crashing.
+ return;
+ }
+
final long callingId = Binder.clearCallingIdentity();
try {
synchronized (this) {
@@ -13089,12 +13117,17 @@
public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,
String callerFeatureId, String receiverId, IIntentReceiver receiver,
IntentFilter filter, String permission, int userId, int flags) {
+ enforceNotIsolatedCaller("registerReceiver");
+
// Allow Sandbox process to register only unexported receivers.
- if ((flags & Context.RECEIVER_NOT_EXPORTED) != 0) {
- enforceNotIsolatedCaller("registerReceiver");
- } else if (mSdkSandboxSettings.isBroadcastReceiverRestrictionsEnforced()) {
- enforceNotIsolatedOrSdkSandboxCaller("registerReceiver");
+ boolean unexported = (flags & Context.RECEIVER_NOT_EXPORTED) != 0;
+ if (mSdkSandboxSettings.isBroadcastReceiverRestrictionsEnforced()
+ && Process.isSdkSandboxUid(Binder.getCallingUid())
+ && !unexported) {
+ throw new SecurityException("SDK sandbox process not allowed to call "
+ + "registerReceiver");
}
+
ArrayList<Intent> stickyIntents = null;
ProcessRecord callerApp = null;
final boolean visibleToInstantApps
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 2f95716..207c10c 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -21,7 +21,6 @@
import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
import android.annotation.NonNull;
-import android.app.AlarmManager;
import android.app.StatsManager;
import android.app.usage.NetworkStatsManager;
import android.bluetooth.BluetoothActivityEnergyInfo;
@@ -357,16 +356,6 @@
mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
com.android.internal.R.integer.config_radioScanningTimeout) * 1000L);
mStats.setPowerProfileLocked(mPowerProfile);
-
- final boolean resetOnUnplugHighBatteryLevel = context.getResources().getBoolean(
- com.android.internal.R.bool.config_batteryStatsResetOnUnplugHighBatteryLevel);
- final boolean resetOnUnplugAfterSignificantCharge = context.getResources().getBoolean(
- com.android.internal.R.bool.config_batteryStatsResetOnUnplugAfterSignificantCharge);
- mStats.setBatteryStatsConfig(
- new BatteryStatsImpl.BatteryStatsConfig.Builder()
- .setResetOnUnplugHighBatteryLevel(resetOnUnplugHighBatteryLevel)
- .setResetOnUnplugAfterSignificantCharge(resetOnUnplugAfterSignificantCharge)
- .build());
mStats.startTrackingSystemServerCpuTime();
if (BATTERY_USAGE_STORE_ENABLED) {
@@ -397,18 +386,6 @@
Slog.e(TAG, "Could not register INetworkManagement event observer " + e);
}
- final AlarmManager am = mContext.getSystemService(AlarmManager.class);
- mHandler.post(() -> {
- synchronized (mStats) {
- mStats.setLongPlugInAlarmInterface(new AlarmInterface(am, () -> {
- synchronized (mStats) {
- if (mStats.isOnBattery()) return;
- mStats.maybeResetWhilePluggedInLocked();
- }
- }));
- }
- });
-
synchronized (mPowerStatsLock) {
mPowerStatsInternal = LocalServices.getService(PowerStatsInternal.class);
if (mPowerStatsInternal != null) {
@@ -2282,32 +2259,6 @@
}
}
- final class AlarmInterface implements BatteryStatsImpl.AlarmInterface,
- AlarmManager.OnAlarmListener {
- private AlarmManager mAm;
- private Runnable mOnAlarm;
-
- AlarmInterface(AlarmManager am, Runnable onAlarm) {
- mAm = am;
- mOnAlarm = onAlarm;
- }
-
- @Override
- public void schedule(long rtcTimeMs, long windowLengthMs) {
- mAm.setWindow(AlarmManager.RTC, rtcTimeMs, windowLengthMs, TAG, this, mHandler);
- }
-
- @Override
- public void cancel() {
- mAm.cancel(this);
- }
-
- @Override
- public void onAlarm() {
- mOnAlarm.run();
- }
- }
-
private static native int nativeWaitWakeup(ByteBuffer outBuffer);
private void dumpHelp(PrintWriter pw) {
@@ -2494,8 +2445,7 @@
} else if ("--reset-all".equals(arg)) {
awaitCompletion();
synchronized (mStats) {
- mStats.resetAllStatsAndHistoryLocked(
- BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ mStats.resetAllStatsCmdLocked();
mBatteryUsageStatsStore.removeAllSnapshots();
pw.println("Battery stats and history reset.");
noOutput = true;
@@ -2503,8 +2453,7 @@
} else if ("--reset".equals(arg)) {
awaitCompletion();
synchronized (mStats) {
- mStats.resetAllStatsAndHistoryLocked(
- BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
+ mStats.resetAllStatsCmdLocked();
pw.println("Battery stats reset.");
noOutput = true;
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 9700e56..8c9373b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -3005,9 +3005,10 @@
hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
final ProcessStateRecord state = r.mState;
- if (!mService.mBooted && !mService.mBooting
+ if (!isolated && !isSdkSandbox
&& userId == UserHandle.USER_SYSTEM
- && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
+ && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK
+ && (TextUtils.equals(proc, info.processName))) {
// The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
state.setSetSchedGroup(ProcessList.SCHED_GROUP_DEFAULT);
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 76d71e2..bb39307 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -22,6 +22,7 @@
import android.graphics.Rect;
import android.hardware.display.DisplayViewport;
import android.os.IBinder;
+import android.util.Slog;
import android.view.Display;
import android.view.DisplayAddress;
import android.view.Surface;
@@ -37,6 +38,7 @@
* </p>
*/
abstract class DisplayDevice {
+ private static final String TAG = "DisplayDevice";
private static final Display.Mode EMPTY_DISPLAY_MODE = new Display.Mode.Builder().build();
private final DisplayAdapter mDisplayAdapter;
@@ -266,10 +268,13 @@
/**
* Sets the display layer stack while in a transaction.
*/
- public final void setLayerStackLocked(SurfaceControl.Transaction t, int layerStack) {
+ public final void setLayerStackLocked(SurfaceControl.Transaction t, int layerStack,
+ int layerStackTag) {
if (mCurrentLayerStack != layerStack) {
mCurrentLayerStack = layerStack;
t.setDisplayLayerStack(mDisplayToken, layerStack);
+ Slog.i(TAG, "[" + layerStackTag + "] Layerstack set to " + layerStack + " for "
+ + mUniqueId);
}
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index e6f27c1..7dc412e 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -494,7 +494,7 @@
DisplayDevice device,
boolean isBlanked) {
// Set the layer stack.
- device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack);
+ device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack, mDisplayId);
// Also inform whether the device is the same one sent to inputflinger for its layerstack.
// Prevent displays that are disabled from receiving input.
// TODO(b/188914255): Remove once input can dispatch against device vs layerstack.
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 350aa6b..2a807b2 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -608,6 +608,9 @@
/* package */ void updateRunningUserAndProfiles(int newActiveUserId) {
synchronized (mLock) {
if (mCurrentActiveUserId != newActiveUserId) {
+ Slog.i(TAG, TextUtils.formatSimple(
+ "switchUser | user: %d", newActiveUserId));
+
mCurrentActiveUserId = newActiveUserId;
for (int i = 0; i < mUserRecords.size(); i++) {
int userId = mUserRecords.keyAt(i);
@@ -679,6 +682,10 @@
userRecord.mHandler.sendMessage(
obtainMessage(UserHandler::notifyRouterRegistered,
userRecord.mHandler, routerRecord));
+
+ Slog.i(TAG, TextUtils.formatSimple(
+ "registerRouter2 | package: %s, uid: %d, pid: %d, router: %d",
+ packageName, uid, pid, routerRecord.mRouterId));
}
@GuardedBy("mLock")
@@ -689,6 +696,11 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "unregisterRouter2 | package: %s, router: %d",
+ routerRecord.mPackageName,
+ routerRecord.mRouterId));
+
UserRecord userRecord = routerRecord.mUserRecord;
userRecord.mRouterRecords.remove(routerRecord);
routerRecord.mUserRecord.mHandler.sendMessage(
@@ -707,6 +719,11 @@
if (routerRecord.mDiscoveryPreference.equals(discoveryRequest)) {
return;
}
+
+ Slog.i(TAG, TextUtils.formatSimple(
+ "setDiscoveryRequestWithRouter2 | router: %d, discovery request: %s",
+ routerRecord.mRouterId, discoveryRequest.toString()));
+
routerRecord.mDiscoveryPreference = discoveryRequest;
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManagers,
@@ -724,6 +741,10 @@
RouterRecord routerRecord = mAllRouterRecords.get(binder);
if (routerRecord != null) {
+ Slog.i(TAG, TextUtils.formatSimple(
+ "setRouteVolumeWithRouter2 | router: %d, volume: %d",
+ routerRecord.mRouterId, volume));
+
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setRouteVolumeOnHandler,
routerRecord.mUserRecord.mHandler,
@@ -804,6 +825,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "selectRouteWithRouter2 | router: %d, route: %s",
+ routerRecord.mRouterId, route.getId()));
+
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::selectRouteOnHandler,
routerRecord.mUserRecord.mHandler,
@@ -819,6 +844,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "deselectRouteWithRouter2 | router: %d, route: %s",
+ routerRecord.mRouterId, route.getId()));
+
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::deselectRouteOnHandler,
routerRecord.mUserRecord.mHandler,
@@ -834,6 +863,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "transferToRouteWithRouter2 | router: %d, route: %s",
+ routerRecord.mRouterId, route.getId()));
+
String defaultRouteId =
routerRecord.mUserRecord.mHandler.mSystemProvider.getDefaultRoute().getId();
if (route.isSystemRoute() && !routerRecord.mHasModifyAudioRoutingPermission
@@ -859,6 +892,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "setSessionVolumeWithRouter2 | router: %d, session: %s, volume: %d",
+ routerRecord.mRouterId, uniqueSessionId, volume));
+
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setSessionVolumeOnHandler,
routerRecord.mUserRecord.mHandler,
@@ -874,6 +911,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "releaseSessionWithRouter2 | router: %d, session: %s",
+ routerRecord.mRouterId, uniqueSessionId));
+
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::releaseSessionOnHandler,
routerRecord.mUserRecord.mHandler,
@@ -916,6 +957,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "registerManager | uid: %d, pid: %d, package: %s, user: %d",
+ uid, pid, packageName, userId));
+
mContext.enforcePermission(Manifest.permission.MEDIA_CONTENT_CONTROL, pid, uid,
"Must hold MEDIA_CONTENT_CONTROL permission.");
@@ -951,6 +996,13 @@
return;
}
UserRecord userRecord = managerRecord.mUserRecord;
+
+ Slog.i(TAG, TextUtils.formatSimple(
+ "unregisterManager | package: %s, user: %d, manager: %d",
+ managerRecord.mPackageName,
+ userRecord.mUserId,
+ managerRecord.mManagerId));
+
userRecord.mManagerRecords.remove(managerRecord);
managerRecord.dispose();
disposeUserIfNeededLocked(userRecord); // since manager removed from user
@@ -962,6 +1014,10 @@
if (managerRecord == null) {
return;
}
+
+ Slog.i(TAG, TextUtils.formatSimple(
+ "startScan | manager: %d", managerRecord.mManagerId));
+
managerRecord.startScan();
}
@@ -971,6 +1027,10 @@
if (managerRecord == null) {
return;
}
+
+ Slog.i(TAG, TextUtils.formatSimple(
+ "stopScan | manager: %d", managerRecord.mManagerId));
+
managerRecord.stopScan();
}
@@ -984,6 +1044,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "setRouteVolumeWithManager | manager: %d, route: %s, volume: %d",
+ managerRecord.mManagerId, route.getId(), volume));
+
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setRouteVolumeOnHandler,
@@ -999,6 +1063,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "requestCreateSessionWithManager | manager: %d, route: %s",
+ managerRecord.mManagerId, route.getId()));
+
String packageName = oldSession.getClientPackageName();
RouterRecord routerRecord = managerRecord.mUserRecord.findRouterRecordLocked(packageName);
@@ -1044,6 +1112,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "selectRouteWithManager | manager: %d, session: %s, route: %s",
+ managerRecord.mManagerId, uniqueSessionId, route.getId()));
+
// Can be null if the session is system's or RCN.
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterWithSessionLocked(uniqueSessionId);
@@ -1065,6 +1137,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "deselectRouteWithManager | manager: %d, session: %s, route: %s",
+ managerRecord.mManagerId, uniqueSessionId, route.getId()));
+
// Can be null if the session is system's or RCN.
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterWithSessionLocked(uniqueSessionId);
@@ -1086,6 +1162,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "transferToRouteWithManager | manager: %d, session: %s, route: %s",
+ managerRecord.mManagerId, uniqueSessionId, route.getId()));
+
// Can be null if the session is system's or RCN.
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterWithSessionLocked(uniqueSessionId);
@@ -1107,6 +1187,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "setSessionVolumeWithManager | manager: %d, session: %s, volume: %d",
+ managerRecord.mManagerId, uniqueSessionId, volume));
+
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setSessionVolumeOnHandler,
@@ -1124,6 +1208,10 @@
return;
}
+ Slog.i(TAG, TextUtils.formatSimple(
+ "releaseSessionWithManager | manager: %d, session: %s",
+ managerRecord.mManagerId, uniqueSessionId));
+
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterWithSessionLocked(uniqueSessionId);
@@ -1484,6 +1572,24 @@
List<IMediaRouter2> routersWithModifyAudioRoutingPermission = getRouters(true);
List<IMediaRouter2> routersWithoutModifyAudioRoutingPermission = getRouters(false);
+
+ if (!addedRoutes.isEmpty()) {
+ // If routes were added, currentInfo cannot be null.
+ Slog.i(TAG,
+ toLoggingMessage(
+ /* source= */ "addProviderRoutes",
+ currentInfo.getUniqueId(),
+ (ArrayList) addedRoutes));
+ }
+ if (!removedRoutes.isEmpty()) {
+ // If routes were removed, prevInfo cannot be null.
+ Slog.i(TAG,
+ toLoggingMessage(
+ /* source= */ "removeProviderRoutes",
+ prevInfo.getUniqueId(),
+ (ArrayList) removedRoutes));
+ }
+
List<IMediaRouter2Manager> managers = getManagers();
List<MediaRoute2Info> defaultRoute = new ArrayList<>();
defaultRoute.add(mSystemProvider.getDefaultRoute());
@@ -1522,6 +1628,16 @@
}
}
+ private static String toLoggingMessage(
+ String source, String providerId, ArrayList<MediaRoute2Info> routes) {
+ String routesString =
+ routes.stream()
+ .map(it -> String.format("%s | %s", it.getOriginalId(), it.getName()))
+ .collect(Collectors.joining(/* delimiter= */ ", "));
+ return TextUtils.formatSimple("%s | provider: %s, routes: [%s]",
+ source, providerId, routesString);
+ }
+
private int getLastProviderInfoIndex(@NonNull String providerId) {
for (int i = 0; i < mLastProviderInfos.size(); i++) {
MediaRoute2ProviderInfo providerInfo = mLastProviderInfos.get(i);
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index b75ba75..c5a337d 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -21,7 +21,9 @@
import android.media.Session2Token;
import android.media.session.MediaSession;
import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.Log;
+import android.util.Slog;
import android.util.SparseArray;
import java.io.PrintWriter;
@@ -82,6 +84,10 @@
* @param record The record to add.
*/
public void addSession(MediaSessionRecordImpl record) {
+ Slog.i(TAG, TextUtils.formatSimple(
+ "addSession to bottom of stack | record: %s",
+ record
+ ));
mSessions.add(record);
clearCache(record.getUserId());
@@ -97,6 +103,10 @@
* @param record The record to remove.
*/
public void removeSession(MediaSessionRecordImpl record) {
+ Slog.i(TAG, TextUtils.formatSimple(
+ "removeSession | record: %s",
+ record
+ ));
mSessions.remove(record);
if (mMediaButtonSession == record) {
// When the media button session is removed, nullify the media button session and do not
@@ -142,6 +152,10 @@
public void onPlaybackStateChanged(
MediaSessionRecordImpl record, boolean shouldUpdatePriority) {
if (shouldUpdatePriority) {
+ Slog.i(TAG, TextUtils.formatSimple(
+ "onPlaybackStateChanged - Pushing session to top | record: %s",
+ record
+ ));
mSessions.remove(record);
mSessions.add(0, record);
clearCache(record.getUserId());
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 5f8e01e..9944f12 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -7973,11 +7973,7 @@
return false;
}
}
- // Activity should be resizable if the task is.
- final boolean isResizeable = task != null
- ? task.isResizeable() || isResizeable()
- : isResizeable();
- return !isResizeable && (info.isFixedOrientation() || hasFixedAspectRatio())
+ return !isResizeable() && (info.isFixedOrientation() || hasFixedAspectRatio())
// The configuration of non-standard type should be enforced by system.
// {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} is set when this activity is
// added to a task, but this function is called when resolving the launch params, at
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index 47bdba3..41eb2c9 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -359,12 +359,6 @@
CAMERA_OPENED_ROTATION_UPDATE_DELAY_MS);
}
- private void updateOrientationWithWmLock() {
- synchronized (mWmService.mGlobalLock) {
- mDisplayContent.updateOrientation();
- }
- }
-
private void delayedUpdateOrientationWithWmLock(
@NonNull String cameraId, @NonNull String packageName) {
synchronized (this) {
@@ -375,25 +369,28 @@
}
mCameraIdPackageBiMap.put(packageName, cameraId);
}
- ActivityRecord topActivity = mDisplayContent.topRunningActivity(
- /* considerKeyguardState= */ true);
- if (topActivity == null || topActivity.getTask() == null) {
- return;
- }
- // Checking whether an activity in fullscreen rather than the task as this camera compat
- // treatment doesn't cover activity embedding.
- if (topActivity.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
- if (topActivity.mLetterboxUiController.isOverrideOrientationOnlyForCameraEnabled()) {
- topActivity.recomputeConfiguration();
+ synchronized (mWmService.mGlobalLock) {
+ ActivityRecord topActivity = mDisplayContent.topRunningActivity(
+ /* considerKeyguardState= */ true);
+ if (topActivity == null || topActivity.getTask() == null) {
+ return;
}
- updateOrientationWithWmLock();
- return;
- }
- // Checking that the whole app is in multi-window mode as we shouldn't show toast
- // for the activity embedding case.
- if (topActivity.getTask().getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
- && isTreatmentEnabledForActivity(topActivity, /* mustBeFullscreen */ false)) {
- showToast(R.string.display_rotation_camera_compat_toast_in_split_screen);
+ // Checking whether an activity in fullscreen rather than the task as this camera
+ // compat treatment doesn't cover activity embedding.
+ if (topActivity.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+ if (topActivity.mLetterboxUiController
+ .isOverrideOrientationOnlyForCameraEnabled()) {
+ topActivity.recomputeConfiguration();
+ }
+ mDisplayContent.updateOrientation();
+ return;
+ }
+ // Checking that the whole app is in multi-window mode as we shouldn't show toast
+ // for the activity embedding case.
+ if (topActivity.getTask().getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
+ && isTreatmentEnabledForActivity(topActivity, /* mustBeFullscreen */ false)) {
+ showToast(R.string.display_rotation_camera_compat_toast_in_split_screen);
+ }
}
}
@@ -441,18 +438,20 @@
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is notified that Camera %s is closed, updating rotation.",
mDisplayContent.mDisplayId, cameraId);
- ActivityRecord topActivity = mDisplayContent.topRunningActivity(
- /* considerKeyguardState= */ true);
- if (topActivity == null
- // Checking whether an activity in fullscreen rather than the task as this camera
- // compat treatment doesn't cover activity embedding.
- || topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
- return;
+ synchronized (mWmService.mGlobalLock) {
+ ActivityRecord topActivity = mDisplayContent.topRunningActivity(
+ /* considerKeyguardState= */ true);
+ if (topActivity == null
+ // Checking whether an activity in fullscreen rather than the task as this
+ // camera compat treatment doesn't cover activity embedding.
+ || topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+ return;
+ }
+ if (topActivity.mLetterboxUiController.isOverrideOrientationOnlyForCameraEnabled()) {
+ topActivity.recomputeConfiguration();
+ }
+ mDisplayContent.updateOrientation();
}
- if (topActivity.mLetterboxUiController.isOverrideOrientationOnlyForCameraEnabled()) {
- topActivity.recomputeConfiguration();
- }
- updateOrientationWithWmLock();
}
private boolean isActivityForCameraIdRefreshing(String cameraId) {
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index e1dbe01a..c20a513 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -870,10 +870,9 @@
return mActivityRecord.mWmService.mContext.getResources();
}
- private void handleHorizontalDoubleTap(int x) {
- // TODO(b/260857308): Investigate if enabling reachability for translucent activity
- if (hasInheritedLetterboxBehavior() || !isHorizontalReachabilityEnabled()
- || mActivityRecord.isInTransition()) {
+ @VisibleForTesting
+ void handleHorizontalDoubleTap(int x) {
+ if (!isHorizontalReachabilityEnabled() || mActivityRecord.isInTransition()) {
return;
}
@@ -911,10 +910,9 @@
mActivityRecord.recomputeConfiguration();
}
- private void handleVerticalDoubleTap(int y) {
- // TODO(b/260857308): Investigate if enabling reachability for translucent activity
- if (hasInheritedLetterboxBehavior() || !isVerticalReachabilityEnabled()
- || mActivityRecord.isInTransition()) {
+ @VisibleForTesting
+ void handleVerticalDoubleTap(int y) {
+ if (!isVerticalReachabilityEnabled() || mActivityRecord.isInTransition()) {
return;
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 79be946..2086b52 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1222,7 +1222,7 @@
// Clear last paused activity if focused root task changed while sleeping, so that the
// top activity of current focused task can be resumed.
- if (mDisplayContent.isSleeping()) {
+ if (mDisplayContent.isSleeping() && currentFocusedTask != null) {
currentFocusedTask.clearLastPausedActivity();
}
diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java
index 37f0624..eff9e8d 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -113,7 +113,6 @@
private static final long USAGE_STATS_QUERY_INTERVAL_SEC = 120L;
@VisibleForTesting
static final int MAX_CACHED_RECENT_SHORTCUTS = 30;
- private static final int DEBOUNCE_LENGTH_MS = 500;
private final Context mContext;
private final Injector mInjector;
@@ -130,7 +129,6 @@
private final List<PeopleService.ConversationsListener> mConversationsListeners =
new ArrayList<>(1);
private final Handler mHandler;
- private final PerPackageThrottler mShortcutsThrottler;
private ContentObserver mCallLogContentObserver;
private ContentObserver mMmsSmsContentObserver;
@@ -142,17 +140,14 @@
private ConversationStatusExpirationBroadcastReceiver mStatusExpReceiver;
public DataManager(Context context) {
- this(context, new Injector(), BackgroundThread.get().getLooper(),
- new PerPackageThrottlerImpl(BackgroundThread.getHandler(), DEBOUNCE_LENGTH_MS));
+ this(context, new Injector(), BackgroundThread.get().getLooper());
}
- DataManager(Context context, Injector injector, Looper looper,
- PerPackageThrottler shortcutsThrottler) {
+ DataManager(Context context, Injector injector, Looper looper) {
mContext = context;
mInjector = injector;
mScheduledExecutor = mInjector.createScheduledExecutor();
mHandler = new Handler(looper);
- mShortcutsThrottler = shortcutsThrottler;
}
/** Initialization. Called when the system services are up running. */
@@ -856,12 +851,12 @@
// pair of <package name, conversation info>
List<Pair<String, ConversationInfo>> cachedConvos = new ArrayList<>();
userData.forAllPackages(packageData -> {
- packageData.forAllConversations(conversationInfo -> {
- if (isEligibleForCleanUp(conversationInfo)) {
- cachedConvos.add(
- Pair.create(packageData.getPackageName(), conversationInfo));
- }
- });
+ packageData.forAllConversations(conversationInfo -> {
+ if (isEligibleForCleanUp(conversationInfo)) {
+ cachedConvos.add(
+ Pair.create(packageData.getPackageName(), conversationInfo));
+ }
+ });
});
if (cachedConvos.size() <= targetCachedCount) {
return;
@@ -872,8 +867,8 @@
numToUncache + 1,
Comparator.comparingLong((Pair<String, ConversationInfo> pair) ->
Math.max(
- pair.second.getLastEventTimestamp(),
- pair.second.getCreationTimestamp())).reversed());
+ pair.second.getLastEventTimestamp(),
+ pair.second.getCreationTimestamp())).reversed());
for (Pair<String, ConversationInfo> cached : cachedConvos) {
if (hasActiveNotifications(cached.first, userId, cached.second.getShortcutId())) {
continue;
@@ -1109,35 +1104,26 @@
@Override
public void onShortcutsAddedOrUpdated(@NonNull String packageName,
@NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {
- mShortcutsThrottler.scheduleDebounced(
- new Pair<>(packageName, user.getIdentifier()),
- () -> {
- PackageData packageData = getPackage(packageName, user.getIdentifier());
- List<ShortcutInfo> queriedShortcuts = getShortcuts(packageName,
- user.getIdentifier(), null);
- boolean hasCachedShortcut = false;
- for (ShortcutInfo shortcut : queriedShortcuts) {
- if (ShortcutHelper.isConversationShortcut(
- shortcut, mShortcutServiceInternal, user.getIdentifier())) {
- if (shortcut.isCached()) {
- ConversationInfo info = packageData != null
- ? packageData.getConversationInfo(shortcut.getId())
- : null;
- if (info == null
- || !info.isShortcutCachedForNotification()) {
- hasCachedShortcut = true;
- }
- }
- addOrUpdateConversationInfo(shortcut);
+ mInjector.getBackgroundExecutor().execute(() -> {
+ PackageData packageData = getPackage(packageName, user.getIdentifier());
+ for (ShortcutInfo shortcut : shortcuts) {
+ if (ShortcutHelper.isConversationShortcut(
+ shortcut, mShortcutServiceInternal, user.getIdentifier())) {
+ if (shortcut.isCached()) {
+ ConversationInfo conversationInfo = packageData != null
+ ? packageData.getConversationInfo(shortcut.getId()) : null;
+ if (conversationInfo == null
+ || !conversationInfo.isShortcutCachedForNotification()) {
+ // This is a newly cached shortcut. Clean up the existing cached
+ // shortcuts to ensure the cache size is under the limit.
+ cleanupCachedShortcuts(user.getIdentifier(),
+ MAX_CACHED_RECENT_SHORTCUTS - 1);
}
}
- // Added at least one new conversation. Uncache older existing cached
- // shortcuts to ensure the cache size is under the limit.
- if (hasCachedShortcut) {
- cleanupCachedShortcuts(user.getIdentifier(),
- MAX_CACHED_RECENT_SHORTCUTS);
- }
- });
+ addOrUpdateConversationInfo(shortcut);
+ }
+ }
+ });
}
@Override
diff --git a/services/people/java/com/android/server/people/data/PerPackageThrottler.java b/services/people/java/com/android/server/people/data/PerPackageThrottler.java
deleted file mode 100644
index 3d6cd84..0000000
--- a/services/people/java/com/android/server/people/data/PerPackageThrottler.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.server.people.data;
-
-import android.util.Pair;
-
-/** The interface for throttling expensive runnables per package. */
-interface PerPackageThrottler {
- /**
- * Schedule a runnable to run in the future, and debounce runnables for same {@code pkgUserId}
- * that occur until that future has run.
- */
- void scheduleDebounced(Pair<String, Integer> pkgUserId, Runnable runnable);
-}
diff --git a/services/people/java/com/android/server/people/data/PerPackageThrottlerImpl.java b/services/people/java/com/android/server/people/data/PerPackageThrottlerImpl.java
deleted file mode 100644
index fa5a67b..0000000
--- a/services/people/java/com/android/server/people/data/PerPackageThrottlerImpl.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.server.people.data;
-
-import android.os.Handler;
-import android.util.Pair;
-
-import java.util.HashSet;
-
-/**
- * A class that implements a per-package throttler that prevents a runnable from executing more than
- * once every {@code debounceTime}.
- */
-public class PerPackageThrottlerImpl implements PerPackageThrottler {
- private final Handler mBackgroundHandler;
- private final int mDebounceTime;
- private final HashSet<Pair<String, Integer>> mPkgScheduledTasks = new HashSet<>();
-
- PerPackageThrottlerImpl(Handler backgroundHandler, int debounceTime) {
- mBackgroundHandler = backgroundHandler;
- mDebounceTime = debounceTime;
- }
-
- @Override
- public synchronized void scheduleDebounced(
- Pair<String, Integer> pkgUserId, Runnable runnable) {
- if (mPkgScheduledTasks.contains(pkgUserId)) {
- return;
- }
- mPkgScheduledTasks.add(pkgUserId);
- mBackgroundHandler.postDelayed(() -> {
- synchronized (this) {
- mPkgScheduledTasks.remove(pkgUserId);
- runnable.run();
- }
- }, mDebounceTime);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index 454a23b..a27602d 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -86,7 +86,6 @@
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
-import android.util.Pair;
import android.util.Range;
import com.android.internal.app.ChooserActivity;
@@ -187,7 +186,6 @@
private ShortcutInfo mShortcutInfo;
private TestInjector mInjector;
private TestLooper mLooper;
- private TestPerPackageThrottler mShortcutThrottler;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
@@ -277,9 +275,7 @@
mInjector = new TestInjector();
mLooper = new TestLooper();
- mShortcutThrottler = new TestPerPackageThrottler();
- mDataManager = new DataManager(mContext, mInjector, mLooper.getLooper(),
- mShortcutThrottler);
+ mDataManager = new DataManager(mContext, mInjector, mLooper.getLooper());
mDataManager.initialize();
when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
@@ -287,7 +283,10 @@
mShortcutInfo = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
buildPerson());
- mockGetShortcuts(Collections.singletonList(mShortcutInfo));
+ when(mShortcutServiceInternal.getShortcuts(
+ anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
+ anyInt(), anyInt(), anyInt(), anyInt()))
+ .thenReturn(Collections.singletonList(mShortcutInfo));
verify(mShortcutServiceInternal).addShortcutChangeCallback(
mShortcutChangeCallbackCaptor.capture());
mShortcutChangeCallback = mShortcutChangeCallbackCaptor.getValue();
@@ -973,7 +972,6 @@
buildPerson());
ShortcutInfo shortcut3 = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, "sc3",
buildPerson());
- mockGetShortcuts(List.of(shortcut1, shortcut2, shortcut3));
mShortcutChangeCallback.onShortcutsAddedOrUpdated(TEST_PKG_NAME,
Arrays.asList(shortcut1, shortcut2, shortcut3), UserHandle.of(USER_ID_PRIMARY));
mShortcutChangeCallback.onShortcutsRemoved(TEST_PKG_NAME,
@@ -1225,6 +1223,7 @@
eq(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS));
}
}
+
@Test
public void testUncacheOldestCachedShortcut_missingNotificationEvents() {
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
@@ -1234,7 +1233,6 @@
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, shortcutId,
buildPerson());
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
- mockGetShortcuts(Collections.singletonList(shortcut));
mShortcutChangeCallback.onShortcutsAddedOrUpdated(
TEST_PKG_NAME,
Collections.singletonList(shortcut),
@@ -1254,6 +1252,7 @@
eq(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS));
}
}
+
@Test
public void testUncacheOldestCachedShortcut_legacyConversation() {
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
@@ -1275,7 +1274,6 @@
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, shortcutId,
buildPerson());
shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
- mockGetShortcuts(Collections.singletonList(shortcut));
mShortcutChangeCallback.onShortcutsAddedOrUpdated(
TEST_PKG_NAME,
Collections.singletonList(shortcut),
@@ -1313,8 +1311,7 @@
mDataManager.reportShareTargetEvent(appTargetEvent, intentFilter);
byte[] payload = mDataManager.getBackupPayload(USER_ID_PRIMARY);
- DataManager dataManager = new DataManager(
- mContext, mInjector, mLooper.getLooper(), mShortcutThrottler);
+ DataManager dataManager = new DataManager(mContext, mInjector, mLooper.getLooper());
dataManager.onUserUnlocked(USER_ID_PRIMARY);
dataManager.restore(USER_ID_PRIMARY, payload);
ConversationInfo conversationInfo = dataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY)
@@ -1726,13 +1723,6 @@
return (queryFlags & flag) != 0;
}
- private void mockGetShortcuts(List<ShortcutInfo> shortcutInfoList) {
- when(mShortcutServiceInternal.getShortcuts(
- anyInt(), anyString(), anyLong(), anyString(), any(), any(), any(),
- anyInt(), anyInt(), anyInt(), anyInt()))
- .thenReturn(shortcutInfoList);
- }
-
// "Sends" a notification to a non-customized notification channel - the notification channel
// is something generic like "messages" and the notification has a shortcut id
private void sendGenericNotification() {
@@ -1958,11 +1948,4 @@
return mUsageStatsQueryHelper;
}
}
-
- private static class TestPerPackageThrottler implements PerPackageThrottler {
- @Override
- public void scheduleDebounced(Pair<String, Integer> pkgUserId, Runnable runnable) {
- runnable.run();
- }
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/people/data/PerPackageThrottlerImplTest.java b/services/tests/servicestests/src/com/android/server/people/data/PerPackageThrottlerImplTest.java
deleted file mode 100644
index 672cbb9..0000000
--- a/services/tests/servicestests/src/com/android/server/people/data/PerPackageThrottlerImplTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.server.people.data;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.util.Pair;
-
-import com.android.server.testutils.OffsettableClock;
-import com.android.server.testutils.TestHandler;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-@RunWith(JUnit4.class)
-public class PerPackageThrottlerImplTest {
- private static final int DEBOUNCE_INTERVAL = 500;
- private static final String PKG_ONE = "pkg_one";
- private static final String PKG_TWO = "pkg_two";
- private static final int USER_ID = 10;
-
- private final OffsettableClock mClock = new OffsettableClock.Stopped();
- private final TestHandler mTestHandler = new TestHandler(null, mClock);
- private PerPackageThrottlerImpl mThrottler;
-
- @Before
- public void setUp() {
- mThrottler = new PerPackageThrottlerImpl(mTestHandler, DEBOUNCE_INTERVAL);
- }
-
- @Test
- public void scheduleDebounced() {
- AtomicBoolean pkgOneRan = new AtomicBoolean();
- AtomicBoolean pkgTwoRan = new AtomicBoolean();
-
- mThrottler.scheduleDebounced(new Pair<>(PKG_ONE, USER_ID), () -> pkgOneRan.set(true));
- mThrottler.scheduleDebounced(new Pair<>(PKG_ONE, USER_ID), () -> pkgOneRan.set(true));
- mThrottler.scheduleDebounced(new Pair<>(PKG_TWO, USER_ID), () -> pkgTwoRan.set(true));
- mThrottler.scheduleDebounced(new Pair<>(PKG_TWO, USER_ID), () -> pkgTwoRan.set(true));
-
- assertFalse(pkgOneRan.get());
- assertFalse(pkgTwoRan.get());
- mClock.fastForward(DEBOUNCE_INTERVAL);
- mTestHandler.timeAdvance();
- assertTrue(pkgOneRan.get());
- assertTrue(pkgTwoRan.get());
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 318fff2..117805b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -113,6 +113,8 @@
import org.mockito.ArgumentCaptor;
import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
/**
* Tests for Size Compatibility mode.
@@ -168,6 +170,156 @@
}
@Test
+ public void testHorizontalReachabilityEnabledForTranslucentActivities() {
+ setUpDisplaySizeWithApp(2500, 1000);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ final LetterboxConfiguration config = mWm.mLetterboxConfiguration;
+ config.setTranslucentLetterboxingOverrideEnabled(true);
+ config.setLetterboxHorizontalPositionMultiplier(0.5f);
+ config.setIsHorizontalReachabilityEnabled(true);
+
+ // Opaque activity
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+ addWindowToActivity(mActivity);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+
+ // Translucent Activity
+ final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
+ .setLaunchedFromUid(mActivity.getUid())
+ .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+ .build();
+ doReturn(false).when(translucentActivity).fillsParent();
+ mTask.addChild(translucentActivity);
+
+ spyOn(translucentActivity.mLetterboxUiController);
+ doReturn(true).when(translucentActivity.mLetterboxUiController)
+ .shouldShowLetterboxUi(any());
+
+ addWindowToActivity(translucentActivity);
+ translucentActivity.mRootWindowContainer.performSurfacePlacement();
+
+ final Function<ActivityRecord, Rect> innerBoundsOf =
+ (ActivityRecord a) -> {
+ final Rect bounds = new Rect();
+ a.mLetterboxUiController.getLetterboxInnerBounds(bounds);
+ return bounds;
+ };
+ final Runnable checkLetterboxPositions = () -> assertEquals(innerBoundsOf.apply(mActivity),
+ innerBoundsOf.apply(translucentActivity));
+ final Runnable checkIsLeft = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).left).isEqualTo(0);
+ final Runnable checkIsRight = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).right).isEqualTo(2500);
+ final Runnable checkIsCentered = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).left > 0
+ && innerBoundsOf.apply(translucentActivity).right < 2500).isTrue();
+
+ final Consumer<Integer> doubleClick =
+ (Integer x) -> {
+ mActivity.mLetterboxUiController.handleHorizontalDoubleTap(x);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+ };
+
+ // Initial state
+ checkIsCentered.run();
+
+ // Double-click left
+ doubleClick.accept(/* x */ 10);
+ checkLetterboxPositions.run();
+ checkIsLeft.run();
+
+ // Double-click right
+ doubleClick.accept(/* x */ 1990);
+ checkLetterboxPositions.run();
+ checkIsCentered.run();
+
+ // Double-click right
+ doubleClick.accept(/* x */ 1990);
+ checkLetterboxPositions.run();
+ checkIsRight.run();
+
+ // Double-click left
+ doubleClick.accept(/* x */ 10);
+ checkLetterboxPositions.run();
+ checkIsCentered.run();
+ }
+
+ @Test
+ public void testVerticalReachabilityEnabledForTranslucentActivities() {
+ setUpDisplaySizeWithApp(1000, 2500);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ final LetterboxConfiguration config = mWm.mLetterboxConfiguration;
+ config.setTranslucentLetterboxingOverrideEnabled(true);
+ config.setLetterboxVerticalPositionMultiplier(0.5f);
+ config.setIsVerticalReachabilityEnabled(true);
+
+ // Opaque activity
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+ addWindowToActivity(mActivity);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+
+ // Translucent Activity
+ final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
+ .setLaunchedFromUid(mActivity.getUid())
+ .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+ .build();
+ doReturn(false).when(translucentActivity).fillsParent();
+ mTask.addChild(translucentActivity);
+
+ spyOn(translucentActivity.mLetterboxUiController);
+ doReturn(true).when(translucentActivity.mLetterboxUiController)
+ .shouldShowLetterboxUi(any());
+
+ addWindowToActivity(translucentActivity);
+ translucentActivity.mRootWindowContainer.performSurfacePlacement();
+
+ final Function<ActivityRecord, Rect> innerBoundsOf =
+ (ActivityRecord a) -> {
+ final Rect bounds = new Rect();
+ a.mLetterboxUiController.getLetterboxInnerBounds(bounds);
+ return bounds;
+ };
+ final Runnable checkLetterboxPositions = () -> assertEquals(innerBoundsOf.apply(mActivity),
+ innerBoundsOf.apply(translucentActivity));
+ final Runnable checkIsTop = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).top).isEqualTo(0);
+ final Runnable checkIsBottom = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).bottom).isEqualTo(2500);
+ final Runnable checkIsCentered = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).top > 0
+ && innerBoundsOf.apply(translucentActivity).bottom < 2500).isTrue();
+
+ final Consumer<Integer> doubleClick =
+ (Integer y) -> {
+ mActivity.mLetterboxUiController.handleVerticalDoubleTap(y);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+ };
+
+ // Initial state
+ checkIsCentered.run();
+
+ // Double-click top
+ doubleClick.accept(/* y */ 10);
+ checkLetterboxPositions.run();
+ checkIsTop.run();
+
+ // Double-click bottom
+ doubleClick.accept(/* y */ 1990);
+ checkLetterboxPositions.run();
+ checkIsCentered.run();
+
+ // Double-click bottom
+ doubleClick.accept(/* y */ 1990);
+ checkLetterboxPositions.run();
+ checkIsBottom.run();
+
+ // Double-click top
+ doubleClick.accept(/* y */ 10);
+ checkLetterboxPositions.run();
+ checkIsCentered.run();
+ }
+
+ @Test
public void testApplyStrategyToTranslucentActivities() {
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
setUpDisplaySizeWithApp(2000, 1000);
@@ -809,7 +961,7 @@
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
.setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
.build();
- assertFalse(activity.shouldCreateCompatDisplayInsets());
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
// The non-resizable activity should not be size compat because it is on a resizable task
// in multi-window mode.
@@ -842,7 +994,7 @@
}
@Test
- public void testShouldNotCreateCompatDisplayInsetsWhenRootActivityIsResizeable() {
+ public void testShouldCreateCompatDisplayInsetsWhenUnresizeableAndSupportsSizeChangesFalse() {
setUpDisplaySizeWithApp(1000, 2500);
// Make the task root resizable.
@@ -851,7 +1003,7 @@
// Create an activity on the same task.
final ActivityRecord activity = buildActivityRecord(/* supportsSizeChanges= */false,
RESIZE_MODE_UNRESIZEABLE, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
- assertFalse(activity.shouldCreateCompatDisplayInsets());
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
}
@Test