1e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal/* 2e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * Copyright (C) 2014 The Android Open Source Project 3e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * 4e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * Licensed under the Apache License, Version 2.0 (the "License"); 5e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * you may not use this file except in compliance with the License. 6e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * You may obtain a copy of the License at 7e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * 8e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * http://www.apache.org/licenses/LICENSE-2.0 9e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * 10e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * Unless required by applicable law or agreed to in writing, software 11e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * distributed under the License is distributed on an "AS IS" BASIS, 12e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * See the License for the specific language governing permissions and 14e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal * limitations under the License. 15e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal */ 16e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 17e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalpackage com.android.launcher3.compat; 18e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 19e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.Context; 20817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschlerimport android.content.pm.ApplicationInfo; 21e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.pm.PackageInstaller; 22e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.pm.PackageInstaller.SessionCallback; 23800a4f217a5b0b7817a70a24974fc13d6b7e4591Sunny Goyalimport android.content.pm.PackageInstaller.SessionInfo; 24d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyalimport android.os.Handler; 257c74e4ae641e76f73d74348e293c244a157f6585Sunny Goyalimport android.os.Process; 267c74e4ae641e76f73d74348e293c244a157f6585Sunny Goyalimport android.os.UserHandle; 276d696f8d7c4ce933eaea4e8d86270ef6a1fc07c3Mario Bertschlerimport android.text.TextUtils; 28e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.util.SparseArray; 29e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 30349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport com.android.launcher3.IconCache; 31e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport com.android.launcher3.LauncherAppState; 32756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyalimport com.android.launcher3.LauncherModel; 33817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschlerimport com.android.launcher3.config.FeatureFlags; 34091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 35e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 36817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschlerimport java.util.ArrayList; 37756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyalimport java.util.HashMap; 38817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschlerimport java.util.Iterator; 39817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschlerimport java.util.List; 40e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 41756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyalpublic class PackageInstallerCompatVL extends PackageInstallerCompat { 42e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 43817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler private static final boolean DEBUG = false; 44817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler 45756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal @Thunk final SparseArray<String> mActiveSessions = new SparseArray<>(); 46d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal 47091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final PackageInstaller mInstaller; 48349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal private final IconCache mCache; 49d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal private final Handler mWorker; 50817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler private final Context mAppContext; 51817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler private final HashMap<String,Boolean> mSessionVerifiedMap = new HashMap<>(); 52e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 53e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal PackageInstallerCompatVL(Context context) { 54817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler mAppContext = context.getApplicationContext(); 55e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mInstaller = context.getPackageManager().getPackageInstaller(); 5687f784c285fdeed9091a4de8b9b44db3eca677d8Sunny Goyal mCache = LauncherAppState.getInstance(context).getIconCache(); 57756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal mWorker = new Handler(LauncherModel.getWorkerLooper()); 58d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal mInstaller.registerSessionCallback(mCallback, mWorker); 59e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 60e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 61e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 62756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public HashMap<String, Integer> updateAndGetActiveSessionCache() { 63756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal HashMap<String, Integer> activePackages = new HashMap<>(); 647c74e4ae641e76f73d74348e293c244a157f6585Sunny Goyal UserHandle user = Process.myUserHandle(); 65817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler for (SessionInfo info : getAllVerifiedSessions()) { 660de011705b132eacdd10f7bfb5cdc4bd79a147e8Hyunyoung Song addSessionInfoToCache(info, user); 679448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if (info.getAppPackageName() != null) { 68756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal activePackages.put(info.getAppPackageName(), (int) (info.getProgress() * 100)); 69756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal mActiveSessions.put(info.getSessionId(), info.getAppPackageName()); 709448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 71349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 729448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal return activePackages; 73349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 74349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 757c74e4ae641e76f73d74348e293c244a157f6585Sunny Goyal @Thunk void addSessionInfoToCache(SessionInfo info, UserHandle user) { 76349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal String packageName = info.getAppPackageName(); 77349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (packageName != null) { 78349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal mCache.cachePackageInstallInfo(packageName, user, info.getAppIcon(), 79349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.getAppLabel()); 80349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 81349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 82349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 83349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal @Override 84e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onStop() { 853d0854e4b8c0a6daaa80ac14c6bc7572a4e90916Dharmesh Mokani mInstaller.unregisterSessionCallback(mCallback); 86e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 87e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 88756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal @Thunk void sendUpdate(PackageInstallInfo info) { 89e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal LauncherAppState app = LauncherAppState.getInstanceNoCreate(); 90756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (app != null) { 91756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal app.getModel().setPackageState(info); 92a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 93e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 94e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 95e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private final SessionCallback mCallback = new SessionCallback() { 96e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 97e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 98e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onCreated(int sessionId) { 99817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId); 100817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS && sessionInfo != null) { 101817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler LauncherAppState app = LauncherAppState.getInstanceNoCreate(); 102817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler if (app != null) { 103817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler app.getModel().onInstallSessionCreated( 104817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler PackageInstallInfo.fromInstallingState(sessionInfo)); 105817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 106817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 107e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 108e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 109e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 110e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onFinished(int sessionId, boolean success) { 111756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // For a finished session, we can't get the session info. So use the 112756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // packageName from our local cache. 113756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal String packageName = mActiveSessions.get(sessionId); 114756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal mActiveSessions.remove(sessionId); 115756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 116756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (packageName != null) { 117817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler sendUpdate(PackageInstallInfo.fromState( 118817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler success ? STATUS_INSTALLED : STATUS_FAILED, 119817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler packageName)); 120e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 121e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 122e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 123e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 124e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onProgressChanged(int sessionId, float progress) { 125817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler SessionInfo session = verify(mInstaller.getSessionInfo(sessionId)); 126ec88204389ffc0d5fdbe656c683d5844b9c8b49bSunny Goyal if (session != null && session.getAppPackageName() != null) { 127817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler sendUpdate(PackageInstallInfo.fromInstallingState(session)); 128e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 129e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 130e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 131e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 132f9847b9bd3e5286fe10667ec12dab5b4c43355faDharmesh Mokani public void onActiveChanged(int sessionId, boolean active) { } 133e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 134e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 135a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal public void onBadgingChanged(int sessionId) { 136756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal pushSessionDisplayToLauncher(sessionId); 137a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 138a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal 139817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler private SessionInfo pushSessionDisplayToLauncher(int sessionId) { 140817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler SessionInfo session = verify(mInstaller.getSessionInfo(sessionId)); 141ec88204389ffc0d5fdbe656c683d5844b9c8b49bSunny Goyal if (session != null && session.getAppPackageName() != null) { 142817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler mActiveSessions.put(sessionId, session.getAppPackageName()); 1437c74e4ae641e76f73d74348e293c244a157f6585Sunny Goyal addSessionInfoToCache(session, Process.myUserHandle()); 144756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal LauncherAppState app = LauncherAppState.getInstanceNoCreate(); 145756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (app != null) { 146756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal app.getModel().updateSessionDisplayInfo(session.getAppPackageName()); 147a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 148817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler return session; 149a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 150817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler return null; 151a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 152e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal }; 153817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler 154817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler private PackageInstaller.SessionInfo verify(PackageInstaller.SessionInfo sessionInfo) { 1556d696f8d7c4ce933eaea4e8d86270ef6a1fc07c3Mario Bertschler if (sessionInfo == null 1566d696f8d7c4ce933eaea4e8d86270ef6a1fc07c3Mario Bertschler || sessionInfo.getInstallerPackageName() == null 1576d696f8d7c4ce933eaea4e8d86270ef6a1fc07c3Mario Bertschler || TextUtils.isEmpty(sessionInfo.getAppPackageName())) { 158817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler return null; 159817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 160bf2d46efad889fc2b123fe191845b32095748842Mario Bertschler String pkg = sessionInfo.getInstallerPackageName(); 161817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler synchronized (mSessionVerifiedMap) { 162817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler if (!mSessionVerifiedMap.containsKey(pkg)) { 163817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mAppContext); 164817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler boolean hasSystemFlag = launcherApps.getApplicationInfo(pkg, 165817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler ApplicationInfo.FLAG_SYSTEM, Process.myUserHandle()) != null; 166817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler mSessionVerifiedMap.put(pkg, DEBUG || hasSystemFlag); 167817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 168817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 169817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler return mSessionVerifiedMap.get(pkg) ? sessionInfo : null; 170817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 171817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler 172817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler @Override 173817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler public List<SessionInfo> getAllVerifiedSessions() { 174817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler List<SessionInfo> list = new ArrayList<>(mInstaller.getAllSessions()); 175817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler Iterator<SessionInfo> it = list.iterator(); 176817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler while (it.hasNext()) { 177817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler if (verify(it.next()) == null) { 178817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler it.remove(); 179817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 180817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 181817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler return list; 182817afa34472dba49b1dee0489da11f410ff09fcdMario Bertschler } 183e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal} 184