diff options
5 files changed, 24 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java index 2e476772f85b..e4eb7b3a8144 100644 --- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java +++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java @@ -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); diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 7995028b1ec7..ed54ea8229fe 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -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); } @@ -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) { diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 9e2e460b8ae4..b8fa5e5b2786 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -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; @@ -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=" @@ -1675,7 +1679,12 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio private void scheduleClientTransactionItem(@NonNull IApplicationThread thread, @NonNull ClientTransactionItem transactionItem) { try { - mAtm.getLifecycleManager().scheduleTransactionItem(thread, transactionItem); + 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=" diff --git a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java index 6dfd60744349..09f677e701df 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java @@ -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()); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 8e3dbb4a200c..400e4b6686cb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -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); @@ -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); |