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; 20e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.pm.PackageInstaller; 21e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.content.pm.PackageInstaller.SessionCallback; 22800a4f217a5b0b7817a70a24974fc13d6b7e4591Sunny Goyalimport android.content.pm.PackageInstaller.SessionInfo; 23d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyalimport android.os.Handler; 24e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.util.Log; 25e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport android.util.SparseArray; 26e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 27349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport com.android.launcher3.IconCache; 28e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport com.android.launcher3.LauncherAppState; 29e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 30e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport java.util.ArrayList; 319448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyalimport java.util.HashSet; 32e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 33d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyalpublic class PackageInstallerCompatVL extends PackageInstallerCompat implements Runnable { 34e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 35e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private static final String TAG = "PackageInstallerCompatVL"; 36e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private static final boolean DEBUG = false; 37e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 38d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal // All updates to these sets must happen on the {@link #mWorker} thread. 39800a4f217a5b0b7817a70a24974fc13d6b7e4591Sunny Goyal private final SparseArray<SessionInfo> mPendingReplays = new SparseArray<SessionInfo>(); 40a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal private final HashSet<String> mPendingBadgeUpdates = new HashSet<String>(); 41d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal 42e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private final PackageInstaller mInstaller; 43349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal private final IconCache mCache; 44d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal private final Handler mWorker; 45e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 46e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private boolean mResumed; 47e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private boolean mBound; 48e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 49e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal PackageInstallerCompatVL(Context context) { 50e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mInstaller = context.getPackageManager().getPackageInstaller(); 515610fe72e01ac752153f58a3c9e615fcb997df35Sunny Goyal LauncherAppState.setApplicationContext(context.getApplicationContext()); 52349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal mCache = LauncherAppState.getInstance().getIconCache(); 53d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal mWorker = new Handler(); 54e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 55e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mResumed = false; 56e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mBound = false; 57e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 58d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal mInstaller.registerSessionCallback(mCallback, mWorker); 59393afd34566ba51f817c45a55305a9ac150d7f5bDharmesh Mokani 60e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // On start, send updates for all active sessions 61d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal mWorker.post(new Runnable() { 62d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal 63d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal @Override 64d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal public void run() { 65d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal for (SessionInfo info : mInstaller.getAllSessions()) { 66d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal mPendingReplays.append(info.getSessionId(), info); 67d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal } 68d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal } 69d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal }); 70e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 71e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 72e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 739448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal public HashSet<String> updateAndGetActiveSessionCache() { 749448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal HashSet<String> activePackages = new HashSet<String>(); 75349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal UserHandleCompat user = UserHandleCompat.myUserHandle(); 76349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal for (SessionInfo info : mInstaller.getAllSessions()) { 77349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal addSessionInfoToCahce(info, user); 789448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if (info.getAppPackageName() != null) { 799448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal activePackages.add(info.getAppPackageName()); 809448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 81349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 829448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal return activePackages; 83349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 84349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 85349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal private void addSessionInfoToCahce(SessionInfo info, UserHandleCompat user) { 86349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal String packageName = info.getAppPackageName(); 87349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (packageName != null) { 88349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal mCache.cachePackageInstallInfo(packageName, user, info.getAppIcon(), 89349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.getAppLabel()); 90349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 91349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 92349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 93349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal @Override 94e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onStop() { 953d0854e4b8c0a6daaa80ac14c6bc7572a4e90916Dharmesh Mokani mInstaller.unregisterSessionCallback(mCallback); 96e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 97e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 98e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 99e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onFinishBind() { 100e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mBound = true; 101d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal mWorker.post(this); 102e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 103e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 104e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 105e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onPause() { 106e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mResumed = false; 107e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 108e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 109e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 110e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onResume() { 111e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mResumed = true; 112d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal mWorker.post(this); 113e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 114e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 115e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 116e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void recordPackageUpdate(String packageName, int state, int progress) { 117e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // No op 118e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 119e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 120d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal @Override 121d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal public void run() { 122d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal // Called on mWorker thread. 123d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal replayUpdates(null); 124d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal } 125d90e938db0523c13f0301ea8cbb2cef4cf044efcSunny Goyal 126e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private void replayUpdates(PackageInstallInfo newInfo) { 127e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if (DEBUG) Log.d(TAG, "updates resumed"); 128e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if (!mResumed || !mBound) { 129e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // Not yet ready 130e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal return; 131e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 132e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if ((mPendingReplays.size() == 0) && (newInfo == null)) { 133e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // Nothing to update 134e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal return; 135e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 136e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 137e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal LauncherAppState app = LauncherAppState.getInstanceNoCreate(); 138e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if (app == null) { 139e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // Try again later 140e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if (DEBUG) Log.d(TAG, "app is null, delaying send"); 141e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal return; 142e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 143e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 14465c6011d0954223c14a0e6127cf307c18f7c2c0dSameer Padala ArrayList<PackageInstallInfo> updates = new ArrayList<PackageInstallInfo>(); 145349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if ((newInfo != null) && (newInfo.state != STATUS_INSTALLED)) { 146e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal updates.add(newInfo); 147e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 148349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal for (int i = mPendingReplays.size() - 1; i >= 0; i--) { 149800a4f217a5b0b7817a70a24974fc13d6b7e4591Sunny Goyal SessionInfo session = mPendingReplays.valueAt(i); 150e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if (session.getAppPackageName() != null) { 151e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal updates.add(new PackageInstallInfo(session.getAppPackageName(), 152349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal STATUS_INSTALLING, 153e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal (int) (session.getProgress() * 100))); 154e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 155e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 156e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mPendingReplays.clear(); 157e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if (!updates.isEmpty()) { 158e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal app.setPackageState(updates); 159e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 160a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal 161a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal if (!mPendingBadgeUpdates.isEmpty()) { 162a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal for (String pkg : mPendingBadgeUpdates) { 163a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal app.updatePackageBadge(pkg); 164a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 165a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal mPendingBadgeUpdates.clear(); 166a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 167e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 168e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 169e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal private final SessionCallback mCallback = new SessionCallback() { 170e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 171e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 172e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onCreated(int sessionId) { 173a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal pushSessionBadgeToLauncher(sessionId); 174e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 175e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 176e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 177e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onFinished(int sessionId, boolean success) { 178e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mPendingReplays.remove(sessionId); 179800a4f217a5b0b7817a70a24974fc13d6b7e4591Sunny Goyal SessionInfo session = mInstaller.getSessionInfo(sessionId); 180e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if ((session != null) && (session.getAppPackageName() != null)) { 181a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal mPendingBadgeUpdates.remove(session.getAppPackageName()); 182e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // Replay all updates with a one time update for this installed package. No 183e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // need to store this record for future updates, as the app list will get 184e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal // refreshed on resume. 185e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal replayUpdates(new PackageInstallInfo(session.getAppPackageName(), 186349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal success ? STATUS_INSTALLED : STATUS_FAILED, 0)); 187e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 188e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 189e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 190e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 191e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void onProgressChanged(int sessionId, float progress) { 192800a4f217a5b0b7817a70a24974fc13d6b7e4591Sunny Goyal SessionInfo session = mInstaller.getSessionInfo(sessionId); 193e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal if (session != null) { 194e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal mPendingReplays.put(sessionId, session); 195e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal replayUpdates(null); 196e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 197e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal } 198e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 199e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 200f9847b9bd3e5286fe10667ec12dab5b4c43355faDharmesh Mokani public void onActiveChanged(int sessionId, boolean active) { } 201e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal 202e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal @Override 203a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal public void onBadgingChanged(int sessionId) { 204a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal pushSessionBadgeToLauncher(sessionId); 205a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 206a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal 207a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal private void pushSessionBadgeToLauncher(int sessionId) { 208a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal SessionInfo session = mInstaller.getSessionInfo(sessionId); 209a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal if (session != null) { 210a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal addSessionInfoToCahce(session, UserHandleCompat.myUserHandle()); 211a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal if (session.getAppPackageName() != null) { 212a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal mPendingBadgeUpdates.add(session.getAppPackageName()); 213a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 214a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal mPendingReplays.put(sessionId, session); 215a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal replayUpdates(null); 216a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 217a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 218e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal }; 219e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal} 220