summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Wale Ogunwale <ogunwale@google.com> 2016-02-01 10:32:02 -0800
committer Wale Ogunwale <ogunwale@google.com> 2016-02-02 19:07:01 -0800
commit22e2526b64a124a641f79de504d201005174754b (patch)
tree7b1f4ff1e43360f01d3ef888942a5c590ddda5e9
parenta0fddc1ed41a4bb14fc33e5bdbc4de1317dc79b7 (diff)
Improved timing of when system sends multi-window change event to app
We were previously sending multi-window/PiP mode changed events to apps once the task config is changed in activity manager. However, the actual changing of the multi-windowing or PiP mode might not be fully complete when the app receives the event so they might be wrong state information they query for like currnet config. We now schedule the events to be send once the current transaction cycle is done. Bug: 26877409 Change-Id: I393b56035bb4197f99b3db3d27c0599835b5f86c
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityRecord.java44
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java58
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java36
4 files changed, 96 insertions, 46 deletions
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 914776ea488a..90a7da977355 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -18,6 +18,7 @@ package com.android.server.am;
import static android.app.ActivityManager.StackId;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
@@ -409,15 +410,40 @@ final class ActivityRecord {
}
void scheduleConfigurationChanged(Configuration config, boolean reportToActivity) {
- if (app != null && app.thread != null) {
- try {
- if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + " " +
- "reportToActivity=" + reportToActivity + " and config: " + config);
- app.thread.scheduleActivityConfigurationChanged(
- appToken, new Configuration(config), reportToActivity);
- } catch (RemoteException e) {
- // If process died, whatever.
- }
+ if (app == null || app.thread == null) {
+ return;
+ }
+ try {
+ if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + " " +
+ "reportToActivity=" + reportToActivity + " and config: " + config);
+ app.thread.scheduleActivityConfigurationChanged(
+ appToken, new Configuration(config), reportToActivity);
+ } catch (RemoteException e) {
+ // If process died, whatever.
+ }
+ }
+
+ void scheduleMultiWindowChanged() {
+ if (task == null || task.stack == null || app == null || app.thread == null) {
+ return;
+ }
+ try {
+ // An activity is considered to be in multi-window mode if its task isn't fullscreen.
+ app.thread.scheduleMultiWindowChanged(appToken, !task.mFullscreen);
+ } catch (Exception e) {
+ // If process died, I don't care.
+ }
+ }
+
+ void schedulePictureInPictureChanged() {
+ if (task == null || task.stack == null || app == null || app.thread == null) {
+ return;
+ }
+ try {
+ app.thread.schedulePictureInPictureChanged(
+ appToken, task.stack.mStackId == PINNED_STACK_ID);
+ } catch (Exception e) {
+ // If process died, no one cares.
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 0e970b3fb827..4825d57a4447 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4827,7 +4827,7 @@ final class ActivityStack {
private void postAddTask(TaskRecord task, ActivityStack prevStack) {
if (prevStack != null) {
- task.reportPictureInPictureChangeIfNeeded(prevStack);
+ mStackSupervisor.scheduleReportPictureInPictureChangedIfNeeded(task, prevStack);
} else if (task.voiceSession != null) {
try {
task.voiceSession.taskStarted(task.intent, task.taskId);
@@ -4886,7 +4886,7 @@ final class ActivityStack {
r.setTask(task, null);
task.addActivityToTop(r);
setAppTask(r, task);
- task.reportPictureInPictureChangeIfNeeded(prevStack);
+ mStackSupervisor.scheduleReportPictureInPictureChangedIfNeeded(task, prevStack);
moveToFrontAndResumeStateIfNeeded(r, wasFocused, wasResumed, "moveActivityToStack");
if (wasResumed) {
prevStack.mResumedActivity = null;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c41caa805b8c..6bbc5d6ddf9e 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -203,6 +203,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
+ static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
+ static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
private static final String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
@@ -322,6 +324,14 @@ public final class ActivityStackSupervisor implements DisplayListener {
/** List of activities that are in the process of going to sleep. */
final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
+ /** List of activities whose multi-window mode changed that we need to report to the
+ * application */
+ final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>();
+
+ /** List of activities whose picture-in-picture mode changed that we need to report to the
+ * application */
+ final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
+
/** Used on user changes */
final ArrayList<UserState> mStartingUsers = new ArrayList<>();
@@ -3390,6 +3400,38 @@ public final class ActivityStackSupervisor implements DisplayListener {
mActivityMetricsLogger.logWindowState();
}
+ void scheduleReportMultiWindowChanged(TaskRecord task) {
+ for (int i = task.mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = task.mActivities.get(i);
+ if (r.app != null && r.app.thread != null) {
+ mMultiWindowModeChangedActivities.add(r);
+ }
+ }
+
+ if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) {
+ mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG);
+ }
+ }
+
+ void scheduleReportPictureInPictureChangedIfNeeded(TaskRecord task, ActivityStack prevStack) {
+ final ActivityStack stack = task.stack;
+ if (prevStack == null || prevStack == stack
+ || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
+ return;
+ }
+
+ for (int i = task.mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = task.mActivities.get(i);
+ if (r.app != null && r.app.thread != null) {
+ mPipModeChangedActivities.add(r);
+ }
+ }
+
+ if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
+ mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
+ }
+ }
+
private final class ActivityStackSupervisorHandler extends Handler {
public ActivityStackSupervisorHandler(Looper looper) {
@@ -3405,6 +3447,22 @@ public final class ActivityStackSupervisor implements DisplayListener {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
+ case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: {
+ synchronized (mService) {
+ for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
+ r.scheduleMultiWindowChanged();
+ }
+ }
+ } break;
+ case REPORT_PIP_MODE_CHANGED_MSG: {
+ synchronized (mService) {
+ for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = mPipModeChangedActivities.remove(i);
+ r.schedulePictureInPictureChanged();
+ }
+ }
+ } break;
case IDLE_TIMEOUT_MSG: {
if (DEBUG_IDLE) Slog.d(TAG_IDLE,
"handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index f39ab2fa98ee..a7d948c9a695 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1320,7 +1320,7 @@ final class TaskRecord {
}
if (mFullscreen != oldFullscreen) {
- reportMultiWindowChange();
+ mService.mStackSupervisor.scheduleReportMultiWindowChanged(this);
}
return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
@@ -1375,40 +1375,6 @@ final class TaskRecord {
return bounds;
}
- private void reportMultiWindowChange() {
- for (int i = mActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord r = mActivities.get(i);
- if (r.app != null && r.app.thread != null) {
- try {
- // An activity is consider to be in multi-window mode if its task isn't
- // fullscreen.
- r.app.thread.scheduleMultiWindowChanged(r.appToken, !mFullscreen);
- } catch (Exception e) {
- Slog.e(TAG, "TaskRecord.reportMultiWindowChange: ", e);
- }
- }
- }
- }
-
- void reportPictureInPictureChangeIfNeeded(ActivityStack prevStack) {
- if (prevStack == null || prevStack == stack
- || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
- return;
- }
-
- for (int i = mActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord r = mActivities.get(i);
- if (r.app != null && r.app.thread != null) {
- try {
- r.app.thread.schedulePictureInPictureChanged(
- r.appToken, stack.mStackId == PINNED_STACK_ID);
- } catch (Exception e) {
- Slog.e(TAG, "TaskRecord.reportPictureInPictureChangeIfNeeded: ", e);
- }
- }
- }
- }
-
/** Updates the task's bounds and override configuration to match what is expected for the
* input stack. */
void updateOverrideConfigurationForStack(ActivityStack inStack) {