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; 21eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_MISSING_TARGET; 22eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_NO_IDMAP; 23eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 24eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.DEBUG; 25eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.TAG; 26eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 27eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.NonNull; 28eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.Nullable; 29eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.om.OverlayInfo; 30eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.pm.PackageInfo; 31a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinskiimport android.text.TextUtils; 32eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArrayMap; 33eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArraySet; 34eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.Slog; 35eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 36eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.io.PrintWriter; 37eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.ArrayList; 38eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Iterator; 39eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.List; 40eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Map; 41eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Set; 42eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 43eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad/** 44eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Internal implementation of OverlayManagerService. 45eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 46eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Methods in this class should only be called by the OverlayManagerService. 47eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * This class is not thread-safe; the caller is expected to ensure the 48eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * necessary thread synchronization. 49eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 50eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * @see OverlayManagerService 51eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */ 52eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadfinal class OverlayManagerServiceImpl { 53eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private final PackageManagerHelper mPackageManager; 54eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private final IdmapManager mIdmapManager; 55eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private final OverlayManagerSettings mSettings; 56a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski private final Set<String> mDefaultOverlays; 57c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private final OverlayChangeListener mListener; 58eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 59eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager, 60eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final IdmapManager idmapManager, 61a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski @NonNull final OverlayManagerSettings settings, 62c745f42169df6687a764e48b65878f22965c1530Adam Lesinski @NonNull final Set<String> defaultOverlays, 63c745f42169df6687a764e48b65878f22965c1530Adam Lesinski @NonNull final OverlayChangeListener listener) { 64eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager = packageManager; 65eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager = idmapManager; 66eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings = settings; 67a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski mDefaultOverlays = defaultOverlays; 68c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener = listener; 69eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 70eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 71ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski /** 72ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski * Call this to synchronize the Settings for a user with what PackageManager knows about a user. 73ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski * Returns a list of target packages that must refresh their overlays. This list is the union 74eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * of two sets: the set of targets with currently active overlays, and the 75eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * set of targets that had, but no longer have, active overlays. 76eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */ 77ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski ArrayList<String> updateOverlaysForUser(final int newUserId) { 78eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 79ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski Slog.d(TAG, "updateOverlaysForUser newUserId=" + newUserId); 80eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 81eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 82eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final Set<String> packagesToUpdateAssets = new ArraySet<>(); 83eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final ArrayMap<String, List<OverlayInfo>> tmp = mSettings.getOverlaysForUser(newUserId); 84eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int tmpSize = tmp.size(); 85eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final ArrayMap<String, OverlayInfo> storedOverlayInfos = new ArrayMap<>(tmpSize); 86eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < tmpSize; i++) { 87eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> chunk = tmp.valueAt(i); 88eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int chunkSize = chunk.size(); 89eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int j = 0; j < chunkSize; j++) { 90eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = chunk.get(j); 91eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad storedOverlayInfos.put(oi.packageName, oi); 92eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 93eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 94eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 95eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId); 96eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int overlayPackagesSize = overlayPackages.size(); 97eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < overlayPackagesSize; i++) { 98eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = overlayPackages.get(i); 99eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName); 100eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) { 101a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski // Update the overlay if it didn't exist or had the wrong target package. 102eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.init(overlayPackage.packageName, newUserId, 103eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.overlayTarget, 10442d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.applicationInfo.getBaseCodePath(), 10542d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.isStaticOverlay, overlayPackage.overlayPriority); 106a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski 107a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski if (oi == null) { 108a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski // This overlay does not exist in our settings. 10984d7f1ecfb962cb6c8e4adefa077729128c26d3bJaekyun Seok if (overlayPackage.isStaticOverlay || 11084d7f1ecfb962cb6c8e4adefa077729128c26d3bJaekyun Seok mDefaultOverlays.contains(overlayPackage.packageName)) { 111a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski // Enable this overlay by default. 112d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski if (DEBUG) { 113d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski Slog.d(TAG, "Enabling overlay " + overlayPackage.packageName 114d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski + " for user " + newUserId + " by default"); 115d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski } 116a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski mSettings.setEnabled(overlayPackage.packageName, newUserId, true); 117a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski } 118a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski } else { 119a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski // The targetPackageName we have stored doesn't match the overlay's target. 120a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski // Queue the old target for an update as well. 121a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski packagesToUpdateAssets.add(oi.targetPackageName); 122a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski } 123eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 124eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 125eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 126eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 127eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(overlayPackage.overlayTarget, newUserId); 128eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateState(targetPackage, overlayPackage, newUserId); 129eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 130eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 131eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(overlayPackage.packageName, newUserId); 132eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 133eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 134eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packagesToUpdateAssets.add(overlayPackage.overlayTarget); 135eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad storedOverlayInfos.remove(overlayPackage.packageName); 136eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 137eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 138eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // any OverlayInfo left in storedOverlayInfos is no longer 139eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // installed and should be removed 140eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int storedOverlayInfosSize = storedOverlayInfos.size(); 141eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < storedOverlayInfosSize; i++) { 142c0bba8b18b41356721c2ebb25af83bc5bb5a74b0Mårten Kongstad final OverlayInfo oi = storedOverlayInfos.valueAt(i); 143eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(oi.packageName, oi.userId); 144eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad removeIdmapIfPossible(oi); 145eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packagesToUpdateAssets.add(oi.targetPackageName); 146eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 147eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 148eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // remove target packages that are not installed 149eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final Iterator<String> iter = packagesToUpdateAssets.iterator(); 150eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad while (iter.hasNext()) { 151eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad String targetPackageName = iter.next(); 152eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (mPackageManager.getPackageInfo(targetPackageName, newUserId) == null) { 153eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad iter.remove(); 154eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 155eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 156a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski return new ArrayList<>(packagesToUpdateAssets); 157eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 158eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 159eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onUserRemoved(final int userId) { 160eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 161eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onUserRemoved userId=" + userId); 162eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 163eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.removeUser(userId); 164eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 165eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 166eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageAdded(@NonNull final String packageName, final int userId) { 167eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 168eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId); 169eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 170eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 171eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 172eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, targetPackage); 173560830c9f06d07d97055426420709733571ca05bTodd Kennedy mListener.onOverlaysChanged(packageName, userId); 174eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 175eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 176eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageChanged(@NonNull final String packageName, final int userId) { 177eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 178eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId); 179eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 180eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 181eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 182560830c9f06d07d97055426420709733571ca05bTodd Kennedy if (updateAllOverlaysForTarget(packageName, userId, targetPackage)) { 183560830c9f06d07d97055426420709733571ca05bTodd Kennedy mListener.onOverlaysChanged(packageName, userId); 184560830c9f06d07d97055426420709733571ca05bTodd Kennedy } 185eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 186eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 187eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) { 188eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 189eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" + userId); 190eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 191eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 192560830c9f06d07d97055426420709733571ca05bTodd Kennedy if (updateAllOverlaysForTarget(packageName, userId, null)) { 193560830c9f06d07d97055426420709733571ca05bTodd Kennedy mListener.onOverlaysChanged(packageName, userId); 194560830c9f06d07d97055426420709733571ca05bTodd Kennedy } 195eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 196eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 197eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) { 198eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 199eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId); 200eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 201eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 202eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 203560830c9f06d07d97055426420709733571ca05bTodd Kennedy if (updateAllOverlaysForTarget(packageName, userId, targetPackage)) { 204560830c9f06d07d97055426420709733571ca05bTodd Kennedy mListener.onOverlaysChanged(packageName, userId); 205560830c9f06d07d97055426420709733571ca05bTodd Kennedy } 206eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 207eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 208eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageRemoved(@NonNull final String packageName, final int userId) { 209eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 210eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId); 211eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 212eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 213eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, null); 214eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 215eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 216c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 217c745f42169df6687a764e48b65878f22965c1530Adam Lesinski * Returns true if the settings were modified for this target. 218c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 219c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean updateAllOverlaysForTarget(@NonNull final String packageName, final int userId, 220eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @Nullable final PackageInfo targetPackage) { 221c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = false; 222eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(packageName, userId); 223eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = ois.size(); 224eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 225eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = ois.get(i); 226eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName, userId); 227eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 228c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(oi.packageName, oi.userId); 229eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad removeIdmapIfPossible(oi); 230eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } else { 231eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 232c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 233eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 234eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 235c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(oi.packageName, userId); 236eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 237eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 238eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 239c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return modified; 240eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 241eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 242eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageAdded(@NonNull final String packageName, final int userId) { 243eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 244eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId); 245eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 246eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 247eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 248eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 249eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found"); 250eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad onOverlayPackageRemoved(packageName, userId); 251eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 252eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 253eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 254eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 255eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(overlayPackage.overlayTarget, userId); 256eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 257eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.init(packageName, userId, overlayPackage.overlayTarget, 25842d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlay, 25942d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.overlayPriority); 260eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 261c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (updateState(targetPackage, overlayPackage, userId)) { 262c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 263c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 264eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 265eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 266eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(packageName, userId); 267eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 268eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 269eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 270eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageChanged(@NonNull final String packageName, final int userId) { 271eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageChanged called, but only pre-installed overlays supported"); 272eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 273eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 274eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) { 275eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageUpgrading called, but only pre-installed overlays supported"); 276eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 277eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 278eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) { 279eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageUpgraded called, but only pre-installed overlays supported"); 280eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 281eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 282eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) { 283eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageRemoved called, but only pre-installed overlays supported"); 284eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 285eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 286eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) { 287eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 288eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlayInfo(packageName, userId); 289eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 290eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return null; 291eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 292eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 293eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 294eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName, 295eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 296eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForTarget(targetPackageName, userId); 297eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 298eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 299eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) { 300eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForUser(userId); 301eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 302eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 303eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setEnabled(@NonNull final String packageName, final boolean enable, 304eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 305eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 306eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d", 307eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packageName, enable, userId)); 308eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 309eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 310eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 311eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 312eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 313eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 314c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 315c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Ignore static overlays. 316c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage.isStaticOverlay) { 3170434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 3180434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 319eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 320eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 321eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 322eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 323eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(oi.targetPackageName, userId); 324c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = mSettings.setEnabled(packageName, userId, enable); 325c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 326c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 327c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 328c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(oi.targetPackageName, userId); 329c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 330929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return true; 331929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } catch (OverlayManagerSettings.BadKeyException e) { 332929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 333929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 334929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 335929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 336c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean setEnabledExclusive(@NonNull final String packageName, final int userId) { 337929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (DEBUG) { 338c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, String.format("setEnabledExclusive packageName=%s userId=%d", packageName, userId)); 339929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 340929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 341929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 342929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (overlayPackage == null) { 343929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 344929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 345929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 346929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk try { 347929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 348c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo targetPackage = 349c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mPackageManager.getPackageInfo(oi.targetPackageName, userId); 350c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 351929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk List<OverlayInfo> allOverlays = getOverlayInfosForTarget(oi.targetPackageName, userId); 352929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 353c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = false; 354c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 355929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk // Disable all other overlays. 356929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk allOverlays.remove(oi); 357929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk for (int i = 0; i < allOverlays.size(); i++) { 358c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final String disabledOverlayPackageName = allOverlays.get(i).packageName; 359c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo( 360c745f42169df6687a764e48b65878f22965c1530Adam Lesinski disabledOverlayPackageName, userId); 361c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (disabledOverlayPackageInfo == null) { 362c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(disabledOverlayPackageName, userId); 363c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 364c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 365c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 366c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (disabledOverlayPackageInfo.isStaticOverlay) { 367c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Don't touch static overlays. 368c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 369c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 370c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 371c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Disable the overlay. 372c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false); 373c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, disabledOverlayPackageInfo, userId); 374929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 375929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 376c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Enable the selected overlay. 377c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(packageName, userId, true); 378c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 379c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 380c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 381c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(oi.targetPackageName, userId); 382c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 383eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return true; 384eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 385eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 386eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 387eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 388eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 389c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) { 3900434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 3910434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (overlayPackage == null || overlayPackage.isStaticOverlay) { 3920434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 3930434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 3940434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return true; 3950434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 3960434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok 397eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setPriority(@NonNull final String packageName, 398eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final String newParentPackageName, final int userId) { 399c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 400c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName=" 401c745f42169df6687a764e48b65878f22965c1530Adam Lesinski + newParentPackageName + " userId=" + userId); 402c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 403c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 404c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 405c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 406c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 407c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 408c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 409c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 410c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 411c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 412c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 413c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setPriority(packageName, newParentPackageName, userId)) { 414c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 415c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 416c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 417eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 418eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 419eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setHighestPriority(@NonNull final String packageName, final int userId) { 420c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 421c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId); 422c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 423c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 424c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 425c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 426c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 427c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 428c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 429c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 430c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 431c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 432c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 433c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setHighestPriority(packageName, userId)) { 434c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 435c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 436c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 437eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 438eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 439eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setLowestPriority(@NonNull final String packageName, final int userId) { 440c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 441c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId); 442c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 443c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 444c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 445c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 446c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 447c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 448c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 449c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 450c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 451c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 452c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 453c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setLowestPriority(packageName, userId)) { 454c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 455c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 456c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 457eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 458eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 459eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onDump(@NonNull final PrintWriter pw) { 460eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.dump(pw); 461a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays)); 462eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 463eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 464eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName, 465eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 466eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName, userId); 467eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<String> paths = new ArrayList<>(overlays.size()); 468eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = overlays.size(); 469eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 470eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = overlays.get(i); 471eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (oi.isEnabled()) { 472eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad paths.add(oi.packageName); 473eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 474eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 475eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return paths; 476eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 477eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 478c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 479c745f42169df6687a764e48b65878f22965c1530Adam Lesinski * Returns true if the settings/state was modified, false otherwise. 480c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 481c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean updateState(@Nullable final PackageInfo targetPackage, 482eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final PackageInfo overlayPackage, final int userId) 483c745f42169df6687a764e48b65878f22965c1530Adam Lesinski throws OverlayManagerSettings.BadKeyException { 4840434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers. 4850434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (targetPackage != null && 4860434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok !("android".equals(targetPackage.packageName) && overlayPackage.isStaticOverlay)) { 487eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.createIdmap(targetPackage, overlayPackage, userId); 488eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 489eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 490c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = mSettings.setBaseCodePath(overlayPackage.packageName, userId, 491eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.applicationInfo.getBaseCodePath()); 492eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 493eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int currentState = mSettings.getState(overlayPackage.packageName, userId); 494eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int newState = calculateNewState(targetPackage, overlayPackage, userId); 495eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (currentState != newState) { 496eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 497eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("%s:%d: %s -> %s", 498eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.packageName, userId, 499eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(currentState), 500eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(newState))); 501eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 502c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setState(overlayPackage.packageName, userId, newState); 503eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 504c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return modified; 505eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 506eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 507eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private int calculateNewState(@Nullable final PackageInfo targetPackage, 508eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final PackageInfo overlayPackage, final int userId) 509eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad throws OverlayManagerSettings.BadKeyException { 510eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (targetPackage == null) { 511eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_MISSING_TARGET; 512eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 513eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 514eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(overlayPackage, userId)) { 515eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_NO_IDMAP; 516eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 517eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 518eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId); 519eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return enabled ? STATE_ENABLED : STATE_DISABLED; 520eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 521eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 522eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) { 523eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // For a given package, all Android users share the same idmap file. 524eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // This works because Android currently does not support users to 525eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // install different versions of the same package. It also means we 526eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // cannot remove an idmap file if any user still needs it. 527eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 528eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // When/if the Android framework allows different versions of the same 529eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // package to be installed for different users, idmap file handling 530eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // should be revised: 531eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 532eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - an idmap file should be unique for each {user, package} pair 533eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 534eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - the path to the idmap file should be passed to the native Asset 535eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // Manager layers, just like the path to the apk is passed today 536eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 537eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // As part of that change, calls to this method should be replaced by 538eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // direct calls to IdmapManager.removeIdmap, without looping over all 539eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // users. 540eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 541eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(oi)) { 542eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 543eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 544c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final int[] userIds = mSettings.getUsers(); 545c745f42169df6687a764e48b65878f22965c1530Adam Lesinski for (int userId : userIds) { 546eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 547eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId); 548eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (tmp != null && tmp.isEnabled()) { 549eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // someone is still using the idmap file -> we cannot remove it 550eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 551eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 552eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 553eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // intentionally left empty 554eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 555eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 556eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.removeIdmap(oi, oi.userId); 557eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 558eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 559c745f42169df6687a764e48b65878f22965c1530Adam Lesinski interface OverlayChangeListener { 560c745f42169df6687a764e48b65878f22965c1530Adam Lesinski void onOverlaysChanged(@NonNull String targetPackage, int userId); 561c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 562c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 563eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad interface PackageManagerHelper { 564eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad PackageInfo getPackageInfo(@NonNull String packageName, int userId); 565eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2, 566eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad int userId); 567eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<PackageInfo> getOverlayPackages(int userId); 568eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 569eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad} 570