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     @SystemApi
38     public static final String KEY_STATUS = "status";
39 
40     /** The title of the current update, expecting a String value. */
41     @SystemApi
42     public static final String KEY_TITLE = "title";
43 
44     /** Whether it is a security update, expecting a boolean value. */
45     @SystemApi
46     public static final String KEY_IS_SECURITY_UPDATE = "is_security_update";
47 
48     /** The build fingerprint after installing the current update, expecting a String value. */
49     @SystemApi
50     public static final String KEY_TARGET_BUILD_FINGERPRINT = "target_build_fingerprint";
51 
52     /** The security patch level after installing the current update, expecting a String value. */
53     @SystemApi
54     public static final String KEY_TARGET_SECURITY_PATCH_LEVEL = "target_security_patch_level";
55 
56     /**
57      * The KEY_STATUS value that indicates there's no update status info available.
58      */
59     @SystemApi
60     public static final int STATUS_UNKNOWN = 0;
61 
62     /**
63      * The KEY_STATUS value that indicates there's no pending update.
64      */
65     @SystemApi
66     public static final int STATUS_IDLE = 1;
67 
68     /**
69      * The KEY_STATUS value that indicates an update is available for download, but pending user
70      * approval to start.
71      */
72     @SystemApi
73     public static final int STATUS_WAITING_DOWNLOAD = 2;
74 
75     /**
76      * The KEY_STATUS value that indicates an update is in progress (i.e. downloading or installing
77      * has started).
78      */
79     @SystemApi
80     public static final int STATUS_IN_PROGRESS = 3;
81 
82     /**
83      * The KEY_STATUS value that indicates an update is available for install.
84      */
85     @SystemApi
86     public static final int STATUS_WAITING_INSTALL = 4;
87 
88     /**
89      * The KEY_STATUS value that indicates an update will be installed after a reboot. This applies
90      * to both of A/B and non-A/B OTAs.
91      */
92     @SystemApi
93     public static final int STATUS_WAITING_REBOOT = 5;
94 
95     private final ISystemUpdateManager mService;
96 
97     /** @hide */
SystemUpdateManager(ISystemUpdateManager service)98     public SystemUpdateManager(ISystemUpdateManager service) {
99         mService = checkNotNull(service, "missing ISystemUpdateManager");
100     }
101 
102     /**
103      * Queries the current pending system update info.
104      *
105      * <p>Requires the {@link android.Manifest.permission#READ_SYSTEM_UPDATE_INFO} or
106      * {@link android.Manifest.permission#RECOVERY} permission.
107      *
108      * @return A {@code Bundle} that contains the pending system update information in key-value
109      * pairs.
110      *
111      * @throws SecurityException if the caller is not allowed to read the info.
112      */
113     @SystemApi
114     @RequiresPermission(anyOf = {
115             android.Manifest.permission.READ_SYSTEM_UPDATE_INFO,
116             android.Manifest.permission.RECOVERY,
117     })
retrieveSystemUpdateInfo()118     public Bundle retrieveSystemUpdateInfo() {
119         try {
120             return mService.retrieveSystemUpdateInfo();
121         } catch (RemoteException re) {
122             throw re.rethrowFromSystemServer();
123         }
124     }
125 
126     /**
127      * Allows a system updater to publish the pending update info.
128      *
129      * <p>The reported info will not persist across reboots. Because only the reporting updater
130      * understands the criteria to determine a successful/failed update.
131      *
132      * <p>Requires the {@link android.Manifest.permission#RECOVERY} permission.
133      *
134      * @param infoBundle The {@code PersistableBundle} that contains the system update information,
135      * such as the current update status. {@link #KEY_STATUS} is required in the bundle.
136      *
137      * @throws IllegalArgumentException if @link #KEY_STATUS} does not exist.
138      * @throws SecurityException if the caller is not allowed to update the info.
139      */
140     @SystemApi
141     @RequiresPermission(android.Manifest.permission.RECOVERY)
updateSystemUpdateInfo(PersistableBundle infoBundle)142     public void updateSystemUpdateInfo(PersistableBundle infoBundle) {
143         if (infoBundle == null || !infoBundle.containsKey(KEY_STATUS)) {
144             throw new IllegalArgumentException("Missing status in the bundle");
145         }
146         try {
147             mService.updateSystemUpdateInfo(infoBundle);
148         } catch (RemoteException re) {
149             throw re.rethrowFromSystemServer();
150         }
151     }
152 }
153