Merge "Pass transition token to finish() for Keyguard" into udc-dev
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index d87226c..65d4b43 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -77,18 +77,18 @@
private static final String TAG = "CameraAdvancedExtensionSessionImpl";
private final Executor mExecutor;
- private final CameraDevice mCameraDevice;
+ private CameraDevice mCameraDevice;
private final Map<String, CameraMetadataNative> mCharacteristicsMap;
private final long mExtensionClientId;
private final Handler mHandler;
private final HandlerThread mHandlerThread;
private final CameraExtensionSession.StateCallback mCallbacks;
- private final IAdvancedExtenderImpl mAdvancedExtender;
+ private IAdvancedExtenderImpl mAdvancedExtender;
// maps registered camera surfaces to extension output configs
private final HashMap<Surface, CameraOutputConfig> mCameraConfigMap = new HashMap<>();
// maps camera extension output ids to camera registered image readers
private final HashMap<Integer, ImageReader> mReaderMap = new HashMap<>();
- private final RequestProcessor mRequestProcessor = new RequestProcessor();
+ private RequestProcessor mRequestProcessor = new RequestProcessor();
private final int mSessionId;
private Surface mClientRepeatingRequestSurface;
@@ -100,7 +100,7 @@
private final ExtensionSessionStatsAggregator mStatsAggregator;
private boolean mInitialized;
-
+ private boolean mSessionClosed;
// Lock to synchronize cross-thread access to device public interface
final Object mInterfaceLock;
@@ -237,6 +237,7 @@
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mInitialized = false;
+ mSessionClosed = false;
mInitializeHandler = new InitializeSessionHandler();
mSessionId = sessionId;
mInterfaceLock = cameraDevice.mInterfaceLock;
@@ -424,7 +425,7 @@
mSessionProcessor.setParameters(request);
seqId = mSessionProcessor.startRepeating(new RequestCallbackHandler(request,
- executor, listener));
+ executor, listener, mCameraDevice.getId()));
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_ERROR,
"Failed to enable repeating request, extension service failed to respond!");
@@ -452,7 +453,7 @@
mSessionProcessor.setParameters(request);
seqId = mSessionProcessor.startCapture(new RequestCallbackHandler(request,
- executor, listener), isPostviewRequested);
+ executor, listener, mCameraDevice.getId()), isPostviewRequested);
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " +
" to submit capture request, extension service failed to respond!");
@@ -460,8 +461,8 @@
} else if ((mClientRepeatingRequestSurface != null) &&
request.containsTarget(mClientRepeatingRequestSurface)) {
try {
- seqId = mSessionProcessor.startTrigger(request,
- new RequestCallbackHandler(request, executor, listener));
+ seqId = mSessionProcessor.startTrigger(request, new RequestCallbackHandler(
+ request, executor, listener, mCameraDevice.getId()));
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " +
" to submit trigger request, extension service failed to respond!");
@@ -528,6 +529,7 @@
mCaptureSession.stopRepeating();
mSessionProcessor.stopRepeating();
mSessionProcessor.onCaptureSessionEnd();
+ mSessionClosed = true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to stop the repeating request or end the session,"
+ " , extension service does not respond!") ;
@@ -560,6 +562,9 @@
if (mSessionProcessor != null) {
try {
+ if (!mSessionClosed) {
+ mSessionProcessor.onCaptureSessionEnd();
+ }
mSessionProcessor.deInitSession();
} catch (RemoteException e) {
Log.e(TAG, "Failed to de-initialize session processor, extension service"
@@ -584,6 +589,10 @@
mClientRepeatingRequestSurface = null;
mClientCaptureSurface = null;
+ mCaptureSession = null;
+ mRequestProcessor = null;
+ mCameraDevice = null;
+ mAdvancedExtender = null;
}
if (notifyClose && !skipCloseNotification) {
@@ -706,13 +715,16 @@
private final CaptureRequest mClientRequest;
private final Executor mClientExecutor;
private final ExtensionCaptureCallback mClientCallbacks;
+ private final String mCameraId;
private RequestCallbackHandler(@NonNull CaptureRequest clientRequest,
@NonNull Executor clientExecutor,
- @NonNull ExtensionCaptureCallback clientCallbacks) {
+ @NonNull ExtensionCaptureCallback clientCallbacks,
+ @NonNull String cameraId) {
mClientRequest = clientRequest;
mClientExecutor = clientExecutor;
mClientCallbacks = clientCallbacks;
+ mCameraId = cameraId;
}
@Override
@@ -784,7 +796,7 @@
}
result.set(CaptureResult.SENSOR_TIMESTAMP, timestamp);
- TotalCaptureResult totalResult = new TotalCaptureResult(mCameraDevice.getId(), result,
+ TotalCaptureResult totalResult = new TotalCaptureResult(mCameraId, result,
mClientRequest, requestId, timestamp, new ArrayList<>(), mSessionId,
new PhysicalCaptureResultInfo[0]);
final long ident = Binder.clearCallingIdentity();
@@ -1036,14 +1048,20 @@
public int submitBurst(List<Request> requests, IRequestCallback callback) {
int seqId = -1;
try {
- CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback);
- ArrayList<CaptureRequest> captureRequests = new ArrayList<>();
- for (Request request : requests) {
- captureRequests.add(initializeCaptureRequest(mCameraDevice, request,
- mCameraConfigMap));
+ synchronized (mInterfaceLock) {
+ if (!mInitialized) {
+ return seqId;
+ }
+
+ CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback);
+ ArrayList<CaptureRequest> captureRequests = new ArrayList<>();
+ for (Request request : requests) {
+ captureRequests.add(initializeCaptureRequest(mCameraDevice, request,
+ mCameraConfigMap));
+ }
+ seqId = mCaptureSession.captureBurstRequests(captureRequests,
+ new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback);
}
- seqId = mCaptureSession.captureBurstRequests(captureRequests,
- new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback);
} catch (CameraAccessException e) {
Log.e(TAG, "Failed to submit capture requests!");
} catch (IllegalStateException e) {
@@ -1057,11 +1075,17 @@
public int setRepeating(Request request, IRequestCallback callback) {
int seqId = -1;
try {
- CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice,
+ synchronized (mInterfaceLock) {
+ if (!mInitialized) {
+ return seqId;
+ }
+
+ CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice,
request, mCameraConfigMap);
- CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback);
- seqId = mCaptureSession.setSingleRepeatingRequest(repeatingRequest,
- new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback);
+ CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback);
+ seqId = mCaptureSession.setSingleRepeatingRequest(repeatingRequest,
+ new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback);
+ }
} catch (CameraAccessException e) {
Log.e(TAG, "Failed to enable repeating request!");
} catch (IllegalStateException e) {
@@ -1074,7 +1098,13 @@
@Override
public void abortCaptures() {
try {
- mCaptureSession.abortCaptures();
+ synchronized (mInterfaceLock) {
+ if (!mInitialized) {
+ return;
+ }
+
+ mCaptureSession.abortCaptures();
+ }
} catch (CameraAccessException e) {
Log.e(TAG, "Failed during capture abort!");
} catch (IllegalStateException e) {
@@ -1085,7 +1115,13 @@
@Override
public void stopRepeating() {
try {
- mCaptureSession.stopRepeating();
+ synchronized (mInterfaceLock) {
+ if (!mInitialized) {
+ return;
+ }
+
+ mCaptureSession.stopRepeating();
+ }
} catch (CameraAccessException e) {
Log.e(TAG, "Failed during repeating capture stop!");
} catch (IllegalStateException e) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
index f9aa1bd..1e6e503 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
@@ -239,7 +239,7 @@
// display state, so we have to look through all displays to match the address
final Display[] displays = mDisplayManager.getDisplays(
DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
- final Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+
for (int i = 0; i < displays.length; i++) {
DisplayAddress.Physical address =
@@ -255,6 +255,8 @@
// TODO(b/287170025): This should be something like if (!rearDisplay.isEnabled)
// instead. Currently when the rear display is disabled, its state is STATE_OFF.
if (rearDisplay.getDisplayId() != Display.DEFAULT_DISPLAY) {
+ final Display defaultDisplay = mDisplayManager
+ .getDisplay(Display.DEFAULT_DISPLAY);
rotateRearDisplayMetricsIfNeeded(defaultDisplay.getRotation(),
rearDisplay.getRotation(), rearDisplayMetrics);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index acbdbf9..cff3172 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -710,4 +710,19 @@
static DesktopModeTaskRepository provideDesktopModeTaskRepository() {
return new DesktopModeTaskRepository();
}
+
+ //
+ // Misc
+ //
+
+ // TODO: Temporarily move dependencies to this instead of ShellInit since that is needed to add
+ // the callback. We will be moving to a different explicit startup mechanism in a follow- up CL.
+ @WMSingleton
+ @ShellCreateTriggerOverride
+ @Provides
+ static Object provideIndependentShellComponentsToCreate(
+ DefaultMixedHandler defaultMixedHandler,
+ Optional<DesktopModeController> desktopModeController) {
+ return new Object();
+ }
}
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 da14d03..964ba9f 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
@@ -2365,6 +2365,11 @@
prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, out);
}
}
+
+ // When split in the background, it should be only opening/dismissing transition and
+ // would keep out not empty. Prevent intercepting all transitions for split screen when
+ // it is in the background and not identify to handle it.
+ return (!out.isEmpty() || isSplitScreenVisible()) ? out : null;
} else {
if (isOpening && getStageOfTask(triggerTask) != null) {
// One task is appearing into split, prepare to enter split screen.
@@ -2373,8 +2378,8 @@
mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering);
}
+ return out;
}
- return out;
}
/**
@@ -2506,8 +2511,9 @@
&& getStageType(dismissStages.valueAt(0)) == STAGE_TYPE_MAIN)
|| mMainStage.getChildCount() == 0 ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
// If there is a fullscreen opening change, we should not bring stage to top.
- prepareExitSplitScreen(record.mContainShowFullscreenChange
- ? STAGE_TYPE_UNDEFINED : dismissTop, wct);
+ prepareExitSplitScreen(
+ !record.mContainShowFullscreenChange && isSplitScreenVisible()
+ ? dismissTop : STAGE_TYPE_UNDEFINED, wct);
mSplitTransitions.startDismissTransition(wct, this, dismissTop,
EXIT_REASON_APP_FINISHED);
// This can happen in some pathological cases. For example:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 1d7c35d..7a0a24a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -104,7 +104,7 @@
case PROMPT_REASON_DEVICE_ADMIN:
return R.string.kg_prompt_reason_device_admin;
case PROMPT_REASON_USER_REQUEST:
- return R.string.kg_prompt_reason_user_request;
+ return R.string.kg_prompt_after_user_lockdown_password;
case PROMPT_REASON_PREPARE_FOR_UPDATE:
return R.string.kg_prompt_reason_timeout_password;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 64b1c50..be42376 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -311,7 +311,7 @@
resId = R.string.kg_prompt_reason_device_admin;
break;
case PROMPT_REASON_USER_REQUEST:
- resId = R.string.kg_prompt_reason_user_request;
+ resId = R.string.kg_prompt_after_user_lockdown_pattern;
break;
case PROMPT_REASON_PREPARE_FOR_UPDATE:
resId = R.string.kg_prompt_reason_timeout_pattern;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 5cb2c5c..687436c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -118,7 +118,7 @@
case PROMPT_REASON_DEVICE_ADMIN:
return R.string.kg_prompt_reason_device_admin;
case PROMPT_REASON_USER_REQUEST:
- return R.string.kg_prompt_reason_user_request;
+ return R.string.kg_prompt_after_user_lockdown_pin;
case PROMPT_REASON_PREPARE_FOR_UPDATE:
return R.string.kg_prompt_reason_timeout_pin;
case PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT:
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index da7bf4e..3f20540 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -266,7 +266,7 @@
/** Flag meant to guard the talkback fix for the KeyguardIndicationTextView */
// TODO(b/286563884): Tracking bug
@JvmField
- val KEYGUARD_TALKBACK_FIX = unreleasedFlag(238, "keyguard_talkback_fix")
+ val KEYGUARD_TALKBACK_FIX = releasedFlag(238, "keyguard_talkback_fix")
// 300 - power menu
// TODO(b/254512600): Tracking Bug
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 97244c8..5bf56a1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -33,6 +33,7 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
@@ -848,6 +849,8 @@
return KeyguardSecurityView.PROMPT_REASON_RESTART;
} else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
} else if ((strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
} else if (trustAgentsEnabled
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index b96ca7a..3b32313e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -224,7 +224,6 @@
return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION;
}
});
- controller.overrideIconTintForNavMode(true);
return controller;
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
index 3eec7fa0e..ff57a73 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
@@ -39,19 +39,12 @@
* [cutout]. We don't show battery estimation in qqs header on the devices with center cutout.
* The result might be null when the battery icon is invisible during the qs-qqs transition
* animation.
+ *
+ * Note: short-circuiting this value until a comprehensive fix for b/282044659 is finished.
*/
@BatteryMeterView.BatteryPercentMode
fun getBatteryMode(cutout: DisplayCutout?, qsExpandedFraction: Float): Int? =
- when {
- qsExpandedFraction > fadeInStartFraction -> BatteryMeterView.MODE_ESTIMATE
- qsExpandedFraction < fadeOutCompleteFraction ->
- if (hasCenterCutout(cutout)) {
- BatteryMeterView.MODE_ON
- } else {
- BatteryMeterView.MODE_ESTIMATE
- }
- else -> null
- }
+ BatteryMeterView.MODE_ON
fun updateResources() {
fadeInStartFraction =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 1cd0f08..648ece5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -475,6 +475,13 @@
*/
private boolean mShouldDelayWakeUpAnimation = false;
+ /**
+ * Whether we should delay the AOD->Lockscreen animation.
+ * If false, the animation will start in onStartedWakingUp().
+ * If true, the animation will start in onFinishedWakingUp().
+ */
+ private boolean mShouldDelayLockscreenTransitionFromAod = false;
+
private final Object mQueueLock = new Object();
private final PulseExpansionHandler mPulseExpansionHandler;
@@ -3242,7 +3249,10 @@
updateVisibleToUser();
updateIsKeyguard();
- if (!mFeatureFlags.isEnabled(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD)) {
+ mShouldDelayLockscreenTransitionFromAod = mDozeParameters.getAlwaysOn()
+ && mFeatureFlags.isEnabled(
+ Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD);
+ if (!mShouldDelayLockscreenTransitionFromAod) {
startLockscreenTransitionFromAod();
}
});
@@ -3251,8 +3261,7 @@
/**
* Private helper for starting the LOCKSCREEN_TRANSITION_FROM_AOD animation - only necessary
- * so we can start it from either onFinishedWakingUp() or onFinishedWakingUp() depending
- * on a flag value.
+ * so we can start it from either onFinishedWakingUp() or onFinishedWakingUp().
*/
private void startLockscreenTransitionFromAod() {
// stopDozing() starts the LOCKSCREEN_TRANSITION_FROM_AOD animation.
@@ -3273,7 +3282,7 @@
@Override
public void onFinishedWakingUp() {
- if (mFeatureFlags.isEnabled(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD)) {
+ if (mShouldDelayLockscreenTransitionFromAod) {
mNotificationShadeWindowController.batchApplyWindowLayoutParams(
this::startLockscreenTransitionFromAod);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index 7bc4fc3..ae70384 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -115,7 +115,6 @@
};
private final Context mContext;
- private Boolean mOverrideIconTintForNavMode;
@AssistedInject
public LightBarTransitionsController(
@@ -276,19 +275,11 @@
}
/**
- * Specify an override value to return for {@link #overrideIconTintForNavMode(boolean)}.
- */
- public void overrideIconTintForNavMode(boolean overrideValue) {
- mOverrideIconTintForNavMode = overrideValue;
- }
- /**
* Return whether to use the tint calculated in this class for nav icons.
*/
public boolean supportsIconTintForNavMode(int navigationMode) {
// In gesture mode, we already do region sampling to update tint based on content beneath.
- return mOverrideIconTintForNavMode != null
- ? mOverrideIconTintForNavMode
- : !QuickStepContract.isGesturalMode(navigationMode);
+ return !QuickStepContract.isGesturalMode(navigationMode);
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 1f353e1..8a422c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -21,6 +21,7 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -356,6 +357,42 @@
}
@Test
+ public void testBouncerPrompt_afterUserLockDown() {
+ // GIVEN biometrics enrolled
+ when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(true);
+
+ // WHEN user has locked down the device
+ KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
+ mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
+ when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
+ when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+ when(strongAuthTracker.getStrongAuthForUser(anyInt()))
+ .thenReturn(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+
+ // THEN the bouncer prompt reason should return PROMPT_REASON_USER_REQUEST
+ assertEquals(KeyguardSecurityView.PROMPT_REASON_USER_REQUEST,
+ mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
+ }
+
+ @Test
+ public void testBouncerPrompt_afterUserLockDown_noBiometricsEnrolled() {
+ // GIVEN biometrics not enrolled
+ when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(false);
+
+ // WHEN user has locked down the device
+ KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
+ mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
+ when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
+ when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+ when(strongAuthTracker.getStrongAuthForUser(anyInt()))
+ .thenReturn(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+
+ // THEN the bouncer prompt reason should return the default prompt
+ assertEquals(KeyguardSecurityView.PROMPT_REASON_NONE,
+ mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
+ }
+
+ @Test
public void testBouncerPrompt_nonStrongIdleTimeout() {
// GIVEN trust agents enabled and biometrics are enrolled
when(mUpdateMonitor.isTrustUsuallyManaged(anyInt())).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
index d421aca..b028f1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
@@ -63,36 +63,40 @@
@Test
fun returnsMODE_ESTIMATEforQsWithCenterCutout() {
+ // TODO (b/282044659): revert this test to previous behavior
assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction()))
- .isEqualTo(BatteryMeterView.MODE_ESTIMATE)
+ .isEqualTo(BatteryMeterView.MODE_ON)
}
@Test
fun returnsMODE_ONforQqsWithCornerCutout() {
whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true)
+ // TODO (b/282044659): revert this test to previous behavior
assertThat(
controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.prevFrameToFraction())
)
- .isEqualTo(BatteryMeterView.MODE_ESTIMATE)
+ .isEqualTo(BatteryMeterView.MODE_ON)
}
@Test
fun returnsMODE_ESTIMATEforQsWithCornerCutout() {
whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true)
+ // TODO (b/282044659): revert this test to previous behavior
assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction()))
- .isEqualTo(BatteryMeterView.MODE_ESTIMATE)
+ .isEqualTo(BatteryMeterView.MODE_ON)
}
@Test
fun returnsNullInBetween() {
+ // TODO (b/282044659): revert this test to previous behavior
assertThat(
controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.nextFrameToFraction())
)
- .isNull()
+ .isEqualTo(BatteryMeterView.MODE_ON)
assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.prevFrameToFraction()))
- .isNull()
+ .isEqualTo(BatteryMeterView.MODE_ON)
}
private fun Int.prevFrameToFraction(): Float = (this - 1) / MOTION_LAYOUT_MAX_FRAME.toFloat()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 8062272..7702630 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -350,7 +350,9 @@
// For the Shade to animate during the Back gesture, we must enable the animation flag.
mFeatureFlags.set(Flags.WM_SHADE_ANIMATE_BACK_GESTURE, true);
mFeatureFlags.set(Flags.LIGHT_REVEAL_MIGRATION, true);
+ // Turn AOD on and toggle feature flag for jank fixes
mFeatureFlags.set(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD, true);
+ when(mDozeParameters.getAlwaysOn()).thenReturn(true);
IThermalService thermalService = mock(IThermalService.class);
mPowerManager = new PowerManager(mContext, mPowerManagerService, thermalService,
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 33e21f1..03d1fbb 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -1608,11 +1608,15 @@
refreshProcessQueuesLocked(uid);
}
}
+ }, ActivityManager.UID_OBSERVER_PROCSTATE,
+ ActivityManager.PROCESS_STATE_TOP, "android");
+ mService.registerUidObserver(new UidObserver() {
@Override
- public void onUidCachedChanged(int uid, boolean cached) {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) {
synchronized (mService) {
- if (cached) {
+ if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
mUidCached.put(uid, true);
} else {
mUidCached.delete(uid);
@@ -1620,8 +1624,8 @@
refreshProcessQueuesLocked(uid);
}
}
- }, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_CACHED,
- ActivityManager.PROCESS_STATE_TOP, "android");
+ }, ActivityManager.UID_OBSERVER_PROCSTATE,
+ ActivityManager.PROCESS_STATE_LAST_ACTIVITY, "android");
// Kick off periodic health checks
mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH);
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 7773190..eccff2a 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -123,7 +123,14 @@
"freeze_debounce_timeout";
@VisibleForTesting static final String KEY_FREEZER_EXEMPT_INST_PKG =
"freeze_exempt_inst_pkg";
-
+ @VisibleForTesting static final String KEY_FREEZER_BINDER_ENABLED =
+ "freeze_binder_enabled";
+ @VisibleForTesting static final String KEY_FREEZER_BINDER_DIVISOR =
+ "freeze_binder_divisor";
+ @VisibleForTesting static final String KEY_FREEZER_BINDER_OFFSET =
+ "freeze_binder_offset";
+ @VisibleForTesting static final String KEY_FREEZER_BINDER_THRESHOLD =
+ "freeze_binder_threshold";
static final int UNFREEZE_REASON_NONE =
FrameworkStatsLog.APP_FREEZE_CHANGED__UNFREEZE_REASON_V2__UFR_NONE;
@@ -237,8 +244,8 @@
@VisibleForTesting static final boolean ENABLE_FILE_COMPACT = false;
// Defaults for phenotype flags.
- @VisibleForTesting static final Boolean DEFAULT_USE_COMPACTION = true;
- @VisibleForTesting static final Boolean DEFAULT_USE_FREEZER = true;
+ @VisibleForTesting static final boolean DEFAULT_USE_COMPACTION = true;
+ @VisibleForTesting static final boolean DEFAULT_USE_FREEZER = true;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_1 = 5_000;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_2 = 10_000;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_3 = 500;
@@ -257,7 +264,11 @@
@VisibleForTesting static final String DEFAULT_COMPACT_PROC_STATE_THROTTLE =
String.valueOf(ActivityManager.PROCESS_STATE_RECEIVER);
@VisibleForTesting static final long DEFAULT_FREEZER_DEBOUNCE_TIMEOUT = 10_000L;
- @VisibleForTesting static final Boolean DEFAULT_FREEZER_EXEMPT_INST_PKG = true;
+ @VisibleForTesting static final boolean DEFAULT_FREEZER_EXEMPT_INST_PKG = true;
+ @VisibleForTesting static final boolean DEFAULT_FREEZER_BINDER_ENABLED = true;
+ @VisibleForTesting static final long DEFAULT_FREEZER_BINDER_DIVISOR = 4;
+ @VisibleForTesting static final int DEFAULT_FREEZER_BINDER_OFFSET = 500;
+ @VisibleForTesting static final long DEFAULT_FREEZER_BINDER_THRESHOLD = 1_000;
@VisibleForTesting static final Uri CACHED_APP_FREEZER_ENABLED_URI = Settings.Global.getUriFor(
Settings.Global.CACHED_APPS_FREEZER_ENABLED);
@@ -393,6 +404,11 @@
updateFreezerDebounceTimeout();
} else if (KEY_FREEZER_EXEMPT_INST_PKG.equals(name)) {
updateFreezerExemptInstPkg();
+ } else if (KEY_FREEZER_BINDER_ENABLED.equals(name)
+ || KEY_FREEZER_BINDER_DIVISOR.equals(name)
+ || KEY_FREEZER_BINDER_THRESHOLD.equals(name)
+ || KEY_FREEZER_BINDER_OFFSET.equals(name)) {
+ updateFreezerBinderState();
}
}
}
@@ -455,6 +471,16 @@
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting final Set<Integer> mProcStateThrottle;
+ @GuardedBy("mPhenotypeFlagLock")
+ @VisibleForTesting volatile boolean mFreezerBinderEnabled = DEFAULT_FREEZER_BINDER_ENABLED;
+ @GuardedBy("mPhenotypeFlagLock")
+ @VisibleForTesting volatile long mFreezerBinderDivisor = DEFAULT_FREEZER_BINDER_DIVISOR;
+ @GuardedBy("mPhenotypeFlagLock")
+ @VisibleForTesting volatile int mFreezerBinderOffset = DEFAULT_FREEZER_BINDER_OFFSET;
+ @GuardedBy("mPhenotypeFlagLock")
+ @VisibleForTesting volatile long mFreezerBinderThreshold = DEFAULT_FREEZER_BINDER_THRESHOLD;
+
+
// Handler on which compaction runs.
@VisibleForTesting
Handler mCompactionHandler;
@@ -759,6 +785,10 @@
pw.println(" " + KEY_FREEZER_STATSD_SAMPLE_RATE + "=" + mFreezerStatsdSampleRate);
pw.println(" " + KEY_FREEZER_DEBOUNCE_TIMEOUT + "=" + mFreezerDebounceTimeout);
pw.println(" " + KEY_FREEZER_EXEMPT_INST_PKG + "=" + mFreezerExemptInstPkg);
+ pw.println(" " + KEY_FREEZER_BINDER_ENABLED + "=" + mFreezerBinderEnabled);
+ pw.println(" " + KEY_FREEZER_BINDER_THRESHOLD + "=" + mFreezerBinderThreshold);
+ pw.println(" " + KEY_FREEZER_BINDER_DIVISOR + "=" + mFreezerBinderDivisor);
+ pw.println(" " + KEY_FREEZER_BINDER_OFFSET + "=" + mFreezerBinderOffset);
synchronized (mProcLock) {
int size = mFrozenProcesses.size();
pw.println(" Apps frozen: " + size);
@@ -1264,6 +1294,26 @@
Slog.d(TAG_AM, "Freezer exemption set to " + mFreezerExemptInstPkg);
}
+ @GuardedBy("mPhenotypeFlagLock")
+ private void updateFreezerBinderState() {
+ mFreezerBinderEnabled = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ KEY_FREEZER_BINDER_ENABLED, DEFAULT_FREEZER_BINDER_ENABLED);
+ mFreezerBinderDivisor = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ KEY_FREEZER_BINDER_DIVISOR, DEFAULT_FREEZER_BINDER_DIVISOR);
+ mFreezerBinderOffset = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ KEY_FREEZER_BINDER_OFFSET, DEFAULT_FREEZER_BINDER_OFFSET);
+ mFreezerBinderThreshold = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ KEY_FREEZER_BINDER_THRESHOLD, DEFAULT_FREEZER_BINDER_THRESHOLD);
+ Slog.d(TAG_AM, "Freezer binder state set to enabled=" + mFreezerBinderEnabled
+ + ", divisor=" + mFreezerBinderDivisor
+ + ", offset=" + mFreezerBinderOffset
+ + ", threshold=" + mFreezerBinderThreshold);
+ }
+
private boolean parseProcStateThrottle(String procStateThrottleString) {
String[] procStates = TextUtils.split(procStateThrottleString, ",");
mProcStateThrottle.clear();
@@ -1352,6 +1402,7 @@
}
}
}
+ app.mOptRecord.setLastUsedTimeout(delayMillis);
mFreezeHandler.sendMessageDelayed(
mFreezeHandler.obtainMessage(SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app),
delayMillis);
@@ -1525,10 +1576,14 @@
opt.setPendingFreeze(false);
}
- UidRecord uidRec = app.getUidRecord();
- if (uidRec != null && uidRec.isFrozen()) {
- uidRec.setFrozen(false);
- postUidFrozenMessage(uidRec.getUid(), false);
+ final UidRecord uidRec = app.getUidRecord();
+ if (uidRec != null) {
+ final boolean isFrozen = uidRec.getNumOfProcs() > 1
+ && uidRec.areAllProcessesFrozen(app);
+ if (isFrozen != uidRec.isFrozen()) {
+ uidRec.setFrozen(isFrozen);
+ postUidFrozenMessage(uidRec.getUid(), isFrozen);
+ }
}
mFrozenProcesses.delete(app.getPid());
@@ -2117,12 +2172,54 @@
}
@GuardedBy({"mAm", "mProcLock"})
- private void rescheduleFreeze(final ProcessRecord proc, final String reason,
- @UnfreezeReason int reasonCode) {
+ private void handleBinderFreezerFailure(final ProcessRecord proc, final String reason) {
+ if (!mFreezerBinderEnabled) {
+ // Just reschedule indefinitely.
+ unfreezeAppLSP(proc, UNFREEZE_REASON_BINDER_TXNS);
+ freezeAppAsyncLSP(proc);
+ return;
+ }
+ /*
+ * This handles the case where a process couldn't be frozen due to pending binder
+ * transactions. In order to prevent apps from avoiding the freezer by spamming binder
+ * transactions, there is an exponential decrease in freezer retry times plus a random
+ * offset per attempt to avoid phase issues. Once the last-attempted timeout is below a
+ * threshold, we assume that the app is spamming binder calls and can never be frozen,
+ * and we will then crash the app.
+ */
+ if (proc.mOptRecord.getLastUsedTimeout() <= mFreezerBinderThreshold) {
+ // We've given the app plenty of chances, assume broken. Time to die.
+ Slog.d(TAG_AM, "Kill app due to repeated failure to freeze binder: "
+ + proc.getPid() + " " + proc.processName);
+ mAm.mHandler.post(() -> {
+ synchronized (mAm) {
+ // Crash regardless of procstate in case the app has found another way
+ // to abuse oom_adj
+ if (proc.getThread() == null) {
+ return;
+ }
+ proc.killLocked("excessive binder traffic during cached",
+ ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE,
+ ApplicationExitInfo.SUBREASON_EXCESSIVE_CPU,
+ true);
+ }
+ });
+ return;
+ }
+
+ long timeout = proc.mOptRecord.getLastUsedTimeout() / mFreezerBinderDivisor;
+ // range is [-mFreezerBinderOffset, +mFreezerBinderOffset]
+ int offset = mRandom.nextInt(mFreezerBinderOffset * 2) - mFreezerBinderOffset;
+ timeout = Math.max(timeout + offset, mFreezerBinderThreshold);
+
Slog.d(TAG_AM, "Reschedule freeze for process " + proc.getPid()
- + " " + proc.processName + " (" + reason + ")");
- unfreezeAppLSP(proc, reasonCode);
- freezeAppAsyncLSP(proc);
+ + " " + proc.processName + " (" + reason + "), timeout=" + timeout);
+ Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_FREEZER_TRACK,
+ "Reschedule freeze " + proc.processName + ":" + proc.getPid()
+ + " timeout=" + timeout + ", reason=" + reason);
+
+ unfreezeAppLSP(proc, UNFREEZE_REASON_BINDER_TXNS);
+ freezeAppAsyncLSP(proc, timeout);
}
/**
@@ -2169,7 +2266,7 @@
// transactions that might be pending.
try {
if (freezeBinder(pid, true, FREEZE_BINDER_TIMEOUT_MS) != 0) {
- rescheduleFreeze(proc, "outstanding txns", UNFREEZE_REASON_BINDER_TXNS);
+ handleBinderFreezerFailure(proc, "outstanding txns");
return;
}
} catch (RuntimeException e) {
@@ -2230,7 +2327,7 @@
if ((freezeInfo & TXNS_PENDING_WHILE_FROZEN) != 0) {
synchronized (mProcLock) {
- rescheduleFreeze(proc, "new pending txns", UNFREEZE_REASON_BINDER_TXNS);
+ handleBinderFreezerFailure(proc, "new pending txns");
}
return;
}
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index ffe5a6e..f5c5ea8 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -127,6 +127,12 @@
@GuardedBy("mProcLock")
private @UptimeMillisLong long mEarliestFreezableTimeMillis;
+ /**
+ * This is the most recently used timeout for freezing the app in millis
+ */
+ @GuardedBy("mProcLock")
+ private long mLastUsedTimeout;
+
@GuardedBy("mProcLock")
long getLastCompactTime() {
return mLastCompactTime;
@@ -282,6 +288,16 @@
}
@GuardedBy("mProcLock")
+ long getLastUsedTimeout() {
+ return mLastUsedTimeout;
+ }
+
+ @GuardedBy("mProcLock")
+ void setLastUsedTimeout(long lastUsedTimeout) {
+ mLastUsedTimeout = lastUsedTimeout;
+ }
+
+ @GuardedBy("mProcLock")
boolean isFreezeExempt() {
return mFreezeExempt;
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 993088e..4329afc 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -345,21 +345,32 @@
}
/**
+ * Check whether all processes in the Uid are frozen.
+ *
+ * @param excluding Skip this process record during the check.
* @return true if all processes in the Uid are frozen, false otherwise.
*/
@GuardedBy(anyOf = {"mService", "mProcLock"})
- public boolean areAllProcessesFrozen() {
+ public boolean areAllProcessesFrozen(ProcessRecord excluding) {
for (int i = mProcRecords.size() - 1; i >= 0; i--) {
final ProcessRecord app = mProcRecords.valueAt(i);
final ProcessCachedOptimizerRecord opt = app.mOptRecord;
- if (!opt.isFrozen()) {
+ if (excluding != app && !opt.isFrozen()) {
return false;
}
}
return true;
}
+ /**
+ * @return true if all processes in the Uid are frozen, false otherwise.
+ */
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
+ public boolean areAllProcessesFrozen() {
+ return areAllProcessesFrozen(null);
+ }
+
@GuardedBy(anyOf = {"mService", "mProcLock"})
public void setFrozen(boolean frozen) {
mUidIsFrozen = frozen;
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index ec85d57..0c7f11f 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1199,11 +1199,16 @@
AudioDeviceInfo device = Stream.of(connectedDevices)
.filter(d -> d.getInternalType() == ada.getInternalType())
.filter(d -> (!AudioSystem.isBluetoothDevice(d.getInternalType())
- || (d.getAddress() == ada.getAddress())))
+ || (d.getAddress().equals(ada.getAddress()))))
.findFirst()
.orElse(null);
if (device == null) {
+ if (AudioService.DEBUG_DEVICES) {
+ Slog.i(TAG, "purgeRoles() removing device: " + ada.toString()
+ + ", for strategy: " + keyRole.first
+ + " and role: " + keyRole.second);
+ }
asi.deviceRoleAction(keyRole.first, keyRole.second, Arrays.asList(ada));
itDev.remove();
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d29d9c8..488745c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -8718,13 +8718,7 @@
ToastRecord lastToast = mToastQueue.remove(index);
- mWindowManagerInternal.removeWindowToken(lastToast.windowToken, false /* removeWindows */,
- lastToast.displayId);
- // We passed 'false' for 'removeWindows' so that the client has time to stop
- // rendering (as hide above is a one-way message), otherwise we could crash
- // a client which was actively using a surface made from the token. However
- // we need to schedule a timeout to make sure the token is eventually killed
- // one way or another.
+ // We need to schedule a timeout to make sure the token is eventually killed
scheduleKillTokenTimeout(lastToast);
keepProcessAliveForToastIfNeededLocked(record.pid);
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index abfc1d7..78f1fa6 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4311,7 +4311,12 @@
if (Process.isIsolatedUid(uid)
&& mPermissionManager.getHotwordDetectionServiceProvider() != null
&& uid == mPermissionManager.getHotwordDetectionServiceProvider().getUid()) {
- uid = getIsolatedOwner(uid);
+ try {
+ uid = getIsolatedOwner(uid);
+ } catch (IllegalStateException e) {
+ // If the owner uid doesn't exist, just use the current uid
+ Slog.wtf(TAG, "Expected isolated uid " + uid + " to have an owner", e);
+ }
}
final int callingUserId = UserHandle.getUserId(callingUid);
final int appId = UserHandle.getAppId(uid);
@@ -4352,7 +4357,12 @@
if (Process.isIsolatedUid(uid)
&& mPermissionManager.getHotwordDetectionServiceProvider() != null
&& uid == mPermissionManager.getHotwordDetectionServiceProvider().getUid()) {
- uid = getIsolatedOwner(uid);
+ try {
+ uid = getIsolatedOwner(uid);
+ } catch (IllegalStateException e) {
+ // If the owner uid doesn't exist, just use the current uid
+ Slog.wtf(TAG, "Expected isolated uid " + uid + " to have an owner", e);
+ }
}
final int appId = UserHandle.getAppId(uid);
final Object obj = mSettings.getSettingBase(appId);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index e7a94c0..7a88069 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -172,6 +172,7 @@
BroadcastConstants mConstants;
private BroadcastSkipPolicy mSkipPolicy;
private UidObserver mUidObserver;
+ private UidObserver mUidCachedStateObserver;
/**
* Desired behavior of the next
@@ -317,7 +318,13 @@
doAnswer((invocation) -> {
mUidObserver = invocation.getArgument(0);
return null;
- }).when(mAms).registerUidObserver(any(), anyInt(), anyInt(), any());
+ }).when(mAms).registerUidObserver(any(), anyInt(),
+ eq(ActivityManager.PROCESS_STATE_TOP), any());
+ doAnswer((invocation) -> {
+ mUidCachedStateObserver = invocation.getArgument(0);
+ return null;
+ }).when(mAms).registerUidObserver(any(), anyInt(),
+ eq(ActivityManager.PROCESS_STATE_LAST_ACTIVITY), any());
mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS);
mConstants.TIMEOUT = 100;
@@ -1762,8 +1769,12 @@
final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW);
final ProcessRecord receiverOrangeApp = makeActiveProcessRecord(PACKAGE_ORANGE);
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), true);
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), true);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_GREEN),
+ ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_BLUE),
+ ActivityManager.PROCESS_STATE_CACHED_EMPTY, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
final BroadcastOptions opts = BroadcastOptions.makeBasic()
@@ -1807,12 +1818,16 @@
eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any());
// Shift blue to be active and confirm that deferred broadcast is delivered
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), false);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_BLUE),
+ ActivityManager.PROCESS_STATE_TOP, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
waitForIdle();
verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick);
// Shift green to be active and confirm that deferred broadcast is delivered
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_GREEN),
+ ActivityManager.PROCESS_STATE_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
waitForIdle();
verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick);
}
@@ -2237,9 +2252,15 @@
final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW);
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), true);
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), true);
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_YELLOW), false);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_GREEN),
+ ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_BLUE),
+ ActivityManager.PROCESS_STATE_CACHED_EMPTY, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_YELLOW),
+ ActivityManager.PROCESS_STATE_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
final BroadcastOptions opts = BroadcastOptions.makeBasic()
@@ -2262,7 +2283,9 @@
verifyScheduleRegisteredReceiver(times(1), receiverYellowApp, airplane);
// Shift green to be active and confirm that deferred broadcast is delivered
- mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false);
+ mUidCachedStateObserver.onUidStateChanged(getUidForPackage(PACKAGE_GREEN),
+ ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
waitForIdle();
verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane);
}