Home | History | Annotate | Download | only in settings
      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.XmlPullParserException;
     20 
     21 import android.app.Activity;
     22 import android.app.AlertDialog;
     23 import android.app.Dialog;
     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.DialogInterface;
     30 import android.content.Intent;
     31 import android.content.pm.ActivityInfo;
     32 import android.content.pm.PackageManager;
     33 import android.content.pm.ResolveInfo;
     34 import android.content.res.Resources;
     35 import android.os.Bundle;
     36 import android.os.Handler;
     37 import android.os.RemoteCallback;
     38 import android.text.TextUtils.TruncateAt;
     39 import android.util.Log;
     40 import android.view.Display;
     41 import android.view.View;
     42 import android.view.ViewGroup;
     43 import android.view.WindowManager;
     44 import android.widget.AppSecurityPermissions;
     45 import android.widget.Button;
     46 import android.widget.ImageView;
     47 import android.widget.TextView;
     48 
     49 import java.io.IOException;
     50 import java.util.ArrayList;
     51 
     52 public 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