1 /*
2  * Copyright (C) 2015 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.server.wm.app;
18 
19 import static android.server.wm.app.Components.TestActivity.COMMAND_NAVIGATE_UP_TO;
20 import static android.server.wm.app.Components.TestActivity.COMMAND_START_ACTIVITY;
21 import static android.server.wm.app.Components.TestActivity.EXTRA_CONFIG_ASSETS_SEQ;
22 import static android.server.wm.app.Components.TestActivity.EXTRA_FIXED_ORIENTATION;
23 import static android.server.wm.app.Components.TestActivity.EXTRA_INTENTS;
24 import static android.server.wm.app.Components.TestActivity.EXTRA_INTENT;
25 import static android.server.wm.app.Components.TestActivity.EXTRA_NO_IDLE;
26 import static android.server.wm.app.Components.TestActivity.TEST_ACTIVITY_ACTION_FINISH_SELF;
27 import static android.server.wm.app.Components.TestActivity.COMMAND_START_ACTIVITIES;
28 
29 import android.content.BroadcastReceiver;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.IntentFilter;
33 import android.content.res.Configuration;
34 import android.os.Bundle;
35 import android.os.Looper;
36 import android.os.Parcelable;
37 import android.util.Log;
38 import android.view.animation.Animation;
39 import android.view.animation.RotateAnimation;
40 import android.widget.ProgressBar;
41 
42 import java.util.Arrays;
43 
44 public class TestActivity extends AbstractLifecycleLogActivity {
45 
46     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
47         @Override
48         public void onReceive(Context context, Intent intent) {
49             if (intent != null && TEST_ACTIVITY_ACTION_FINISH_SELF.equals(intent.getAction())) {
50                 finish();
51             }
52         }
53     };
54 
55     @Override
onCreate(Bundle icicle)56     protected void onCreate(Bundle icicle) {
57         super.onCreate(icicle);
58 
59         // Set the fixed orientation if requested
60         if (getIntent().hasExtra(EXTRA_FIXED_ORIENTATION)) {
61             final int ori = Integer.parseInt(getIntent().getStringExtra(EXTRA_FIXED_ORIENTATION));
62             setRequestedOrientation(ori);
63         }
64 
65         if (getIntent().hasExtra(EXTRA_NO_IDLE)) {
66             preventActivityIdle();
67         }
68     }
69 
70     /** Starts a repeated animation on main thread to make its message queue non-empty. */
preventActivityIdle()71     private void preventActivityIdle() {
72         final ProgressBar progressBar = new ProgressBar(this);
73         progressBar.setIndeterminate(true);
74         setContentView(progressBar);
75         final RotateAnimation animation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF,
76                 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
77         animation.setRepeatCount(Animation.INFINITE);
78         progressBar.startAnimation(animation);
79 
80         Looper.myLooper().getQueue().addIdleHandler(() -> {
81             if (progressBar.isAnimating()) {
82                 throw new RuntimeException("Shouldn't receive idle while animating");
83             }
84             return false;
85         });
86     }
87 
88     @Override
onStart()89     protected void onStart() {
90         super.onStart();
91         registerReceiver(mReceiver, new IntentFilter(TEST_ACTIVITY_ACTION_FINISH_SELF));
92     }
93 
94     @Override
onResume()95     protected void onResume() {
96         super.onResume();
97         final Configuration configuration = getResources().getConfiguration();
98         dumpConfiguration(configuration);
99         dumpAssetSeqNumber(configuration);
100         dumpConfigInfo();
101     }
102 
103     @Override
onStop()104     protected void onStop() {
105         super.onStop();
106         unregisterReceiver(mReceiver);
107     }
108 
109     @Override
handleCommand(String command, Bundle data)110     public void handleCommand(String command, Bundle data) {
111         switch (command) {
112             case COMMAND_START_ACTIVITY:
113                 final Intent startIntent = data.getParcelable(EXTRA_INTENT);
114                 try {
115                     startActivity(startIntent);
116                 } catch (Exception e) {
117                     Log.w(getTag(), "Failed to startActivity: " + startIntent, e);
118                 }
119                 break;
120             case COMMAND_START_ACTIVITIES:
121                 final Parcelable[] intents = data.getParcelableArray(EXTRA_INTENTS);
122                 startActivities(Arrays.copyOf(intents, intents.length, Intent[].class));
123                 break;
124             case COMMAND_NAVIGATE_UP_TO:
125                 final Intent intent = data.getParcelable(EXTRA_INTENT);
126                 try {
127                     navigateUpTo(intent);
128                 } catch (Exception e) {
129                     // Expected if the target activity in not exported with different uid.
130                     Log.w(getTag(), "Failed to navigateUpTo: " + intent, e);
131                 }
132                 break;
133             default:
134                 super.handleCommand(command, data);
135         }
136     }
137 
138     @Override
onConfigurationChanged(Configuration newConfig)139     public void onConfigurationChanged(Configuration newConfig) {
140         super.onConfigurationChanged(newConfig);
141         dumpConfiguration(newConfig);
142         dumpAssetSeqNumber(newConfig);
143         dumpConfigInfo();
144     }
145 
146     @Override
onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig)147     public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
148         super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
149         dumpConfiguration(newConfig);
150         dumpAssetSeqNumber(newConfig);
151         dumpConfigInfo();
152     }
153 
dumpAssetSeqNumber(Configuration newConfig)154     private void dumpAssetSeqNumber(Configuration newConfig) {
155         withTestJournalClient(client -> {
156             final Bundle extras = new Bundle();
157             extras.putInt(EXTRA_CONFIG_ASSETS_SEQ, newConfig.assetsSeq);
158             client.putExtras(extras);
159         });
160     }
161 }
162