1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import static com.android.internal.util.Preconditions.checkNotNull;
20 
21 import android.annotation.RequiresPermission;
22 import android.annotation.SystemApi;
23 import android.annotation.SystemService;
24 import android.content.Context;
25 
26 /**
27  * Allows querying and posting system update information.
28  *
29  * {@hide}
30  */
31 @SystemApi
32 @SystemService(Context.SYSTEM_UPDATE_SERVICE)
33 public class SystemUpdateManager {
34     private static final String TAG = "SystemUpdateManager";
35 
36     /** The status key of the system update info, expecting an int value. */
37     public static final String KEY_STATUS = "status";
38 
39     /** The title of the current update, expecting a String value. */
40     public static final String KEY_TITLE = "title";
41 
42     /** Whether it is a security update, expecting a boolean value. */
43     public static final String KEY_IS_SECURITY_UPDATE = "is_security_update";
44 
45     /** The build fingerprint after installing the current update, expecting a String value. */
46     public static final String KEY_TARGET_BUILD_FINGERPRINT = "target_build_fingerprint";
47 
48     /** The security patch level after installing the current update, expecting a String value. */
49     public static final String KEY_TARGET_SECURITY_PATCH_LEVEL = "target_security_patch_level";
50 
51     /**
52      * The KEY_STATUS value that indicates there's no update status info available.
53      */
54     public static final int STATUS_UNKNOWN = 0;
55 
56     /**
57      * The KEY_STATUS value that indicates there's no pending update.
58      */
59     public static final int STATUS_IDLE = 1;
60 
61     /**
62      * The KEY_STATUS value that indicates an update is available for download, but pending user
63      * approval to start.
64      */
65     public static final int STATUS_WAITING_DOWNLOAD = 2;
66 
67     /**
68      * The KEY_STATUS value that indicates an update is in progress (i.e. downloading or installing
69      * has started).
70      */
71     public static final int STATUS_IN_PROGRESS = 3;
72 
73     /**
74      * The KEY_STATUS value that indicates an update is available for install.
75      */
76     public static final int STATUS_WAITING_INSTALL = 4;
77 
78     /**
79      * The KEY_STATUS value that indicates an update will be installed after a reboot. This applies
80      * to both of A/B and non-A/B OTAs.
81      */
82     public static final int STATUS_WAITING_REBOOT = 5;
83 
84     private final ISystemUpdateManager mService;
85 
86     /** @hide */
SystemUpdateManager(ISystemUpdateManager service)87     public SystemUpdateManager(ISystemUpdateManager service) {
88         mService = checkNotNull(service, "missing ISystemUpdateManager");
89     }
90 
91     /**
92      * Queries the current pending system update info.
93      *
94      * <p>Requires the {@link android.Manifest.permission#READ_SYSTEM_UPDATE_INFO} or
95      * {@link android.Manifest.permission#RECOVERY} permission.
96      *
97      * @return A {@code Bundle} that contains the pending system update information in key-value
98      * pairs.
99      *
100      * @throws SecurityException if the caller is not allowed to read the info.
101      */
102     @RequiresPermission(anyOf = {
103             android.Manifest.permission.READ_SYSTEM_UPDATE_INFO,
104             android.Manifest.permission.RECOVERY,
105     })
retrieveSystemUpdateInfo()106     public Bundle retrieveSystemUpdateInfo() {
107         try {
108             return mService.retrieveSystemUpdateInfo();
109         } catch (RemoteException re) {
110             throw re.rethrowFromSystemServer();
111         }
112     }
113 
114     /**
115      * Allows a system updater to publish the pending update info.
116      *
117      * <p>The reported info will not persist across reboots. Because only the reporting updater
118      * understands the criteria to determine a successful/failed update.
119      *
120      * <p>Requires the {@link android.Manifest.permission#RECOVERY} permission.
121      *
122      * @param infoBundle The {@code PersistableBundle} that contains the system update information,
123      * such as the current update status. {@link #KEY_STATUS} is required in the bundle.
124      *
125      * @throws IllegalArgumentException if @link #KEY_STATUS} does not exist.
126      * @throws SecurityException if the caller is not allowed to update the info.
127      */
128     @RequiresPermission(android.Manifest.permission.RECOVERY)
updateSystemUpdateInfo(PersistableBundle infoBundle)129     public void updateSystemUpdateInfo(PersistableBundle infoBundle) {
130         if (infoBundle == null || !infoBundle.containsKey(KEY_STATUS)) {
131             throw new IllegalArgumentException("Missing status in the bundle");
132         }
133         try {
134             mService.updateSystemUpdateInfo(infoBundle);
135         } catch (RemoteException re) {
136             throw re.rethrowFromSystemServer();
137         }
138     }
139 }
140