M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

@@ -0,0 +1,409 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.admin;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Printer;
import android.util.SparseArray;
import android.util.Xml;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
/**
* This class is used to specify meta information of a device administrator
* component.
*/
public final class DeviceAdminInfo implements Parcelable {
static final String TAG = "DeviceAdminInfo";
/**
* A type of policy that this device admin can use: limit the passwords
* that the user can select, via {@link DevicePolicyManager#setPasswordQuality}
* and {@link DevicePolicyManager#setPasswordMinimumLength}.
*
* <p>To control this policy, the device admin must have a "limit-password"
* tag in the "uses-policies" section of its meta-data.
*/
public static final int USES_POLICY_LIMIT_PASSWORD = 0;
/**
* A type of policy that this device admin can use: able to watch login
* attempts from the user, via {@link DeviceAdminReceiver#ACTION_PASSWORD_FAILED},
* {@link DeviceAdminReceiver#ACTION_PASSWORD_SUCCEEDED}, and
* {@link DevicePolicyManager#getCurrentFailedPasswordAttempts}.
*
* <p>To control this policy, the device admin must have a "watch-login"
* tag in the "uses-policies" section of its meta-data.
*/
public static final int USES_POLICY_WATCH_LOGIN = 1;
/**
* A type of policy that this device admin can use: able to reset the
* user's password via
* {@link DevicePolicyManager#resetPassword}.
*
* <p>To control this policy, the device admin must have a "reset-password"
* tag in the "uses-policies" section of its meta-data.
*/
public static final int USES_POLICY_RESET_PASSWORD = 2;
/**
* A type of policy that this device admin can use: able to force the device
* to lock via{@link DevicePolicyManager#lockNow} or limit the
* maximum lock timeout for the device via
* {@link DevicePolicyManager#setMaximumTimeToLock}.
*
* <p>To control this policy, the device admin must have a "force-lock"
* tag in the "uses-policies" section of its meta-data.
*/
public static final int USES_POLICY_FORCE_LOCK = 3;
/**
* A type of policy that this device admin can use: able to factory
* reset the device, erasing all of the user's data, via
* {@link DevicePolicyManager#wipeData}.
*
* <p>To control this policy, the device admin must have a "wipe-data"
* tag in the "uses-policies" section of its meta-data.
*/
public static final int USES_POLICY_WIPE_DATA = 4;
/** @hide */
public static class PolicyInfo {
public final int ident;
final public String tag;
final public int label;
final public int description;
public PolicyInfo(int identIn, String tagIn, int labelIn, int descriptionIn) {
ident = identIn;
tag = tagIn;
label = labelIn;
description = descriptionIn;
}
}
static ArrayList<PolicyInfo> sPoliciesDisplayOrder = new ArrayList<PolicyInfo>();
static HashMap<String, Integer> sKnownPolicies = new HashMap<String, Integer>();
static SparseArray<PolicyInfo> sRevKnownPolicies = new SparseArray<PolicyInfo>();
static {
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WIPE_DATA, "wipe-data",
com.android.internal.R.string.policylab_wipeData,
com.android.internal.R.string.policydesc_wipeData));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_RESET_PASSWORD, "reset-password",
com.android.internal.R.string.policylab_resetPassword,
com.android.internal.R.string.policydesc_resetPassword));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_PASSWORD, "limit-password",
com.android.internal.R.string.policylab_limitPassword,
com.android.internal.R.string.policydesc_limitPassword));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WATCH_LOGIN, "watch-login",
com.android.internal.R.string.policylab_watchLogin,
com.android.internal.R.string.policydesc_watchLogin));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock",
com.android.internal.R.string.policylab_forceLock,
com.android.internal.R.string.policydesc_forceLock));
for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
PolicyInfo pi = sPoliciesDisplayOrder.get(i);
sRevKnownPolicies.put(pi.ident, pi);
sKnownPolicies.put(pi.tag, pi.ident);
}
}
/**
* The BroadcastReceiver that implements this device admin component.
*/
final ResolveInfo mReceiver;
/**
* Whether this should be visible to the user.
*/
boolean mVisible;
/**
* The policies this administrator needs access to.
*/
int mUsesPolicies;
/**
* Constructor.
*
* @param context The Context in which we are parsing the device admin.
* @param receiver The ResolveInfo returned from the package manager about
* this device admin's component.
*/
public DeviceAdminInfo(Context context, ResolveInfo receiver)
throws XmlPullParserException, IOException {
mReceiver = receiver;
ActivityInfo ai = receiver.activityInfo;
PackageManager pm = context.getPackageManager();
XmlResourceParser parser = null;
try {
parser = ai.loadXmlMetaData(pm, DeviceAdminReceiver.DEVICE_ADMIN_META_DATA);
if (parser == null) {
throw new XmlPullParserException("No "
+ DeviceAdminReceiver.DEVICE_ADMIN_META_DATA + " meta-data");
}
Resources res = pm.getResourcesForApplication(ai.applicationInfo);
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
String nodeName = parser.getName();
if (!"device-admin".equals(nodeName)) {
throw new XmlPullParserException(
"Meta-data does not start with device-admin tag");
}
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.DeviceAdmin);
mVisible = sa.getBoolean(
com.android.internal.R.styleable.DeviceAdmin_visible, true);
sa.recycle();
int outerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("uses-policies")) {
int innerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
String policyName = parser.getName();
Integer val = sKnownPolicies.get(policyName);
if (val != null) {
mUsesPolicies |= 1 << val.intValue();
} else {
Log.w(TAG, "Unknown tag under uses-policies of "
+ getComponent() + ": " + policyName);
}
}
}
}
} catch (NameNotFoundException e) {
throw new XmlPullParserException(
"Unable to create context for: " + ai.packageName);
} finally {
if (parser != null) parser.close();
}
}
DeviceAdminInfo(Parcel source) {
mReceiver = ResolveInfo.CREATOR.createFromParcel(source);
mUsesPolicies = source.readInt();
}
/**
* Return the .apk package that implements this device admin.
*/
public String getPackageName() {
return mReceiver.activityInfo.packageName;
}
/**
* Return the class name of the receiver component that implements
* this device admin.
*/
public String getReceiverName() {
return mReceiver.activityInfo.name;
}
/**
* Return the raw information about the receiver implementing this
* device admin. Do not modify the returned object.
*/
public ActivityInfo getActivityInfo() {
return mReceiver.activityInfo;
}
/**
* Return the component of the receiver that implements this device admin.
*/
public ComponentName getComponent() {
return new ComponentName(mReceiver.activityInfo.packageName,
mReceiver.activityInfo.name);
}
/**
* Load the user-displayed label for this device admin.
*
* @param pm Supply a PackageManager used to load the device admin's
* resources.
*/
public CharSequence loadLabel(PackageManager pm) {
return mReceiver.loadLabel(pm);
}
/**
* Load user-visible description associated with this device admin.
*
* @param pm Supply a PackageManager used to load the device admin's
* resources.
*/
public CharSequence loadDescription(PackageManager pm) throws NotFoundException {
if (mReceiver.activityInfo.descriptionRes != 0) {
String packageName = mReceiver.resolvePackageName;
ApplicationInfo applicationInfo = null;
if (packageName == null) {
packageName = mReceiver.activityInfo.packageName;
applicationInfo = mReceiver.activityInfo.applicationInfo;
}
return pm.getText(packageName,
mReceiver.activityInfo.descriptionRes, applicationInfo);
}
throw new NotFoundException();
}
/**
* Load the user-displayed icon for this device admin.
*
* @param pm Supply a PackageManager used to load the device admin's
* resources.
*/
public Drawable loadIcon(PackageManager pm) {
return mReceiver.loadIcon(pm);
}
/**
* Returns whether this device admin would like to be visible to the
* user, even when it is not enabled.
*/
public boolean isVisible() {
return mVisible;
}
/**
* Return true if the device admin has requested that it be able to use
* the given policy control. The possible policy identifier inputs are:
* {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN},
* {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
* {@link #USES_POLICY_WIPE_DATA}.
*/
public boolean usesPolicy(int policyIdent) {
return (mUsesPolicies & (1<<policyIdent)) != 0;
}
/**
* Return the XML tag name for the given policy identifier. Valid identifiers
* are as per {@link #usesPolicy(int)}. If the given identifier is not
* known, null is returned.
*/
public String getTagForPolicy(int policyIdent) {
return sRevKnownPolicies.get(policyIdent).tag;
}
/** @hide */
public ArrayList<PolicyInfo> getUsedPolicies() {
ArrayList<PolicyInfo> res = new ArrayList<PolicyInfo>();
for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
PolicyInfo pi = sPoliciesDisplayOrder.get(i);
if (usesPolicy(pi.ident)) {
res.add(pi);
}
}
return res;
}
/** @hide */
public void writePoliciesToXml(XmlSerializer out)
throws IllegalArgumentException, IllegalStateException, IOException {
out.attribute(null, "flags", Integer.toString(mUsesPolicies));
}
/** @hide */
public void readPoliciesFromXml(XmlPullParser parser)
throws XmlPullParserException, IOException {
mUsesPolicies = Integer.parseInt(
parser.getAttributeValue(null, "flags"));
}
public void dump(Printer pw, String prefix) {
pw.println(prefix + "Receiver:");
mReceiver.dump(pw, prefix + " ");
}
@Override
public String toString() {
return "DeviceAdminInfo{" + mReceiver.activityInfo.name + "}";
}
/**
* Used to package this object into a {@link Parcel}.
*
* @param dest The {@link Parcel} to be written.
* @param flags The flags used for parceling.
*/
public void writeToParcel(Parcel dest, int flags) {
mReceiver.writeToParcel(dest, flags);
dest.writeInt(mUsesPolicies);
}
/**
* Used to make this class parcelable.
*/
public static final Parcelable.Creator<DeviceAdminInfo> CREATOR =
new Parcelable.Creator<DeviceAdminInfo>() {
public DeviceAdminInfo createFromParcel(Parcel source) {
return new DeviceAdminInfo(source);
}
public DeviceAdminInfo[] newArray(int size) {
return new DeviceAdminInfo[size];
}
};
public int describeContents() {
return 0;
}
}

