1 /* 2 * Copyright (C) 2017 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.admin; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.BroadcastReceiver; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.content.pm.PackageInfo; 26 import android.content.pm.PackageManager; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.provider.Settings; 30 import android.view.View; 31 import android.widget.Button; 32 import android.widget.ImageView; 33 import android.widget.TextView; 34 35 import com.android.cts.verifier.PassFailButtons; 36 import com.android.cts.verifier.R; 37 38 /** 39 * Test that checks that active device admins can be easily uninstalled via the app details screen 40 */ 41 public class DeviceAdminUninstallTestActivity extends PassFailButtons.Activity implements 42 View.OnClickListener { 43 44 private static final String TAG = DeviceAdminUninstallTestActivity.class.getSimpleName(); 45 private static final String ADMIN_PACKAGE_NAME = "com.android.cts.emptydeviceadmin"; 46 private static final String ADMIN_RECEIVER_CLASS_NAME = 47 "com.android.cts.emptydeviceadmin.EmptyDeviceAdmin"; 48 private static final String ADMIN_INSTALLED_BUNDLE_KEY = "admin_installed"; 49 private static final String ADMIN_ACTIVATED_BUNDLE_KEY = "admin_activated"; 50 private static final String ADMIN_REMOVED_BUNDLE_KEY = "admin_removed"; 51 52 private static final int REQUEST_ENABLE_ADMIN = 1; 53 private static final int REQUEST_UNINSTALL_ADMIN = 2; 54 55 private DevicePolicyManager mDevicePolicyManager; 56 57 private ImageView mInstallStatus; 58 private TextView mInstallAdminText; 59 private Button mAddDeviceAdminButton; 60 private ImageView mEnableStatus; 61 private Button mUninstallAdminButton; 62 private ImageView mUninstallStatus; 63 private boolean mAdminInstalled; 64 private boolean mAdminActivated; 65 private boolean mAdminRemoved; 66 private ComponentName mAdmin; 67 private final BroadcastReceiver mPackageAddedListener = new BroadcastReceiver() { 68 @Override 69 public void onReceive(Context context, Intent intent) { 70 final Uri uri = intent.getData(); 71 if (uri != null && ADMIN_PACKAGE_NAME.equals(uri.getSchemeSpecificPart())) { 72 onAdminPackageInstalled(); 73 } 74 } 75 }; 76 77 @Override 78 protected void onCreate(Bundle savedInstanceState) { 79 super.onCreate(savedInstanceState); 80 setContentView(R.layout.da_uninstall_test_main); 81 setInfoResources(R.string.da_uninstall_test, R.string.da_uninstall_test_info, -1); 82 setPassFailButtonClickListeners(); 83 mAdmin = new ComponentName(ADMIN_PACKAGE_NAME, ADMIN_RECEIVER_CLASS_NAME); 84 mDevicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); 85 86 if (savedInstanceState != null) { 87 mAdminInstalled = savedInstanceState.getBoolean(ADMIN_INSTALLED_BUNDLE_KEY, false); 88 mAdminActivated = savedInstanceState.getBoolean(ADMIN_ACTIVATED_BUNDLE_KEY, false); 89 mAdminRemoved = savedInstanceState.getBoolean(ADMIN_REMOVED_BUNDLE_KEY, false); 90 } else { 91 mAdminInstalled = isPackageInstalled(ADMIN_PACKAGE_NAME); 92 mAdminActivated = mDevicePolicyManager.isAdminActive(mAdmin); 93 } 94 mInstallStatus = findViewById(R.id.install_admin_status); 95 mInstallAdminText = findViewById(R.id.install_admin_instructions); 96 if (!mAdminInstalled) { 97 final IntentFilter packageAddedFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 98 packageAddedFilter.addDataScheme("package"); 99 registerReceiver(mPackageAddedListener, packageAddedFilter); 100 } 101 102 mEnableStatus = findViewById(R.id.enable_admin_status); 103 mAddDeviceAdminButton = findViewById(R.id.enable_device_admin_button); 104 mAddDeviceAdminButton.setOnClickListener(this); 105 106 mUninstallStatus = findViewById(R.id.uninstall_admin_status); 107 mUninstallAdminButton = findViewById(R.id.open_app_details_button); 108 mUninstallAdminButton.setOnClickListener(this); 109 } 110 111 private void onAdminPackageInstalled() { 112 mAdminInstalled = true; 113 updateWidgets(); 114 unregisterReceiver(mPackageAddedListener); 115 } 116 117 private boolean isPackageInstalled(String packageName) { 118 PackageInfo packageInfo = null; 119 try { 120 packageInfo = getPackageManager().getPackageInfo(packageName, 0); 121 } catch (PackageManager.NameNotFoundException exc) { 122 // Expected. 123 } 124 return packageInfo != null; 125 } 126 127 @Override 128 public void onClick(View v) { 129 if (v == mAddDeviceAdminButton) { 130 Intent securitySettingsIntent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); 131 securitySettingsIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdmin); 132 startActivityForResult(securitySettingsIntent, REQUEST_ENABLE_ADMIN); 133 } else if (v == mUninstallAdminButton) { 134 Intent appDetails = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 135 appDetails.setData(Uri.parse("package:" + ADMIN_PACKAGE_NAME)); 136 startActivityForResult(appDetails, REQUEST_UNINSTALL_ADMIN); 137 } 138 } 139 140 @Override 141 public void onActivityResult(int requestCode, int resultCode, Intent data) { 142 if (requestCode == REQUEST_ENABLE_ADMIN) { 143 mAdminActivated = mDevicePolicyManager.isAdminActive(mAdmin); 144 } else if (requestCode == REQUEST_UNINSTALL_ADMIN) { 145 mAdminRemoved = !isPackageInstalled(ADMIN_PACKAGE_NAME); 146 } 147 } 148 149 @Override 150 public void onResume() { 151 super.onResume(); 152 updateWidgets(); 153 } 154 155 @Override 156 public void onSaveInstanceState(Bundle icicle) { 157 icicle.putBoolean(ADMIN_INSTALLED_BUNDLE_KEY, mAdminInstalled); 158 icicle.putBoolean(ADMIN_ACTIVATED_BUNDLE_KEY, mAdminActivated); 159 icicle.putBoolean(ADMIN_REMOVED_BUNDLE_KEY, mAdminRemoved); 160 } 161 162 private void updateWidgets() { 163 mInstallStatus.setImageResource( 164 mAdminInstalled ? R.drawable.fs_good : R.drawable.fs_indeterminate); 165 mInstallAdminText.setText(mAdminInstalled ? R.string.da_admin_installed_status_text 166 : R.string.da_install_admin_instructions); 167 mInstallStatus.invalidate(); 168 mAddDeviceAdminButton.setEnabled(mAdminInstalled && !mAdminActivated); 169 mEnableStatus.setImageResource( 170 mAdminActivated ? R.drawable.fs_good : R.drawable.fs_indeterminate); 171 mEnableStatus.invalidate(); 172 173 mUninstallAdminButton.setEnabled(mAdminActivated && !mAdminRemoved); 174 mUninstallStatus.setImageResource( 175 mAdminRemoved ? R.drawable.fs_good : R.drawable.fs_indeterminate); 176 mUninstallStatus.invalidate(); 177 178 getPassButton().setEnabled(mAdminRemoved); 179 } 180 } 181