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 com.android.cts.verifier.managedprovisioning; 18 19 import static android.os.UserHandle.myUserId; 20 21 import android.app.admin.DevicePolicyManager; 22 import android.content.ActivityNotFoundException; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.pm.ApplicationInfo; 27 import android.content.pm.PackageManager; 28 import android.net.Uri; 29 import android.os.Bundle; 30 import android.os.UserManager; 31 import android.provider.Settings; 32 import android.util.Log; 33 import android.view.View; 34 import android.view.ViewGroup; 35 import android.widget.Button; 36 import android.widget.ImageView; 37 import android.widget.RadioGroup; 38 import android.widget.TextView; 39 import android.widget.Toast; 40 41 import com.android.cts.verifier.PassFailButtons; 42 import com.android.cts.verifier.R; 43 44 import java.util.Arrays; 45 46 public class PermissionLockdownTestActivity extends PassFailButtons.Activity 47 implements RadioGroup.OnCheckedChangeListener { 48 49 private static final String TAG = PermissionLockdownTestActivity.class.getSimpleName(); 50 51 private static final String PERMISSION_APP_PACKAGE = "com.android.cts.permissionapp"; 52 53 // Alias used for starting the activity from ByodFlowTestActivity (Managed profile tests). 54 static final String ACTIVITY_ALIAS 55 = "com.android.cts.verifier.managedprovisioning" + 56 ".ManagedProfilePermissionLockdownTestActivity"; 57 58 private static final String MANAGED_PROVISIONING_ACTION_PREFIX 59 = "com.android.cts.verifier.managedprovisioning.action."; 60 // Indicates that activity is started for device owner case. 61 static final String ACTION_CHECK_PERMISSION_LOCKDOWN 62 = MANAGED_PROVISIONING_ACTION_PREFIX + "CHECK_PERMISSION_LOCKDOWN"; 63 // Indicates that activity is started for profile owner case. 64 static final String ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN 65 = MANAGED_PROVISIONING_ACTION_PREFIX + "MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN"; 66 67 // Permission grant states will be set on these permissions. 68 private static final String[] CONTACTS_PERMISSIONS = new String[] { 69 android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.WRITE_CONTACTS 70 }; 71 72 private boolean mDeviceOwnerTest; 73 private DevicePolicyManager mDevicePolicyManager; 74 private ComponentName mAdmin; 75 76 @Override onCreate(Bundle savedInstanceState)77 public void onCreate(Bundle savedInstanceState) { 78 super.onCreate(savedInstanceState); 79 setContentView(R.layout.permission_lockdown); 80 81 Log.d(TAG, "created on user " + myUserId()); 82 83 mDevicePolicyManager = 84 (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); 85 mAdmin = DeviceAdminTestReceiver.getReceiverComponentName(); 86 87 mDeviceOwnerTest = 88 ACTION_CHECK_PERMISSION_LOCKDOWN.equals(getIntent().getAction()) ? true : false; 89 // Return immediately if we are neither profile nor device owner. 90 if (!isProfileOrDeviceOwner()) { 91 setTestResultAndFinish(false); 92 return; 93 } 94 95 buildLayout(); 96 } 97 buildLayout()98 private void buildLayout() { 99 PackageManager packageManager = getPackageManager(); 100 ApplicationInfo applicationInfo = null; 101 try { 102 // We need to make sure that the CtsPermissionApp is installed on the device or 103 // work profile. 104 applicationInfo = packageManager.getApplicationInfo( 105 PERMISSION_APP_PACKAGE, 0 /* flags */); 106 } catch (PackageManager.NameNotFoundException e) { 107 showToast(getString(R.string.package_not_found, PERMISSION_APP_PACKAGE)); 108 setTestResultAndFinish(false); 109 return; 110 } 111 112 ImageView packageIconImageView = (ImageView) findViewById(R.id.package_icon); 113 packageIconImageView.setImageDrawable(packageManager.getApplicationIcon(applicationInfo)); 114 TextView packageNameTextView = (TextView) findViewById(R.id.package_name); 115 packageNameTextView.setText(packageManager.getApplicationLabel(applicationInfo)); 116 117 TextView permissionNameTextView = (TextView) findViewById(R.id.permission_name); 118 permissionNameTextView.setText(Arrays.toString(CONTACTS_PERMISSIONS)); 119 120 // Get the current permission grant state for initializing the RadioGroup. 121 int readPermissionState = mDevicePolicyManager.getPermissionGrantState(mAdmin, 122 PERMISSION_APP_PACKAGE, CONTACTS_PERMISSIONS[0]); 123 int writePermissionState = mDevicePolicyManager.getPermissionGrantState(mAdmin, 124 PERMISSION_APP_PACKAGE, CONTACTS_PERMISSIONS[1]); 125 int currentPermissionState; 126 if (readPermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED || 127 writePermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED) { 128 currentPermissionState = DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED; 129 } else if (readPermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED || 130 writePermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED) { 131 currentPermissionState = DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED; 132 } else { 133 currentPermissionState = readPermissionState; 134 } 135 RadioGroup permissionRadioGroup = (RadioGroup) findViewById(R.id.permission_group); 136 switch (currentPermissionState) { 137 case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: { 138 permissionRadioGroup.check(R.id.permission_allow); 139 } break; 140 case DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT: { 141 permissionRadioGroup.check(R.id.permission_default); 142 } break; 143 case DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED: { 144 permissionRadioGroup.check(R.id.permission_deny); 145 } break; 146 } 147 permissionRadioGroup.setOnCheckedChangeListener(this); 148 149 addFinishOrPassFailButtons(); 150 } 151 addFinishOrPassFailButtons()152 private void addFinishOrPassFailButtons() { 153 // In case of device owner, we include the pass-fail buttons where as in case of profile 154 // owner, we add a finish button. 155 ViewGroup parentView = (ViewGroup) findViewById(R.id.permission_lockdown_activity); 156 if (mDeviceOwnerTest) { 157 parentView.addView( 158 getLayoutInflater().inflate(R.layout.pass_fail_buttons, parentView, false)); 159 setInfoResources(R.string.device_profile_owner_permission_lockdown_test, 160 R.string.device_owner_permission_lockdown_test_info, 0); 161 setPassFailButtonClickListeners(); 162 } else { 163 Button finishButton = new Button(this); 164 finishButton.setText(R.string.finish_button_label); 165 finishButton.setOnClickListener(new View.OnClickListener() { 166 @Override 167 public void onClick(View v) { 168 PermissionLockdownTestActivity.this.setTestResultAndFinish(false); 169 } 170 }); 171 parentView.addView(finishButton); 172 } 173 } 174 175 // Dispatches an intent to open the Settings screen for CtsPermissionApp. openSettings(View v)176 public void openSettings(View v) { 177 Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) 178 .setData(Uri.fromParts("package", PERMISSION_APP_PACKAGE, null)) 179 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 180 try { 181 startActivity(intent); 182 } catch (ActivityNotFoundException e) { 183 showToast(getString(R.string.activity_not_found, intent)); 184 } 185 } 186 187 @Override onCheckedChanged(RadioGroup radioGroup, int checkedId)188 public void onCheckedChanged(RadioGroup radioGroup, int checkedId) { 189 int permissionGrantState = -1; 190 switch (checkedId) { 191 case R.id.permission_allow: { 192 permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED; 193 } break; 194 case R.id.permission_default: { 195 permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT; 196 } break; 197 case R.id.permission_deny: { 198 permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED; 199 } break; 200 } 201 mDevicePolicyManager.setPermissionGrantState(mAdmin, PERMISSION_APP_PACKAGE, 202 CONTACTS_PERMISSIONS[0], permissionGrantState); 203 mDevicePolicyManager.setPermissionGrantState(mAdmin, PERMISSION_APP_PACKAGE, 204 CONTACTS_PERMISSIONS[1], permissionGrantState); 205 } 206 isProfileOrDeviceOwner()207 private boolean isProfileOrDeviceOwner() { 208 String adminPackage = mAdmin.getPackageName(); 209 // On headless system user mode, permissions are set in the current user, which is not 210 // device owner, but affiliated profile owner 211 boolean expectDeviceOwner = mDeviceOwnerTest && !UserManager.isHeadlessSystemUserMode(); 212 213 boolean isDeviceOwner = mDevicePolicyManager.isDeviceOwnerApp(adminPackage); 214 boolean isProfileOwner = mDevicePolicyManager.isProfileOwnerApp(adminPackage); 215 Log.d(TAG, "isProfileOrDeviceOwner(): userId=" + myUserId() 216 + ", mDeviceOwnerTest=" + mDeviceOwnerTest 217 + ", expectDeviceOwner=" + expectDeviceOwner 218 + ", isDeviceOwner=" + isDeviceOwner 219 + ", isProfileOwner=" + isProfileOwner); 220 221 if (expectDeviceOwner) { 222 if (!isDeviceOwner) { 223 showToast(getString(R.string.not_device_owner, adminPackage)); 224 return false; 225 } 226 return true; 227 } 228 if (!isProfileOwner) { 229 showToast(getString(R.string.not_profile_owner, adminPackage)); 230 return false; 231 } 232 return true; 233 } 234 showToast(String toast)235 private void showToast(String toast) { 236 Log.d(TAG, "showToast(" + toast + ")"); 237 Toast.makeText(this, toast, Toast.LENGTH_LONG).show(); 238 } 239 }