View File

@@ -0,0 +1,281 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.admin;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
/**
* Base class for implementing a device administration component. This
* class provides a convenience for interpreting the raw intent actions
* that are sent by the system.
*
* <p>The callback methods, like the base
* {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()}
* method, happen on the main thread of the process. Thus long running
* operations must be done on another thread. Note that because a receiver
* is done once returning from its receive function, such long-running operations
* should probably be done in a {@link Service}.
*
* <p>When publishing your DeviceAdmin subclass as a receiver, it must
* handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the
* {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission. A typical
* manifest entry would look like:</p>
*
* {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
*
* <p>The meta-data referenced here provides addition information specific
* to the device administrator, as parsed by the {@link DeviceAdminInfo} class.
* A typical file would be:</p>
*
* {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data}
*/
public class DeviceAdminReceiver extends BroadcastReceiver {
private static String TAG = "DevicePolicy";
private static boolean DEBUG = false;
private static boolean localLOGV = DEBUG || android.util.Config.LOGV;
/**
* This is the primary action that a device administrator must implement to be
* allowed to manage a device. This will be set to the receiver
* when the user enables it for administration. You will generally
* handle this in {@link DeviceAdminReceiver#onEnabled(Context, Intent)}. To be
* supported, the receiver must also require the
* {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so
* that other applications can not abuse it.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_DEVICE_ADMIN_ENABLED
= "android.app.action.DEVICE_ADMIN_ENABLED";
/**
* Action sent to a device administrator when the user has requested to
* disable it, but before this has actually been done. This gives you
* a chance to supply a message to the user about the impact of
* disabling your admin, by setting the extra field
* {@link #EXTRA_DISABLE_WARNING} in the result Intent. If not set,
* no warning will be displayed. If set, the given text will be shown
* to the user before they disable your admin.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
= "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
/**
* A CharSequence that can be shown to the user informing them of the
* impact of disabling your admin.
*
* @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
*/
public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
/**
* Action sent to a device administrator when the user has disabled
* it. Upon return, the application no longer has access to the
* protected device policy manager APIs. You will generally
* handle this in {@link DeviceAdminReceiver#onDisabled(Context, Intent)}. Note
* that this action will be
* sent the receiver regardless of whether it is explicitly listed in
* its intent filter.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_DEVICE_ADMIN_DISABLED
= "android.app.action.DEVICE_ADMIN_DISABLED";
/**
* Action sent to a device administrator when the user has changed the
* password of their device. You can at this point check the characteristics
* of the new password with {@link DevicePolicyManager#isActivePasswordSufficient()
* DevicePolicyManager.isActivePasswordSufficient()}.
* You will generally
* handle this in {@link DeviceAdminReceiver#onPasswordChanged}.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive
* this broadcast.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PASSWORD_CHANGED
= "android.app.action.ACTION_PASSWORD_CHANGED";
/**
* Action sent to a device administrator when the user has failed at
* attempted to enter the password. You can at this point check the
* number of failed password attempts there have been with
* {@link DevicePolicyManager#getCurrentFailedPasswordAttempts
* DevicePolicyManager.getCurrentFailedPasswordAttempts()}. You will generally
* handle this in {@link DeviceAdminReceiver#onPasswordFailed}.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
* this broadcast.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PASSWORD_FAILED
= "android.app.action.ACTION_PASSWORD_FAILED";
/**
* Action sent to a device administrator when the user has successfully
* entered their password, after failing one or more times.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
* this broadcast.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PASSWORD_SUCCEEDED
= "android.app.action.ACTION_PASSWORD_SUCCEEDED";
/**
* Name under which an DevicePolicy component publishes information
* about itself. This meta-data must reference an XML resource containing
* a device-admin tag. XXX TO DO: describe syntax.
*/
public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
private DevicePolicyManager mManager;
private ComponentName mWho;
/**
* Retrieve the DevicePolicyManager interface for this administrator to work
* with the system.
*/
public DevicePolicyManager getManager(Context context) {
if (mManager != null) {
return mManager;
}
mManager = (DevicePolicyManager)context.getSystemService(
Context.DEVICE_POLICY_SERVICE);
return mManager;
}
/**
* Retrieve the ComponentName describing who this device administrator is, for
* use in {@link DevicePolicyManager} APIs that require the administrator to
* identify itself.
*/
public ComponentName getWho(Context context) {
if (mWho != null) {
return mWho;
}
mWho = new ComponentName(context, getClass());
return mWho;
}
/**
* Called after the administrator is first enabled, as a result of
* receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}. At this point you
* can use {@link DevicePolicyManager} to set your desired policies.
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
*/
public void onEnabled(Context context, Intent intent) {
}
/**
* Called when the user has asked to disable the administrator, as a result of
* receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
* a chance to present a warning message to them. The message is returned
* as the result; if null is returned (the default implementation), no
* message will be displayed.
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
* @return Return the warning message to display to the user before
* being disabled; if null is returned, no message is displayed.
*/
public CharSequence onDisableRequested(Context context, Intent intent) {
return null;
}
/**
* Called prior to the administrator being disabled, as a result of
* receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}. Upon return, you
* can no longer use the protected parts of the {@link DevicePolicyManager}
* API.
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
*/
public void onDisabled(Context context, Intent intent) {
}
/**
* Called after the user has changed their password, as a result of
* receiving {@link #ACTION_PASSWORD_CHANGED}. At this point you
* can use {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()
* DevicePolicyManager.getCurrentFailedPasswordAttempts()}
* to retrieve the active password characteristics.
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
*/
public void onPasswordChanged(Context context, Intent intent) {
}
/**
* Called after the user has failed at entering their current password, as a result of
* receiving {@link #ACTION_PASSWORD_FAILED}. At this point you
* can use {@link DevicePolicyManager} to retrieve the number of failed
* password attempts.
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
*/
public void onPasswordFailed(Context context, Intent intent) {
}
/**
* Called after the user has succeeded at entering their current password,
* as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}. This will
* only be received the first time they succeed after having previously
* failed.
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
*/
public void onPasswordSucceeded(Context context, Intent intent) {
}
/**
* Intercept standard device administrator broadcasts. Implementations
* should not override this method; it is better to implement the
* convenience callbacks for each action.
*/
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_PASSWORD_CHANGED.equals(action)) {
onPasswordChanged(context, intent);
} else if (ACTION_PASSWORD_FAILED.equals(action)) {
onPasswordFailed(context, intent);
} else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
onPasswordSucceeded(context, intent);
} else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
onEnabled(context, intent);
} else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
CharSequence res = onDisableRequested(context, intent);
if (res != null) {
Bundle extras = getResultExtras(true);
extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
}
} else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
onDisabled(context, intent);
}
}
}

