1eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad/* 2eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Copyright (C) 2016 The Android Open Source Project 3eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 4eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Licensed under the Apache License, Version 2.0 (the "License"); 5eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * you may not use this file except in compliance with the License. 6eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * You may obtain a copy of the License at 7eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 8eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * http://www.apache.org/licenses/LICENSE-2.0 9eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 10eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Unless required by applicable law or agreed to in writing, software 11eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * distributed under the License is distributed on an "AS IS" BASIS, 12eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * See the License for the specific language governing permissions and 14eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * limitations under the License. 15eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */ 16eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 17eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadpackage com.android.server.om; 18eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 19eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_DISABLED; 20eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_ENABLED; 21a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_ENABLED_STATIC; 22eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_MISSING_TARGET; 23eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_NO_IDMAP; 24db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstadimport static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING; 25db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstadimport static android.content.om.OverlayInfo.STATE_TARGET_UPGRADING; 26eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 27eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.DEBUG; 28eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.TAG; 29eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 30eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.NonNull; 31eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.Nullable; 32eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.om.OverlayInfo; 33eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.pm.PackageInfo; 34a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinskiimport android.text.TextUtils; 35eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArrayMap; 36eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArraySet; 37eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.Slog; 38eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 39eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.io.PrintWriter; 40eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.ArrayList; 41eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Iterator; 42eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.List; 43eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Map; 44607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamathimport java.util.Objects; 45eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Set; 46eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 47eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad/** 48eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Internal implementation of OverlayManagerService. 49eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 50eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Methods in this class should only be called by the OverlayManagerService. 51eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * This class is not thread-safe; the caller is expected to ensure the 52eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * necessary thread synchronization. 53eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 54eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * @see OverlayManagerService 55eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */ 56eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadfinal class OverlayManagerServiceImpl { 57db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad // Flags to use in conjunction with updateState. 58db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad private static final int FLAG_TARGET_IS_UPGRADING = 1<<0; 59db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad private static final int FLAG_OVERLAY_IS_UPGRADING = 1<<1; 60db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 61eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private final PackageManagerHelper mPackageManager; 62eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private final IdmapManager mIdmapManager; 63eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private final OverlayManagerSettings mSettings; 647b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski private final String[] mDefaultOverlays; 65c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private final OverlayChangeListener mListener; 66eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 672f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad /** 682f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * Helper method to merge the overlay manager's (as read from overlays.xml) 692f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * and package manager's (as parsed from AndroidManifest.xml files) views 702f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * on overlays. 712f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * 722f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * Both managers are usually in agreement, but especially after an OTA things 732f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * may differ. The package manager is always providing the truth; the overlay 742f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * manager has to adapt. Depending on what has changed about an overlay, we 752f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * should either scrap the overlay manager's previous settings or merge the old 762f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad * settings with the new. 772f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad */ 782f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad private static boolean mustReinitializeOverlay(@NonNull final PackageInfo theTruth, 792f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad @Nullable final OverlayInfo oldSettings) { 802f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (oldSettings == null) { 812f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad return true; 822f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 832f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) { 842f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad return true; 852f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 862f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) { 872f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad return true; 882f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 892f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // a change in priority is only relevant for static RROs: specifically, 902f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // a regular RRO should not have its state reset only because a change 912f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // in priority 922f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (theTruth.isStaticOverlayPackage() && 932f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad theTruth.overlayPriority != oldSettings.priority) { 942f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad return true; 952f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 962f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad return false; 972f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 982f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad 99eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager, 100eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final IdmapManager idmapManager, 101a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski @NonNull final OverlayManagerSettings settings, 1027b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski @NonNull final String[] defaultOverlays, 103c745f42169df6687a764e48b65878f22965c1530Adam Lesinski @NonNull final OverlayChangeListener listener) { 104eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager = packageManager; 105eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager = idmapManager; 106eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings = settings; 107a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski mDefaultOverlays = defaultOverlays; 108c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener = listener; 109eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 110eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 111ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski /** 112ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski * Call this to synchronize the Settings for a user with what PackageManager knows about a user. 113ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski * Returns a list of target packages that must refresh their overlays. This list is the union 114eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * of two sets: the set of targets with currently active overlays, and the 115eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * set of targets that had, but no longer have, active overlays. 116eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */ 117ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski ArrayList<String> updateOverlaysForUser(final int newUserId) { 118eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 119ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski Slog.d(TAG, "updateOverlaysForUser newUserId=" + newUserId); 120eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 121eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 122eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final Set<String> packagesToUpdateAssets = new ArraySet<>(); 123eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final ArrayMap<String, List<OverlayInfo>> tmp = mSettings.getOverlaysForUser(newUserId); 124eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int tmpSize = tmp.size(); 125eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final ArrayMap<String, OverlayInfo> storedOverlayInfos = new ArrayMap<>(tmpSize); 126eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < tmpSize; i++) { 127eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> chunk = tmp.valueAt(i); 128eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int chunkSize = chunk.size(); 129eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int j = 0; j < chunkSize; j++) { 130eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = chunk.get(j); 131eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad storedOverlayInfos.put(oi.packageName, oi); 132eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 133eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 134eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 1352f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // Reset overlays if something critical like the target package name 1362f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // has changed 137eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId); 138eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int overlayPackagesSize = overlayPackages.size(); 139eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < overlayPackagesSize; i++) { 140eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = overlayPackages.get(i); 141eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName); 1422f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad 1432f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (mustReinitializeOverlay(overlayPackage, oi)) { 1442f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // if targetPackageName has changed the package that *used* to 1452f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // be the target must also update its assets 1462f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (oi != null) { 1472f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad packagesToUpdateAssets.add(oi.targetPackageName); 1482f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 1492f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad 150eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.init(overlayPackage.packageName, newUserId, 151eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.overlayTarget, 15242d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.applicationInfo.getBaseCodePath(), 1537b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski overlayPackage.isStaticOverlayPackage(), 1547b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski overlayPackage.overlayPriority, 155c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos overlayPackage.overlayCategory); 156eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 157eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 158eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad storedOverlayInfos.remove(overlayPackage.packageName); 159eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 160eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 161eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // any OverlayInfo left in storedOverlayInfos is no longer 162eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // installed and should be removed 163eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int storedOverlayInfosSize = storedOverlayInfos.size(); 164eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < storedOverlayInfosSize; i++) { 165c0bba8b18b41356721c2ebb25af83bc5bb5a74b0Mårten Kongstad final OverlayInfo oi = storedOverlayInfos.valueAt(i); 166eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(oi.packageName, oi.userId); 167eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad removeIdmapIfPossible(oi); 168eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packagesToUpdateAssets.add(oi.targetPackageName); 169eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 170eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 1712f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // make sure every overlay's state is up-to-date; this needs to happen 1722f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // after old overlays have been removed, or we risk removing a 1732f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // legitimate idmap file if a new overlay package has the same apk path 1742f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad // as the removed overlay package used to have 1752f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad for (int i = 0; i < overlayPackagesSize; i++) { 1762f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad final PackageInfo overlayPackage = overlayPackages.get(i); 1772f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad try { 1782f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad updateState(overlayPackage.overlayTarget, overlayPackage.packageName, 1792f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad newUserId, 0); 1802f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 1812f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 1822f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad mSettings.remove(overlayPackage.packageName, newUserId); 1832f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 1842f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad packagesToUpdateAssets.add(overlayPackage.overlayTarget); 1852f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 1862f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad 187eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // remove target packages that are not installed 188eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final Iterator<String> iter = packagesToUpdateAssets.iterator(); 189eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad while (iter.hasNext()) { 190eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad String targetPackageName = iter.next(); 191eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (mPackageManager.getPackageInfo(targetPackageName, newUserId) == null) { 192eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad iter.remove(); 193eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 194eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 1957b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski 1967b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski // Collect all of the categories in which we have at least one overlay enabled. 1977b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski final ArraySet<String> enabledCategories = new ArraySet<>(); 1987b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski final ArrayMap<String, List<OverlayInfo>> userOverlays = 1997b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski mSettings.getOverlaysForUser(newUserId); 2007b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski final int userOverlayTargetCount = userOverlays.size(); 2017b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski for (int i = 0; i < userOverlayTargetCount; i++) { 2027b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski final List<OverlayInfo> overlayList = userOverlays.valueAt(i); 2037b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski final int overlayCount = overlayList != null ? overlayList.size() : 0; 2047b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski for (int j = 0; j < overlayCount; j++) { 2057b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski final OverlayInfo oi = overlayList.get(j); 2067b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski if (oi.isEnabled()) { 2077b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski enabledCategories.add(oi.category); 2087b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } 2097b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } 2107b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } 2117b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski 2127b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski // Enable the default overlay if its category does not have a single overlay enabled. 2137b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski for (final String defaultOverlay : mDefaultOverlays) { 2147b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski try { 2157b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski final OverlayInfo oi = mSettings.getOverlayInfo(defaultOverlay, newUserId); 2167b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski if (!enabledCategories.contains(oi.category)) { 2177b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski Slog.w(TAG, "Enabling default overlay '" + defaultOverlay + "' for target '" 2187b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski + oi.targetPackageName + "' in category '" + oi.category + "' for user " 2197b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski + newUserId); 2207b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski mSettings.setEnabled(oi.packageName, newUserId, true); 2217b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski if (updateState(oi.targetPackageName, oi.packageName, newUserId, 0)) { 2227b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski packagesToUpdateAssets.add(oi.targetPackageName); 2237b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } 2247b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } 2257b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } catch (OverlayManagerSettings.BadKeyException e) { 2267b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski Slog.e(TAG, "Failed to set default overlay '" + defaultOverlay + "' for user " 2277b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski + newUserId, e); 2287b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } 2297b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski } 2307b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski 231a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski return new ArrayList<>(packagesToUpdateAssets); 232eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 233eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 234eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onUserRemoved(final int userId) { 235eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 236eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onUserRemoved userId=" + userId); 237eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 238eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.removeUser(userId); 239eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 240eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 241eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageAdded(@NonNull final String packageName, final int userId) { 242eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 243eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId); 244eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 245eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 246497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad if (updateAllOverlaysForTarget(packageName, userId, 0)) { 247497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(packageName, userId); 248497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad } 249eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 250eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 251d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell void onTargetPackageChanged(@NonNull final String packageName, final int userId) { 252d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell if (DEBUG) { 253d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId); 254d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell } 255d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell 256d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell updateAllOverlaysForTarget(packageName, userId, 0); 257d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell } 258d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell 259eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) { 260eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 261db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" 262db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad + userId); 263eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 264eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 265d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING); 266eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 267eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 268eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) { 269eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 270eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId); 271eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 272eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 273d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell updateAllOverlaysForTarget(packageName, userId, 0); 274eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 275eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 276eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageRemoved(@NonNull final String packageName, final int userId) { 277eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 278eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId); 279eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 280eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 281497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad if (updateAllOverlaysForTarget(packageName, userId, 0)) { 282497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(packageName, userId); 283497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad } 284eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 285eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 286c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 287a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad * Update the state of any overlays for this target. 288a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad * 289a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad * Returns true if the system should refresh the app's overlay paths (i.e. 290a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad * if the settings were modified for this target, or there is at least one 291a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad * enabled framework overlay). 292c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 293497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName, 294db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final int userId, final int flags) { 295497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad boolean modified = false; 296db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(targetPackageName, userId); 297eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = ois.size(); 298eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 299eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = ois.get(i); 300db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName, 301db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad userId); 302eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 303497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad modified |= mSettings.remove(oi.packageName, oi.userId); 304eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad removeIdmapIfPossible(oi); 305eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } else { 306eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 307497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad modified |= updateState(targetPackageName, oi.packageName, userId, flags); 308eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 309eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 310497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad modified |= mSettings.remove(oi.packageName, userId); 311eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 312eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 313eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 314a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad 315a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad // check for enabled framework overlays 316a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad modified = modified || !getEnabledOverlayPackageNames("android", userId).isEmpty(); 317a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad 318497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad return modified; 319eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 320eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 321eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageAdded(@NonNull final String packageName, final int userId) { 322eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 323eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId); 324eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 325eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 326eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 327eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 328eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found"); 329eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad onOverlayPackageRemoved(packageName, userId); 330eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 331eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 332eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 333eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.init(packageName, userId, overlayPackage.overlayTarget, 334ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski overlayPackage.applicationInfo.getBaseCodePath(), 335c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, 336c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos overlayPackage.overlayCategory); 337eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 338db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (updateState(overlayPackage.overlayTarget, packageName, userId, 0)) { 339497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 340c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 341eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 342eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 343eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(packageName, userId); 344eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 345eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 346eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 347eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageChanged(@NonNull final String packageName, final int userId) { 348db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (DEBUG) { 349db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.d(TAG, "onOverlayPackageChanged packageName=" + packageName + " userId=" + userId); 350db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 351db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 352db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad try { 353db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 354db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (updateState(oi.targetPackageName, packageName, userId, 0)) { 355497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(oi.targetPackageName, userId); 356db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 357db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 358db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.e(TAG, "failed to update settings", e); 359db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 360eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 361eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 362eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) { 363db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (DEBUG) { 364db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.d(TAG, "onOverlayPackageUpgrading packageName=" + packageName + " userId=" 365db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad + userId); 366db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 367db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 368db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad try { 369db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 370db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (updateState(oi.targetPackageName, packageName, userId, FLAG_OVERLAY_IS_UPGRADING)) { 371db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad removeIdmapIfPossible(oi); 372497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(oi.targetPackageName, userId); 373db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 374db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 375db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.e(TAG, "failed to update settings", e); 376db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 377eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 378eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 379eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) { 380db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (DEBUG) { 381db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.d(TAG, "onOverlayPackageUpgraded packageName=" + packageName + " userId=" 382db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad + userId); 383db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 384db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 385db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final PackageInfo pkg = mPackageManager.getPackageInfo(packageName, userId); 386db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (pkg == null) { 387db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.w(TAG, "overlay package " + packageName + " was upgraded, but couldn't be found"); 388db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad onOverlayPackageRemoved(packageName, userId); 389db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad return; 390db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 391db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 392db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad try { 393db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId); 3942f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (mustReinitializeOverlay(pkg, oldOi)) { 3952f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) { 3962f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad mListener.onOverlaysChanged(pkg.overlayTarget, userId); 3972f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad } 398db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad mSettings.init(packageName, userId, pkg.overlayTarget, 399db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(), 400c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos pkg.overlayPriority, pkg.overlayCategory); 401db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 402db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 403db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (updateState(pkg.overlayTarget, packageName, userId, 0)) { 404497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(pkg.overlayTarget, userId); 405db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 406db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 407db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad Slog.e(TAG, "failed to update settings", e); 408db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 409eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 410eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 411eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) { 412b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski try { 413b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski final OverlayInfo overlayInfo = mSettings.getOverlayInfo(packageName, userId); 414b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski if (mSettings.remove(packageName, userId)) { 415b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski removeIdmapIfPossible(overlayInfo); 416b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski if (overlayInfo.isEnabled()) { 417b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski // Only trigger updates if the overlay was enabled. 418497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId); 419b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski } 420b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski } 421b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski } catch (OverlayManagerSettings.BadKeyException e) { 422b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski Slog.e(TAG, "failed to remove overlay", e); 423b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski } 424eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 425eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 426eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) { 427eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 428eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlayInfo(packageName, userId); 429eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 430eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return null; 431eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 432eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 433eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 434eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName, 435eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 436eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForTarget(targetPackageName, userId); 437eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 438eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 439eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) { 440eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForUser(userId); 441eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 442eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 443eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setEnabled(@NonNull final String packageName, final boolean enable, 444eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 445eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 446eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d", 447eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packageName, enable, userId)); 448eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 449eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 450eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 451eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 452eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 453eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 454c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 455c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Ignore static overlays. 456ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski if (overlayPackage.isStaticOverlayPackage()) { 4570434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 4580434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 459eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 460eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 461eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 462c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = mSettings.setEnabled(packageName, userId, enable); 463db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad modified |= updateState(oi.targetPackageName, oi.packageName, userId, 0); 464c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 465c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 466497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(oi.targetPackageName, userId); 467c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 468929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return true; 469929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } catch (OverlayManagerSettings.BadKeyException e) { 470929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 471929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 472929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 473929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 474c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos boolean setEnabledExclusive(@NonNull final String packageName, boolean withinCategory, 475c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos final int userId) { 476929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (DEBUG) { 477c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos Slog.d(TAG, String.format("setEnabledExclusive packageName=%s" 478c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos + " withinCategory=%s userId=%d", packageName, withinCategory, userId)); 479929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 480929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 481929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 482929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (overlayPackage == null) { 483929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 484929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 485929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 486929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk try { 487929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 488db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final String targetPackageName = oi.targetPackageName; 489c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 490db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad List<OverlayInfo> allOverlays = getOverlayInfosForTarget(targetPackageName, userId); 491929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 492c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = false; 493c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 494929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk // Disable all other overlays. 495929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk allOverlays.remove(oi); 496929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk for (int i = 0; i < allOverlays.size(); i++) { 497c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final String disabledOverlayPackageName = allOverlays.get(i).packageName; 498c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo( 499c745f42169df6687a764e48b65878f22965c1530Adam Lesinski disabledOverlayPackageName, userId); 500c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (disabledOverlayPackageInfo == null) { 501c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(disabledOverlayPackageName, userId); 502c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 503c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 504c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 505ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski if (disabledOverlayPackageInfo.isStaticOverlayPackage()) { 506c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Don't touch static overlays. 507c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 508c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 509607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamath if (withinCategory && !Objects.equals(disabledOverlayPackageInfo.overlayCategory, 510c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos oi.category)) { 511c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos // Don't touch overlays from other categories. 512c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos continue; 513c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos } 514c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 515c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Disable the overlay. 516c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false); 517db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad modified |= updateState(targetPackageName, disabledOverlayPackageName, userId, 0); 518929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 519929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 520c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Enable the selected overlay. 521c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(packageName, userId, true); 522db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad modified |= updateState(targetPackageName, packageName, userId, 0); 523c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 524c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 525497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(targetPackageName, userId); 526c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 527eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return true; 528eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 529eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 530eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 531eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 532eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 533c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) { 5340434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 535ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski if (overlayPackage == null || overlayPackage.isStaticOverlayPackage()) { 5360434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 5370434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 5380434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return true; 5390434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 5400434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok 541eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setPriority(@NonNull final String packageName, 542eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final String newParentPackageName, final int userId) { 543c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 544c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName=" 545c745f42169df6687a764e48b65878f22965c1530Adam Lesinski + newParentPackageName + " userId=" + userId); 546c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 547c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 548c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 549c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 550c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 551c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 552c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 553c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 554c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 555c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 556c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 557c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setPriority(packageName, newParentPackageName, userId)) { 558497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 559c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 560c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 561eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 562eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 563eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setHighestPriority(@NonNull final String packageName, final int userId) { 564c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 565c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId); 566c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 567c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 568c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 569c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 570c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 571c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 572c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 573c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 574c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 575c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 576c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 577c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setHighestPriority(packageName, userId)) { 578497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 579c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 580c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 581eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 582eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 583eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setLowestPriority(@NonNull final String packageName, final int userId) { 584c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 585c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId); 586c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 587c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 588c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 589c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 590c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 591c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 592c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 593c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 594c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 595c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 596c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 597c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setLowestPriority(packageName, userId)) { 598497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 599c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 600c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 601eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 602eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 603eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onDump(@NonNull final PrintWriter pw) { 604eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.dump(pw); 605a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays)); 606eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 607eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 608eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName, 609eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 610db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName, 611db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad userId); 612eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<String> paths = new ArrayList<>(overlays.size()); 613eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = overlays.size(); 614eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 615eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = overlays.get(i); 616eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (oi.isEnabled()) { 617eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad paths.add(oi.packageName); 618eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 619eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 620eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return paths; 621eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 622eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 623c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 624c745f42169df6687a764e48b65878f22965c1530Adam Lesinski * Returns true if the settings/state was modified, false otherwise. 625c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 626db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad private boolean updateState(@NonNull final String targetPackageName, 627db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad @NonNull final String overlayPackageName, final int userId, final int flags) 628c745f42169df6687a764e48b65878f22965c1530Adam Lesinski throws OverlayManagerSettings.BadKeyException { 629db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 630db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(targetPackageName, userId); 631db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(overlayPackageName, 632db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad userId); 633db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 6340434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers. 635db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (targetPackage != null && overlayPackage != null && 636db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad !("android".equals(targetPackageName) 637ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski && overlayPackage.isStaticOverlayPackage())) { 638eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.createIdmap(targetPackage, overlayPackage, userId); 639eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 640eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 641db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad boolean modified = false; 642db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (overlayPackage != null) { 643db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad modified |= mSettings.setBaseCodePath(overlayPackageName, userId, 644db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad overlayPackage.applicationInfo.getBaseCodePath()); 6452f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad modified |= mSettings.setCategory(overlayPackageName, userId, 6462f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad overlayPackage.overlayCategory); 647db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 648eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 649db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId); 650db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad final @OverlayInfo.State int newState = calculateNewState(targetPackage, overlayPackage, 651db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad userId, flags); 652eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (currentState != newState) { 653eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 654eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("%s:%d: %s -> %s", 655db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad overlayPackageName, userId, 656eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(currentState), 657eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(newState))); 658eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 659db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad modified |= mSettings.setState(overlayPackageName, userId, newState); 660eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 661c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return modified; 662eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 663eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 664db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad private @OverlayInfo.State int calculateNewState(@Nullable final PackageInfo targetPackage, 665db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad @Nullable final PackageInfo overlayPackage, final int userId, final int flags) 666eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad throws OverlayManagerSettings.BadKeyException { 667db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 668db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if ((flags & FLAG_TARGET_IS_UPGRADING) != 0) { 669db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad return STATE_TARGET_UPGRADING; 670db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 671db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 672db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) { 673db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad return STATE_OVERLAY_UPGRADING; 674db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 675db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 676db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad // assert expectation on overlay package: can only be null if the flags are used 677db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad if (DEBUG && overlayPackage == null) { 678db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad throw new IllegalArgumentException("null overlay package not compatible with no flags"); 679db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad } 680db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad 681eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (targetPackage == null) { 682eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_MISSING_TARGET; 683eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 684eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 685eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(overlayPackage, userId)) { 686eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_NO_IDMAP; 687eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 688eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 689a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad if (overlayPackage.isStaticOverlayPackage()) { 690a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad return STATE_ENABLED_STATIC; 691a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad } 692a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad 693eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId); 694eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return enabled ? STATE_ENABLED : STATE_DISABLED; 695eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 696eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 697eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) { 698eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // For a given package, all Android users share the same idmap file. 699eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // This works because Android currently does not support users to 700eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // install different versions of the same package. It also means we 701eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // cannot remove an idmap file if any user still needs it. 702eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 703eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // When/if the Android framework allows different versions of the same 704eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // package to be installed for different users, idmap file handling 705eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // should be revised: 706eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 707eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - an idmap file should be unique for each {user, package} pair 708eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 709eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - the path to the idmap file should be passed to the native Asset 710eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // Manager layers, just like the path to the apk is passed today 711eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 712eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // As part of that change, calls to this method should be replaced by 713eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // direct calls to IdmapManager.removeIdmap, without looping over all 714eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // users. 715eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 716eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(oi)) { 717eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 718eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 719c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final int[] userIds = mSettings.getUsers(); 720c745f42169df6687a764e48b65878f22965c1530Adam Lesinski for (int userId : userIds) { 721eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 722eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId); 723eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (tmp != null && tmp.isEnabled()) { 724eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // someone is still using the idmap file -> we cannot remove it 725eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 726eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 727eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 728eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // intentionally left empty 729eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 730eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 731eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.removeIdmap(oi, oi.userId); 732eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 733eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 734c745f42169df6687a764e48b65878f22965c1530Adam Lesinski interface OverlayChangeListener { 735d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell 736d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell /** 737d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell * An event triggered by changes made to overlay state or settings as well as changes that 738d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell * add or remove target packages of overlays. 739d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell **/ 740497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad void onOverlaysChanged(@NonNull String targetPackage, int userId); 741c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 742c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 743eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad interface PackageManagerHelper { 744eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad PackageInfo getPackageInfo(@NonNull String packageName, int userId); 745eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2, 746eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad int userId); 747eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<PackageInfo> getOverlayPackages(int userId); 748eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 749eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad} 750