Added some test for visible behind activities.
Bug: 19225708
Change-Id: I26b2889063278e4deb0e48f1ce9354b39a1e1034
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 7e1662d..522fd71 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -59,6 +59,19 @@
androidprv:alwaysFocusable="true"
android:exported="true"
/>
+ <activity android:name=".TranslucentActivity"
+ android:theme="@style/Theme.Transparent"
+ android:resizeable="true"
+ android:supportsPictureInPicture="true"
+ android:exported="true"
+ android:taskAffinity="nobody.but.TranslucentActivity"
+ />
+ <activity android:name=".VisibleBehindActivity"
+ android:resizeable="true"
+ android:supportsPictureInPicture="true"
+ android:exported="true"
+ android:taskAffinity="nobody.but.VisibleBehindActivity"
+ />
</application>
</manifest>
diff --git a/hostsidetests/services/activitymanager/app/res/values/styles.xml b/hostsidetests/services/activitymanager/app/res/values/styles.xml
new file mode 100644
index 0000000..59ebad2
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/res/values/styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 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
+ -->
+
+<resources>
+ <style name="Theme.Transparent" parent="android:Theme">
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowNoTitle">true</item>
+ </style>
+</resources>
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/TranslucentActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/TranslucentActivity.java
new file mode 100644
index 0000000..35c0e91
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/TranslucentActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 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.server.app;
+
+import android.app.Activity;
+
+public class TranslucentActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/VisibleBehindActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/VisibleBehindActivity.java
new file mode 100644
index 0000000..cc8f273
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/VisibleBehindActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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.server.app;
+
+import android.app.Activity;
+import android.util.Log;
+
+public class VisibleBehindActivity extends Activity {
+ private static final String TAG = "VisibleBehindActivity";
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (requestVisibleBehind(true)) {
+ Log.e(TAG, "Failed to request visibility behind...");
+ }
+ }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
index fc60b78..8bd3145 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
@@ -125,4 +125,23 @@
void assertFrontWindow(String msg, String windowName) {
assertEquals(msg, windowName, mWmState.getFrontWindow());
}
+
+ void assertVisibility(String activityName, boolean visible) {
+ final String activityComponentName =
+ ActivityManagerTestBase.getActivityComponentName(activityName);
+ final String windowName =
+ ActivityManagerTestBase.getWindowName(activityName);
+
+ final boolean activityVisible = mAmState.isActivityVisible(activityComponentName);
+ final boolean windowVisible = mWmState.isWindowVisible(windowName);
+
+ if (visible) {
+ assertTrue("Activity=" + activityComponentName + " must be visible.", activityVisible);
+ assertTrue("Window=" + windowName + " must be visible.", windowVisible);
+ } else {
+ assertFalse("Activity=" + activityComponentName + " must NOT be visible.",
+ activityVisible);
+ assertFalse("Window=" + windowName + " must NOT be visible.", windowVisible);
+ }
+ }
}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
index f6019d2..b194e7d 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
@@ -31,14 +31,13 @@
private static final String AM_START_LAUNCH_TO_SIDE_ACTIVITY =
"am start -n android.server.app/." + LAUNCH_TO_SIDE_ACTIVITY_NAME;
- private static final String AM_FORCE_STOP_TEST = "am force-stop android.server.app";
private static final String AM_FORCE_STOP_SETTINGS = "am force-stop com.android.settings";
private static final String AM_MOVE_TASK = "am stack movetask ";
@Override
- protected void tearDown() {
+ protected void tearDown() throws Exception {
+ super.tearDown();
try {
- mDevice.executeShellCommand(AM_FORCE_STOP_TEST);
mDevice.executeShellCommand(AM_FORCE_STOP_SETTINGS);
} catch (DeviceNotAvailableException e) {
}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
index 4f16295..0542ba4 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
@@ -22,8 +22,6 @@
import java.lang.String;
public class ActivityManagerPinnedStackTests extends ActivityManagerTestBase {
- private static final boolean PRETEND_DEVICE_SUPPORTS_PIP = false;
-
private static final String PIP_ACTIVITY_COMPONENT_NAME = "android.server.app/.PipActivity";
private static final String PIP_WINDOW_NAME =
"android.server.app/android.server.app.PipActivity";
@@ -45,8 +43,6 @@
private static final String AM_START_PIP_ACTIVITY =
"am start -n " + PIP_ACTIVITY_COMPONENT_NAME;
- private static final String AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK =
- "am stack move-top-activity-to-pinned-stack 1 0 0 500 500";
private static final String AM_START_AUTO_ENTER_PIP_ACTIVITY =
"am start -n " + AUTO_ENTER_PIP_ACTIVITY_COMPONENT_NAME;
private static final String AM_START_ALWAYS_FOCUSABLE_PIP_ACTIVITY =
@@ -54,16 +50,6 @@
private static final String AM_START_LAUNCH_INTO_PINNED_STACK_PIP_ACTIVITY =
"am start -n " + LAUNCH_INTO_PINNED_STACK_PIP_ACTIVITY_COMPONENT_NAME;
- private static final String AM_FORCE_STOP_TEST_PACKAGE = "am force-stop android.server.app";
-
- @Override
- protected void tearDown() {
- try {
- mDevice.executeShellCommand(AM_FORCE_STOP_TEST_PACKAGE);
- } catch (DeviceNotAvailableException e) {
- }
- }
-
public void testEnterPictureInPictureMode() throws Exception {
final String[] commands = { AM_START_AUTO_ENTER_PIP_ACTIVITY };
pinnedStackTester(AUTO_ENTER_PIP_ACTIVITY_COMPONENT_NAME,
@@ -71,13 +57,14 @@
}
public void testMoveTopActivityToPinnedStack() throws Exception {
- final String[] commands = { AM_START_PIP_ACTIVITY, AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK };
+ final String[] commands = { AM_START_PIP_ACTIVITY,
+ AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND };
pinnedStackTester(PIP_ACTIVITY_COMPONENT_NAME, PIP_WINDOW_NAME, commands, false);
}
public void testAlwaysFocusablePipActivity() throws Exception {
- final String[] commands =
- { AM_START_ALWAYS_FOCUSABLE_PIP_ACTIVITY, AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK };
+ final String[] commands = { AM_START_ALWAYS_FOCUSABLE_PIP_ACTIVITY,
+ AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND };
pinnedStackTester(ALWAYS_FOCUSABLE_PIP_ACTIVITY_COMPONENT_NAME,
ALWAYS_FOCUSABLE_PIP_WINDOW_NAME, commands, true);
}
@@ -97,8 +84,6 @@
private void pinnedStackTester(String activiyName, String windowName, String[] commands,
boolean isFocusable) throws Exception {
- final boolean supportsPip = hasDeviceFeature("android.software.picture_in_picture")
- || PRETEND_DEVICE_SUPPORTS_PIP;
for (String command : commands) {
mDevice.executeShellCommand(command);
@@ -107,7 +92,7 @@
mAmWmState.computeState(mDevice);
mAmWmState.assertSanity();
- if (supportsPip) {
+ if (supportsPip()) {
mAmWmState.assertContainsStack("Must contain pinned stack.", PINNED_STACK_ID);
mAmWmState.assertFrontStack("Pinned stack must be the front stack.", PINNED_STACK_ID);
mAmWmState.assertFrontWindow("Pinned window must be the front window.", windowName);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
index a4ec55b..785e487 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
@@ -34,19 +34,10 @@
private static final String SLOW_CREATE_ACTIVITY_NAME = "SlowCreateActivity";
private static final String NO_RELAUNCH_ACTIVITY_NAME = "NoRelaunchActivity";
- private static final String AM_FORCE_STOP_TEST = "am force-stop android.server.app";
private static final String AM_MOVE_TASK = "am stack movetask ";
private List<String> mTempWindowTokens = new ArrayList();
- @Override
- protected void tearDown() {
- try {
- mDevice.executeShellCommand(AM_FORCE_STOP_TEST);
- } catch (DeviceNotAvailableException e) {
- }
- }
-
public void testReplaceWindow_Dock_Relaunch() throws Exception {
testReplaceWindow_Dock(true);
}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
index 7181fdd..7939c06 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
@@ -182,6 +182,19 @@
return mStacks.size();
}
+ boolean isActivityVisible(String activityName) {
+ for (ActivityStack stack : mStacks) {
+ for (ActivityTask task : stack.mTasks) {
+ for (Activity activity : task.mActivities) {
+ if (activity.name.equals(activityName)) {
+ return activity.visible;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
static class ActivityStack extends ActivityContainer {
private static final Pattern TASK_ID_PATTERN = Pattern.compile("Task id #(\\d+)");
@@ -269,11 +282,21 @@
private static final Pattern ORIG_ACTIVITY_PATTERN = Pattern.compile("origActivity=(\\S+)");
private static final Pattern REAL_ACTIVITY_PATTERN = Pattern.compile("realActivity=(\\S+)");
+ private static final Pattern ACTIVITY_NAME_PATTERN = Pattern.compile(
+ "\\* Hist #(\\d+)\\: ActivityRecord\\{(\\S+) u(\\d+) (\\S+) t(\\d+)\\}");
+
+ private static final Pattern TASK_TYPE_PATTERN = Pattern.compile("autoRemoveRecents=(\\S+) "
+ + "isPersistable=(\\S+) numFullscreen=(\\d+) taskType=(\\d+) "
+ + "mTaskToReturnTo=(\\d+)");
+
int mTaskId;
int mStackId;
Rectangle mLastNonFullscreenBounds;
String mRealActivity;
String mOrigActivity;
+ ArrayList<Activity> mActivities = new ArrayList();
+ int mTaskType = -1;
+ int mReturnToType = -1;
private ActivityTask() {
}
@@ -300,8 +323,21 @@
}
private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+ final List<Pattern> activityExitPatterns = new ArrayList();
+ Collections.addAll(activityExitPatterns, exitPatterns);
+ activityExitPatterns.add(ACTIVITY_NAME_PATTERN);
+ final Pattern[] activityExitPatternsArray =
+ activityExitPatterns.toArray(new Pattern[activityExitPatterns.size()]);
while (!doneExtracting(dump, exitPatterns)) {
+ final Activity activity =
+ Activity.create(dump, ACTIVITY_NAME_PATTERN, activityExitPatternsArray);
+
+ if (activity != null) {
+ mActivities.add(activity);
+ continue;
+ }
+
final String line = dump.pop().trim();
if (extractFullscreen(line)) {
@@ -346,6 +382,73 @@
}
continue;
}
+
+ matcher = TASK_TYPE_PATTERN.matcher(line);
+ if (matcher.matches()) {
+ CLog.logAndDisplay(INFO, line);
+ mTaskType = Integer.valueOf(matcher.group(4));
+ mReturnToType = Integer.valueOf(matcher.group(5));
+ continue;
+ }
+ }
+ }
+ }
+
+ static class Activity {
+ private static final Pattern VISIBILITY_PATTERN = Pattern.compile(
+ "keysPaused=(\\S+) inHistory=(\\S+) visible=(\\S+) sleeping=(\\S+) idle=(\\S+)");
+ private static final Pattern FRONT_OF_TASK_PATTERN = Pattern.compile("frontOfTask=(\\S+) "
+ + "task=TaskRecord\\{(\\S+) #(\\d+) A=(\\S+) U=(\\d+) StackId=(\\d+) sz=(\\d+)\\}");
+
+ String name;
+ boolean visible;
+ boolean frontOfTask;
+
+ private Activity() {
+ }
+
+ static Activity create(
+ LinkedList<String> dump, Pattern activityNamePattern, Pattern[] exitPatterns) {
+ final String line = dump.peek().trim();
+
+ final Matcher matcher = activityNamePattern.matcher(line);
+ if (!matcher.matches()) {
+ // Not an activity.
+ return null;
+ }
+ // For the activity name line we just read.
+ dump.pop();
+
+ final Activity activity = new Activity();
+ CLog.logAndDisplay(INFO, line);
+ activity.name = matcher.group(4);
+ CLog.logAndDisplay(INFO, activity.name);
+ activity.extract(dump, exitPatterns);
+ return activity;
+ }
+
+ private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
+
+ while (!doneExtracting(dump, exitPatterns)) {
+ final String line = dump.pop().trim();
+
+ Matcher matcher = VISIBILITY_PATTERN.matcher(line);
+ if (matcher.matches()) {
+ CLog.logAndDisplay(INFO, line);
+ final String visibleString = matcher.group(3);
+ visible = Boolean.valueOf(visibleString);
+ CLog.logAndDisplay(INFO, visibleString);
+ continue;
+ }
+
+ matcher = FRONT_OF_TASK_PATTERN.matcher(line);
+ if (matcher.matches()) {
+ CLog.logAndDisplay(INFO, line);
+ final String frontOfTaskString = matcher.group(1);
+ frontOfTask = Boolean.valueOf(frontOfTaskString);
+ CLog.logAndDisplay(INFO, frontOfTaskString);
+ continue;
+ }
}
}
}
@@ -358,20 +461,6 @@
protected boolean mFullscreen;
protected Rectangle mBounds;
- static boolean doneExtracting(LinkedList<String> dump, Pattern[] exitPatterns) {
- if (dump.isEmpty()) {
- return true;
- }
- final String line = dump.peek().trim();
-
- for (Pattern pattern : exitPatterns) {
- if (pattern.matcher(line).matches()) {
- return true;
- }
- }
- return false;
- }
-
boolean extractFullscreen(String line) {
final Matcher matcher = FULLSCREEN_PATTERN.matcher(line);
if (!matcher.matches()) {
@@ -405,4 +494,18 @@
return rect;
}
}
+
+ static boolean doneExtracting(LinkedList<String> dump, Pattern[] exitPatterns) {
+ if (dump.isEmpty()) {
+ return true;
+ }
+ final String line = dump.peek().trim();
+
+ for (Pattern pattern : exitPatterns) {
+ if (pattern.matcher(line).matches()) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
index 953d185..1f67520 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
@@ -29,6 +29,7 @@
import java.util.HashSet;
public abstract class ActivityManagerTestBase extends DeviceTestCase {
+ private static final boolean PRETEND_DEVICE_SUPPORTS_PIP = false;
// Constants copied from ActivityManager.StackId. If they are changed there, these must be
// updated.
@@ -54,16 +55,32 @@
private static final String AM_STACK_LIST = "am stack list";
+ private static final String AM_FORCE_STOP_TEST_PACKAGE = "am force-stop android.server.app";
+
+ protected static final String AM_START_HOME_ACTIVITY_COMMAND =
+ "am start -a android.intent.action.MAIN -c android.intent.category.HOME";
+
+ protected static final String AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND =
+ "am stack move-top-activity-to-pinned-stack 1 0 0 500 500";
+
/** A reference to the device under test. */
protected ITestDevice mDevice;
private HashSet<String> mAvailableFeatures;
protected static String getAmStartCmd(final String activityName) {
- return "am start -n android.server.app/." + activityName;
+ return "am start -n " + getActivityComponentName(activityName);
}
- protected static String getWindowName(final String activityName) {
+ protected static String getAmStartCmdOverHome(final String activityName) {
+ return "am start --activity-task-on-home -n " + getActivityComponentName(activityName);
+ }
+
+ static String getActivityComponentName(final String activityName) {
+ return "android.server.app/." + activityName;
+ }
+
+ static String getWindowName(final String activityName) {
return "android.server.app/android.server.app." + activityName;
}
@@ -77,6 +94,15 @@
mDevice = getDevice();
}
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ try {
+ mDevice.executeShellCommand(AM_FORCE_STOP_TEST_PACKAGE);
+ } catch (DeviceNotAvailableException e) {
+ }
+ }
+
// Utility method for debugging, not used directly here, but useful, so kept around.
protected void printStacksAndTasks() throws DeviceNotAvailableException {
CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
@@ -104,6 +130,11 @@
return -1;
}
+ protected boolean supportsPip() throws DeviceNotAvailableException {
+ return hasDeviceFeature("android.software.picture_in_picture")
+ || PRETEND_DEVICE_SUPPORTS_PIP;
+ }
+
protected boolean hasDeviceFeature(String requiredFeature) throws DeviceNotAvailableException {
if (mAvailableFeatures == null) {
// TODO: Move this logic to ITestDevice.
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerVisibleBehindActivityTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerVisibleBehindActivityTests.java
new file mode 100644
index 0000000..1ceba88
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerVisibleBehindActivityTests.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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.server.cts;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import java.lang.Exception;
+import java.lang.String;
+
+public class ActivityManagerVisibleBehindActivityTests extends ActivityManagerTestBase {
+ private static final String TRANSLUCENT_ACTIVITY = "TranslucentActivity";
+ private static final String VISIBLE_BEHIND_ACTIVITY = "VisibleBehindActivity";
+ private static final String PIP_ACTIVITY = "PipActivity";
+
+ public void testVisibleBehindHomeActivity() throws Exception {
+ mDevice.executeShellCommand(getAmStartCmd(VISIBLE_BEHIND_ACTIVITY));
+ mDevice.executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
+
+ mAmWmState.computeState(mDevice);
+ mAmWmState.assertSanity();
+ mAmWmState.assertContainsStack(
+ "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+ mAmWmState.assertFrontStack("Home stack must be the front stack.", HOME_STACK_ID);
+ mAmWmState.assertVisibility(
+ VISIBLE_BEHIND_ACTIVITY, hasDeviceFeature("android.software.leanback"));
+ }
+
+ public void testVisibleBehindOtherActivity_NotOverHome() throws Exception {
+ mDevice.executeShellCommand(getAmStartCmd(VISIBLE_BEHIND_ACTIVITY));
+ mDevice.executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
+
+ mAmWmState.computeState(mDevice);
+ mAmWmState.assertSanity();
+ mAmWmState.assertVisibility(VISIBLE_BEHIND_ACTIVITY, true);
+ mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+ }
+
+ public void testVisibleBehindOtherActivity_OverHome() throws Exception {
+ mDevice.executeShellCommand(getAmStartCmdOverHome(VISIBLE_BEHIND_ACTIVITY));
+ mDevice.executeShellCommand(getAmStartCmdOverHome(TRANSLUCENT_ACTIVITY));
+
+ mAmWmState.computeState(mDevice);
+ mAmWmState.assertSanity();
+ mAmWmState.assertVisibility(VISIBLE_BEHIND_ACTIVITY, true);
+ mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+ }
+
+ public void testTranslucentActivityOnTopOfPinnedStack() throws Exception {
+ if (!supportsPip()) {
+ return;
+ }
+
+ mDevice.executeShellCommand(getAmStartCmdOverHome(PIP_ACTIVITY));
+ mDevice.executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
+ mDevice.executeShellCommand(getAmStartCmdOverHome(TRANSLUCENT_ACTIVITY));
+ mDevice.executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
+
+ mAmWmState.computeState(mDevice);
+ mAmWmState.assertSanity();
+ mAmWmState.assertFrontStack("Pinned stack must be the front stack.", PINNED_STACK_ID);
+ mAmWmState.assertVisibility(PIP_ACTIVITY, true);
+ mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
+ }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
index 169e245..949dc9b 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
@@ -213,6 +213,15 @@
return false;
}
+ boolean isWindowVisible(String windowName) {
+ for (String window : mWindows) {
+ if (window.equals(windowName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void reset() {
mSysDump.clear();
mStacks.clear();