summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Charles He <qiurui@google.com> 2017-01-23 17:11:50 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-01-23 17:11:53 +0000
commit34f04ffa0b9e42930f8cb753445e1f5f45cd11cc (patch)
tree43b88c3a8b450c5272d401588af33b479b863cf8
parent91a0c0983fd1f2222b66165a6f1ad6e2fd3c07da (diff)
parentdea0c3b654abefa488edc1e037424fbbceb759ed (diff)
Merge "DPM: Notify DO/PO of security updates."
-rw-r--r--api/current.txt4
-rw-r--r--api/system-current.txt5
-rw-r--r--api/test-current.txt4
-rw-r--r--core/java/android/app/admin/DeviceAdminReceiver.java13
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java47
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--core/java/android/app/admin/SystemUpdateInfo.java99
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java11
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/Owners.java13
9 files changed, 158 insertions, 40 deletions
diff --git a/api/current.txt b/api/current.txt
index 97019181111d..637cdac5b4fb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6366,8 +6366,12 @@ package android.app.admin {
public final class SystemUpdateInfo implements android.os.Parcelable {
method public int describeContents();
method public long getReceivedTime();
+ method public int getSecurityPatchState();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdateInfo> CREATOR;
+ field public static final int SECURITY_PATCH_STATE_FALSE = 1; // 0x1
+ field public static final int SECURITY_PATCH_STATE_TRUE = 2; // 0x2
+ field public static final int SECURITY_PATCH_STATE_UNKNOWN = 0; // 0x0
}
public class SystemUpdatePolicy implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 4cd63d694dcb..bafc3657cf8f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6382,6 +6382,7 @@ package android.app.admin {
method public void lockNow();
method public void lockNow(int);
method public void notifyPendingSystemUpdate(long);
+ method public void notifyPendingSystemUpdate(long, boolean);
method public boolean packageHasActiveAdmins(java.lang.String);
method public void reboot(android.content.ComponentName);
method public void removeActiveAdmin(android.content.ComponentName);
@@ -6589,8 +6590,12 @@ package android.app.admin {
public final class SystemUpdateInfo implements android.os.Parcelable {
method public int describeContents();
method public long getReceivedTime();
+ method public int getSecurityPatchState();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdateInfo> CREATOR;
+ field public static final int SECURITY_PATCH_STATE_FALSE = 1; // 0x1
+ field public static final int SECURITY_PATCH_STATE_TRUE = 2; // 0x2
+ field public static final int SECURITY_PATCH_STATE_UNKNOWN = 0; // 0x0
}
public class SystemUpdatePolicy implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 1aa70ebbb74a..c4081f0d4b4d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6388,8 +6388,12 @@ package android.app.admin {
public final class SystemUpdateInfo implements android.os.Parcelable {
method public int describeContents();
method public long getReceivedTime();
+ method public int getSecurityPatchState();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdateInfo> CREATOR;
+ field public static final int SECURITY_PATCH_STATE_FALSE = 1; // 0x1
+ field public static final int SECURITY_PATCH_STATE_TRUE = 2; // 0x2
+ field public static final int SECURITY_PATCH_STATE_UNKNOWN = 0; // 0x0
}
public class SystemUpdatePolicy implements android.os.Parcelable {
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index a248bce2a6ca..34a0c305a6d8 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -707,17 +707,24 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
}
/**
- * Allows the receiver to be notified when information about a pending system update is
+ * Called when the information about a pending system update is available.
+ *
+ * <p>Allows the receiver to be notified when information about a pending system update is
* available from the system update service. The same pending system update can trigger multiple
* calls to this method, so it is necessary to examine the incoming parameters for details about
* the update.
- * <p>
- * This callback is only applicable to device owners.
+ *
+ * <p>This callback is only applicable to device owners and profile owners.
+ *
+ * <p>To get further information about a pending system update (for example, whether or not the
+ * update is a security patch), the device owner or profile owner can call
+ * {@link DevicePolicyManager#getPendingSystemUpdate}.
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
* @param receivedTime The time as given by {@link System#currentTimeMillis()} indicating when
* the current pending update was first available. -1 if no pending update is available.
+ * @see DevicePolicyManager#getPendingSystemUpdate
*/
public void onSystemUpdatePending(Context context, Intent intent, long receivedTime) {
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b8bc7f155176..0da89eb2bd98 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1438,6 +1438,7 @@ public class DevicePolicyManager {
}
return false;
}
+
/**
* Return true if the given administrator component is currently being removed
* for the user.
@@ -1454,7 +1455,6 @@ public class DevicePolicyManager {
return false;
}
-
/**
* Return a list of all currently active device administrators' component
* names. If there are no administrators {@code null} may be
@@ -6199,12 +6199,18 @@ public class DevicePolicyManager {
}
/**
- * Callable by the system update service to notify device owners about pending updates.
+ * Called by the system update service to notify device and profile owners of pending system
+ * updates.
+ *
* The caller must hold {@link android.Manifest.permission#NOTIFY_PENDING_SYSTEM_UPDATE}
- * permission.
+ * permission. This method should only be used when it is unknown whether the pending system
+ * update is a security patch. Otherwise, use
+ * {@link #notifyPendingSystemUpdate(long, boolean)}.
*
- * @param updateReceivedTime The time as given by {@link System#currentTimeMillis()} indicating
- * when the current pending update was first available. -1 if no update is available.
+ * @param updateReceivedTime The time as given by {@link System#currentTimeMillis()}
+ * indicating when the current pending update was first available. {@code -1} if no
+ * update is available.
+ * @see #notifyPendingSystemUpdate(long, boolean)
* @hide
*/
@SystemApi
@@ -6212,7 +6218,36 @@ public class DevicePolicyManager {
throwIfParentInstance("notifyPendingSystemUpdate");
if (mService != null) {
try {
- mService.notifyPendingSystemUpdate(updateReceivedTime);
+ mService.notifyPendingSystemUpdate(SystemUpdateInfo.of(updateReceivedTime));
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Called by the system update service to notify device and profile owners of pending system
+ * updates.
+ *
+ * The caller must hold {@link android.Manifest.permission#NOTIFY_PENDING_SYSTEM_UPDATE}
+ * permission. This method should be used instead of {@link #notifyPendingSystemUpdate(long)}
+ * when it is known whether the pending system update is a security patch.
+ *
+ * @param updateReceivedTime The time as given by {@link System#currentTimeMillis()}
+ * indicating when the current pending update was first available. {@code -1} if no
+ * update is available.
+ * @param isSecurityPatch {@code true} if this system update is purely a security patch;
+ * {@code false} if not.
+ * @see #notifyPendingSystemUpdate(long)
+ * @hide
+ */
+ @SystemApi
+ public void notifyPendingSystemUpdate(long updateReceivedTime, boolean isSecurityPatch) {
+ throwIfParentInstance("notifyPendingSystemUpdate");
+ if (mService != null) {
+ try {
+ mService.notifyPendingSystemUpdate(SystemUpdateInfo.of(updateReceivedTime,
+ isSecurityPatch));
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 8891f93fcbb4..80ef557de831 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -264,7 +264,7 @@ interface IDevicePolicyManager {
boolean setStatusBarDisabled(in ComponentName who, boolean disabled);
boolean getDoNotAskCredentialsOnBoot();
- void notifyPendingSystemUpdate(in long updateReceivedTime);
+ void notifyPendingSystemUpdate(in SystemUpdateInfo info);
SystemUpdateInfo getPendingSystemUpdate(in ComponentName admin);
void setPermissionPolicy(in ComponentName admin, int policy);
diff --git a/core/java/android/app/admin/SystemUpdateInfo.java b/core/java/android/app/admin/SystemUpdateInfo.java
index 0937f3c37c59..6bb9f2d0ea22 100644
--- a/core/java/android/app/admin/SystemUpdateInfo.java
+++ b/core/java/android/app/admin/SystemUpdateInfo.java
@@ -16,6 +16,7 @@
package android.app.admin;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Build;
import android.os.Parcel;
@@ -25,41 +26,86 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* A class containing information about a pending system update.
*/
public final class SystemUpdateInfo implements Parcelable {
- private static final String ATTR_RECEIVED_TIME = "mReceivedTime";
+
+ /**
+ * Represents it is unknown whether the system update is a security patch.
+ */
+ public static final int SECURITY_PATCH_STATE_UNKNOWN = 0;
+
+ /**
+ * Represents the system update is not a security patch.
+ */
+ public static final int SECURITY_PATCH_STATE_FALSE = 1;
+
+ /**
+ * Represents the system update is a security patch.
+ */
+ public static final int SECURITY_PATCH_STATE_TRUE = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({SECURITY_PATCH_STATE_FALSE, SECURITY_PATCH_STATE_TRUE, SECURITY_PATCH_STATE_UNKNOWN})
+ public @interface SecurityPatchState {}
+
+ private static final String ATTR_RECEIVED_TIME = "received-time";
+ private static final String ATTR_SECURITY_PATCH_STATE = "security-patch-state";
// Tag used to store original build fingerprint to detect when the update is applied.
- private static final String ATTR_ORIGINAL_BUILD = "originalBuild";
+ private static final String ATTR_ORIGINAL_BUILD = "original-build";
+
private final long mReceivedTime;
+ @SecurityPatchState
+ private final int mSecurityPatchState;
- private SystemUpdateInfo(long receivedTime) {
+ private SystemUpdateInfo(long receivedTime, @SecurityPatchState int securityPatchState) {
this.mReceivedTime = receivedTime;
+ this.mSecurityPatchState = securityPatchState;
}
private SystemUpdateInfo(Parcel in) {
mReceivedTime = in.readLong();
+ mSecurityPatchState = in.readInt();
}
- /**
- * @hide
- */
+ /** @hide */
@Nullable
public static SystemUpdateInfo of(long receivedTime) {
- return receivedTime == -1 ? null : new SystemUpdateInfo(receivedTime);
+ return receivedTime == -1
+ ? null : new SystemUpdateInfo(receivedTime, SECURITY_PATCH_STATE_UNKNOWN);
+ }
+
+ /** @hide */
+ @Nullable
+ public static SystemUpdateInfo of(long receivedTime, boolean isSecurityPatch) {
+ return receivedTime == -1 ? null : new SystemUpdateInfo(receivedTime,
+ isSecurityPatch ? SECURITY_PATCH_STATE_TRUE : SECURITY_PATCH_STATE_FALSE);
}
/**
- * Get time when the update was first available.
- * @return time as given by {@link System#currentTimeMillis()}
+ * Gets time when the update was first available.
+ * @return Time as given by {@link System#currentTimeMillis()}
*/
public long getReceivedTime() {
return mReceivedTime;
}
+ /**
+ * Gets whether the update is a security patch.
+ * @return {@link #SECURITY_PATCH_STATE_FALSE}, {@link #SECURITY_PATCH_STATE_TRUE}, or
+ * {@link #SECURITY_PATCH_STATE_UNKNOWN}.
+ */
+ @SecurityPatchState
+ public int getSecurityPatchState() {
+ return mSecurityPatchState;
+ }
+
public static final Creator<SystemUpdateInfo> CREATOR =
new Creator<SystemUpdateInfo>() {
@Override
@@ -73,19 +119,16 @@ public final class SystemUpdateInfo implements Parcelable {
}
};
- /**
- * @hide
- */
+ /** @hide */
public void writeToXml(XmlSerializer out, String tag) throws IOException {
out.startTag(null, tag);
out.attribute(null, ATTR_RECEIVED_TIME, String.valueOf(mReceivedTime));
+ out.attribute(null, ATTR_SECURITY_PATCH_STATE, String.valueOf(mSecurityPatchState));
out.attribute(null, ATTR_ORIGINAL_BUILD , Build.FINGERPRINT);
out.endTag(null, tag);
}
- /**
- * @hide
- */
+ /** @hide */
@Nullable
public static SystemUpdateInfo readFromXml(XmlPullParser parser) {
// If an OTA has been applied (build fingerprint has changed), discard stale info.
@@ -95,7 +138,9 @@ public final class SystemUpdateInfo implements Parcelable {
}
final long receivedTime =
Long.parseLong(parser.getAttributeValue(null, ATTR_RECEIVED_TIME));
- return of(receivedTime);
+ final int securityPatchState =
+ Integer.parseInt(parser.getAttributeValue(null, ATTR_SECURITY_PATCH_STATE));
+ return new SystemUpdateInfo(receivedTime, securityPatchState);
}
@Override
@@ -106,11 +151,26 @@ public final class SystemUpdateInfo implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(getReceivedTime());
+ dest.writeInt(getSecurityPatchState());
}
@Override
public String toString() {
- return String.format("SystemUpdateInfo (receivedTime = %d)", mReceivedTime);
+ return String.format("SystemUpdateInfo (receivedTime = %d, securityPatchState = %s)",
+ mReceivedTime, securityPatchStateToString(mSecurityPatchState));
+ }
+
+ private static String securityPatchStateToString(@SecurityPatchState int state) {
+ switch (state) {
+ case SECURITY_PATCH_STATE_FALSE:
+ return "false";
+ case SECURITY_PATCH_STATE_TRUE:
+ return "true";
+ case SECURITY_PATCH_STATE_UNKNOWN:
+ return "unknown";
+ default:
+ throw new IllegalArgumentException("Unrecognized security patch state: " + state);
+ }
}
@Override
@@ -118,11 +178,12 @@ public final class SystemUpdateInfo implements Parcelable {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SystemUpdateInfo that = (SystemUpdateInfo) o;
- return mReceivedTime == that.mReceivedTime;
+ return mReceivedTime == that.mReceivedTime
+ && mSecurityPatchState == that.mSecurityPatchState;
}
@Override
public int hashCode() {
- return Objects.hash(mReceivedTime);
+ return Objects.hash(mReceivedTime, mSecurityPatchState);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8835ab273498..623a0a59fd1a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -8814,7 +8814,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
- public void notifyPendingSystemUpdate(long updateReceivedTime) {
+ public void notifyPendingSystemUpdate(@Nullable SystemUpdateInfo info) {
mContext.enforceCallingOrSelfPermission(permission.NOTIFY_PENDING_SYSTEM_UPDATE,
"Only the system update service can broadcast update information");
@@ -8824,13 +8824,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return;
}
- if (!mOwners.saveSystemUpdateInfo(updateReceivedTime)) {
- // Received time hasn't changed, don't send duplicate notification.
+ if (!mOwners.saveSystemUpdateInfo(info)) {
+ // Pending system update hasn't changed, don't send duplicate notification.
return;
}
- final Intent intent = new Intent(DeviceAdminReceiver.ACTION_NOTIFY_PENDING_SYSTEM_UPDATE);
- intent.putExtra(DeviceAdminReceiver.EXTRA_SYSTEM_UPDATE_RECEIVED_TIME, updateReceivedTime);
+ final Intent intent = new Intent(DeviceAdminReceiver.ACTION_NOTIFY_PENDING_SYSTEM_UPDATE)
+ .putExtra(DeviceAdminReceiver.EXTRA_SYSTEM_UPDATE_RECEIVED_TIME,
+ info == null ? -1 : info.getReceivedTime());
final long ident = mInjector.binderClearCallingIdentity();
try {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 99c76b169598..a5500dd70c96 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -476,19 +476,20 @@ class Owners {
}
/**
- * @return Whether update received time has changed.
+ * Saves the given {@link SystemUpdateInfo} if it is different from the existing one, or if
+ * none exists.
+ *
+ * @return Whether the saved system update information has changed.
*/
- boolean saveSystemUpdateInfo(long receivedTime) {
- final SystemUpdateInfo newSystemUpdateInfo = SystemUpdateInfo.of(receivedTime);
+ boolean saveSystemUpdateInfo(@Nullable SystemUpdateInfo newInfo) {
synchronized (mLock) {
// Check if we already have the same update information.
- if (Objects.equals(newSystemUpdateInfo, mSystemUpdateInfo)) {
+ if (Objects.equals(newInfo, mSystemUpdateInfo)) {
return false;
}
- mSystemUpdateInfo = newSystemUpdateInfo;
+ mSystemUpdateInfo = newInfo;
new DeviceOwnerReadWriter().writeToFileLocked();
-
return true;
}
}