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