blob: b08bfd0f64e947df27cbcddf75d6f3642e495469 [file] [log] [blame]
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -07001/*
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
17package com.example.android.systemupdatersample;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070022import org.json.JSONArray;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -070023import org.json.JSONException;
24import org.json.JSONObject;
25
26import java.io.File;
27import java.io.Serializable;
Zhomart Mukhamejanov6aa5fb02018-05-09 14:28:49 -070028import java.util.Optional;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -070029
30/**
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070031 * An update description. It will be parsed from JSON, which is intended to
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -070032 * be sent from server to the update app, but in this sample app it will be stored on the device.
33 */
34public class UpdateConfig implements Parcelable {
35
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070036 public static final int AB_INSTALL_TYPE_NON_STREAMING = 0;
37 public static final int AB_INSTALL_TYPE_STREAMING = 1;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -070038
39 public static final Parcelable.Creator<UpdateConfig> CREATOR =
40 new Parcelable.Creator<UpdateConfig>() {
41 @Override
42 public UpdateConfig createFromParcel(Parcel source) {
43 return new UpdateConfig(source);
44 }
45
46 @Override
47 public UpdateConfig[] newArray(int size) {
48 return new UpdateConfig[size];
49 }
50 };
51
52 /** parse update config from json */
53 public static UpdateConfig fromJson(String json) throws JSONException {
54 UpdateConfig c = new UpdateConfig();
55
56 JSONObject o = new JSONObject(json);
57 c.mName = o.getString("name");
58 c.mUrl = o.getString("url");
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070059 switch (o.getString("ab_install_type")) {
60 case AB_INSTALL_TYPE_NON_STREAMING_JSON:
61 c.mAbInstallType = AB_INSTALL_TYPE_NON_STREAMING;
62 break;
63 case AB_INSTALL_TYPE_STREAMING_JSON:
64 c.mAbInstallType = AB_INSTALL_TYPE_STREAMING;
65 break;
66 default:
67 throw new JSONException("Invalid type, expected either "
68 + "NON_STREAMING or STREAMING, got " + o.getString("ab_install_type"));
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -070069 }
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070070 if (c.mAbInstallType == AB_INSTALL_TYPE_STREAMING) {
71 JSONObject meta = o.getJSONObject("ab_streaming_metadata");
72 JSONArray propertyFilesJson = meta.getJSONArray("property_files");
Zhomart Mukhamejanov0dd5a832018-04-23 11:38:54 -070073 PackageFile[] propertyFiles =
74 new PackageFile[propertyFilesJson.length()];
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070075 for (int i = 0; i < propertyFilesJson.length(); i++) {
76 JSONObject p = propertyFilesJson.getJSONObject(i);
Zhomart Mukhamejanov0dd5a832018-04-23 11:38:54 -070077 propertyFiles[i] = new PackageFile(
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070078 p.getString("filename"),
79 p.getLong("offset"),
80 p.getLong("size"));
81 }
Zhomart Mukhamejanov6aa5fb02018-05-09 14:28:49 -070082 c.mAbStreamingMetadata = new StreamingMetadata(
83 propertyFiles,
84 meta.getString("authorization_token"));
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -070085 }
86 c.mRawJson = json;
87 return c;
88 }
89
90 /**
91 * these strings are represent types in JSON config files
92 */
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -070093 private static final String AB_INSTALL_TYPE_NON_STREAMING_JSON = "NON_STREAMING";
94 private static final String AB_INSTALL_TYPE_STREAMING_JSON = "STREAMING";
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -070095
96 /** name will be visible on UI */
97 private String mName;
98
99 /** update zip file URI, can be https:// or file:// */
100 private String mUrl;
101
102 /** non-streaming (first saves locally) OR streaming (on the fly) */
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700103 private int mAbInstallType;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700104
105 /** metadata is required only for streaming update */
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700106 private StreamingMetadata mAbStreamingMetadata;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700107
108 private String mRawJson;
109
110 protected UpdateConfig() {
111 }
112
113 protected UpdateConfig(Parcel in) {
114 this.mName = in.readString();
115 this.mUrl = in.readString();
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700116 this.mAbInstallType = in.readInt();
117 this.mAbStreamingMetadata = (StreamingMetadata) in.readSerializable();
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700118 this.mRawJson = in.readString();
119 }
120
121 public UpdateConfig(String name, String url, int installType) {
122 this.mName = name;
123 this.mUrl = url;
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700124 this.mAbInstallType = installType;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700125 }
126
127 public String getName() {
128 return mName;
129 }
130
131 public String getUrl() {
132 return mUrl;
133 }
134
135 public String getRawJson() {
136 return mRawJson;
137 }
138
139 public int getInstallType() {
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700140 return mAbInstallType;
141 }
142
143 public StreamingMetadata getStreamingMetadata() {
144 return mAbStreamingMetadata;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700145 }
146
147 /**
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700148 * @return File object for given url
149 */
150 public File getUpdatePackageFile() {
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700151 if (mAbInstallType != AB_INSTALL_TYPE_NON_STREAMING) {
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700152 throw new RuntimeException("Expected non-streaming install type");
153 }
154 if (!mUrl.startsWith("file://")) {
155 throw new RuntimeException("url is expected to start with file://");
156 }
157 return new File(mUrl.substring(7, mUrl.length()));
158 }
159
160 @Override
161 public int describeContents() {
162 return 0;
163 }
164
165 @Override
166 public void writeToParcel(Parcel dest, int flags) {
167 dest.writeString(mName);
168 dest.writeString(mUrl);
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700169 dest.writeInt(mAbInstallType);
170 dest.writeSerializable(mAbStreamingMetadata);
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700171 dest.writeString(mRawJson);
172 }
173
174 /**
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700175 * Metadata for streaming A/B update.
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700176 */
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700177 public static class StreamingMetadata implements Serializable {
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700178
179 private static final long serialVersionUID = 31042L;
180
181 /** defines beginning of update data in archive */
Zhomart Mukhamejanov0dd5a832018-04-23 11:38:54 -0700182 private PackageFile[] mPropertyFiles;
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700183
Zhomart Mukhamejanov6aa5fb02018-05-09 14:28:49 -0700184 /** SystemUpdaterSample receives the authorization token from the OTA server, in addition
185 * to the package URL. It passes on the info to update_engine, so that the latter can
186 * fetch the data from the package server directly with the token. */
187 private String mAuthorization;
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700188
Zhomart Mukhamejanov6aa5fb02018-05-09 14:28:49 -0700189 public StreamingMetadata(PackageFile[] propertyFiles, String authorization) {
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700190 this.mPropertyFiles = propertyFiles;
Zhomart Mukhamejanov6aa5fb02018-05-09 14:28:49 -0700191 this.mAuthorization = authorization;
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700192 }
193
Zhomart Mukhamejanov0dd5a832018-04-23 11:38:54 -0700194 public PackageFile[] getPropertyFiles() {
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700195 return mPropertyFiles;
196 }
Zhomart Mukhamejanov6aa5fb02018-05-09 14:28:49 -0700197
198 public Optional<String> getAuthorization() {
199 return Optional.of(mAuthorization);
200 }
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700201 }
202
203 /**
204 * Description of a file in an OTA package zip file.
205 */
Zhomart Mukhamejanov0dd5a832018-04-23 11:38:54 -0700206 public static class PackageFile implements Serializable {
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700207
208 private static final long serialVersionUID = 31043L;
209
210 /** filename in an archive */
211 private String mFilename;
212
213 /** defines beginning of update data in archive */
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700214 private long mOffset;
215
216 /** size of the update data in archive */
217 private long mSize;
218
Zhomart Mukhamejanov0dd5a832018-04-23 11:38:54 -0700219 public PackageFile(String filename, long offset, long size) {
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700220 this.mFilename = filename;
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700221 this.mOffset = offset;
222 this.mSize = size;
223 }
224
Zhomart Mukhamejanov963e3ee2018-04-26 21:07:05 -0700225 public String getFilename() {
226 return mFilename;
227 }
228
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700229 public long getOffset() {
230 return mOffset;
231 }
232
233 public long getSize() {
234 return mSize;
235 }
Zhomart Mukhamejanovf4d280c2018-04-17 13:20:22 -0700236 }
237
238}