1 /*
2  * Copyright (C) 2016 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 com.android.cts.verifier.managedprovisioning;
18 
19 import android.content.Intent;
20 import android.content.pm.PackageManager;
21 import android.database.DataSetObserver;
22 import android.os.Bundle;
23 import android.provider.Settings;
24 import android.util.Pair;
25 import android.view.View;
26 
27 import com.android.cts.verifier.ArrayTestListAdapter;
28 import com.android.cts.verifier.PassFailButtons;
29 import com.android.cts.verifier.R;
30 import com.android.cts.verifier.TestListAdapter.TestListItem;
31 
32 import java.util.Arrays;
33 import java.util.List;
34 
35 /**
36  * Test class to verify transparency for policies enforced by device/profile owner.
37  */
38 public class PolicyTransparencyTestListActivity extends PassFailButtons.TestListActivity
39         implements View.OnClickListener {
40     public static final String ACTION_CHECK_POLICY_TRANSPARENCY =
41             "com.android.cts.verifier.managedprovisioning.action.CHECK_POLICY_TRANSPARENCY";
42 
43     public static final String EXTRA_MODE =
44             "com.android.cts.verifier.managedprovisioning.extra.mode";
45 
46     public static final int MODE_DEVICE_OWNER = 1;
47     public static final int MODE_MANAGED_PROFILE = 2;
48     public static final int MODE_MANAGED_USER = 4;
49 
50     /**
51      * Pairs of:
52      * <ul>
53      *   <li>An intent to start {@link PolicyTransparencyTestActivity}
54      *   <li>a label to show the user.
55      * </ul>
56      * These contain all the policies except for the user restriction ones.
57      */
58     private static final Pair<Intent, Integer>[] POLICIES;
59     static {
60         final String[] policyTests = new String[] {
61             PolicyTransparencyTestActivity.TEST_CHECK_AUTO_TIME_REQUIRED,
62             PolicyTransparencyTestActivity.TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION,
63             PolicyTransparencyTestActivity.TEST_CHECK_LOCK_SCREEN_INFO,
64             PolicyTransparencyTestActivity.TEST_CHECK_MAXIMUM_TIME_TO_LOCK,
65             PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE,
66             PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD
67         };
68         final String[] settingsIntentActions = new String[] {
69             Settings.ACTION_DATE_SETTINGS,
70             Settings.ACTION_SETTINGS,
71             Settings.ACTION_DISPLAY_SETTINGS,
72             Settings.ACTION_DISPLAY_SETTINGS,
73             Settings.ACTION_ACCESSIBILITY_SETTINGS,
74             Settings.ACTION_SETTINGS
75         };
76         final int[] policyLabels = new int[] {
77             R.string.set_auto_time_required,
78             R.string.disallow_keyguard_unredacted_notifications,
79             R.string.set_lock_screen_info,
80             R.string.set_maximum_time_to_lock,
81             R.string.set_permitted_accessibility_services,
82             R.string.set_permitted_input_methods
83         };
84         if (policyTests.length != settingsIntentActions.length ||
85                 policyTests.length != policyLabels.length) {
86             throw new AssertionError("Number of items in policyTests, "
87                     + " settingsIntentActions and policyLabels do not match");
88         }
89         POLICIES = new Pair[policyTests.length];
90         for (int i = 0; i < policyTests.length; ++i) {
91             final Intent intent =
92                     new Intent(PolicyTransparencyTestActivity.ACTION_SHOW_POLICY_TRANSPARENCY_TEST)
93                             .putExtra(PolicyTransparencyTestActivity.EXTRA_TEST, policyTests[i])
94                             .putExtra(PolicyTransparencyTestActivity.EXTRA_SETTINGS_INTENT_ACTION,
95                                     settingsIntentActions[i]);
96             POLICIES[i] = Pair.create(intent, policyLabels[i]);
97         }
98     }
99 
100     private static final List<String> ALSO_VALID_FOR_MANAGED_PROFILE = Arrays.asList(
101             PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE,
102             PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD);
103     private static final List<String> ALSO_VALID_FOR_MANAGED_USER = Arrays.asList(
104             PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE,
105             PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD);
106 
107     private int mMode;
108 
109     @Override
onCreate(Bundle savedInstanceState)110     protected void onCreate(Bundle savedInstanceState) {
111         super.onCreate(savedInstanceState);
112         setContentView(R.layout.policy_transparency_test_list);
113         setInfoResources(R.string.device_profile_owner_policy_transparency_test,
114                 R.string.device_profile_owner_policy_transparency_test_info, 0);
115         setPassFailButtonClickListeners();
116         setSupportMsgButtonClickListeners();
117 
118         if (!getIntent().hasExtra(EXTRA_MODE)) {
119             throw new RuntimeException("PolicyTransparencyTestListActivity started without extra "
120                     + EXTRA_MODE);
121         }
122         mMode = getIntent().getIntExtra(EXTRA_MODE, MODE_DEVICE_OWNER);
123         if (mMode != MODE_DEVICE_OWNER && mMode != MODE_MANAGED_PROFILE
124                 && mMode != MODE_MANAGED_USER) {
125             throw new RuntimeException("Unknown mode " + mMode);
126         }
127 
128         final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
129         addTestsToAdapter(adapter);
130         adapter.registerDataSetObserver(new DataSetObserver() {
131             @Override
132             public void onChanged() {
133                 updatePassButton();
134             }
135         });
136 
137         setTestListAdapter(adapter);
138     }
139 
addTestsToAdapter(final ArrayTestListAdapter adapter)140     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
141         for (String restriction :
142                 UserRestrictions.getUserRestrictionsForPolicyTransparency(mMode)) {
143             final Intent intent = UserRestrictions.getUserRestrictionTestIntent(this, restriction);
144             if (!UserRestrictions.isRestrictionValid(this, restriction)) {
145                 continue;
146             }
147             final String title = UserRestrictions.getRestrictionLabel(this, restriction);
148             String testId = getTestId(title);
149             intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId);
150             adapter.add(TestListItem.newTest(title, testId, intent, null));
151         }
152         for (Pair<Intent, Integer> policy : POLICIES) {
153             final Intent intent = policy.first;
154             String test = intent.getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST);
155             if (!isPolicyValid(test)) {
156                 continue;
157             }
158             if (mMode == MODE_MANAGED_PROFILE && !ALSO_VALID_FOR_MANAGED_PROFILE.contains(test)) {
159                 continue;
160             }
161             if (mMode == MODE_MANAGED_USER && !ALSO_VALID_FOR_MANAGED_USER.contains(test)) {
162                 continue;
163             }
164             final String title = getString(policy.second);
165             String testId = getTestId(title);
166             intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TITLE, title);
167             intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId);
168             adapter.add(TestListItem.newTest(title, testId, intent, null));
169         }
170     }
171 
getTestId(String title)172     private String getTestId(String title) {
173         if (mMode == MODE_DEVICE_OWNER) {
174             return "DO_" + title;
175         } else if (mMode == MODE_MANAGED_PROFILE) {
176             return "MP_" + title;
177         } else if (mMode == MODE_MANAGED_USER) {
178             return "MU_" + title;
179         }
180         throw new RuntimeException("Unknown mode " + mMode);
181     }
182 
isPolicyValid(String test)183     private boolean isPolicyValid(String test) {
184         final PackageManager pm = getPackageManager();
185         switch (test) {
186             case PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD:
187                 return pm.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS);
188             // TODO(b/189282625): replace FEATURE_WATCH with a more specific feature
189             case PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE:
190                 return (pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)
191                     && !pm.hasSystemFeature(PackageManager.FEATURE_WATCH));
192             // TODO(b/189282625): replace FEATURE_WATCH with a more specific feature
193             case PolicyTransparencyTestActivity.TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION:
194             case PolicyTransparencyTestActivity.TEST_CHECK_LOCK_SCREEN_INFO:
195             case PolicyTransparencyTestActivity.TEST_CHECK_MAXIMUM_TIME_TO_LOCK:
196                 return (pm.hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
197                     && !pm.hasSystemFeature(PackageManager.FEATURE_WATCH));
198             default:
199                 return true;
200         }
201     }
202 
setSupportMsgButtonClickListeners()203     private void setSupportMsgButtonClickListeners() {
204         findViewById(R.id.short_msg_button).setOnClickListener(this);
205         findViewById(R.id.long_msg_button).setOnClickListener(this);
206     }
207 
208     @Override
onClick(View view)209     public void onClick(View view) {
210         if (view.getId() == R.id.short_msg_button) {
211             final Intent intent = new Intent(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
212             intent.putExtra(SetSupportMessageActivity.EXTRA_SUPPORT_MSG_TYPE,
213                     SetSupportMessageActivity.TYPE_SHORT_MSG);
214             startActivity(intent);
215         } else if (view.getId() == R.id.long_msg_button) {
216             final Intent intent = new Intent(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
217             intent.putExtra(SetSupportMessageActivity.EXTRA_SUPPORT_MSG_TYPE,
218                     SetSupportMessageActivity.TYPE_LONG_MSG);
219             startActivity(intent);
220         }
221     }
222 
223     @Override
getTestId()224     public String getTestId() {
225         return getIntent().getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID);
226     }
227 
228     @Override
finish()229     public void finish() {
230         super.finish();
231         final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
232         intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND,
233                 CommandReceiverActivity.COMMAND_CLEAR_POLICIES);
234         intent.putExtra(PolicyTransparencyTestListActivity.EXTRA_MODE, mMode);
235         startActivity(intent);
236     }
237 }
238