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 package com.android.cts.verifier.screenpinning;
17 
18 import android.app.ActivityManager;
19 import android.os.Bundle;
20 import android.util.Log;
21 import android.view.View;
22 import android.view.View.OnClickListener;
23 import android.widget.Button;
24 import android.widget.LinearLayout;
25 import android.widget.TextView;
26 
27 import com.android.cts.verifier.PassFailButtons;
28 import com.android.cts.verifier.R;
29 
30 public class ScreenPinningTestActivity extends PassFailButtons.Activity {
31 
32     private static final String TAG = "ScreenPinningTestActivity";
33     private static final String KEY_CURRENT_TEST = "keyCurrentTest";
34 
35     private Test[] mTests;
36     private int mTestIndex;
37 
38     private ActivityManager mActivityManager;
39     private Button mNextButton;
40     private LinearLayout mInstructions;
41 
onCreate(Bundle savedInstanceState)42     protected void onCreate(Bundle savedInstanceState) {
43         super.onCreate(savedInstanceState);
44         setContentView(R.layout.screen_pinning);
45         setPassFailButtonClickListeners();
46 
47         mTests = new Test[] {
48             // Verify not already pinned.
49             mCheckStartedUnpinned,
50             // Enter pinning, verify pinned, try leaving and have the user exit.
51             mCheckStartPinning,
52             mCheckIsPinned,
53             mCheckTryLeave,
54             mCheckUnpin,
55             // Enter pinning, verify pinned, and use APIs to exit.
56             mCheckStartPinning,
57             mCheckIsPinned,
58             mCheckUnpinFromCode,
59             // All done.
60             mDone,
61         };
62 
63         mActivityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
64         mInstructions = (LinearLayout) findViewById(R.id.instructions_list);
65 
66         mNextButton = (Button) findViewById(R.id.next_button);
67         mNextButton.setOnClickListener(new OnClickListener() {
68             @Override
69             public void onClick(View v) {
70                 if ((mTestIndex >= 0) && (mTestIndex < mTests.length)) {
71                     mTests[mTestIndex].onNextClick();
72                 }
73             }
74         });
75 
76         // Don't allow pass until all tests complete.
77         findViewById(R.id.pass_button).setVisibility(View.GONE);
78 
79         // Figure out if we are in a test or starting from the beginning.
80         if (savedInstanceState != null && savedInstanceState.containsKey(KEY_CURRENT_TEST)) {
81             mTestIndex = savedInstanceState.getInt(KEY_CURRENT_TEST);
82         } else {
83             mTestIndex = 0;
84         }
85         // Display any pre-existing text.
86         for (int i = 0; i < mTestIndex; i++) {
87             mTests[i].showText();
88         }
89         mTests[mTestIndex].run();
90     };
91 
92     @Override
onSaveInstanceState(Bundle outState)93     protected void onSaveInstanceState(Bundle outState) {
94         outState.putInt(KEY_CURRENT_TEST, mTestIndex);
95     }
96 
97     @Override
onBackPressed()98     public void onBackPressed() {
99         // Block back button so we can test screen pinning exit functionality.
100         // Users can still leave by pressing fail (or when done the pass) button.
101     }
102 
show(int id)103     private void show(int id) {
104         TextView tv = new TextView(this);
105         tv.setPadding(10, 10, 10, 30);
106         tv.setText(id);
107         mInstructions.removeAllViews();
108         mInstructions.addView(tv);
109     }
110 
succeed()111     private void succeed() {
112         runOnUiThread(new Runnable() {
113             @Override
114             public void run() {
115                 mTestIndex++;
116                 if (mTestIndex < mTests.length) {
117                     mTests[mTestIndex].run();
118                 } else {
119                     mNextButton.setVisibility(View.GONE);
120                     findViewById(R.id.pass_button).setVisibility(View.VISIBLE);
121                 }
122             }
123         });
124     }
125 
error(int errorId)126     private void error(int errorId) {
127         error(errorId, new Throwable());
128     }
129 
error(final int errorId, final Throwable cause)130     private void error(final int errorId, final Throwable cause) {
131         runOnUiThread(new Runnable() {
132             @Override
133             public void run() {
134                 String error = getString(errorId);
135                 Log.d(TAG, error, cause);
136                 // No more instructions needed.
137                 findViewById(R.id.instructions_group).setVisibility(View.GONE);
138 
139                 ((TextView) findViewById(R.id.error_text)).setText(error);
140             }
141         });
142     }
143 
144     // Verify we don't start in screen pinning.
145     private final Test mCheckStartedUnpinned = new Test(0) {
146         public void run() {
147             if (mActivityManager.isInLockTaskMode()) {
148                 error(R.string.error_screen_already_pinned);
149             } else {
150                 succeed();
151             }
152         }
153     };
154 
155     // Start screen pinning by having the user click next then confirm it for us.
156     private final Test mCheckStartPinning = new Test(R.string.screen_pin_instructions) {
157         protected void onNextClick() {
158             startLockTask();
159             succeed();
160         }
161     };
162 
163     // Click next and check that we got pinned.
164     // Wait for the user to click next to verify that they got back from the prompt
165     // successfully.
166     private final Test mCheckIsPinned = new Test(R.string.screen_pin_check_pinned) {
167         protected void onNextClick() {
168             if (mActivityManager.isInLockTaskMode()) {
169                 succeed();
170             } else {
171                 error(R.string.error_screen_pinning_did_not_start);
172             }
173         }
174     };
175 
176     // Tell user to try to leave.
177     private final Test mCheckTryLeave = new Test(R.string.screen_pin_no_exit) {
178         protected void onNextClick() {
179             if (mActivityManager.isInLockTaskMode()) {
180                 succeed();
181             } else {
182                 error(R.string.error_screen_no_longer_pinned);
183             }
184         }
185     };
186 
187     // Verify that the user unpinned and it worked.
188     private final Test mCheckUnpin = new Test(R.string.screen_pin_exit) {
189         protected void onNextClick() {
190             if (!mActivityManager.isInLockTaskMode()) {
191                 succeed();
192             } else {
193                 error(R.string.error_screen_pinning_did_not_exit);
194             }
195         }
196     };
197 
198     // Unpin from code and check that it worked.
199     private final Test mCheckUnpinFromCode = new Test(0) {
200         protected void run() {
201             if (!mActivityManager.isInLockTaskMode()) {
202                 error(R.string.error_screen_pinning_did_not_start);
203                 return;
204             }
205             stopLockTask();
206             if (!mActivityManager.isInLockTaskMode()) {
207                 succeed();
208             } else {
209                 error(R.string.error_screen_pinning_couldnt_exit);
210             }
211         };
212     };
213 
214     private final Test mDone = new Test(R.string.screen_pinning_done) {
215         protected void run() {
216             showText();
217             succeed();
218         };
219     };
220 
221     private abstract class Test {
222         private final int mResId;
223 
Test(int showId)224         public Test(int showId) {
225             mResId = showId;
226         }
227 
run()228         protected void run() {
229             showText();
230         }
231 
showText()232         public void showText() {
233             if (mResId == 0) {
234                 return;
235             }
236             show(mResId);
237         }
238 
onNextClick()239         protected void onNextClick() {
240         }
241     }
242 
243 }
244