diff options
8 files changed, 150 insertions, 24 deletions
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index a390db2e9644..1ee33660cc62 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -868,6 +868,94 @@ public class ViewDebug { return null; } + private static class StreamingPictureCallbackHandler implements AutoCloseable, + HardwareRenderer.PictureCapturedCallback, Runnable { + private final HardwareRenderer mRenderer; + private final Callable<OutputStream> mCallback; + private final Executor mExecutor; + private final ReentrantLock mLock = new ReentrantLock(false); + private final ArrayDeque<byte[]> mQueue = new ArrayDeque<>(3); + private final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream(); + private boolean mStopListening; + private Thread mRenderThread; + + private StreamingPictureCallbackHandler(HardwareRenderer renderer, + Callable<OutputStream> callback, Executor executor) { + mRenderer = renderer; + mCallback = callback; + mExecutor = executor; + mRenderer.setPictureCaptureCallback(this); + } + + @Override + public void close() { + mLock.lock(); + mStopListening = true; + mLock.unlock(); + mRenderer.setPictureCaptureCallback(null); + } + + @Override + public void onPictureCaptured(Picture picture) { + mLock.lock(); + if (mStopListening) { + mLock.unlock(); + mRenderer.setPictureCaptureCallback(null); + return; + } + if (mRenderThread == null) { + mRenderThread = Thread.currentThread(); + } + boolean needsInvoke = true; + if (mQueue.size() == 3) { + mQueue.removeLast(); + needsInvoke = false; + } + picture.writeToStream(mByteStream); + mQueue.add(mByteStream.toByteArray()); + mByteStream.reset(); + mLock.unlock(); + + if (needsInvoke) { + mExecutor.execute(this); + } + } + + @Override + public void run() { + mLock.lock(); + final byte[] picture = mQueue.poll(); + final boolean isStopped = mStopListening; + mLock.unlock(); + if (Thread.currentThread() == mRenderThread) { + close(); + throw new IllegalStateException( + "ViewDebug#startRenderingCommandsCapture must be given an executor that " + + "invokes asynchronously"); + } + if (isStopped) { + return; + } + OutputStream stream = null; + try { + stream = mCallback.call(); + } catch (Exception ex) { + Log.w("ViewDebug", "Aborting rendering commands capture " + + "because callback threw exception", ex); + } + if (stream != null) { + try { + stream.write(picture); + } catch (IOException ex) { + Log.w("ViewDebug", "Aborting rendering commands capture " + + "due to IOException writing to output stream", ex); + } + } else { + close(); + } + } + } + /** * Begins capturing the entire rendering commands for the view tree referenced by the given * view. The view passed may be any View in the tree as long as it is attached. That is, @@ -913,18 +1001,7 @@ public class ViewDebug { } final HardwareRenderer renderer = attachInfo.mThreadedRenderer; if (renderer != null) { - return new PictureCallbackHandler(renderer, (picture -> { - try { - OutputStream stream = callback.call(); - if (stream != null) { - picture.writeToStream(stream); - return true; - } - } catch (Exception ex) { - // fall through - } - return false; - }), executor); + return new StreamingPictureCallbackHandler(renderer, callback, executor); } return null; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java index 4700baae8fab..18d436ff7659 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java @@ -421,7 +421,7 @@ public class NotificationGuts extends FrameLayout { } /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */ - private static class AnimateCloseListener extends AnimatorListenerAdapter { + private class AnimateCloseListener extends AnimatorListenerAdapter { final View mView; private final GutsContent mGutsContent; @@ -433,8 +433,10 @@ public class NotificationGuts extends FrameLayout { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - mView.setVisibility(View.GONE); - mGutsContent.onFinishedClosing(); + if (!isExposed()) { + mView.setVisibility(View.GONE); + mGutsContent.onFinishedClosing(); + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 8f7671a5dd96..719ec3215d42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -100,6 +100,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx protected String mKeyToRemoveOnGutsClosed; private StatusBar mStatusBar; + private Runnable mOpenRunnable; @Inject public NotificationGutsManager( @@ -343,6 +344,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls, int x, int y, boolean resetMenu) { if (mNotificationGutsExposed != null) { + mNotificationGutsExposed.removeCallbacks(mOpenRunnable); mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force); } if (resetMenu) { @@ -445,7 +447,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx // ensure that it's laid but not visible until actually laid out guts.setVisibility(View.INVISIBLE); // Post to ensure the the guts are properly laid out. - guts.post(new Runnable() { + mOpenRunnable = new Runnable() { @Override public void run() { if (row.getWindowToken() == null) { @@ -470,7 +472,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mListContainer.onHeightChanged(row, true /* needsAnimation */); mGutsMenuItem = menuItem; } - }); + }; + guts.post(mOpenRunnable); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt index f4635d1270a8..f7b8a2e29129 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt @@ -67,6 +67,9 @@ class KeyguardLiftController constructor( } private fun updateListeningState() { + if (pickupSensor == null) { + return + } val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible && !statusBarStateController.isDozing diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 0c47d1468a7f..68ee8bbbb69b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -62,6 +62,8 @@ import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; import java.io.PrintWriter; import java.util.ArrayList; +import androidx.annotation.VisibleForTesting; + /** * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done, @@ -161,6 +163,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private boolean mLastLockVisible; private OnDismissAction mAfterKeyguardGoneAction; + private Runnable mKeyguardGoneCancelAction; private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>(); // Dismiss action to be launched when we stop dozing or the keyguard is gone. @@ -328,10 +331,20 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb return false; } - private void hideBouncer(boolean destroyView) { + @VisibleForTesting + void hideBouncer(boolean destroyView) { if (mBouncer == null) { return; } + if (mShowing) { + // If we were showing the bouncer and then aborting, we need to also clear out any + // potential actions unless we actually unlocked. + mAfterKeyguardGoneAction = null; + if (mKeyguardGoneCancelAction != null) { + mKeyguardGoneCancelAction.run(); + mKeyguardGoneCancelAction = null; + } + } mBouncer.hide(destroyView); cancelPendingWakeupAction(); } @@ -364,6 +377,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBouncer.showWithDismissAction(r, cancelAction); } else { mAfterKeyguardGoneAction = r; + mKeyguardGoneCancelAction = cancelAction; mBouncer.show(false /* resetSecuritySelection */); } } @@ -671,6 +685,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mAfterKeyguardGoneAction.onDismiss(); mAfterKeyguardGoneAction = null; } + mKeyguardGoneCancelAction = null; for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) { mAfterKeyguardGoneRunnables.get(i).run(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index 63f653b0b303..0da0e7647707 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -221,6 +221,31 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { verify(mStatusBar, never()).animateKeyguardUnoccluding(); } + @Test + public void testHiding_cancelsGoneRunnable() { + OnDismissAction action = mock(OnDismissAction.class); + Runnable cancelAction = mock(Runnable.class); + mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction, + true /* afterKeyguardGone */); + + mStatusBarKeyguardViewManager.hideBouncer(true); + mStatusBarKeyguardViewManager.hide(0, 30); + verify(action, never()).onDismiss(); + verify(cancelAction).run(); + } + + @Test + public void testHiding_doesntCancelWhenShowing() { + OnDismissAction action = mock(OnDismissAction.class); + Runnable cancelAction = mock(Runnable.class); + mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction, + true /* afterKeyguardGone */); + + mStatusBarKeyguardViewManager.hide(0, 30); + verify(action).onDismiss(); + verify(cancelAction, never()).run(); + } + private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager { public TestableStatusBarKeyguardViewManager(Context context, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 078fcef0f88b..c2482ef77a7a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5262,7 +5262,7 @@ public class ActivityManagerService extends IActivityManager.Stub storageManager.commitChanges(); } catch (Exception e) { PowerManager pm = (PowerManager) - mInjector.getContext().getSystemService(Context.POWER_SERVICE); + mContext.getSystemService(Context.POWER_SERVICE); pm.reboot("Checkpoint commit failed"); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index aae48239a0cc..dd8cb4dba0a7 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18626,7 +18626,7 @@ public class PackageManagerService extends IPackageManager.Stub continue; } List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr( - libraryInfo, 0, currUserId); + libraryInfo, MATCH_KNOWN_PACKAGES, currUserId); if (!ArrayUtils.isEmpty(libClientPackages)) { Slog.w(TAG, "Not removing package " + pkg.manifestPackageName + " hosting lib " + libraryInfo.getName() + " version " @@ -22967,9 +22967,9 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeKernelMappingLPr(ps); } - final UserManager um = mContext.getSystemService(UserManager.class); + final UserManagerService um = sUserManager; UserManagerInternal umInternal = getUserManagerInternal(); - for (UserInfo user : um.getUsers()) { + for (UserInfo user : um.getUsers(false /* excludeDying */)) { final int flags; if (umInternal.isUserUnlockingOrUnlocked(user.id)) { flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; @@ -23652,8 +23652,9 @@ public class PackageManagerService extends IPackageManager.Stub continue; } final String packageName = ps.pkg.packageName; - // Skip over if system app - if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { + // Skip over if system app or static shared library + if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0 + || !TextUtils.isEmpty(ps.pkg.staticSharedLibName)) { continue; } if (DEBUG_CLEAN_APKS) { |