OverlayManagerServiceImpl.java revision 42d53f6b1883e3db514ad8d105d23fe6a1e9a59b
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 71eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad /* 72eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Call this when switching to a new Android user. Will return a list of 73eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * 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 */ 77eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<String> onSwitchUser(final int newUserId) { 78eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 79eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onSwitchUser 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. 112a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski mSettings.setEnabled(overlayPackage.packageName, newUserId, true); 113a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski } 114a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski } else { 115a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski // The targetPackageName we have stored doesn't match the overlay's target. 116a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski // Queue the old target for an update as well. 117a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski packagesToUpdateAssets.add(oi.targetPackageName); 118a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski } 119eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 120eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 121eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 122eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 123eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(overlayPackage.overlayTarget, newUserId); 124eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateState(targetPackage, overlayPackage, newUserId); 125eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 126eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 127eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(overlayPackage.packageName, newUserId); 128eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 129eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 130eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packagesToUpdateAssets.add(overlayPackage.overlayTarget); 131eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad storedOverlayInfos.remove(overlayPackage.packageName); 132eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 133eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 134eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // any OverlayInfo left in storedOverlayInfos is no longer 135eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // installed and should be removed 136eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int storedOverlayInfosSize = storedOverlayInfos.size(); 137eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < storedOverlayInfosSize; i++) { 138c0bba8b18b41356721c2ebb25af83bc5bb5a74b0Mårten Kongstad final OverlayInfo oi = storedOverlayInfos.valueAt(i); 139eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(oi.packageName, oi.userId); 140eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad removeIdmapIfPossible(oi); 141eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packagesToUpdateAssets.add(oi.targetPackageName); 142eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 143eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 144eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // remove target packages that are not installed 145eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final Iterator<String> iter = packagesToUpdateAssets.iterator(); 146eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad while (iter.hasNext()) { 147eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad String targetPackageName = iter.next(); 148eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (mPackageManager.getPackageInfo(targetPackageName, newUserId) == null) { 149eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad iter.remove(); 150eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 151eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 152a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski return new ArrayList<>(packagesToUpdateAssets); 153eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 154eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 155eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onUserRemoved(final int userId) { 156eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 157eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onUserRemoved userId=" + userId); 158eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 159eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.removeUser(userId); 160eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 161eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 162eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageAdded(@NonNull final String packageName, final int userId) { 163eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 164eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId); 165eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 166eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 167eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 168eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, targetPackage); 169eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 170eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 171eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageChanged(@NonNull final String packageName, final int userId) { 172eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 173eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId); 174eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 175eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 176eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 177eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, targetPackage); 178eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 179eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 180eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) { 181eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 182eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" + userId); 183eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 184eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 185eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, null); 186eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 187eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 188eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) { 189eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 190eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId); 191eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 192eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 193eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 194eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, targetPackage); 195eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 196eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 197eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageRemoved(@NonNull final String packageName, final int userId) { 198eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 199eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId); 200eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 201eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 202eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, null); 203eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 204eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 205c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 206c745f42169df6687a764e48b65878f22965c1530Adam Lesinski * Returns true if the settings were modified for this target. 207c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 208c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean updateAllOverlaysForTarget(@NonNull final String packageName, final int userId, 209eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @Nullable final PackageInfo targetPackage) { 210c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = false; 211eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(packageName, userId); 212eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = ois.size(); 213eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 214eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = ois.get(i); 215eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName, userId); 216eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 217c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(oi.packageName, oi.userId); 218eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad removeIdmapIfPossible(oi); 219eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } else { 220eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 221c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 222eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 223eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 224c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(oi.packageName, userId); 225eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 226eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 227eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 228c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return modified; 229eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 230eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 231eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageAdded(@NonNull final String packageName, final int userId) { 232eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 233eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId); 234eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 235eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 236eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 237eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 238eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found"); 239eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad onOverlayPackageRemoved(packageName, userId); 240eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 241eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 242eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 243eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 244eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(overlayPackage.overlayTarget, userId); 245eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 246eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.init(packageName, userId, overlayPackage.overlayTarget, 24742d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlay, 24842d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.overlayPriority); 249eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 250c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (updateState(targetPackage, overlayPackage, userId)) { 251c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 252c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 253eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 254eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 255eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(packageName, userId); 256eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 257eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 258eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 259eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageChanged(@NonNull final String packageName, final int userId) { 260eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageChanged called, but only pre-installed overlays supported"); 261eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 262eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 263eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) { 264eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageUpgrading called, but only pre-installed overlays supported"); 265eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 266eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 267eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) { 268eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageUpgraded called, but only pre-installed overlays supported"); 269eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 270eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 271eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) { 272eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageRemoved called, but only pre-installed overlays supported"); 273eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 274eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 275eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) { 276eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 277eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlayInfo(packageName, userId); 278eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 279eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return null; 280eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 281eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 282eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 283eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName, 284eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 285eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForTarget(targetPackageName, userId); 286eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 287eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 288eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) { 289eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForUser(userId); 290eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 291eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 292eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setEnabled(@NonNull final String packageName, final boolean enable, 293eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 294eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 295eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d", 296eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packageName, enable, userId)); 297eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 298eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 299eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 300eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 301eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 302eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 303c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 304c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Ignore static overlays. 305c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage.isStaticOverlay) { 3060434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 3070434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 308eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 309eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 310eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 311eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 312eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(oi.targetPackageName, userId); 313c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = mSettings.setEnabled(packageName, userId, enable); 314c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 315c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 316c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 317c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(oi.targetPackageName, userId); 318c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 319929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return true; 320929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } catch (OverlayManagerSettings.BadKeyException e) { 321929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 322929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 323929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 324929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 325c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean setEnabledExclusive(@NonNull final String packageName, final int userId) { 326929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (DEBUG) { 327c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, String.format("setEnabledExclusive packageName=%s userId=%d", packageName, userId)); 328929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 329929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 330929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 331929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (overlayPackage == null) { 332929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 333929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 334929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 335929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk try { 336929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 337c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo targetPackage = 338c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mPackageManager.getPackageInfo(oi.targetPackageName, userId); 339c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 340929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk List<OverlayInfo> allOverlays = getOverlayInfosForTarget(oi.targetPackageName, userId); 341929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 342c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = false; 343c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 344929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk // Disable all other overlays. 345929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk allOverlays.remove(oi); 346929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk for (int i = 0; i < allOverlays.size(); i++) { 347c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final String disabledOverlayPackageName = allOverlays.get(i).packageName; 348c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo( 349c745f42169df6687a764e48b65878f22965c1530Adam Lesinski disabledOverlayPackageName, userId); 350c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (disabledOverlayPackageInfo == null) { 351c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(disabledOverlayPackageName, userId); 352c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 353c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 354c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 355c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (disabledOverlayPackageInfo.isStaticOverlay) { 356c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Don't touch static overlays. 357c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 358c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 359c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 360c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Disable the overlay. 361c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false); 362c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, disabledOverlayPackageInfo, userId); 363929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 364929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 365c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Enable the selected overlay. 366c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(packageName, userId, true); 367c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 368c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 369c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 370c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(oi.targetPackageName, userId); 371c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 372eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return true; 373eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 374eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 375eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 376eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 377eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 378c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) { 3790434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 3800434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (overlayPackage == null || overlayPackage.isStaticOverlay) { 3810434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 3820434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 3830434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return true; 3840434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 3850434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok 386eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setPriority(@NonNull final String packageName, 387eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final String newParentPackageName, final int userId) { 388c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 389c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName=" 390c745f42169df6687a764e48b65878f22965c1530Adam Lesinski + newParentPackageName + " userId=" + userId); 391c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 392c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 393c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 394c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 395c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 396c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 397c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 398c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 399c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 400c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 401c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 402c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setPriority(packageName, newParentPackageName, userId)) { 403c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 404c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 405c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 406eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 407eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 408eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setHighestPriority(@NonNull final String packageName, final int userId) { 409c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 410c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId); 411c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 412c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 413c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 414c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 415c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 416c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 417c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 418c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 419c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 420c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 421c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 422c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setHighestPriority(packageName, userId)) { 423c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 424c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 425c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 426eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 427eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 428eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setLowestPriority(@NonNull final String packageName, final int userId) { 429c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 430c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId); 431c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 432c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 433c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 434c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 435c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 436c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 437c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 438c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 439c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 440c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 441c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 442c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setLowestPriority(packageName, userId)) { 443c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 444c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 445c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 446eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 447eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 448eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onDump(@NonNull final PrintWriter pw) { 449eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.dump(pw); 450a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays)); 451eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 452eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 453eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName, 454eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 455eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName, userId); 456eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<String> paths = new ArrayList<>(overlays.size()); 457eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = overlays.size(); 458eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 459eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = overlays.get(i); 460eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (oi.isEnabled()) { 461eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad paths.add(oi.packageName); 462eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 463eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 464eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return paths; 465eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 466eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 467c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 468c745f42169df6687a764e48b65878f22965c1530Adam Lesinski * Returns true if the settings/state was modified, false otherwise. 469c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 470c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean updateState(@Nullable final PackageInfo targetPackage, 471eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final PackageInfo overlayPackage, final int userId) 472c745f42169df6687a764e48b65878f22965c1530Adam Lesinski throws OverlayManagerSettings.BadKeyException { 4730434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers. 4740434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (targetPackage != null && 4750434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok !("android".equals(targetPackage.packageName) && overlayPackage.isStaticOverlay)) { 476eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.createIdmap(targetPackage, overlayPackage, userId); 477eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 478eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 479c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = mSettings.setBaseCodePath(overlayPackage.packageName, userId, 480eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.applicationInfo.getBaseCodePath()); 481eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 482eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int currentState = mSettings.getState(overlayPackage.packageName, userId); 483eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int newState = calculateNewState(targetPackage, overlayPackage, userId); 484eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (currentState != newState) { 485eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 486eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("%s:%d: %s -> %s", 487eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.packageName, userId, 488eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(currentState), 489eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(newState))); 490eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 491c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setState(overlayPackage.packageName, userId, newState); 492eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 493c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return modified; 494eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 495eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 496eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private int calculateNewState(@Nullable final PackageInfo targetPackage, 497eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final PackageInfo overlayPackage, final int userId) 498eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad throws OverlayManagerSettings.BadKeyException { 499eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (targetPackage == null) { 500eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_MISSING_TARGET; 501eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 502eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 503eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(overlayPackage, userId)) { 504eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_NO_IDMAP; 505eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 506eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 507eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId); 508eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return enabled ? STATE_ENABLED : STATE_DISABLED; 509eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 510eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 511eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) { 512eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // For a given package, all Android users share the same idmap file. 513eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // This works because Android currently does not support users to 514eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // install different versions of the same package. It also means we 515eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // cannot remove an idmap file if any user still needs it. 516eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 517eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // When/if the Android framework allows different versions of the same 518eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // package to be installed for different users, idmap file handling 519eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // should be revised: 520eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 521eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - an idmap file should be unique for each {user, package} pair 522eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 523eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - the path to the idmap file should be passed to the native Asset 524eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // Manager layers, just like the path to the apk is passed today 525eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 526eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // As part of that change, calls to this method should be replaced by 527eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // direct calls to IdmapManager.removeIdmap, without looping over all 528eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // users. 529eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 530eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(oi)) { 531eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 532eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 533c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final int[] userIds = mSettings.getUsers(); 534c745f42169df6687a764e48b65878f22965c1530Adam Lesinski for (int userId : userIds) { 535eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 536eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId); 537eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (tmp != null && tmp.isEnabled()) { 538eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // someone is still using the idmap file -> we cannot remove it 539eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 540eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 541eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 542eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // intentionally left empty 543eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 544eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 545eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.removeIdmap(oi, oi.userId); 546eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 547eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 548c745f42169df6687a764e48b65878f22965c1530Adam Lesinski interface OverlayChangeListener { 549c745f42169df6687a764e48b65878f22965c1530Adam Lesinski void onOverlaysChanged(@NonNull String targetPackage, int userId); 550c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 551c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 552eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad interface PackageManagerHelper { 553eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad PackageInfo getPackageInfo(@NonNull String packageName, int userId); 554eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2, 555eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad int userId); 556eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<PackageInfo> getOverlayPackages(int userId); 557eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 558eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad} 559