1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings; 18 19 import org.xmlpull.v1.XmlPullParser; 20 import org.xmlpull.v1.XmlPullParserException; 21 22 import android.app.Activity; 23 import android.app.ListFragment; 24 import android.app.admin.DeviceAdminInfo; 25 import android.app.admin.DeviceAdminReceiver; 26 import android.app.admin.DevicePolicyManager; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.pm.PackageManager; 31 import android.content.pm.ResolveInfo; 32 import android.content.res.Resources; 33 import android.os.Bundle; 34 import android.util.Log; 35 import android.view.LayoutInflater; 36 import android.view.View; 37 import android.view.ViewGroup; 38 import android.widget.BaseAdapter; 39 import android.widget.CheckBox; 40 import android.widget.ImageView; 41 import android.widget.ListView; 42 import android.widget.TextView; 43 44 import java.io.IOException; 45 import java.util.ArrayList; 46 import java.util.Collections; 47 import java.util.HashSet; 48 import java.util.List; 49 import java.util.Set; 50 51 public class DeviceAdminSettings extends ListFragment { 52 static final String TAG = "DeviceAdminSettings"; 53 54 static final int DIALOG_WARNING = 1; 55 56 DevicePolicyManager mDPM; 57 final HashSet<ComponentName> mActiveAdmins = new HashSet<ComponentName>(); 58 final ArrayList<DeviceAdminInfo> mAvailableAdmins = new ArrayList<DeviceAdminInfo>(); 59 String mDeviceOwnerPkg; 60 61 @Override 62 public void onCreate(Bundle icicle) { 63 super.onCreate(icicle); 64 } 65 66 @Override 67 public View onCreateView(LayoutInflater inflater, ViewGroup container, 68 Bundle savedInstanceState) { 69 mDPM = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); 70 return inflater.inflate(R.layout.device_admin_settings, container, false); 71 } 72 73 @Override 74 public void onResume() { 75 super.onResume(); 76 mDeviceOwnerPkg = mDPM.getDeviceOwner(); 77 if (mDeviceOwnerPkg != null && !mDPM.isDeviceOwner(mDeviceOwnerPkg)) { 78 mDeviceOwnerPkg = null; 79 } 80 updateList(); 81 } 82 83 void updateList() { 84 mActiveAdmins.clear(); 85 List<ComponentName> cur = mDPM.getActiveAdmins(); 86 if (cur != null) { 87 for (int i=0; i<cur.size(); i++) { 88 mActiveAdmins.add(cur.get(i)); 89 } 90 } 91 92 mAvailableAdmins.clear(); 93 List<ResolveInfo> avail = getActivity().getPackageManager().queryBroadcastReceivers( 94 new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), 95 PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS); 96 if (avail == null) { 97 avail = Collections.emptyList(); 98 } 99 100 // Some admins listed in mActiveAdmins may not have been found by the above query. 101 // We thus add them separately. 102 Set<ComponentName> activeAdminsNotInAvail = new HashSet<ComponentName>(mActiveAdmins); 103 for (ResolveInfo ri : avail) { 104 ComponentName riComponentName = 105 new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); 106 activeAdminsNotInAvail.remove(riComponentName); 107 } 108 if (!activeAdminsNotInAvail.isEmpty()) { 109 avail = new ArrayList<ResolveInfo>(avail); 110 PackageManager packageManager = getActivity().getPackageManager(); 111 for (ComponentName unlistedActiveAdmin : activeAdminsNotInAvail) { 112 List<ResolveInfo> resolved = packageManager.queryBroadcastReceivers( 113 new Intent().setComponent(unlistedActiveAdmin), 114 PackageManager.GET_META_DATA 115 | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS); 116 if (resolved != null) { 117 avail.addAll(resolved); 118 } 119 } 120 } 121 122 for (int i = 0, count = avail.size(); i < count; i++) { 123 ResolveInfo ri = avail.get(i); 124 try { 125 DeviceAdminInfo dpi = new DeviceAdminInfo(getActivity(), ri); 126 if (dpi.isVisible() || mActiveAdmins.contains(dpi.getComponent())) { 127 mAvailableAdmins.add(dpi); 128 } 129 } catch (XmlPullParserException e) { 130 Log.w(TAG, "Skipping " + ri.activityInfo, e); 131 } catch (IOException e) { 132 Log.w(TAG, "Skipping " + ri.activityInfo, e); 133 } 134 } 135 136 getListView().setAdapter(new PolicyListAdapter()); 137 } 138 139 @Override 140 public void onListItemClick(ListView l, View v, int position, long id) { 141 DeviceAdminInfo dpi = (DeviceAdminInfo)l.getAdapter().getItem(position); 142 Intent intent = new Intent(); 143 intent.setClass(getActivity(), DeviceAdminAdd.class); 144 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, dpi.getComponent()); 145 startActivity(intent); 146 } 147 148 static class ViewHolder { 149 ImageView icon; 150 TextView name; 151 CheckBox checkbox; 152 TextView description; 153 } 154 155 class PolicyListAdapter extends BaseAdapter { 156 final LayoutInflater mInflater; 157 158 PolicyListAdapter() { 159 mInflater = (LayoutInflater) 160 getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 161 } 162 163 public boolean hasStableIds() { 164 return true; 165 } 166 167 public int getCount() { 168 return mAvailableAdmins.size(); 169 } 170 171 public Object getItem(int position) { 172 return mAvailableAdmins.get(position); 173 } 174 175 public long getItemId(int position) { 176 return position; 177 } 178 179 public boolean areAllItemsEnabled() { 180 return false; 181 } 182 183 public boolean isEnabled(int position) { 184 DeviceAdminInfo info = mAvailableAdmins.get(position); 185 if (mActiveAdmins.contains(info.getComponent()) 186 && info.getPackageName().equals(mDeviceOwnerPkg)) { 187 return false; 188 } else { 189 return true; 190 } 191 } 192 193 public View getView(int position, View convertView, ViewGroup parent) { 194 View v; 195 if (convertView == null) { 196 v = newView(parent); 197 } else { 198 v = convertView; 199 } 200 bindView(v, position); 201 return v; 202 } 203 204 public View newView(ViewGroup parent) { 205 View v = mInflater.inflate(R.layout.device_admin_item, parent, false); 206 ViewHolder h = new ViewHolder(); 207 h.icon = (ImageView)v.findViewById(R.id.icon); 208 h.name = (TextView)v.findViewById(R.id.name); 209 h.checkbox = (CheckBox)v.findViewById(R.id.checkbox); 210 h.description = (TextView)v.findViewById(R.id.description); 211 v.setTag(h); 212 return v; 213 } 214 215 public void bindView(View view, int position) { 216 final Activity activity = getActivity(); 217 ViewHolder vh = (ViewHolder) view.getTag(); 218 DeviceAdminInfo item = mAvailableAdmins.get(position); 219 vh.icon.setImageDrawable(item.loadIcon(activity.getPackageManager())); 220 vh.name.setText(item.loadLabel(activity.getPackageManager())); 221 vh.checkbox.setChecked(mActiveAdmins.contains(item.getComponent())); 222 final boolean activeOwner = vh.checkbox.isChecked() 223 && item.getPackageName().equals(mDeviceOwnerPkg); 224 try { 225 vh.description.setText(item.loadDescription(activity.getPackageManager())); 226 } catch (Resources.NotFoundException e) { 227 } 228 vh.checkbox.setEnabled(!activeOwner); 229 vh.name.setEnabled(!activeOwner); 230 vh.description.setEnabled(!activeOwner); 231 vh.icon.setEnabled(!activeOwner); 232 } 233 } 234 } 235