PackageInstallerCompatVL.java revision 800a4f217a5b0b7817a70a24974fc13d6b7e4591
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.launcher3.compat;
18
19import android.content.Context;
20import android.content.pm.PackageInstaller;
21import android.content.pm.PackageInstaller.SessionCallback;
22import android.content.pm.PackageInstaller.SessionInfo;
23import android.util.Log;
24import android.util.SparseArray;
25
26import com.android.launcher3.LauncherAppState;
27import com.android.launcher3.ShortcutInfo;
28
29import java.util.ArrayList;
30
31public class PackageInstallerCompatVL extends PackageInstallerCompat {
32
33    private static final String TAG = "PackageInstallerCompatVL";
34    private static final boolean DEBUG = false;
35
36    private final SparseArray<SessionInfo> mPendingReplays = new SparseArray<SessionInfo>();
37    private final PackageInstaller mInstaller;
38
39    private boolean mResumed;
40    private boolean mBound;
41
42    PackageInstallerCompatVL(Context context) {
43        mInstaller = context.getPackageManager().getPackageInstaller();
44
45        mResumed = false;
46        mBound = false;
47
48        mInstaller.addSessionCallback(mCallback);
49        // On start, send updates for all active sessions
50        for (SessionInfo info : mInstaller.getAllSessions()) {
51            mPendingReplays.append(info.getSessionId(), info);
52        }
53    }
54
55    @Override
56    public void onStop() {
57        mInstaller.removeSessionCallback(mCallback);
58    }
59
60    @Override
61    public void onFinishBind() {
62        mBound = true;
63        replayUpdates(null);
64    }
65
66    @Override
67    public void onPause() {
68        mResumed = false;
69    }
70
71    @Override
72    public void onResume() {
73        mResumed = true;
74        replayUpdates(null);
75    }
76
77    @Override
78    public void recordPackageUpdate(String packageName, int state, int progress) {
79        // No op
80    }
81
82    private void replayUpdates(PackageInstallInfo newInfo) {
83        if (DEBUG) Log.d(TAG, "updates resumed");
84        if (!mResumed || !mBound) {
85            // Not yet ready
86            return;
87        }
88        if ((mPendingReplays.size() == 0) && (newInfo == null)) {
89            // Nothing to update
90            return;
91        }
92
93        LauncherAppState app = LauncherAppState.getInstanceNoCreate();
94        if (app == null) {
95            // Try again later
96            if (DEBUG) Log.d(TAG, "app is null, delaying send");
97            return;
98        }
99
100        ArrayList<PackageInstallInfo> updates = new ArrayList<PackageInstallInfo>();
101        if (newInfo != null) {
102            updates.add(newInfo);
103        }
104        for (int i = mPendingReplays.size() - 1; i > 0; i--) {
105            SessionInfo session = mPendingReplays.valueAt(i);
106            if (session.getAppPackageName() != null) {
107                updates.add(new PackageInstallInfo(session.getAppPackageName(),
108                        ShortcutInfo.PACKAGE_STATE_INSTALLING,
109                        (int) (session.getProgress() * 100)));
110            }
111        }
112        mPendingReplays.clear();
113        if (!updates.isEmpty()) {
114            app.setPackageState(updates);
115        }
116    }
117
118    private final SessionCallback mCallback = new SessionCallback() {
119
120        @Override
121        public void onCreated(int sessionId) {
122            SessionInfo session = mInstaller.getSessionInfo(sessionId);
123            if (session != null) {
124                mPendingReplays.put(sessionId, session);
125                replayUpdates(null);
126            }
127        }
128
129        @Override
130        public void onFinished(int sessionId, boolean success) {
131            mPendingReplays.remove(sessionId);
132            SessionInfo session = mInstaller.getSessionInfo(sessionId);
133            if ((session != null) && (session.getAppPackageName() != null)) {
134                // Replay all updates with a one time update for this installed package. No
135                // need to store this record for future updates, as the app list will get
136                // refreshed on resume.
137                replayUpdates(new PackageInstallInfo(session.getAppPackageName(),
138                        success ? ShortcutInfo.PACKAGE_STATE_DEFAULT
139                                : ShortcutInfo.PACKAGE_STATE_ERROR, 0));
140            }
141        }
142
143        @Override
144        public void onProgressChanged(int sessionId, float progress) {
145            SessionInfo session = mInstaller.getSessionInfo(sessionId);
146            if (session != null) {
147                mPendingReplays.put(sessionId, session);
148                replayUpdates(null);
149            }
150        }
151
152        @Override
153        public void onOpened(int sessionId) { }
154
155        @Override
156        public void onClosed(int sessionId) { }
157
158    };
159}
160