1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.openglperf.cts;
18 
19 import android.app.Activity;
20 import android.app.ActivityManager;
21 import android.app.Instrumentation;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.test.ActivityInstrumentationTestCase2;
26 
27 import java.util.List;
28 
29 /**
30  * Tests OpenGl rendering after task switching to other GL-using application
31  * This test needs to control two applications and task switch between them to
32  * force losing and reclaiming GL context
33  */
34 public class GlAppSwitchTest extends
35         ActivityInstrumentationTestCase2<GlPlanetsActivity> {
36 
37     private static final String REPLICA_ISLAND_PACKAGE = "com.replica.replicaisland";
38     private static final String REPLICA_ISLAND_ACTIVITY = "AndouKun";
39     private static final long TASK_SWITCH_SLOW_WAIT_TIME_MS = 15 * 1000;
40     private static final int NUMBER_OF_TASK_SWITCHES_SLOW = 10;
41     private static final long TASK_SWITCH_FAST_WAIT_TIME_MS = 2000;
42     private static final int NUMBER_OF_TASK_SWITCHES_FAST = 50;
43     private static final String ERROR_REPLICA_ISLAND_DEAD = "replica island not running";
44     private static final int MAX_RUNNING_TASKS = 1000;
45 
46     private ActivityManager mActivityManager;
47 
48     private int mTaskIdSelf;
49     private int mTaskIdReplica;
50 
GlAppSwitchTest()51     public GlAppSwitchTest() {
52         super(GlPlanetsActivity.class);
53     }
54 
testGlActivitySwitchingFast()55     public void testGlActivitySwitchingFast() throws InterruptedException {
56         runTaskSwitchTest(TASK_SWITCH_FAST_WAIT_TIME_MS, NUMBER_OF_TASK_SWITCHES_FAST);
57         // wait for more time at the last run to allow watch dog timer in replica island to kick
58         Thread.sleep(TASK_SWITCH_SLOW_WAIT_TIME_MS);
59         assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
60     }
61 
testGlActivitySwitchingSlow()62     public void testGlActivitySwitchingSlow() throws InterruptedException {
63         runTaskSwitchTest(TASK_SWITCH_SLOW_WAIT_TIME_MS, NUMBER_OF_TASK_SWITCHES_SLOW);
64     }
65 
66     @Override
setUp()67     protected void setUp() throws Exception {
68         super.setUp();
69         Instrumentation instrument = getInstrumentation();
70         Context context = instrument.getContext();
71 
72         // This is needed so that |mActivityManager.getRunningTasks(...)| is able to
73         // see tasks from |REPLICA_ISLAND_PACKAGE|.
74         instrument.getUiAutomation().adoptShellPermissionIdentity();
75 
76         mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
77 
78         Intent intentPlanets = new Intent();
79         intentPlanets.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_FRAMES, 0); //runs forever
80         intentPlanets.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_PLANETS, 4); // max load
81         setActivityIntent(intentPlanets);
82         Activity activity = getActivity();
83         instrument.waitForIdleSync();
84         mTaskIdSelf = activity.getTaskId();
85         // wait further to render some frames
86         Thread.sleep(1000);
87 
88         Intent intentIsland = new Intent(Intent.ACTION_MAIN);
89         intentIsland.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
90         intentIsland.addCategory(Intent.CATEGORY_LAUNCHER);
91         intentIsland.setComponent(new ComponentName(REPLICA_ISLAND_PACKAGE,
92                 REPLICA_ISLAND_PACKAGE + "." + REPLICA_ISLAND_ACTIVITY));
93         context.startActivity(intentIsland);
94         // wait to render some frames
95         Thread.sleep(5000);
96 
97         setReplicaIslandTask();
98     }
99 
100     @Override
tearDown()101     protected void tearDown() throws Exception {
102         showOrHideReplicaIsland(false);
103         super.tearDown();
104     }
105 
106     /**
107      * run foreground / background task switching between replica island and GlPlanetsActivity.
108      * @param waitTimeMs time to wait after each task switching
109      * @param numberOfSwitches number of task switches to run
110      * @throws InterruptedException
111      */
runTaskSwitchTest(long waitTimeMs, int numberOfSwitches)112     private void runTaskSwitchTest(long waitTimeMs, int numberOfSwitches)
113             throws InterruptedException {
114         boolean replicaForeground = false;
115         assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
116         for (int i = 0; i < numberOfSwitches; i++ ) {
117             showOrHideReplicaIsland(replicaForeground);
118             replicaForeground = !replicaForeground;
119             Thread.sleep(waitTimeMs);
120             assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
121         }
122     }
123 
setReplicaIslandTask()124     private void setReplicaIslandTask() {
125         boolean foundReplica = false;
126         List<ActivityManager.RunningTaskInfo> tasks =
127                 mActivityManager.getRunningTasks(MAX_RUNNING_TASKS);
128         for (ActivityManager.RunningTaskInfo info : tasks) {
129             String packageName = info.baseActivity.getPackageName();
130             if (packageName.contentEquals(REPLICA_ISLAND_PACKAGE)) {
131                 foundReplica = true;
132                 mTaskIdReplica = info.id;
133                 break;
134             }
135         }
136         assertTrue("cannot find replica island running", foundReplica);
137     }
138 
isReplicaIslandRunning()139     private boolean isReplicaIslandRunning() {
140         boolean foundReplica = false;
141         List<ActivityManager.RunningTaskInfo> tasks =
142                 mActivityManager.getRunningTasks(MAX_RUNNING_TASKS);
143         for (ActivityManager.RunningTaskInfo info : tasks) {
144             String packageName = info.baseActivity.getPackageName();
145             if (packageName.contentEquals(REPLICA_ISLAND_PACKAGE)) {
146                 foundReplica = true;
147                 break;
148             }
149         }
150         return foundReplica;
151     }
152 
153     /**
154      * send replica island to foreground (when show = true) or background
155      * requires both replica island and GlPlanetsActivity to be alive.
156      * @param show
157      */
showOrHideReplicaIsland(boolean show)158     private void showOrHideReplicaIsland(boolean show) {
159         mActivityManager.moveTaskToFront(show ? mTaskIdReplica : mTaskIdSelf, 0);
160     }
161 }
162