13a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey/*
23a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * Copyright (C) 2014 The Android Open Source Project
33a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey *
43a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
53a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * you may not use this file except in compliance with the License.
63a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * You may obtain a copy of the License at
73a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey *
83a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
93a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey *
103a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
113a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
123a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * See the License for the specific language governing permissions and
143a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * limitations under the License.
153a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey */
163a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
173a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkeypackage android.content.pm;
183a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
1916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.annotation.NonNull;
2016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.annotation.Nullable;
217121e18595d4c559044e26bfe6035406a862f466Svet Ganovimport android.annotation.RequiresPermission;
221cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport android.annotation.SdkConstant;
231cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport android.annotation.SdkConstant.SdkConstantType;
247121e18595d4c559044e26bfe6035406a862f466Svet Ganovimport android.annotation.SystemApi;
25a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.app.ActivityManager;
26a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.content.Context;
27fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkeyimport android.content.Intent;
28a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.content.IntentSender;
29a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.graphics.Bitmap;
30a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.net.Uri;
3178cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport android.os.FileBridge;
3216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.os.Handler;
3316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.os.Looper;
3416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.os.Message;
35a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.os.Parcel;
363a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkeyimport android.os.ParcelFileDescriptor;
37a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.os.Parcelable;
383a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkeyimport android.os.RemoteException;
39a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkeyimport android.util.ExceptionUtils;
40a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
41a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
423a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
43ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkeyimport java.io.Closeable;
44a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkeyimport java.io.IOException;
451cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport java.io.InputStream;
4678cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.io.OutputStream;
471cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport java.security.MessageDigest;
4816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport java.util.ArrayList;
4916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport java.util.Iterator;
50bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkeyimport java.util.List;
5178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
526c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey/**
536c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * Offers the ability to install, upgrade, and remove applications on the
546c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * device. This includes support for apps packaged either as a single
556c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * "monolithic" APK, or apps packaged as multiple "split" APKs.
566c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <p>
576c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * An app is delivered for installation through a
586c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * {@link PackageInstaller.Session}, which any app can create. Once the session
596c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * is created, the installer can stream one or more APKs into place until it
606c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * decides to either commit or destroy the session. Committing may require user
616c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * intervention to complete the installation.
626c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <p>
636c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * Sessions can install brand new apps, upgrade existing apps, or add new splits
64da96e137bcc8191c584ada7b5de31eaae92f244fJeff Sharkey * into an existing app.
656c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <p>
66da96e137bcc8191c584ada7b5de31eaae92f244fJeff Sharkey * Apps packaged as multiple split APKs always consist of a single "base" APK
676c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * (with a {@code null} split name) and zero or more "split" APKs (with unique
686c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * split names). Any subset of these APKs can be installed together, as long as
696c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * the following constraints are met:
706c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <ul>
716c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <li>All APKs must have the exact same package name, version code, and signing
726c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * certificates.
736c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <li>All APKs must have unique split names.
74da96e137bcc8191c584ada7b5de31eaae92f244fJeff Sharkey * <li>All installations must contain a single base APK.
756c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * </ul>
766c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey */
773a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkeypublic class PackageInstaller {
78a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    private static final String TAG = "PackageInstaller";
79a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
801cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    /**
811cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * Activity Action: Show details about a particular install session. This
821cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * may surface actions such as pause, resume, or cancel.
831cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <p>
841cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * This should always be scoped to the installer package that owns the
85de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey     * session. Clients should use {@link SessionInfo#createDetailsIntent()} to
86a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * build this intent correctly.
871cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <p>
881cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * In some cases, a matching Activity may not exist, so ensure you safeguard
891cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * against this.
90941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
91941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The session to show details for is defined in {@link #EXTRA_SESSION_ID}.
921cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     */
931cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
941cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    public static final String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
951cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
967328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    /** {@hide} */
977328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    public static final String
987328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey            ACTION_CONFIRM_PERMISSIONS = "android.content.pm.action.CONFIRM_PERMISSIONS";
997328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey
1001cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    /**
101941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * An integer session ID that an operation is working with.
1021cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     *
103941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getIntExtra(String, int)
1041cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     */
1051cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    public static final String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
1061cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
107941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
108941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Package name that an operation is working with.
109941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
110941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getStringExtra(String)
111941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
112941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    public static final String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
113941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey
114941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
115941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Current status of an operation. Will be one of
116941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_PENDING_USER_ACTION}, {@link #STATUS_SUCCESS},
117941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE}, {@link #STATUS_FAILURE_ABORTED},
118941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE_BLOCKED}, {@link #STATUS_FAILURE_CONFLICT},
119941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID}, or
120941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE_STORAGE}.
121941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
122941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * More information about a status may be available through additional
123941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * extras; see the individual status documentation for details.
124941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
125941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getIntExtra(String, int)
126941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
127a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_STATUS = "android.content.pm.extra.STATUS";
128941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey
129941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
130941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Detailed string representation of the status, including raw details that
131941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * are useful for debugging.
132941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
133941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getStringExtra(String)
134941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
135a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
136a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
137a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
138941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Another package name relevant to a status. This is typically the package
139941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * responsible for causing an operation failure.
140a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
141bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey     * @see Intent#getStringExtra(String)
142a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
143941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    public static final String
144941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey            EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME";
145941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey
146941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
147941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Storage path relevant to a status.
148941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
149941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getStringExtra(String)
150941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
151941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    public static final String EXTRA_STORAGE_PATH = "android.content.pm.extra.STORAGE_PATH";
152bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey
153bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey    /** {@hide} */
154bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey    @Deprecated
155a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_PACKAGE_NAMES = "android.content.pm.extra.PACKAGE_NAMES";
156a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
157a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /** {@hide} */
158a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
159a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /** {@hide} */
160a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_LEGACY_BUNDLE = "android.content.pm.extra.LEGACY_BUNDLE";
161f06009542390472872da986486d385001e91a2a7Jeff Sharkey    /** {@hide} */
162f06009542390472872da986486d385001e91a2a7Jeff Sharkey    public static final String EXTRA_CALLBACK = "android.content.pm.extra.CALLBACK";
163f06009542390472872da986486d385001e91a2a7Jeff Sharkey
164a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
165a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * User action is currently required to proceed. You can launch the intent
166a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * activity described by {@link Intent#EXTRA_INTENT} to involve the user and
167a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * continue.
168a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * <p>
169a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * You may choose to immediately launch the intent if the user is actively
170a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * using your app. Otherwise, you should use a notification to guide the
171a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * user back into your app before launching.
172a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
173a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see Intent#getParcelableExtra(String)
174a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
175742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_PENDING_USER_ACTION = -1;
176a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
177a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
178a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation succeeded.
179a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
180a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final int STATUS_SUCCESS = 0;
181a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
182a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
183a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed in a generic way. The system will always try to
184a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * provide a more specific failure reason, but in some rare cases this may
185a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * be delivered.
186a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
187a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
188a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
189a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final int STATUS_FAILURE = 1;
190a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
191a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
192a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it was blocked. For example, a device policy
193a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * may be blocking the operation, a package verifier may have blocked the
194a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * operation, or the app may be required for core system operation.
195941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
196941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The result may also contain {@link #EXTRA_OTHER_PACKAGE_NAME} with the
197941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * specific package blocking the install.
198a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
199a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
200941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see #EXTRA_OTHER_PACKAGE_NAME
201a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
202742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_BLOCKED = 2;
203a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
204a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
205a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it was actively aborted. For example, the
206a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * user actively declined requested permissions, or the session was
207a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * abandoned.
208a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
209a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
210a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
211742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_ABORTED = 3;
212a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
213a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
214a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because one or more of the APKs was invalid. For
215a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * example, they might be malformed, corrupt, incorrectly signed,
216a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * mismatched, etc.
217a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
218a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
219a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
220742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_INVALID = 4;
221a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
222a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
223a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it conflicts (or is inconsistent with) with
224a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * another package already installed on the device. For example, an existing
225a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * permission, incompatible certificates, etc. The user may be able to
226a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * uninstall another app to fix the issue.
227a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * <p>
228941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The result may also contain {@link #EXTRA_OTHER_PACKAGE_NAME} with the
229bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey     * specific package identified as the cause of the conflict.
230a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
231a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
232941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see #EXTRA_OTHER_PACKAGE_NAME
233a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
234742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_CONFLICT = 5;
235a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
236a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
237a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because of storage issues. For example, the device
238a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * may be running low on space, or external media may be unavailable. The
239a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * user may be able to help free space or insert different external media.
240941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
241941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The result may also contain {@link #EXTRA_STORAGE_PATH} with the path to
242941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * the storage device that caused the failure.
243a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
244a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
245941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see #EXTRA_STORAGE_PATH
246a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
247742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_STORAGE = 6;
248a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
249a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
250a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it is fundamentally incompatible with this
251a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * device. For example, the app may require a hardware feature that doesn't
252a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * exist, it may be missing native code for the ABIs supported by the
253a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * device, or it requires a newer SDK version, etc.
254a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
255a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
256a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
257742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_INCOMPATIBLE = 7;
258a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
259a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    private final Context mContext;
2603a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    private final PackageManager mPm;
2613a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    private final IPackageInstaller mInstaller;
2623a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    private final int mUserId;
2633a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    private final String mInstallerPackageName;
2643a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
26516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    private final ArrayList<SessionCallbackDelegate> mDelegates = new ArrayList<>();
26616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
2673a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    /** {@hide} */
268a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public PackageInstaller(Context context, PackageManager pm, IPackageInstaller installer,
269ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey            String installerPackageName, int userId) {
270a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        mContext = context;
2713a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        mPm = pm;
2723a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        mInstaller = installer;
2733a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        mInstallerPackageName = installerPackageName;
274ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey        mUserId = userId;
2753a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
2763a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
2776c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
2786c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * Create a new session using the given parameters, returning a unique ID
2796c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * that represents the session. Once created, the session can be opened
2806c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * multiple times across multiple device boots.
2816c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * <p>
2826c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * The system may automatically destroy sessions that have not been
2836c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * finalized (either committed or abandoned) within a reasonable period of
2846c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * time, typically on the order of a day.
2856c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     *
2866c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * @throws IOException if parameters were unsatisfiable, such as lack of
2876c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     *             disk space or unavailable media.
28877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when installation services are unavailable,
28977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             such as when called from a restricted user.
29077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws IllegalArgumentException when {@link SessionParams} is invalid.
291f174c6e6de6ba863179401aa7b3d55d91ceed707Jeff Sharkey     * @return positive, non-zero unique ID that represents the created session.
292f174c6e6de6ba863179401aa7b3d55d91ceed707Jeff Sharkey     *         This ID remains consistent across device reboots until the
293f174c6e6de6ba863179401aa7b3d55d91ceed707Jeff Sharkey     *         session is finalized. IDs are not reused during a given boot.
2946c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
295a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public int createSession(@NonNull SessionParams params) throws IOException {
2963a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
29716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            return mInstaller.createSession(params, mInstallerPackageName, mUserId);
298a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        } catch (RuntimeException e) {
299a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            ExceptionUtils.maybeUnwrapIOException(e);
300a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            throw e;
3013a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        } catch (RemoteException e) {
302f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
3033a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
3043a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
3053a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
3066c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
30716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * Open an existing session to actively perform work. To succeed, the caller
30816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * must be the owner of the install session.
30977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
31077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws IOException if parameters were unsatisfiable, such as lack of
31177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             disk space or unavailable media.
31277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
31377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
3146c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
315bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey    public @NonNull Session openSession(int sessionId) throws IOException {
3163a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
3173a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            return new Session(mInstaller.openSession(sessionId));
318bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        } catch (RuntimeException e) {
319bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            ExceptionUtils.maybeUnwrapIOException(e);
320bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            throw e;
3213a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        } catch (RemoteException e) {
322f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
3233a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
324381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey    }
325381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey
326ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /**
327ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * Update the icon representing the app being installed in a specific
328ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * session. This should be roughly
329ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * {@link ActivityManager#getLauncherLargeIconSize()} in both dimensions.
33077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
33177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
33277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
333ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     */
334ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void updateSessionAppIcon(int sessionId, @Nullable Bitmap appIcon) {
335ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        try {
336ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            mInstaller.updateSessionAppIcon(sessionId, appIcon);
337ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        } catch (RemoteException e) {
338f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
339ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        }
340ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
341ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
342ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /**
343ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * Update the label representing the app being installed in a specific
344ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * session.
34577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
34677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
34777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
348ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     */
349ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void updateSessionAppLabel(int sessionId, @Nullable CharSequence appLabel) {
350ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        try {
351ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            final String val = (appLabel != null) ? appLabel.toString() : null;
352ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            mInstaller.updateSessionAppLabel(sessionId, val);
353ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        } catch (RemoteException e) {
354f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
355ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        }
356ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
357ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
35877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey    /**
35977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Completely abandon the given session, destroying all staged data and
36077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * rendering it invalid. Abandoned sessions will be reported to
36177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * {@link SessionCallback} listeners as failures. This is equivalent to
36277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * opening the session and calling {@link Session#abandon()}.
36377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
36477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
36577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
36677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     */
367381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey    public void abandonSession(int sessionId) {
368381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey        try {
369381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey            mInstaller.abandonSession(sessionId);
370381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey        } catch (RemoteException e) {
371f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
372381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey        }
3733a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
3743a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
3756c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
37677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Return details for a specific session. No special permissions are
37777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * required to retrieve these details.
37877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
37977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @return details for the requested session, or {@code null} if the session
38077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *         does not exist.
3816c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
382a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public @Nullable SessionInfo getSessionInfo(int sessionId) {
3833a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
38416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            return mInstaller.getSessionInfo(sessionId);
38516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        } catch (RemoteException e) {
386f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
38716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
38816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
38916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
39016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /**
39177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Return list of all known install sessions, regardless of the installer.
39216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     */
393a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public @NonNull List<SessionInfo> getAllSessions() {
39416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        try {
39597d47ed036ff7bd3d7d2ddc1c6df1104ec237559Jeff Sharkey            return mInstaller.getAllSessions(mUserId).getList();
39616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        } catch (RemoteException e) {
397f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
39816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
39916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
40016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
40116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /**
40277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Return list of all known install sessions owned by the calling app.
40316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     */
404a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public @NonNull List<SessionInfo> getMySessions() {
40516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        try {
40697d47ed036ff7bd3d7d2ddc1c6df1104ec237559Jeff Sharkey            return mInstaller.getMySessions(mInstallerPackageName, mUserId).getList();
4073a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        } catch (RemoteException e) {
408f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
4093a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
4103a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
4113a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
4126c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
4136c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * Uninstall the given package, removing it completely from the device. This
4146c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * method is only available to the current "installer of record" for the
4156c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * package.
4166c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
417a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public void uninstall(@NonNull String packageName, @NonNull IntentSender statusReceiver) {
4183a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
41939fb7fd730dc2113ced7e663d7a35e48a4c6b1aeBenjamin Franz            mInstaller.uninstall(packageName, mInstallerPackageName, 0, statusReceiver, mUserId);
420bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        } catch (RemoteException e) {
421f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
422bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
423bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
424bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
4257328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    /** {@hide} */
4267328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    public void setPermissionsResult(int sessionId, boolean accepted) {
4277328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        try {
4287328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey            mInstaller.setPermissionsResult(sessionId, accepted);
4297328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        } catch (RemoteException e) {
430f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
4317328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        }
4327328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    }
4337328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey
4346c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
4356c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * Events for observing session lifecycle.
4361cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <p>
4371cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * A typical session lifecycle looks like this:
4381cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <ul>
4391cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <li>An installer creates a session to indicate pending app delivery. All
4401cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * install details are available at this point.
4411cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <li>The installer opens the session to deliver APK data. Note that a
4421cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * session may be opened and closed multiple times as network connectivity
4431cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * changes. The installer may deliver periodic progress updates.
4441cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <li>The installer commits or abandons the session, resulting in the
4451cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * session being finished.
4461cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * </ul>
4476c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
44816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    public static abstract class SessionCallback {
4496c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
4501cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * New session has been created. Details about the session can be
4511cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * obtained from {@link PackageInstaller#getSessionInfo(int)}.
4526c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
45316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public abstract void onCreated(int sessionId);
4546c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey
4556c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
456ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey         * Badging details for an existing session has changed. For example, the
457ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey         * app icon or label has been updated.
458ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey         */
459ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        public abstract void onBadgingChanged(int sessionId);
460ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
461ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        /**
462bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Active state for session has been changed.
463bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
464bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * A session is considered active whenever there is ongoing forward
465bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * progress being made, such as the installer holding an open
466bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session} instance while streaming data into place, or the
467bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system optimizing code as the result of
468bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session#commit(IntentSender)}.
469bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
470bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * If the installer closes the {@link Session} without committing, the
471bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * session is considered inactive until the installer opens the session
472bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * again.
4731cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         */
474bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public abstract void onActiveChanged(int sessionId, boolean active);
4751cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
4761cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        /**
4776c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Progress for given session has been updated.
4786c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * <p>
4796c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Note that this progress may not directly correspond to the value
480bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * reported by
481bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link PackageInstaller.Session#setStagingProgress(float)}, as the
482bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system may carve out a portion of the overall progress to represent
483bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * its own internal installation work.
4846c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
48516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public abstract void onProgressChanged(int sessionId, float progress);
4866c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey
4876c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
48816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * Session has completely finished, either with success or failure.
4896c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
49016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public abstract void onFinished(int sessionId, boolean success);
49116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
49216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
49316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /** {@hide} */
49416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    private static class SessionCallbackDelegate extends IPackageInstallerCallback.Stub implements
49516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            Handler.Callback {
49616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        private static final int MSG_SESSION_CREATED = 1;
497ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        private static final int MSG_SESSION_BADGING_CHANGED = 2;
498bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        private static final int MSG_SESSION_ACTIVE_CHANGED = 3;
499ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        private static final int MSG_SESSION_PROGRESS_CHANGED = 4;
500bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        private static final int MSG_SESSION_FINISHED = 5;
50116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
50216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        final SessionCallback mCallback;
50316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        final Handler mHandler;
50416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
50516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public SessionCallbackDelegate(SessionCallback callback, Looper looper) {
50616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mCallback = callback;
50716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler = new Handler(looper, this);
50816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
50916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
51016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
51116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public boolean handleMessage(Message msg) {
512bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            final int sessionId = msg.arg1;
51316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            switch (msg.what) {
51416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                case MSG_SESSION_CREATED:
515bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onCreated(sessionId);
51616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    return true;
517ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey                case MSG_SESSION_BADGING_CHANGED:
518bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onBadgingChanged(sessionId);
519ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey                    return true;
520bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                case MSG_SESSION_ACTIVE_CHANGED:
521bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    final boolean active = msg.arg2 != 0;
522bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onActiveChanged(sessionId, active);
5231cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                    return true;
52416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                case MSG_SESSION_PROGRESS_CHANGED:
525bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onProgressChanged(sessionId, (float) msg.obj);
5261cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                    return true;
52716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                case MSG_SESSION_FINISHED:
528bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onFinished(sessionId, msg.arg2 != 0);
52916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    return true;
53016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
53116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            return false;
53216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
53316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
53416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
53516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void onSessionCreated(int sessionId) {
53616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_CREATED, sessionId, 0).sendToTarget();
53716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
53816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
53916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
540ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        public void onSessionBadgingChanged(int sessionId) {
541ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_BADGING_CHANGED, sessionId, 0).sendToTarget();
542ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        }
543ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
544ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        @Override
545bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public void onSessionActiveChanged(int sessionId, boolean active) {
546bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_ACTIVE_CHANGED, sessionId, active ? 1 : 0)
547bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    .sendToTarget();
5481cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        }
5491cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
5501cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        @Override
55116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void onSessionProgressChanged(int sessionId, float progress) {
55216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_PROGRESS_CHANGED, sessionId, 0, progress)
55316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    .sendToTarget();
55416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
55516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
55616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
55716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void onSessionFinished(int sessionId, boolean success) {
55816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_FINISHED, sessionId, success ? 1 : 0)
55916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    .sendToTarget();
56016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
561bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
562bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
563ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /** {@hide} */
564ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    @Deprecated
565ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void addSessionCallback(@NonNull SessionCallback callback) {
566ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        registerSessionCallback(callback);
567ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
568ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
5696c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
57077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Register to watch for session lifecycle events. No special permissions
57177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * are required to watch for these events.
5726c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
573ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void registerSessionCallback(@NonNull SessionCallback callback) {
574ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        registerSessionCallback(callback, new Handler());
575ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
576ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
577ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /** {@hide} */
578ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    @Deprecated
579ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void addSessionCallback(@NonNull SessionCallback callback, @NonNull Handler handler) {
580ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        registerSessionCallback(callback, handler);
58116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
58216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
58316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /**
58477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Register to watch for session lifecycle events. No special permissions
58577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * are required to watch for these events.
58616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     *
58716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * @param handler to dispatch callback events through, otherwise uses
58816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     *            calling thread.
58916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     */
590ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void registerSessionCallback(@NonNull SessionCallback callback, @NonNull Handler handler) {
59116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        synchronized (mDelegates) {
59216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            final SessionCallbackDelegate delegate = new SessionCallbackDelegate(callback,
59316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    handler.getLooper());
59416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            try {
59516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                mInstaller.registerCallback(delegate, mUserId);
59616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            } catch (RemoteException e) {
597f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
59816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
59916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mDelegates.add(delegate);
600bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
601bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
602bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
603ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /** {@hide} */
604ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    @Deprecated
605ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void removeSessionCallback(@NonNull SessionCallback callback) {
606ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        unregisterSessionCallback(callback);
607ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
608ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
6096c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
61077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Unregister a previously registered callback.
6116c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
612ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void unregisterSessionCallback(@NonNull SessionCallback callback) {
61316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        synchronized (mDelegates) {
61416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            for (Iterator<SessionCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
61516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                final SessionCallbackDelegate delegate = i.next();
61616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                if (delegate.mCallback == callback) {
61716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    try {
61816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                        mInstaller.unregisterCallback(delegate);
61916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    } catch (RemoteException e) {
620f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                        throw e.rethrowFromSystemServer();
62116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    }
62216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    i.remove();
62316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                }
62416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
6253a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
6263a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
6273a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
6283a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    /**
6293a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * An installation that is being actively staged. For an install to succeed,
6303a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * all existing and new packages must have identical package names, version
6313a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * codes, and signing certificates.
6323a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * <p>
6333a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * A session may contain any number of split packages. If the application
6343a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * does not yet exist, this session must include a base package.
6353a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * <p>
63616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * If an APK included in this session is already defined by the existing
63716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * installation (for example, the same split name), the APK in this session
63816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * will replace the existing APK.
6393a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     */
640ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey    public static class Session implements Closeable {
6413a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        private IPackageInstallerSession mSession;
6423a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
6433a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        /** {@hide} */
6443a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        public Session(IPackageInstallerSession session) {
6453a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            mSession = session;
6463a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
6473a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
648bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        /** {@hide} */
649bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        @Deprecated
650bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public void setProgress(float progress) {
651bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            setStagingProgress(progress);
652bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        }
653bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey
6546c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
655bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Set current progress of staging this session. Valid values are
656bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * anywhere between 0 and 1.
657bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
658bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Note that this progress may not directly correspond to the value
659bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * reported by {@link SessionCallback#onProgressChanged(int, float)}, as
660bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * the system may carve out a portion of the overall progress to
661bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * represent its own internal installation work.
6626c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
663bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public void setStagingProgress(float progress) {
6643a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
665a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                mSession.setClientProgress(progress);
666a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            } catch (RemoteException e) {
667f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
668a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            }
669a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        }
670a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey
671a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        /** {@hide} */
67216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void addProgress(float progress) {
673a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            try {
674a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                mSession.addClientProgress(progress);
6753a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
676f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
6773a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
6783a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
6793a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
68078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        /**
68116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * Open a stream to write an APK file into the session.
68216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * <p>
68316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * The returned stream will start writing data at the requested offset
68416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * in the underlying file, which can be used to resume a partially
68516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * written file. If a valid file length is specified, the system will
68616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * preallocate the underlying disk space to optimize placement on disk.
68716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * It's strongly recommended to provide a valid file length when known.
68816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * <p>
68916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * You can write data into the returned stream, optionally call
69016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * {@link #fsync(OutputStream)} as needed to ensure bytes have been
69116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * persisted to disk, and then close when finished. All streams must be
692a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * closed before calling {@link #commit(IntentSender)}.
69316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *
69416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * @param name arbitrary, unique name of your choosing to identify the
69516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            APK being written. You can open a file again for
69616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            additional writes (such as after a reboot) by using the
69716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            same name. This name is only meaningful within the context
69816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            of a single install session.
69916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * @param offsetBytes offset into the file to begin writing at, or 0 to
70016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            start at the beginning of the file.
70116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * @param lengthBytes total size of the file being written, used to
70216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            preallocate the underlying disk space, or -1 if unknown.
70377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *            The system may clear various caches as needed to allocate
70477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *            this space.
70577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws IOException if trouble opening the file for writing, such as
70677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             lack of disk space or unavailable media.
70777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if called after the session has been
70877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             committed or abandoned.
70978cc340c2de873d6995c283b777476f7237d690fJeff Sharkey         */
71016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public @NonNull OutputStream openWrite(@NonNull String name, long offsetBytes,
71116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                long lengthBytes) throws IOException {
7123a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
71316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                final ParcelFileDescriptor clientSocket = mSession.openWrite(name,
71478cc340c2de873d6995c283b777476f7237d690fJeff Sharkey                        offsetBytes, lengthBytes);
7159a1507aa10577badabcbe00396613a967302e456Jeff Sharkey                return new FileBridge.FileBridgeOutputStream(clientSocket);
716a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            } catch (RuntimeException e) {
717a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                ExceptionUtils.maybeUnwrapIOException(e);
718a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                throw e;
7193a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
720f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
7213a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
7223a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
7233a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
7246c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
7256c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Ensure that any outstanding data for given stream has been committed
7266c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * to disk. This is only valid for streams returned from
7276c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * {@link #openWrite(String, long, long)}.
7286c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
72916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void fsync(@NonNull OutputStream out) throws IOException {
730a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            if (out instanceof FileBridge.FileBridgeOutputStream) {
731a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                ((FileBridge.FileBridgeOutputStream) out).fsync();
732a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            } else {
733a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                throw new IllegalArgumentException("Unrecognized stream");
734a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            }
735a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        }
736a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey
7376c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
738a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return all APK names contained in this session.
7391cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * <p>
7401cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * This returns all names which have been previously written through
7411cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * {@link #openWrite(String, long, long)} as part of this session.
74277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *
74377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if called after the session has been
74477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             committed or abandoned.
7451cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         */
746742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey        public @NonNull String[] getNames() throws IOException {
7471cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            try {
748a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                return mSession.getNames();
749742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey            } catch (RuntimeException e) {
750742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey                ExceptionUtils.maybeUnwrapIOException(e);
751742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey                throw e;
7521cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            } catch (RemoteException e) {
753f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
7541cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            }
7551cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        }
7561cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
7571cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        /**
7581cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * Open a stream to read an APK file from the session.
7591cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * <p>
7601cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * This is only valid for names which have been previously written
7611cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * through {@link #openWrite(String, long, long)} as part of this
7621cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * session. For example, this stream may be used to calculate a
7631cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * {@link MessageDigest} of a written APK before committing.
76477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *
76577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if called after the session has been
76677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             committed or abandoned.
7671cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         */
7681cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        public @NonNull InputStream openRead(@NonNull String name) throws IOException {
7691cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            try {
7701cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                final ParcelFileDescriptor pfd = mSession.openRead(name);
7711cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                return new ParcelFileDescriptor.AutoCloseInputStream(pfd);
7721cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            } catch (RuntimeException e) {
7731cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                ExceptionUtils.maybeUnwrapIOException(e);
774eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                throw e;
775eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            } catch (RemoteException e) {
776eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                throw e.rethrowFromSystemServer();
777eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            }
778eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy        }
779eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy
780eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy        /**
781eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * Removes a split.
782eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * <p>
783eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * Split removals occur prior to adding new APKs. If upgrading a feature
784eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * split, it is not expected nor desirable to remove the split prior to
785eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * upgrading.
786eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * <p>
787eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * When split removal is bundled with new APKs, the packageName must be
788eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * identical.
789eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         */
790eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy        public void removeSplit(@NonNull String splitName) throws IOException {
791eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            try {
792eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                mSession.removeSplit(splitName);
793eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            } catch (RuntimeException e) {
794eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                ExceptionUtils.maybeUnwrapIOException(e);
7951cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                throw e;
7961cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            } catch (RemoteException e) {
797f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
7981cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            }
7991cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        }
8001cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
8011cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        /**
8026c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Attempt to commit everything staged in this session. This may require
8036c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * user intervention, and so it may not happen immediately. The final
8046c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * result of the commit will be reported through the given callback.
8056c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * <p>
8066c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Once this method is called, no additional mutations may be performed
8076c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * on the session. If the device reboots before the session has been
8086c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * finalized, you may commit the session again.
80977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *
81077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if streams opened through
81177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             {@link #openWrite(String, long, long)} are still open.
8126c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
813a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void commit(@NonNull IntentSender statusReceiver) {
8143a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
815a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                mSession.commit(statusReceiver);
8163a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
817f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
8183a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
8193a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
8203a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
8216c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
8226c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Release this session object. You can open the session again if it
8236c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * hasn't been finalized.
8246c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
825ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey        @Override
8263a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        public void close() {
82716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            try {
82816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                mSession.close();
82916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            } catch (RemoteException e) {
830f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
83116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
8323a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
8333a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
8346c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
83516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * Completely abandon this session, destroying all staged data and
83677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * rendering it invalid. Abandoned sessions will be reported to
83777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * {@link SessionCallback} listeners as failures. This is equivalent to
83877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * opening the session and calling {@link Session#abandon()}.
8396c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
84016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void abandon() {
8413a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
84216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                mSession.abandon();
8433a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
844f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
8453a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
8463a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
8473a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
848bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
8496c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
850a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * Parameters for creating a new {@link PackageInstaller.Session}.
8516c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
852a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static class SessionParams implements Parcelable {
853a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
854a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
855a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final int MODE_INVALID = -1;
856a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
857a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
858a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Mode for an install session whose staged APKs should fully replace any
859a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * existing APKs for the target app.
860a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
861a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final int MODE_FULL_INSTALL = 1;
862a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
863a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
864a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Mode for an install session that should inherit any existing APKs for the
865a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * target app, unless they have been explicitly overridden (based on split
866a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * name) by the session. For example, this can be used to add one or more
867a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * split APKs to an existing installation.
868a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * <p>
869a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * If there are no existing APKs for the target app, this behaves like
870a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * {@link #MODE_FULL_INSTALL}.
871a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
872a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final int MODE_INHERIT_EXISTING = 2;
873a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
874a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
875a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public static final int UID_UNKNOWN = -1;
876a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy
877a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /** {@hide} */
878a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int mode = MODE_INVALID;
879a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
880a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int installFlags;
881a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
882a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
883a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
884a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public long sizeBytes = -1;
885a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
886a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String appPackageName;
887a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
888a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Bitmap appIcon;
889a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
890a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String appLabel;
891a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
89202bd78490d8594d225ecc70a74b2058cb968a657Jeff Sharkey        public long appIconLastModified = -1;
89302bd78490d8594d225ecc70a74b2058cb968a657Jeff Sharkey        /** {@hide} */
894a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Uri originatingUri;
895a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
896a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public int originatingUid = UID_UNKNOWN;
897a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /** {@hide} */
898a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Uri referrerUri;
899a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
900a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String abiOverride;
901b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        /** {@hide} */
902b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        public String volumeUuid;
9037121e18595d4c559044e26bfe6035406a862f466Svet Ganov        /** {@hide} */
9047121e18595d4c559044e26bfe6035406a862f466Svet Ganov        public String[] grantedRuntimePermissions;
905a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
906fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        /**
907a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Construct parameters for a new package install session.
908a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
909a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @param mode one of {@link #MODE_FULL_INSTALL} or
910a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *            {@link #MODE_INHERIT_EXISTING} describing how the session
911a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *            should interact with an existing app.
912f06009542390472872da986486d385001e91a2a7Jeff Sharkey         */
913a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionParams(int mode) {
914a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.mode = mode;
915a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
916a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
917a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
918a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionParams(Parcel source) {
919a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            mode = source.readInt();
920a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            installFlags = source.readInt();
921a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            installLocation = source.readInt();
922a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sizeBytes = source.readLong();
923a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appPackageName = source.readString();
924a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appIcon = source.readParcelable(null);
925a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appLabel = source.readString();
926a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            originatingUri = source.readParcelable(null);
927a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            originatingUid = source.readInt();
928a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            referrerUri = source.readParcelable(null);
929a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            abiOverride = source.readString();
930b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            volumeUuid = source.readString();
9317121e18595d4c559044e26bfe6035406a862f466Svet Ganov            grantedRuntimePermissions = source.readStringArray();
932a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
933f06009542390472872da986486d385001e91a2a7Jeff Sharkey
934f06009542390472872da986486d385001e91a2a7Jeff Sharkey        /**
935a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Provide value of {@link PackageInfo#installLocation}, which may be used
936a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * to determine where the app will be staged. Defaults to
937a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * {@link PackageInfo#INSTALL_LOCATION_INTERNAL_ONLY}.
938f06009542390472872da986486d385001e91a2a7Jeff Sharkey         */
939a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setInstallLocation(int installLocation) {
940a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.installLocation = installLocation;
941a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
942f06009542390472872da986486d385001e91a2a7Jeff Sharkey
943f06009542390472872da986486d385001e91a2a7Jeff Sharkey        /**
944a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally indicate the total size (in bytes) of all APKs that will be
945a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * delivered in this session. The system may use this to ensure enough disk
946a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * space exists before proceeding, or to estimate container size for
947a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * installations living on external storage.
948a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
949a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see PackageInfo#INSTALL_LOCATION_AUTO
950a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see PackageInfo#INSTALL_LOCATION_PREFER_EXTERNAL
951f06009542390472872da986486d385001e91a2a7Jeff Sharkey         */
952a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setSize(long sizeBytes) {
953a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.sizeBytes = sizeBytes;
954a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
955f06009542390472872da986486d385001e91a2a7Jeff Sharkey
956f06009542390472872da986486d385001e91a2a7Jeff Sharkey        /**
957a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally set the package name of the app being installed. It's strongly
958a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * recommended that you provide this value when known, so that observers can
959a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * communicate installing apps to users.
960fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         * <p>
961a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * If the APKs staged in the session aren't consistent with this package
962a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * name, the install will fail. Regardless of this value, all APKs in the
963a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * app must have the same package name.
964fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         */
965a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setAppPackageName(@Nullable String appPackageName) {
966a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.appPackageName = appPackageName;
967a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
968fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey
969a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
970a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally set an icon representing the app being installed. This should
971a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * be roughly {@link ActivityManager#getLauncherLargeIconSize()} in both
972a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * dimensions.
973a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
974a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setAppIcon(@Nullable Bitmap appIcon) {
975a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.appIcon = appIcon;
976a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
977bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
978a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
979a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally set a label representing the app being installed.
980a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
981a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setAppLabel(@Nullable CharSequence appLabel) {
982a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.appLabel = (appLabel != null) ? appLabel.toString() : null;
983a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
984bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
985a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
9861ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * Optionally set the URI where this package was downloaded from. This is
9871ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * informational and may be used as a signal for anti-malware purposes.
988a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
989a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see Intent#EXTRA_ORIGINATING_URI
990a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
991a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setOriginatingUri(@Nullable Uri originatingUri) {
992a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.originatingUri = originatingUri;
993bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
994bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
995a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
9961ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * Sets the UID that initiated package installation. This is informational
9971ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * and may be used as a signal for anti-malware purposes.
998a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy         *
999a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy         * @see PackageManager#EXTRA_VERIFICATION_INSTALLER_UID
1000a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy         */
1001a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public void setOriginatingUid(int originatingUid) {
1002a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            this.originatingUid = originatingUid;
1003a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        }
1004a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy
1005a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /**
10061ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * Optionally set the URI that referred you to install this package. This is
10071ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * informational and may be used as a signal for anti-malware purposes.
1008a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
1009a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see Intent#EXTRA_REFERRER
1010a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
1011a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setReferrerUri(@Nullable Uri referrerUri) {
1012a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.referrerUri = referrerUri;
1013a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1014a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
10157121e18595d4c559044e26bfe6035406a862f466Svet Ganov        /**
10167121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * Sets which runtime permissions to be granted to the package at installation.
10177121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * Using this API requires holding {@link android.Manifest.permission
10187121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * #INSTALL_GRANT_RUNTIME_PERMISSIONS}
10197121e18595d4c559044e26bfe6035406a862f466Svet Ganov         *
10207121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * @param permissions The permissions to grant or null to grant all runtime
10217121e18595d4c559044e26bfe6035406a862f466Svet Ganov         *     permissions.
10227121e18595d4c559044e26bfe6035406a862f466Svet Ganov         *
10237121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * @hide
10247121e18595d4c559044e26bfe6035406a862f466Svet Ganov         */
10257121e18595d4c559044e26bfe6035406a862f466Svet Ganov        @SystemApi
10267121e18595d4c559044e26bfe6035406a862f466Svet Ganov        @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
10277121e18595d4c559044e26bfe6035406a862f466Svet Ganov        public void setGrantedRuntimePermissions(String[] permissions) {
10287121e18595d4c559044e26bfe6035406a862f466Svet Ganov            installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
10297121e18595d4c559044e26bfe6035406a862f466Svet Ganov            this.grantedRuntimePermissions = permissions;
10307121e18595d4c559044e26bfe6035406a862f466Svet Ganov        }
10317121e18595d4c559044e26bfe6035406a862f466Svet Ganov
1032a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
103377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        public void setInstallFlagsInternal() {
103477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags |= PackageManager.INSTALL_INTERNAL;
103577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
103677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        }
103777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey
103877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        /** {@hide} */
1039c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy        @SystemApi
1040948b702f39935fc856bca913714e489dcd67239bTodd Kennedy        public void setAllowDowngrade(boolean allowDowngrade) {
1041948b702f39935fc856bca913714e489dcd67239bTodd Kennedy            if (allowDowngrade) {
1042948b702f39935fc856bca913714e489dcd67239bTodd Kennedy                installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
1043948b702f39935fc856bca913714e489dcd67239bTodd Kennedy            } else {
1044948b702f39935fc856bca913714e489dcd67239bTodd Kennedy                installFlags &= ~PackageManager.INSTALL_ALLOW_DOWNGRADE;
1045948b702f39935fc856bca913714e489dcd67239bTodd Kennedy            }
1046c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy        }
1047c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy
1048c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy        /** {@hide} */
104977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        public void setInstallFlagsExternal() {
105077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags |= PackageManager.INSTALL_EXTERNAL;
105177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags &= ~PackageManager.INSTALL_INTERNAL;
105277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        }
105377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey
105477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        /** {@hide} */
1055a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public void setInstallFlagsForcePermissionPrompt() {
1056a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            installFlags |= PackageManager.INSTALL_FORCE_PERMISSION_PROMPT;
1057a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        }
1058a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy
1059a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /** {@hide} */
106024ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy        @SystemApi
106124ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy        public void setDontKillApp(boolean dontKillApp) {
106224ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy            if (dontKillApp) {
106324ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy                installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
106424ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy            } else {
106524ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy                installFlags &= ~PackageManager.INSTALL_DONT_KILL_APP;
106624ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy            }
106739bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy        }
106839bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy
106939bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy        /** {@hide} */
1070a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void dump(IndentingPrintWriter pw) {
1071a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("mode", mode);
1072a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printHexPair("installFlags", installFlags);
1073a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("installLocation", installLocation);
1074a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("sizeBytes", sizeBytes);
1075a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("appPackageName", appPackageName);
1076a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("appIcon", (appIcon != null));
1077a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("appLabel", appLabel);
1078a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("originatingUri", originatingUri);
1079a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            pw.printPair("originatingUid", originatingUid);
1080a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("referrerUri", referrerUri);
1081a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("abiOverride", abiOverride);
1082b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            pw.printPair("volumeUuid", volumeUuid);
10837121e18595d4c559044e26bfe6035406a862f466Svet Ganov            pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions);
1084a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.println();
1085fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        }
1086fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey
1087fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        @Override
1088a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int describeContents() {
1089a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return 0;
1090bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
1091a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1092a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        @Override
1093a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void writeToParcel(Parcel dest, int flags) {
1094a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(mode);
1095a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(installFlags);
1096a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(installLocation);
1097a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeLong(sizeBytes);
1098a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appPackageName);
1099a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(appIcon, flags);
1100a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appLabel);
1101a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(originatingUri, flags);
1102a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            dest.writeInt(originatingUid);
1103a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(referrerUri, flags);
1104a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(abiOverride);
1105b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            dest.writeString(volumeUuid);
11067121e18595d4c559044e26bfe6035406a862f466Svet Ganov            dest.writeStringArray(grantedRuntimePermissions);
1107a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1108a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1109a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final Parcelable.Creator<SessionParams>
1110a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                CREATOR = new Parcelable.Creator<SessionParams>() {
1111a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1112a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionParams createFromParcel(Parcel p) {
1113a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionParams(p);
1114a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
1115a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1116a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1117a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionParams[] newArray(int size) {
1118a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionParams[size];
1119a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
1120a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                };
1121bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
1122bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
11236c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
1124a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * Details for an active install session.
11256c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
1126a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static class SessionInfo implements Parcelable {
1127a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1128a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1129a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int sessionId;
1130a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1131a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String installerPackageName;
1132a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1133a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String resolvedBaseCodePath;
1134a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1135a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public float progress;
1136a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1137a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public boolean sealed;
1138a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1139bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public boolean active;
1140a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1141a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1142a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int mode;
1143a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1144a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public long sizeBytes;
1145a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1146a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String appPackageName;
1147a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1148a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Bitmap appIcon;
1149a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1150a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public CharSequence appLabel;
1151a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1152a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1153a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionInfo() {
1154a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1155a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1156a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1157a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionInfo(Parcel source) {
1158a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sessionId = source.readInt();
1159a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            installerPackageName = source.readString();
1160a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            resolvedBaseCodePath = source.readString();
1161a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            progress = source.readFloat();
1162a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sealed = source.readInt() != 0;
1163bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            active = source.readInt() != 0;
1164a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1165a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            mode = source.readInt();
1166a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sizeBytes = source.readLong();
1167a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appPackageName = source.readString();
1168a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appIcon = source.readParcelable(null);
1169a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appLabel = source.readString();
1170a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1171a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
11726c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
1173a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return the ID for this session.
11746c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
1175a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int getSessionId() {
1176a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return sessionId;
1177a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1178bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1179bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1180a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return the package name of the app that owns this session.
1181bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1182a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable String getInstallerPackageName() {
1183a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return installerPackageName;
1184a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1185bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1186bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1187a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return current overall progress of this session, between 0 and 1.
118816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * <p>
1189bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Note that this progress may not directly correspond to the value
1190bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * reported by
1191bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link PackageInstaller.Session#setStagingProgress(float)}, as the
1192bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system may carve out a portion of the overall progress to represent
1193bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * its own internal installation work.
1194bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1195a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public float getProgress() {
1196a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return progress;
1197a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1198bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1199bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1200bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Return if this session is currently active.
1201bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
1202bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * A session is considered active whenever there is ongoing forward
1203bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * progress being made, such as the installer holding an open
1204bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session} instance while streaming data into place, or the
1205bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system optimizing code as the result of
1206bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session#commit(IntentSender)}.
1207bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
1208bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * If the installer closes the {@link Session} without committing, the
1209bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * session is considered inactive until the installer opens the session
1210bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * again.
1211bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1212bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public boolean isActive() {
1213bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            return active;
1214bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        }
1215bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey
1216bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        /** {@hide} */
1217bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        @Deprecated
1218a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public boolean isOpen() {
1219bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            return isActive();
1220a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1221bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1222bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1223a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return the package name this session is working with. May be {@code null}
1224a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * if unknown.
1225bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1226a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable String getAppPackageName() {
1227a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return appPackageName;
1228a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
122916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
12307328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        /**
1231a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return an icon representing the app being installed. May be {@code null}
1232a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * if unavailable.
12337328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey         */
1234a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable Bitmap getAppIcon() {
1235a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return appIcon;
1236a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
12377328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey
1238a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
1239a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return a label representing the app being installed. May be {@code null}
1240a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * if unavailable.
1241a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
1242a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable CharSequence getAppLabel() {
1243a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return appLabel;
1244a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
124516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
1246fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        /**
1247a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return an Intent that can be started to view details about this install
1248a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * session. This may surface actions such as pause, resume, or cancel.
1249fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         * <p>
1250a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * In some cases, a matching Activity may not exist, so ensure you safeguard
1251a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * against this.
1252a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
1253a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see PackageInstaller#ACTION_SESSION_DETAILS
1254fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         */
1255de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        public @Nullable Intent createDetailsIntent() {
1256a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            final Intent intent = new Intent(PackageInstaller.ACTION_SESSION_DETAILS);
1257a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
1258a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            intent.setPackage(installerPackageName);
1259a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1260a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return intent;
1261bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
1262bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1263de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        /** {@hide} */
1264de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        @Deprecated
1265de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        public @Nullable Intent getDetailsIntent() {
1266de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey            return createDetailsIntent();
1267de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        }
1268de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey
1269bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        @Override
1270a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int describeContents() {
1271a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return 0;
1272fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        }
1273fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey
1274fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        @Override
1275a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void writeToParcel(Parcel dest, int flags) {
1276a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(sessionId);
1277a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(installerPackageName);
1278a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(resolvedBaseCodePath);
1279a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeFloat(progress);
1280a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(sealed ? 1 : 0);
1281bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            dest.writeInt(active ? 1 : 0);
1282a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1283a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(mode);
1284a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeLong(sizeBytes);
1285a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appPackageName);
1286a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(appIcon, flags);
1287a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appLabel != null ? appLabel.toString() : null);
1288a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1289a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1290a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final Parcelable.Creator<SessionInfo>
1291a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                CREATOR = new Parcelable.Creator<SessionInfo>() {
1292a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1293a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionInfo createFromParcel(Parcel p) {
1294a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionInfo(p);
1295a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
129616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
1297a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1298a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionInfo[] newArray(int size) {
1299a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionInfo[size];
1300a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
1301a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                };
1302bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
13033a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey}
1304