1 /*
2  * Copyright (C) 2021 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.content.om;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.FabricatedOverlayInternal;
22 import android.os.FabricatedOverlayInternalEntry;
23 import android.text.TextUtils;
24 
25 import com.android.internal.util.Preconditions;
26 
27 import java.util.ArrayList;
28 
29 /**
30  * Fabricated Runtime Resource Overlays (FRROs) are overlays generated ar runtime.
31  *
32  * Fabricated overlays are enabled, disabled, and reordered just like normal overlays. The
33  * overlayable policies a fabricated overlay fulfills are the same policies the creator of the
34  * overlay fulfill. For example, a fabricated overlay created by a platform signed package on the
35  * system partition would fulfil the {@code system} and {@code signature} policies.
36  *
37  * The owner of a fabricated overlay is the UID that created it. Overlays commit to the overlay
38  * manager persist across reboots. When the UID is uninstalled, its fabricated overlays are wiped.
39  *
40  * Processes with {@link Android.Manifest.permission.CHANGE_OVERLAY_PACKAGES} can manage normal
41  * overlays and fabricated overlays.
42  * @hide
43  */
44 public class FabricatedOverlay {
45 
46     /** Retrieves the identifier for this fabricated overlay. */
getIdentifier()47     public OverlayIdentifier getIdentifier() {
48         return new OverlayIdentifier(
49                 mOverlay.packageName, TextUtils.nullIfEmpty(mOverlay.overlayName));
50     }
51 
52     public static class Builder {
53         private final String mOwningPackage;
54         private final String mName;
55         private final String mTargetPackage;
56         private String mTargetOverlayable = "";
57         private final ArrayList<FabricatedOverlayInternalEntry> mEntries = new ArrayList<>();
58 
59         /**
60          * Constructs a build for a fabricated overlay.
61          *
62          * @param owningPackage the name of the package that owns the fabricated overlay (must
63          *                      be a package name of this UID).
64          * @param name a name used to uniquely identify the fabricated overlay owned by
65          *             {@param owningPackageName}
66          * @param targetPackage the name of the package to overlay
67          */
Builder(@onNull String owningPackage, @NonNull String name, @NonNull String targetPackage)68         public Builder(@NonNull String owningPackage, @NonNull String name,
69                 @NonNull String targetPackage) {
70             Preconditions.checkStringNotEmpty(owningPackage,
71                     "'owningPackage' must not be empty nor null");
72             Preconditions.checkStringNotEmpty(name,
73                     "'name'' must not be empty nor null");
74             Preconditions.checkStringNotEmpty(targetPackage,
75                     "'targetPackage' must not be empty nor null");
76 
77             mOwningPackage = owningPackage;
78             mName = name;
79             mTargetPackage = targetPackage;
80         }
81 
82         /**
83          * Sets the name of the overlayable resources to overlay (can be null).
84          */
setTargetOverlayable(@ullable String targetOverlayable)85         public Builder setTargetOverlayable(@Nullable String targetOverlayable) {
86             mTargetOverlayable = TextUtils.emptyIfNull(targetOverlayable);
87             return this;
88         }
89 
90         /**
91          * Sets the value of
92          *
93          * @param resourceName name of the target resource to overlay (in the form
94          *                     [package]:type/entry)
95          * @param dataType the data type of the new value
96          * @param value the unsigned 32 bit integer representing the new value
97          *
98          * @see android.util.TypedValue#type
99          */
setResourceValue(@onNull String resourceName, int dataType, int value)100         public Builder setResourceValue(@NonNull String resourceName, int dataType, int value) {
101             final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
102             entry.resourceName = resourceName;
103             entry.dataType = dataType;
104             entry.data = value;
105             mEntries.add(entry);
106             return this;
107         }
108 
109         /** Builds an immutable fabricated overlay. */
build()110         public FabricatedOverlay build() {
111             final FabricatedOverlayInternal overlay = new FabricatedOverlayInternal();
112             overlay.packageName = mOwningPackage;
113             overlay.overlayName = mName;
114             overlay.targetPackageName = mTargetPackage;
115             overlay.targetOverlayable = mTargetOverlayable;
116             overlay.entries = new ArrayList<>();
117             overlay.entries.addAll(mEntries);
118             return new FabricatedOverlay(overlay);
119         }
120     }
121 
122     final FabricatedOverlayInternal mOverlay;
FabricatedOverlay(FabricatedOverlayInternal overlay)123     private FabricatedOverlay(FabricatedOverlayInternal overlay) {
124         mOverlay = overlay;
125     }
126 }
127