Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 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.settings; |
| 18 | |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 19 | import android.app.AppOpsManager; |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 20 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 21 | import org.xmlpull.v1.XmlPullParserException; |
| 22 | |
| 23 | import android.app.Activity; |
Dianne Hackborn | 4f25e1d | 2011-03-02 22:39:49 -0800 | [diff] [blame] | 24 | import android.app.ActivityManagerNative; |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 25 | import android.app.AlertDialog; |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 26 | import android.app.Dialog; |
Dianne Hackborn | 4037c7f | 2010-02-26 17:26:55 -0800 | [diff] [blame] | 27 | import android.app.admin.DeviceAdminInfo; |
| 28 | import android.app.admin.DeviceAdminReceiver; |
| 29 | import android.app.admin.DevicePolicyManager; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 30 | import android.content.ComponentName; |
| 31 | import android.content.Context; |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 32 | import android.content.DialogInterface; |
Dianne Hackborn | 39e64e7 | 2010-03-26 13:24:39 -0700 | [diff] [blame] | 33 | import android.content.Intent; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 34 | import android.content.pm.ActivityInfo; |
Amith Yamasani | 080f8db | 2014-08-13 11:11:44 -0700 | [diff] [blame] | 35 | import android.content.pm.ApplicationInfo; |
| 36 | import android.content.pm.PackageInfo; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 37 | import android.content.pm.PackageManager; |
Amith Yamasani | 080f8db | 2014-08-13 11:11:44 -0700 | [diff] [blame] | 38 | import android.content.pm.PackageManager.NameNotFoundException; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 39 | import android.content.pm.ResolveInfo; |
| 40 | import android.content.res.Resources; |
| 41 | import android.os.Bundle; |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 42 | import android.os.Handler; |
| 43 | import android.os.RemoteCallback; |
Dianne Hackborn | 4f25e1d | 2011-03-02 22:39:49 -0800 | [diff] [blame] | 44 | import android.os.RemoteException; |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 45 | import android.os.UserHandle; |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 46 | import android.text.TextUtils.TruncateAt; |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 47 | import android.util.EventLog; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 48 | import android.util.Log; |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 49 | import android.view.Display; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 50 | import android.view.View; |
| 51 | import android.view.ViewGroup; |
Fyodor Kupolov | 1c8600b | 2015-05-29 11:17:32 -0700 | [diff] [blame^] | 52 | import android.view.ViewTreeObserver; |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 53 | import android.view.WindowManager; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 54 | import android.widget.AppSecurityPermissions; |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 55 | import android.widget.Button; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 56 | import android.widget.ImageView; |
| 57 | import android.widget.TextView; |
| 58 | |
| 59 | import java.io.IOException; |
| 60 | import java.util.ArrayList; |
Dianne Hackborn | 8274b67 | 2013-05-22 11:29:36 -0700 | [diff] [blame] | 61 | import java.util.List; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 62 | |
| 63 | public class DeviceAdminAdd extends Activity { |
| 64 | static final String TAG = "DeviceAdminAdd"; |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 65 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 66 | static final int DIALOG_WARNING = 1; |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 67 | |
| 68 | private static final int MAX_ADD_MSG_LINES_PORTRAIT = 5; |
| 69 | private static final int MAX_ADD_MSG_LINES_LANDSCAPE = 2; |
| 70 | private static final int MAX_ADD_MSG_LINES = 15; |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 71 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 72 | Handler mHandler; |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 73 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 74 | DevicePolicyManager mDPM; |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 75 | AppOpsManager mAppOps; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 76 | DeviceAdminInfo mDeviceAdmin; |
Dianne Hackborn | b885afe | 2010-01-26 18:03:42 -0800 | [diff] [blame] | 77 | CharSequence mAddMsgText; |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 78 | String mProfileOwnerName; |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 79 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 80 | ImageView mAdminIcon; |
| 81 | TextView mAdminName; |
| 82 | TextView mAdminDescription; |
Dianne Hackborn | b885afe | 2010-01-26 18:03:42 -0800 | [diff] [blame] | 83 | TextView mAddMsg; |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 84 | TextView mProfileOwnerWarning; |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 85 | ImageView mAddMsgExpander; |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 86 | boolean mAddMsgEllipsized = true; |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 87 | TextView mAdminWarning; |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 88 | ViewGroup mAdminPolicies; |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 89 | Button mActionButton; |
Dianne Hackborn | 97de6bc | 2010-03-03 17:18:13 -0800 | [diff] [blame] | 90 | Button mCancelButton; |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 91 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 92 | boolean mAdding; |
Andy Stadler | 5cc0e41 | 2010-12-08 15:57:18 -0800 | [diff] [blame] | 93 | boolean mRefreshing; |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 94 | boolean mWaitingForRemoveMsg; |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 95 | boolean mAddingProfileOwner; |
Fyodor Kupolov | 7dc56bd | 2015-02-24 09:26:53 -0800 | [diff] [blame] | 96 | boolean mAdminPoliciesInitialized; |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 97 | int mCurSysAppOpMode; |
| 98 | int mCurToastAppOpMode; |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 99 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 100 | @Override |
| 101 | protected void onCreate(Bundle icicle) { |
| 102 | super.onCreate(icicle); |
| 103 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 104 | mHandler = new Handler(getMainLooper()); |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 105 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 106 | mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE); |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 107 | mAppOps = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE); |
Amith Yamasani | 080f8db | 2014-08-13 11:11:44 -0700 | [diff] [blame] | 108 | PackageManager packageManager = getPackageManager(); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 109 | |
Dianne Hackborn | 39e64e7 | 2010-03-26 13:24:39 -0700 | [diff] [blame] | 110 | if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { |
Andy Stadler | 5cc0e41 | 2010-12-08 15:57:18 -0800 | [diff] [blame] | 111 | Log.w(TAG, "Cannot start ADD_DEVICE_ADMIN as a new task"); |
Dianne Hackborn | 39e64e7 | 2010-03-26 13:24:39 -0700 | [diff] [blame] | 112 | finish(); |
| 113 | return; |
| 114 | } |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 115 | |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 116 | String action = getIntent().getAction(); |
| 117 | ComponentName who = (ComponentName)getIntent().getParcelableExtra( |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 118 | DevicePolicyManager.EXTRA_DEVICE_ADMIN); |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 119 | if (who == null) { |
| 120 | Log.w(TAG, "No component specified in " + action); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 121 | finish(); |
| 122 | return; |
| 123 | } |
Dianne Hackborn | 8274b67 | 2013-05-22 11:29:36 -0700 | [diff] [blame] | 124 | |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 125 | if (action != null && action.equals(DevicePolicyManager.ACTION_SET_PROFILE_OWNER)) { |
Amith Yamasani | 080f8db | 2014-08-13 11:11:44 -0700 | [diff] [blame] | 126 | setResult(RESULT_CANCELED); |
| 127 | setFinishOnTouchOutside(true); |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 128 | mAddingProfileOwner = true; |
| 129 | mProfileOwnerName = |
| 130 | getIntent().getStringExtra(DevicePolicyManager.EXTRA_PROFILE_OWNER_NAME); |
| 131 | String callingPackage = getCallingPackage(); |
| 132 | if (callingPackage == null || !callingPackage.equals(who.getPackageName())) { |
| 133 | Log.e(TAG, "Unknown or incorrect caller"); |
| 134 | finish(); |
| 135 | return; |
| 136 | } |
Amith Yamasani | 080f8db | 2014-08-13 11:11:44 -0700 | [diff] [blame] | 137 | try { |
| 138 | PackageInfo packageInfo = packageManager.getPackageInfo(callingPackage, 0); |
| 139 | if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { |
| 140 | Log.e(TAG, "Cannot set a non-system app as a profile owner"); |
| 141 | finish(); |
| 142 | return; |
| 143 | } |
| 144 | } catch (NameNotFoundException nnfe) { |
| 145 | Log.e(TAG, "Cannot find the package " + callingPackage); |
| 146 | finish(); |
| 147 | return; |
| 148 | } |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 149 | } |
| 150 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 151 | ActivityInfo ai; |
| 152 | try { |
Amith Yamasani | 080f8db | 2014-08-13 11:11:44 -0700 | [diff] [blame] | 153 | ai = packageManager.getReceiverInfo(who, PackageManager.GET_META_DATA); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 154 | } catch (PackageManager.NameNotFoundException e) { |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 155 | Log.w(TAG, "Unable to retrieve device policy " + who, e); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 156 | finish(); |
| 157 | return; |
| 158 | } |
Dianne Hackborn | 8274b67 | 2013-05-22 11:29:36 -0700 | [diff] [blame] | 159 | |
Alex Klyubin | 29de9d5 | 2013-06-06 14:56:24 -0700 | [diff] [blame] | 160 | // When activating, make sure the given component name is actually a valid device admin. |
| 161 | // No need to check this when deactivating, because it is safe to deactivate an active |
| 162 | // invalid device admin. |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 163 | if (!mDPM.isAdminActive(who)) { |
Amith Yamasani | 080f8db | 2014-08-13 11:11:44 -0700 | [diff] [blame] | 164 | List<ResolveInfo> avail = packageManager.queryBroadcastReceivers( |
Alex Klyubin | 29de9d5 | 2013-06-06 14:56:24 -0700 | [diff] [blame] | 165 | new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), |
Alex Klyubin | 681b21f | 2013-06-06 15:45:23 -0700 | [diff] [blame] | 166 | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS); |
Alex Klyubin | 29de9d5 | 2013-06-06 14:56:24 -0700 | [diff] [blame] | 167 | int count = avail == null ? 0 : avail.size(); |
| 168 | boolean found = false; |
| 169 | for (int i=0; i<count; i++) { |
| 170 | ResolveInfo ri = avail.get(i); |
| 171 | if (ai.packageName.equals(ri.activityInfo.packageName) |
| 172 | && ai.name.equals(ri.activityInfo.name)) { |
| 173 | try { |
| 174 | // We didn't retrieve the meta data for all possible matches, so |
| 175 | // need to use the activity info of this specific one that was retrieved. |
| 176 | ri.activityInfo = ai; |
| 177 | DeviceAdminInfo dpi = new DeviceAdminInfo(this, ri); |
| 178 | found = true; |
| 179 | } catch (XmlPullParserException e) { |
| 180 | Log.w(TAG, "Bad " + ri.activityInfo, e); |
| 181 | } catch (IOException e) { |
| 182 | Log.w(TAG, "Bad " + ri.activityInfo, e); |
| 183 | } |
| 184 | break; |
Dianne Hackborn | 8274b67 | 2013-05-22 11:29:36 -0700 | [diff] [blame] | 185 | } |
Dianne Hackborn | 8274b67 | 2013-05-22 11:29:36 -0700 | [diff] [blame] | 186 | } |
Alex Klyubin | 29de9d5 | 2013-06-06 14:56:24 -0700 | [diff] [blame] | 187 | if (!found) { |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 188 | Log.w(TAG, "Request to add invalid device admin: " + who); |
Alex Klyubin | 29de9d5 | 2013-06-06 14:56:24 -0700 | [diff] [blame] | 189 | finish(); |
| 190 | return; |
| 191 | } |
Dianne Hackborn | 8274b67 | 2013-05-22 11:29:36 -0700 | [diff] [blame] | 192 | } |
| 193 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 194 | ResolveInfo ri = new ResolveInfo(); |
| 195 | ri.activityInfo = ai; |
| 196 | try { |
Andy Stadler | 5cc0e41 | 2010-12-08 15:57:18 -0800 | [diff] [blame] | 197 | mDeviceAdmin = new DeviceAdminInfo(this, ri); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 198 | } catch (XmlPullParserException e) { |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 199 | Log.w(TAG, "Unable to retrieve device policy " + who, e); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 200 | finish(); |
| 201 | return; |
| 202 | } catch (IOException e) { |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 203 | Log.w(TAG, "Unable to retrieve device policy " + who, e); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 204 | finish(); |
| 205 | return; |
| 206 | } |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 207 | |
Andy Stadler | 5cc0e41 | 2010-12-08 15:57:18 -0800 | [diff] [blame] | 208 | // This admin already exists, an we have two options at this point. If new policy |
| 209 | // bits are set, show the user the new list. If nothing has changed, simply return |
| 210 | // "OK" immediately. |
| 211 | if (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN.equals(getIntent().getAction())) { |
| 212 | mRefreshing = false; |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 213 | if (mDPM.isAdminActive(who)) { |
Andy Stadler | 5cc0e41 | 2010-12-08 15:57:18 -0800 | [diff] [blame] | 214 | ArrayList<DeviceAdminInfo.PolicyInfo> newPolicies = mDeviceAdmin.getUsedPolicies(); |
| 215 | for (int i = 0; i < newPolicies.size(); i++) { |
| 216 | DeviceAdminInfo.PolicyInfo pi = newPolicies.get(i); |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 217 | if (!mDPM.hasGrantedPolicy(who, pi.ident)) { |
Andy Stadler | 5cc0e41 | 2010-12-08 15:57:18 -0800 | [diff] [blame] | 218 | mRefreshing = true; |
| 219 | break; |
| 220 | } |
| 221 | } |
| 222 | if (!mRefreshing) { |
| 223 | // Nothing changed (or policies were removed) - return immediately |
| 224 | setResult(Activity.RESULT_OK); |
| 225 | finish(); |
| 226 | return; |
| 227 | } |
| 228 | } |
| 229 | } |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 230 | |
| 231 | // If we're trying to add a profile owner and user setup hasn't completed yet, no |
| 232 | // need to prompt for permission. Just add and finish. |
| 233 | if (mAddingProfileOwner && !mDPM.hasUserSetupCompleted()) { |
| 234 | addAndFinish(); |
| 235 | return; |
| 236 | } |
| 237 | |
Andy Stadler | 5cc0e41 | 2010-12-08 15:57:18 -0800 | [diff] [blame] | 238 | mAddMsgText = getIntent().getCharSequenceExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION); |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 239 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 240 | setContentView(R.layout.device_admin_add); |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 241 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 242 | mAdminIcon = (ImageView)findViewById(R.id.admin_icon); |
| 243 | mAdminName = (TextView)findViewById(R.id.admin_name); |
| 244 | mAdminDescription = (TextView)findViewById(R.id.admin_description); |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 245 | mProfileOwnerWarning = (TextView) findViewById(R.id.profile_owner_warning); |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 246 | |
Dianne Hackborn | b885afe | 2010-01-26 18:03:42 -0800 | [diff] [blame] | 247 | mAddMsg = (TextView)findViewById(R.id.add_msg); |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 248 | mAddMsgExpander = (ImageView) findViewById(R.id.add_msg_expander); |
Fyodor Kupolov | 1c8600b | 2015-05-29 11:17:32 -0700 | [diff] [blame^] | 249 | final View.OnClickListener onClickListener = new View.OnClickListener() { |
| 250 | @Override |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 251 | public void onClick(View v) { |
Fyodor Kupolov | 1c8600b | 2015-05-29 11:17:32 -0700 | [diff] [blame^] | 252 | toggleMessageEllipsis(mAddMsg); |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 253 | } |
Fyodor Kupolov | 1c8600b | 2015-05-29 11:17:32 -0700 | [diff] [blame^] | 254 | }; |
| 255 | mAddMsgExpander.setOnClickListener(onClickListener); |
| 256 | mAddMsg.setOnClickListener(onClickListener); |
| 257 | |
| 258 | // Determine whether the message can be collapsed - getLineCount() gives the correct |
| 259 | // number of lines only after a layout pass. |
| 260 | mAddMsg.getViewTreeObserver().addOnGlobalLayoutListener( |
| 261 | new ViewTreeObserver.OnGlobalLayoutListener() { |
| 262 | @Override |
| 263 | public void onGlobalLayout() { |
| 264 | final int maxLines = getEllipsizedLines(); |
| 265 | // hide the icon if number of visible lines does not exceed maxLines |
| 266 | boolean hideMsgExpander = mAddMsg.getLineCount() <= maxLines; |
| 267 | mAddMsgExpander.setVisibility(hideMsgExpander ? View.GONE : View.VISIBLE); |
| 268 | if (hideMsgExpander) { |
| 269 | mAddMsg.setOnClickListener(null); |
| 270 | ((View)mAddMsgExpander.getParent()).invalidate(); |
| 271 | } |
| 272 | mAddMsg.getViewTreeObserver().removeOnGlobalLayoutListener(this); |
| 273 | } |
| 274 | }); |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 275 | |
| 276 | // toggleMessageEllipsis also handles initial layout: |
| 277 | toggleMessageEllipsis(mAddMsg); |
| 278 | |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 279 | mAdminWarning = (TextView) findViewById(R.id.admin_warning); |
| 280 | mAdminPolicies = (ViewGroup) findViewById(R.id.admin_policies); |
| 281 | mCancelButton = (Button) findViewById(R.id.cancel_button); |
Stephan Huber | dc33321 | 2015-01-23 09:49:57 +0100 | [diff] [blame] | 282 | mCancelButton.setFilterTouchesWhenObscured(true); |
Dianne Hackborn | 97de6bc | 2010-03-03 17:18:13 -0800 | [diff] [blame] | 283 | mCancelButton.setOnClickListener(new View.OnClickListener() { |
| 284 | public void onClick(View v) { |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 285 | EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_DECLINED_BY_USER, |
| 286 | mDeviceAdmin.getActivityInfo().applicationInfo.uid); |
Dianne Hackborn | 97de6bc | 2010-03-03 17:18:13 -0800 | [diff] [blame] | 287 | finish(); |
| 288 | } |
| 289 | }); |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 290 | mActionButton = (Button) findViewById(R.id.action_button); |
Stephan Huber | dc33321 | 2015-01-23 09:49:57 +0100 | [diff] [blame] | 291 | mActionButton.setFilterTouchesWhenObscured(true); |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 292 | mActionButton.setOnClickListener(new View.OnClickListener() { |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 293 | public void onClick(View v) { |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 294 | if (mAdding) { |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 295 | addAndFinish(); |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 296 | } else if (!mWaitingForRemoveMsg) { |
Dianne Hackborn | 4f25e1d | 2011-03-02 22:39:49 -0800 | [diff] [blame] | 297 | try { |
| 298 | // Don't allow the admin to put a dialog up in front |
| 299 | // of us while we interact with the user. |
| 300 | ActivityManagerNative.getDefault().stopAppSwitches(); |
| 301 | } catch (RemoteException e) { |
| 302 | } |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 303 | mWaitingForRemoveMsg = true; |
Andrew Stadler | 4df6edb | 2010-02-05 01:00:13 -0800 | [diff] [blame] | 304 | mDPM.getRemoveWarning(mDeviceAdmin.getComponent(), |
| 305 | new RemoteCallback(mHandler) { |
| 306 | @Override |
| 307 | protected void onResult(Bundle bundle) { |
| 308 | CharSequence msg = bundle != null |
Dianne Hackborn | 5435511 | 2010-02-16 20:40:42 -0800 | [diff] [blame] | 309 | ? bundle.getCharSequence( |
| 310 | DeviceAdminReceiver.EXTRA_DISABLE_WARNING) |
Andrew Stadler | 4df6edb | 2010-02-05 01:00:13 -0800 | [diff] [blame] | 311 | : null; |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 312 | continueRemoveAction(msg); |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 313 | } |
Andrew Stadler | 4df6edb | 2010-02-05 01:00:13 -0800 | [diff] [blame] | 314 | }); |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 315 | // Don't want to wait too long. |
| 316 | getWindow().getDecorView().getHandler().postDelayed(new Runnable() { |
| 317 | @Override public void run() { |
| 318 | continueRemoveAction(null); |
| 319 | } |
| 320 | }, 2*1000); |
Andrew Stadler | 4df6edb | 2010-02-05 01:00:13 -0800 | [diff] [blame] | 321 | } |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 322 | } |
| 323 | }); |
| 324 | } |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 325 | |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 326 | void addAndFinish() { |
| 327 | try { |
| 328 | mDPM.setActiveAdmin(mDeviceAdmin.getComponent(), mRefreshing); |
| 329 | EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_ACTIVATED_BY_USER, |
| 330 | mDeviceAdmin.getActivityInfo().applicationInfo.uid); |
| 331 | setResult(Activity.RESULT_OK); |
| 332 | } catch (RuntimeException e) { |
| 333 | // Something bad happened... could be that it was |
| 334 | // already set, though. |
| 335 | Log.w(TAG, "Exception trying to activate admin " |
| 336 | + mDeviceAdmin.getComponent(), e); |
| 337 | if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) { |
| 338 | setResult(Activity.RESULT_OK); |
| 339 | } |
| 340 | } |
| 341 | if (mAddingProfileOwner) { |
| 342 | try { |
| 343 | mDPM.setProfileOwner(mDeviceAdmin.getComponent(), |
| 344 | mProfileOwnerName, UserHandle.myUserId()); |
| 345 | } catch (RuntimeException re) { |
| 346 | setResult(Activity.RESULT_CANCELED); |
| 347 | } |
| 348 | } |
| 349 | finish(); |
| 350 | } |
| 351 | |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 352 | void continueRemoveAction(CharSequence msg) { |
| 353 | if (!mWaitingForRemoveMsg) { |
| 354 | return; |
| 355 | } |
| 356 | mWaitingForRemoveMsg = false; |
| 357 | if (msg == null) { |
| 358 | try { |
| 359 | ActivityManagerNative.getDefault().resumeAppSwitches(); |
| 360 | } catch (RemoteException e) { |
| 361 | } |
| 362 | mDPM.removeActiveAdmin(mDeviceAdmin.getComponent()); |
| 363 | finish(); |
| 364 | } else { |
| 365 | try { |
| 366 | // Continue preventing anything from coming in front. |
| 367 | ActivityManagerNative.getDefault().stopAppSwitches(); |
| 368 | } catch (RemoteException e) { |
| 369 | } |
| 370 | Bundle args = new Bundle(); |
| 371 | args.putCharSequence( |
| 372 | DeviceAdminReceiver.EXTRA_DISABLE_WARNING, msg); |
| 373 | showDialog(DIALOG_WARNING, args); |
| 374 | } |
| 375 | } |
| 376 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 377 | @Override |
| 378 | protected void onResume() { |
| 379 | super.onResume(); |
| 380 | updateInterface(); |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 381 | // As long as we are running, don't let this admin overlay stuff on top of the screen. |
| 382 | final int uid = mDeviceAdmin.getActivityInfo().applicationInfo.uid; |
| 383 | final String pkg = mDeviceAdmin.getActivityInfo().applicationInfo.packageName; |
| 384 | mCurSysAppOpMode = mAppOps.checkOp(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg); |
| 385 | mCurToastAppOpMode = mAppOps.checkOp(AppOpsManager.OP_TOAST_WINDOW, uid, pkg); |
| 386 | mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg, AppOpsManager.MODE_IGNORED); |
| 387 | mAppOps.setMode(AppOpsManager.OP_TOAST_WINDOW, uid, pkg, AppOpsManager.MODE_IGNORED); |
| 388 | } |
| 389 | |
| 390 | @Override |
| 391 | protected void onPause() { |
| 392 | super.onPause(); |
| 393 | // As long as we are running, don't let this admin overlay stuff on top of the screen. |
| 394 | final int uid = mDeviceAdmin.getActivityInfo().applicationInfo.uid; |
| 395 | final String pkg = mDeviceAdmin.getActivityInfo().applicationInfo.packageName; |
| 396 | mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg, mCurSysAppOpMode); |
| 397 | mAppOps.setMode(AppOpsManager.OP_TOAST_WINDOW, uid, pkg, mCurToastAppOpMode); |
| 398 | try { |
| 399 | ActivityManagerNative.getDefault().resumeAppSwitches(); |
| 400 | } catch (RemoteException e) { |
| 401 | } |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 402 | } |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 403 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 404 | @Override |
| 405 | protected Dialog onCreateDialog(int id, Bundle args) { |
| 406 | switch (id) { |
| 407 | case DIALOG_WARNING: { |
Dianne Hackborn | 5435511 | 2010-02-16 20:40:42 -0800 | [diff] [blame] | 408 | CharSequence msg = args.getCharSequence(DeviceAdminReceiver.EXTRA_DISABLE_WARNING); |
Fyodor Kupolov | 7dc56bd | 2015-02-24 09:26:53 -0800 | [diff] [blame] | 409 | AlertDialog.Builder builder = new AlertDialog.Builder(this); |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 410 | builder.setMessage(msg); |
| 411 | builder.setPositiveButton(R.string.dlg_ok, |
| 412 | new DialogInterface.OnClickListener() { |
| 413 | public void onClick(DialogInterface dialog, int which) { |
Dianne Hackborn | b763e34 | 2014-07-22 16:23:36 -0700 | [diff] [blame] | 414 | try { |
| 415 | ActivityManagerNative.getDefault().resumeAppSwitches(); |
| 416 | } catch (RemoteException e) { |
| 417 | } |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 418 | mDPM.removeActiveAdmin(mDeviceAdmin.getComponent()); |
| 419 | finish(); |
| 420 | } |
| 421 | }); |
| 422 | builder.setNegativeButton(R.string.dlg_cancel, null); |
| 423 | return builder.create(); |
| 424 | } |
| 425 | default: |
| 426 | return super.onCreateDialog(id, args); |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 427 | |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 428 | } |
| 429 | } |
William Luh | 64e676a | 2013-11-22 15:42:40 -0800 | [diff] [blame] | 430 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 431 | void updateInterface() { |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 432 | mAdminIcon.setImageDrawable(mDeviceAdmin.loadIcon(getPackageManager())); |
| 433 | mAdminName.setText(mDeviceAdmin.loadLabel(getPackageManager())); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 434 | try { |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 435 | mAdminDescription.setText( |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 436 | mDeviceAdmin.loadDescription(getPackageManager())); |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 437 | mAdminDescription.setVisibility(View.VISIBLE); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 438 | } catch (Resources.NotFoundException e) { |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 439 | mAdminDescription.setVisibility(View.GONE); |
Dianne Hackborn | b885afe | 2010-01-26 18:03:42 -0800 | [diff] [blame] | 440 | } |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 441 | if (mAddingProfileOwner) { |
| 442 | mProfileOwnerWarning.setVisibility(View.VISIBLE); |
| 443 | } |
Dianne Hackborn | b885afe | 2010-01-26 18:03:42 -0800 | [diff] [blame] | 444 | if (mAddMsgText != null) { |
| 445 | mAddMsg.setText(mAddMsgText); |
| 446 | mAddMsg.setVisibility(View.VISIBLE); |
| 447 | } else { |
| 448 | mAddMsg.setVisibility(View.GONE); |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 449 | mAddMsgExpander.setVisibility(View.GONE); |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 450 | } |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 451 | if (!mRefreshing && !mAddingProfileOwner |
| 452 | && mDPM.isAdminActive(mDeviceAdmin.getComponent())) { |
Fyodor Kupolov | 7dc56bd | 2015-02-24 09:26:53 -0800 | [diff] [blame] | 453 | addDeviceAdminPolicies(false /* showDescription */); |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 454 | mAdminWarning.setText(getString(R.string.device_admin_status, |
| 455 | mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager()))); |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 456 | setTitle(getText(R.string.active_device_admin_msg)); |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 457 | mActionButton.setText(getText(R.string.remove_device_admin)); |
| 458 | mAdding = false; |
| 459 | } else { |
Fyodor Kupolov | 7dc56bd | 2015-02-24 09:26:53 -0800 | [diff] [blame] | 460 | addDeviceAdminPolicies(true /* showDescription */); |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 461 | mAdminWarning.setText(getString(R.string.device_admin_warning, |
| 462 | mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager()))); |
Amith Yamasani | b8e0f60 | 2014-07-28 16:28:36 -0700 | [diff] [blame] | 463 | if (mAddingProfileOwner) { |
| 464 | setTitle(getText(R.string.profile_owner_add_title)); |
| 465 | } else { |
| 466 | setTitle(getText(R.string.add_device_admin_msg)); |
| 467 | } |
Dianne Hackborn | 61daf83 | 2010-01-27 16:22:05 -0800 | [diff] [blame] | 468 | mActionButton.setText(getText(R.string.add_device_admin)); |
| 469 | mAdding = true; |
| 470 | } |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 471 | } |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 472 | |
Fyodor Kupolov | 7dc56bd | 2015-02-24 09:26:53 -0800 | [diff] [blame] | 473 | private void addDeviceAdminPolicies(boolean showDescription) { |
| 474 | if (!mAdminPoliciesInitialized) { |
| 475 | boolean isOwner = UserHandle.getCallingUserHandle().isOwner(); |
| 476 | for (DeviceAdminInfo.PolicyInfo pi : mDeviceAdmin.getUsedPolicies()) { |
| 477 | int descriptionId = isOwner ? pi.description : pi.descriptionForSecondaryUsers; |
| 478 | int labelId = isOwner ? pi.label : pi.labelForSecondaryUsers; |
| 479 | View view = AppSecurityPermissions.getPermissionItemView(this, getText(labelId), |
| 480 | showDescription ? getText(descriptionId) : "", true); |
| 481 | mAdminPolicies.addView(view); |
| 482 | } |
| 483 | mAdminPoliciesInitialized = true; |
| 484 | } |
| 485 | } |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 486 | |
| 487 | void toggleMessageEllipsis(View v) { |
| 488 | TextView tv = (TextView) v; |
| 489 | |
| 490 | mAddMsgEllipsized = ! mAddMsgEllipsized; |
| 491 | tv.setEllipsize(mAddMsgEllipsized ? TruncateAt.END : null); |
| 492 | tv.setMaxLines(mAddMsgEllipsized ? getEllipsizedLines() : MAX_ADD_MSG_LINES); |
| 493 | |
Amith Yamasani | a1d0184 | 2011-01-24 16:02:11 -0800 | [diff] [blame] | 494 | mAddMsgExpander.setImageResource(mAddMsgEllipsized ? |
Chris Palmer | 51794a0 | 2010-09-13 15:14:55 -0700 | [diff] [blame] | 495 | com.android.internal.R.drawable.expander_ic_minimized : |
| 496 | com.android.internal.R.drawable.expander_ic_maximized); |
| 497 | } |
| 498 | |
| 499 | int getEllipsizedLines() { |
| 500 | Display d = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) |
| 501 | .getDefaultDisplay(); |
| 502 | |
| 503 | return d.getHeight() > d.getWidth() ? |
| 504 | MAX_ADD_MSG_LINES_PORTRAIT : MAX_ADD_MSG_LINES_LANDSCAPE; |
| 505 | } |
| 506 | |
Dianne Hackborn | 2842903 | 2010-01-25 18:56:17 -0800 | [diff] [blame] | 507 | } |