1/*
2 * Copyright (C) 2016 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
17package android.os;
18
19import android.annotation.SystemApi;
20import android.os.IUpdateEngine;
21import android.os.IUpdateEngineCallback;
22import android.os.RemoteException;
23
24import android.util.Log;
25
26/**
27 * UpdateEngine handles calls to the update engine which takes care of A/B OTA
28 * updates. It wraps up the update engine Binder APIs and exposes them as
29 * SystemApis, which will be called by system apps like GmsCore.
30 *
31 * The APIs defined in this class and UpdateEngineCallback class must be in
32 * sync with the ones in
33 * system/update_engine/binder_bindings/android/os/IUpdateEngine.aidl and
34 * system/update_engine/binder_bindings/android/os/IUpdateEngineCallback.aidl.
35 *
36 * {@hide}
37 */
38@SystemApi
39public class UpdateEngine {
40    private static final String TAG = "UpdateEngine";
41
42    private static final String UPDATE_ENGINE_SERVICE = "android.os.UpdateEngineService";
43
44    /**
45     * Error code from the update engine. Values must agree with the ones in
46     * system/update_engine/common/error_code.h.
47     */
48    @SystemApi
49    public static final class ErrorCodeConstants {
50        public static final int SUCCESS = 0;
51        public static final int ERROR = 1;
52        public static final int FILESYSTEM_COPIER_ERROR = 4;
53        public static final int POST_INSTALL_RUNNER_ERROR = 5;
54        public static final int PAYLOAD_MISMATCHED_TYPE_ERROR = 6;
55        public static final int INSTALL_DEVICE_OPEN_ERROR = 7;
56        public static final int KERNEL_DEVICE_OPEN_ERROR = 8;
57        public static final int DOWNLOAD_TRANSFER_ERROR = 9;
58        public static final int PAYLOAD_HASH_MISMATCH_ERROR = 10;
59        public static final int PAYLOAD_SIZE_MISMATCH_ERROR = 11;
60        public static final int DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 12;
61    }
62
63    /**
64     * Update status code from the update engine. Values must agree with the
65     * ones in system/update_engine/client_library/include/update_engine/update_status.h.
66     */
67    @SystemApi
68    public static final class UpdateStatusConstants {
69        public static final int IDLE = 0;
70        public static final int CHECKING_FOR_UPDATE = 1;
71        public static final int UPDATE_AVAILABLE = 2;
72        public static final int DOWNLOADING = 3;
73        public static final int VERIFYING = 4;
74        public static final int FINALIZING = 5;
75        public static final int UPDATED_NEED_REBOOT = 6;
76        public static final int REPORTING_ERROR_EVENT = 7;
77        public static final int ATTEMPTING_ROLLBACK = 8;
78        public static final int DISABLED = 9;
79    }
80
81    private IUpdateEngine mUpdateEngine;
82
83    @SystemApi
84    public UpdateEngine() {
85        mUpdateEngine = IUpdateEngine.Stub.asInterface(
86                ServiceManager.getService(UPDATE_ENGINE_SERVICE));
87    }
88
89    @SystemApi
90    public boolean bind(final UpdateEngineCallback callback, final Handler handler) {
91        IUpdateEngineCallback updateEngineCallback = new IUpdateEngineCallback.Stub() {
92            @Override
93            public void onStatusUpdate(final int status, final float percent) {
94                if (handler != null) {
95                    handler.post(new Runnable() {
96                        @Override
97                        public void run() {
98                            callback.onStatusUpdate(status, percent);
99                        }
100                    });
101                } else {
102                    callback.onStatusUpdate(status, percent);
103                }
104            }
105
106            @Override
107            public void onPayloadApplicationComplete(final int errorCode) {
108                if (handler != null) {
109                    handler.post(new Runnable() {
110                        @Override
111                        public void run() {
112                            callback.onPayloadApplicationComplete(errorCode);
113                        }
114                    });
115                } else {
116                    callback.onPayloadApplicationComplete(errorCode);
117                }
118            }
119        };
120
121        try {
122            return mUpdateEngine.bind(updateEngineCallback);
123        } catch (RemoteException e) {
124            throw e.rethrowFromSystemServer();
125        }
126    }
127
128    @SystemApi
129    public boolean bind(final UpdateEngineCallback callback) {
130        return bind(callback, null);
131    }
132
133    @SystemApi
134    public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) {
135        try {
136            mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs);
137        } catch (RemoteException e) {
138            throw e.rethrowFromSystemServer();
139        }
140    }
141
142    @SystemApi
143    public void cancel() {
144        try {
145            mUpdateEngine.cancel();
146        } catch (RemoteException e) {
147            throw e.rethrowFromSystemServer();
148        }
149    }
150
151    @SystemApi
152    public void suspend() {
153        try {
154            mUpdateEngine.suspend();
155        } catch (RemoteException e) {
156            throw e.rethrowFromSystemServer();
157        }
158    }
159
160    @SystemApi
161    public void resume() {
162        try {
163            mUpdateEngine.resume();
164        } catch (RemoteException e) {
165            throw e.rethrowFromSystemServer();
166        }
167    }
168
169    @SystemApi
170    public void resetStatus() {
171        try {
172            mUpdateEngine.resetStatus();
173        } catch (RemoteException e) {
174            throw e.rethrowFromSystemServer();
175        }
176    }
177}
178