blob: 00f4d9cbec360264e43d9545b441796b4a01524d [file] [log] [blame]
Dianne Hackbornfeff6522010-01-12 18:18:05 -08001/*
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
17package com.android.settings;
18
Dianne Hackbornfeff6522010-01-12 18:18:05 -080019import android.app.Activity;
Makoto Onuki7cdaa522016-02-24 12:56:44 -080020import android.app.AppGlobals;
Amith Yamasania1d01842011-01-24 16:02:11 -080021import android.app.ListFragment;
Dianne Hackborn4037c7f2010-02-26 17:26:55 -080022import android.app.admin.DeviceAdminInfo;
23import android.app.admin.DeviceAdminReceiver;
24import android.app.admin.DevicePolicyManager;
Fyodor Kupolovcfae8552014-11-25 17:34:22 -080025import android.content.BroadcastReceiver;
Dianne Hackbornfeff6522010-01-12 18:18:05 -080026import android.content.ComponentName;
27import android.content.Context;
28import android.content.Intent;
Fyodor Kupolovcfae8552014-11-25 17:34:22 -080029import android.content.IntentFilter;
Makoto Onuki7cdaa522016-02-24 12:56:44 -080030import android.content.pm.ActivityInfo;
31import android.content.pm.IPackageManager;
Dianne Hackbornfeff6522010-01-12 18:18:05 -080032import android.content.pm.PackageManager;
33import android.content.pm.ResolveInfo;
Dianne Hackborn28429032010-01-25 18:56:17 -080034import android.content.res.Resources;
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +010035import android.graphics.drawable.Drawable;
Dianne Hackbornfeff6522010-01-12 18:18:05 -080036import android.os.Bundle;
Makoto Onuki7cdaa522016-02-24 12:56:44 -080037import android.os.RemoteException;
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +010038import android.os.UserHandle;
39import android.os.UserManager;
Dianne Hackbornfeff6522010-01-12 18:18:05 -080040import android.util.Log;
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +010041import android.util.SparseArray;
Dianne Hackbornfeff6522010-01-12 18:18:05 -080042import android.view.LayoutInflater;
43import android.view.View;
44import android.view.ViewGroup;
45import android.widget.BaseAdapter;
Dianne Hackborn61daf832010-01-27 16:22:05 -080046import android.widget.CheckBox;
Dianne Hackbornfeff6522010-01-12 18:18:05 -080047import android.widget.ImageView;
48import android.widget.ListView;
49import android.widget.TextView;
50
Tamas Berghammer265d3c22016-06-22 15:34:45 +010051import com.android.internal.logging.nano.MetricsProto;
Doris Ling03a3b512017-10-18 14:25:01 -070052import com.android.settings.core.InstrumentedPreferenceFragment;
Fan Zhang65076132016-08-08 10:25:13 -070053import com.android.settings.core.instrumentation.Instrumentable;
Fan Zhang45fb1192016-09-20 09:05:27 -070054import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
Fan Zhang65076132016-08-08 10:25:13 -070055
Jason Monk39b46742015-09-10 15:52:51 -040056import org.xmlpull.v1.XmlPullParserException;
57
Dianne Hackbornfeff6522010-01-12 18:18:05 -080058import java.io.IOException;
59import java.util.ArrayList;
Fyodor Kupolovcfae8552014-11-25 17:34:22 -080060import java.util.Collection;
Alex Klyubind14258e2013-05-22 09:06:35 -070061import java.util.Collections;
Dianne Hackbornfeff6522010-01-12 18:18:05 -080062import java.util.List;
63
Fan Zhang65076132016-08-08 10:25:13 -070064public class DeviceAdminSettings extends ListFragment implements Instrumentable {
Dianne Hackbornfeff6522010-01-12 18:18:05 -080065 static final String TAG = "DeviceAdminSettings";
Amith Yamasanib8e0f602014-07-28 16:28:36 -070066
Fan Zhang65076132016-08-08 10:25:13 -070067 private final VisibilityLoggerMixin mVisibilityLoggerMixin =
Fan Zhangea024152016-08-22 15:20:22 -070068 new VisibilityLoggerMixin(getMetricsCategory());
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +010069 private DevicePolicyManager mDPM;
70 private UserManager mUm;
Amith Yamasanib8e0f602014-07-28 16:28:36 -070071
Kenny Guy7a355592015-12-22 12:11:41 +000072 private static class DeviceAdminListItem implements Comparable<DeviceAdminListItem> {
73 public DeviceAdminInfo info;
74
75 // These aren't updated so they keep a stable sort order if user activates / de-activates
76 // an admin.
77 public String name;
78 public boolean active;
79
80 public int compareTo(DeviceAdminListItem other) {
81 // Sort active admins first, then by name.
82 if (this.active != other.active) {
83 return this.active ? -1 : 1;
84 }
85 return this.name.compareTo(other.name);
86 }
87 }
Fan Zhang45fb1192016-09-20 09:05:27 -070088
89 @Override
90 public void onAttach(Context context) {
91 super.onAttach(context);
92 mVisibilityLoggerMixin.onAttach(context);
93 }
94
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +010095 /**
96 * Internal collection of device admin info objects for all profiles associated with the current
97 * user.
98 */
Kenny Guy7a355592015-12-22 12:11:41 +000099 private final ArrayList<DeviceAdminListItem>
100 mAdmins = new ArrayList<DeviceAdminListItem>();
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100101
102 private String mDeviceOwnerPkg;
103 private SparseArray<ComponentName> mProfileOwnerComponents = new SparseArray<ComponentName>();
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800104
Fyodor Kupolovcfae8552014-11-25 17:34:22 -0800105 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
106 @Override
107 public void onReceive(Context context, Intent intent) {
108 // Refresh the list, if state change has been received. It could be that checkboxes
109 // need to be updated
110 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
111 intent.getAction())) {
112 updateList();
113 }
114 }
115 };
116
Dianne Hackborn28429032010-01-25 18:56:17 -0800117 @Override
Fan Zhang65076132016-08-08 10:25:13 -0700118 public int getMetricsCategory() {
119 return MetricsProto.MetricsEvent.DEVICE_ADMIN_SETTINGS;
120 }
121
122 @Override
Amith Yamasania1d01842011-01-24 16:02:11 -0800123 public void onCreate(Bundle icicle) {
124 super.onCreate(icicle);
125 }
126
127 @Override
128 public View onCreateView(LayoutInflater inflater, ViewGroup container,
129 Bundle savedInstanceState) {
130 mDPM = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100131 mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
Amith Yamasania1d01842011-01-24 16:02:11 -0800132 return inflater.inflate(R.layout.device_admin_settings, container, false);
133 }
134
135 @Override
Fabrice Di Meglio402c4512014-07-28 18:55:29 -0700136 public void onActivityCreated(Bundle savedInstanceState) {
137 super.onActivityCreated(savedInstanceState);
Udam Saini0708d9e2016-03-28 16:35:13 -0700138 setHasOptionsMenu(true);
Fabrice Di Meglio402c4512014-07-28 18:55:29 -0700139 Utils.forceCustomPadding(getListView(), true /* additive padding */);
Doris Ling03a3b512017-10-18 14:25:01 -0700140 if (InstrumentedPreferenceFragment.usePreferenceScreenTitle()) {
141 getActivity().setTitle(R.string.manage_device_admin);
142 }
Fabrice Di Meglio402c4512014-07-28 18:55:29 -0700143 }
144
145 @Override
Amith Yamasania1d01842011-01-24 16:02:11 -0800146 public void onResume() {
Dianne Hackborn28429032010-01-25 18:56:17 -0800147 super.onResume();
Fan Zhang65076132016-08-08 10:25:13 -0700148 final Activity activity = getActivity();
Fan Zhangea024152016-08-22 15:20:22 -0700149 mVisibilityLoggerMixin.onResume();
Fyodor Kupolovcfae8552014-11-25 17:34:22 -0800150 IntentFilter filter = new IntentFilter();
151 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Fan Zhang65076132016-08-08 10:25:13 -0700152 activity.registerReceiverAsUser(
Fyodor Kupolovcfae8552014-11-25 17:34:22 -0800153 mBroadcastReceiver, UserHandle.ALL, filter, null, null);
Makoto Onuki4cfe39f2015-11-19 13:47:55 -0800154
155 final ComponentName deviceOwnerComponent = mDPM.getDeviceOwnerComponentOnAnyUser();
156 mDeviceOwnerPkg =
157 deviceOwnerComponent != null ? deviceOwnerComponent.getPackageName() : null;
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100158 mProfileOwnerComponents.clear();
159 final List<UserHandle> profiles = mUm.getUserProfiles();
160 final int profilesSize = profiles.size();
161 for (int i = 0; i < profilesSize; ++i) {
162 final int profileId = profiles.get(i).getIdentifier();
163 mProfileOwnerComponents.put(profileId, mDPM.getProfileOwnerAsUser(profileId));
164 }
Dianne Hackborn61daf832010-01-27 16:22:05 -0800165 updateList();
Dianne Hackborn28429032010-01-25 18:56:17 -0800166 }
167
Fyodor Kupolovcfae8552014-11-25 17:34:22 -0800168 @Override
169 public void onPause() {
Fan Zhang65076132016-08-08 10:25:13 -0700170 final Activity activity = getActivity();
171 activity.unregisterReceiver(mBroadcastReceiver);
Fan Zhangea024152016-08-22 15:20:22 -0700172 mVisibilityLoggerMixin.onPause();
Fyodor Kupolovcfae8552014-11-25 17:34:22 -0800173 super.onPause();
174 }
175
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100176 /**
177 * Update the internal collection of available admins for all profiles associated with the
178 * current user.
179 */
Dianne Hackborn61daf832010-01-27 16:22:05 -0800180 void updateList() {
Kenny Guy7a355592015-12-22 12:11:41 +0000181 mAdmins.clear();
Amith Yamasania1d01842011-01-24 16:02:11 -0800182
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100183 final List<UserHandle> profiles = mUm.getUserProfiles();
184 final int profilesSize = profiles.size();
185 for (int i = 0; i < profilesSize; ++i) {
186 final int profileId = profiles.get(i).getIdentifier();
187 updateAvailableAdminsForProfile(profileId);
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800188 }
Kenny Guy7a355592015-12-22 12:11:41 +0000189 Collections.sort(mAdmins);
Amith Yamasanib8e0f602014-07-28 16:28:36 -0700190
Dianne Hackborn61daf832010-01-27 16:22:05 -0800191 getListView().setAdapter(new PolicyListAdapter());
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800192 }
Amith Yamasania1d01842011-01-24 16:02:11 -0800193
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800194 @Override
Amith Yamasania1d01842011-01-24 16:02:11 -0800195 public void onListItemClick(ListView l, View v, int position, long id) {
Zoltan Szatmary-Band92897d2014-08-28 13:13:34 +0100196 Object o = l.getAdapter().getItem(position);
Zoltan Szatmary-Band92897d2014-08-28 13:13:34 +0100197 DeviceAdminInfo dpi = (DeviceAdminInfo) o;
Kenny Guy7a355592015-12-22 12:11:41 +0000198 final UserHandle user = new UserHandle(getUserId(dpi));
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100199 final Activity activity = getActivity();
Kenny Guy7a355592015-12-22 12:11:41 +0000200 Intent intent = new Intent(activity, DeviceAdminAdd.class);
201 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, dpi.getComponent());
202 activity.startActivityAsUser(intent, user);
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800203 }
Amith Yamasania1d01842011-01-24 16:02:11 -0800204
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800205 static class ViewHolder {
206 ImageView icon;
207 TextView name;
Dianne Hackborn61daf832010-01-27 16:22:05 -0800208 CheckBox checkbox;
209 TextView description;
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800210 }
Amith Yamasanib8e0f602014-07-28 16:28:36 -0700211
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800212 class PolicyListAdapter extends BaseAdapter {
213 final LayoutInflater mInflater;
Amith Yamasanib8e0f602014-07-28 16:28:36 -0700214
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800215 PolicyListAdapter() {
Amith Yamasania1d01842011-01-24 16:02:11 -0800216 mInflater = (LayoutInflater)
217 getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800218 }
219
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100220 @Override
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800221 public boolean hasStableIds() {
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100222 return false;
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800223 }
Amith Yamasanib8e0f602014-07-28 16:28:36 -0700224
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100225 @Override
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800226 public int getCount() {
Kenny Guy7a355592015-12-22 12:11:41 +0000227 return mAdmins.size();
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800228 }
229
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100230 /**
231 * The item for the given position in the list.
232 *
Kenny Guy7a355592015-12-22 12:11:41 +0000233 * @return DeviceAdminInfo object for actual device admins.
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100234 */
235 @Override
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800236 public Object getItem(int position) {
Kenny Guy7a355592015-12-22 12:11:41 +0000237 return ((DeviceAdminListItem) (mAdmins.get(position))).info;
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800238 }
239
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100240 @Override
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800241 public long getItemId(int position) {
242 return position;
243 }
244
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100245 @Override
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800246 public boolean areAllItemsEnabled() {
247 return false;
248 }
249
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100250 /**
251 * See {@link #getItemViewType} for the view types.
252 */
253 @Override
254 public int getViewTypeCount() {
Kenny Guy7a355592015-12-22 12:11:41 +0000255 return 1;
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100256 }
257
258 /**
Kenny Guy7a355592015-12-22 12:11:41 +0000259 * Returns 0 for all types.
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100260 */
261 @Override
262 public int getItemViewType(int position) {
Kenny Guy7a355592015-12-22 12:11:41 +0000263 return 0;
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100264 }
265
266 @Override
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800267 public boolean isEnabled(int position) {
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100268 Object o = getItem(position);
269 return isEnabled(o);
270 }
271
272 private boolean isEnabled(Object o) {
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100273 DeviceAdminInfo info = (DeviceAdminInfo) o;
Fyodor Kupolovcfae8552014-11-25 17:34:22 -0800274 // Disable item if admin is being removed
275 if (isRemovingAdmin(info)) {
276 return false;
277 }
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100278 return true;
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800279 }
280
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100281 @Override
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800282 public View getView(int position, View convertView, ViewGroup parent) {
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100283 Object o = getItem(position);
Kenny Guy7a355592015-12-22 12:11:41 +0000284 if (convertView == null) {
285 convertView = newDeviceAdminView(parent);
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800286 }
Kenny Guy7a355592015-12-22 12:11:41 +0000287 bindView(convertView, (DeviceAdminInfo) o);
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100288 return convertView;
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800289 }
Amith Yamasanib8e0f602014-07-28 16:28:36 -0700290
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100291 private View newDeviceAdminView(ViewGroup parent) {
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800292 View v = mInflater.inflate(R.layout.device_admin_item, parent, false);
293 ViewHolder h = new ViewHolder();
Kenny Guy7a355592015-12-22 12:11:41 +0000294 h.icon = (ImageView) v.findViewById(R.id.icon);
295 h.name = (TextView) v.findViewById(R.id.name);
296 h.checkbox = (CheckBox) v.findViewById(R.id.checkbox);
297 h.description = (TextView) v.findViewById(R.id.description);
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800298 v.setTag(h);
299 return v;
300 }
Amith Yamasanib8e0f602014-07-28 16:28:36 -0700301
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100302 private void bindView(View view, DeviceAdminInfo item) {
Amith Yamasania1d01842011-01-24 16:02:11 -0800303 final Activity activity = getActivity();
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800304 ViewHolder vh = (ViewHolder) view.getTag();
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100305 Drawable activityIcon = item.loadIcon(activity.getPackageManager());
Amith Yamasani30c50b12014-09-07 15:38:09 -0700306 Drawable badgedIcon = activity.getPackageManager().getUserBadgedIcon(
307 activityIcon, new UserHandle(getUserId(item)));
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100308 vh.icon.setImageDrawable(badgedIcon);
Amith Yamasania1d01842011-01-24 16:02:11 -0800309 vh.name.setText(item.loadLabel(activity.getPackageManager()));
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100310 vh.checkbox.setChecked(isActiveAdmin(item));
311 final boolean enabled = isEnabled(item);
Dianne Hackborn61daf832010-01-27 16:22:05 -0800312 try {
Amith Yamasania1d01842011-01-24 16:02:11 -0800313 vh.description.setText(item.loadDescription(activity.getPackageManager()));
Dianne Hackborn61daf832010-01-27 16:22:05 -0800314 } catch (Resources.NotFoundException e) {
315 }
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100316 vh.checkbox.setEnabled(enabled);
317 vh.name.setEnabled(enabled);
318 vh.description.setEnabled(enabled);
319 vh.icon.setEnabled(enabled);
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800320 }
321 }
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100322
323 private boolean isDeviceOwner(DeviceAdminInfo item) {
324 return getUserId(item) == UserHandle.myUserId()
325 && item.getPackageName().equals(mDeviceOwnerPkg);
326 }
327
328 private boolean isProfileOwner(DeviceAdminInfo item) {
329 ComponentName profileOwner = mProfileOwnerComponents.get(getUserId(item));
330 return item.getComponent().equals(profileOwner);
331 }
332
333 private boolean isActiveAdmin(DeviceAdminInfo item) {
334 return mDPM.isAdminActiveAsUser(item.getComponent(), getUserId(item));
335 }
336
Fyodor Kupolovcfae8552014-11-25 17:34:22 -0800337 private boolean isRemovingAdmin(DeviceAdminInfo item) {
338 return mDPM.isRemovingAdmin(item.getComponent(), getUserId(item));
339 }
340
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100341 /**
342 * Add device admins to the internal collection that belong to a profile.
343 *
344 * @param profileId the profile identifier.
345 */
346 private void updateAvailableAdminsForProfile(final int profileId) {
347 // We are adding the union of two sets 'A' and 'B' of device admins to mAvailableAdmins.
348 // Set 'A' is the set of active admins for the profile whereas set 'B' is the set of
349 // listeners to DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED for the profile.
350
351 // Add all of set 'A' to mAvailableAdmins.
352 List<ComponentName> activeAdminsListForProfile = mDPM.getActiveAdminsAsUser(profileId);
353 addActiveAdminsForProfile(activeAdminsListForProfile, profileId);
354
355 // Collect set 'B' and add B-A to mAvailableAdmins.
356 addDeviceAdminBroadcastReceiversForProfile(activeAdminsListForProfile, profileId);
357 }
358
359 /**
360 * Add a profile's device admins that are receivers of
361 * {@code DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED} to the internal collection if they
362 * haven't been added yet.
363 *
364 * @param alreadyAddedComponents the set of active admin component names. Receivers of
365 * {@code DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED} whose component is in this
366 * set are not added to the internal collection again.
367 * @param profileId the identifier of the profile
368 */
369 private void addDeviceAdminBroadcastReceiversForProfile(
370 Collection<ComponentName> alreadyAddedComponents, final int profileId) {
371 final PackageManager pm = getActivity().getPackageManager();
Jeff Sharkeydf828402016-01-06 14:51:30 -0700372 List<ResolveInfo> enabledForProfile = pm.queryBroadcastReceiversAsUser(
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100373 new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
374 PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
375 profileId);
376 if (enabledForProfile == null) {
377 enabledForProfile = Collections.emptyList();
378 }
379 final int n = enabledForProfile.size();
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100380 for (int i = 0; i < n; ++i) {
381 ResolveInfo resolveInfo = enabledForProfile.get(i);
382 ComponentName riComponentName =
383 new ComponentName(resolveInfo.activityInfo.packageName,
384 resolveInfo.activityInfo.name);
385 if (alreadyAddedComponents == null
386 || !alreadyAddedComponents.contains(riComponentName)) {
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800387 DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolveInfo.activityInfo);
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100388 // add only visible ones (note: active admins are added regardless of visibility)
389 if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) {
Makoto Onuki9dbad572016-02-17 11:15:04 -0800390 if (!deviceAdminInfo.getActivityInfo().applicationInfo.isInternal()) {
391 continue;
392 }
Kenny Guy7a355592015-12-22 12:11:41 +0000393 DeviceAdminListItem item = new DeviceAdminListItem();
394 item.info = deviceAdminInfo;
395 item.name = deviceAdminInfo.loadLabel(pm).toString();
396 // Active ones already added.
397 item.active = false;
398 mAdmins.add(item);
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100399 }
400 }
401 }
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100402 }
403
404 /**
405 * Add a {@link DeviceAdminInfo} object to the internal collection of available admins for all
406 * active admin components associated with a profile.
407 *
408 * @param profileId a profile identifier.
409 */
410 private void addActiveAdminsForProfile(final List<ComponentName> activeAdmins,
411 final int profileId) {
412 if (activeAdmins != null) {
413 final PackageManager packageManager = getActivity().getPackageManager();
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800414 final IPackageManager iPackageManager = AppGlobals.getPackageManager();
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100415 final int n = activeAdmins.size();
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100416 for (int i = 0; i < n; ++i) {
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800417 final ComponentName activeAdmin = activeAdmins.get(i);
418 final ActivityInfo ai;
419 try {
420 ai = iPackageManager.getReceiverInfo(activeAdmin,
421 PackageManager.GET_META_DATA |
422 PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
Jeff Sharkey2079a382017-02-24 12:03:09 -0700423 PackageManager.MATCH_DIRECT_BOOT_UNAWARE |
424 PackageManager.MATCH_DIRECT_BOOT_AWARE, profileId);
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800425 } catch (RemoteException e) {
426 Log.w(TAG, "Unable to load component: " + activeAdmin);
427 continue;
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100428 }
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800429 final DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(ai);
430 if (deviceAdminInfo == null) {
431 continue;
432 }
433 // Don't do the applicationInfo.isInternal() check here; if an active
434 // admin is already on SD card, just show it.
435 final DeviceAdminListItem item = new DeviceAdminListItem();
436 item.info = deviceAdminInfo;
437 item.name = deviceAdminInfo.loadLabel(packageManager).toString();
438 item.active = true;
439 mAdmins.add(item);
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100440 }
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100441 }
442 }
443
444 /**
445 * Creates a device admin info object for the resolved intent that points to the component of
446 * the device admin.
447 *
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800448 * @param ai ActivityInfo for the admin component.
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100449 * @return new {@link DeviceAdminInfo} object or null if there was an error.
450 */
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800451 private DeviceAdminInfo createDeviceAdminInfo(ActivityInfo ai) {
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100452 try {
Makoto Onuki7cdaa522016-02-24 12:56:44 -0800453 return new DeviceAdminInfo(getActivity(), ai);
454 } catch (XmlPullParserException|IOException e) {
455 Log.w(TAG, "Skipping " + ai, e);
Zoltan Szatmary-Banf3d72092014-07-02 16:48:00 +0100456 }
457 return null;
458 }
459
460 /**
461 * Extracts the user id from a device admin info object.
462 * @param adminInfo the device administrator info.
463 * @return identifier of the user associated with the device admin.
464 */
465 private int getUserId(DeviceAdminInfo adminInfo) {
466 return UserHandle.getUserId(adminInfo.getActivityInfo().applicationInfo.uid);
467 }
Dianne Hackbornfeff6522010-01-12 18:18:05 -0800468}