1feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn/*
2feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project
3feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn *
4feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * you may not use this file except in compliance with the License.
6feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * You may obtain a copy of the License at
7feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn *
8feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn *
10feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * See the License for the specific language governing permissions and
14feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn * limitations under the License.
15feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn */
16feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
17feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornpackage com.android.settings;
18feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
19feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.app.Activity;
207cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onukiimport android.app.AppGlobals;
21a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasaniimport android.app.ListFragment;
224037c7f27c849a1ada0980ad881636fc940a0b85Dianne Hackbornimport android.app.admin.DeviceAdminInfo;
234037c7f27c849a1ada0980ad881636fc940a0b85Dianne Hackbornimport android.app.admin.DeviceAdminReceiver;
244037c7f27c849a1ada0980ad881636fc940a0b85Dianne Hackbornimport android.app.admin.DevicePolicyManager;
25cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolovimport android.content.BroadcastReceiver;
26feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.ComponentName;
27feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.Context;
28feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.Intent;
29cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolovimport android.content.IntentFilter;
307cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onukiimport android.content.pm.ActivityInfo;
317cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onukiimport android.content.pm.IPackageManager;
32feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.pm.PackageManager;
33feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.pm.ResolveInfo;
3428429033375c3876af56528bfc9ea6b541052fcbDianne Hackbornimport android.content.res.Resources;
35f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.graphics.drawable.Drawable;
36feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.os.Bundle;
377cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onukiimport android.os.RemoteException;
38f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.os.UserHandle;
39f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.os.UserManager;
40feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.util.Log;
41f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.util.SparseArray;
42feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.view.LayoutInflater;
43feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.view.View;
44feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.view.ViewGroup;
45feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.BaseAdapter;
4661daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackbornimport android.widget.CheckBox;
47feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.ImageView;
48feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.ListView;
49feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.TextView;
50feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
51265d3c2a0c36251bf8a9f571d7239b6dd404d942Tamas Berghammerimport com.android.internal.logging.nano.MetricsProto;
526507613ebcd22e4691c2af92a5c161bd327db336Fan Zhangimport com.android.settings.core.instrumentation.Instrumentable;
5345fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhangimport com.android.settings.core.instrumentation.VisibilityLoggerMixin;
546507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang
5539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport org.xmlpull.v1.XmlPullParserException;
5639b467482d1bf256a111c757e9b7621c6f523271Jason Monk
57feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport java.io.IOException;
58feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport java.util.ArrayList;
59cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolovimport java.util.Collection;
60d14258e50efc3677abef3cd204b67e7f26e47b56Alex Klyubinimport java.util.Collections;
61feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport java.util.List;
62feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
636507613ebcd22e4691c2af92a5c161bd327db336Fan Zhangpublic class DeviceAdminSettings extends ListFragment implements Instrumentable {
64feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    static final String TAG = "DeviceAdminSettings";
65b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
666507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang    private final VisibilityLoggerMixin mVisibilityLoggerMixin =
67ea024155fb6333058525908f4fee3fa60dd1f70aFan Zhang            new VisibilityLoggerMixin(getMetricsCategory());
68f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private DevicePolicyManager mDPM;
69f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private UserManager mUm;
70b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
717a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy    private static class DeviceAdminListItem implements Comparable<DeviceAdminListItem> {
727a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        public DeviceAdminInfo info;
737a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy
747a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        // These aren't updated so they keep a stable sort order if user activates / de-activates
757a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        // an admin.
767a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        public String name;
777a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        public boolean active;
787a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy
797a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        public int compareTo(DeviceAdminListItem other)  {
807a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            // Sort active admins first, then by name.
817a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            if (this.active != other.active) {
827a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                return this.active ? -1 : 1;
837a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            }
847a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            return this.name.compareTo(other.name);
857a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        }
867a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy    }
8745fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhang
8845fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhang    @Override
8945fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhang    public void onAttach(Context context) {
9045fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhang        super.onAttach(context);
9145fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhang        mVisibilityLoggerMixin.onAttach(context);
9245fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhang    }
9345fb1199a2f5c3e1fc57096bc758a7d9e20cffddFan Zhang
94f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
95f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Internal collection of device admin info objects for all profiles associated with the current
96f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * user.
97f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
987a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy    private final ArrayList<DeviceAdminListItem>
997a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            mAdmins = new ArrayList<DeviceAdminListItem>();
100f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
101f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private String mDeviceOwnerPkg;
102f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private SparseArray<ComponentName> mProfileOwnerComponents = new SparseArray<ComponentName>();
103a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
104cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
105cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        @Override
106cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        public void onReceive(Context context, Intent intent) {
107cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            // Refresh the list, if state change has been received. It could be that checkboxes
108cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            // need to be updated
109cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
110cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                    intent.getAction())) {
111cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                updateList();
112cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            }
113cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        }
114cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    };
115cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov
116feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    @Override
1176507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang    public int getMetricsCategory() {
1186507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang        return MetricsProto.MetricsEvent.DEVICE_ADMIN_SETTINGS;
1196507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang    }
1206507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang
1216507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang    @Override
122a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public void onCreate(Bundle icicle) {
123feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        super.onCreate(icicle);
124a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    }
125feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
126a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    @Override
127a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public View onCreateView(LayoutInflater inflater, ViewGroup container,
128a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            Bundle savedInstanceState) {
129a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani        mDPM = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
130f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
131a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani        return inflater.inflate(R.layout.device_admin_settings, container, false);
132feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
133a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
13428429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn    @Override
135402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio    public void onActivityCreated(Bundle savedInstanceState) {
136402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio        super.onActivityCreated(savedInstanceState);
1370708d9e119da4c4d9424c0bc54fa458d01856bd7Udam Saini        setHasOptionsMenu(true);
138402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio        Utils.forceCustomPadding(getListView(), true /* additive padding */);
139402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio    }
140402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio
141402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio    @Override
142a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public void onResume() {
14328429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn        super.onResume();
1446507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang        final Activity activity = getActivity();
145ea024155fb6333058525908f4fee3fa60dd1f70aFan Zhang        mVisibilityLoggerMixin.onResume();
146cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        IntentFilter filter = new IntentFilter();
147cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1486507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang        activity.registerReceiverAsUser(
149cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                mBroadcastReceiver, UserHandle.ALL, filter, null, null);
1504cfe39f5397d037d106abf07db31b0e01484bd92Makoto Onuki
1514cfe39f5397d037d106abf07db31b0e01484bd92Makoto Onuki        final ComponentName deviceOwnerComponent = mDPM.getDeviceOwnerComponentOnAnyUser();
1524cfe39f5397d037d106abf07db31b0e01484bd92Makoto Onuki        mDeviceOwnerPkg =
1534cfe39f5397d037d106abf07db31b0e01484bd92Makoto Onuki                deviceOwnerComponent != null ? deviceOwnerComponent.getPackageName() : null;
154f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        mProfileOwnerComponents.clear();
155f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final List<UserHandle> profiles = mUm.getUserProfiles();
156f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final int profilesSize = profiles.size();
157f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        for (int i = 0; i < profilesSize; ++i) {
158f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int profileId = profiles.get(i).getIdentifier();
159f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            mProfileOwnerComponents.put(profileId, mDPM.getProfileOwnerAsUser(profileId));
160f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
16161daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        updateList();
16228429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn    }
16328429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn
164cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    @Override
165cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    public void onPause() {
1666507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang        final Activity activity = getActivity();
1676507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang        activity.unregisterReceiver(mBroadcastReceiver);
168ea024155fb6333058525908f4fee3fa60dd1f70aFan Zhang        mVisibilityLoggerMixin.onPause();
169cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        super.onPause();
170cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    }
171cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov
172f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
173f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Update the internal collection of available admins for all profiles associated with the
174f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * current user.
175f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
17661daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn    void updateList() {
1777a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        mAdmins.clear();
178d14258e50efc3677abef3cd204b67e7f26e47b56Alex Klyubin
179f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final List<UserHandle> profiles = mUm.getUserProfiles();
180f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final int profilesSize = profiles.size();
181f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        for (int i = 0; i < profilesSize; ++i) {
182f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int profileId = profiles.get(i).getIdentifier();
183f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            updateAvailableAdminsForProfile(profileId);
184feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
1857a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        Collections.sort(mAdmins);
186b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
18761daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        getListView().setAdapter(new PolicyListAdapter());
188feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
189a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
190feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    @Override
191a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public void onListItemClick(ListView l, View v, int position, long id) {
192d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban        Object o = l.getAdapter().getItem(position);
193d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban        DeviceAdminInfo dpi = (DeviceAdminInfo) o;
1947a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        final UserHandle user = new UserHandle(getUserId(dpi));
195f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final Activity activity = getActivity();
1967a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        Intent intent = new Intent(activity, DeviceAdminAdd.class);
1977a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, dpi.getComponent());
1987a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy        activity.startActivityAsUser(intent, user);
199feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
200a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
201feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    static class ViewHolder {
202feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        ImageView icon;
203feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        TextView name;
20461daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        CheckBox checkbox;
20561daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        TextView description;
206feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
207b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
208feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    class PolicyListAdapter extends BaseAdapter {
209feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        final LayoutInflater mInflater;
210b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
211feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        PolicyListAdapter() {
212a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            mInflater = (LayoutInflater)
213a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani                    getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
214feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
215feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
216f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
217feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public boolean hasStableIds() {
218f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return false;
219feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
220b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
221f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
222feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public int getCount() {
2237a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            return mAdmins.size();
224feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
225feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
226f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        /**
227f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         * The item for the given position in the list.
228f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         *
2297a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy         * @return DeviceAdminInfo object for actual device admins.
230f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         */
231f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
232feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public Object getItem(int position) {
2337a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            return ((DeviceAdminListItem) (mAdmins.get(position))).info;
234feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
235feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
236f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
237feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public long getItemId(int position) {
238feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            return position;
239feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
240feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
241f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
242feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public boolean areAllItemsEnabled() {
243feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            return false;
244feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
245feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
246f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        /**
247f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         * See {@link #getItemViewType} for the view types.
248f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         */
249f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
250f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        public int getViewTypeCount() {
2517a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            return 1;
252f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
253f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
254f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        /**
2557a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy         * Returns 0 for all types.
256f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         */
257f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
258f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        public int getItemViewType(int position) {
2597a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            return 0;
260f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
261f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
262f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
263feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public boolean isEnabled(int position) {
264f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Object o = getItem(position);
265f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return isEnabled(o);
266f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
267f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
268f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        private boolean isEnabled(Object o) {
269f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            DeviceAdminInfo info = (DeviceAdminInfo) o;
270cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            // Disable item if admin is being removed
271cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            if (isRemovingAdmin(info)) {
272cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                return false;
273cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            }
274f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return true;
275feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
276feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
277f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
278feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public View getView(int position, View convertView, ViewGroup parent) {
279f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Object o = getItem(position);
2807a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            if (convertView == null) {
2817a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                convertView = newDeviceAdminView(parent);
282feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            }
2837a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            bindView(convertView, (DeviceAdminInfo) o);
284f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return convertView;
285feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
286b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
287f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        private View newDeviceAdminView(ViewGroup parent) {
288feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            View v = mInflater.inflate(R.layout.device_admin_item, parent, false);
289feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            ViewHolder h = new ViewHolder();
2907a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            h.icon = (ImageView) v.findViewById(R.id.icon);
2917a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            h.name = (TextView) v.findViewById(R.id.name);
2927a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            h.checkbox = (CheckBox) v.findViewById(R.id.checkbox);
2937a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy            h.description = (TextView) v.findViewById(R.id.description);
294feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            v.setTag(h);
295feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            return v;
296feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
297b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
298f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        private void bindView(View view, DeviceAdminInfo item) {
299a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            final Activity activity = getActivity();
300feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            ViewHolder vh = (ViewHolder) view.getTag();
301f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Drawable activityIcon = item.loadIcon(activity.getPackageManager());
30230c50b15d0d716567c71d590aa835dc4a27591d6Amith Yamasani            Drawable badgedIcon = activity.getPackageManager().getUserBadgedIcon(
30330c50b15d0d716567c71d590aa835dc4a27591d6Amith Yamasani                    activityIcon, new UserHandle(getUserId(item)));
304f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.icon.setImageDrawable(badgedIcon);
305a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            vh.name.setText(item.loadLabel(activity.getPackageManager()));
306f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.checkbox.setChecked(isActiveAdmin(item));
307f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final boolean enabled = isEnabled(item);
30861daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            try {
309a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani                vh.description.setText(item.loadDescription(activity.getPackageManager()));
31061daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            } catch (Resources.NotFoundException e) {
31161daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            }
312f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.checkbox.setEnabled(enabled);
313f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.name.setEnabled(enabled);
314f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.description.setEnabled(enabled);
315f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.icon.setEnabled(enabled);
316f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
317f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
318f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
319f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private boolean isDeviceOwner(DeviceAdminInfo item) {
320f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return getUserId(item) == UserHandle.myUserId()
321f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                && item.getPackageName().equals(mDeviceOwnerPkg);
322f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
323f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
324f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private boolean isProfileOwner(DeviceAdminInfo item) {
325f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        ComponentName profileOwner = mProfileOwnerComponents.get(getUserId(item));
326f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return item.getComponent().equals(profileOwner);
327f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
328f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
329f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private boolean isActiveAdmin(DeviceAdminInfo item) {
330f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return mDPM.isAdminActiveAsUser(item.getComponent(), getUserId(item));
331f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
332f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
333cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    private boolean isRemovingAdmin(DeviceAdminInfo item) {
334cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        return mDPM.isRemovingAdmin(item.getComponent(), getUserId(item));
335cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    }
336cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov
337f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
338f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Add device admins to the internal collection that belong to a profile.
339f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
340f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param profileId the profile identifier.
341f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
342f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private void updateAvailableAdminsForProfile(final int profileId) {
343f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // We are adding the union of two sets 'A' and 'B' of device admins to mAvailableAdmins.
344f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // Set 'A' is the set of active admins for the profile whereas set 'B' is the set of
345f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // listeners to DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED for the profile.
346f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
347f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // Add all of set 'A' to mAvailableAdmins.
348f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        List<ComponentName> activeAdminsListForProfile = mDPM.getActiveAdminsAsUser(profileId);
349f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        addActiveAdminsForProfile(activeAdminsListForProfile, profileId);
350f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
351f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // Collect set 'B' and add B-A to mAvailableAdmins.
352f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        addDeviceAdminBroadcastReceiversForProfile(activeAdminsListForProfile, profileId);
353f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
354f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
355f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
356f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Add a profile's device admins that are receivers of
357f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * {@code DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED} to the internal collection if they
358f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * haven't been added yet.
359f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
360f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param alreadyAddedComponents the set of active admin component names. Receivers of
361f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *            {@code DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED} whose component is in this
362f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *            set are not added to the internal collection again.
363f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param profileId the identifier of the profile
364f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
365f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private void addDeviceAdminBroadcastReceiversForProfile(
366f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Collection<ComponentName> alreadyAddedComponents, final int profileId) {
367f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final PackageManager pm = getActivity().getPackageManager();
368df828405b107fd6a2602580cf7e8f43723c69d58Jeff Sharkey        List<ResolveInfo> enabledForProfile = pm.queryBroadcastReceiversAsUser(
369f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
370f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
371f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                profileId);
372f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        if (enabledForProfile == null) {
373f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            enabledForProfile = Collections.emptyList();
374f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
375f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final int n = enabledForProfile.size();
376f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        for (int i = 0; i < n; ++i) {
377f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            ResolveInfo resolveInfo = enabledForProfile.get(i);
378f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            ComponentName riComponentName =
379f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    new ComponentName(resolveInfo.activityInfo.packageName,
380f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                            resolveInfo.activityInfo.name);
381f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (alreadyAddedComponents == null
382f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    || !alreadyAddedComponents.contains(riComponentName)) {
3837cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                DeviceAdminInfo deviceAdminInfo =  createDeviceAdminInfo(resolveInfo.activityInfo);
384f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                // add only visible ones (note: active admins are added regardless of visibility)
385f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) {
3869dbad57a84035642a6c174158352a2e03f88f522Makoto Onuki                    if (!deviceAdminInfo.getActivityInfo().applicationInfo.isInternal()) {
3879dbad57a84035642a6c174158352a2e03f88f522Makoto Onuki                        continue;
3889dbad57a84035642a6c174158352a2e03f88f522Makoto Onuki                    }
3897a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                    DeviceAdminListItem item = new DeviceAdminListItem();
3907a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                    item.info = deviceAdminInfo;
3917a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                    item.name = deviceAdminInfo.loadLabel(pm).toString();
3927a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                    // Active ones already added.
3937a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                    item.active = false;
3947a3555961d9827ead97da293ef1e84a2c1d827d5Kenny Guy                    mAdmins.add(item);
395f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
396f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
397feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
398f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
399f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
400f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
401f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Add a {@link DeviceAdminInfo} object to the internal collection of available admins for all
402f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * active admin components associated with a profile.
403f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
404f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param profileId a profile identifier.
405f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
406f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private void addActiveAdminsForProfile(final List<ComponentName> activeAdmins,
407f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int profileId) {
408f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        if (activeAdmins != null) {
409f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final PackageManager packageManager = getActivity().getPackageManager();
4107cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki            final IPackageManager iPackageManager = AppGlobals.getPackageManager();
411f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int n = activeAdmins.size();
412f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            for (int i = 0; i < n; ++i) {
4137cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                final ComponentName activeAdmin = activeAdmins.get(i);
4147cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                final ActivityInfo ai;
4157cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                try {
4167cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                    ai = iPackageManager.getReceiverInfo(activeAdmin,
4177cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                            PackageManager.GET_META_DATA |
4187cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                            PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
4192079a38036545eb412ba92f8f0de73ee37672d9fJeff Sharkey                            PackageManager.MATCH_DIRECT_BOOT_UNAWARE |
4202079a38036545eb412ba92f8f0de73ee37672d9fJeff Sharkey                            PackageManager.MATCH_DIRECT_BOOT_AWARE, profileId);
4217cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                } catch (RemoteException e) {
4227cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                    Log.w(TAG, "Unable to load component: " + activeAdmin);
4237cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                    continue;
4247cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                }
4257cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                final DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(ai);
4267cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                if (deviceAdminInfo == null) {
4277cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                    continue;
428f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
4297cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                // Don't do the applicationInfo.isInternal() check here; if an active
4307cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                // admin is already on SD card, just show it.
4317cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                final DeviceAdminListItem item = new DeviceAdminListItem();
4327cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                item.info = deviceAdminInfo;
4337cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                item.name = deviceAdminInfo.loadLabel(packageManager).toString();
4347cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                item.active = true;
4357cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki                mAdmins.add(item);
436f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
437f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
438f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
439f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
440f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
441f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Creates a device admin info object for the resolved intent that points to the component of
442f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * the device admin.
443f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
4447cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki     * @param ai ActivityInfo for the admin component.
445f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @return new {@link DeviceAdminInfo} object or null if there was an error.
446f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
4477cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki    private DeviceAdminInfo createDeviceAdminInfo(ActivityInfo ai) {
448f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        try {
4497cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki            return new DeviceAdminInfo(getActivity(), ai);
4507cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki        } catch (XmlPullParserException|IOException e) {
4517cdaa52161bccd240de3a42846a1a0a677be8b47Makoto Onuki            Log.w(TAG, "Skipping " + ai, e);
452f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
453f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return null;
454f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
455f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
456f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
457f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Extracts the user id from a device admin info object.
458f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param adminInfo the device administrator info.
459f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @return identifier of the user associated with the device admin.
460f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
461f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private int getUserId(DeviceAdminInfo adminInfo) {
462f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return UserHandle.getUserId(adminInfo.getActivityInfo().applicationInfo.uid);
463feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
464feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn}
465