blob: 112a6e3eff6783e54bf8432b2b6594d8f670cecb [file] [log] [blame]
Rubin Xu55d22d42014-09-24 19:56:58 +01001/*
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
17package com.android.cts.verifier.managedprovisioning;
18
19import android.app.AlertDialog;
Rubin Xu55d22d42014-09-24 19:56:58 +010020import android.app.admin.DevicePolicyManager;
21import android.content.ActivityNotFoundException;
22import android.content.ComponentName;
23import android.content.Context;
24import android.content.DialogInterface;
25import android.content.Intent;
Rubin Xu55d22d42014-09-24 19:56:58 +010026import android.content.pm.PackageManager;
27import android.os.Bundle;
28import android.provider.Settings;
29import android.util.Log;
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +000030import android.view.LayoutInflater;
Rubin Xu55d22d42014-09-24 19:56:58 +010031import android.view.View;
32import android.view.ViewGroup;
33import android.view.View.OnClickListener;
34import android.widget.ArrayAdapter;
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +000035import android.widget.ImageView;
Rubin Xu55d22d42014-09-24 19:56:58 +010036import android.widget.ListView;
37import android.widget.TextView;
38import android.widget.Toast;
39
40import com.android.cts.verifier.PassFailButtons;
41import com.android.cts.verifier.R;
42import com.android.cts.verifier.TestListActivity;
43
44import java.util.ArrayList;
45import java.util.List;
46
47/**
48 * CTS verifier test for BYOD managed provisioning flow.
49 * This activity is responsible for starting the managed provisioning flow and verify the outcome of provisioning.
50 * It performs the following verifications:
51 * Full disk encryption is enabled.
52 * Profile owner is correctly installed.
53 * Profile owner shows up in the Settings app.
54 * Badged work apps show up in launcher.
55 * The first two verifications are performed automatically, by interacting with profile owner using
56 * cross-profile intents, while the last two are carried out manually by the user.
57 */
58public class ByodFlowTestActivity extends PassFailButtons.ListActivity {
59
60 private final String TAG = "ByodFlowTestActivity";
Sudheer Shanka98ff0002015-03-26 16:32:59 +000061 private static final int REQUEST_PROFILE_OWNER_STATUS = 1;
62 private static final int REQUEST_INTENT_FILTERS_STATUS = 2;
Rubin Xu55d22d42014-09-24 19:56:58 +010063
64 private ComponentName mAdminReceiverComponent;
65
Rubin Xuc2b00d82015-02-02 11:30:26 +000066 private TestAdapter mTestListAdapter;
Rubin Xu55d22d42014-09-24 19:56:58 +010067 private View mStartProvisioningButton;
68 private List<TestItem> mTests = new ArrayList<TestItem>();
69
70 protected DevicePolicyManager mDevicePolicyManager;
71
72 private TestItem mProfileOwnerInstalled;
Rubin Xuc2b00d82015-02-02 11:30:26 +000073 private TestItem mProfileAccountVisibleTest;
Rubin Xu55d22d42014-09-24 19:56:58 +010074 private TestItem mDeviceAdminVisibleTest;
75 private TestItem mWorkAppVisibleTest;
Alexandra Gherghinaaa24ed72014-10-08 01:11:32 +010076 private TestItem mCrossProfileIntentFiltersTest;
Robin Lee020f1852015-01-15 11:56:05 +000077 private TestItem mDisableNonMarketTest;
78 private TestItem mEnableNonMarketTest;
Alexandra Gherghina2c672b72015-01-22 11:20:23 +000079 private TestItem mWorkNotificationBadgedTest;
Kenny Guy68e7df92015-05-29 15:26:28 +010080 private TestItem mWorkStatusBarIconTest;
81 private TestItem mWorkStatusBarToastTest;
Rubin Xuc2b00d82015-02-02 11:30:26 +000082 private TestItem mAppSettingsVisibleTest;
83 private TestItem mLocationSettingsVisibleTest;
84 private TestItem mCredSettingsVisibleTest;
85 private TestItem mPrintSettingsVisibleTest;
Sudheer Shanka98ff0002015-03-26 16:32:59 +000086 private TestItem mIntentFiltersTest;
Sander Alewijnse7e24fda2015-03-26 17:41:57 +000087 private TestItem mCrossProfileImageCaptureSupportTest;
88 private TestItem mCrossProfileVideoCaptureSupportTest;
89 private TestItem mCrossProfileAudioCaptureSupportTest;
Rubin Xuc2b00d82015-02-02 11:30:26 +000090
91 private int mCurrentTestPosition;
Rubin Xu55d22d42014-09-24 19:56:58 +010092
93 @Override
94 protected void onCreate(Bundle savedInstanceState) {
95 super.onCreate(savedInstanceState);
96 mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
97 mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
98 disableComponent();
99
100 setContentView(R.layout.provisioning_byod);
101 setInfoResources(R.string.provisioning_byod, R.string.provisioning_byod_info, -1);
102 setPassFailButtonClickListeners();
103 getPassButton().setEnabled(false);
104 setResult(RESULT_CANCELED);
105
106 setupTests();
107
Rubin Xuc2b00d82015-02-02 11:30:26 +0000108 mTestListAdapter = new TestAdapter(this);
109 setListAdapter(mTestListAdapter);
110 mTestListAdapter.addAll(mTests);
111
112 mCurrentTestPosition = 0;
Rubin Xu55d22d42014-09-24 19:56:58 +0100113
114 mStartProvisioningButton = findViewById(R.id.byod_start);
115 mStartProvisioningButton.setOnClickListener(new OnClickListener() {
116 @Override
117 public void onClick(View v) {
118 startByodProvisioning();
119 }
120 });
121
122 // If we are started by managed provisioning (fresh managed provisioning after encryption
123 // reboot), redirect the user back to the main test list. This is because the test result
124 // is only saved by the parent TestListActivity, and if we did allow the user to proceed
125 // here, the test result would be lost when this activity finishes.
126 if (ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS.equals(getIntent().getAction())) {
127 startActivity(new Intent(this, TestListActivity.class));
128 // Calling super.finish() because we delete managed profile in our overridden of finish(),
129 // which is not what we want to do here.
130 super.finish();
131 } else {
132 queryProfileOwner(false);
133 }
134 }
135
136 @Override
137 protected void onNewIntent(Intent intent) {
138 // This is called when managed provisioning completes successfully without reboot.
139 super.onNewIntent(intent);
140 if (ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS.equals(intent.getAction())) {
141 handleStatusUpdate(intent);
142 }
143 }
144
145 @Override
146 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Rubin Xu55d22d42014-09-24 19:56:58 +0100147 super.onActivityResult(requestCode, resultCode, data);
Sudheer Shanka98ff0002015-03-26 16:32:59 +0000148 // Called after queryProfileOwner()
149 if (requestCode == REQUEST_PROFILE_OWNER_STATUS && resultCode == RESULT_OK) {
Rubin Xu55d22d42014-09-24 19:56:58 +0100150 handleStatusUpdate(data);
Sudheer Shanka98ff0002015-03-26 16:32:59 +0000151 // Called after checkIntentFilters()
152 } else if (requestCode == REQUEST_INTENT_FILTERS_STATUS) {
153 handleIntentFiltersStatus(resultCode);
Rubin Xu55d22d42014-09-24 19:56:58 +0100154 }
155 }
156
157 private void handleStatusUpdate(Intent data) {
158 boolean provisioned = data.getBooleanExtra(ByodHelperActivity.EXTRA_PROVISIONED, false);
159 setTestResult(mProfileOwnerInstalled, provisioned ? TestResult.Passed : TestResult.Failed);
160 }
161
162 @Override
163 public void finish() {
164 // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
165 // clean up the provisioned profile.
166 requestDeleteProfileOwner();
167 super.finish();
168 }
169
170 private void setupTests() {
171 mProfileOwnerInstalled = new TestItem(this, R.string.provisioning_byod_profileowner) {
172 @Override
173 public void performTest(ByodFlowTestActivity activity) {
174 queryProfileOwner(true);
175 }
176 };
177
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000178 /*
179 * To keep the image in this test up to date, use the instructions in
180 * {@link ByodIconSamplerActivity}.
181 */
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000182 mWorkAppVisibleTest = new TestItemWithIcon(this,
183 R.string.provisioning_byod_workapps_visible,
Rubin Xuc2b00d82015-02-02 11:30:26 +0000184 R.string.provisioning_byod_workapps_visible_instruction,
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000185 new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),
186 R.drawable.badged_icon);
187
188 mWorkNotificationBadgedTest = new TestItemWithIcon(this,
189 R.string.provisioning_byod_work_notification,
190 R.string.provisioning_byod_work_notification_instruction,
191 new Intent(WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION),
192 R.drawable.ic_corp_icon);
Rubin Xu55d22d42014-09-24 19:56:58 +0100193
Kenny Guy68e7df92015-05-29 15:26:28 +0100194 Intent workStatusIcon = new Intent(WorkStatusTestActivity.ACTION_WORK_STATUS_ICON);
195 workStatusIcon.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
196 mWorkStatusBarIconTest = new TestItemWithIcon(this,
197 R.string.provisioning_byod_work_status_icon,
198 R.string.provisioning_byod_work_status_icon_instruction,
199 workStatusIcon,
200 R.drawable.stat_sys_managed_profile_status);
201
202 Intent workStatusToast = new Intent(WorkStatusTestActivity.ACTION_WORK_STATUS_TOAST);
203 workStatusToast.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
204 mWorkStatusBarToastTest = new TestItem(this,
205 R.string.provisioning_byod_work_status_toast,
206 R.string.provisioning_byod_work_status_toast_instruction,
207 workStatusToast);
208
Robin Lee020f1852015-01-15 11:56:05 +0000209 mDisableNonMarketTest = new TestItem(this, R.string.provisioning_byod_nonmarket_deny,
210 R.string.provisioning_byod_nonmarket_deny_info,
211 new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
212 .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, false));
213
214 mEnableNonMarketTest = new TestItem(this, R.string.provisioning_byod_nonmarket_allow,
215 R.string.provisioning_byod_nonmarket_allow_info,
216 new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
217 .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, true));
218
Rubin Xuc2b00d82015-02-02 11:30:26 +0000219 mProfileAccountVisibleTest = new TestItem(this, R.string.provisioning_byod_profile_visible,
220 R.string.provisioning_byod_profile_visible_instruction,
221 new Intent(Settings.ACTION_SETTINGS));
222
223 mAppSettingsVisibleTest = new TestItem(this, R.string.provisioning_byod_app_settings,
224 R.string.provisioning_byod_app_settings_instruction,
225 new Intent(Settings.ACTION_APPLICATION_SETTINGS));
226
227 mDeviceAdminVisibleTest = new TestItem(this, R.string.provisioning_byod_admin_visible,
228 R.string.provisioning_byod_admin_visible_instruction,
229 new Intent(Settings.ACTION_SECURITY_SETTINGS));
230
231 mCredSettingsVisibleTest = new TestItem(this, R.string.provisioning_byod_cred_settings,
232 R.string.provisioning_byod_cred_settings_instruction,
233 new Intent(Settings.ACTION_SECURITY_SETTINGS));
234
235 mLocationSettingsVisibleTest = new TestItem(this,
236 R.string.provisioning_byod_location_settings,
237 R.string.provisioning_byod_location_settings_instruction,
238 new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
239
240 mPrintSettingsVisibleTest = new TestItem(this, R.string.provisioning_byod_print_settings,
241 R.string.provisioning_byod_print_settings_instruction,
242 new Intent(Settings.ACTION_PRINT_SETTINGS));
243
Alexandra Gherghinaaa24ed72014-10-08 01:11:32 +0100244 Intent intent = new Intent(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
Rubin Xuc2b00d82015-02-02 11:30:26 +0000245 Intent chooser = Intent.createChooser(intent,
246 getResources().getString(R.string.provisioning_cross_profile_chooser));
Alexandra Gherghinaaa24ed72014-10-08 01:11:32 +0100247 mCrossProfileIntentFiltersTest = new TestItem(this,
248 R.string.provisioning_byod_cross_profile,
249 R.string.provisioning_byod_cross_profile_instruction,
250 chooser);
251
Sudheer Shanka98ff0002015-03-26 16:32:59 +0000252 // Test for checking if the required intent filters are set during managed provisioning.
253 mIntentFiltersTest = new TestItem(this,
254 R.string.provisioning_byod_cross_profile_intent_filters) {
255 @Override
256 public void performTest(ByodFlowTestActivity activity) {
257 checkIntentFilters();
258 }
259 };
260
Rubin Xu55d22d42014-09-24 19:56:58 +0100261 mTests.add(mProfileOwnerInstalled);
Rubin Xuc2b00d82015-02-02 11:30:26 +0000262
263 // Badge related tests
Rubin Xu55d22d42014-09-24 19:56:58 +0100264 mTests.add(mWorkAppVisibleTest);
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000265 mTests.add(mWorkNotificationBadgedTest);
Kenny Guy68e7df92015-05-29 15:26:28 +0100266 mTests.add(mWorkStatusBarIconTest);
267 mTests.add(mWorkStatusBarToastTest);
Rubin Xuc2b00d82015-02-02 11:30:26 +0000268
269 // Settings related tests.
270 mTests.add(mProfileAccountVisibleTest);
271 mTests.add(mDeviceAdminVisibleTest);
272 mTests.add(mCredSettingsVisibleTest);
273 mTests.add(mAppSettingsVisibleTest);
274 mTests.add(mLocationSettingsVisibleTest);
275 mTests.add(mPrintSettingsVisibleTest);
276
Alexandra Gherghinaaa24ed72014-10-08 01:11:32 +0100277 mTests.add(mCrossProfileIntentFiltersTest);
Robin Lee020f1852015-01-15 11:56:05 +0000278 mTests.add(mDisableNonMarketTest);
279 mTests.add(mEnableNonMarketTest);
Sudheer Shanka98ff0002015-03-26 16:32:59 +0000280 mTests.add(mIntentFiltersTest);
Sander Alewijnse7e24fda2015-03-26 17:41:57 +0000281
282 if (canResolveIntent(ByodHelperActivity.getCaptureImageIntent())) {
283 // Capture image intent can be resolved in primary profile, so test.
284 mCrossProfileImageCaptureSupportTest = new TestItem(this,
285 R.string.provisioning_byod_capture_image_support,
286 R.string.provisioning_byod_capture_image_support_info,
287 new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE));
288 mTests.add(mCrossProfileImageCaptureSupportTest);
289 } else {
290 // Capture image intent cannot be resolved in primary profile, so skip test.
291 Toast.makeText(ByodFlowTestActivity.this,
292 R.string.provisioning_byod_no_image_capture_resolver, Toast.LENGTH_SHORT)
293 .show();
294 }
295
296 if (canResolveIntent(ByodHelperActivity.getCaptureVideoIntent())) {
297 // Capture video intent can be resolved in primary profile, so test.
298 mCrossProfileVideoCaptureSupportTest = new TestItem(this,
299 R.string.provisioning_byod_capture_video_support,
300 R.string.provisioning_byod_capture_video_support_info,
301 new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO));
302 mTests.add(mCrossProfileVideoCaptureSupportTest);
303 } else {
304 // Capture video intent cannot be resolved in primary profile, so skip test.
305 Toast.makeText(ByodFlowTestActivity.this,
306 R.string.provisioning_byod_no_video_capture_resolver, Toast.LENGTH_SHORT)
307 .show();
308 }
309
310 /* TODO: reinstate when bug b/20131958 is fixed
311 if (canResolveIntent(ByodHelperActivity.getCaptureAudioIntent())) {
312 // Capture audio intent can be resolved in primary profile, so test.
313 mCrossProfileAudioCaptureSupportTest = new TestItem(this,
314 R.string.provisioning_byod_capture_audio_support,
315 R.string.provisioning_byod_capture_audio_support_info,
316 new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_AUDIO));
317 mTests.add(mCrossProfileAudioCaptureSupportTest);
318 } else {
319 // Capture audio intent cannot be resolved in primary profile, so skip test.
320 Toast.makeText(ByodFlowTestActivity.this,
321 R.string.provisioning_byod_no_audio_capture_resolver, Toast.LENGTH_SHORT)
322 .show();
323 }
324 */
Rubin Xu55d22d42014-09-24 19:56:58 +0100325 }
326
327 @Override
328 protected void onListItemClick(ListView l, View v, int position, long id) {
329 super.onListItemClick(l, v, position, id);
Rubin Xuc2b00d82015-02-02 11:30:26 +0000330 mCurrentTestPosition = position;
Rubin Xu55d22d42014-09-24 19:56:58 +0100331 TestItem test = (TestItem) getListAdapter().getItem(position);
332 test.performTest(this);
333 }
334
Sander Alewijnse7e24fda2015-03-26 17:41:57 +0000335 // Return whether the intent can be resolved in the current profile
336 private boolean canResolveIntent(Intent intent) {
337 return intent.resolveActivity(getPackageManager()) != null;
338 }
339
Rubin Xu55d22d42014-09-24 19:56:58 +0100340 private void showManualTestDialog(final TestItem test) {
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000341 AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this)
Rubin Xu55d22d42014-09-24 19:56:58 +0100342 .setIcon(android.R.drawable.ic_dialog_info)
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000343 .setTitle(R.string.provisioning_byod)
Rubin Xu55d22d42014-09-24 19:56:58 +0100344 .setNeutralButton(R.string.provisioning_byod_go, null)
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000345 .setPositiveButton(R.string.pass_button_text, new AlertDialog.OnClickListener() {
Rubin Xu55d22d42014-09-24 19:56:58 +0100346 @Override
347 public void onClick(DialogInterface dialog, int which) {
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000348 clearRemainingState(test);
Rubin Xu55d22d42014-09-24 19:56:58 +0100349 setTestResult(test, TestResult.Passed);
350 }
351 })
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000352 .setNegativeButton(R.string.fail_button_text, new AlertDialog.OnClickListener() {
Rubin Xu55d22d42014-09-24 19:56:58 +0100353 @Override
354 public void onClick(DialogInterface dialog, int which) {
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000355 clearRemainingState(test);
Rubin Xu55d22d42014-09-24 19:56:58 +0100356 setTestResult(test, TestResult.Failed);
357 }
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000358 });
359 View customView = test.getCustomView();
360 if (customView != null) {
361 dialogBuilder.setView(customView);
362 } else {
363 dialogBuilder.setMessage(test.getManualTestInstruction());
364 }
Rubin Xuc2b00d82015-02-02 11:30:26 +0000365 final AlertDialog dialog = dialogBuilder.show();
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000366 // Note: Setting the OnClickListener on the Dialog rather than the Builder, prevents the
367 // dialog being dismissed on onClick.
Rubin Xu55d22d42014-09-24 19:56:58 +0100368 dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new OnClickListener() {
369 @Override
370 public void onClick(View v) {
Rubin Xuc2b00d82015-02-02 11:30:26 +0000371 try {
372 ByodFlowTestActivity.this.startActivity(test.getManualTestIntent());
373 } catch (ActivityNotFoundException e) {
374 Toast.makeText(ByodFlowTestActivity.this,
375 "Cannot start " + test.getManualTestIntent(), Toast.LENGTH_LONG).show();
376 setTestResult(test, TestResult.Failed);
377 dialog.dismiss();
378 }
Rubin Xu55d22d42014-09-24 19:56:58 +0100379 }
380 });
381 }
382
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000383 private void clearRemainingState(final TestItem test) {
384 if (WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION.equals(
385 test.getManualTestIntent().getAction())) {
Rubin Xuc2b00d82015-02-02 11:30:26 +0000386 try {
387 ByodFlowTestActivity.this.startActivity(new Intent(
388 WorkNotificationTestActivity.ACTION_CLEAR_WORK_NOTIFICATION));
389 } catch (ActivityNotFoundException e) {
390 // User shouldn't run this test before work profile is set up.
391 }
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000392 }
393 }
394
Rubin Xu55d22d42014-09-24 19:56:58 +0100395 private void setTestResult(TestItem test, TestResult result) {
396 test.setPassFailState(result);
397
398 boolean testSucceeds = true;
399 for(TestItem aTest : mTests) {
400 testSucceeds &= (aTest.getPassFailState() == TestResult.Passed);
401 }
402 getPassButton().setEnabled(testSucceeds);
Rubin Xuc2b00d82015-02-02 11:30:26 +0000403 mTestListAdapter.notifyDataSetChanged();
404
405 this.getListView().smoothScrollToPosition(mCurrentTestPosition + 1);
Rubin Xu55d22d42014-09-24 19:56:58 +0100406 }
407
408 private void startByodProvisioning() {
409 Intent sending = new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
Sudheer Shankab64e0dc2015-03-23 16:42:35 +0000410 sending.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
411 mAdminReceiverComponent);
Rubin Xu55d22d42014-09-24 19:56:58 +0100412
413 if (sending.resolveActivity(getPackageManager()) != null) {
414 // ManagedProvisioning must be started with startActivityForResult, but we don't
415 // care about the result, so passing 0 as a requestCode
416 startActivityForResult(sending, 0);
417 } else {
418 showToast(R.string.provisioning_byod_disabled);
419 }
420 }
421
422 private void queryProfileOwner(boolean showToast) {
423 try {
424 Intent intent = new Intent(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
Sudheer Shanka98ff0002015-03-26 16:32:59 +0000425 startActivityForResult(intent, REQUEST_PROFILE_OWNER_STATUS);
Rubin Xu55d22d42014-09-24 19:56:58 +0100426 }
427 catch (ActivityNotFoundException e) {
428 Log.d(TAG, "queryProfileOwner: ActivityNotFoundException", e);
429 setTestResult(mProfileOwnerInstalled, TestResult.Failed);
430 if (showToast) {
431 showToast(R.string.provisioning_byod_no_activity);
432 }
433 }
434 }
435
436 private void requestDeleteProfileOwner() {
437 try {
438 Intent intent = new Intent(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
439 startActivity(intent);
440 showToast(R.string.provisioning_byod_delete_profile);
441 }
442 catch (ActivityNotFoundException e) {
443 Log.d(TAG, "requestDeleteProfileOwner: ActivityNotFoundException", e);
444 }
445 }
446
Sudheer Shanka98ff0002015-03-26 16:32:59 +0000447 private void checkIntentFilters() {
448 try {
449 // We disable the ByodHelperActivity in the primary profile. So, this intent
450 // will be handled by the ByodHelperActivity in the managed profile.
451 Intent intent = new Intent(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS);
452 startActivityForResult(intent, REQUEST_INTENT_FILTERS_STATUS);
453 } catch (ActivityNotFoundException e) {
454 Log.d(TAG, "checkIntentFilters: ActivityNotFoundException", e);
455 setTestResult(mIntentFiltersTest, TestResult.Failed);
456 showToast(R.string.provisioning_byod_no_activity);
457 }
458 }
459
460 private void handleIntentFiltersStatus(int resultCode) {
461 // we use the resultCode from ByodHelperActivity in the managed profile to know if certain
462 // intents fired from the managed profile are forwarded.
463 final boolean intentFiltersSetForManagedIntents = (resultCode == RESULT_OK);
464 // Since the ByodFlowTestActivity is running in the primary profile, we directly use
465 // the IntentFiltersTestHelper to know if certain intents fired from the primary profile
466 // are forwarded.
467 final boolean intentFiltersSetForPrimaryIntents =
468 new IntentFiltersTestHelper(this).checkCrossProfileIntentFilters(
469 IntentFiltersTestHelper.FLAG_INTENTS_FROM_PRIMARY);
470 final boolean intentFiltersSet =
471 intentFiltersSetForPrimaryIntents & intentFiltersSetForManagedIntents;
472 setTestResult(mIntentFiltersTest,
473 intentFiltersSet ? TestResult.Passed : TestResult.Failed);
474 }
475
Rubin Xu55d22d42014-09-24 19:56:58 +0100476 private void disableComponent() {
477 // Disable app components in the current profile, so only the counterpart in the other profile
478 // can respond (via cross-profile intent filter)
479 getPackageManager().setComponentEnabledSetting(new ComponentName(
480 this, ByodHelperActivity.class),
481 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
482 PackageManager.DONT_KILL_APP);
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000483 getPackageManager().setComponentEnabledSetting(new ComponentName(
484 this, WorkNotificationTestActivity.class),
485 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
486 PackageManager.DONT_KILL_APP);
Kenny Guy68e7df92015-05-29 15:26:28 +0100487 getPackageManager().setComponentEnabledSetting(new ComponentName(
488 this, WorkStatusTestActivity.class),
489 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
490 PackageManager.DONT_KILL_APP);
Rubin Xu55d22d42014-09-24 19:56:58 +0100491 }
492
Rubin Xu55d22d42014-09-24 19:56:58 +0100493 private void showToast(int messageId) {
494 String message = getString(messageId);
495 Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
496 }
497
498 enum TestResult {
499 Unknown, Failed, Passed
500 }
501
502 static class TestItem {
503
504 private String mDisplayName;
505 private TestResult mPassed;
506 private boolean mManualTest;
507 private String mManualInstruction;
508 private Intent mManualIntent;
509
510 public TestItem(Context context, int nameResId) {
511 mDisplayName = context.getString(nameResId);
512 mPassed = TestResult.Unknown;
513 mManualTest = false;
514 }
515
516 public void performTest(ByodFlowTestActivity activity) {
517 if (isManualTest()) {
518 activity.showManualTestDialog(this);
519 }
520 }
521
522 public TestItem(Context context, int nameResId, int testInstructionResId, Intent testIntent) {
523 mDisplayName = context.getString(nameResId);
524 mPassed = TestResult.Unknown;
525 mManualTest = true;
526 mManualInstruction = context.getString(testInstructionResId);
527 mManualIntent = testIntent;
528 }
529
530 @Override
531 public String toString() {
532 return mDisplayName;
533 }
534
535 TestResult getPassFailState() {
536 return mPassed;
537 }
538
539 void setPassFailState(TestResult state) {
540 mPassed = state;
541 }
542
543 public boolean isManualTest() {
544 return mManualTest;
545 }
546
547 public String getManualTestInstruction() {
548 return mManualInstruction;
549 }
550
551 public Intent getManualTestIntent() {
552 return mManualIntent;
553 }
Alexandra Gherghina9c1c5a52014-12-09 12:55:23 +0000554
555 public View getCustomView() {
556 return null;
557 }
Rubin Xu55d22d42014-09-24 19:56:58 +0100558 }
559
Alexandra Gherghina2c672b72015-01-22 11:20:23 +0000560 static class TestItemWithIcon extends TestItem {
561
562 private int mImageResId;
563 private Context mContext;
564
565 public TestItemWithIcon(Context context, int nameResId, int testInstructionResId,
566 Intent testIntent, int imageResId) {
567 super(context, nameResId, testInstructionResId, testIntent);
568 mContext = context;
569 mImageResId = imageResId;
570 }
571
572 @Override
573 public View getCustomView() {
574 LayoutInflater layoutInflater = LayoutInflater.from(mContext);
575 View view = layoutInflater.inflate(R.layout.byod_custom_view,
576 null /* root */);
577 ((ImageView) view.findViewById(R.id.sample_icon)).setImageResource(mImageResId);
578 ((TextView) view.findViewById(R.id.message)).setText(getManualTestInstruction());
579 return view;
580 }
581 }
582
Rubin Xu55d22d42014-09-24 19:56:58 +0100583 static class TestAdapter extends ArrayAdapter<TestItem> {
584
585 public TestAdapter(Context context) {
586 super(context, android.R.layout.simple_list_item_1);
587 }
588
589 @Override
590 public View getView(int position, View convertView, ViewGroup parent) {
591 TextView view = (TextView) super.getView(position, convertView, parent);
592
593 TestItem item = getItem(position);
594 int backgroundResource = 0;
595 int iconResource = 0;
596 if (item.getPassFailState() == TestResult.Passed) {
597 backgroundResource = R.drawable.test_pass_gradient;
598 iconResource = R.drawable.fs_good;
599 } else if (item.getPassFailState() == TestResult.Failed){
600 backgroundResource = R.drawable.test_fail_gradient;
601 iconResource = R.drawable.fs_error;
602 }
603 view.setBackgroundResource(backgroundResource);
604 view.setPadding(10, 0, 10, 0);
605 view.setCompoundDrawablePadding(10);
606 view.setCompoundDrawablesWithIntrinsicBounds(0, 0, iconResource, 0);
607
608 return view;
609 }
610 }
Rubin Xu55d22d42014-09-24 19:56:58 +0100611}