diff options
author | 2017-01-23 17:11:50 +0000 | |
---|---|---|
committer | 2017-01-23 17:11:53 +0000 | |
commit | 34f04ffa0b9e42930f8cb753445e1f5f45cd11cc (patch) | |
tree | 43b88c3a8b450c5272d401588af33b479b863cf8 | |
parent | 91a0c0983fd1f2222b66165a6f1ad6e2fd3c07da (diff) | |
parent | dea0c3b654abefa488edc1e037424fbbceb759ed (diff) |
Merge "DPM: Notify DO/PO of security updates."
-rw-r--r-- | api/current.txt | 4 | ||||
-rw-r--r-- | api/system-current.txt | 5 | ||||
-rw-r--r-- | api/test-current.txt | 4 | ||||
-rw-r--r-- | core/java/android/app/admin/DeviceAdminReceiver.java | 13 | ||||
-rw-r--r-- | core/java/android/app/admin/DevicePolicyManager.java | 47 | ||||
-rw-r--r-- | core/java/android/app/admin/IDevicePolicyManager.aidl | 2 | ||||
-rw-r--r-- | core/java/android/app/admin/SystemUpdateInfo.java | 99 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 11 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/Owners.java | 13 |
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; } } |