OverlayManagerServiceImpl.java revision d11c5510b13171878f8d6f6a3424c7b2418c3031
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. 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); 173eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 174eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 175eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageChanged(@NonNull final String packageName, final int userId) { 176eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 177eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId); 178eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 179eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 180eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 181eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, targetPackage); 182eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 183eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 184eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) { 185eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 186eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" + userId); 187eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 188eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 189eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, null); 190eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 191eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 192eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) { 193eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 194eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId); 195eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 196eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 197eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId); 198eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, targetPackage); 199eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 200eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 201eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onTargetPackageRemoved(@NonNull final String packageName, final int userId) { 202eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 203eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId); 204eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 205eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 206eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad updateAllOverlaysForTarget(packageName, userId, null); 207eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 208eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 209c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 210c745f42169df6687a764e48b65878f22965c1530Adam Lesinski * Returns true if the settings were modified for this target. 211c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 212c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean updateAllOverlaysForTarget(@NonNull final String packageName, final int userId, 213eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @Nullable final PackageInfo targetPackage) { 214c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = false; 215eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(packageName, userId); 216eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = ois.size(); 217eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 218eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = ois.get(i); 219eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName, userId); 220eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 221c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(oi.packageName, oi.userId); 222eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad removeIdmapIfPossible(oi); 223eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } else { 224eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 225c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 226eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 227eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 228c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(oi.packageName, userId); 229eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 230eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 231eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 232c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return modified; 233eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 234eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 235eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageAdded(@NonNull final String packageName, final int userId) { 236eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 237eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId); 238eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 239eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 240eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 241eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 242eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found"); 243eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad onOverlayPackageRemoved(packageName, userId); 244eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 245eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 246eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 247eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 248eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(overlayPackage.overlayTarget, userId); 249eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 250eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.init(packageName, userId, overlayPackage.overlayTarget, 25142d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlay, 25242d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok overlayPackage.overlayPriority); 253eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 254c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (updateState(targetPackage, overlayPackage, userId)) { 255c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 256c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 257eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 258eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.e(TAG, "failed to update settings", e); 259eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.remove(packageName, userId); 260eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 261eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 262eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 263eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageChanged(@NonNull final String packageName, final int userId) { 264eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageChanged called, but only pre-installed overlays supported"); 265eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 266eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 267eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) { 268eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageUpgrading called, but only pre-installed overlays supported"); 269eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 270eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 271eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) { 272eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageUpgraded called, but only pre-installed overlays supported"); 273eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 274eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 275eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) { 276eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.wtf(TAG, "onOverlayPackageRemoved called, but only pre-installed overlays supported"); 277eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 278eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 279eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) { 280eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 281eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlayInfo(packageName, userId); 282eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 283eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return null; 284eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 285eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 286eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 287eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName, 288eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 289eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForTarget(targetPackageName, userId); 290eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 291eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 292eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) { 293eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return mSettings.getOverlaysForUser(userId); 294eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 295eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 296eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setEnabled(@NonNull final String packageName, final boolean enable, 297eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 298eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 299eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d", 300eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad packageName, enable, userId)); 301eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 302eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 303eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 304eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (overlayPackage == null) { 305eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 306eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 307c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 308c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Ignore static overlays. 309c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage.isStaticOverlay) { 3100434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 3110434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 312eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 313eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 314eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 315eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final PackageInfo targetPackage = 316eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mPackageManager.getPackageInfo(oi.targetPackageName, userId); 317c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = mSettings.setEnabled(packageName, userId, enable); 318c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 319c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 320c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 321c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(oi.targetPackageName, userId); 322c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 323929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return true; 324929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } catch (OverlayManagerSettings.BadKeyException e) { 325929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 326929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 327929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 328929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 329c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean setEnabledExclusive(@NonNull final String packageName, final int userId) { 330929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (DEBUG) { 331c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, String.format("setEnabledExclusive packageName=%s userId=%d", packageName, userId)); 332929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 333929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 334929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 335929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk if (overlayPackage == null) { 336929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk return false; 337929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 338929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 339929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk try { 340929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); 341c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo targetPackage = 342c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mPackageManager.getPackageInfo(oi.targetPackageName, userId); 343c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 344929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk List<OverlayInfo> allOverlays = getOverlayInfosForTarget(oi.targetPackageName, userId); 345929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 346c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = false; 347c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 348929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk // Disable all other overlays. 349929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk allOverlays.remove(oi); 350929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk for (int i = 0; i < allOverlays.size(); i++) { 351c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final String disabledOverlayPackageName = allOverlays.get(i).packageName; 352c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo( 353c745f42169df6687a764e48b65878f22965c1530Adam Lesinski disabledOverlayPackageName, userId); 354c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (disabledOverlayPackageInfo == null) { 355c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.remove(disabledOverlayPackageName, userId); 356c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 357c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 358c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 359c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (disabledOverlayPackageInfo.isStaticOverlay) { 360c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Don't touch static overlays. 361c745f42169df6687a764e48b65878f22965c1530Adam Lesinski continue; 362c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 363c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 364c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Disable the overlay. 365c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false); 366c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, disabledOverlayPackageInfo, userId); 367929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk } 368929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk 369c745f42169df6687a764e48b65878f22965c1530Adam Lesinski // Enable the selected overlay. 370c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setEnabled(packageName, userId, true); 371c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= updateState(targetPackage, overlayPackage, userId); 372c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 373c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (modified) { 374c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(oi.targetPackageName, userId); 375c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 376eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return true; 377eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 378eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return false; 379eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 380eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 381eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 382c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) { 3830434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 3840434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (overlayPackage == null || overlayPackage.isStaticOverlay) { 3850434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return false; 3860434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 3870434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok return true; 3880434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok } 3890434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok 390eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setPriority(@NonNull final String packageName, 391eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final String newParentPackageName, final int userId) { 392c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 393c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName=" 394c745f42169df6687a764e48b65878f22965c1530Adam Lesinski + newParentPackageName + " userId=" + userId); 395c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 396c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 397c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 398c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 399c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 400c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 401c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 402c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 403c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 404c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 405c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 406c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setPriority(packageName, newParentPackageName, userId)) { 407c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 408c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 409c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 410eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 411eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 412eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setHighestPriority(@NonNull final String packageName, final int userId) { 413c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 414c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId); 415c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 416c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 417c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 418c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 419c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 420c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 421c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 422c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 423c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 424c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 425c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 426c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setHighestPriority(packageName, userId)) { 427c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 428c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 429c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 430eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 431eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 432eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean setLowestPriority(@NonNull final String packageName, final int userId) { 433c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (DEBUG) { 434c745f42169df6687a764e48b65878f22965c1530Adam Lesinski Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId); 435c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 436c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 437c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (!isPackageUpdatableOverlay(packageName, userId)) { 438c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 439c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 440c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 441c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); 442c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (overlayPackage == null) { 443c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return false; 444c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 445c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 446c745f42169df6687a764e48b65878f22965c1530Adam Lesinski if (mSettings.setLowestPriority(packageName, userId)) { 447c745f42169df6687a764e48b65878f22965c1530Adam Lesinski mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); 448c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 449c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return true; 450eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 451eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 452eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad void onDump(@NonNull final PrintWriter pw) { 453eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mSettings.dump(pw); 454a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays)); 455eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 456eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 457eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName, 458eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int userId) { 459eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName, userId); 460eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final List<String> paths = new ArrayList<>(overlays.size()); 461eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int N = overlays.size(); 462eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad for (int i = 0; i < N; i++) { 463eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo oi = overlays.get(i); 464eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (oi.isEnabled()) { 465eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad paths.add(oi.packageName); 466eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 467eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 468eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return paths; 469eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 470eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 471c745f42169df6687a764e48b65878f22965c1530Adam Lesinski /** 472c745f42169df6687a764e48b65878f22965c1530Adam Lesinski * Returns true if the settings/state was modified, false otherwise. 473c745f42169df6687a764e48b65878f22965c1530Adam Lesinski */ 474c745f42169df6687a764e48b65878f22965c1530Adam Lesinski private boolean updateState(@Nullable final PackageInfo targetPackage, 475eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final PackageInfo overlayPackage, final int userId) 476c745f42169df6687a764e48b65878f22965c1530Adam Lesinski throws OverlayManagerSettings.BadKeyException { 4770434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers. 4780434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok if (targetPackage != null && 4790434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok !("android".equals(targetPackage.packageName) && overlayPackage.isStaticOverlay)) { 480eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.createIdmap(targetPackage, overlayPackage, userId); 481eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 482eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 483c745f42169df6687a764e48b65878f22965c1530Adam Lesinski boolean modified = mSettings.setBaseCodePath(overlayPackage.packageName, userId, 484eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.applicationInfo.getBaseCodePath()); 485eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 486eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int currentState = mSettings.getState(overlayPackage.packageName, userId); 487eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final int newState = calculateNewState(targetPackage, overlayPackage, userId); 488eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (currentState != newState) { 489eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (DEBUG) { 490eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad Slog.d(TAG, String.format("%s:%d: %s -> %s", 491eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad overlayPackage.packageName, userId, 492eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(currentState), 493eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad OverlayInfo.stateToString(newState))); 494eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 495c745f42169df6687a764e48b65878f22965c1530Adam Lesinski modified |= mSettings.setState(overlayPackage.packageName, userId, newState); 496eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 497c745f42169df6687a764e48b65878f22965c1530Adam Lesinski return modified; 498eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 499eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 500eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private int calculateNewState(@Nullable final PackageInfo targetPackage, 501eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad @NonNull final PackageInfo overlayPackage, final int userId) 502eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad throws OverlayManagerSettings.BadKeyException { 503eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (targetPackage == null) { 504eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_MISSING_TARGET; 505eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 506eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 507eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(overlayPackage, userId)) { 508eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return STATE_NO_IDMAP; 509eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 510eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 511eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId); 512eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return enabled ? STATE_ENABLED : STATE_DISABLED; 513eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 514eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 515eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) { 516eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // For a given package, all Android users share the same idmap file. 517eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // This works because Android currently does not support users to 518eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // install different versions of the same package. It also means we 519eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // cannot remove an idmap file if any user still needs it. 520eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 521eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // When/if the Android framework allows different versions of the same 522eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // package to be installed for different users, idmap file handling 523eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // should be revised: 524eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 525eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - an idmap file should be unique for each {user, package} pair 526eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 527eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // - the path to the idmap file should be passed to the native Asset 528eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // Manager layers, just like the path to the apk is passed today 529eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // 530eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // As part of that change, calls to this method should be replaced by 531eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // direct calls to IdmapManager.removeIdmap, without looping over all 532eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // users. 533eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 534eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (!mIdmapManager.idmapExists(oi)) { 535eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 536eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 537c745f42169df6687a764e48b65878f22965c1530Adam Lesinski final int[] userIds = mSettings.getUsers(); 538c745f42169df6687a764e48b65878f22965c1530Adam Lesinski for (int userId : userIds) { 539eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad try { 540eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId); 541eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad if (tmp != null && tmp.isEnabled()) { 542eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // someone is still using the idmap file -> we cannot remove it 543eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad return; 544eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 545eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } catch (OverlayManagerSettings.BadKeyException e) { 546eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad // intentionally left empty 547eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 548eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 549eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad mIdmapManager.removeIdmap(oi, oi.userId); 550eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 551eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad 552c745f42169df6687a764e48b65878f22965c1530Adam Lesinski interface OverlayChangeListener { 553c745f42169df6687a764e48b65878f22965c1530Adam Lesinski void onOverlaysChanged(@NonNull String targetPackage, int userId); 554c745f42169df6687a764e48b65878f22965c1530Adam Lesinski } 555c745f42169df6687a764e48b65878f22965c1530Adam Lesinski 556eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad interface PackageManagerHelper { 557eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad PackageInfo getPackageInfo(@NonNull String packageName, int userId); 558eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2, 559eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad int userId); 560eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad List<PackageInfo> getOverlayPackages(int userId); 561eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad } 562eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad} 563