Loading services/core/java/com/android/server/wm/ClientLifecycleManager.java +3 −3 Original line number Diff line number Diff line Loading @@ -74,13 +74,13 @@ class ClientLifecycleManager { } /** * Similar to {@link #scheduleTransactionItem}, but is called without WM lock. * Similar to {@link #scheduleTransactionItem}, but it sends the transaction immediately and * it can be called without WM lock. * * @see WindowProcessController#setReportedProcState(int) */ void scheduleTransactionItemUnlocked(@NonNull IApplicationThread client, void scheduleTransactionItemNow(@NonNull IApplicationThread client, @NonNull ClientTransactionItem transactionItem) throws RemoteException { // Immediately dispatching to client, and must not access WMS. final ClientTransaction clientTransaction = ClientTransaction.obtain(client); if (transactionItem.isActivityLifecycleItem()) { clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem); Loading services/core/java/com/android/server/wm/Session.java +4 −0 Original line number Diff line number Diff line Loading @@ -771,6 +771,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { mService.dispatchNewAnimatorScaleLocked(this); } mProcess.mWindowSession = this; } mAddedWindows.add(w); } Loading @@ -782,6 +783,9 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } } boolean hasWindow() { return !mAddedWindows.isEmpty(); } void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController, boolean visible, int type) { Loading services/core/java/com/android/server/wm/WindowProcessController.java +11 −2 Original line number Diff line number Diff line Loading @@ -188,6 +188,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // Set to true when process was launched with a wrapper attached private volatile boolean mUsingWrapper; /** Non-null if this process may have a window. */ @Nullable Session mWindowSession; // Thread currently set for VR scheduling int mVrThreadTid; Loading Loading @@ -399,7 +403,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // the latest configuration in their lifecycle callbacks (e.g. onReceive, onCreate). try { // No WM lock here. mAtm.getLifecycleManager().scheduleTransactionItemUnlocked( mAtm.getLifecycleManager().scheduleTransactionItemNow( thread, configurationChangeItem); } catch (Exception e) { Slog.e(TAG_CONFIGURATION, "Failed to schedule ConfigurationChangeItem=" Loading Loading @@ -1675,7 +1679,12 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio private void scheduleClientTransactionItem(@NonNull IApplicationThread thread, @NonNull ClientTransactionItem transactionItem) { try { if (mWindowSession != null && mWindowSession.hasWindow()) { mAtm.getLifecycleManager().scheduleTransactionItem(thread, transactionItem); } else { // Non-UI process can handle the change directly. mAtm.getLifecycleManager().scheduleTransactionItemNow(thread, transactionItem); } } catch (DeadObjectException e) { // Expected if the process has been killed. Slog.w(TAG_CONFIGURATION, "Failed for dead process. ClientTransactionItem=" Loading services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -172,7 +172,7 @@ public class ClientLifecycleManagerTests { @Test public void testScheduleTransactionItemUnlocked() throws RemoteException { // Use non binder client to get non-recycled ClientTransaction. mLifecycleManager.scheduleTransactionItemUnlocked(mNonBinderClient, mTransactionItem); mLifecycleManager.scheduleTransactionItemNow(mNonBinderClient, mTransactionItem); // Dispatch immediately. assertTrue(mLifecycleManager.mPendingTransactions.isEmpty()); Loading services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +5 −3 Original line number Diff line number Diff line Loading @@ -305,10 +305,12 @@ public class WindowProcessControllerTests extends WindowTestsBase { @Test public void testCachedStateConfigurationChange() throws RemoteException { doNothing().when(mClientLifecycleManager).scheduleTransactionItemUnlocked(any(), any()); doNothing().when(mClientLifecycleManager).scheduleTransactionItemNow(any(), any()); final IApplicationThread thread = mWpc.getThread(); final Configuration newConfig = new Configuration(mWpc.getConfiguration()); newConfig.densityDpi += 100; mWpc.mWindowSession = getTestSession(); mWpc.mWindowSession.onWindowAdded(mock(WindowState.class)); // Non-cached state will send the change directly. mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); clearInvocations(mClientLifecycleManager); Loading @@ -321,13 +323,13 @@ public class WindowProcessControllerTests extends WindowTestsBase { newConfig.densityDpi += 100; mWpc.onConfigurationChanged(newConfig); verify(mClientLifecycleManager, never()).scheduleTransactionItem(eq(thread), any()); verify(mClientLifecycleManager, never()).scheduleTransactionItemUnlocked(eq(thread), any()); verify(mClientLifecycleManager, never()).scheduleTransactionItemNow(eq(thread), any()); // Cached -> non-cached will send the previous deferred config immediately. mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_RECEIVER); final ArgumentCaptor<ConfigurationChangeItem> captor = ArgumentCaptor.forClass(ConfigurationChangeItem.class); verify(mClientLifecycleManager).scheduleTransactionItemUnlocked( verify(mClientLifecycleManager).scheduleTransactionItemNow( eq(thread), captor.capture()); final ClientTransactionHandler client = mock(ClientTransactionHandler.class); captor.getValue().preExecute(client); Loading Loading
services/core/java/com/android/server/wm/ClientLifecycleManager.java +3 −3 Original line number Diff line number Diff line Loading @@ -74,13 +74,13 @@ class ClientLifecycleManager { } /** * Similar to {@link #scheduleTransactionItem}, but is called without WM lock. * Similar to {@link #scheduleTransactionItem}, but it sends the transaction immediately and * it can be called without WM lock. * * @see WindowProcessController#setReportedProcState(int) */ void scheduleTransactionItemUnlocked(@NonNull IApplicationThread client, void scheduleTransactionItemNow(@NonNull IApplicationThread client, @NonNull ClientTransactionItem transactionItem) throws RemoteException { // Immediately dispatching to client, and must not access WMS. final ClientTransaction clientTransaction = ClientTransaction.obtain(client); if (transactionItem.isActivityLifecycleItem()) { clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem); Loading
services/core/java/com/android/server/wm/Session.java +4 −0 Original line number Diff line number Diff line Loading @@ -771,6 +771,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { mService.dispatchNewAnimatorScaleLocked(this); } mProcess.mWindowSession = this; } mAddedWindows.add(w); } Loading @@ -782,6 +783,9 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } } boolean hasWindow() { return !mAddedWindows.isEmpty(); } void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController, boolean visible, int type) { Loading
services/core/java/com/android/server/wm/WindowProcessController.java +11 −2 Original line number Diff line number Diff line Loading @@ -188,6 +188,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // Set to true when process was launched with a wrapper attached private volatile boolean mUsingWrapper; /** Non-null if this process may have a window. */ @Nullable Session mWindowSession; // Thread currently set for VR scheduling int mVrThreadTid; Loading Loading @@ -399,7 +403,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // the latest configuration in their lifecycle callbacks (e.g. onReceive, onCreate). try { // No WM lock here. mAtm.getLifecycleManager().scheduleTransactionItemUnlocked( mAtm.getLifecycleManager().scheduleTransactionItemNow( thread, configurationChangeItem); } catch (Exception e) { Slog.e(TAG_CONFIGURATION, "Failed to schedule ConfigurationChangeItem=" Loading Loading @@ -1675,7 +1679,12 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio private void scheduleClientTransactionItem(@NonNull IApplicationThread thread, @NonNull ClientTransactionItem transactionItem) { try { if (mWindowSession != null && mWindowSession.hasWindow()) { mAtm.getLifecycleManager().scheduleTransactionItem(thread, transactionItem); } else { // Non-UI process can handle the change directly. mAtm.getLifecycleManager().scheduleTransactionItemNow(thread, transactionItem); } } catch (DeadObjectException e) { // Expected if the process has been killed. Slog.w(TAG_CONFIGURATION, "Failed for dead process. ClientTransactionItem=" Loading
services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -172,7 +172,7 @@ public class ClientLifecycleManagerTests { @Test public void testScheduleTransactionItemUnlocked() throws RemoteException { // Use non binder client to get non-recycled ClientTransaction. mLifecycleManager.scheduleTransactionItemUnlocked(mNonBinderClient, mTransactionItem); mLifecycleManager.scheduleTransactionItemNow(mNonBinderClient, mTransactionItem); // Dispatch immediately. assertTrue(mLifecycleManager.mPendingTransactions.isEmpty()); Loading
services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +5 −3 Original line number Diff line number Diff line Loading @@ -305,10 +305,12 @@ public class WindowProcessControllerTests extends WindowTestsBase { @Test public void testCachedStateConfigurationChange() throws RemoteException { doNothing().when(mClientLifecycleManager).scheduleTransactionItemUnlocked(any(), any()); doNothing().when(mClientLifecycleManager).scheduleTransactionItemNow(any(), any()); final IApplicationThread thread = mWpc.getThread(); final Configuration newConfig = new Configuration(mWpc.getConfiguration()); newConfig.densityDpi += 100; mWpc.mWindowSession = getTestSession(); mWpc.mWindowSession.onWindowAdded(mock(WindowState.class)); // Non-cached state will send the change directly. mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); clearInvocations(mClientLifecycleManager); Loading @@ -321,13 +323,13 @@ public class WindowProcessControllerTests extends WindowTestsBase { newConfig.densityDpi += 100; mWpc.onConfigurationChanged(newConfig); verify(mClientLifecycleManager, never()).scheduleTransactionItem(eq(thread), any()); verify(mClientLifecycleManager, never()).scheduleTransactionItemUnlocked(eq(thread), any()); verify(mClientLifecycleManager, never()).scheduleTransactionItemNow(eq(thread), any()); // Cached -> non-cached will send the previous deferred config immediately. mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_RECEIVER); final ArgumentCaptor<ConfigurationChangeItem> captor = ArgumentCaptor.forClass(ConfigurationChangeItem.class); verify(mClientLifecycleManager).scheduleTransactionItemUnlocked( verify(mClientLifecycleManager).scheduleTransactionItemNow( eq(thread), captor.capture()); final ClientTransactionHandler client = mock(ClientTransactionHandler.class); captor.getValue().preExecute(client); Loading