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         mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
73 
74         Intent intentPlanets = new Intent();
75         intentPlanets.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_FRAMES, 0); //runs forever
76         intentPlanets.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_PLANETS, 4); // max load
77         setActivityIntent(intentPlanets);
78         Activity activity = getActivity();
79         instrument.waitForIdleSync();
80         mTaskIdSelf = activity.getTaskId();
81         // wait further to render some frames
82         Thread.sleep(1000);
83 
84         Intent intentIsland = new Intent(Intent.ACTION_MAIN);
85         intentIsland.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
86         intentIsland.addCategory(Intent.CATEGORY_LAUNCHER);
87         intentIsland.setComponent(new ComponentName(REPLICA_ISLAND_PACKAGE,
88                 REPLICA_ISLAND_PACKAGE + "." + REPLICA_ISLAND_ACTIVITY));
89         context.startActivity(intentIsland);
90         // wait to render some frames
91         Thread.sleep(5000);
92 
93         setReplicaIslandTask();
94     }
95 
96     @Override
tearDown()97     protected void tearDown() throws Exception {
98         showOrHideReplicaIsland(false);
99         super.tearDown();
100     }
101 
102     /**
103      * run foreground / background task switching between replica island and GlPlanetsActivity.
104      * @param waitTimeMs time to wait after each task switching
105      * @param numberOfSwitches number of task switches to run
106      * @throws InterruptedException
107      */
runTaskSwitchTest(long waitTimeMs, int numberOfSwitches)108     private void runTaskSwitchTest(long waitTimeMs, int numberOfSwitches)
109             throws InterruptedException {
110         boolean replicaForeground = false;
111         assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
112         for (int i = 0; i < numberOfSwitches; i++ ) {
113             showOrHideReplicaIsland(replicaForeground);
114             replicaForeground = !replicaForeground;
115             Thread.sleep(waitTimeMs);
116             assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
117         }
118     }
119 
setReplicaIslandTask()120     private void setReplicaIslandTask() {
121         boolean foundReplica = false;
122         List<ActivityManager.RunningTaskInfo> tasks =
123                 mActivityManager.getRunningTasks(MAX_RUNNING_TASKS);
124         for (ActivityManager.RunningTaskInfo info : tasks) {
125             String packageName = info.baseActivity.getPackageName();
126             if (packageName.contentEquals(REPLICA_ISLAND_PACKAGE)) {
127                 foundReplica = true;
128                 mTaskIdReplica = info.id;
129                 break;
130             }
131         }
132         assertTrue("cannot find replica island running", foundReplica);
133     }
134 
isReplicaIslandRunning()135     private boolean isReplicaIslandRunning() {
136         boolean foundReplica = false;
137         List<ActivityManager.RunningTaskInfo> tasks =
138                 mActivityManager.getRunningTasks(MAX_RUNNING_TASKS);
139         for (ActivityManager.RunningTaskInfo info : tasks) {
140             String packageName = info.baseActivity.getPackageName();
141             if (packageName.contentEquals(REPLICA_ISLAND_PACKAGE)) {
142                 foundReplica = true;
143                 break;
144             }
145         }
146         return foundReplica;
147     }
148 
149     /**
150      * send replica island to foreground (when show = true) or background
151      * requires both replica island and GlPlanetsActivity to be alive.
152      * @param show
153      */
showOrHideReplicaIsland(boolean show)154     private void showOrHideReplicaIsland(boolean show) {
155         mActivityManager.moveTaskToFront(show ? mTaskIdReplica : mTaskIdSelf, 0);
156     }
157 }
158