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