Loading core/java/android/view/ViewDebug.java +89 −12 Original line number Original line Diff line number Diff line Loading @@ -870,6 +870,94 @@ public class ViewDebug { return null; 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 * 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, * view. The view passed may be any View in the tree as long as it is attached. That is, Loading Loading @@ -915,18 +1003,7 @@ public class ViewDebug { } } final HardwareRenderer renderer = attachInfo.mThreadedRenderer; final HardwareRenderer renderer = attachInfo.mThreadedRenderer; if (renderer != null) { if (renderer != null) { return new PictureCallbackHandler(renderer, (picture -> { return new StreamingPictureCallbackHandler(renderer, callback, executor); try { OutputStream stream = callback.call(); if (stream != null) { picture.writeToStream(stream); return true; } } catch (Exception ex) { // fall through } return false; }), executor); } } return null; return null; } } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java +5 −3 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ public class NotificationGuts extends FrameLayout { } } /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */ /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */ private static class AnimateCloseListener extends AnimatorListenerAdapter { private class AnimateCloseListener extends AnimatorListenerAdapter { final View mView; final View mView; private final GutsContent mGutsContent; private final GutsContent mGutsContent; Loading @@ -433,8 +433,10 @@ public class NotificationGuts extends FrameLayout { @Override @Override public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); super.onAnimationEnd(animation); if (!isExposed()) { mView.setVisibility(View.GONE); mView.setVisibility(View.GONE); mGutsContent.onFinishedClosing(); mGutsContent.onFinishedClosing(); } } } } } } } packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx protected String mKeyToRemoveOnGutsClosed; protected String mKeyToRemoveOnGutsClosed; private StatusBar mStatusBar; private StatusBar mStatusBar; private Runnable mOpenRunnable; @Inject @Inject public NotificationGutsManager( public NotificationGutsManager( Loading Loading @@ -343,6 +344,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls, public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls, int x, int y, boolean resetMenu) { int x, int y, boolean resetMenu) { if (mNotificationGutsExposed != null) { if (mNotificationGutsExposed != null) { mNotificationGutsExposed.removeCallbacks(mOpenRunnable); mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force); mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force); } } if (resetMenu) { if (resetMenu) { Loading Loading @@ -445,7 +447,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx // ensure that it's laid but not visible until actually laid out // ensure that it's laid but not visible until actually laid out guts.setVisibility(View.INVISIBLE); guts.setVisibility(View.INVISIBLE); // Post to ensure the the guts are properly laid out. // Post to ensure the the guts are properly laid out. guts.post(new Runnable() { mOpenRunnable = new Runnable() { @Override @Override public void run() { public void run() { if (row.getWindowToken() == null) { if (row.getWindowToken() == null) { Loading @@ -470,7 +472,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mListContainer.onHeightChanged(row, true /* needsAnimation */); mListContainer.onHeightChanged(row, true /* needsAnimation */); mGutsMenuItem = menuItem; mGutsMenuItem = menuItem; } } }); }; guts.post(mOpenRunnable); return true; return true; } } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt +3 −0 Original line number Original line Diff line number Diff line Loading @@ -67,6 +67,9 @@ class KeyguardLiftController constructor( } } private fun updateListeningState() { private fun updateListeningState() { if (pickupSensor == null) { return } val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible && val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible && !statusBarStateController.isDozing !statusBarStateController.isDozing Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +16 −1 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,8 @@ import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import androidx.annotation.VisibleForTesting; /** /** * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back * 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, * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done, Loading Loading @@ -161,6 +163,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private boolean mLastLockVisible; private boolean mLastLockVisible; private OnDismissAction mAfterKeyguardGoneAction; private OnDismissAction mAfterKeyguardGoneAction; private Runnable mKeyguardGoneCancelAction; private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>(); private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>(); // Dismiss action to be launched when we stop dozing or the keyguard is gone. // Dismiss action to be launched when we stop dozing or the keyguard is gone. Loading Loading @@ -328,10 +331,20 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb return false; return false; } } private void hideBouncer(boolean destroyView) { @VisibleForTesting void hideBouncer(boolean destroyView) { if (mBouncer == null) { if (mBouncer == null) { return; 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); mBouncer.hide(destroyView); cancelPendingWakeupAction(); cancelPendingWakeupAction(); } } Loading Loading @@ -364,6 +377,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBouncer.showWithDismissAction(r, cancelAction); mBouncer.showWithDismissAction(r, cancelAction); } else { } else { mAfterKeyguardGoneAction = r; mAfterKeyguardGoneAction = r; mKeyguardGoneCancelAction = cancelAction; mBouncer.show(false /* resetSecuritySelection */); mBouncer.show(false /* resetSecuritySelection */); } } } } Loading Loading @@ -671,6 +685,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mAfterKeyguardGoneAction.onDismiss(); mAfterKeyguardGoneAction.onDismiss(); mAfterKeyguardGoneAction = null; mAfterKeyguardGoneAction = null; } } mKeyguardGoneCancelAction = null; for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) { for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) { mAfterKeyguardGoneRunnables.get(i).run(); mAfterKeyguardGoneRunnables.get(i).run(); } } Loading Loading
core/java/android/view/ViewDebug.java +89 −12 Original line number Original line Diff line number Diff line Loading @@ -870,6 +870,94 @@ public class ViewDebug { return null; 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 * 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, * view. The view passed may be any View in the tree as long as it is attached. That is, Loading Loading @@ -915,18 +1003,7 @@ public class ViewDebug { } } final HardwareRenderer renderer = attachInfo.mThreadedRenderer; final HardwareRenderer renderer = attachInfo.mThreadedRenderer; if (renderer != null) { if (renderer != null) { return new PictureCallbackHandler(renderer, (picture -> { return new StreamingPictureCallbackHandler(renderer, callback, executor); try { OutputStream stream = callback.call(); if (stream != null) { picture.writeToStream(stream); return true; } } catch (Exception ex) { // fall through } return false; }), executor); } } return null; return null; } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java +5 −3 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ public class NotificationGuts extends FrameLayout { } } /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */ /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */ private static class AnimateCloseListener extends AnimatorListenerAdapter { private class AnimateCloseListener extends AnimatorListenerAdapter { final View mView; final View mView; private final GutsContent mGutsContent; private final GutsContent mGutsContent; Loading @@ -433,8 +433,10 @@ public class NotificationGuts extends FrameLayout { @Override @Override public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); super.onAnimationEnd(animation); if (!isExposed()) { mView.setVisibility(View.GONE); mView.setVisibility(View.GONE); mGutsContent.onFinishedClosing(); mGutsContent.onFinishedClosing(); } } } } } } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx protected String mKeyToRemoveOnGutsClosed; protected String mKeyToRemoveOnGutsClosed; private StatusBar mStatusBar; private StatusBar mStatusBar; private Runnable mOpenRunnable; @Inject @Inject public NotificationGutsManager( public NotificationGutsManager( Loading Loading @@ -343,6 +344,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls, public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls, int x, int y, boolean resetMenu) { int x, int y, boolean resetMenu) { if (mNotificationGutsExposed != null) { if (mNotificationGutsExposed != null) { mNotificationGutsExposed.removeCallbacks(mOpenRunnable); mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force); mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force); } } if (resetMenu) { if (resetMenu) { Loading Loading @@ -445,7 +447,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx // ensure that it's laid but not visible until actually laid out // ensure that it's laid but not visible until actually laid out guts.setVisibility(View.INVISIBLE); guts.setVisibility(View.INVISIBLE); // Post to ensure the the guts are properly laid out. // Post to ensure the the guts are properly laid out. guts.post(new Runnable() { mOpenRunnable = new Runnable() { @Override @Override public void run() { public void run() { if (row.getWindowToken() == null) { if (row.getWindowToken() == null) { Loading @@ -470,7 +472,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mListContainer.onHeightChanged(row, true /* needsAnimation */); mListContainer.onHeightChanged(row, true /* needsAnimation */); mGutsMenuItem = menuItem; mGutsMenuItem = menuItem; } } }); }; guts.post(mOpenRunnable); return true; return true; } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt +3 −0 Original line number Original line Diff line number Diff line Loading @@ -67,6 +67,9 @@ class KeyguardLiftController constructor( } } private fun updateListeningState() { private fun updateListeningState() { if (pickupSensor == null) { return } val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible && val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible && !statusBarStateController.isDozing !statusBarStateController.isDozing Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +16 −1 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,8 @@ import com.android.systemui.statusbar.policy.KeyguardMonitorImpl; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import androidx.annotation.VisibleForTesting; /** /** * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back * 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, * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done, Loading Loading @@ -161,6 +163,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private boolean mLastLockVisible; private boolean mLastLockVisible; private OnDismissAction mAfterKeyguardGoneAction; private OnDismissAction mAfterKeyguardGoneAction; private Runnable mKeyguardGoneCancelAction; private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>(); private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>(); // Dismiss action to be launched when we stop dozing or the keyguard is gone. // Dismiss action to be launched when we stop dozing or the keyguard is gone. Loading Loading @@ -328,10 +331,20 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb return false; return false; } } private void hideBouncer(boolean destroyView) { @VisibleForTesting void hideBouncer(boolean destroyView) { if (mBouncer == null) { if (mBouncer == null) { return; 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); mBouncer.hide(destroyView); cancelPendingWakeupAction(); cancelPendingWakeupAction(); } } Loading Loading @@ -364,6 +377,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBouncer.showWithDismissAction(r, cancelAction); mBouncer.showWithDismissAction(r, cancelAction); } else { } else { mAfterKeyguardGoneAction = r; mAfterKeyguardGoneAction = r; mKeyguardGoneCancelAction = cancelAction; mBouncer.show(false /* resetSecuritySelection */); mBouncer.show(false /* resetSecuritySelection */); } } } } Loading Loading @@ -671,6 +685,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mAfterKeyguardGoneAction.onDismiss(); mAfterKeyguardGoneAction.onDismiss(); mAfterKeyguardGoneAction = null; mAfterKeyguardGoneAction = null; } } mKeyguardGoneCancelAction = null; for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) { for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) { mAfterKeyguardGoneRunnables.get(i).run(); mAfterKeyguardGoneRunnables.get(i).run(); } } Loading