summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt21
-rw-r--r--api/system-current.txt24
-rw-r--r--core/java/android/app/admin/DeviceInitializerStatus.java177
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java54
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java34
7 files changed, 319 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt
index bec686d..533682f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5615,6 +5615,26 @@ package android.app.admin {
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
}
+ public class DeviceInitializerStatus {
+ method public static boolean isCustomStatus(int);
+ method public static boolean isErrorStatus(int);
+ method public static boolean isHighPriority(int);
+ field public static final int FLAG_STATUS_CUSTOM = 33554432; // 0x2000000
+ field public static final int FLAG_STATUS_ERROR = 16777216; // 0x1000000
+ field public static final int FLAG_STATUS_HIGH_PRIORITY = 134217728; // 0x8000000
+ field public static final int FLAG_STATUS_RESERVED = 67108864; // 0x4000000
+ field public static final int STATUS_ERROR_CONNECT_WIFI = 16777237; // 0x1000015
+ field public static final int STATUS_ERROR_DELETE_APPS = 16777242; // 0x100001a
+ field public static final int STATUS_ERROR_DOUBLE_BUMP = 16777246; // 0x100001e
+ field public static final int STATUS_ERROR_DOWNLOAD_PACKAGE = 16777239; // 0x1000017
+ field public static final int STATUS_ERROR_INSTALL_PACKAGE = 16777240; // 0x1000018
+ field public static final int STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING = 16777238; // 0x1000016
+ field public static final int STATUS_ERROR_SET_DEVICE_POLICY = 16777241; // 0x1000019
+ field public static final int STATUS_STATE_CONNECT_BLUETOOTH_PROXY = 134217736; // 0x8000008
+ field public static final int STATUS_STATE_DEVICE_PROVISIONED = 134217738; // 0x800000a
+ field public static final int STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY = 134217737; // 0x8000009
+ }
+
public class DevicePolicyManager {
method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5678,6 +5698,7 @@ package android.app.admin {
method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
method public boolean resetPassword(java.lang.String, int);
+ method public void sendDeviceInitializerStatus(int, java.lang.String);
method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
diff --git a/api/system-current.txt b/api/system-current.txt
index 2cfa9a7..7698f8e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5710,6 +5710,26 @@ package android.app.admin {
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
}
+ public class DeviceInitializerStatus {
+ method public static boolean isCustomStatus(int);
+ method public static boolean isErrorStatus(int);
+ method public static boolean isHighPriority(int);
+ field public static final int FLAG_STATUS_CUSTOM = 33554432; // 0x2000000
+ field public static final int FLAG_STATUS_ERROR = 16777216; // 0x1000000
+ field public static final int FLAG_STATUS_HIGH_PRIORITY = 134217728; // 0x8000000
+ field public static final int FLAG_STATUS_RESERVED = 67108864; // 0x4000000
+ field public static final int STATUS_ERROR_CONNECT_WIFI = 16777237; // 0x1000015
+ field public static final int STATUS_ERROR_DELETE_APPS = 16777242; // 0x100001a
+ field public static final int STATUS_ERROR_DOUBLE_BUMP = 16777246; // 0x100001e
+ field public static final int STATUS_ERROR_DOWNLOAD_PACKAGE = 16777239; // 0x1000017
+ field public static final int STATUS_ERROR_INSTALL_PACKAGE = 16777240; // 0x1000018
+ field public static final int STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING = 16777238; // 0x1000016
+ field public static final int STATUS_ERROR_SET_DEVICE_POLICY = 16777241; // 0x1000019
+ field public static final int STATUS_STATE_CONNECT_BLUETOOTH_PROXY = 134217736; // 0x8000008
+ field public static final int STATUS_STATE_DEVICE_PROVISIONED = 134217738; // 0x800000a
+ field public static final int STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY = 134217737; // 0x8000009
+ }
+
public class DevicePolicyManager {
method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5781,6 +5801,7 @@ package android.app.admin {
method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
method public boolean resetPassword(java.lang.String, int);
+ method public void sendDeviceInitializerStatus(int, java.lang.String);
method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
method public deprecated boolean setActiveProfileOwner(android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException;
method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
@@ -5826,6 +5847,7 @@ package android.app.admin {
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
+ field public static final java.lang.String ACTION_SEND_DEVICE_INITIALIZER_STATUS = "android.app.action.SEND_DEVICE_INITIALIZER_STATUS";
field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
field public static final java.lang.String ACTION_SET_PROFILE_OWNER = "android.app.action.SET_PROFILE_OWNER";
field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
@@ -5836,6 +5858,8 @@ package android.app.admin {
field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
+ field public static final java.lang.String EXTRA_DEVICE_INITIALIZER_STATUS_CODE = "android.app.extra.DEVICE_INITIALIZER_STATUS_CODE";
+ field public static final java.lang.String EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION = "android.app.extra.DEVICE_INITIALIZER_STATUS_DESCRIPTION";
field public static final java.lang.String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
field public static final java.lang.String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
diff --git a/core/java/android/app/admin/DeviceInitializerStatus.java b/core/java/android/app/admin/DeviceInitializerStatus.java
new file mode 100644
index 0000000..b58711c
--- /dev/null
+++ b/core/java/android/app/admin/DeviceInitializerStatus.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015 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;
+
+/**
+ * Defines constants designating device provisioning status used with {@link
+ * android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}.
+ *
+ * This class contains flag constants that define special status codes:
+ * <ul>
+ * <li>{@link #FLAG_STATUS_ERROR} is used to define provisioning error status codes
+ * <li>{@link #FLAG_STATUS_CUSTOM} is used to define custom status codes
+ * <li>{@link #FLAG_STATUS_HIGH_PRIORITY} is used to define high priority status codes
+ * </ul>
+ *
+ * <p>Status codes used by ManagedProvisioning are also defined in this class. These status codes
+ * include provisioning errors and status codes.
+ * <ul>
+ * <li>{@link #STATUS_ERROR_CONNECT_WIFI}
+ * <li>{@link #STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING}
+ * <li>{@link #STATUS_ERROR_DOWNLOAD_PACKAGE}
+ * <li>{@link #STATUS_ERROR_INSTALL_PACKAGE}
+ * <li>{@link #STATUS_ERROR_SET_DEVICE_POLICY}
+ * <li>{@link #STATUS_ERROR_DELETE_APPS}
+ * <li>{@link #STATUS_ERROR_DOUBLE_BUMP}
+ * <li>{@link #STATUS_STATE_CONNECT_BLUETOOTH_PROXY}
+ * <li>{@link #STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY}
+ * <li>{@link #STATUS_STATE_DEVICE_PROVISIONED}
+ * </ul>
+ */
+public class DeviceInitializerStatus {
+ /**
+ * A flag used to designate an error status.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ * @see #isErrorStatus(int)
+ */
+ public static final int FLAG_STATUS_ERROR = 0x01000000;
+
+ /**
+ * A flag used to designate a custom status. Custom status codes will be defined by device
+ * initializer agents.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ * @see #isCustomStatus(int)
+ */
+ public static final int FLAG_STATUS_CUSTOM = 0x02000000;
+
+ /**
+ * A bit flag used to designate a reserved status. Reserved status codes will not be defined
+ * in AOSP.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ */
+ public static final int FLAG_STATUS_RESERVED = 0x04000000;
+
+ /**
+ * A flag used to indicate that a status message is high priority.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ * @see #isHighPriority(int)
+ */
+ public static final int FLAG_STATUS_HIGH_PRIORITY = 0x08000000;
+
+ /**
+ * Device provisioning status code that indicates that a device is connecting to establish
+ * a Bluetooth network proxy.
+ */
+ public static final int STATUS_STATE_CONNECT_BLUETOOTH_PROXY = FLAG_STATUS_HIGH_PRIORITY | 8;
+
+ /**
+ * Device provisioning status code that indicates that a connected Bluetooth network proxy
+ * is being shut down.
+ */
+ public static final int STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY = FLAG_STATUS_HIGH_PRIORITY | 9;
+
+ /**
+ * Device provisioning status code that indicates that a device has been successfully
+ * provisioned.
+ */
+ public static final int STATUS_STATE_DEVICE_PROVISIONED = FLAG_STATUS_HIGH_PRIORITY | 10;
+
+ /**
+ * Device provisioning error status code that indicates that a device could not connect to
+ * a Wi-Fi network.
+ */
+ public static final int STATUS_ERROR_CONNECT_WIFI = FLAG_STATUS_ERROR | 21;
+
+ /**
+ * Device provisioning error status indicating that factory reset protection is enabled on
+ * the provisioned device and cannot be disabled with the provided data.
+ */
+ public static final int STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING =
+ FLAG_STATUS_ERROR | 22;
+
+ /**
+ * Device provisioning error status indicating that device administrator and device initializer
+ * packages could not be downloaded and verified successfully.
+ */
+ public static final int STATUS_ERROR_DOWNLOAD_PACKAGE = FLAG_STATUS_ERROR | 23;
+
+ /**
+ * Device provisioning error status indicating that device owner and device initializer packages
+ * could not be installed.
+ */
+ public static final int STATUS_ERROR_INSTALL_PACKAGE = FLAG_STATUS_ERROR | 24;
+
+ /**
+ * Device provisioning error status indicating that the device owner or device initializer
+ * components could not be set.
+ */
+ public static final int STATUS_ERROR_SET_DEVICE_POLICY = FLAG_STATUS_ERROR | 25;
+
+ /**
+ * Device provisioning error status indicating that deleting non-required applications during
+ * provisioning failed.
+ */
+ public static final int STATUS_ERROR_DELETE_APPS = FLAG_STATUS_ERROR | 26;
+
+ /**
+ * Device provisioning error status code that indicates that a provisioning attempt has failed
+ * because the device has already been provisioned or that provisioning has already started.
+ */
+ public static final int STATUS_ERROR_DOUBLE_BUMP = FLAG_STATUS_ERROR | 30;
+
+ /**
+ * Determine if the specified status code represents an error status.
+ * @param statusCode status code to check
+ * @return {@code true} if the status code is an error status code
+ */
+ public static boolean isErrorStatus(int statusCode) {
+ return isFlagSet(statusCode, FLAG_STATUS_ERROR);
+ }
+
+ /**
+ * Determine if the specified status code is a custom status. Custom status codes are defined
+ * and sent by device initialization agents.
+ * @param statusCode status code to check
+ * @return {@code true} if the status code is a custom status code
+ */
+ public static boolean isCustomStatus(int statusCode) {
+ return isFlagSet(statusCode, FLAG_STATUS_CUSTOM);
+ }
+
+ /**
+ * Determine if the specified status code is a high priority status code.
+ * @param statusCode status code to check
+ * @return {@code true} if the status code is a high priority status code
+ */
+ public static boolean isHighPriority(int statusCode) {
+ return isFlagSet(statusCode, FLAG_STATUS_HIGH_PRIORITY);
+ }
+
+ private static boolean isFlagSet(int statusCode, int flag) {
+ return (statusCode & flag) != 0;
+ }
+
+ private DeviceInitializerStatus() {}
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 68f4707..26b1b36 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -651,6 +651,45 @@ public class DevicePolicyManager {
= "android.app.action.SET_PROFILE_OWNER";
/**
+ * Protected broadcast action that will be sent to managed provisioning to notify it that a
+ * status update has been reported by the device initializer. The status update will be
+ * reported to the remote setup device over Bluetooth.
+ *
+ * <p>Broadcasts with this action must supply a
+ * {@linkplain DeviceInitializerStatus#isCustomStatus(int) custom} status code in the
+ * {@link EXTRA_DEVICE_INITIALIZER_STATUS_CODE} extra.
+ *
+ * <p>Broadcasts may optionally contain a description in the
+ * {@link EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION} extra.
+ * @hide
+ */
+ @SystemApi
+ public static final String ACTION_SEND_DEVICE_INITIALIZER_STATUS
+ = "android.app.action.SEND_DEVICE_INITIALIZER_STATUS";
+
+ /**
+ * An integer extra that contains the status code that defines a status update. This extra must
+ * sent as part of a broadcast with an action of {@code ACTION_SEND_DEVICE_INITIALIZER_STATUS}.
+ *
+ * <p>The status code sent with this extra must be a custom status code as defined by
+ * {@link DeviceInitializerStatus#isCustomStatus(int)}.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_DEVICE_INITIALIZER_STATUS_CODE
+ = "android.app.extra.DEVICE_INITIALIZER_STATUS_CODE";
+
+ /**
+ * A {@code String} extra that contains an optional description accompanying a status update.
+ * This extra my be sent as part of a broadcast with an action of
+ * {@code ACTION_SEND_DEVICE_INITIALIZER_STATUS}.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION
+ = "android.app.extra.DEVICE_INITIALIZER_STATUS_DESCRIPTION";
+
+ /**
* @hide
* Name of the profile owner admin that controls the user.
*/
@@ -4012,4 +4051,19 @@ public class DevicePolicyManager {
Log.w(TAG, "Could not set the user icon ", re);
}
}
+
+ /**
+ * Called by device initializer to send a provisioning status update to the remote setup device.
+ *
+ * @param statusCode a custom status code value as defined by
+ * {@link DeviceInitializerStatus#isCustomStatus(int)}.
+ * @param description custom description of the status code sent
+ */
+ public void sendDeviceInitializerStatus(int statusCode, String description) {
+ try {
+ mService.sendDeviceInitializerStatus(statusCode, description);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not send device initializer status", re);
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index c68311e..75b97a8 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -213,4 +213,6 @@ interface IDevicePolicyManager {
ComponentName getDeviceInitializerComponent();
void setUserIcon(in ComponentName admin, in Bitmap icon);
+
+ void sendDeviceInitializerStatus(int statusCode, String description);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7c5d194..4a1be2d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -87,6 +87,7 @@
<protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" />
<protected-broadcast android:name="android.app.action.EXIT_DESK_MODE" />
<protected-broadcast android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED" />
+ <protected-broadcast android:name="android.app.action.SEND_DEVICE_INITIALIZER_STATUS" />
<protected-broadcast android:name="android.appwidget.action.APPWIDGET_UPDATE_OPTIONS" />
<protected-broadcast android:name="android.appwidget.action.APPWIDGET_DELETED" />
@@ -2374,6 +2375,12 @@
<permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"
android:protectionLevel="signature" />
+ <!-- Allows receiving status updates from a device initializer.
+ @hide Not for use by third-party applications. -->
+ <permission android:name="android.permission.RECEIVE_DEVICE_INITIALIZER_STATUS"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bb3085e..c500d79 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5715,6 +5715,40 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
+ public void sendDeviceInitializerStatus(int statusCode, String description) {
+ synchronized (this) {
+ String packageName = getDeviceInitializer();
+ if (packageName == null) {
+ throw new SecurityException("No device initializers");
+ }
+ UserHandle callingUser = Binder.getCallingUserHandle();
+ int deviceInitializerUid = -1;
+ try {
+ deviceInitializerUid = mContext.getPackageManager().getPackageUid(
+ packageName, callingUser.getIdentifier());
+ } catch (NameNotFoundException e) {
+ throw new SecurityException(e);
+ }
+ if (Binder.getCallingUid() != deviceInitializerUid) {
+ throw new SecurityException("Caller must be a device initializer");
+ }
+ long id = Binder.clearCallingIdentity();
+ try {
+ Intent intent = new Intent(
+ DevicePolicyManager.ACTION_SEND_DEVICE_INITIALIZER_STATUS);
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_INITIALIZER_STATUS_CODE,
+ statusCode);
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION,
+ description);
+ mContext.sendBroadcastAsUser(intent, callingUser,
+ android.Manifest.permission.RECEIVE_DEVICE_INITIALIZER_STATUS);
+ } finally {
+ restoreCallingIdentity(id);
+ }
+ }
+ }
+
/**
* We need to update the internal state of whether a user has completed setup once. After
* that, we ignore any changes that reset the Settings.Secure.USER_SETUP_COMPLETE changes