1 /* 2 * Copyright (C) 2010 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.tv.settings.deviceadmin; 18 19 import android.app.Activity; 20 import android.app.admin.DeviceAdminInfo; 21 import android.app.admin.DeviceAdminReceiver; 22 import android.app.admin.DevicePolicyManager; 23 import android.app.settings.SettingsEnums; 24 import android.content.ComponentName; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.pm.ActivityInfo; 28 import android.content.pm.ApplicationInfo; 29 import android.content.pm.PackageInfo; 30 import android.content.pm.PackageManager; 31 import android.content.pm.PackageManager.NameNotFoundException; 32 import android.content.pm.ResolveInfo; 33 import android.os.Bundle; 34 import android.os.UserHandle; 35 import android.util.EventLog; 36 import android.util.Log; 37 38 import org.xmlpull.v1.XmlPullParserException; 39 40 import java.io.IOException; 41 import java.util.List; 42 43 public class DeviceAdminAdd extends Activity { 44 static final String TAG = "DeviceAdminAdd"; 45 46 DevicePolicyManager mDPM; 47 DeviceAdminInfo mDeviceAdmin; 48 String mProfileOwnerName; 49 50 boolean mRefreshing; 51 boolean mAddingProfileOwner; 52 53 @Override onCreate(Bundle icicle)54 protected void onCreate(Bundle icicle) { 55 super.onCreate(icicle); 56 57 mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE); 58 PackageManager packageManager = getPackageManager(); 59 60 if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 61 Log.w(TAG, "Cannot start ADD_DEVICE_ADMIN as a new task"); 62 finish(); 63 return; 64 } 65 66 String action = getIntent().getAction(); 67 ComponentName who = (ComponentName)getIntent().getParcelableExtra( 68 DevicePolicyManager.EXTRA_DEVICE_ADMIN); 69 if (who == null) { 70 Log.w(TAG, "No component specified in " + action); 71 finish(); 72 return; 73 } 74 75 if (action != null && action.equals(DevicePolicyManager.ACTION_SET_PROFILE_OWNER)) { 76 setResult(RESULT_CANCELED); 77 setFinishOnTouchOutside(true); 78 mAddingProfileOwner = true; 79 mProfileOwnerName = 80 getIntent().getStringExtra(DevicePolicyManager.EXTRA_PROFILE_OWNER_NAME); 81 String callingPackage = getCallingPackage(); 82 if (callingPackage == null || !callingPackage.equals(who.getPackageName())) { 83 Log.e(TAG, "Unknown or incorrect caller"); 84 finish(); 85 return; 86 } 87 try { 88 PackageInfo packageInfo = packageManager.getPackageInfo(callingPackage, 0); 89 if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 90 Log.e(TAG, "Cannot set a non-system app as a profile owner"); 91 finish(); 92 return; 93 } 94 } catch (NameNotFoundException nnfe) { 95 Log.e(TAG, "Cannot find the package " + callingPackage); 96 finish(); 97 return; 98 } 99 } 100 101 ActivityInfo ai; 102 try { 103 ai = packageManager.getReceiverInfo(who, PackageManager.GET_META_DATA); 104 } catch (PackageManager.NameNotFoundException e) { 105 Log.w(TAG, "Unable to retrieve device policy " + who, e); 106 finish(); 107 return; 108 } 109 110 // When activating, make sure the given component name is actually a valid device admin. 111 // No need to check this when deactivating, because it is safe to deactivate an active 112 // invalid device admin. 113 if (!mDPM.isAdminActive(who)) { 114 List<ResolveInfo> avail = packageManager.queryBroadcastReceivers( 115 new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), 116 PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS); 117 int count = avail == null ? 0 : avail.size(); 118 boolean found = false; 119 for (int i=0; i<count; i++) { 120 ResolveInfo ri = avail.get(i); 121 if (ai.packageName.equals(ri.activityInfo.packageName) 122 && ai.name.equals(ri.activityInfo.name)) { 123 try { 124 // We didn't retrieve the meta data for all possible matches, so 125 // need to use the activity info of this specific one that was retrieved. 126 ri.activityInfo = ai; 127 DeviceAdminInfo dpi = new DeviceAdminInfo(this, ri); 128 found = true; 129 } catch (XmlPullParserException e) { 130 Log.w(TAG, "Bad " + ri.activityInfo, e); 131 } catch (IOException e) { 132 Log.w(TAG, "Bad " + ri.activityInfo, e); 133 } 134 break; 135 } 136 } 137 if (!found) { 138 Log.w(TAG, "Request to add invalid device admin: " + who); 139 finish(); 140 return; 141 } 142 } 143 144 ResolveInfo ri = new ResolveInfo(); 145 ri.activityInfo = ai; 146 try { 147 mDeviceAdmin = new DeviceAdminInfo(this, ri); 148 } catch (XmlPullParserException e) { 149 Log.w(TAG, "Unable to retrieve device policy " + who, e); 150 finish(); 151 return; 152 } catch (IOException e) { 153 Log.w(TAG, "Unable to retrieve device policy " + who, e); 154 finish(); 155 return; 156 } 157 158 if (mAddingProfileOwner) { 159 // If we're trying to add a profile owner and user setup hasn't completed yet, no 160 // need to prompt for permission. Just add and finish 161 if (!mDPM.hasUserSetupCompleted()) { 162 addAndFinish(); 163 return; 164 } 165 166 // othewise, only the defined default supervision profile owner can be set after user 167 // setup. 168 final String supervisor = getString( 169 com.android.internal.R.string.config_defaultSupervisionProfileOwnerComponent); 170 if (supervisor == null) { 171 Log.w(TAG, "Unable to set profile owner post-setup, no default supervisor" 172 + "profile owner defined"); 173 finish(); 174 return; 175 } 176 177 final ComponentName supervisorComponent = ComponentName.unflattenFromString( 178 supervisor); 179 if (who.compareTo(supervisorComponent) != 0) { 180 Log.w(TAG, "Unable to set non-default profile owner post-setup " + who); 181 finish(); 182 return; 183 } else { 184 addAndFinish(); 185 } 186 } 187 188 // do not finish if ACTION_ADD_DEVICE_ADMIN, expected by some CTS tests 189 if (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN.equals(getIntent().getAction())) { 190 if (mDPM.isAdminActive(who)) { 191 if (mDPM.isRemovingAdmin(who, android.os.Process.myUserHandle().getIdentifier())) { 192 Log.w(TAG, "Requested admin is already being removed: " + who); 193 finish(); 194 return; 195 } 196 } 197 } else { 198 finish(); 199 } 200 } 201 addAndFinish()202 void addAndFinish() { 203 try { 204 logSpecialPermissionChange(true, mDeviceAdmin.getComponent().getPackageName()); 205 mDPM.setActiveAdmin(mDeviceAdmin.getComponent(), mRefreshing); 206 EventLog.writeEvent(1234, 207 mDeviceAdmin.getActivityInfo().applicationInfo.uid); 208 209 setResult(Activity.RESULT_OK); 210 } catch (RuntimeException e) { 211 // Something bad happened... could be that it was 212 // already set, though. 213 Log.w(TAG, "Exception trying to activate admin " 214 + mDeviceAdmin.getComponent(), e); 215 if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) { 216 setResult(Activity.RESULT_OK); 217 } 218 } 219 if (mAddingProfileOwner) { 220 try { 221 mDPM.setProfileOwner(mDeviceAdmin.getComponent(), 222 mProfileOwnerName, UserHandle.myUserId()); 223 } catch (RuntimeException re) { 224 setResult(Activity.RESULT_CANCELED); 225 } 226 } 227 finish(); 228 } 229 230 logSpecialPermissionChange(boolean allow, String packageName)231 void logSpecialPermissionChange(boolean allow, String packageName) { 232 int logCategory = allow ? SettingsEnums.APP_SPECIAL_PERMISSION_ADMIN_ALLOW : 233 SettingsEnums.APP_SPECIAL_PERMISSION_ADMIN_DENY; 234 } 235 } 236