summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorHongwei Wang <hwwang@google.com>2019-11-15 15:44:12 -0800
committerHongwei Wang <hwwang@google.com>2020-04-30 08:48:09 -0700
commit5711b8fdaf2d99414c8167d142c140c02301c64c (patch)
tree2e5263c89c916158ce828c1e07cacdcced851c08 /core/java
parent265622e3c79afde612d39e4f74635f741cacf4c1 (diff)
Move PIP/MW mode callbacks to be on the client side
We now infer the PIP/MW mode change from the new configuration. Note also that both - Activity#isInPictureInPictureMode - Activity#isInMultiWindowMode infer the current state from the configuration rather than querying against the WM. Also in this CL: - When in removePinnedStackInSurfaceTransaction, keep the pinned stack hidden till the windowing mode is set to fullscreen, this is to surpress the attempt to set the activities to be started in reparenting - When in ActivityRecord#shouldBeVisible, should take account the force hidden flag, which is not actually in use before Bug: 144097203 Bug: 142282126 Bug: 138329093 Test: atest ActivityLifecyclePipTests \ ActivityLifecycleSplitScreenTests \ ActivityLifecycleTopResumedStateTests \ PinnedStackTests \ SplitScreenTests \ ActivityTaskManagerServiceTests \ RecentsAnimationTest \ AssistantStackTests \ StartActivityTests \ ActivityVisibilityTests \ MultiDisplaySecurityTests \ MultiDisplaySystemDecorationTests Change-Id: Ibe032b5e50ba5c6d6bc44ebb54d07ac974ebe656
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/Activity.java12
-rw-r--r--core/java/android/app/ActivityThread.java73
-rw-r--r--core/java/android/app/ClientTransactionHandler.java8
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl2
-rw-r--r--core/java/android/app/WindowConfiguration.java10
-rw-r--r--core/java/android/app/servertransaction/MultiWindowModeChangeItem.java121
-rw-r--r--core/java/android/app/servertransaction/PipModeChangeItem.java119
7 files changed, 59 insertions, 286 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e0ae750ba5ee..17720a34c424 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2748,11 +2748,7 @@ public class Activity extends ContextThemeWrapper
* @return True if the activity is in multi-window mode.
*/
public boolean isInMultiWindowMode() {
- try {
- return ActivityTaskManager.getService().isInMultiWindowMode(mToken);
- } catch (RemoteException e) {
- }
- return false;
+ return mLastDispatchedIsInMultiWindowMode == Boolean.TRUE;
}
/**
@@ -2795,11 +2791,7 @@ public class Activity extends ContextThemeWrapper
* @return True if the activity is in picture-in-picture mode.
*/
public boolean isInPictureInPictureMode() {
- try {
- return ActivityTaskManager.getService().isInPictureInPictureMode(mToken);
- } catch (RemoteException e) {
- }
- return false;
+ return mLastDispatchedIsInPictureInPictureMode == Boolean.TRUE;
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 51eaff1ae99f..73566d93afa0 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -17,6 +17,8 @@
package android.app;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY;
import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
@@ -407,6 +409,9 @@ public final class ActivityThread extends ClientTransactionHandler {
@GuardedBy("this")
private @Nullable Map<SafeCancellationTransport, CancellationSignal> mRemoteCancellations;
+ private final Map<IBinder, Integer> mLastReportedWindowingMode = Collections.synchronizedMap(
+ new ArrayMap<>());
+
private static final class ProviderKey {
final String authority;
final int userId;
@@ -3324,6 +3329,8 @@ public final class ActivityThread extends ClientTransactionHandler {
" did not call through to super.onCreate()");
}
r.activity = activity;
+ mLastReportedWindowingMode.put(activity.getActivityToken(),
+ config.windowConfiguration.getWindowingMode());
}
r.setState(ON_CREATE);
@@ -3747,32 +3754,6 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
- Configuration overrideConfig) {
- final ActivityClientRecord r = mActivities.get(token);
- if (r != null) {
- final Configuration newConfig = new Configuration(mConfiguration);
- if (overrideConfig != null) {
- newConfig.updateFrom(overrideConfig);
- }
- r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
- }
- }
-
- @Override
- public void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode,
- Configuration overrideConfig) {
- final ActivityClientRecord r = mActivities.get(token);
- if (r != null) {
- final Configuration newConfig = new Configuration(mConfiguration);
- if (overrideConfig != null) {
- newConfig.updateFrom(overrideConfig);
- }
- r.activity.dispatchPictureInPictureModeChanged(isInPipMode, newConfig);
- }
- }
-
- @Override
public void handlePictureInPictureRequested(IBinder token) {
final ActivityClientRecord r = mActivities.get(token);
if (r == null) {
@@ -5269,8 +5250,15 @@ public final class ActivityThread extends ClientTransactionHandler {
throw e.rethrowFromSystemServer();
}
+ // Save the current windowing mode to be restored and compared to the new configuration's
+ // windowing mode (needed because we update the last reported windowing mode when launching
+ // an activity and we can't tell inside performLaunchActivity whether we are relaunching)
+ final int oldWindowingMode = mLastReportedWindowingMode.getOrDefault(
+ r.activity.getActivityToken(), WINDOWING_MODE_UNDEFINED);
handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
+ mLastReportedWindowingMode.put(r.activity.getActivityToken(), oldWindowingMode);
+ handleWindowingModeChangeIfNeeded(r.activity, r.activity.mCurrentConfig);
if (pendingActions != null) {
// Only report a successful relaunch to WindowManager.
@@ -5553,6 +5541,10 @@ public final class ActivityThread extends ClientTransactionHandler {
throw new IllegalArgumentException("Activity token not set. Is the activity attached?");
}
+ // multi-window / pip mode changes, if any, should be sent before the configuration change
+ // callback, see also PinnedStackTests#testConfigurationChangeOrderDuringTransition
+ handleWindowingModeChangeIfNeeded(activity, newConfig);
+
boolean shouldChangeConfig = false;
if (activity.mCurrentConfig == null) {
shouldChangeConfig = true;
@@ -5747,6 +5739,35 @@ public final class ActivityThread extends ClientTransactionHandler {
}
/**
+ * Sends windowing mode change callbacks to {@link Activity} if applicable.
+ *
+ * See also {@link Activity#onMultiWindowModeChanged(boolean, Configuration)} and
+ * {@link Activity#onPictureInPictureModeChanged(boolean, Configuration)}
+ */
+ private void handleWindowingModeChangeIfNeeded(Activity activity,
+ Configuration newConfiguration) {
+ final int newWindowingMode = newConfiguration.windowConfiguration.getWindowingMode();
+ final IBinder token = activity.getActivityToken();
+ final int oldWindowingMode = mLastReportedWindowingMode.getOrDefault(token,
+ WINDOWING_MODE_UNDEFINED);
+ if (oldWindowingMode == newWindowingMode) return;
+ // PiP callback is sent before the MW one.
+ if (newWindowingMode == WINDOWING_MODE_PINNED) {
+ activity.dispatchPictureInPictureModeChanged(true, newConfiguration);
+ } else if (oldWindowingMode == WINDOWING_MODE_PINNED) {
+ activity.dispatchPictureInPictureModeChanged(false, newConfiguration);
+ }
+ final boolean wasInMultiWindowMode = WindowConfiguration.inMultiWindowMode(
+ oldWindowingMode);
+ final boolean nowInMultiWindowMode = WindowConfiguration.inMultiWindowMode(
+ newWindowingMode);
+ if (wasInMultiWindowMode != nowInMultiWindowMode) {
+ activity.dispatchMultiWindowModeChanged(nowInMultiWindowMode, newConfiguration);
+ }
+ mLastReportedWindowingMode.put(token, newWindowingMode);
+ }
+
+ /**
* Updates the application info.
*
* This only works in the system process. Must be called on the main thread.
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index d2235f10da99..83465b0f8d36 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -146,17 +146,9 @@ public abstract class ClientTransactionHandler {
/** Deliver result from another activity. */
public abstract void handleSendResult(IBinder token, List<ResultInfo> results, String reason);
- /** Deliver multi-window mode change notification. */
- public abstract void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
- Configuration overrideConfig);
-
/** Deliver new intent. */
public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents);
- /** Deliver picture-in-picture mode change notification. */
- public abstract void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode,
- Configuration overrideConfig);
-
/** Request that an activity enter picture-in-picture. */
public abstract void handlePictureInPictureRequested(IBinder token);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index b7ceb6ae1b4c..3ce768944e48 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -300,8 +300,6 @@ interface IActivityTaskManager {
void suppressResizeConfigChanges(boolean suppress);
boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds);
- boolean isInMultiWindowMode(in IBinder token);
- boolean isInPictureInPictureMode(in IBinder token);
boolean enterPictureInPictureMode(in IBinder token, in PictureInPictureParams params);
void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params);
void requestPictureInPictureMode(in IBinder token);
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 37e07de9809a..a486b9501e0c 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -727,6 +727,16 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
}
/**
+ * Returns {@code true} if the windowingMode represents a window in multi-window mode.
+ * I.e. sharing the screen with another activity.
+ * @hide
+ */
+ public static boolean inMultiWindowMode(int windowingMode) {
+ return windowingMode != WINDOWING_MODE_FULLSCREEN
+ && windowingMode != WINDOWING_MODE_UNDEFINED;
+ }
+
+ /**
* Returns true if the windowingMode represents a split window.
* @hide
*/
diff --git a/core/java/android/app/servertransaction/MultiWindowModeChangeItem.java b/core/java/android/app/servertransaction/MultiWindowModeChangeItem.java
deleted file mode 100644
index b1507177f7e8..000000000000
--- a/core/java/android/app/servertransaction/MultiWindowModeChangeItem.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.servertransaction;
-
-import android.app.ClientTransactionHandler;
-import android.content.res.Configuration;
-import android.os.IBinder;
-import android.os.Parcel;
-
-import java.util.Objects;
-
-/**
- * Multi-window mode change message.
- * @hide
- */
-// TODO(lifecycler): Remove the use of this and just use the configuration change message to
-// communicate multi-window mode change with WindowConfiguration.
-public class MultiWindowModeChangeItem extends ClientTransactionItem {
-
- private boolean mIsInMultiWindowMode;
- private Configuration mOverrideConfig;
-
- @Override
- public void execute(ClientTransactionHandler client, IBinder token,
- PendingTransactionActions pendingActions) {
- client.handleMultiWindowModeChanged(token, mIsInMultiWindowMode, mOverrideConfig);
- }
-
-
- // ObjectPoolItem implementation
-
- private MultiWindowModeChangeItem() {}
-
- /** Obtain an instance initialized with provided params. */
- public static MultiWindowModeChangeItem obtain(boolean isInMultiWindowMode,
- Configuration overrideConfig) {
- MultiWindowModeChangeItem instance = ObjectPool.obtain(MultiWindowModeChangeItem.class);
- if (instance == null) {
- instance = new MultiWindowModeChangeItem();
- }
- instance.mIsInMultiWindowMode = isInMultiWindowMode;
- instance.mOverrideConfig = overrideConfig;
-
- return instance;
- }
-
- @Override
- public void recycle() {
- mIsInMultiWindowMode = false;
- mOverrideConfig = null;
- ObjectPool.recycle(this);
- }
-
-
- // Parcelable implementation
-
- /** Write to Parcel. */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeBoolean(mIsInMultiWindowMode);
- dest.writeTypedObject(mOverrideConfig, flags);
- }
-
- /** Read from Parcel. */
- private MultiWindowModeChangeItem(Parcel in) {
- mIsInMultiWindowMode = in.readBoolean();
- mOverrideConfig = in.readTypedObject(Configuration.CREATOR);
- }
-
- public static final @android.annotation.NonNull Creator<MultiWindowModeChangeItem> CREATOR =
- new Creator<MultiWindowModeChangeItem>() {
- public MultiWindowModeChangeItem createFromParcel(Parcel in) {
- return new MultiWindowModeChangeItem(in);
- }
-
- public MultiWindowModeChangeItem[] newArray(int size) {
- return new MultiWindowModeChangeItem[size];
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- final MultiWindowModeChangeItem other = (MultiWindowModeChangeItem) o;
- return mIsInMultiWindowMode == other.mIsInMultiWindowMode
- && Objects.equals(mOverrideConfig, other.mOverrideConfig);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + (mIsInMultiWindowMode ? 1 : 0);
- result = 31 * result + mOverrideConfig.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "MultiWindowModeChangeItem{isInMultiWindowMode=" + mIsInMultiWindowMode
- + ",overrideConfig=" + mOverrideConfig + "}";
- }
-}
diff --git a/core/java/android/app/servertransaction/PipModeChangeItem.java b/core/java/android/app/servertransaction/PipModeChangeItem.java
deleted file mode 100644
index 1955897665be..000000000000
--- a/core/java/android/app/servertransaction/PipModeChangeItem.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.servertransaction;
-
-import android.app.ClientTransactionHandler;
-import android.content.res.Configuration;
-import android.os.IBinder;
-import android.os.Parcel;
-
-import java.util.Objects;
-
-/**
- * Picture in picture mode change message.
- * @hide
- */
-// TODO(lifecycler): Remove the use of this and just use the configuration change message to
-// communicate multi-window mode change with WindowConfiguration.
-public class PipModeChangeItem extends ClientTransactionItem {
-
- private boolean mIsInPipMode;
- private Configuration mOverrideConfig;
-
- @Override
- public void execute(ClientTransactionHandler client, IBinder token,
- PendingTransactionActions pendingActions) {
- client.handlePictureInPictureModeChanged(token, mIsInPipMode, mOverrideConfig);
- }
-
-
- // ObjectPoolItem implementation
-
- private PipModeChangeItem() {}
-
- /** Obtain an instance initialized with provided params. */
- public static PipModeChangeItem obtain(boolean isInPipMode, Configuration overrideConfig) {
- PipModeChangeItem instance = ObjectPool.obtain(PipModeChangeItem.class);
- if (instance == null) {
- instance = new PipModeChangeItem();
- }
- instance.mIsInPipMode = isInPipMode;
- instance.mOverrideConfig = overrideConfig;
-
- return instance;
- }
-
- @Override
- public void recycle() {
- mIsInPipMode = false;
- mOverrideConfig = null;
- ObjectPool.recycle(this);
- }
-
-
- // Parcelable implementation
-
- /** Write to Parcel. */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeBoolean(mIsInPipMode);
- dest.writeTypedObject(mOverrideConfig, flags);
- }
-
- /** Read from Parcel. */
- private PipModeChangeItem(Parcel in) {
- mIsInPipMode = in.readBoolean();
- mOverrideConfig = in.readTypedObject(Configuration.CREATOR);
- }
-
- public static final @android.annotation.NonNull Creator<PipModeChangeItem> CREATOR =
- new Creator<PipModeChangeItem>() {
- public PipModeChangeItem createFromParcel(Parcel in) {
- return new PipModeChangeItem(in);
- }
-
- public PipModeChangeItem[] newArray(int size) {
- return new PipModeChangeItem[size];
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- final PipModeChangeItem other = (PipModeChangeItem) o;
- return mIsInPipMode == other.mIsInPipMode
- && Objects.equals(mOverrideConfig, other.mOverrideConfig);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + (mIsInPipMode ? 1 : 0);
- result = 31 * result + mOverrideConfig.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "PipModeChangeItem{isInPipMode=" + mIsInPipMode
- + ",overrideConfig=" + mOverrideConfig + "}";
- }
-}