summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Pavel Grafov <pgrafov@google.com> 2016-12-02 11:21:45 +0000
committer Pavel Grafov <pgrafov@google.com> 2017-01-17 15:06:22 +0000
commitd65799ee812132bc54fd9d67d4ef9b19906b9da5 (patch)
treecf64fd04e10b531329146fec58498d078ed9d917
parent0872c2455e896c9238014efb4d739c62a8103b74 (diff)
Store pending OTA state and make it accessible via polling api.
Change-Id: Ieb71dfb902371a683b17561f51ba9c2c730eb37b Test: gts-tradefed run gts -a armeabi-v7a -m GtsGmscoreHostTestCases -t com.google.android.gts.devicepolicy.DeviceOwnerTest Bug: 31000521
-rw-r--r--api/current.txt8
-rw-r--r--api/system-current.txt8
-rw-r--r--api/test-current.txt8
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java21
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--core/java/android/app/admin/SystemUpdateInfo.aidl20
-rw-r--r--core/java/android/app/admin/SystemUpdateInfo.java128
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java48
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/Owners.java61
9 files changed, 273 insertions, 31 deletions
diff --git a/api/current.txt b/api/current.txt
index 6da09e35fe5e..dfb33025cd6a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6107,6 +6107,7 @@ package android.app.admin {
method public int getPasswordMinimumSymbols(android.content.ComponentName);
method public int getPasswordMinimumUpperCase(android.content.ComponentName);
method public int getPasswordQuality(android.content.ComponentName);
+ method public android.app.admin.SystemUpdateInfo getPendingSystemUpdate(android.content.ComponentName);
method public int getPermissionGrantState(android.content.ComponentName, java.lang.String, java.lang.String);
method public int getPermissionPolicy(android.content.ComponentName);
method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
@@ -6328,6 +6329,13 @@ package android.app.admin {
field public static final android.os.Parcelable.Creator<android.app.admin.SecurityLog.SecurityEvent> CREATOR;
}
+ public final class SystemUpdateInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getReceivedTime();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdateInfo> CREATOR;
+ }
+
public class SystemUpdatePolicy implements android.os.Parcelable {
method public static android.app.admin.SystemUpdatePolicy createAutomaticInstallPolicy();
method public static android.app.admin.SystemUpdatePolicy createPostponeInstallPolicy();
diff --git a/api/system-current.txt b/api/system-current.txt
index 5640eafcee1f..dfe57d871e41 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6292,6 +6292,7 @@ package android.app.admin {
method public int getPasswordMinimumSymbols(android.content.ComponentName);
method public int getPasswordMinimumUpperCase(android.content.ComponentName);
method public int getPasswordQuality(android.content.ComponentName);
+ method public android.app.admin.SystemUpdateInfo getPendingSystemUpdate(android.content.ComponentName);
method public int getPermissionGrantState(android.content.ComponentName, java.lang.String, java.lang.String);
method public int getPermissionPolicy(android.content.ComponentName);
method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
@@ -6537,6 +6538,13 @@ package android.app.admin {
field public static final android.os.Parcelable.Creator<android.app.admin.SecurityLog.SecurityEvent> CREATOR;
}
+ public final class SystemUpdateInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getReceivedTime();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdateInfo> CREATOR;
+ }
+
public class SystemUpdatePolicy implements android.os.Parcelable {
method public static android.app.admin.SystemUpdatePolicy createAutomaticInstallPolicy();
method public static android.app.admin.SystemUpdatePolicy createPostponeInstallPolicy();
diff --git a/api/test-current.txt b/api/test-current.txt
index 714cac9fc559..189c6e2ab79f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6128,6 +6128,7 @@ package android.app.admin {
method public int getPasswordMinimumSymbols(android.content.ComponentName);
method public int getPasswordMinimumUpperCase(android.content.ComponentName);
method public int getPasswordQuality(android.content.ComponentName);
+ method public android.app.admin.SystemUpdateInfo getPendingSystemUpdate(android.content.ComponentName);
method public int getPermissionGrantState(android.content.ComponentName, java.lang.String, java.lang.String);
method public int getPermissionPolicy(android.content.ComponentName);
method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
@@ -6350,6 +6351,13 @@ package android.app.admin {
field public static final android.os.Parcelable.Creator<android.app.admin.SecurityLog.SecurityEvent> CREATOR;
}
+ public final class SystemUpdateInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getReceivedTime();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdateInfo> CREATOR;
+ }
+
public class SystemUpdatePolicy implements android.os.Parcelable {
method public static android.app.admin.SystemUpdatePolicy createAutomaticInstallPolicy();
method public static android.app.admin.SystemUpdatePolicy createPostponeInstallPolicy();
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index c95e0113e801..6d6ada6ddab9 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -20,7 +20,6 @@ import android.annotation.ColorInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
@@ -28,7 +27,6 @@ import android.annotation.TestApi;
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.Activity;
-import android.app.admin.PasswordMetrics;
import android.app.IServiceConnection;
import android.app.admin.SecurityLog.SecurityEvent;
import android.content.ComponentName;
@@ -5536,7 +5534,7 @@ public class DevicePolicyManager {
* {@link DevicePolicyManager#setApplicationRestrictions} was called, or an empty
* {@link Bundle} if no restrictions have been set.
* @throws SecurityException if {@code admin} is not a device or profile owner.
- * @see {@link #setApplicationRestrictionsManagingPackage}
+ * @see #setApplicationRestrictionsManagingPackage
*/
@WorkerThread
public @NonNull Bundle getApplicationRestrictions(
@@ -6221,6 +6219,23 @@ public class DevicePolicyManager {
}
/**
+ * Called by device or profile owners to get information about a pending system update.
+ *
+ * @param admin Which profile or device owner this request is associated with.
+ * @return Information about a pending system update or {@code null} if no update pending.
+ * @throws SecurityException if {@code admin} is not a device or profile owner.
+ * @see DeviceAdminReceiver#onSystemUpdatePending(Context, Intent, long)
+ */
+ public @Nullable SystemUpdateInfo getPendingSystemUpdate(@NonNull ComponentName admin) {
+ throwIfParentInstance("getPendingSystemUpdate");
+ try {
+ return mService.getPendingSystemUpdate(admin);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Called by profile or device owners to set the default response for future runtime permission
* requests by applications. The policy can allow for normal operation which prompts the user to
* grant a permission, or can allow automatic granting or denying of runtime permission requests
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 66185d53fb0a..8891f93fcbb4 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -20,6 +20,7 @@ package android.app.admin;
import android.app.admin.NetworkEvent;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
+import android.app.admin.SystemUpdateInfo;
import android.app.admin.SystemUpdatePolicy;
import android.app.admin.PasswordMetrics;
import android.content.ComponentName;
@@ -264,6 +265,7 @@ interface IDevicePolicyManager {
boolean getDoNotAskCredentialsOnBoot();
void notifyPendingSystemUpdate(in long updateReceivedTime);
+ SystemUpdateInfo getPendingSystemUpdate(in ComponentName admin);
void setPermissionPolicy(in ComponentName admin, int policy);
int getPermissionPolicy(in ComponentName admin);
diff --git a/core/java/android/app/admin/SystemUpdateInfo.aidl b/core/java/android/app/admin/SystemUpdateInfo.aidl
new file mode 100644
index 000000000000..6d14904f4a1d
--- /dev/null
+++ b/core/java/android/app/admin/SystemUpdateInfo.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2017, 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;
+
+parcelable SystemUpdateInfo;
diff --git a/core/java/android/app/admin/SystemUpdateInfo.java b/core/java/android/app/admin/SystemUpdateInfo.java
new file mode 100644
index 000000000000..0937f3c37c59
--- /dev/null
+++ b/core/java/android/app/admin/SystemUpdateInfo.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2017 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.Nullable;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+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";
+ // Tag used to store original build fingerprint to detect when the update is applied.
+ private static final String ATTR_ORIGINAL_BUILD = "originalBuild";
+ private final long mReceivedTime;
+
+ private SystemUpdateInfo(long receivedTime) {
+ this.mReceivedTime = receivedTime;
+ }
+
+ private SystemUpdateInfo(Parcel in) {
+ mReceivedTime = in.readLong();
+ }
+
+ /**
+ * @hide
+ */
+ @Nullable
+ public static SystemUpdateInfo of(long receivedTime) {
+ return receivedTime == -1 ? null : new SystemUpdateInfo(receivedTime);
+ }
+
+ /**
+ * Get time when the update was first available.
+ * @return time as given by {@link System#currentTimeMillis()}
+ */
+ public long getReceivedTime() {
+ return mReceivedTime;
+ }
+
+ public static final Creator<SystemUpdateInfo> CREATOR =
+ new Creator<SystemUpdateInfo>() {
+ @Override
+ public SystemUpdateInfo createFromParcel(Parcel in) {
+ return new SystemUpdateInfo(in);
+ }
+
+ @Override
+ public SystemUpdateInfo[] newArray(int size) {
+ return new SystemUpdateInfo[size];
+ }
+ };
+
+ /**
+ * @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_ORIGINAL_BUILD , Build.FINGERPRINT);
+ out.endTag(null, tag);
+ }
+
+ /**
+ * @hide
+ */
+ @Nullable
+ public static SystemUpdateInfo readFromXml(XmlPullParser parser) {
+ // If an OTA has been applied (build fingerprint has changed), discard stale info.
+ final String buildFingerprint = parser.getAttributeValue(null, ATTR_ORIGINAL_BUILD );
+ if (!Build.FINGERPRINT.equals(buildFingerprint)) {
+ return null;
+ }
+ final long receivedTime =
+ Long.parseLong(parser.getAttributeValue(null, ATTR_RECEIVED_TIME));
+ return of(receivedTime);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(getReceivedTime());
+ }
+
+ @Override
+ public String toString() {
+ return String.format("SystemUpdateInfo (receivedTime = %d)", mReceivedTime);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SystemUpdateInfo that = (SystemUpdateInfo) o;
+ return mReceivedTime == that.mReceivedTime;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mReceivedTime);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 040188dded2c..76bab4f6badc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -69,6 +69,7 @@ import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
import android.app.admin.NetworkEvent;
import android.app.admin.PasswordMetrics;
+import android.app.admin.SystemUpdateInfo;
import android.app.admin.SecurityLog;
import android.app.admin.SecurityLog.SecurityEvent;
import android.app.admin.SystemUpdatePolicy;
@@ -4526,9 +4527,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
}
} else {
- synchronized (this) {
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- }
+ enforceProfileOrDeviceOwner(who);
+ }
+ }
+
+ private void enforceProfileOrDeviceOwner(ComponentName who) {
+ synchronized (this) {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
}
}
@@ -4538,9 +4543,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
throw new SecurityException("who == null, but caller is not cert installer");
}
} else {
- synchronized (this) {
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- }
+ enforceProfileOrDeviceOwner(who);
}
}
@@ -4830,9 +4833,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean setAlwaysOnVpnPackage(ComponentName admin, String vpnPackage, boolean lockdown)
throws SecurityException {
- synchronized (this) {
- getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- }
+ enforceProfileOrDeviceOwner(admin);
final int userId = mInjector.userHandleGetCallingUserId();
final long token = mInjector.binderClearCallingIdentity();
@@ -4854,9 +4855,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public String getAlwaysOnVpnPackage(ComponentName admin)
throws SecurityException {
- synchronized (this) {
- getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- }
+ enforceProfileOrDeviceOwner(admin);
final int userId = mInjector.userHandleGetCallingUserId();
final long token = mInjector.binderClearCallingIdentity();
@@ -6999,9 +6998,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void enforceCanManageApplicationRestrictions(ComponentName who) {
if (who != null) {
- synchronized (this) {
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- }
+ enforceProfileOrDeviceOwner(who);
} else if (!isCallerApplicationRestrictionsManagingPackage()) {
throw new SecurityException(
"No admin component given, and caller cannot manage application restrictions "
@@ -8801,9 +8798,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
"can broadcast update information.");
return;
}
+
+ if (!mOwners.saveSystemUpdateInfo(updateReceivedTime)) {
+ // Received time 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);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_SYSTEM_UPDATE_RECEIVED_TIME, updateReceivedTime);
final long ident = mInjector.binderClearCallingIdentity();
try {
@@ -8842,6 +8844,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
+ public SystemUpdateInfo getPendingSystemUpdate(ComponentName admin) {
+ Preconditions.checkNotNull(admin, "ComponentName is null");
+ enforceProfileOrDeviceOwner(admin);
+
+ return mOwners.getSystemUpdateInfo();
+ }
+
+ @Override
public void setPermissionPolicy(ComponentName admin, int policy) throws RemoteException {
int userId = UserHandle.getCallingUserId();
synchronized (this) {
@@ -9168,9 +9178,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean isManagedProfile(ComponentName admin) {
- synchronized (this) {
- getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- }
+ enforceProfileOrDeviceOwner(admin);
return isManagedProfile(mInjector.userHandleGetCallingUserId());
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index b53933e07f2b..99c76b169598 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -17,6 +17,7 @@
package com.android.server.devicepolicy;
import android.annotation.Nullable;
+import android.app.admin.SystemUpdateInfo;
import android.app.admin.SystemUpdatePolicy;
import android.content.ComponentName;
import android.content.pm.PackageManagerInternal;
@@ -47,13 +48,14 @@ import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import libcore.io.IoUtils;
/**
- * Stores and restores state for the Device and Profile owners. By definition there can be
- * only one device owner, but there may be a profile owner for each user.
+ * Stores and restores state for the Device and Profile owners and related device-wide information.
+ * By definition there can be only one device owner, but there may be a profile owner for each user.
*
* <p>This class is thread safe, so individual methods can safely be called without locking.
* However, caller must still synchronize on their side to ensure integrity between multiple calls.
@@ -65,6 +67,7 @@ class Owners {
private static final String DEVICE_OWNER_XML_LEGACY = "device_owner.xml";
+ // XML storing device owner info, system update policy and pending OTA update information.
private static final String DEVICE_OWNER_XML = "device_owner_2.xml";
private static final String PROFILE_OWNER_XML = "profile_owner.xml";
@@ -73,6 +76,8 @@ class Owners {
private static final String TAG_DEVICE_OWNER = "device-owner";
private static final String TAG_DEVICE_INITIALIZER = "device-initializer";
+ private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy";
+ private static final String TAG_PENDING_OTA_INFO = "pending-ota-info";
private static final String TAG_PROFILE_OWNER = "profile-owner";
// Holds "context" for device-owner, this must not be show up before device-owner.
private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context";
@@ -85,8 +90,6 @@ class Owners {
private static final String ATTR_USERID = "userId";
private static final String ATTR_USER_RESTRICTIONS_MIGRATED = "userRestrictionsMigrated";
- private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy";
-
private final UserManager mUserManager;
private final UserManagerInternal mUserManagerInternal;
private final PackageManagerInternal mPackageManagerInternal;
@@ -102,6 +105,10 @@ class Owners {
// Local system update policy controllable by device owner.
private SystemUpdatePolicy mSystemUpdatePolicy;
+ // Pending OTA info if there is one.
+ @Nullable
+ private SystemUpdateInfo mSystemUpdateInfo;
+
private final Object mLock = new Object();
public Owners(UserManager userManager,
@@ -468,6 +475,31 @@ class Owners {
}
}
+ /**
+ * @return Whether update received time has changed.
+ */
+ boolean saveSystemUpdateInfo(long receivedTime) {
+ final SystemUpdateInfo newSystemUpdateInfo = SystemUpdateInfo.of(receivedTime);
+ synchronized (mLock) {
+ // Check if we already have the same update information.
+ if (Objects.equals(newSystemUpdateInfo, mSystemUpdateInfo)) {
+ return false;
+ }
+
+ mSystemUpdateInfo = newSystemUpdateInfo;
+ new DeviceOwnerReadWriter().writeToFileLocked();
+
+ return true;
+ }
+ }
+
+ @Nullable
+ public SystemUpdateInfo getSystemUpdateInfo() {
+ synchronized (mLock) {
+ return mSystemUpdateInfo;
+ }
+ }
+
private abstract static class FileReadWriter {
private final File mFile;
@@ -573,7 +605,7 @@ class Owners {
}
}
} catch (XmlPullParserException | IOException e) {
- Slog.e(TAG, "Error parsing device-owner file", e);
+ Slog.e(TAG, "Error parsing owners information file", e);
} finally {
IoUtils.closeQuietly(input);
}
@@ -592,7 +624,8 @@ class Owners {
@Override
boolean shouldWrite() {
- return (mDeviceOwner != null) || (mSystemUpdatePolicy != null);
+ return (mDeviceOwner != null) || (mSystemUpdatePolicy != null)
+ || (mSystemUpdateInfo != null);
}
@Override
@@ -609,6 +642,10 @@ class Owners {
mSystemUpdatePolicy.saveToXml(out);
out.endTag(null, TAG_SYSTEM_UPDATE_POLICY);
}
+
+ if (mSystemUpdateInfo != null) {
+ mSystemUpdateInfo.writeToXml(out, TAG_PENDING_OTA_INFO);
+ }
}
@Override
@@ -637,6 +674,9 @@ class Owners {
case TAG_SYSTEM_UPDATE_POLICY:
mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
break;
+ case TAG_PENDING_OTA_INFO:
+ mSystemUpdateInfo = SystemUpdateInfo.readFromXml(parser);
+ break;
default:
Slog.e(TAG, "Unexpected tag: " + tag);
return false;
@@ -783,7 +823,6 @@ class Owners {
}
if (mSystemUpdatePolicy != null) {
if (needBlank) {
- needBlank = false;
pw.println();
}
pw.println(prefix + "System Update Policy: " + mSystemUpdatePolicy);
@@ -792,7 +831,6 @@ class Owners {
if (mProfileOwners != null) {
for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) {
if (needBlank) {
- needBlank = false;
pw.println();
}
pw.println(prefix + "Profile Owner (User " + entry.getKey() + "): ");
@@ -800,6 +838,13 @@ class Owners {
needBlank = true;
}
}
+ if (mSystemUpdateInfo != null) {
+ if (needBlank) {
+ pw.println();
+ }
+ pw.println(prefix + "Pending System Update: " + mSystemUpdateInfo);
+ needBlank = true;
+ }
}
File getLegacyConfigFileWithTestOverride() {