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 17package com.android.settings; 18 19import org.xmlpull.v1.XmlPullParserException; 20 21import android.app.Activity; 22import android.app.AlertDialog; 23import android.app.Dialog; 24import android.app.admin.DeviceAdminInfo; 25import android.app.admin.DeviceAdminReceiver; 26import android.app.admin.DevicePolicyManager; 27import android.content.ComponentName; 28import android.content.Context; 29import android.content.DialogInterface; 30import android.content.Intent; 31import android.content.pm.ActivityInfo; 32import android.content.pm.PackageManager; 33import android.content.pm.ResolveInfo; 34import android.content.res.Resources; 35import android.os.Bundle; 36import android.os.Handler; 37import android.os.RemoteCallback; 38import android.text.TextUtils.TruncateAt; 39import android.util.Log; 40import android.view.Display; 41import android.view.View; 42import android.view.ViewGroup; 43import android.view.WindowManager; 44import android.widget.AppSecurityPermissions; 45import android.widget.Button; 46import android.widget.ImageView; 47import android.widget.TextView; 48 49import java.io.IOException; 50import java.util.ArrayList; 51 52public class DeviceAdminAdd extends Activity { 53 static final String TAG = "DeviceAdminAdd"; 54 55 static final int DIALOG_WARNING = 1; 56 57 private static final int MAX_ADD_MSG_LINES_PORTRAIT = 5; 58 private static final int MAX_ADD_MSG_LINES_LANDSCAPE = 2; 59 private static final int MAX_ADD_MSG_LINES = 15; 60 61 Handler mHandler; 62 63 DevicePolicyManager mDPM; 64 DeviceAdminInfo mDeviceAdmin; 65 CharSequence mAddMsgText; 66 67 TextView mTitle; 68 ImageView mAdminIcon; 69 TextView mAdminName; 70 TextView mAdminDescription; 71 TextView mAddMsg; 72 boolean mAddMsgEllipsized = true; 73 TextView mAdminWarning; 74 ViewGroup mAdminPolicies; 75 Button mActionButton; 76 Button mCancelButton; 77 78 View mSelectLayout; 79 80 final ArrayList<View> mAddingPolicies = new ArrayList<View>(); 81 final ArrayList<View> mActivePolicies = new ArrayList<View>(); 82 83 boolean mAdding; 84 85 @Override 86 protected void onCreate(Bundle icicle) { 87 super.onCreate(icicle); 88 89 mHandler = new Handler(getMainLooper()); 90 91 mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE); 92 93 if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 94 Log.w(TAG, "Can now start ADD_DEVICE_ADMIN as a new task"); 95 finish(); 96 return; 97 } 98 99 ComponentName cn = (ComponentName)getIntent().getParcelableExtra( 100 DevicePolicyManager.EXTRA_DEVICE_ADMIN); 101 if (cn == null) { 102 Log.w(TAG, "No component specified in " + getIntent().getAction()); 103 finish(); 104 return; 105 } 106 if (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN.equals(getIntent().getAction())) { 107 // If this was an add request, then just exit immediately if the 108 // given component is already added. 109 if (mDPM.isAdminActive(cn)) { 110 setResult(Activity.RESULT_OK); 111 finish(); 112 return; 113 } 114 } 115 116 ActivityInfo ai; 117 try { 118 ai = getPackageManager().getReceiverInfo(cn, 119 PackageManager.GET_META_DATA); 120 } catch (PackageManager.NameNotFoundException e) { 121 Log.w(TAG, "Unable to retrieve device policy " + cn, e); 122 finish(); 123 return; 124 } 125 126 ResolveInfo ri = new ResolveInfo(); 127 ri.activityInfo = ai; 128 try { 129 mDeviceAdmin= new DeviceAdminInfo(this, ri); 130 } catch (XmlPullParserException e) { 131 Log.w(TAG, "Unable to retrieve device policy " + cn, e); 132 finish(); 133 return; 134 } catch (IOException e) { 135 Log.w(TAG, "Unable to retrieve device policy " + cn, e); 136 finish(); 137 return; 138 } 139 140 mAddMsgText = getIntent().getCharSequenceExtra( 141 DevicePolicyManager.EXTRA_ADD_EXPLANATION); 142 143 setContentView(R.layout.device_admin_add); 144 145 mTitle = (TextView)findViewById(R.id.title); 146 mAdminIcon = (ImageView)findViewById(R.id.admin_icon); 147 mAdminName = (TextView)findViewById(R.id.admin_name); 148 mAdminDescription = (TextView)findViewById(R.id.admin_description); 149 150 mAddMsg = (TextView)findViewById(R.id.add_msg); 151 mAddMsg.setOnClickListener(new View.OnClickListener() { 152 public void onClick(View v) { 153 toggleMessageEllipsis(v); 154 } 155 }); 156 157 // toggleMessageEllipsis also handles initial layout: 158 toggleMessageEllipsis(mAddMsg); 159 160 mAdminWarning = (TextView)findViewById(R.id.admin_warning); 161 mAdminPolicies = (ViewGroup)findViewById(R.id.admin_policies); 162 mCancelButton = (Button)findViewById(R.id.cancel_button); 163 mCancelButton.setOnClickListener(new View.OnClickListener() { 164 public void onClick(View v) { 165 finish(); 166 } 167 }); 168 mActionButton = (Button)findViewById(R.id.action_button); 169 mActionButton.setOnClickListener(new View.OnClickListener() { 170 public void onClick(View v) { 171 if (mAdding) { 172 try { 173 mDPM.setActiveAdmin(mDeviceAdmin.getComponent()); 174 setResult(Activity.RESULT_OK); 175 } catch (RuntimeException e) { 176 // Something bad happened... could be that it was 177 // already set, though. 178 Log.w(TAG, "Exception trying to activate admin " 179 + mDeviceAdmin.getComponent(), e); 180 if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) { 181 setResult(Activity.RESULT_OK); 182 } 183 } 184 finish(); 185 } else { 186 mDPM.getRemoveWarning(mDeviceAdmin.getComponent(), 187 new RemoteCallback(mHandler) { 188 @Override 189 protected void onResult(Bundle bundle) { 190 CharSequence msg = bundle != null 191 ? bundle.getCharSequence( 192 DeviceAdminReceiver.EXTRA_DISABLE_WARNING) 193 : null; 194 if (msg == null) { 195 mDPM.removeActiveAdmin(mDeviceAdmin.getComponent()); 196 finish(); 197 } else { 198 Bundle args = new Bundle(); 199 args.putCharSequence( 200 DeviceAdminReceiver.EXTRA_DISABLE_WARNING, msg); 201 showDialog(DIALOG_WARNING, args); 202 } 203 } 204 }); 205 } 206 } 207 }); 208 } 209 210 @Override 211 protected void onResume() { 212 super.onResume(); 213 updateInterface(); 214 } 215 216 @Override 217 protected Dialog onCreateDialog(int id, Bundle args) { 218 switch (id) { 219 case DIALOG_WARNING: { 220 CharSequence msg = args.getCharSequence(DeviceAdminReceiver.EXTRA_DISABLE_WARNING); 221 AlertDialog.Builder builder = new AlertDialog.Builder( 222 DeviceAdminAdd.this); 223 builder.setMessage(msg); 224 builder.setPositiveButton(R.string.dlg_ok, 225 new DialogInterface.OnClickListener() { 226 public void onClick(DialogInterface dialog, int which) { 227 mDPM.removeActiveAdmin(mDeviceAdmin.getComponent()); 228 finish(); 229 } 230 }); 231 builder.setNegativeButton(R.string.dlg_cancel, null); 232 return builder.create(); 233 } 234 default: 235 return super.onCreateDialog(id, args); 236 237 } 238 } 239 240 static void setViewVisibility(ArrayList<View> views, int visibility) { 241 final int N = views.size(); 242 for (int i=0; i<N; i++) { 243 views.get(i).setVisibility(visibility); 244 } 245 } 246 247 void updateInterface() { 248 mAdminIcon.setImageDrawable(mDeviceAdmin.loadIcon(getPackageManager())); 249 mAdminName.setText(mDeviceAdmin.loadLabel(getPackageManager())); 250 try { 251 mAdminDescription.setText( 252 mDeviceAdmin.loadDescription(getPackageManager())); 253 mAdminDescription.setVisibility(View.VISIBLE); 254 } catch (Resources.NotFoundException e) { 255 mAdminDescription.setVisibility(View.GONE); 256 } 257 if (mAddMsgText != null) { 258 mAddMsg.setText(mAddMsgText); 259 mAddMsg.setVisibility(View.VISIBLE); 260 } else { 261 mAddMsg.setVisibility(View.GONE); 262 } 263 if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) { 264 if (mActivePolicies.size() == 0) { 265 ArrayList<DeviceAdminInfo.PolicyInfo> policies = mDeviceAdmin.getUsedPolicies(); 266 for (int i=0; i<policies.size(); i++) { 267 DeviceAdminInfo.PolicyInfo pi = policies.get(i); 268 View view = AppSecurityPermissions.getPermissionItemView( 269 this, getText(pi.label), "", true); 270 mActivePolicies.add(view); 271 mAdminPolicies.addView(view); 272 } 273 } 274 setViewVisibility(mActivePolicies, View.VISIBLE); 275 setViewVisibility(mAddingPolicies, View.GONE); 276 mAdminWarning.setText(getString(R.string.device_admin_status, 277 mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager()))); 278 mTitle.setText(getText(R.string.active_device_admin_msg)); 279 mActionButton.setText(getText(R.string.remove_device_admin)); 280 mAdding = false; 281 } else { 282 if (mAddingPolicies.size() == 0) { 283 ArrayList<DeviceAdminInfo.PolicyInfo> policies = mDeviceAdmin.getUsedPolicies(); 284 for (int i=0; i<policies.size(); i++) { 285 DeviceAdminInfo.PolicyInfo pi = policies.get(i); 286 View view = AppSecurityPermissions.getPermissionItemView( 287 this, getText(pi.label), getText(pi.description), true); 288 mAddingPolicies.add(view); 289 mAdminPolicies.addView(view); 290 } 291 } 292 setViewVisibility(mAddingPolicies, View.VISIBLE); 293 setViewVisibility(mActivePolicies, View.GONE); 294 mAdminWarning.setText(getString(R.string.device_admin_warning, 295 mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager()))); 296 mTitle.setText(getText(R.string.add_device_admin_msg)); 297 mActionButton.setText(getText(R.string.add_device_admin)); 298 mAdding = true; 299 } 300 } 301 302 303 void toggleMessageEllipsis(View v) { 304 TextView tv = (TextView) v; 305 306 mAddMsgEllipsized = ! mAddMsgEllipsized; 307 tv.setEllipsize(mAddMsgEllipsized ? TruncateAt.END : null); 308 tv.setMaxLines(mAddMsgEllipsized ? getEllipsizedLines() : MAX_ADD_MSG_LINES); 309 310 ImageView iv = (ImageView) findViewById(R.id.add_msg_expander); 311 iv.setImageResource(mAddMsgEllipsized ? 312 com.android.internal.R.drawable.expander_ic_minimized : 313 com.android.internal.R.drawable.expander_ic_maximized); 314 } 315 316 int getEllipsizedLines() { 317 Display d = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) 318 .getDefaultDisplay(); 319 320 return d.getHeight() > d.getWidth() ? 321 MAX_ADD_MSG_LINES_PORTRAIT : MAX_ADD_MSG_LINES_LANDSCAPE; 322 } 323 324} 325