本编将从两个方面分析客户端,原生测试模块update_engine_client和framwork层接口
一、update_engine_client
Android原生编译出了测试模块update_engine_client,在system/bin/下,我个人理解是与framekwork 层binder机制连接update_engine服务端是类似的,不过该模块增加了命令行测试的部分。
首先我们先根据android.mk看下大概依赖和文件,这就是我们先从android.mk开始的好处,大概知道了那些模块,需要看具体的再查看这个模块具体需要的内容
1LOCAL_C_INCLUDES += \ 2 external/cros/system_api/dbus 3LOCAL_SHARED_LIBRARIES += \ 共享库依赖 4 libbinder \ 5 libbinderwrapper \ 6 libbrillo-binder \ 7 libutils 8LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder_bindings aid文件 9LOCAL_SRC_FILES := \ 具体文件 10 binder_bindings/android/os/IUpdateEngine.aidl \ 11 binder_bindings/android/os/IUpdateEngineCallback.aidl \ 12 common/error_code_utils.cc \ 13 update_engine_client_android.cc \ 14 update_status_utils.cc
分析可执行程序先从main方法入手
1update_engine_client_android.cc 2 3int main(int argc, char** argv) { 4 //创建UpdateEngineClientAndroid 的对象client,并传入接收的参数 5 chromeos_update_engine::internal::UpdateEngineClientAndroid client( 6 argc, argv); 7 //返回client的run方法 8 return client.Run(); 9}
UpdateEngineClientAndroid类的初始化
1//UpdateEngineClientAndroid 继承了brillo 的Daemon类 2class UpdateEngineClientAndroid : public brillo::Daemon { 3 public: 4 //根据main传入的argc argv变为私有的成员变量argc_ argv_ 5 UpdateEngineClientAndroid(int argc, char** argv) : argc_(argc), argv_(argv) { 6 } 7 //定义退出方法传入不同的参数 8 int ExitWhenIdle(const Status& status); 9 int ExitWhenIdle(int return_code); 10 11 private: 12 class UECallback : public android::os::BnUpdateEngineCallback { 13 public: 14 //C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 15 //而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的, 16 //类构造函数默认情况下即声明为implicit(隐式). 17 explicit UECallback(UpdateEngineClientAndroid* client) : client_(client) {} 18 19 // android::os::BnUpdateEngineCallback overrides. 20 //重写callback的两个方法,监听升级状态和是否升级成功 21 Status onStatusUpdate(int status_code, float progress) override; 22 Status onPayloadApplicationComplete(int error_code) override; 23 24 //客户端指针 25 private: 26 UpdateEngineClientAndroid* client_; 27 }; 28 //重写父类的init方法 29 int OnInit() override; 30 31 // Called whenever the UpdateEngine daemon dies. 32 // 每当UpdateEngine守护程序终止时调用。 33 void UpdateEngineServiceDied(); 34 35 // Copy of argc and argv passed to main(). 36 // 拷贝从main方法传入的参数,也就是UpdateEngineClientAndroid的成员变量 37 int argc_; 38 char** argv_; 39 40 //IUpdateEngine 指针service_ 41 android::sp<android::os::IUpdateEngine> service_; 42 //BnUpdateEngineCallback 指针callback_ 43 android::sp<android::os::BnUpdateEngineCallback> callback_; 44 45 brillo::BinderWatcher binder_watcher_; 46};
client.Run()方法
因为update_engine_client_android.cc中没有定义该方法,执行父类Daemon的run方法
1external/libbrillo/brillo/daemons/daemon.cc 2int Daemon::Run() { 3 //执行onint方法,获得返回值exit_code 4 int exit_code = OnInit(); 5 if (exit_code != EX_OK) 6 return exit_code; 7 //开启消息处理循环 8 message_loop_.Run(); 9 //空方法,不用管 10 OnShutdown(&exit_code_); 11 12 // base::RunLoop::QuitClosure() causes the message loop to quit 13 // immediately, even if pending tasks are still queued. 14 // Run a secondary loop to make sure all those are processed. 15 // This becomes important when working with D-Bus since dbus::Bus does 16 // a bunch of clean-up tasks asynchronously when shutting down. 17 //base :: RunLoop :: QuitClosure()导致消息循环退出 即使待处理的任务仍在排队,也要立即运行。 18 //运行辅助循环以确保所有这些任务都得到处理。这在使用D-Bus时非常重要, 19 //因为dbus :: Bus在关闭时会异步执行大量清理任务。 20 //等待消息退出 21 while (message_loop_.RunOnce(false /* may_block */)) {} 22 //返回onint结果exit_code 23 return exit_code_; 24}
父类Daemon::OnInit()方法
1external/libbrillo/brillo/daemons/daemon.cc 2 3int Daemon::OnInit() { 4 async_signal_handler_.Init(); 5 for (int signal : {SIGTERM, SIGINT}) { 6 //RegisterHandler注册信号SIGINT 7 async_signal_handler_.RegisterHandler( 8 signal, base::Bind(&Daemon::Shutdown, base::Unretained(this))); 9 } 10 //RegisterHandler注册信号SIGHUP 11 async_signal_handler_.RegisterHandler( 12 SIGHUP, base::Bind(&Daemon::Restart, base::Unretained(this))); 13 //返回EX_OK; 14 return EX_OK; 15}
Daemon的子类UpdateEngineClientAndroid重写了Oninit方法,先调用子类的方法
1update_engine_client_android.cc 2 3int UpdateEngineClientAndroid::OnInit() { 4 //调用父类Daemon::OnInit()方法获得返回值 5 int ret = Daemon::OnInit(); 6 if (ret != EX_OK) 7 return ret; 8 //以下这些是跟命令行参数有关的 9 //定义update参数 “如果没有正在进行的更新,则开始新的更新。” 10 DEFINE_bool(update, false, "Start a new update, if no update in progress."); 11 //定义payload参数 升级使用的payload地址 12 DEFINE_string(payload, 13 "http://127.0.0.1:8080/payload", 14 "The URI to the update payload to use."); 15 //定义offset参数,调用服务端applyPayload包含该参数 16 DEFINE_int64(offset, 0, 17 "The offset in the payload where the CrAU update starts. " 18 "Used when --update is passed."); 19 //定义size参数,调用服务端applyPayload包含该参数 20 DEFINE_int64(size, 0, 21 "The size of the CrAU part of the payload. If 0 is passed, it " 22 "will be autodetected. Used when --update is passed."); 23 //定义headers参数,调用服务端applyPayload包含该参数 24 DEFINE_string(headers, 25 "", 26 "A list of key-value pairs, one element of the list per line. " 27 "Used when --update is passed."); 28 //定义suspend参数 “暂停正在进行的更新并退出。” 29 DEFINE_bool(suspend, false, "Suspend an ongoing update and exit."); 30 //定义resume参数 恢复暂停的更新。 31 DEFINE_bool(resume, false, "Resume a suspended update."); 32 //定义cancel参数 取消正在进行的更新并退出。 33 DEFINE_bool(cancel, false, "Cancel the ongoing update and exit."); 34 //定义reset_status参数 重置已应用的更新并退出 35 DEFINE_bool(reset_status, false, "Reset an already applied update and exit."); 36 //定义follow参数 37 //“跟随状态更新将更改,直到达到最终状态为止。” “如果更新成功,则退出状态为0,否则为1。 38 DEFINE_bool(follow, 39 false, 40 "Follow status update changes until a final state is reached. " 41 "Exit status is 0 if the update succeeded, and 1 otherwise."); 42 43 // Boilerplate init commands.解析命令行参数 44 base::CommandLine::Init(argc_, argv_); 45 //解析argc_,argv_的参数,首行打印"Android Update Engine Client" 46 brillo::FlagHelper::Init(argc_, argv_, "Android Update Engine Client"); 47 //如果没有参数输入,直接打印Nothing to do. Run with --help for help. 48 if (argc_ == 1) { 49 LOG(ERROR) << "Nothing to do. Run with --help for help."; 50 return 1; 51 } 52 53 // Ensure there are no positional arguments.确保没有位置参数。 54 const std::vector<std::string> positional_args = 55 base::CommandLine::ForCurrentProcess()->GetArgs(); 56 if (!positional_args.empty()) { 57 LOG(ERROR) << "Found a positional argument '" << positional_args.front() 58 << "'. If you want to pass a value to a flag, pass it as " 59 "--flag=value."; 60 return 1; 61 } 62 63 bool keep_running = false; 64 //初始化log 65 brillo::InitLog(brillo::kLogToStderr); 66 67 // Initialize a binder watcher early in the process before any interaction 68 // with the binder driver. 69 //binder_watcher初始化 在进行任何交互之前,在流程的早期初始化绑定监视程序 70 binder_watcher_.Init(); 71 //获取服务端android.os.UpdateEngineService的服务,存储在service_,使用service_ 72 //调用服务端相应的方法 73 android::status_t status = android::getService( 74 android::String16("android.os.UpdateEngineService"), &service_); 75 //如果获取服务失败,打印错误Failed to get IUpdateEngine binder from service manager 76 if (status != android::OK) { 77 LOG(ERROR) << "Failed to get IUpdateEngine binder from service manager: " 78 << Status::fromStatusT(status).toString8(); 79 return ExitWhenIdle(1); 80 } 81 //以下是根据参数 调用相应服务端的方法 82 //调用服务的suspend方法 83 if (FLAGS_suspend) { 84 return ExitWhenIdle(service_->suspend()); 85 } 86 //调用服务的resume方法 87 if (FLAGS_resume) { 88 return ExitWhenIdle(service_->resume()); 89 } 90 //调用服务的cancel方法 91 if (FLAGS_cancel) { 92 return ExitWhenIdle(service_->cancel()); 93 } 94 //调用服务的resetStatus方法 95 if (FLAGS_reset_status) { 96 return ExitWhenIdle(service_->resetStatus()); 97 } 98 //注册回调函数UECallback到服务端service_ 99 if (FLAGS_follow) { 100 // Register a callback object with the service. 101 callback_ = new UECallback(this); 102 bool bound; 103 if (!service_->bind(callback_, &bound).isOk() || !bound) { 104 LOG(ERROR) << "Failed to bind() the UpdateEngine daemon."; 105 return 1; 106 } 107 keep_running = true; 108 } 109 //参数为update,调用服务applyPayload方法,传入对应的参数 110 if (FLAGS_update) { 111 //将header以空格\n进行分割放入string类型的容器中 112 std::vector<std::string> headers = base::SplitString( 113 FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); 114 //声明and_headers string类型的容器 115 std::vector<android::String16> and_headers; 116 //通过push_back方法以键值对的方式放入到and_headers中 117 for (const auto& header : headers) { 118 and_headers.push_back(android::String16{header.data(), header.size()}); 119 } 120 //将praload offset size and_headers 参数传入服务端的applyPayload方法进行升级 121 Status status = service_->applyPayload( 122 android::String16{FLAGS_payload.data(), FLAGS_payload.size()}, 123 FLAGS_offset, 124 FLAGS_size, 125 and_headers); 126 //如果升级失败,调用ExitWhenIdle传入status退出 127 if (!status.isOk()) 128 return ExitWhenIdle(status); 129 } 130 //我对这个标志位不是很理解,意思相当于如果keep_running不为真,那么编译完成了并退出? 131 if (!keep_running) 132 return ExitWhenIdle(EX_OK); 133 134 // When following updates status changes, exit if the update_engine daemon 135 // dies.//当更新状态发生变化时,如果update_engine守护程序退出死亡。 136 //如果服务端进程终止了,相应的也会停止客户端进程 137 android::BinderWrapper::Create(); 138 android::BinderWrapper::Get()->RegisterForDeathNotifications( 139 android::os::IUpdateEngine::asBinder(service_), 140 base::Bind(&UpdateEngineClientAndroid::UpdateEngineServiceDied, 141 base::Unretained(this))); 142 143 return EX_OK; 144}
UpdateEngineServiceDied方法
1update_engine_client_android.cc 2 3//如果服务挂了,停止客户端并退出 4void UpdateEngineClientAndroid::UpdateEngineServiceDied() { 5 LOG(ERROR) << "UpdateEngineService died."; 6 QuitWithExitCode(1); 7}
这就是update_engine_client的大致代码流程
二、framwork层 应用接口
首先应用方面要处理的借口和回调方法:
1、在app中设置一个callback,用来接收update_engine 升级状态和完成的通知
源代码位置:framwork/base/core/java/android/os/UpdateEngine.java
继承UpdateEngineCallback 重写onStatusUpdate 和 onPayloadApplicationComplete 方法
onStatusUpdate方法用于获取升级的状态比如升级的百分比或者错误
onPayloadApplicationComplete被调用当升级完整或者返回错误状态的时候
完成的列表或者错误的在./system/update_engine/common/error_code.h
2、app应用调取applyUpdate方法
pubic void applyPayload(String url,long offset,long size,String[] headerKeyValuePairs)
url:升级包(Payload)的路径,ab升级只能使用内置存储,必须在目录 /data/ota_package/xxx 而且需要以file://开头,比如file://data/ota_package/update.zip
update engine只接受固定的路径/data/ota_package/update.zip,其他路径和sdcard不支持
app需要获取se权限区操作使用这个路径:
allow your_app ota_package_file:dir { read open write create remove_name search rename add_name getattr };
allow your_app ota_otapackage_file:file{ read write create open rename getattr unlink };
offset:这是payload 在update.zip中的偏移量,需要从升级包文件中计算出来
Size:这是payload文件的大小,可以在payload_properties.txt中找到
headerKeyValuePairs:这是metadata,可以在升级包中的payload_properties.txt中找到,
headerKeyValuePairs参数 时用来传输metadata数据给update_engine服务端,存储在payload_properties.txt,通过脚本system/update_engine/scripts/brillo_update_payload
生成,数据格式如下:
String[] pairs = {
"FILE_HASH=f1KT8nZAvNCx7hesGI0xaqVm9CIWzQvXGfg2T2Cp+ME=",
"FILE_SIZE=781070526",
"METADATA_HASH=lMosFzUjtB1ODkiSTw4xgNt6WkYuGV70GzTkdNTtlMU=",
"METADATA_SIZE=89254"
};
我们先看下framwork 层对应的代码内容
./framwork/base/core/java/android/os/UpdateEngineCallback.java
1/** 2 * Callback function for UpdateEngine. Used to keep the caller up to date 3 * with progress, so the UI (if any) can be updated. 4 * 5 * The APIs defined in this class and UpdateEngine class must be in sync with 6 * the ones in 7 * system/update_engine/binder_bindings/android/os/IUpdateEngine.aidl and 8 * system/update_engine/binder_bindings/android/os/IUpdateEngineCallback.aidl. 9 * 10 * {@hide} 11 */ 12@SystemApi 13// UpdateEngine的回调函数。 用户调用app保持最新状态进度,因此可以更新UI,这是抽象函数 14// app需要继承UpdateEngineCallback,并重写其中的方法 15public abstract class UpdateEngineCallback { 16 17 /** 18 * Invoked when anything changes. The value of {@code status} will 19 * be one of the values from {@link UpdateEngine.UpdateStatusConstants}, 20 * and {@code percent} will be valid [TODO: in which cases?]. 21 */ 22 @SystemApi//监听升级状态 23 public abstract void onStatusUpdate(int status, float percent); 24 25 /** 26 * Invoked when the payload has been applied, whether successfully or 27 * unsuccessfully. The value of {@code errorCode} will be one of the 28 * values from {@link UpdateEngine.ErrorCodeConstants}. 29 */ 30 @SystemApi//监听升级结果 31 public abstract void onPayloadApplicationComplete(int errorCode); 32}
./framwork/base/core/java/android/os/UpdateEngine.java
1@SystemApi 2public class UpdateEngine { 3 //定义文件log的tag 4 private static final String TAG = "UpdateEngine"; 5 //定义update_engine service的名称 6 private static final String UPDATE_ENGINE_SERVICE = "android.os.UpdateEngineService"; 7 8 /** 9 * Error code from the update engine. Values must agree with the ones in 10 * system/update_engine/common/error_code.h. 11 */ 12 @SystemApi //升级结果常量,这些值于服务端的errorcode相同 13 public static final class ErrorCodeConstants { 14 public static final int SUCCESS = 0; 15 public static final int ERROR = 1; 16 public static final int FILESYSTEM_COPIER_ERROR = 4; 17 public static final int POST_INSTALL_RUNNER_ERROR = 5; 18 public static final int PAYLOAD_MISMATCHED_TYPE_ERROR = 6; 19 public static final int INSTALL_DEVICE_OPEN_ERROR = 7; 20 public static final int KERNEL_DEVICE_OPEN_ERROR = 8; 21 public static final int DOWNLOAD_TRANSFER_ERROR = 9; 22 public static final int PAYLOAD_HASH_MISMATCH_ERROR = 10; 23 public static final int PAYLOAD_SIZE_MISMATCH_ERROR = 11; 24 public static final int DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 12; 25 public static final int UPDATED_BUT_NOT_ACTIVE = 52; 26 } 27 28 /** 29 * Update status code from the update engine. Values must agree with the 30 * ones in system/update_engine/client_library/include/update_engine/update_status.h. 31 */ 32 @SystemApi //升级进度常量,这些值于服务端的UpdateStatu相同 33 public static final class UpdateStatusConstants { 34 public static final int IDLE = 0; 35 public static final int CHECKING_FOR_UPDATE = 1; 36 public static final int UPDATE_AVAILABLE = 2; 37 public static final int DOWNLOADING = 3; 38 public static final int VERIFYING = 4; 39 public static final int FINALIZING = 5; 40 public static final int UPDATED_NEED_REBOOT = 6; 41 public static final int REPORTING_ERROR_EVENT = 7; 42 public static final int ATTEMPTING_ROLLBACK = 8; 43 public static final int DISABLED = 9; 44 } 45 46 private IUpdateEngine mUpdateEngine; 47 private IUpdateEngineCallback mUpdateEngineCallback = null; 48 private final Object mUpdateEngineCallbackLock = new Object(); 49 50 /** 51 * Creates a new instance.当我们new 一个UpdateEngine对象时,service也被创建出来 52 */ 53 @SystemApi 54 public UpdateEngine() { 55 mUpdateEngine = IUpdateEngine.Stub.asInterface( 56 ServiceManager.getService(UPDATE_ENGINE_SERVICE)); 57 } 58 59 /** 60 * Prepares this instance for use. The callback will be notified on any 61 * status change, and when the update completes. A handler can be supplied 62 * to control which thread runs the callback, or null. 63 */ 64 @SystemApi 65 public boolean bind(final UpdateEngineCallback callback, final Handler handler) { 66 synchronized (mUpdateEngineCallbackLock) { 67 mUpdateEngineCallback = new IUpdateEngineCallback.Stub() { 68 @Override 69 public void onStatusUpdate(final int status, final float percent) { 70 if (handler != null) { 71 handler.post(new Runnable() { 72 @Override 73 public void run() { 74 callback.onStatusUpdate(status, percent); 75 } 76 }); 77 } else { 78 callback.onStatusUpdate(status, percent); 79 } 80 } 81 82 @Override 83 public void onPayloadApplicationComplete(final int errorCode) { 84 if (handler != null) { 85 handler.post(new Runnable() { 86 @Override 87 public void run() { 88 callback.onPayloadApplicationComplete(errorCode); 89 } 90 }); 91 } else { 92 callback.onPayloadApplicationComplete(errorCode); 93 } 94 } 95 }; 96 97 try { 98 //绑定mUpdateEngineCallback到服务端 99 return mUpdateEngine.bind(mUpdateEngineCallback); 100 } catch (RemoteException e) { 101 throw e.rethrowFromSystemServer(); 102 } 103 } 104 } 105 106 /** 107 * Equivalent to {@code bind(callback, null)}. 108 */ 109 @SystemApi //第三方应用调取 用户绑定服务 110 public boolean bind(final UpdateEngineCallback callback) { 111 return bind(callback, null); 112 } 113 114 /** 115 * Applies the payload found at the given {@code url}. For non-streaming 116 * updates, the URL can be a local file using the {@code file://} scheme. 117 * 118 * <p>The {@code offset} and {@code size} parameters specify the location 119 * of the payload within the file represented by the URL. This is useful 120 * if the downloadable package at the URL contains more than just the 121 * update_engine payload (such as extra metadata). This is true for 122 * Google's OTA system, where the URL points to a zip file in which the 123 * payload is stored uncompressed within the zip file alongside other 124 * data. 125 * 126 * <p>The {@code headerKeyValuePairs} parameter is used to pass metadata 127 * to update_engine. In Google's implementation, this is stored as 128 * {@code payload_properties.txt} in the zip file. It's generated by the 129 * script {@code system/update_engine/scripts/brillo_update_payload}. 130 * The complete list of keys and their documentation is in 131 * {@code system/update_engine/common/constants.cc}, but an example 132 * might be: 133 * <pre> 134 * String[] pairs = { 135 * "FILE_HASH=lURPCIkIAjtMOyB/EjQcl8zDzqtD6Ta3tJef6G/+z2k=", 136 * "FILE_SIZE=871903868", 137 * "METADATA_HASH=tBvj43QOB0Jn++JojcpVdbRLz0qdAuL+uTkSy7hokaw=", 138 * "METADATA_SIZE=70604" 139 * }; 140 * </pre> 141 */ 142 @SystemApi 具体执行升级的接口 143 public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) { 144 try { 145 //调用服务端的applyPayload方法执行升级 146 mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs); 147 } catch (RemoteException e) { 148 throw e.rethrowFromSystemServer(); 149 } 150 } 151 152 /** 153 * Permanently cancels an in-progress update. 154 * 155 * <p>See {@link #resetStatus} to undo a finshed update (only available 156 * before the updated system has been rebooted). 157 * 158 * <p>See {@link #suspend} for a way to temporarily stop an in-progress 159 * update with the ability to resume it later. 160 */ 161 @SystemApi //调用服务端cancel方法 162 public void cancel() { 163 try { 164 mUpdateEngine.cancel(); 165 } catch (RemoteException e) { 166 throw e.rethrowFromSystemServer(); 167 } 168 } 169 170 /** 171 * Suspends an in-progress update. This can be undone by calling 172 * {@link #resume}. 173 */ 174 @SystemApi //调用服务端suspend方法 175 public void suspend() { 176 try { 177 mUpdateEngine.suspend(); 178 } catch (RemoteException e) { 179 throw e.rethrowFromSystemServer(); 180 } 181 } 182 183 /** 184 * Resumes a suspended update. 185 */ 186 @SystemApi //调用服务端resume方法 187 public void resume() { 188 try { 189 mUpdateEngine.resume(); 190 } catch (RemoteException e) { 191 throw e.rethrowFromSystemServer(); 192 } 193 } 194 195 /** 196 * Resets the bootable flag on the non-current partition and all internal 197 * update_engine state. This can be used after an unwanted payload has been 198 * successfully applied and the device has not yet been rebooted to signal 199 * that we no longer want to boot into that updated system. After this call 200 * completes, update_engine will no longer report 201 * {@code UPDATED_NEED_REBOOT}, so your callback can remove any outstanding 202 * notification that rebooting into the new system is possible. 203 */ 204 @SystemApi //调用服务端resetStatus方法 205 public void resetStatus() { 206 try { 207 mUpdateEngine.resetStatus(); 208 } catch (RemoteException e) { 209 throw e.rethrowFromSystemServer(); 210 } 211 } 212 213 /** 214 * Unbinds the last bound callback function. 215 */ 216 @SystemApi //解除绑定callback的监听 217 public boolean unbind() { 218 synchronized (mUpdateEngineCallbackLock) { 219 if (mUpdateEngineCallback == null) { 220 return true; 221 } 222 try { 223 boolean result = mUpdateEngine.unbind(mUpdateEngineCallback); 224 mUpdateEngineCallback = null; 225 return result; 226 } catch (RemoteException e) { 227 throw e.rethrowFromSystemServer(); 228 } 229 } 230 } 231 232 /** 233 * Verifies that a payload associated with the given payload metadata 234 * {@code payloadMetadataFilename} can be safely applied to ths device. 235 * Returns {@code true} if the update can successfully be applied and 236 * returns {@code false} otherwise. 237 * 238 * @param payloadMetadataFilename the location of the metadata without the 239 * {@code file://} prefix. 240 */ 241 @SystemApi //校验Payload的元数据 242 public boolean verifyPayloadMetadata(String payloadMetadataFilename) { 243 try { 244 return mUpdateEngine.verifyPayloadApplicable(payloadMetadataFilename); 245 } catch (RemoteException e) { 246 throw e.rethrowFromSystemServer(); 247 } 248 } 249}
看完这两两个文件的代码,相信android的小伙伴都知道该怎么处理了,我这里只说一下大致流程
1、创建类abtest继承UpdateEngineCallback
2、创建UpdateEngine的对象mUpdateEngine,创建后服务开启
3、使用mUpdateEngine.bind(abtest) 因为bind方法时接受的callback对象,而我们创建的类继承了callback,传入当前类的对象即可
4、调用applyPayload方法具体执行升级
5、在重写的onStatusUpdate(int status, float percent)方法中根据拿到的状态执行进度逻辑
在重写的onPayloadApplicationComplete(int errorCode);方法中执行升级完成后的逻辑
两种情况其实相差不大,都是绑定监听,调用服务端相同的方法进行升级,好了,如果把AB升级理解为一栋别墅,我们现在已经开启了院子的大门,里面放了一个update_engine等待我们去拜访,后面将分析这个最重要的模块