summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ClientLifecycleManager.java19
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java11
3 files changed, 40 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
index 28f656e624fb..8b282dd3e7a8 100644
--- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java
+++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
@@ -58,6 +58,23 @@ class ClientLifecycleManager {
}
/**
+ * Similar to {@link #scheduleTransactionItem}, but is called without WM lock.
+ *
+ * @see WindowProcessController#setReportedProcState(int)
+ */
+ void scheduleTransactionItemUnlocked(@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);
+ } else {
+ clientTransaction.addCallback(transactionItem);
+ }
+ scheduleTransaction(clientTransaction);
+ }
+
+ /**
* Schedules a single transaction item, either a callback or a lifecycle request, delivery to
* client application.
* @throws RemoteException
@@ -65,6 +82,7 @@ class ClientLifecycleManager {
*/
void scheduleTransactionItem(@NonNull IApplicationThread client,
@NonNull ClientTransactionItem transactionItem) throws RemoteException {
+ // TODO(b/260873529): queue the transaction items.
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
if (transactionItem.isActivityLifecycleItem()) {
clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem);
@@ -82,6 +100,7 @@ class ClientLifecycleManager {
void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client,
@NonNull ClientTransactionItem transactionItem,
@NonNull ActivityLifecycleItem lifecycleItem) throws RemoteException {
+ // TODO(b/260873529): replace with #scheduleTransactionItem after launch for cleanup.
final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
clientTransaction.addCallback(transactionItem);
clientTransaction.setLifecycleStateRequest(lifecycleItem);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 558bf9d6310a..2b18f0775047 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -388,13 +388,22 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
final IApplicationThread thread = mThread;
if (prevProcState >= CACHED_CONFIG_PROC_STATE && repProcState < CACHED_CONFIG_PROC_STATE
&& thread != null && mHasCachedConfiguration) {
- final Configuration config;
+ final ConfigurationChangeItem configurationChangeItem;
synchronized (mLastReportedConfiguration) {
- config = new Configuration(mLastReportedConfiguration);
+ onConfigurationChangePreScheduled(mLastReportedConfiguration);
+ configurationChangeItem = ConfigurationChangeItem.obtain(
+ mLastReportedConfiguration, mLastTopActivityDeviceId);
}
// Schedule immediately to make sure the app component (e.g. receiver, service) can get
// the latest configuration in their lifecycle callbacks (e.g. onReceive, onCreate).
- scheduleConfigurationChange(thread, config);
+ try {
+ // No WM lock here.
+ mAtm.getLifecycleManager().scheduleTransactionItemUnlocked(
+ thread, configurationChangeItem);
+ } catch (Exception e) {
+ Slog.e(TAG_CONFIGURATION, "Failed to schedule ConfigurationChangeItem="
+ + configurationChangeItem + " owner=" + mOwner, e);
+ }
}
}
@@ -1634,11 +1643,12 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
}
}
- scheduleConfigurationChange(thread, config);
+ onConfigurationChangePreScheduled(config);
+ scheduleClientTransactionItem(thread, ConfigurationChangeItem.obtain(
+ config, mLastTopActivityDeviceId));
}
- private void scheduleConfigurationChange(@NonNull IApplicationThread thread,
- @NonNull Configuration config) {
+ private void onConfigurationChangePreScheduled(@NonNull Configuration config) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending to proc %s new config %s", mName,
config);
if (Build.IS_DEBUGGABLE && mHasImeService) {
@@ -1646,8 +1656,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config);
}
mHasCachedConfiguration = false;
- scheduleClientTransactionItem(thread, ConfigurationChangeItem.obtain(
- config, mLastTopActivityDeviceId));
}
@VisibleForTesting
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 e152feb141e1..e31ee1174656 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -306,7 +306,7 @@ public class WindowProcessControllerTests extends WindowTestsBase {
@Test
public void testCachedStateConfigurationChange() throws RemoteException {
- doNothing().when(mClientLifecycleManager).scheduleTransactionItem(any(), any());
+ doNothing().when(mClientLifecycleManager).scheduleTransactionItemUnlocked(any(), any());
final IApplicationThread thread = mWpc.getThread();
final Configuration newConfig = new Configuration(mWpc.getConfiguration());
newConfig.densityDpi += 100;
@@ -322,18 +322,17 @@ 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());
// 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).scheduleTransactionItem(eq(thread), captor.capture());
+ verify(mClientLifecycleManager).scheduleTransactionItemUnlocked(
+ eq(thread), captor.capture());
final ClientTransactionHandler client = mock(ClientTransactionHandler.class);
captor.getValue().preExecute(client);
- final ArgumentCaptor<Configuration> configCaptor =
- ArgumentCaptor.forClass(Configuration.class);
- verify(client).updatePendingConfiguration(configCaptor.capture());
- assertEquals(newConfig, configCaptor.getValue());
+ verify(client).updatePendingConfiguration(newConfig);
}
@Test