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