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 org.xmlpull.v1.XmlPullParserException;
20feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
21feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.app.Activity;
22f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.app.AlertDialog;
23a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasaniimport android.app.ListFragment;
244037c7f27c849a1ada0980ad881636fc940a0b85Dianne Hackbornimport android.app.admin.DeviceAdminInfo;
254037c7f27c849a1ada0980ad881636fc940a0b85Dianne Hackbornimport android.app.admin.DeviceAdminReceiver;
264037c7f27c849a1ada0980ad881636fc940a0b85Dianne Hackbornimport android.app.admin.DevicePolicyManager;
27cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolovimport android.content.BroadcastReceiver;
28feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.ComponentName;
29feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.Context;
30feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.content.Intent;
31cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolovimport android.content.IntentFilter;
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;
37f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.os.UserHandle;
38f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.os.UserManager;
39feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.util.Log;
40f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Banimport android.util.SparseArray;
41feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.view.LayoutInflater;
42feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.view.View;
43feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.view.ViewGroup;
44feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.BaseAdapter;
4561daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackbornimport android.widget.CheckBox;
46feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.ImageView;
47feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.ListView;
48feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport android.widget.TextView;
49feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
50feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport java.io.IOException;
51feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport java.util.ArrayList;
52cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolovimport java.util.Collection;
53d14258e50efc3677abef3cd204b67e7f26e47b56Alex Klyubinimport java.util.Collections;
54feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackbornimport java.util.List;
55feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
56a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasanipublic class DeviceAdminSettings extends ListFragment {
57feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    static final String TAG = "DeviceAdminSettings";
58b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
59f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private DevicePolicyManager mDPM;
60f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private UserManager mUm;
61b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
62f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
63f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Internal collection of device admin info objects for all profiles associated with the current
64f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * user.
65f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
66f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private final SparseArray<ArrayList<DeviceAdminInfo>>
67f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            mAdminsByProfile = new SparseArray<ArrayList<DeviceAdminInfo>>();
68f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
69f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private String mDeviceOwnerPkg;
70f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private SparseArray<ComponentName> mProfileOwnerComponents = new SparseArray<ComponentName>();
71a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
72cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
73cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        @Override
74cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        public void onReceive(Context context, Intent intent) {
75cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            // Refresh the list, if state change has been received. It could be that checkboxes
76cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            // need to be updated
77cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
78cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                    intent.getAction())) {
79cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                updateList();
80cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            }
81cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        }
82cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    };
83cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov
84feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    @Override
85a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public void onCreate(Bundle icicle) {
86feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        super.onCreate(icicle);
87a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    }
88feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
89a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    @Override
90a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public View onCreateView(LayoutInflater inflater, ViewGroup container,
91a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            Bundle savedInstanceState) {
92a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani        mDPM = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
93f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
94a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani        return inflater.inflate(R.layout.device_admin_settings, container, false);
95feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
96a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
9728429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn    @Override
98402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio    public void onActivityCreated(Bundle savedInstanceState) {
99402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio        super.onActivityCreated(savedInstanceState);
100402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio
101402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio        Utils.forceCustomPadding(getListView(), true /* additive padding */);
102402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio    }
103402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio
104402c4515dbe03ac56425569812e970d86095e3daFabrice Di Meglio    @Override
105a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public void onResume() {
10628429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn        super.onResume();
107cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        IntentFilter filter = new IntentFilter();
108cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
109cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        getActivity().registerReceiverAsUser(
110cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                mBroadcastReceiver, UserHandle.ALL, filter, null, null);
111f3f7c1dfb7abb35d7eea9afb39e5076b2e421006Amith Yamasani        mDeviceOwnerPkg = mDPM.getDeviceOwner();
112f3f7c1dfb7abb35d7eea9afb39e5076b2e421006Amith Yamasani        if (mDeviceOwnerPkg != null && !mDPM.isDeviceOwner(mDeviceOwnerPkg)) {
113f3f7c1dfb7abb35d7eea9afb39e5076b2e421006Amith Yamasani            mDeviceOwnerPkg = null;
114f3f7c1dfb7abb35d7eea9afb39e5076b2e421006Amith Yamasani        }
115f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        mProfileOwnerComponents.clear();
116f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final List<UserHandle> profiles = mUm.getUserProfiles();
117f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final int profilesSize = profiles.size();
118f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        for (int i = 0; i < profilesSize; ++i) {
119f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int profileId = profiles.get(i).getIdentifier();
120f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            mProfileOwnerComponents.put(profileId, mDPM.getProfileOwnerAsUser(profileId));
121f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
12261daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        updateList();
12328429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn    }
12428429033375c3876af56528bfc9ea6b541052fcbDianne Hackborn
125cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    @Override
126cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    public void onPause() {
127cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        getActivity().unregisterReceiver(mBroadcastReceiver);
128cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        super.onPause();
129cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    }
130cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov
131f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
132f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Update the internal collection of available admins for all profiles associated with the
133f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * current user.
134f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
13561daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn    void updateList() {
136f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        mAdminsByProfile.clear();
137d14258e50efc3677abef3cd204b67e7f26e47b56Alex Klyubin
138f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final List<UserHandle> profiles = mUm.getUserProfiles();
139f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final int profilesSize = profiles.size();
140f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        for (int i = 0; i < profilesSize; ++i) {
141f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int profileId = profiles.get(i).getIdentifier();
142f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            updateAvailableAdminsForProfile(profileId);
143feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
144b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
14561daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        getListView().setAdapter(new PolicyListAdapter());
146feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
147a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
148feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    @Override
149a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani    public void onListItemClick(ListView l, View v, int position, long id) {
150d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban        Object o = l.getAdapter().getItem(position);
151d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban        if (!(o instanceof DeviceAdminInfo)) {
152d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban            // race conditions may cause this
153d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban            return;
154d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban        }
155d92897d39fb9734cf2fd8c74ff1f6f3233933086Zoltan Szatmary-Ban        DeviceAdminInfo dpi = (DeviceAdminInfo) o;
156f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final Activity activity = getActivity();
157f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final int userId = getUserId(dpi);
158f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        if (userId == UserHandle.myUserId() || !isProfileOwner(dpi)) {
159f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Intent intent = new Intent();
160f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            intent.setClass(activity, DeviceAdminAdd.class);
161f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, dpi.getComponent());
162f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            activity.startActivityAsUser(intent, new UserHandle(userId));
163f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        } else {
164f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
165f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            builder.setMessage(getString(R.string.managed_profile_device_admin_info,
166f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    dpi.loadLabel(activity.getPackageManager())));
167f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            builder.setPositiveButton(android.R.string.ok, null);
168f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            builder.create().show();
169f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
170feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
171a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani
172feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    static class ViewHolder {
173feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        ImageView icon;
174feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        TextView name;
17561daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        CheckBox checkbox;
17661daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn        TextView description;
177feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
178b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
179feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    class PolicyListAdapter extends BaseAdapter {
180feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        final LayoutInflater mInflater;
181b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
182feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        PolicyListAdapter() {
183a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            mInflater = (LayoutInflater)
184a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani                    getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
185feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
186feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
187f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
188feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public boolean hasStableIds() {
189f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return false;
190feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
191b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
192f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
193feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public int getCount() {
194f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            int adminCount = 0;
195f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int profileCount = mAdminsByProfile.size();
196f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            for (int i = 0; i < profileCount; ++i) {
197f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                adminCount += mAdminsByProfile.valueAt(i).size();
198f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
199f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            // Add 'profileCount' for title items.
200f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return adminCount + profileCount;
201feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
202feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
203f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        /**
204f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         * The item for the given position in the list.
205f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         *
206f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         * @return a String object for title items and a DeviceAdminInfo object for actual device
207f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         *         admins.
208f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         */
209f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
210feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public Object getItem(int position) {
211f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (position < 0) {
212f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                throw new ArrayIndexOutOfBoundsException();
213f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
214f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            // The position of the item in the list of admins.
215f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            // We start from the given position and discount the length of the upper lists until we
216f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            // get the one for the right profile
217f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            int adminPosition = position;
218f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int n = mAdminsByProfile.size();
219f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            int i = 0;
220f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            for (; i < n; ++i) {
221f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                // The elements in that section including the title item (that's why adding one).
222f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                final int listSize = mAdminsByProfile.valueAt(i).size() + 1;
223f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                if (adminPosition < listSize) {
224f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    break;
225f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
226f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                adminPosition -= listSize;
227f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
228f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (i == n) {
229f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                throw new ArrayIndexOutOfBoundsException();
230f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
231f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            // If countdown == 0 that means the title item
232f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (adminPosition == 0) {
233f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                Resources res = getActivity().getResources();
234f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                if (mAdminsByProfile.keyAt(i) == UserHandle.myUserId()) {
235f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    return res.getString(R.string.personal_device_admin_title);
236f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                } else {
237f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    return res.getString(R.string.managed_device_admin_title);
238f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
239f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            } else {
240f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                // Subtracting one for the title.
241f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                return mAdminsByProfile.valueAt(i).get(adminPosition - 1);
242f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
243feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
244feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
245f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
246feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public long getItemId(int position) {
247feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            return position;
248feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
249feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
250f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
251feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public boolean areAllItemsEnabled() {
252feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            return false;
253feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
254feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
255f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        /**
256f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         * See {@link #getItemViewType} for the view types.
257f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         */
258f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
259f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        public int getViewTypeCount() {
260f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return 2;
261f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
262f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
263f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        /**
264f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         * Returns 1 for title items and 0 for anything else.
265f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban         */
266f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
267f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        public int getItemViewType(int position) {
268f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Object o = getItem(position);
269f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return (o instanceof String) ? 1 : 0;
270f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
271f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
272f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
273feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public boolean isEnabled(int position) {
274f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Object o = getItem(position);
275f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return isEnabled(o);
276f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
277f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
278f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        private boolean isEnabled(Object o) {
279f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (!(o instanceof DeviceAdminInfo)) {
280f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                // Title item
281f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                return false;
282f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
283f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            DeviceAdminInfo info = (DeviceAdminInfo) o;
284f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (isActiveAdmin(info) && getUserId(info) == UserHandle.myUserId()
285f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    && (isDeviceOwner(info) || isProfileOwner(info))) {
286f3f7c1dfb7abb35d7eea9afb39e5076b2e421006Amith Yamasani                return false;
287f3f7c1dfb7abb35d7eea9afb39e5076b2e421006Amith Yamasani            }
288cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            // Disable item if admin is being removed
289cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            if (isRemovingAdmin(info)) {
290cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov                return false;
291cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov            }
292f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return true;
293feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
294feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn
295f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        @Override
296feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        public View getView(int position, View convertView, ViewGroup parent) {
297f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Object o = getItem(position);
298f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (o instanceof DeviceAdminInfo) {
299f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                if (convertView == null) {
300f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    convertView = newDeviceAdminView(parent);
301f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
302f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                bindView(convertView, (DeviceAdminInfo) o);
303feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            } else {
304f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                if (convertView == null) {
3053af2e4c35c898d61b6268f22123135b403b3fa3bZoltan Szatmary-Ban                    convertView = Utils.inflateCategoryHeader(mInflater, parent);
306f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
307f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                final TextView title = (TextView) convertView.findViewById(android.R.id.title);
308f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                title.setText((String)o);
309feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            }
310f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return convertView;
311feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
312b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
313f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        private View newDeviceAdminView(ViewGroup parent) {
314feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            View v = mInflater.inflate(R.layout.device_admin_item, parent, false);
315feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            ViewHolder h = new ViewHolder();
316feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            h.icon = (ImageView)v.findViewById(R.id.icon);
317feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            h.name = (TextView)v.findViewById(R.id.name);
31861daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            h.checkbox = (CheckBox)v.findViewById(R.id.checkbox);
31961daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            h.description = (TextView)v.findViewById(R.id.description);
320feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            v.setTag(h);
321feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            return v;
322feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
323b8e0f608cf28f20b95b65a4f7c0b345298d98e41Amith Yamasani
324f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        private void bindView(View view, DeviceAdminInfo item) {
325a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            final Activity activity = getActivity();
326feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn            ViewHolder vh = (ViewHolder) view.getTag();
327f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Drawable activityIcon = item.loadIcon(activity.getPackageManager());
32830c50b15d0d716567c71d590aa835dc4a27591d6Amith Yamasani            Drawable badgedIcon = activity.getPackageManager().getUserBadgedIcon(
32930c50b15d0d716567c71d590aa835dc4a27591d6Amith Yamasani                    activityIcon, new UserHandle(getUserId(item)));
330f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.icon.setImageDrawable(badgedIcon);
331a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani            vh.name.setText(item.loadLabel(activity.getPackageManager()));
332f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.checkbox.setChecked(isActiveAdmin(item));
333f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final boolean enabled = isEnabled(item);
33461daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            try {
335a1d01841664131eca201acfaf747f1f187de10f6Amith Yamasani                vh.description.setText(item.loadDescription(activity.getPackageManager()));
33661daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            } catch (Resources.NotFoundException e) {
33761daf83ca8bcf1353e0e81316a2b3809ec7397c5Dianne Hackborn            }
338f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.checkbox.setEnabled(enabled);
339f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.name.setEnabled(enabled);
340f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.description.setEnabled(enabled);
341f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            vh.icon.setEnabled(enabled);
342f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
343f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
344f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
345f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private boolean isDeviceOwner(DeviceAdminInfo item) {
346f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return getUserId(item) == UserHandle.myUserId()
347f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                && item.getPackageName().equals(mDeviceOwnerPkg);
348f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
349f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
350f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private boolean isProfileOwner(DeviceAdminInfo item) {
351f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        ComponentName profileOwner = mProfileOwnerComponents.get(getUserId(item));
352f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return item.getComponent().equals(profileOwner);
353f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
354f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
355f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private boolean isActiveAdmin(DeviceAdminInfo item) {
356f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return mDPM.isAdminActiveAsUser(item.getComponent(), getUserId(item));
357f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
358f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
359cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    private boolean isRemovingAdmin(DeviceAdminInfo item) {
360cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov        return mDPM.isRemovingAdmin(item.getComponent(), getUserId(item));
361cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov    }
362cfae855d67990e783c24fdcafe1e6795f43b8caaFyodor Kupolov
363f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
364f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Add device admins to the internal collection that belong to a profile.
365f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
366f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param profileId the profile identifier.
367f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
368f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private void updateAvailableAdminsForProfile(final int profileId) {
369f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // We are adding the union of two sets 'A' and 'B' of device admins to mAvailableAdmins.
370f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // Set 'A' is the set of active admins for the profile whereas set 'B' is the set of
371f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // listeners to DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED for the profile.
372f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
373f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // Add all of set 'A' to mAvailableAdmins.
374f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        List<ComponentName> activeAdminsListForProfile = mDPM.getActiveAdminsAsUser(profileId);
375f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        addActiveAdminsForProfile(activeAdminsListForProfile, profileId);
376f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
377f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        // Collect set 'B' and add B-A to mAvailableAdmins.
378f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        addDeviceAdminBroadcastReceiversForProfile(activeAdminsListForProfile, profileId);
379f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
380f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
381f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
382f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Add a profile's device admins that are receivers of
383f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * {@code DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED} to the internal collection if they
384f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * haven't been added yet.
385f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
386f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param alreadyAddedComponents the set of active admin component names. Receivers of
387f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *            {@code DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED} whose component is in this
388f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *            set are not added to the internal collection again.
389f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param profileId the identifier of the profile
390f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
391f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private void addDeviceAdminBroadcastReceiversForProfile(
392f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Collection<ComponentName> alreadyAddedComponents, final int profileId) {
393f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final PackageManager pm = getActivity().getPackageManager();
394f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        List<ResolveInfo> enabledForProfile = pm.queryBroadcastReceivers(
395f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
396f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
397f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                profileId);
398f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        if (enabledForProfile == null) {
399f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            enabledForProfile = Collections.emptyList();
400f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
401f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        final int n = enabledForProfile.size();
402f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        ArrayList<DeviceAdminInfo> deviceAdmins = mAdminsByProfile.get(profileId);
403f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        if (deviceAdmins == null) {
404f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            deviceAdmins = new ArrayList<DeviceAdminInfo>(n);
405f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
406f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        for (int i = 0; i < n; ++i) {
407f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            ResolveInfo resolveInfo = enabledForProfile.get(i);
408f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            ComponentName riComponentName =
409f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    new ComponentName(resolveInfo.activityInfo.packageName,
410f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                            resolveInfo.activityInfo.name);
411f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (alreadyAddedComponents == null
412f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    || !alreadyAddedComponents.contains(riComponentName)) {
413f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolveInfo);
414f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                // add only visible ones (note: active admins are added regardless of visibility)
415f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) {
416f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    deviceAdmins.add(deviceAdminInfo);
417f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
418f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
419feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn        }
420f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        if (!deviceAdmins.isEmpty()) {
421f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            mAdminsByProfile.put(profileId, deviceAdmins);
422f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
423f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
424f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
425f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
426f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Add a {@link DeviceAdminInfo} object to the internal collection of available admins for all
427f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * active admin components associated with a profile.
428f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
429f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param profileId a profile identifier.
430f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
431f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private void addActiveAdminsForProfile(final List<ComponentName> activeAdmins,
432f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int profileId) {
433f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        if (activeAdmins != null) {
434f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final PackageManager packageManager = getActivity().getPackageManager();
435f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            final int n = activeAdmins.size();
436f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            ArrayList<DeviceAdminInfo> deviceAdmins = new ArrayList<DeviceAdminInfo>(n);
437f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            for (int i = 0; i < n; ++i) {
438f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                ComponentName activeAdmin = activeAdmins.get(i);
439f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                List<ResolveInfo> resolved = packageManager.queryBroadcastReceivers(
440f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                        new Intent().setComponent(activeAdmin), PackageManager.GET_META_DATA
441f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                                | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, profileId);
442f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                if (resolved != null) {
443f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    final int resolvedMax = resolved.size();
444f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    for (int j = 0; j < resolvedMax; ++j) {
445f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                        DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolved.get(j));
446f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                        if (deviceAdminInfo != null) {
447f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                            deviceAdmins.add(deviceAdminInfo);
448f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                        }
449f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                    }
450f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                }
451f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
452f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            if (!deviceAdmins.isEmpty()) {
453f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban                mAdminsByProfile.put(profileId, deviceAdmins);
454f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            }
455f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
456f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
457f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
458f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
459f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Creates a device admin info object for the resolved intent that points to the component of
460f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * the device admin.
461f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     *
462f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param resolved resolved intent.
463f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @return new {@link DeviceAdminInfo} object or null if there was an error.
464f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
465f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private DeviceAdminInfo createDeviceAdminInfo(ResolveInfo resolved) {
466f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        try {
467f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            return new DeviceAdminInfo(getActivity(), resolved);
468f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        } catch (XmlPullParserException e) {
469f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Log.w(TAG, "Skipping " + resolved.activityInfo, e);
470f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        } catch (IOException e) {
471f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban            Log.w(TAG, "Skipping " + resolved.activityInfo, e);
472f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        }
473f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return null;
474f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    }
475f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban
476f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    /**
477f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * Extracts the user id from a device admin info object.
478f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @param adminInfo the device administrator info.
479f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     * @return identifier of the user associated with the device admin.
480f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban     */
481f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban    private int getUserId(DeviceAdminInfo adminInfo) {
482f3d72098b0008a9a8e137985d7fbc0e0470adc9cZoltan Szatmary-Ban        return UserHandle.getUserId(adminInfo.getActivityInfo().applicationInfo.uid);
483feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn    }
484feff65213231ba6a0f6185f98e660042b5b14595Dianne Hackborn}
485