summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/DeviceAdminAdd.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/DeviceAdminAdd.java')
-rw-r--r--src/com/android/settings/DeviceAdminAdd.java236
1 files changed, 178 insertions, 58 deletions
diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java
index 6234038..ed95500 100644
--- a/src/com/android/settings/DeviceAdminAdd.java
+++ b/src/com/android/settings/DeviceAdminAdd.java
@@ -16,6 +16,8 @@
package com.android.settings;
+import android.app.AppOpsManager;
+
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
@@ -30,14 +32,19 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteCallback;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.text.TextUtils.TruncateAt;
+import android.util.EventLog;
import android.util.Log;
import android.view.Display;
import android.view.View;
@@ -50,68 +57,103 @@ import android.widget.TextView;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
public class DeviceAdminAdd extends Activity {
static final String TAG = "DeviceAdminAdd";
-
+
static final int DIALOG_WARNING = 1;
private static final int MAX_ADD_MSG_LINES_PORTRAIT = 5;
private static final int MAX_ADD_MSG_LINES_LANDSCAPE = 2;
private static final int MAX_ADD_MSG_LINES = 15;
-
+
Handler mHandler;
-
+
DevicePolicyManager mDPM;
+ AppOpsManager mAppOps;
DeviceAdminInfo mDeviceAdmin;
CharSequence mAddMsgText;
-
+ String mProfileOwnerName;
+
ImageView mAdminIcon;
TextView mAdminName;
TextView mAdminDescription;
TextView mAddMsg;
+ TextView mProfileOwnerWarning;
ImageView mAddMsgExpander;
boolean mAddMsgEllipsized = true;
TextView mAdminWarning;
ViewGroup mAdminPolicies;
Button mActionButton;
Button mCancelButton;
-
+
final ArrayList<View> mAddingPolicies = new ArrayList<View>();
final ArrayList<View> mActivePolicies = new ArrayList<View>();
-
+
boolean mAdding;
boolean mRefreshing;
-
+ boolean mWaitingForRemoveMsg;
+ boolean mAddingProfileOwner;
+ int mCurSysAppOpMode;
+ int mCurToastAppOpMode;
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mHandler = new Handler(getMainLooper());
-
+
mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
+ mAppOps = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
+ PackageManager packageManager = getPackageManager();
if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Log.w(TAG, "Cannot start ADD_DEVICE_ADMIN as a new task");
finish();
return;
}
-
- ComponentName cn = (ComponentName)getIntent().getParcelableExtra(
+
+ String action = getIntent().getAction();
+ ComponentName who = (ComponentName)getIntent().getParcelableExtra(
DevicePolicyManager.EXTRA_DEVICE_ADMIN);
- if (cn == null) {
- Log.w(TAG, "No component specified in " + getIntent().getAction());
+ if (who == null) {
+ Log.w(TAG, "No component specified in " + action);
finish();
return;
}
+ if (action != null && action.equals(DevicePolicyManager.ACTION_SET_PROFILE_OWNER)) {
+ setResult(RESULT_CANCELED);
+ setFinishOnTouchOutside(true);
+ mAddingProfileOwner = true;
+ mProfileOwnerName =
+ getIntent().getStringExtra(DevicePolicyManager.EXTRA_PROFILE_OWNER_NAME);
+ String callingPackage = getCallingPackage();
+ if (callingPackage == null || !callingPackage.equals(who.getPackageName())) {
+ Log.e(TAG, "Unknown or incorrect caller");
+ finish();
+ return;
+ }
+ try {
+ PackageInfo packageInfo = packageManager.getPackageInfo(callingPackage, 0);
+ if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ Log.e(TAG, "Cannot set a non-system app as a profile owner");
+ finish();
+ return;
+ }
+ } catch (NameNotFoundException nnfe) {
+ Log.e(TAG, "Cannot find the package " + callingPackage);
+ finish();
+ return;
+ }
+ }
+
ActivityInfo ai;
try {
- ai = getPackageManager().getReceiverInfo(cn, PackageManager.GET_META_DATA);
+ ai = packageManager.getReceiverInfo(who, PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Unable to retrieve device policy " + cn, e);
+ Log.w(TAG, "Unable to retrieve device policy " + who, e);
finish();
return;
}
@@ -119,8 +161,8 @@ public class DeviceAdminAdd extends Activity {
// When activating, make sure the given component name is actually a valid device admin.
// No need to check this when deactivating, because it is safe to deactivate an active
// invalid device admin.
- if (!mDPM.isAdminActive(cn)) {
- List<ResolveInfo> avail = getPackageManager().queryBroadcastReceivers(
+ if (!mDPM.isAdminActive(who)) {
+ List<ResolveInfo> avail = packageManager.queryBroadcastReceivers(
new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
int count = avail == null ? 0 : avail.size();
@@ -144,7 +186,7 @@ public class DeviceAdminAdd extends Activity {
}
}
if (!found) {
- Log.w(TAG, "Request to add invalid device admin: " + cn);
+ Log.w(TAG, "Request to add invalid device admin: " + who);
finish();
return;
}
@@ -155,25 +197,25 @@ public class DeviceAdminAdd extends Activity {
try {
mDeviceAdmin = new DeviceAdminInfo(this, ri);
} catch (XmlPullParserException e) {
- Log.w(TAG, "Unable to retrieve device policy " + cn, e);
+ Log.w(TAG, "Unable to retrieve device policy " + who, e);
finish();
return;
} catch (IOException e) {
- Log.w(TAG, "Unable to retrieve device policy " + cn, e);
+ Log.w(TAG, "Unable to retrieve device policy " + who, e);
finish();
return;
}
-
+
// This admin already exists, an we have two options at this point. If new policy
// bits are set, show the user the new list. If nothing has changed, simply return
// "OK" immediately.
if (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN.equals(getIntent().getAction())) {
mRefreshing = false;
- if (mDPM.isAdminActive(cn)) {
+ if (mDPM.isAdminActive(who)) {
ArrayList<DeviceAdminInfo.PolicyInfo> newPolicies = mDeviceAdmin.getUsedPolicies();
for (int i = 0; i < newPolicies.size(); i++) {
DeviceAdminInfo.PolicyInfo pi = newPolicies.get(i);
- if (!mDPM.hasGrantedPolicy(cn, pi.ident)) {
+ if (!mDPM.hasGrantedPolicy(who, pi.ident)) {
mRefreshing = true;
break;
}
@@ -186,13 +228,22 @@ public class DeviceAdminAdd extends Activity {
}
}
}
+
+ // If we're trying to add a profile owner and user setup hasn't completed yet, no
+ // need to prompt for permission. Just add and finish.
+ if (mAddingProfileOwner && !mDPM.hasUserSetupCompleted()) {
+ addAndFinish();
+ return;
+ }
+
mAddMsgText = getIntent().getCharSequenceExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION);
setContentView(R.layout.device_admin_add);
-
+
mAdminIcon = (ImageView)findViewById(R.id.admin_icon);
mAdminName = (TextView)findViewById(R.id.admin_name);
mAdminDescription = (TextView)findViewById(R.id.admin_description);
+ mProfileOwnerWarning = (TextView) findViewById(R.id.profile_owner_warning);
mAddMsg = (TextView)findViewById(R.id.add_msg);
mAddMsgExpander = (ImageView) findViewById(R.id.add_msg_expander);
@@ -210,6 +261,8 @@ public class DeviceAdminAdd extends Activity {
mCancelButton = (Button) findViewById(R.id.cancel_button);
mCancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
+ EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_DECLINED_BY_USER,
+ mDeviceAdmin.getActivityInfo().applicationInfo.uid);
finish();
}
});
@@ -217,26 +270,15 @@ public class DeviceAdminAdd extends Activity {
mActionButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mAdding) {
- try {
- mDPM.setActiveAdmin(mDeviceAdmin.getComponent(), mRefreshing);
- setResult(Activity.RESULT_OK);
- } catch (RuntimeException e) {
- // Something bad happened... could be that it was
- // already set, though.
- Log.w(TAG, "Exception trying to activate admin "
- + mDeviceAdmin.getComponent(), e);
- if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) {
- setResult(Activity.RESULT_OK);
- }
- }
- finish();
- } else {
+ addAndFinish();
+ } else if (!mWaitingForRemoveMsg) {
try {
// Don't allow the admin to put a dialog up in front
// of us while we interact with the user.
ActivityManagerNative.getDefault().stopAppSwitches();
} catch (RemoteException e) {
}
+ mWaitingForRemoveMsg = true;
mDPM.getRemoveWarning(mDeviceAdmin.getComponent(),
new RemoteCallback(mHandler) {
@Override
@@ -245,32 +287,98 @@ public class DeviceAdminAdd extends Activity {
? bundle.getCharSequence(
DeviceAdminReceiver.EXTRA_DISABLE_WARNING)
: null;
- if (msg == null) {
- try {
- ActivityManagerNative.getDefault().resumeAppSwitches();
- } catch (RemoteException e) {
- }
- mDPM.removeActiveAdmin(mDeviceAdmin.getComponent());
- finish();
- } else {
- Bundle args = new Bundle();
- args.putCharSequence(
- DeviceAdminReceiver.EXTRA_DISABLE_WARNING, msg);
- showDialog(DIALOG_WARNING, args);
- }
+ continueRemoveAction(msg);
}
});
+ // Don't want to wait too long.
+ getWindow().getDecorView().getHandler().postDelayed(new Runnable() {
+ @Override public void run() {
+ continueRemoveAction(null);
+ }
+ }, 2*1000);
}
}
});
}
-
+
+ void addAndFinish() {
+ try {
+ mDPM.setActiveAdmin(mDeviceAdmin.getComponent(), mRefreshing);
+ EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_ACTIVATED_BY_USER,
+ mDeviceAdmin.getActivityInfo().applicationInfo.uid);
+ setResult(Activity.RESULT_OK);
+ } catch (RuntimeException e) {
+ // Something bad happened... could be that it was
+ // already set, though.
+ Log.w(TAG, "Exception trying to activate admin "
+ + mDeviceAdmin.getComponent(), e);
+ if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) {
+ setResult(Activity.RESULT_OK);
+ }
+ }
+ if (mAddingProfileOwner) {
+ try {
+ mDPM.setProfileOwner(mDeviceAdmin.getComponent(),
+ mProfileOwnerName, UserHandle.myUserId());
+ } catch (RuntimeException re) {
+ setResult(Activity.RESULT_CANCELED);
+ }
+ }
+ finish();
+ }
+
+ void continueRemoveAction(CharSequence msg) {
+ if (!mWaitingForRemoveMsg) {
+ return;
+ }
+ mWaitingForRemoveMsg = false;
+ if (msg == null) {
+ try {
+ ActivityManagerNative.getDefault().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ mDPM.removeActiveAdmin(mDeviceAdmin.getComponent());
+ finish();
+ } else {
+ try {
+ // Continue preventing anything from coming in front.
+ ActivityManagerNative.getDefault().stopAppSwitches();
+ } catch (RemoteException e) {
+ }
+ Bundle args = new Bundle();
+ args.putCharSequence(
+ DeviceAdminReceiver.EXTRA_DISABLE_WARNING, msg);
+ showDialog(DIALOG_WARNING, args);
+ }
+ }
+
@Override
protected void onResume() {
super.onResume();
updateInterface();
+ // As long as we are running, don't let this admin overlay stuff on top of the screen.
+ final int uid = mDeviceAdmin.getActivityInfo().applicationInfo.uid;
+ final String pkg = mDeviceAdmin.getActivityInfo().applicationInfo.packageName;
+ mCurSysAppOpMode = mAppOps.checkOp(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg);
+ mCurToastAppOpMode = mAppOps.checkOp(AppOpsManager.OP_TOAST_WINDOW, uid, pkg);
+ mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg, AppOpsManager.MODE_IGNORED);
+ mAppOps.setMode(AppOpsManager.OP_TOAST_WINDOW, uid, pkg, AppOpsManager.MODE_IGNORED);
}
-
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ // As long as we are running, don't let this admin overlay stuff on top of the screen.
+ final int uid = mDeviceAdmin.getActivityInfo().applicationInfo.uid;
+ final String pkg = mDeviceAdmin.getActivityInfo().applicationInfo.packageName;
+ mAppOps.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg, mCurSysAppOpMode);
+ mAppOps.setMode(AppOpsManager.OP_TOAST_WINDOW, uid, pkg, mCurToastAppOpMode);
+ try {
+ ActivityManagerNative.getDefault().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ }
+
@Override
protected Dialog onCreateDialog(int id, Bundle args) {
switch (id) {
@@ -282,6 +390,10 @@ public class DeviceAdminAdd extends Activity {
builder.setPositiveButton(R.string.dlg_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
+ try {
+ ActivityManagerNative.getDefault().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
mDPM.removeActiveAdmin(mDeviceAdmin.getComponent());
finish();
}
@@ -291,17 +403,17 @@ public class DeviceAdminAdd extends Activity {
}
default:
return super.onCreateDialog(id, args);
-
+
}
}
-
+
static void setViewVisibility(ArrayList<View> views, int visibility) {
final int N = views.size();
for (int i=0; i<N; i++) {
views.get(i).setVisibility(visibility);
}
}
-
+
void updateInterface() {
mAdminIcon.setImageDrawable(mDeviceAdmin.loadIcon(getPackageManager()));
mAdminName.setText(mDeviceAdmin.loadLabel(getPackageManager()));
@@ -312,6 +424,9 @@ public class DeviceAdminAdd extends Activity {
} catch (Resources.NotFoundException e) {
mAdminDescription.setVisibility(View.GONE);
}
+ if (mAddingProfileOwner) {
+ mProfileOwnerWarning.setVisibility(View.VISIBLE);
+ }
if (mAddMsgText != null) {
mAddMsg.setText(mAddMsgText);
mAddMsg.setVisibility(View.VISIBLE);
@@ -319,7 +434,8 @@ public class DeviceAdminAdd extends Activity {
mAddMsg.setVisibility(View.GONE);
mAddMsgExpander.setVisibility(View.GONE);
}
- if (!mRefreshing && mDPM.isAdminActive(mDeviceAdmin.getComponent())) {
+ if (!mRefreshing && !mAddingProfileOwner
+ && mDPM.isAdminActive(mDeviceAdmin.getComponent())) {
if (mActivePolicies.size() == 0) {
ArrayList<DeviceAdminInfo.PolicyInfo> policies = mDeviceAdmin.getUsedPolicies();
for (int i=0; i<policies.size(); i++) {
@@ -352,7 +468,11 @@ public class DeviceAdminAdd extends Activity {
setViewVisibility(mActivePolicies, View.GONE);
mAdminWarning.setText(getString(R.string.device_admin_warning,
mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager())));
- setTitle(getText(R.string.add_device_admin_msg));
+ if (mAddingProfileOwner) {
+ setTitle(getText(R.string.profile_owner_add_title));
+ } else {
+ setTitle(getText(R.string.add_device_admin_msg));
+ }
mActionButton.setText(getText(R.string.add_device_admin));
mAdding = true;
}