View File

@@ -0,0 +1,631 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.admin;
import org.xmlpull.v1.XmlPullParserException;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Handler;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import java.io.IOException;
import java.util.List;
/**
* Public interface for managing policies enforced on a device. Most clients
* of this class must have published a {@link DeviceAdminReceiver} that the user
* has currently enabled.
*/
public class DevicePolicyManager {
private static String TAG = "DevicePolicyManager";
private static boolean DEBUG = false;
private static boolean localLOGV = DEBUG || android.util.Config.LOGV;
private final Context mContext;
private final IDevicePolicyManager mService;
private final Handler mHandler;
private DevicePolicyManager(Context context, Handler handler) {
mContext = context;
mHandler = handler;
mService = IDevicePolicyManager.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
}
/** @hide */
public static DevicePolicyManager create(Context context, Handler handler) {
DevicePolicyManager me = new DevicePolicyManager(context, handler);
return me.mService != null ? me : null;
}
/**
* Activity action: ask the user to add a new device administrator to the system.
* The desired policy is the ComponentName of the policy in the
* {@link #EXTRA_DEVICE_ADMIN} extra field. This will invoke a UI to
* bring the user through adding the device administrator to the system (or
* allowing them to reject it).
*
* <p>You can optionally include the {@link #EXTRA_ADD_EXPLANATION}
* field to provide the user with additional explanation (in addition
* to your component's description) about what is being added.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_ADD_DEVICE_ADMIN
= "android.app.action.ADD_DEVICE_ADMIN";
/**
* Activity action: send when any policy admin changes a policy.
* This is generally used to find out when a new policy is in effect.
*
* @hide
*/
public static final String ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
= "android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED";
/**
* The ComponentName of the administrator component.
*
* @see #ACTION_ADD_DEVICE_ADMIN
*/
public static final String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
/**
* An optional CharSequence providing additional explanation for why the
* admin is being added.
*
* @see #ACTION_ADD_DEVICE_ADMIN
*/
public static final String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
/**
* Activity action: have the user enter a new password. This activity
* should be launched after using {@link #setPasswordQuality(ComponentName, int)}
* or {@link #setPasswordMinimumLength(ComponentName, int)} to have the
* user enter a new password that meets the current requirements. You can
* use {@link #isActivePasswordSufficient()} to determine whether you need
* to have the user select a new password in order to meet the current
* constraints. Upon being resumed from this activity,
* you can check the new password characteristics to see if they are
* sufficient.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_SET_NEW_PASSWORD
= "android.app.action.SET_NEW_PASSWORD";
/**
* Return true if the given administrator component is currently
* active (enabled) in the system.
*/
public boolean isAdminActive(ComponentName who) {
if (mService != null) {
try {
return mService.isAdminActive(who);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return false;
}
/**
* Return a list of all currently active device administrator's component
* names. Note that if there are no administrators than null may be
* returned.
*/
public List<ComponentName> getActiveAdmins() {
if (mService != null) {
try {
return mService.getActiveAdmins();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return null;
}
/**
* @hide
*/
public boolean packageHasActiveAdmins(String packageName) {
if (mService != null) {
try {
return mService.packageHasActiveAdmins(packageName);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return false;
}
/**
* Remove a current administration component. This can only be called
* by the application that owns the administration component; if you
* try to remove someone else's component, a security exception will be
* thrown.
*/
public void removeActiveAdmin(ComponentName who) {
if (mService != null) {
try {
mService.removeActiveAdmin(who);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* Constant for {@link #setPasswordQuality}: the policy has no requirements
* for the password. Note that quality constants are ordered so that higher
* values are more restrictive.
*/
public static final int PASSWORD_QUALITY_UNSPECIFIED = 0;
/**
* Constant for {@link #setPasswordQuality}: the policy requires some kind
* of password, but doesn't care what it is. Note that quality constants
* are ordered so that higher values are more restrictive.
*/
public static final int PASSWORD_QUALITY_SOMETHING = 0x10000;
/**
* Constant for {@link #setPasswordQuality}: the user must have entered a
* password containing at least numeric characters. Note that quality
* constants are ordered so that higher values are more restrictive.
*/
public static final int PASSWORD_QUALITY_NUMERIC = 0x20000;
/**
* Constant for {@link #setPasswordQuality}: the user must have entered a
* password containing at least alphabetic (or other symbol) characters.
* Note that quality constants are ordered so that higher values are more
* restrictive.
*/
public static final int PASSWORD_QUALITY_ALPHABETIC = 0x40000;
/**
* Constant for {@link #setPasswordQuality}: the user must have entered a
* password containing at least <em>both></em> numeric <em>and</em>
* alphabetic (or other symbol) characters. Note that quality constants are
* ordered so that higher values are more restrictive.
*/
public static final int PASSWORD_QUALITY_ALPHANUMERIC = 0x50000;
/**
* Called by an application that is administering the device to set the
* password restrictions it is imposing. After setting this, the user
* will not be able to enter a new password that is not at least as
* restrictive as what has been set. Note that the current password
* will remain until the user has set a new one, so the change does not
* take place immediately. To prompt the user for a new password, use
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value.
*
* <p>Quality constants are ordered so that higher values are more restrictive;
* thus the highest requested quality constant (between the policy set here,
* the user's preference, and any other considerations) is the one that
* is in effect.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
* this method; if it has not, a security exception will be thrown.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param quality The new desired quality. One of
* {@link #PASSWORD_QUALITY_UNSPECIFIED}, {@link #PASSWORD_QUALITY_SOMETHING},
* {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_ALPHABETIC},
* or {@link #PASSWORD_QUALITY_ALPHANUMERIC}.
*/
public void setPasswordQuality(ComponentName admin, int quality) {
if (mService != null) {
try {
mService.setPasswordQuality(admin, quality);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* Retrieve the current minimum password quality for all admins
* or a particular one.
* @param admin The name of the admin component to check, or null to aggregate
* all admins.
*/
public int getPasswordQuality(ComponentName admin) {
if (mService != null) {
try {
return mService.getPasswordQuality(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return PASSWORD_QUALITY_UNSPECIFIED;
}
/**
* Called by an application that is administering the device to set the
* minimum allowed password length. After setting this, the user
* will not be able to enter a new password that is not at least as
* restrictive as what has been set. Note that the current password
* will remain until the user has set a new one, so the change does not
* take place immediately. To prompt the user for a new password, use
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value. This
* constraint is only imposed if the administrator has also requested either
* {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_ALPHABETIC},
* or {@link #PASSWORD_QUALITY_ALPHANUMERIC}
* with {@link #setPasswordQuality}.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
* this method; if it has not, a security exception will be thrown.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param length The new desired minimum password length. A value of 0
* means there is no restriction.
*/
public void setPasswordMinimumLength(ComponentName admin, int length) {
if (mService != null) {
try {
mService.setPasswordMinimumLength(admin, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* Retrieve the current minimum password length for all admins
* or a particular one.
* @param admin The name of the admin component to check, or null to aggregate
* all admins.
*/
public int getPasswordMinimumLength(ComponentName admin) {
if (mService != null) {
try {
return mService.getPasswordMinimumLength(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return 0;
}
/**
* Return the maximum password length that the device supports for a
* particular password quality.
* @param quality The quality being interrogated.
* @return Returns the maximum length that the user can enter.
*/
public int getPasswordMaximumLength(int quality) {
// Kind-of arbitrary.
return 16;
}
/**
* Determine whether the current password the user has set is sufficient
* to meet the policy requirements (quality, minimum length) that have been
* requested.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
* this method; if it has not, a security exception will be thrown.
*
* @return Returns true if the password meets the current requirements,
* else false.
*/
public boolean isActivePasswordSufficient() {
if (mService != null) {
try {
return mService.isActivePasswordSufficient();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return false;
}
/**
* Retrieve the number of times the user has failed at entering a
* password since that last successful password entry.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to be able to call
* this method; if it has not, a security exception will be thrown.
*/
public int getCurrentFailedPasswordAttempts() {
if (mService != null) {
try {
return mService.getCurrentFailedPasswordAttempts();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return -1;
}
/**
* Setting this to a value greater than zero enables a built-in policy
* that will perform a device wipe after too many incorrect
* device-unlock passwords have been entered. This built-in policy combines
* watching for failed passwords and wiping the device, and requires
* that you request both {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} and
* {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}}.
*
* <p>To implement any other policy (e.g. wiping data for a particular
* application only, erasing or revoking credentials, or reporting the
* failure to a server), you should implement
* {@link DeviceAdminReceiver#onPasswordFailed(Context, android.content.Intent)}
* instead. Do not use this API, because if the maximum count is reached,
* the device will be wiped immediately, and your callback will not be invoked.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param num The number of failed password attempts at which point the
* device will wipe its data.
*/
public void setMaximumFailedPasswordsForWipe(ComponentName admin, int num) {
if (mService != null) {
try {
mService.setMaximumFailedPasswordsForWipe(admin, num);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* Retrieve the current maximum number of login attempts that are allowed
* before the device wipes itself, for all admins
* or a particular one.
* @param admin The name of the admin component to check, or null to aggregate
* all admins.
*/
public int getMaximumFailedPasswordsForWipe(ComponentName admin) {
if (mService != null) {
try {
return mService.getMaximumFailedPasswordsForWipe(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return 0;
}
/**
* Flag for {@link #resetPassword}: don't allow other admins to change
* the password again until the user has entered it.
*/
public static final int RESET_PASSWORD_REQUIRE_ENTRY = 0x0001;
/**
* Force a new device unlock password (the password needed to access the
* entire device, not for individual accounts) on the user. This takes
* effect immediately.
* The given password must be sufficient for the
* current password quality and length constraints as returned by
* {@link #getPasswordQuality(ComponentName)} and
* {@link #getPasswordMinimumLength(ComponentName)}; if it does not meet
* these constraints, then it will be rejected and false returned. Note
* that the password may be a stronger quality (containing alphanumeric
* characters when the requested quality is only numeric), in which case
* the currently active quality will be increased to match.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call
* this method; if it has not, a security exception will be thrown.
*
* @param password The new password for the user.
* @param flags May be 0 or {@link #RESET_PASSWORD_REQUIRE_ENTRY}.
* @return Returns true if the password was applied, or false if it is
* not acceptable for the current constraints.
*/
public boolean resetPassword(String password, int flags) {
if (mService != null) {
try {
return mService.resetPassword(password, flags);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return false;
}
/**
* Called by an application that is administering the device to set the
* maximum time for user activity until the device will lock. This limits
* the length that the user can set. It takes effect immediately.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} to be able to call
* this method; if it has not, a security exception will be thrown.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param timeMs The new desired maximum time to lock in milliseconds.
* A value of 0 means there is no restriction.
*/
public void setMaximumTimeToLock(ComponentName admin, long timeMs) {
if (mService != null) {
try {
mService.setMaximumTimeToLock(admin, timeMs);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* Retrieve the current maximum time to unlock for all admins
* or a particular one.
* @param admin The name of the admin component to check, or null to aggregate
* all admins.
*/
public long getMaximumTimeToLock(ComponentName admin) {
if (mService != null) {
try {
return mService.getMaximumTimeToLock(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return 0;
}
/**
* Make the device lock immediately, as if the lock screen timeout has
* expired at the point of this call.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} to be able to call
* this method; if it has not, a security exception will be thrown.
*/
public void lockNow() {
if (mService != null) {
try {
mService.lockNow();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* Flag for {@link #wipeData(int)}: also erase the device's external
* storage.
*/
public static final int WIPE_EXTERNAL_STORAGE = 0x0001;
/**
* Ask the user date be wiped. This will cause the device to reboot,
* erasing all user data while next booting up. External storage such
* as SD cards will not be erased.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} to be able to call
* this method; if it has not, a security exception will be thrown.
*
* @param flags Bit mask of additional options: currently must be 0.
*/
public void wipeData(int flags) {
if (mService != null) {
try {
mService.wipeData(flags);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* @hide
*/
public void setActiveAdmin(ComponentName policyReceiver) {
if (mService != null) {
try {
mService.setActiveAdmin(policyReceiver);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* @hide
*/
public DeviceAdminInfo getAdminInfo(ComponentName cn) {
ActivityInfo ai;
try {
ai = mContext.getPackageManager().getReceiverInfo(cn,
PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Unable to retrieve device policy " + cn, e);
return null;
}
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
try {
return new DeviceAdminInfo(mContext, ri);
} catch (XmlPullParserException e) {
Log.w(TAG, "Unable to parse device policy " + cn, e);
return null;
} catch (IOException e) {
Log.w(TAG, "Unable to parse device policy " + cn, e);
return null;
}
}
/**
* @hide
*/
public void getRemoveWarning(ComponentName admin, RemoteCallback result) {
if (mService != null) {
try {
mService.getRemoveWarning(admin, result);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* @hide
*/
public void setActivePasswordState(int quality, int length) {
if (mService != null) {
try {
mService.setActivePasswordState(quality, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* @hide
*/
public void reportFailedPasswordAttempt() {
if (mService != null) {
try {
mService.reportFailedPasswordAttempt();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* @hide
*/
public void reportSuccessfulPasswordAttempt() {
if (mService != null) {
try {
mService.reportSuccessfulPasswordAttempt();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
}

View File

@@ -0,0 +1,59 @@
/*
**
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package android.app.admin;
import android.content.ComponentName;
import android.os.RemoteCallback;
/**
* Internal IPC interface to the device policy service.
* {@hide}
*/
interface IDevicePolicyManager {
void setPasswordQuality(in ComponentName who, int quality);
int getPasswordQuality(in ComponentName who);
void setPasswordMinimumLength(in ComponentName who, int length);
int getPasswordMinimumLength(in ComponentName who);
boolean isActivePasswordSufficient();
int getCurrentFailedPasswordAttempts();
void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num);
int getMaximumFailedPasswordsForWipe(in ComponentName admin);
boolean resetPassword(String password, int flags);
void setMaximumTimeToLock(in ComponentName who, long timeMs);
long getMaximumTimeToLock(in ComponentName who);
void lockNow();
void wipeData(int flags);
void setActiveAdmin(in ComponentName policyReceiver);
boolean isAdminActive(in ComponentName policyReceiver);
List<ComponentName> getActiveAdmins();
boolean packageHasActiveAdmins(String packageName);
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result);
void removeActiveAdmin(in ComponentName policyReceiver);
void setActivePasswordState(int quality, int length);
void reportFailedPasswordAttempt();
void reportSuccessfulPasswordAttempt();
}