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