Merge "Device Owner, a special kind of device admin" into jb-mr2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
df5e9fe181
@@ -4337,6 +4337,7 @@ package android.app.admin {
|
||||
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
|
||||
method public boolean isActivePasswordSufficient();
|
||||
method public boolean isAdminActive(android.content.ComponentName);
|
||||
method public boolean isDeviceOwner(java.lang.String);
|
||||
method public void lockNow();
|
||||
method public void removeActiveAdmin(android.content.ComponentName);
|
||||
method public boolean resetPassword(java.lang.String, int);
|
||||
@@ -16788,9 +16789,20 @@ package android.os {
|
||||
method public int getUserCount();
|
||||
method public android.os.UserHandle getUserForSerialNumber(long);
|
||||
method public java.lang.String getUserName();
|
||||
method public android.os.Bundle getUserRestrictions();
|
||||
method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
|
||||
method public boolean isUserAGoat();
|
||||
method public boolean isUserRestricted();
|
||||
method public boolean isUserRunning(android.os.UserHandle);
|
||||
method public boolean isUserRunningOrStopping(android.os.UserHandle);
|
||||
method public void setUserRestriction(java.lang.String, boolean);
|
||||
method public void setUserRestrictions(android.os.Bundle);
|
||||
method public void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
|
||||
field public static final java.lang.String DISALLOW_CONFIG_WIFI = "no_config_wifi";
|
||||
field public static final java.lang.String DISALLOW_INSTALL_APPS = "no_install_apps";
|
||||
field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
|
||||
field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
|
||||
field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
|
||||
}
|
||||
|
||||
public abstract class Vibrator {
|
||||
|
||||
@@ -1513,4 +1513,57 @@ public class DevicePolicyManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Sets the given package as the device owner. The package must already be installed and there
|
||||
* shouldn't be an existing device owner registered, for this call to succeed. Also, this
|
||||
* method must be called before the device is provisioned.
|
||||
* @param packageName the package name of the application to be registered as the device owner.
|
||||
* @return whether the package was successfully registered as the device owner.
|
||||
* @throws IllegalArgumentException if the package name is null or invalid
|
||||
* @throws IllegalStateException if a device owner is already registered or the device has
|
||||
* already been provisioned.
|
||||
*/
|
||||
public boolean setDeviceOwner(String packageName) throws IllegalArgumentException,
|
||||
IllegalStateException {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.setDeviceOwner(packageName);
|
||||
} catch (RemoteException re) {
|
||||
Log.w(TAG, "Failed to set device owner");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine if a particular package has been registered as a Device Owner admin.
|
||||
* Device Owner admins cannot be deactivated by the user unless the Device Owner itself allows
|
||||
* it. And Device Owner packages cannot be uninstalled, once registered.
|
||||
* @param packageName the package name to check against the registered device owner.
|
||||
* @return whether or not the package is registered as the Device Owner.
|
||||
*/
|
||||
public boolean isDeviceOwner(String packageName) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.isDeviceOwner(packageName);
|
||||
} catch (RemoteException re) {
|
||||
Log.w(TAG, "Failed to check device owner");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public String getDeviceOwner() {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getDeviceOwner();
|
||||
} catch (RemoteException re) {
|
||||
Log.w(TAG, "Failed to get device owner");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,4 +97,8 @@ interface IDevicePolicyManager {
|
||||
int numbers, int symbols, int nonletter, int userHandle);
|
||||
void reportFailedPasswordAttempt(int userHandle);
|
||||
void reportSuccessfulPasswordAttempt(int userHandle);
|
||||
|
||||
boolean setDeviceOwner(String packageName);
|
||||
boolean isDeviceOwner(String packageName);
|
||||
String getDeviceOwner();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ interface IUserManager {
|
||||
Bitmap getUserIcon(int userHandle);
|
||||
List<UserInfo> getUsers(boolean excludeDying);
|
||||
UserInfo getUserInfo(int userHandle);
|
||||
boolean isRestricted();
|
||||
void setGuestEnabled(boolean enable);
|
||||
boolean isGuestEnabled();
|
||||
void wipeUser(int userHandle);
|
||||
|
||||
@@ -37,48 +37,56 @@ public class UserManager {
|
||||
private final Context mContext;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Key for user restrictions. Specifies if a user is allowed to add or remove accounts.
|
||||
* Key for user restrictions. Specifies if a user is disallowed from adding and removing
|
||||
* accounts.
|
||||
* The default value is <code>false</code>.
|
||||
* <p/>
|
||||
* Type: Boolean
|
||||
* @see #setUserRestrictions(Bundle)
|
||||
* @see #getUserRestrictions()
|
||||
*/
|
||||
public static final String ALLOW_MODIFY_ACCOUNTS = "modify_accounts";
|
||||
public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Key for user restrictions. Specifies if a user is allowed to change Wi-Fi access points.
|
||||
* Key for user restrictions. Specifies if a user is disallowed from changing Wi-Fi
|
||||
* access points.
|
||||
* The default value is <code>false</code>.
|
||||
* <p/>
|
||||
* Type: Boolean
|
||||
* @see #setUserRestrictions(Bundle)
|
||||
* @see #getUserRestrictions()
|
||||
*/
|
||||
public static final String ALLOW_CONFIG_WIFI = "config_wifi";
|
||||
public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Key for user restrictions. Specifies if a user is allowed to install applications.
|
||||
* Key for user restrictions. Specifies if a user is disallowed from installing applications.
|
||||
* The default value is <code>false</code>.
|
||||
* <p/>
|
||||
* Type: Boolean
|
||||
* @see #setUserRestrictions(Bundle)
|
||||
* @see #getUserRestrictions()
|
||||
*/
|
||||
public static final String ALLOW_INSTALL_APPS = "install_apps";
|
||||
public static final String DISALLOW_INSTALL_APPS = "no_install_apps";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Key for user restrictions. Specifies if a user is allowed to uninstall applications.
|
||||
* Key for user restrictions. Specifies if a user is disallowed from uninstalling applications.
|
||||
* The default value is <code>false</code>.
|
||||
* <p/>
|
||||
* Type: Boolean
|
||||
* @see #setUserRestrictions(Bundle)
|
||||
* @see #getUserRestrictions()
|
||||
*/
|
||||
public static final String ALLOW_UNINSTALL_APPS = "uninstall_apps";
|
||||
public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
|
||||
|
||||
/** @hide *
|
||||
* Key for user restrictions. Specifies if a user is allowed to toggle location sharing.
|
||||
/**
|
||||
* Key for user restrictions. Specifies if a user is disallowed from toggling location sharing.
|
||||
* The default value is <code>false</code>.
|
||||
* <p/>
|
||||
* Type: Boolean
|
||||
* @see #setUserRestrictions(Bundle)
|
||||
* @see #getUserRestrictions()
|
||||
*/
|
||||
public static final String ALLOW_CONFIG_LOCATION_ACCESS = "config_location_access";
|
||||
public static final String DISALLOW_SHARE_LOCATION = "no_share_location";
|
||||
|
||||
/** @hide */
|
||||
public UserManager(Context context, IUserManager service) {
|
||||
@@ -129,11 +137,14 @@ public class UserManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Used to check if the user making this call is a restricted user. Restricted users may have
|
||||
* application restrictions imposed on them. All apps should default to the most restrictive
|
||||
* version, unless they have specific restrictions available through a call to
|
||||
* {@link Context#getApplicationRestrictions()}.
|
||||
*/
|
||||
public boolean isUserRestricted() {
|
||||
try {
|
||||
return mService.getUserInfo(getUserHandle()).isRestricted();
|
||||
return mService.isRestricted();
|
||||
} catch (RemoteException re) {
|
||||
Log.w(TAG, "Could not check if user restricted ", re);
|
||||
return false;
|
||||
@@ -189,12 +200,19 @@ public class UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Returns the user-wide restrictions imposed on this user.
|
||||
* @return a Bundle containing all the restrictions.
|
||||
*/
|
||||
public Bundle getUserRestrictions() {
|
||||
return getUserRestrictions(Process.myUserHandle());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Returns the user-wide restrictions imposed on the user specified by <code>userHandle</code>.
|
||||
* @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
|
||||
* @return a Bundle containing all the restrictions.
|
||||
*/
|
||||
public Bundle getUserRestrictions(UserHandle userHandle) {
|
||||
try {
|
||||
return mService.getUserRestrictions(userHandle.getIdentifier());
|
||||
@@ -204,12 +222,21 @@ public class UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Sets all the user-wide restrictions for this user.
|
||||
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission.
|
||||
* @param restrictions the Bundle containing all the restrictions.
|
||||
*/
|
||||
public void setUserRestrictions(Bundle restrictions) {
|
||||
setUserRestrictions(restrictions, Process.myUserHandle());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Sets all the user-wide restrictions for the specified user.
|
||||
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission.
|
||||
* @param restrictions the Bundle containing all the restrictions.
|
||||
* @param userHandle the UserHandle of the user for whom to set the restrictions.
|
||||
*/
|
||||
public void setUserRestrictions(Bundle restrictions, UserHandle userHandle) {
|
||||
try {
|
||||
mService.setUserRestrictions(restrictions, userHandle.getIdentifier());
|
||||
@@ -218,7 +245,27 @@ public class UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Sets the value of a specific restriction.
|
||||
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission.
|
||||
* @param key the key of the restriction
|
||||
* @param value the value for the restriction
|
||||
* @param userHandle the user whose restriction is to be changed.
|
||||
*/
|
||||
public void setUserRestriction(String key, boolean value) {
|
||||
Bundle bundle = getUserRestrictions();
|
||||
bundle.putBoolean(key, value);
|
||||
setUserRestrictions(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Sets the value of a specific restriction on a specific user.
|
||||
* Requires the {@link android.Manifest.permission#MANAGE_USERS} permission.
|
||||
* @param key the key of the restriction
|
||||
* @param value the value for the restriction
|
||||
* @param userHandle the user whose restriction is to be changed.
|
||||
*/
|
||||
public void setUserRestriction(String key, boolean value, UserHandle userHandle) {
|
||||
Bundle bundle = getUserRestrictions(userHandle);
|
||||
bundle.putBoolean(key, value);
|
||||
@@ -467,7 +514,7 @@ public class UserManager {
|
||||
* @hide
|
||||
*/
|
||||
public boolean isLocationSharingToggleAllowed() {
|
||||
return getUserRestrictions().getBoolean(ALLOW_CONFIG_LOCATION_ACCESS);
|
||||
return !getUserRestrictions().getBoolean(DISALLOW_SHARE_LOCATION, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,10 +41,14 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.Signature;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
@@ -62,6 +66,7 @@ import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Printer;
|
||||
import android.util.Slog;
|
||||
@@ -88,10 +93,11 @@ import java.util.Set;
|
||||
* Implementation of the device policy APIs.
|
||||
*/
|
||||
public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
private static final String DEVICE_POLICIES_XML = "device_policies.xml";
|
||||
|
||||
private static final String TAG = "DevicePolicyManagerService";
|
||||
|
||||
private static final String DEVICE_POLICIES_XML = "device_policies.xml";
|
||||
|
||||
private static final int REQUEST_EXPIRE_PASSWORD = 5571;
|
||||
|
||||
private static final long MS_PER_DAY = 86400 * 1000;
|
||||
@@ -109,6 +115,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
IPowerManager mIPowerManager;
|
||||
IWindowManager mIWindowManager;
|
||||
|
||||
private DeviceOwner mDeviceOwner;
|
||||
|
||||
public static class DevicePolicyData {
|
||||
int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
int mActivePasswordLength = 0;
|
||||
@@ -507,6 +515,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addDataScheme("package");
|
||||
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
|
||||
}
|
||||
@@ -545,6 +554,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
void loadDeviceOwner() {
|
||||
synchronized (this) {
|
||||
if (DeviceOwner.isRegistered()) {
|
||||
mDeviceOwner = new DeviceOwner();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration
|
||||
* reminders. Clears alarm if no expirations are configured.
|
||||
@@ -709,7 +726,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
Intent resolveIntent = new Intent();
|
||||
resolveIntent.setComponent(adminName);
|
||||
List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers(
|
||||
resolveIntent, PackageManager.GET_META_DATA, userHandle);
|
||||
resolveIntent,
|
||||
PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
|
||||
userHandle);
|
||||
if (infos == null || infos.size() <= 0) {
|
||||
throw new IllegalArgumentException("Unknown admin: " + adminName);
|
||||
}
|
||||
@@ -994,6 +1013,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
public void systemReady() {
|
||||
synchronized (this) {
|
||||
loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
|
||||
loadDeviceOwner();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1052,6 +1072,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
if (replaceIndex == -1) {
|
||||
policy.mAdminList.add(newAdmin);
|
||||
enableIfNecessary(info.getPackageName(), userHandle);
|
||||
} else {
|
||||
policy.mAdminList.set(replaceIndex, newAdmin);
|
||||
}
|
||||
@@ -1119,6 +1140,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
return;
|
||||
}
|
||||
if (admin.getUid() != Binder.getCallingUid()) {
|
||||
// If trying to remove device owner, refuse when the caller is not the owner.
|
||||
if (mDeviceOwner != null
|
||||
&& adminReceiver.getPackageName().equals(mDeviceOwner.getPackageName())) {
|
||||
return;
|
||||
}
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
|
||||
}
|
||||
@@ -2351,6 +2377,49 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDeviceOwner(String packageName) {
|
||||
if (packageName == null
|
||||
|| !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) {
|
||||
throw new IllegalArgumentException("Invalid package name " + packageName
|
||||
+ " for device owner");
|
||||
}
|
||||
synchronized (this) {
|
||||
if (mDeviceOwner == null && !isDeviceProvisioned()) {
|
||||
mDeviceOwner = new DeviceOwner(packageName);
|
||||
mDeviceOwner.writeOwnerFile();
|
||||
return true;
|
||||
} else {
|
||||
throw new IllegalStateException("Trying to set device owner to " + packageName
|
||||
+ ", owner=" + mDeviceOwner.getPackageName()
|
||||
+ ", device_provisioned=" + isDeviceProvisioned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeviceOwner(String packageName) {
|
||||
synchronized (this) {
|
||||
return mDeviceOwner != null
|
||||
&& mDeviceOwner.getPackageName().equals(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeviceOwner() {
|
||||
synchronized (this) {
|
||||
if (mDeviceOwner != null) {
|
||||
return mDeviceOwner.getPackageName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isDeviceProvisioned() {
|
||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 0) > 0;
|
||||
}
|
||||
|
||||
private void enforceCrossUserPermission(int userHandle) {
|
||||
if (userHandle < 0) {
|
||||
throw new IllegalArgumentException("Invalid userId " + userHandle);
|
||||
@@ -2364,6 +2433,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void enableIfNecessary(String packageName, int userId) {
|
||||
try {
|
||||
IPackageManager ipm = AppGlobals.getPackageManager();
|
||||
ApplicationInfo ai = ipm.getApplicationInfo(packageName,
|
||||
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
|
||||
userId);
|
||||
if (ai.enabledSetting
|
||||
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
|
||||
ipm.setApplicationEnabledSetting(packageName,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
|
||||
PackageManager.DONT_KILL_APP, userId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
|
||||
@@ -2399,4 +2484,92 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class DeviceOwner {
|
||||
private static final String DEVICE_OWNER_XML = "device_owner.xml";
|
||||
private static final String TAG_DEVICE_OWNER = "device-owner";
|
||||
private static final String ATTR_PACKAGE = "package";
|
||||
private String mPackageName;
|
||||
|
||||
DeviceOwner() {
|
||||
readOwnerFile();
|
||||
}
|
||||
|
||||
DeviceOwner(String packageName) {
|
||||
this.mPackageName = packageName;
|
||||
}
|
||||
|
||||
static boolean isRegistered() {
|
||||
return new File(Environment.getSystemSecureDirectory(),
|
||||
DEVICE_OWNER_XML).exists();
|
||||
}
|
||||
|
||||
String getPackageName() {
|
||||
return mPackageName;
|
||||
}
|
||||
|
||||
static boolean isInstalled(String packageName, PackageManager pm) {
|
||||
try {
|
||||
PackageInfo pi;
|
||||
if ((pi = pm.getPackageInfo(packageName, 0)) != null) {
|
||||
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (NameNotFoundException nnfe) {
|
||||
Slog.w(TAG, "Device Owner package " + packageName + " not installed.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void readOwnerFile() {
|
||||
AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
|
||||
DEVICE_OWNER_XML));
|
||||
try {
|
||||
FileInputStream input = file.openRead();
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(input, null);
|
||||
int type;
|
||||
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& type != XmlPullParser.START_TAG) {
|
||||
}
|
||||
String tag = parser.getName();
|
||||
if (!TAG_DEVICE_OWNER.equals(tag)) {
|
||||
throw new XmlPullParserException(
|
||||
"Device Owner file does not start with device-owner tag: found " + tag);
|
||||
}
|
||||
mPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
|
||||
input.close();
|
||||
} catch (XmlPullParserException xppe) {
|
||||
Slog.e(TAG, "Error parsing device-owner file\n" + xppe);
|
||||
} catch (IOException ioe) {
|
||||
Slog.e(TAG, "IO Exception when reading device-owner file\n" + ioe);
|
||||
}
|
||||
}
|
||||
|
||||
void writeOwnerFile() {
|
||||
synchronized (this) {
|
||||
writeOwnerFileLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeOwnerFileLocked() {
|
||||
AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
|
||||
DEVICE_OWNER_XML));
|
||||
try {
|
||||
FileOutputStream output = file.startWrite();
|
||||
XmlSerializer out = new FastXmlSerializer();
|
||||
out.setOutput(output, "utf-8");
|
||||
out.startDocument(null, true);
|
||||
out.startTag(null, TAG_DEVICE_OWNER);
|
||||
out.attribute(null, ATTR_PACKAGE, mPackageName);
|
||||
out.endTag(null, TAG_DEVICE_OWNER);
|
||||
out.endDocument();
|
||||
out.flush();
|
||||
file.finishWrite(output);
|
||||
} catch (IOException ioe) {
|
||||
Slog.e(TAG, "IO Exception when writing device-owner file\n" + ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1425,9 +1425,9 @@ public class AccountManagerService
|
||||
if (accountType == null) throw new IllegalArgumentException("accountType is null");
|
||||
checkManageAccountsPermission();
|
||||
|
||||
// Is user allowed to modify accounts?
|
||||
if (!getUserManager().getUserRestrictions(Binder.getCallingUserHandle())
|
||||
.getBoolean(UserManager.ALLOW_MODIFY_ACCOUNTS)) {
|
||||
// Is user disallowed from modifying accounts?
|
||||
if (getUserManager().getUserRestrictions(Binder.getCallingUserHandle())
|
||||
.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
|
||||
try {
|
||||
response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED,
|
||||
"User is not allowed to add an account!");
|
||||
@@ -2572,7 +2572,7 @@ public class AccountManagerService
|
||||
if (callingUid != android.os.Process.myUid()) {
|
||||
Bundle restrictions = getUserManager().getUserRestrictions(
|
||||
new UserHandle(UserHandle.getUserId(callingUid)));
|
||||
if (!restrictions.getBoolean(UserManager.ALLOW_MODIFY_ACCOUNTS)) {
|
||||
if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5945,7 +5945,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
null);
|
||||
|
||||
final int uid = Binder.getCallingUid();
|
||||
if (!isUserAllowed(UserHandle.getUserId(uid), UserManager.ALLOW_INSTALL_APPS)) {
|
||||
if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
|
||||
try {
|
||||
observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
|
||||
} catch (RemoteException re) {
|
||||
@@ -5993,7 +5993,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
|
||||
"installExistingPackage for user " + userId);
|
||||
}
|
||||
if (!isUserAllowed(userId, UserManager.ALLOW_INSTALL_APPS)) {
|
||||
if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
|
||||
return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
|
||||
}
|
||||
|
||||
@@ -6027,13 +6027,13 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return PackageManager.INSTALL_SUCCEEDED;
|
||||
}
|
||||
|
||||
private boolean isUserAllowed(int userId, String restrictionKey) {
|
||||
private boolean isUserRestricted(int userId, String restrictionKey) {
|
||||
Bundle restrictions = sUserManager.getUserRestrictions(userId);
|
||||
if (!restrictions.getBoolean(UserManager.ALLOW_INSTALL_APPS)) {
|
||||
Log.w(TAG, "User does not have permission to: " + restrictionKey);
|
||||
return false;
|
||||
if (restrictions.getBoolean(restrictionKey, false)) {
|
||||
Log.w(TAG, "User is restricted: " + restrictionKey);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -8430,7 +8430,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
|
||||
"deletePackage for user " + userId);
|
||||
}
|
||||
if (!isUserAllowed(userId, UserManager.ALLOW_UNINSTALL_APPS)) {
|
||||
if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
|
||||
try {
|
||||
observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED);
|
||||
} catch (RemoteException re) {
|
||||
@@ -8476,7 +8476,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
|
||||
try {
|
||||
if (dpm != null && dpm.packageHasActiveAdmins(packageName, userId)) {
|
||||
if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId)
|
||||
|| dpm.isDeviceOwner(packageName))) {
|
||||
Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
|
||||
return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
|
||||
}
|
||||
|
||||
@@ -226,6 +226,13 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRestricted() {
|
||||
synchronized (mPackagesLock) {
|
||||
return getUserInfoLocked(UserHandle.getCallingUserId()).isRestricted();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Should be locked on mUsers before calling this.
|
||||
*/
|
||||
@@ -558,7 +565,6 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
mNextSerialNumber = MIN_USER_ID;
|
||||
|
||||
Bundle restrictions = new Bundle();
|
||||
initRestrictionsToDefaults(restrictions);
|
||||
mUserRestrictions.append(UserHandle.USER_OWNER, restrictions);
|
||||
|
||||
updateUserIdsLocked();
|
||||
@@ -608,11 +614,11 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
Bundle restrictions = mUserRestrictions.get(userInfo.id);
|
||||
if (restrictions != null) {
|
||||
serializer.startTag(null, TAG_RESTRICTIONS);
|
||||
writeBoolean(serializer, restrictions, UserManager.ALLOW_CONFIG_WIFI);
|
||||
writeBoolean(serializer, restrictions, UserManager.ALLOW_MODIFY_ACCOUNTS);
|
||||
writeBoolean(serializer, restrictions, UserManager.ALLOW_INSTALL_APPS);
|
||||
writeBoolean(serializer, restrictions, UserManager.ALLOW_UNINSTALL_APPS);
|
||||
writeBoolean(serializer, restrictions, UserManager.ALLOW_CONFIG_LOCATION_ACCESS);
|
||||
writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_WIFI);
|
||||
writeBoolean(serializer, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS);
|
||||
writeBoolean(serializer, restrictions, UserManager.DISALLOW_INSTALL_APPS);
|
||||
writeBoolean(serializer, restrictions, UserManager.DISALLOW_UNINSTALL_APPS);
|
||||
writeBoolean(serializer, restrictions, UserManager.DISALLOW_SHARE_LOCATION);
|
||||
serializer.endTag(null, TAG_RESTRICTIONS);
|
||||
}
|
||||
serializer.endTag(null, TAG_USER);
|
||||
@@ -676,7 +682,6 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
long lastLoggedInTime = 0L;
|
||||
boolean partial = false;
|
||||
Bundle restrictions = new Bundle();
|
||||
initRestrictionsToDefaults(restrictions);
|
||||
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
@@ -725,11 +730,11 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
name = parser.getText();
|
||||
}
|
||||
} else if (TAG_RESTRICTIONS.equals(tag)) {
|
||||
readBoolean(parser, restrictions, UserManager.ALLOW_CONFIG_WIFI);
|
||||
readBoolean(parser, restrictions, UserManager.ALLOW_MODIFY_ACCOUNTS);
|
||||
readBoolean(parser, restrictions, UserManager.ALLOW_INSTALL_APPS);
|
||||
readBoolean(parser, restrictions, UserManager.ALLOW_UNINSTALL_APPS);
|
||||
readBoolean(parser, restrictions, UserManager.ALLOW_CONFIG_LOCATION_ACCESS);
|
||||
readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_WIFI);
|
||||
readBoolean(parser, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS);
|
||||
readBoolean(parser, restrictions, UserManager.DISALLOW_INSTALL_APPS);
|
||||
readBoolean(parser, restrictions, UserManager.DISALLOW_UNINSTALL_APPS);
|
||||
readBoolean(parser, restrictions, UserManager.DISALLOW_SHARE_LOCATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,7 +763,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
private void readBoolean(XmlPullParser parser, Bundle restrictions,
|
||||
String restrictionKey) {
|
||||
String value = parser.getAttributeValue(null, restrictionKey);
|
||||
restrictions.putBoolean(restrictionKey, value == null ? true : Boolean.parseBoolean(value));
|
||||
if (value != null) {
|
||||
restrictions.putBoolean(restrictionKey, Boolean.parseBoolean(value));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeBoolean(XmlSerializer xml, Bundle restrictions, String restrictionKey)
|
||||
@@ -769,14 +776,6 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void initRestrictionsToDefaults(Bundle restrictions) {
|
||||
restrictions.putBoolean(UserManager.ALLOW_CONFIG_WIFI, true);
|
||||
restrictions.putBoolean(UserManager.ALLOW_MODIFY_ACCOUNTS, true);
|
||||
restrictions.putBoolean(UserManager.ALLOW_INSTALL_APPS, true);
|
||||
restrictions.putBoolean(UserManager.ALLOW_UNINSTALL_APPS, true);
|
||||
restrictions.putBoolean(UserManager.ALLOW_CONFIG_LOCATION_ACCESS, true);
|
||||
}
|
||||
|
||||
private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) {
|
||||
String valueString = parser.getAttributeValue(null, attr);
|
||||
if (valueString == null) return defaultValue;
|
||||
@@ -823,7 +822,6 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
writeUserLocked(userInfo);
|
||||
updateUserIdsLocked();
|
||||
Bundle restrictions = new Bundle();
|
||||
initRestrictionsToDefaults(restrictions);
|
||||
mUserRestrictions.append(userId, restrictions);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user