blob: 999d986628284e903747d1eba1b4a8994a7075ab [file] [log] [blame]
Mårten Kongstadeabc9e92015-12-15 16:40:23 +01001/*
2 * Copyright (C) 2015 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.content.om;
18
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010019import android.annotation.IntDef;
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010020import android.annotation.NonNull;
Hyunyoung Song880a9512018-12-20 11:24:48 -080021import android.annotation.SystemApi;
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010022import android.os.Parcel;
23import android.os.Parcelable;
24
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010025import java.lang.annotation.Retention;
26import java.lang.annotation.RetentionPolicy;
27
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010028/**
29 * Immutable overlay information about a package. All PackageInfos that
30 * represent an overlay package will have a corresponding OverlayInfo.
31 *
32 * @hide
33 */
Hyunyoung Song880a9512018-12-20 11:24:48 -080034@SystemApi
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010035public final class OverlayInfo implements Parcelable {
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010036
Hyunyoung Song880a9512018-12-20 11:24:48 -080037 /** @hide */
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010038 @IntDef(prefix = "STATE_", value = {
39 STATE_UNKNOWN,
40 STATE_MISSING_TARGET,
41 STATE_NO_IDMAP,
42 STATE_DISABLED,
43 STATE_ENABLED,
Mårten Kongstada525e222018-04-10 16:57:33 +020044 STATE_ENABLED_STATIC,
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010045 STATE_TARGET_UPGRADING,
46 STATE_OVERLAY_UPGRADING,
47 })
Hyunyoung Song880a9512018-12-20 11:24:48 -080048 /** @hide */
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010049 @Retention(RetentionPolicy.SOURCE)
50 public @interface State {}
51
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010052 /**
53 * An internal state used as the initial state of an overlay. OverlayInfo
54 * objects exposed outside the {@link
55 * com.android.server.om.OverlayManagerService} should never have this
56 * state.
Hyunyoung Song880a9512018-12-20 11:24:48 -080057 *
58 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010059 */
60 public static final int STATE_UNKNOWN = -1;
61
62 /**
63 * The target package of the overlay is not installed. The overlay cannot be enabled.
Hyunyoung Song880a9512018-12-20 11:24:48 -080064 *
65 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010066 */
67 public static final int STATE_MISSING_TARGET = 0;
68
69 /**
70 * Creation of idmap file failed (e.g. no matching resources). The overlay
71 * cannot be enabled.
Hyunyoung Song880a9512018-12-20 11:24:48 -080072 *
73 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010074 */
75 public static final int STATE_NO_IDMAP = 1;
76
77 /**
78 * The overlay is currently disabled. It can be enabled.
79 *
Adrian Roosc84df772018-01-19 21:20:22 +010080 * @see IOverlayManager#setEnabled
Hyunyoung Song880a9512018-12-20 11:24:48 -080081 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010082 */
83 public static final int STATE_DISABLED = 2;
84
85 /**
86 * The overlay is currently enabled. It can be disabled.
87 *
Adrian Roosc84df772018-01-19 21:20:22 +010088 * @see IOverlayManager#setEnabled
Hyunyoung Song880a9512018-12-20 11:24:48 -080089 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +010090 */
91 public static final int STATE_ENABLED = 3;
92
93 /**
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010094 * The target package is currently being upgraded; the state will change
95 * once the package installation has finished.
Hyunyoung Song880a9512018-12-20 11:24:48 -080096 * @hide
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +010097 */
98 public static final int STATE_TARGET_UPGRADING = 4;
99
100 /**
101 * The overlay package is currently being upgraded; the state will change
102 * once the package installation has finished.
Hyunyoung Song880a9512018-12-20 11:24:48 -0800103 * @hide
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +0100104 */
105 public static final int STATE_OVERLAY_UPGRADING = 5;
106
107 /**
Mårten Kongstada525e222018-04-10 16:57:33 +0200108 * The overlay package is currently enabled because it is marked as
109 * 'static'. It cannot be disabled but will change state if for instance
110 * its target is uninstalled.
Hyunyoung Song880a9512018-12-20 11:24:48 -0800111 * @hide
Mårten Kongstada525e222018-04-10 16:57:33 +0200112 */
113 public static final int STATE_ENABLED_STATIC = 6;
114
115 /**
116 * Overlay category: theme.
117 * <p>
118 * Change how Android (including the status bar, dialogs, ...) looks.
Hyunyoung Song880a9512018-12-20 11:24:48 -0800119 *
120 * @hide
Adrian Roosc84df772018-01-19 21:20:22 +0100121 */
122 public static final String CATEGORY_THEME = "android.theme";
123
124 /**
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100125 * Package name of the overlay package
Hyunyoung Song880a9512018-12-20 11:24:48 -0800126 *
127 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100128 */
Hyunyoung Song880a9512018-12-20 11:24:48 -0800129 @SystemApi
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100130 public final String packageName;
131
132 /**
133 * Package name of the target package
Hyunyoung Song880a9512018-12-20 11:24:48 -0800134 *
135 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100136 */
Hyunyoung Song880a9512018-12-20 11:24:48 -0800137 @SystemApi
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100138 public final String targetPackageName;
139
140 /**
Adrian Roosc84df772018-01-19 21:20:22 +0100141 * Category of the overlay package
Hyunyoung Song880a9512018-12-20 11:24:48 -0800142 *
143 * @hide
Adrian Roosc84df772018-01-19 21:20:22 +0100144 */
Hyunyoung Song880a9512018-12-20 11:24:48 -0800145 @SystemApi
Adrian Roosc84df772018-01-19 21:20:22 +0100146 public final String category;
147
148 /**
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100149 * Full path to the base APK for this overlay package
Hyunyoung Song880a9512018-12-20 11:24:48 -0800150 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100151 */
152 public final String baseCodePath;
153
154 /**
155 * The state of this OverlayInfo as defined by the STATE_* constants in this class.
Hyunyoung Song880a9512018-12-20 11:24:48 -0800156 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100157 */
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +0100158 public final @State int state;
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100159
160 /**
161 * User handle for which this overlay applies
Hyunyoung Song880a9512018-12-20 11:24:48 -0800162 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100163 */
Hyunyoung Song880a9512018-12-20 11:24:48 -0800164 @SystemApi
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100165 public final int userId;
166
167 /**
Mårten Kongstad2f1944b2018-04-10 17:44:42 +0200168 * Priority as read from the manifest. Used if isStatic is true. Not
169 * intended to be exposed to 3rd party.
170 *
171 * @hide
172 */
173 public final int priority;
174
175 /**
176 * isStatic as read from the manifest. If true, the overlay is
177 * unconditionally loaded and cannot be unloaded. Not intended to be
178 * exposed to 3rd party.
179 *
180 * @hide
181 */
182 public final boolean isStatic;
183
184 /**
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100185 * Create a new OverlayInfo based on source with an updated state.
186 *
187 * @param source the source OverlayInfo to base the new instance on
188 * @param state the new state for the source OverlayInfo
Hyunyoung Song880a9512018-12-20 11:24:48 -0800189 *
190 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100191 */
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +0100192 public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
Adrian Roosc84df772018-01-19 21:20:22 +0100193 this(source.packageName, source.targetPackageName, source.category, source.baseCodePath,
Mårten Kongstad2f1944b2018-04-10 17:44:42 +0200194 state, source.userId, source.priority, source.isStatic);
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100195 }
196
Hyunyoung Song880a9512018-12-20 11:24:48 -0800197 /** @hide */
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100198 public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
Mårten Kongstad2f1944b2018-04-10 17:44:42 +0200199 @NonNull String category, @NonNull String baseCodePath, int state, int userId,
200 int priority, boolean isStatic) {
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100201 this.packageName = packageName;
202 this.targetPackageName = targetPackageName;
Adrian Roosc84df772018-01-19 21:20:22 +0100203 this.category = category;
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100204 this.baseCodePath = baseCodePath;
205 this.state = state;
206 this.userId = userId;
Mårten Kongstad2f1944b2018-04-10 17:44:42 +0200207 this.priority = priority;
208 this.isStatic = isStatic;
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100209 ensureValidState();
210 }
211
Hyunyoung Song880a9512018-12-20 11:24:48 -0800212 /** @hide */
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100213 public OverlayInfo(Parcel source) {
214 packageName = source.readString();
215 targetPackageName = source.readString();
Adrian Roosc84df772018-01-19 21:20:22 +0100216 category = source.readString();
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100217 baseCodePath = source.readString();
218 state = source.readInt();
219 userId = source.readInt();
Mårten Kongstad2f1944b2018-04-10 17:44:42 +0200220 priority = source.readInt();
221 isStatic = source.readBoolean();
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100222 ensureValidState();
223 }
224
225 private void ensureValidState() {
226 if (packageName == null) {
227 throw new IllegalArgumentException("packageName must not be null");
228 }
229 if (targetPackageName == null) {
230 throw new IllegalArgumentException("targetPackageName must not be null");
231 }
232 if (baseCodePath == null) {
233 throw new IllegalArgumentException("baseCodePath must not be null");
234 }
235 switch (state) {
236 case STATE_UNKNOWN:
237 case STATE_MISSING_TARGET:
238 case STATE_NO_IDMAP:
239 case STATE_DISABLED:
240 case STATE_ENABLED:
Mårten Kongstada525e222018-04-10 16:57:33 +0200241 case STATE_ENABLED_STATIC:
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +0100242 case STATE_TARGET_UPGRADING:
243 case STATE_OVERLAY_UPGRADING:
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100244 break;
245 default:
246 throw new IllegalArgumentException("State " + state + " is not a valid state");
247 }
248 }
249
250 @Override
251 public int describeContents() {
252 return 0;
253 }
254
255 @Override
256 public void writeToParcel(Parcel dest, int flags) {
257 dest.writeString(packageName);
258 dest.writeString(targetPackageName);
Adrian Roosc84df772018-01-19 21:20:22 +0100259 dest.writeString(category);
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100260 dest.writeString(baseCodePath);
261 dest.writeInt(state);
262 dest.writeInt(userId);
Mårten Kongstad2f1944b2018-04-10 17:44:42 +0200263 dest.writeInt(priority);
264 dest.writeBoolean(isStatic);
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100265 }
266
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700267 public static final @android.annotation.NonNull Parcelable.Creator<OverlayInfo> CREATOR =
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +0100268 new Parcelable.Creator<OverlayInfo>() {
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100269 @Override
270 public OverlayInfo createFromParcel(Parcel source) {
271 return new OverlayInfo(source);
272 }
273
274 @Override
275 public OverlayInfo[] newArray(int size) {
276 return new OverlayInfo[size];
277 }
278 };
279
280 /**
281 * Return true if this overlay is enabled, i.e. should be used to overlay
282 * the resources in the target package.
283 *
284 * Disabled overlay packages are installed but are currently not in use.
285 *
286 * @return true if the overlay is enabled, else false.
Hyunyoung Song880a9512018-12-20 11:24:48 -0800287 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100288 */
Hyunyoung Song880a9512018-12-20 11:24:48 -0800289 @SystemApi
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100290 public boolean isEnabled() {
291 switch (state) {
292 case STATE_ENABLED:
Mårten Kongstada525e222018-04-10 16:57:33 +0200293 case STATE_ENABLED_STATIC:
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100294 return true;
295 default:
296 return false;
297 }
298 }
299
300 /**
301 * Translate a state to a human readable string. Only intended for
302 * debugging purposes.
303 *
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100304 * @return a human readable String representing the state.
Hyunyoung Song880a9512018-12-20 11:24:48 -0800305 * @hide
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100306 */
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +0100307 public static String stateToString(@State int state) {
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100308 switch (state) {
309 case STATE_UNKNOWN:
310 return "STATE_UNKNOWN";
311 case STATE_MISSING_TARGET:
312 return "STATE_MISSING_TARGET";
313 case STATE_NO_IDMAP:
314 return "STATE_NO_IDMAP";
315 case STATE_DISABLED:
316 return "STATE_DISABLED";
317 case STATE_ENABLED:
318 return "STATE_ENABLED";
Mårten Kongstada525e222018-04-10 16:57:33 +0200319 case STATE_ENABLED_STATIC:
320 return "STATE_ENABLED_STATIC";
Mårten Kongstaddb0e34e2018-01-10 12:05:26 +0100321 case STATE_TARGET_UPGRADING:
322 return "STATE_TARGET_UPGRADING";
323 case STATE_OVERLAY_UPGRADING:
324 return "STATE_OVERLAY_UPGRADING";
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100325 default:
326 return "<unknown state>";
327 }
328 }
329
330 @Override
331 public int hashCode() {
332 final int prime = 31;
333 int result = 1;
334 result = prime * result + userId;
335 result = prime * result + state;
336 result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
337 result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode());
Mårten Kongstad3e933112018-04-09 14:29:36 +0200338 result = prime * result + ((category == null) ? 0 : category.hashCode());
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100339 result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode());
340 return result;
341 }
342
343 @Override
344 public boolean equals(Object obj) {
345 if (this == obj) {
346 return true;
347 }
348 if (obj == null) {
349 return false;
350 }
351 if (getClass() != obj.getClass()) {
352 return false;
353 }
354 OverlayInfo other = (OverlayInfo) obj;
355 if (userId != other.userId) {
356 return false;
357 }
358 if (state != other.state) {
359 return false;
360 }
361 if (!packageName.equals(other.packageName)) {
362 return false;
363 }
364 if (!targetPackageName.equals(other.targetPackageName)) {
365 return false;
366 }
Adrian Roosc84df772018-01-19 21:20:22 +0100367 if (!category.equals(other.category)) {
368 return false;
369 }
Mårten Kongstadeabc9e92015-12-15 16:40:23 +0100370 if (!baseCodePath.equals(other.baseCodePath)) {
371 return false;
372 }
373 return true;
374 }
375
376 @Override
377 public String toString() {
378 return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state="
379 + state + " (" + stateToString(state) + "), userId=" + userId + " }";
380 }
381}