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
196788212d17f54475ca9c3dd689a863e031db868fSvet Ganovimport android.Manifest;
2016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.annotation.NonNull;
2116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.annotation.Nullable;
227121e18595d4c559044e26bfe6035406a862f466Svet Ganovimport android.annotation.RequiresPermission;
231cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport android.annotation.SdkConstant;
241cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport android.annotation.SdkConstant.SdkConstantType;
257121e18595d4c559044e26bfe6035406a862f466Svet Ganovimport android.annotation.SystemApi;
26a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.app.ActivityManager;
27fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkeyimport android.content.Intent;
28a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.content.IntentSender;
2940a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowskiimport android.content.pm.PackageManager.InstallReason;
30a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.graphics.Bitmap;
31a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.net.Uri;
3278cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport android.os.FileBridge;
3316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.os.Handler;
3416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.os.Looper;
3516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport android.os.Message;
36a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.os.Parcel;
373a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkeyimport android.os.ParcelFileDescriptor;
38a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport android.os.Parcelable;
393a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkeyimport android.os.RemoteException;
4002d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkeyimport android.os.SystemProperties;
4102d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkeyimport android.system.ErrnoException;
4202d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkeyimport android.system.Os;
43a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkeyimport android.util.ExceptionUtils;
44a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
45a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
466788212d17f54475ca9c3dd689a863e031db868fSvet Ganovimport com.android.internal.util.Preconditions;
473a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
48ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkeyimport java.io.Closeable;
49a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkeyimport java.io.IOException;
501cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport java.io.InputStream;
5178cc340c2de873d6995c283b777476f7237d690fJeff Sharkeyimport java.io.OutputStream;
521cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkeyimport java.security.MessageDigest;
5316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport java.util.ArrayList;
5416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkeyimport java.util.Iterator;
55bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkeyimport java.util.List;
5678cc340c2de873d6995c283b777476f7237d690fJeff Sharkey
576c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey/**
586c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * Offers the ability to install, upgrade, and remove applications on the
596c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * device. This includes support for apps packaged either as a single
606c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * "monolithic" APK, or apps packaged as multiple "split" APKs.
616c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <p>
626c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * An app is delivered for installation through a
636c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * {@link PackageInstaller.Session}, which any app can create. Once the session
646c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * is created, the installer can stream one or more APKs into place until it
656c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * decides to either commit or destroy the session. Committing may require user
666c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * intervention to complete the installation.
676c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <p>
686c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * Sessions can install brand new apps, upgrade existing apps, or add new splits
69da96e137bcc8191c584ada7b5de31eaae92f244fJeff Sharkey * into an existing app.
706c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <p>
71da96e137bcc8191c584ada7b5de31eaae92f244fJeff Sharkey * Apps packaged as multiple split APKs always consist of a single "base" APK
726c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * (with a {@code null} split name) and zero or more "split" APKs (with unique
736c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * split names). Any subset of these APKs can be installed together, as long as
746c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * the following constraints are met:
756c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <ul>
766c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <li>All APKs must have the exact same package name, version code, and signing
776c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * certificates.
786c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * <li>All APKs must have unique split names.
79da96e137bcc8191c584ada7b5de31eaae92f244fJeff Sharkey * <li>All installations must contain a single base APK.
806c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey * </ul>
816c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey */
823a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkeypublic class PackageInstaller {
83a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    private static final String TAG = "PackageInstaller";
84a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
8502d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey    /** {@hide} */
8602d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey    public static final boolean ENABLE_REVOCABLE_FD =
8702d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey            SystemProperties.getBoolean("fw.revocable_fd", false);
8802d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey
891cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    /**
901cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * Activity Action: Show details about a particular install session. This
911cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * may surface actions such as pause, resume, or cancel.
921cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <p>
931cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * This should always be scoped to the installer package that owns the
94de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey     * session. Clients should use {@link SessionInfo#createDetailsIntent()} to
95a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * build this intent correctly.
961cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <p>
971cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * In some cases, a matching Activity may not exist, so ensure you safeguard
981cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * against this.
99941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
100941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The session to show details for is defined in {@link #EXTRA_SESSION_ID}.
1011cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     */
1021cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
1031cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    public static final String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
1041cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
1056d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal    /**
1066d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * Broadcast Action: Explicit broadcast sent to the last known default launcher when a session
1076d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * for a new install is committed. For managed profile, this is sent to the default launcher
1086d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * of the primary profile.
1096d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * <p>
1106d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * The associated session is defined in {@link #EXTRA_SESSION} and the user for which this
1116d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * session was created in {@link Intent#EXTRA_USER}.
1126d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     */
1136d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1146d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal    public static final String ACTION_SESSION_COMMITTED =
1156d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal            "android.content.pm.action.SESSION_COMMITTED";
1166d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal
1177328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    /** {@hide} */
1187328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    public static final String
1197328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey            ACTION_CONFIRM_PERMISSIONS = "android.content.pm.action.CONFIRM_PERMISSIONS";
1207328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey
1211cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    /**
122941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * An integer session ID that an operation is working with.
1231cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     *
124941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getIntExtra(String, int)
1251cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     */
1261cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey    public static final String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
1271cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
128941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
1296d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * {@link SessionInfo} that an operation is working with.
1306d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     *
1316d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     * @see Intent#getParcelableExtra(String)
1326d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal     */
1336d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal    public static final String EXTRA_SESSION = "android.content.pm.extra.SESSION";
1346d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal
1356d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal    /**
136941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Package name that an operation is working with.
137941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
138941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getStringExtra(String)
139941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
140941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    public static final String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
141941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey
142941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
143941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Current status of an operation. Will be one of
144941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_PENDING_USER_ACTION}, {@link #STATUS_SUCCESS},
145941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE}, {@link #STATUS_FAILURE_ABORTED},
146941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE_BLOCKED}, {@link #STATUS_FAILURE_CONFLICT},
147941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID}, or
148941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * {@link #STATUS_FAILURE_STORAGE}.
149941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
150941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * More information about a status may be available through additional
151941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * extras; see the individual status documentation for details.
152941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
153941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getIntExtra(String, int)
154941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
155a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_STATUS = "android.content.pm.extra.STATUS";
156941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey
157941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
158941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Detailed string representation of the status, including raw details that
159941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * are useful for debugging.
160941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
161941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getStringExtra(String)
162941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
163a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
164a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
165a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
166941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Another package name relevant to a status. This is typically the package
167941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * responsible for causing an operation failure.
168a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
169bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey     * @see Intent#getStringExtra(String)
170a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
171941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    public static final String
172941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey            EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME";
173941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey
174941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    /**
175941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * Storage path relevant to a status.
176941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     *
177941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see Intent#getStringExtra(String)
178941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     */
179941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey    public static final String EXTRA_STORAGE_PATH = "android.content.pm.extra.STORAGE_PATH";
180bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey
181bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey    /** {@hide} */
182bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey    @Deprecated
183a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_PACKAGE_NAMES = "android.content.pm.extra.PACKAGE_NAMES";
184a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
185a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /** {@hide} */
186a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
187a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /** {@hide} */
188a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final String EXTRA_LEGACY_BUNDLE = "android.content.pm.extra.LEGACY_BUNDLE";
189f06009542390472872da986486d385001e91a2a7Jeff Sharkey    /** {@hide} */
190f06009542390472872da986486d385001e91a2a7Jeff Sharkey    public static final String EXTRA_CALLBACK = "android.content.pm.extra.CALLBACK";
191f06009542390472872da986486d385001e91a2a7Jeff Sharkey
192a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
193a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * User action is currently required to proceed. You can launch the intent
194a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * activity described by {@link Intent#EXTRA_INTENT} to involve the user and
195a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * continue.
196a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * <p>
197a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * You may choose to immediately launch the intent if the user is actively
198a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * using your app. Otherwise, you should use a notification to guide the
199a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * user back into your app before launching.
200a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
201a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see Intent#getParcelableExtra(String)
202a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
203742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_PENDING_USER_ACTION = -1;
204a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
205a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
206a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation succeeded.
207a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
208a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final int STATUS_SUCCESS = 0;
209a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
210a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
211a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed in a generic way. The system will always try to
212a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * provide a more specific failure reason, but in some rare cases this may
213a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * be delivered.
214a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
215a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
216a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
217a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static final int STATUS_FAILURE = 1;
218a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
219a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
220a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it was blocked. For example, a device policy
221a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * may be blocking the operation, a package verifier may have blocked the
222a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * operation, or the app may be required for core system operation.
223941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
224941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The result may also contain {@link #EXTRA_OTHER_PACKAGE_NAME} with the
225941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * specific package blocking the install.
226a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
227a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
228941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see #EXTRA_OTHER_PACKAGE_NAME
229a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
230742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_BLOCKED = 2;
231a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
232a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
233a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it was actively aborted. For example, the
234a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * user actively declined requested permissions, or the session was
235a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * abandoned.
236a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
237a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
238a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
239742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_ABORTED = 3;
240a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
241a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
242a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because one or more of the APKs was invalid. For
243a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * example, they might be malformed, corrupt, incorrectly signed,
244a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * mismatched, etc.
245a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
246a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
247a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
248742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_INVALID = 4;
249a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
250a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
251a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it conflicts (or is inconsistent with) with
252a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * another package already installed on the device. For example, an existing
253a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * permission, incompatible certificates, etc. The user may be able to
254a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * uninstall another app to fix the issue.
255a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * <p>
256941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The result may also contain {@link #EXTRA_OTHER_PACKAGE_NAME} with the
257bb7b7bea19223c1eba74f525c7fe87ca3911813bJeff Sharkey     * specific package identified as the cause of the conflict.
258a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
259a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
260941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see #EXTRA_OTHER_PACKAGE_NAME
261a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
262742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_CONFLICT = 5;
263a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
264a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
265a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because of storage issues. For example, the device
266a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * may be running low on space, or external media may be unavailable. The
267a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * user may be able to help free space or insert different external media.
268941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * <p>
269941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * The result may also contain {@link #EXTRA_STORAGE_PATH} with the path to
270941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * the storage device that caused the failure.
271a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
272a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
273941a8ba1a6043cf84a7bf622e44a0b4f7abd0178Jeff Sharkey     * @see #EXTRA_STORAGE_PATH
274a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
275742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_STORAGE = 6;
276a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
277a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    /**
278a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * The operation failed because it is fundamentally incompatible with this
279a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * device. For example, the app may require a hardware feature that doesn't
280a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * exist, it may be missing native code for the ABIs supported by the
281a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * device, or it requires a newer SDK version, etc.
282a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     *
283a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * @see #EXTRA_STATUS_MESSAGE
284a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     */
285742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey    public static final int STATUS_FAILURE_INCOMPATIBLE = 7;
286a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
2873a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    private final IPackageInstaller mInstaller;
2883a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    private final int mUserId;
2893a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    private final String mInstallerPackageName;
2903a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
29116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    private final ArrayList<SessionCallbackDelegate> mDelegates = new ArrayList<>();
29216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
2933a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    /** {@hide} */
2946788212d17f54475ca9c3dd689a863e031db868fSvet Ganov    public PackageInstaller(IPackageInstaller installer,
295ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey            String installerPackageName, int userId) {
2963a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        mInstaller = installer;
2973a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        mInstallerPackageName = installerPackageName;
298ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey        mUserId = userId;
2993a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
3003a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
3016c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
3026c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * Create a new session using the given parameters, returning a unique ID
3036c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * that represents the session. Once created, the session can be opened
3046c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * multiple times across multiple device boots.
3056c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * <p>
3066c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * The system may automatically destroy sessions that have not been
3076c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * finalized (either committed or abandoned) within a reasonable period of
3086c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * time, typically on the order of a day.
3096c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     *
3106c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * @throws IOException if parameters were unsatisfiable, such as lack of
3116c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     *             disk space or unavailable media.
31277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when installation services are unavailable,
31377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             such as when called from a restricted user.
31477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws IllegalArgumentException when {@link SessionParams} is invalid.
315f174c6e6de6ba863179401aa7b3d55d91ceed707Jeff Sharkey     * @return positive, non-zero unique ID that represents the created session.
316f174c6e6de6ba863179401aa7b3d55d91ceed707Jeff Sharkey     *         This ID remains consistent across device reboots until the
317f174c6e6de6ba863179401aa7b3d55d91ceed707Jeff Sharkey     *         session is finalized. IDs are not reused during a given boot.
3186c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
319a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public int createSession(@NonNull SessionParams params) throws IOException {
3203a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
32116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            return mInstaller.createSession(params, mInstallerPackageName, mUserId);
322a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        } catch (RuntimeException e) {
323a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            ExceptionUtils.maybeUnwrapIOException(e);
324a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            throw e;
3253a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        } catch (RemoteException e) {
326f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
3273a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
3283a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
3293a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
3306c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
33116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * Open an existing session to actively perform work. To succeed, the caller
33216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * must be the owner of the install session.
33377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
33477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws IOException if parameters were unsatisfiable, such as lack of
33577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             disk space or unavailable media.
33677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
33777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
3386c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
339bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey    public @NonNull Session openSession(int sessionId) throws IOException {
3403a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
3413a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            return new Session(mInstaller.openSession(sessionId));
342bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        } catch (RuntimeException e) {
343bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            ExceptionUtils.maybeUnwrapIOException(e);
344bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            throw e;
3453a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        } catch (RemoteException e) {
346f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
3473a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
348381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey    }
349381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey
350ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /**
351ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * Update the icon representing the app being installed in a specific
352ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * session. This should be roughly
353ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * {@link ActivityManager#getLauncherLargeIconSize()} in both dimensions.
35477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
35577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
35677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
357ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     */
358ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void updateSessionAppIcon(int sessionId, @Nullable Bitmap appIcon) {
359ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        try {
360ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            mInstaller.updateSessionAppIcon(sessionId, appIcon);
361ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        } catch (RemoteException e) {
362f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
363ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        }
364ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
365ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
366ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /**
367ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * Update the label representing the app being installed in a specific
368ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     * session.
36977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
37077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
37177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
372ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey     */
373ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void updateSessionAppLabel(int sessionId, @Nullable CharSequence appLabel) {
374ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        try {
375ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            final String val = (appLabel != null) ? appLabel.toString() : null;
376ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            mInstaller.updateSessionAppLabel(sessionId, val);
377ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        } catch (RemoteException e) {
378f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
379ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        }
380ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
381ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
38277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey    /**
38377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Completely abandon the given session, destroying all staged data and
38477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * rendering it invalid. Abandoned sessions will be reported to
38577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * {@link SessionCallback} listeners as failures. This is equivalent to
38677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * opening the session and calling {@link Session#abandon()}.
38777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
38877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @throws SecurityException when the caller does not own the session, or
38977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *             the session is invalid.
39077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     */
391381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey    public void abandonSession(int sessionId) {
392381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey        try {
393381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey            mInstaller.abandonSession(sessionId);
394381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey        } catch (RemoteException e) {
395f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
396381d94b712605112b35d7f70064b0d18bd877877Jeff Sharkey        }
3973a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
3983a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
3996c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
40077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Return details for a specific session. No special permissions are
40177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * required to retrieve these details.
40277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *
40377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * @return details for the requested session, or {@code null} if the session
40477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     *         does not exist.
4056c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
406a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public @Nullable SessionInfo getSessionInfo(int sessionId) {
4073a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
40816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            return mInstaller.getSessionInfo(sessionId);
40916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        } catch (RemoteException e) {
410f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
41116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
41216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
41316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
41416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /**
41577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Return list of all known install sessions, regardless of the installer.
41616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     */
417a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public @NonNull List<SessionInfo> getAllSessions() {
41816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        try {
41997d47ed036ff7bd3d7d2ddc1c6df1104ec237559Jeff Sharkey            return mInstaller.getAllSessions(mUserId).getList();
42016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        } catch (RemoteException e) {
421f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
42216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
42316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
42416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
42516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /**
42677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Return list of all known install sessions owned by the calling app.
42716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     */
428a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public @NonNull List<SessionInfo> getMySessions() {
42916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        try {
43097d47ed036ff7bd3d7d2ddc1c6df1104ec237559Jeff Sharkey            return mInstaller.getMySessions(mInstallerPackageName, mUserId).getList();
4313a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        } catch (RemoteException e) {
432f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
4333a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
4343a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
4353a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
4366c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
4376c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * Uninstall the given package, removing it completely from the device. This
4386c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * method is only available to the current "installer of record" for the
4396c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * package.
4406788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     *
4416788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * @param packageName The package to uninstall.
4426788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * @param statusReceiver Where to deliver the result.
4436c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
444a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public void uninstall(@NonNull String packageName, @NonNull IntentSender statusReceiver) {
4456788212d17f54475ca9c3dd689a863e031db868fSvet Ganov       uninstall(new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
4466788212d17f54475ca9c3dd689a863e031db868fSvet Ganov               statusReceiver);
4476788212d17f54475ca9c3dd689a863e031db868fSvet Ganov    }
4486788212d17f54475ca9c3dd689a863e031db868fSvet Ganov
4496788212d17f54475ca9c3dd689a863e031db868fSvet Ganov    /**
4506788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * Uninstall the given package with a specific version code, removing it
4516788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * completely from the device. This method is only available to the current
4526788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * "installer of record" for the package. If the version code of the package
4536788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * does not match the one passed in the versioned package argument this
4546788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * method is a no-op. Use {@link PackageManager#VERSION_CODE_HIGHEST} to
4556788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * uninstall the latest version of the package.
4566788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     *
4576788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * @param versionedPackage The versioned package to uninstall.
4586788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     * @param statusReceiver Where to deliver the result.
4596788212d17f54475ca9c3dd689a863e031db868fSvet Ganov     */
4606788212d17f54475ca9c3dd689a863e031db868fSvet Ganov    @RequiresPermission(anyOf = {
4616788212d17f54475ca9c3dd689a863e031db868fSvet Ganov            Manifest.permission.DELETE_PACKAGES,
4626788212d17f54475ca9c3dd689a863e031db868fSvet Ganov            Manifest.permission.REQUEST_DELETE_PACKAGES})
4636788212d17f54475ca9c3dd689a863e031db868fSvet Ganov    public void uninstall(@NonNull VersionedPackage versionedPackage,
4646788212d17f54475ca9c3dd689a863e031db868fSvet Ganov            @NonNull IntentSender statusReceiver) {
4656788212d17f54475ca9c3dd689a863e031db868fSvet Ganov        Preconditions.checkNotNull(versionedPackage, "versionedPackage cannot be null");
4663a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        try {
4676788212d17f54475ca9c3dd689a863e031db868fSvet Ganov            mInstaller.uninstall(versionedPackage, mInstallerPackageName,
4686788212d17f54475ca9c3dd689a863e031db868fSvet Ganov                    0, statusReceiver, mUserId);
469bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        } catch (RemoteException e) {
470f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
471bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
472bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
473bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
4747328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    /** {@hide} */
47504cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy    @SystemApi
476d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey    @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES)
4777328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    public void setPermissionsResult(int sessionId, boolean accepted) {
4787328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        try {
4797328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey            mInstaller.setPermissionsResult(sessionId, accepted);
4807328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        } catch (RemoteException e) {
481f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey            throw e.rethrowFromSystemServer();
4827328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        }
4837328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey    }
4847328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey
4856c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
4866c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     * Events for observing session lifecycle.
4871cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <p>
4881cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * A typical session lifecycle looks like this:
4891cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <ul>
4901cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <li>An installer creates a session to indicate pending app delivery. All
4911cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * install details are available at this point.
4921cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <li>The installer opens the session to deliver APK data. Note that a
4931cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * session may be opened and closed multiple times as network connectivity
4941cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * changes. The installer may deliver periodic progress updates.
4951cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * <li>The installer commits or abandons the session, resulting in the
4961cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * session being finished.
4971cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey     * </ul>
4986c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
49916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    public static abstract class SessionCallback {
5006c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
5011cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * New session has been created. Details about the session can be
5021cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * obtained from {@link PackageInstaller#getSessionInfo(int)}.
5036c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
50416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public abstract void onCreated(int sessionId);
5056c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey
5066c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
507ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey         * Badging details for an existing session has changed. For example, the
508ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey         * app icon or label has been updated.
509ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey         */
510ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        public abstract void onBadgingChanged(int sessionId);
511ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
512ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        /**
513bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Active state for session has been changed.
514bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
515bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * A session is considered active whenever there is ongoing forward
516bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * progress being made, such as the installer holding an open
517bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session} instance while streaming data into place, or the
518bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system optimizing code as the result of
519bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session#commit(IntentSender)}.
520bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
521bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * If the installer closes the {@link Session} without committing, the
522bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * session is considered inactive until the installer opens the session
523bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * again.
5241cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         */
525bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public abstract void onActiveChanged(int sessionId, boolean active);
5261cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
5271cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        /**
5286c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Progress for given session has been updated.
5296c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * <p>
5306c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Note that this progress may not directly correspond to the value
531bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * reported by
532bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link PackageInstaller.Session#setStagingProgress(float)}, as the
533bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system may carve out a portion of the overall progress to represent
534bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * its own internal installation work.
5356c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
53616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public abstract void onProgressChanged(int sessionId, float progress);
5376c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey
5386c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
53916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * Session has completely finished, either with success or failure.
5406c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
54116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public abstract void onFinished(int sessionId, boolean success);
54216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
54316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
54416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /** {@hide} */
54516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    private static class SessionCallbackDelegate extends IPackageInstallerCallback.Stub implements
54616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            Handler.Callback {
54716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        private static final int MSG_SESSION_CREATED = 1;
548ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        private static final int MSG_SESSION_BADGING_CHANGED = 2;
549bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        private static final int MSG_SESSION_ACTIVE_CHANGED = 3;
550ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        private static final int MSG_SESSION_PROGRESS_CHANGED = 4;
551bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        private static final int MSG_SESSION_FINISHED = 5;
55216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
55316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        final SessionCallback mCallback;
55416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        final Handler mHandler;
55516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
55616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public SessionCallbackDelegate(SessionCallback callback, Looper looper) {
55716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mCallback = callback;
55816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler = new Handler(looper, this);
55916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
56016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
56116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
56216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public boolean handleMessage(Message msg) {
563bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            final int sessionId = msg.arg1;
56416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            switch (msg.what) {
56516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                case MSG_SESSION_CREATED:
566bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onCreated(sessionId);
56716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    return true;
568ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey                case MSG_SESSION_BADGING_CHANGED:
569bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onBadgingChanged(sessionId);
570ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey                    return true;
571bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                case MSG_SESSION_ACTIVE_CHANGED:
572bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    final boolean active = msg.arg2 != 0;
573bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onActiveChanged(sessionId, active);
5741cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                    return true;
57516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                case MSG_SESSION_PROGRESS_CHANGED:
576bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onProgressChanged(sessionId, (float) msg.obj);
5771cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                    return true;
57816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                case MSG_SESSION_FINISHED:
579bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    mCallback.onFinished(sessionId, msg.arg2 != 0);
58016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    return true;
58116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
58216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            return false;
58316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
58416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
58516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
58616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void onSessionCreated(int sessionId) {
58716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_CREATED, sessionId, 0).sendToTarget();
58816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
58916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
59016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
591ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        public void onSessionBadgingChanged(int sessionId) {
592ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_BADGING_CHANGED, sessionId, 0).sendToTarget();
593ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        }
594ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
595ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        @Override
596bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public void onSessionActiveChanged(int sessionId, boolean active) {
597bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_ACTIVE_CHANGED, sessionId, active ? 1 : 0)
598bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey                    .sendToTarget();
5991cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        }
6001cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
6011cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        @Override
60216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void onSessionProgressChanged(int sessionId, float progress) {
60316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_PROGRESS_CHANGED, sessionId, 0, progress)
60416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    .sendToTarget();
60516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
60616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
60716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        @Override
60816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void onSessionFinished(int sessionId, boolean success) {
60916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mHandler.obtainMessage(MSG_SESSION_FINISHED, sessionId, success ? 1 : 0)
61016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    .sendToTarget();
61116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        }
612bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
613bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
614ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /** {@hide} */
615ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    @Deprecated
616ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void addSessionCallback(@NonNull SessionCallback callback) {
617ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        registerSessionCallback(callback);
618ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
619ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
6206c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
62177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Register to watch for session lifecycle events. No special permissions
62277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * are required to watch for these events.
6236c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
624ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void registerSessionCallback(@NonNull SessionCallback callback) {
625ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        registerSessionCallback(callback, new Handler());
626ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
627ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
628ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /** {@hide} */
629ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    @Deprecated
630ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void addSessionCallback(@NonNull SessionCallback callback, @NonNull Handler handler) {
631ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        registerSessionCallback(callback, handler);
63216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    }
63316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
63416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey    /**
63577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Register to watch for session lifecycle events. No special permissions
63677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * are required to watch for these events.
63716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     *
63816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * @param handler to dispatch callback events through, otherwise uses
63916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     *            calling thread.
64016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     */
641ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void registerSessionCallback(@NonNull SessionCallback callback, @NonNull Handler handler) {
64216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        synchronized (mDelegates) {
64316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            final SessionCallbackDelegate delegate = new SessionCallbackDelegate(callback,
64416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    handler.getLooper());
64516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            try {
64616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                mInstaller.registerCallback(delegate, mUserId);
64716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            } catch (RemoteException e) {
648f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
64916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
65016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            mDelegates.add(delegate);
651bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
652bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
653bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
654ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    /** {@hide} */
655ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    @Deprecated
656ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void removeSessionCallback(@NonNull SessionCallback callback) {
657ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey        unregisterSessionCallback(callback);
658ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    }
659ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey
6606c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
66177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey     * Unregister a previously registered callback.
6626c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
663ec9bad2015c6d3bc91bab66f0824043c1e24d013Jeff Sharkey    public void unregisterSessionCallback(@NonNull SessionCallback callback) {
66416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        synchronized (mDelegates) {
66516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            for (Iterator<SessionCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
66616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                final SessionCallbackDelegate delegate = i.next();
66716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                if (delegate.mCallback == callback) {
66816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    try {
66916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                        mInstaller.unregisterCallback(delegate);
67016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    } catch (RemoteException e) {
671f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                        throw e.rethrowFromSystemServer();
67216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    }
67316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                    i.remove();
67416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                }
67516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
6763a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
6773a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
6783a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
6793a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    /**
6803a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * An installation that is being actively staged. For an install to succeed,
6813a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * all existing and new packages must have identical package names, version
6823a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * codes, and signing certificates.
6833a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * <p>
6843a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * A session may contain any number of split packages. If the application
6853a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * does not yet exist, this session must include a base package.
6863a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     * <p>
68716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * If an APK included in this session is already defined by the existing
68816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * installation (for example, the same split name), the APK in this session
68916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey     * will replace the existing APK.
6903a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey     */
691ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey    public static class Session implements Closeable {
6923a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        private IPackageInstallerSession mSession;
6933a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
6943a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        /** {@hide} */
6953a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        public Session(IPackageInstallerSession session) {
6963a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            mSession = session;
6973a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
6983a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
699bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        /** {@hide} */
700bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        @Deprecated
701bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public void setProgress(float progress) {
702bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            setStagingProgress(progress);
703bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        }
704bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey
7056c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
706bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Set current progress of staging this session. Valid values are
707bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * anywhere between 0 and 1.
708bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
709bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Note that this progress may not directly correspond to the value
710bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * reported by {@link SessionCallback#onProgressChanged(int, float)}, as
711bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * the system may carve out a portion of the overall progress to
712bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * represent its own internal installation work.
7136c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
714bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public void setStagingProgress(float progress) {
7153a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
716a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                mSession.setClientProgress(progress);
717a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            } catch (RemoteException e) {
718f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
719a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            }
720a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        }
721a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey
722a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        /** {@hide} */
72316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void addProgress(float progress) {
724a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            try {
725a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                mSession.addClientProgress(progress);
7263a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
727f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
7283a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
7293a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
7303a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
73178cc340c2de873d6995c283b777476f7237d690fJeff Sharkey        /**
73216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * Open a stream to write an APK file into the session.
73316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * <p>
73416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * The returned stream will start writing data at the requested offset
73516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * in the underlying file, which can be used to resume a partially
73616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * written file. If a valid file length is specified, the system will
73716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * preallocate the underlying disk space to optimize placement on disk.
73816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * It's strongly recommended to provide a valid file length when known.
73916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * <p>
74016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * You can write data into the returned stream, optionally call
74116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * {@link #fsync(OutputStream)} as needed to ensure bytes have been
74216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * persisted to disk, and then close when finished. All streams must be
743a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * closed before calling {@link #commit(IntentSender)}.
74416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *
74516c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * @param name arbitrary, unique name of your choosing to identify the
74616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            APK being written. You can open a file again for
74716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            additional writes (such as after a reboot) by using the
74816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            same name. This name is only meaningful within the context
74916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            of a single install session.
75016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * @param offsetBytes offset into the file to begin writing at, or 0 to
75116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            start at the beginning of the file.
75216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * @param lengthBytes total size of the file being written, used to
75316c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         *            preallocate the underlying disk space, or -1 if unknown.
75477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *            The system may clear various caches as needed to allocate
75577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *            this space.
75677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws IOException if trouble opening the file for writing, such as
75777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             lack of disk space or unavailable media.
75877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if called after the session has been
75977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             committed or abandoned.
76078cc340c2de873d6995c283b777476f7237d690fJeff Sharkey         */
76116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public @NonNull OutputStream openWrite(@NonNull String name, long offsetBytes,
76216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                long lengthBytes) throws IOException {
7633a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
76402d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                if (ENABLE_REVOCABLE_FD) {
76502d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    return new ParcelFileDescriptor.AutoCloseOutputStream(
76602d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                            mSession.openWrite(name, offsetBytes, lengthBytes));
76702d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                } else {
76802d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    final ParcelFileDescriptor clientSocket = mSession.openWrite(name,
76902d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                            offsetBytes, lengthBytes);
77002d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    return new FileBridge.FileBridgeOutputStream(clientSocket);
77102d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                }
772a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            } catch (RuntimeException e) {
773a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                ExceptionUtils.maybeUnwrapIOException(e);
774a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey                throw e;
7753a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
776f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
7773a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
77802d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey
7793a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
7803a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
7816c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
7826c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Ensure that any outstanding data for given stream has been committed
7836c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * to disk. This is only valid for streams returned from
7846c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * {@link #openWrite(String, long, long)}.
7856c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
78616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void fsync(@NonNull OutputStream out) throws IOException {
78702d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey            if (ENABLE_REVOCABLE_FD) {
78802d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                if (out instanceof ParcelFileDescriptor.AutoCloseOutputStream) {
78902d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    try {
79002d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                        Os.fsync(((ParcelFileDescriptor.AutoCloseOutputStream) out).getFD());
79102d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    } catch (ErrnoException e) {
79202d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                        throw e.rethrowAsIOException();
79302d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    }
79402d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                } else {
79502d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    throw new IllegalArgumentException("Unrecognized stream");
79602d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                }
797a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            } else {
79802d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                if (out instanceof FileBridge.FileBridgeOutputStream) {
79902d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    ((FileBridge.FileBridgeOutputStream) out).fsync();
80002d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                } else {
80102d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                    throw new IllegalArgumentException("Unrecognized stream");
80202d4e3441bc1bf767d0ed57b81bdfa59d2894cb6Jeff Sharkey                }
803a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey            }
804a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey        }
805a10311434778ea1be1621c2251c0c8c2966f337bJeff Sharkey
8066c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
807a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return all APK names contained in this session.
8081cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * <p>
8091cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * This returns all names which have been previously written through
8101cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * {@link #openWrite(String, long, long)} as part of this session.
81177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *
81277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if called after the session has been
81377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             committed or abandoned.
8141cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         */
815742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey        public @NonNull String[] getNames() throws IOException {
8161cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            try {
817a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                return mSession.getNames();
818742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey            } catch (RuntimeException e) {
819742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey                ExceptionUtils.maybeUnwrapIOException(e);
820742e790294b3441b79f715fe447069b63c6065dbJeff Sharkey                throw e;
8211cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            } catch (RemoteException e) {
822f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
8231cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            }
8241cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        }
8251cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
8261cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        /**
8271cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * Open a stream to read an APK file from the session.
8281cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * <p>
8291cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * This is only valid for names which have been previously written
8301cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * through {@link #openWrite(String, long, long)} as part of this
8311cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * session. For example, this stream may be used to calculate a
8321cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         * {@link MessageDigest} of a written APK before committing.
83377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *
83477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if called after the session has been
83577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             committed or abandoned.
8361cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey         */
8371cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        public @NonNull InputStream openRead(@NonNull String name) throws IOException {
8381cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            try {
8391cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                final ParcelFileDescriptor pfd = mSession.openRead(name);
8401cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                return new ParcelFileDescriptor.AutoCloseInputStream(pfd);
8411cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            } catch (RuntimeException e) {
8421cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                ExceptionUtils.maybeUnwrapIOException(e);
843eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                throw e;
844eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            } catch (RemoteException e) {
845eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                throw e.rethrowFromSystemServer();
846eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            }
847eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy        }
848eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy
849eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy        /**
850eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * Removes a split.
851eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * <p>
852eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * Split removals occur prior to adding new APKs. If upgrading a feature
853eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * split, it is not expected nor desirable to remove the split prior to
854eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * upgrading.
855eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * <p>
856eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * When split removal is bundled with new APKs, the packageName must be
857eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         * identical.
858eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy         */
859eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy        public void removeSplit(@NonNull String splitName) throws IOException {
860eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            try {
861eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                mSession.removeSplit(splitName);
862eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy            } catch (RuntimeException e) {
863eb9b05392ad047863244f9e07a3b10e9c0561e39Todd Kennedy                ExceptionUtils.maybeUnwrapIOException(e);
8641cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey                throw e;
8651cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            } catch (RemoteException e) {
866f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
8671cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey            }
8681cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        }
8691cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey
8701cb2d0d4bba387665128c62c342e59103ea4be26Jeff Sharkey        /**
8716c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Attempt to commit everything staged in this session. This may require
8726c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * user intervention, and so it may not happen immediately. The final
8736c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * result of the commit will be reported through the given callback.
8746c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * <p>
87504cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         * Once this method is called, the session is sealed and no additional
87604cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         * mutations may be performed on the session. If the device reboots
87704cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         * before the session has been finalized, you may commit the session again.
87877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *
87977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * @throws SecurityException if streams opened through
88077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         *             {@link #openWrite(String, long, long)} are still open.
8816c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
882a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void commit(@NonNull IntentSender statusReceiver) {
8833a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
884a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                mSession.commit(statusReceiver);
8853a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
886f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
8873a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
8883a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
8893a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
8906c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
8916c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * Release this session object. You can open the session again if it
8926c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         * hasn't been finalized.
8936c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
894ec55ef0934b8e0d1bb705434947de817f7be57f1Jeff Sharkey        @Override
8953a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        public void close() {
89616c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            try {
89716c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                mSession.close();
89816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            } catch (RemoteException e) {
899f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
90016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey            }
9013a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
9023a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey
9036c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
90416c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * Completely abandon this session, destroying all staged data and
90577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * rendering it invalid. Abandoned sessions will be reported to
90677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * {@link SessionCallback} listeners as failures. This is equivalent to
90777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey         * opening the session and calling {@link Session#abandon()}.
9086c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
90916c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey        public void abandon() {
9103a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            try {
91116c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey                mSession.abandon();
9123a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            } catch (RemoteException e) {
913f8880561e67e1da246970b49b14285efd4164ab1Jeff Sharkey                throw e.rethrowFromSystemServer();
9143a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey            }
9153a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey        }
9163a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey    }
917bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
9186c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
919a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * Parameters for creating a new {@link PackageInstaller.Session}.
9206c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
921a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static class SessionParams implements Parcelable {
922a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
923a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
924a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final int MODE_INVALID = -1;
925a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
926a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
927a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Mode for an install session whose staged APKs should fully replace any
928a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * existing APKs for the target app.
929a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
930a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final int MODE_FULL_INSTALL = 1;
931a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
932a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
933a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Mode for an install session that should inherit any existing APKs for the
934a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * target app, unless they have been explicitly overridden (based on split
935a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * name) by the session. For example, this can be used to add one or more
936a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * split APKs to an existing installation.
937a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * <p>
938a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * If there are no existing APKs for the target app, this behaves like
939a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * {@link #MODE_FULL_INSTALL}.
940a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
941a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final int MODE_INHERIT_EXISTING = 2;
942a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
943a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
944a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public static final int UID_UNKNOWN = -1;
945a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy
946a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /** {@hide} */
947a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int mode = MODE_INVALID;
948a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
949a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int installFlags;
950a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
951a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
952a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
95340a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski        public @InstallReason int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
954a34f53f61be31b7171d6cbcb12490ee143acffffBartosz Fabianowski        /** {@hide} */
955a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public long sizeBytes = -1;
956a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
957a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String appPackageName;
958a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
959a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Bitmap appIcon;
960a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
961a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String appLabel;
962a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
96302bd78490d8594d225ecc70a74b2058cb968a657Jeff Sharkey        public long appIconLastModified = -1;
96402bd78490d8594d225ecc70a74b2058cb968a657Jeff Sharkey        /** {@hide} */
965a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Uri originatingUri;
966a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
967a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public int originatingUid = UID_UNKNOWN;
968a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /** {@hide} */
969a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Uri referrerUri;
970a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
971a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String abiOverride;
972b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        /** {@hide} */
973b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey        public String volumeUuid;
9747121e18595d4c559044e26bfe6035406a862f466Svet Ganov        /** {@hide} */
9757121e18595d4c559044e26bfe6035406a862f466Svet Ganov        public String[] grantedRuntimePermissions;
976a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
977fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        /**
978a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Construct parameters for a new package install session.
979a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
980a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @param mode one of {@link #MODE_FULL_INSTALL} or
981a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *            {@link #MODE_INHERIT_EXISTING} describing how the session
982a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *            should interact with an existing app.
983f06009542390472872da986486d385001e91a2a7Jeff Sharkey         */
984a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionParams(int mode) {
985a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.mode = mode;
986a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
987a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
988a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
989a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionParams(Parcel source) {
990a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            mode = source.readInt();
991a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            installFlags = source.readInt();
992a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            installLocation = source.readInt();
993a34f53f61be31b7171d6cbcb12490ee143acffffBartosz Fabianowski            installReason = source.readInt();
994a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sizeBytes = source.readLong();
995a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appPackageName = source.readString();
996a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appIcon = source.readParcelable(null);
997a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appLabel = source.readString();
998a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            originatingUri = source.readParcelable(null);
999a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            originatingUid = source.readInt();
1000a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            referrerUri = source.readParcelable(null);
1001a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            abiOverride = source.readString();
1002b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            volumeUuid = source.readString();
10037121e18595d4c559044e26bfe6035406a862f466Svet Ganov            grantedRuntimePermissions = source.readStringArray();
1004a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1005f06009542390472872da986486d385001e91a2a7Jeff Sharkey
1006f06009542390472872da986486d385001e91a2a7Jeff Sharkey        /**
1007a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Provide value of {@link PackageInfo#installLocation}, which may be used
1008a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * to determine where the app will be staged. Defaults to
1009a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * {@link PackageInfo#INSTALL_LOCATION_INTERNAL_ONLY}.
1010f06009542390472872da986486d385001e91a2a7Jeff Sharkey         */
1011a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setInstallLocation(int installLocation) {
1012a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.installLocation = installLocation;
1013a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1014f06009542390472872da986486d385001e91a2a7Jeff Sharkey
1015f06009542390472872da986486d385001e91a2a7Jeff Sharkey        /**
1016a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally indicate the total size (in bytes) of all APKs that will be
1017a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * delivered in this session. The system may use this to ensure enough disk
1018a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * space exists before proceeding, or to estimate container size for
1019a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * installations living on external storage.
1020a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
1021a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see PackageInfo#INSTALL_LOCATION_AUTO
1022a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see PackageInfo#INSTALL_LOCATION_PREFER_EXTERNAL
1023f06009542390472872da986486d385001e91a2a7Jeff Sharkey         */
1024a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setSize(long sizeBytes) {
1025a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.sizeBytes = sizeBytes;
1026a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1027f06009542390472872da986486d385001e91a2a7Jeff Sharkey
1028f06009542390472872da986486d385001e91a2a7Jeff Sharkey        /**
1029a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally set the package name of the app being installed. It's strongly
1030a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * recommended that you provide this value when known, so that observers can
1031a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * communicate installing apps to users.
1032fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         * <p>
1033a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * If the APKs staged in the session aren't consistent with this package
1034a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * name, the install will fail. Regardless of this value, all APKs in the
1035a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * app must have the same package name.
1036fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         */
1037a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setAppPackageName(@Nullable String appPackageName) {
1038a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.appPackageName = appPackageName;
1039a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1040fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey
1041a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
1042a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally set an icon representing the app being installed. This should
1043a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * be roughly {@link ActivityManager#getLauncherLargeIconSize()} in both
1044a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * dimensions.
1045a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
1046a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setAppIcon(@Nullable Bitmap appIcon) {
1047a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.appIcon = appIcon;
1048a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1049bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1050a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
1051a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Optionally set a label representing the app being installed.
1052a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
1053a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setAppLabel(@Nullable CharSequence appLabel) {
1054a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.appLabel = (appLabel != null) ? appLabel.toString() : null;
1055a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1056bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1057a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
10581ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * Optionally set the URI where this package was downloaded from. This is
10591ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * informational and may be used as a signal for anti-malware purposes.
1060a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
1061a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see Intent#EXTRA_ORIGINATING_URI
1062a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
1063a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setOriginatingUri(@Nullable Uri originatingUri) {
1064a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.originatingUri = originatingUri;
1065bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
1066bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1067a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
10681ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * Sets the UID that initiated package installation. This is informational
10691ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * and may be used as a signal for anti-malware purposes.
1070a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy         *
1071a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy         * @see PackageManager#EXTRA_VERIFICATION_INSTALLER_UID
1072a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy         */
1073a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public void setOriginatingUid(int originatingUid) {
1074a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            this.originatingUid = originatingUid;
1075a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        }
1076a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy
1077a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /**
10781ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * Optionally set the URI that referred you to install this package. This is
10791ed6b876346b60cbe429955a022c86c02e43e280Todd Kennedy         * informational and may be used as a signal for anti-malware purposes.
1080a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
1081a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see Intent#EXTRA_REFERRER
1082a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
1083a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void setReferrerUri(@Nullable Uri referrerUri) {
1084a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            this.referrerUri = referrerUri;
1085a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1086a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
10877121e18595d4c559044e26bfe6035406a862f466Svet Ganov        /**
10887121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * Sets which runtime permissions to be granted to the package at installation.
10897121e18595d4c559044e26bfe6035406a862f466Svet Ganov         *
10907121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * @param permissions The permissions to grant or null to grant all runtime
10917121e18595d4c559044e26bfe6035406a862f466Svet Ganov         *     permissions.
10927121e18595d4c559044e26bfe6035406a862f466Svet Ganov         *
10937121e18595d4c559044e26bfe6035406a862f466Svet Ganov         * @hide
10947121e18595d4c559044e26bfe6035406a862f466Svet Ganov         */
10957121e18595d4c559044e26bfe6035406a862f466Svet Ganov        @SystemApi
10967121e18595d4c559044e26bfe6035406a862f466Svet Ganov        @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
10977121e18595d4c559044e26bfe6035406a862f466Svet Ganov        public void setGrantedRuntimePermissions(String[] permissions) {
10987121e18595d4c559044e26bfe6035406a862f466Svet Ganov            installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
10997121e18595d4c559044e26bfe6035406a862f466Svet Ganov            this.grantedRuntimePermissions = permissions;
11007121e18595d4c559044e26bfe6035406a862f466Svet Ganov        }
11017121e18595d4c559044e26bfe6035406a862f466Svet Ganov
1102a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
110377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        public void setInstallFlagsInternal() {
110477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags |= PackageManager.INSTALL_INTERNAL;
110577d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
110677d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        }
110777d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey
110877d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        /** {@hide} */
1109c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy        @SystemApi
1110948b702f39935fc856bca913714e489dcd67239bTodd Kennedy        public void setAllowDowngrade(boolean allowDowngrade) {
1111948b702f39935fc856bca913714e489dcd67239bTodd Kennedy            if (allowDowngrade) {
1112948b702f39935fc856bca913714e489dcd67239bTodd Kennedy                installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
1113948b702f39935fc856bca913714e489dcd67239bTodd Kennedy            } else {
1114948b702f39935fc856bca913714e489dcd67239bTodd Kennedy                installFlags &= ~PackageManager.INSTALL_ALLOW_DOWNGRADE;
1115948b702f39935fc856bca913714e489dcd67239bTodd Kennedy            }
1116c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy        }
1117c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy
1118c84d1ab11a5b9d0dc81b673e382e804cc70f35a4Todd Kennedy        /** {@hide} */
111977d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        public void setInstallFlagsExternal() {
112077d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags |= PackageManager.INSTALL_EXTERNAL;
112177d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey            installFlags &= ~PackageManager.INSTALL_INTERNAL;
112277d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        }
112377d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey
112477d218e1869e69c8d436b09cd11dcfe45e50b2cfJeff Sharkey        /** {@hide} */
1125a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        public void setInstallFlagsForcePermissionPrompt() {
1126a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            installFlags |= PackageManager.INSTALL_FORCE_PERMISSION_PROMPT;
1127a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        }
1128a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy
1129a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy        /** {@hide} */
113024ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy        @SystemApi
113124ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy        public void setDontKillApp(boolean dontKillApp) {
113224ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy            if (dontKillApp) {
113324ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy                installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
113424ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy            } else {
113524ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy                installFlags &= ~PackageManager.INSTALL_DONT_KILL_APP;
113624ca5c6d7da534dd529421ccdb45447c90063108Todd Kennedy            }
113739bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy        }
113839bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy
113939bfee5e3674faea992c32204abc1c03429b8cdaTodd Kennedy        /** {@hide} */
1140b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy        @SystemApi
1141b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy        public void setInstallAsInstantApp(boolean isInstantApp) {
1142b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy            if (isInstantApp) {
1143be0b8896d1bc385d4c8fb54c21929745935dcbeaTodd Kennedy                installFlags |= PackageManager.INSTALL_INSTANT_APP;
1144be0b8896d1bc385d4c8fb54c21929745935dcbeaTodd Kennedy                installFlags &= ~PackageManager.INSTALL_FULL_APP;
1145b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy            } else {
1146be0b8896d1bc385d4c8fb54c21929745935dcbeaTodd Kennedy                installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1147be0b8896d1bc385d4c8fb54c21929745935dcbeaTodd Kennedy                installFlags |= PackageManager.INSTALL_FULL_APP;
1148b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy            }
1149b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy        }
1150b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy
115140a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski        /**
115240a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski         * Set the reason for installing this package.
115340a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski         */
115440a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski        public void setInstallReason(@InstallReason int installReason) {
1155a34f53f61be31b7171d6cbcb12490ee143acffffBartosz Fabianowski            this.installReason = installReason;
1156a34f53f61be31b7171d6cbcb12490ee143acffffBartosz Fabianowski        }
1157a34f53f61be31b7171d6cbcb12490ee143acffffBartosz Fabianowski
1158b7717682495e51f602004dfbfabdf767d3fbf3deTodd Kennedy        /** {@hide} */
1159683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        @SystemApi
1160d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey        @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE)
1161683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        public void setAllocateAggressive(boolean allocateAggressive) {
1162683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey            if (allocateAggressive) {
1163683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey                installFlags |= PackageManager.INSTALL_ALLOCATE_AGGRESSIVE;
1164683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey            } else {
1165683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey                installFlags &= ~PackageManager.INSTALL_ALLOCATE_AGGRESSIVE;
1166683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey            }
1167683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        }
1168683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey
1169683bcd30ef0a90bc2a6a3dffb91be5a803560fa9Jeff Sharkey        /** {@hide} */
1170a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void dump(IndentingPrintWriter pw) {
1171a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("mode", mode);
1172a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printHexPair("installFlags", installFlags);
1173a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("installLocation", installLocation);
1174a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("sizeBytes", sizeBytes);
1175a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("appPackageName", appPackageName);
1176a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("appIcon", (appIcon != null));
1177a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("appLabel", appLabel);
1178a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("originatingUri", originatingUri);
1179a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            pw.printPair("originatingUid", originatingUid);
1180a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("referrerUri", referrerUri);
1181a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.printPair("abiOverride", abiOverride);
1182b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            pw.printPair("volumeUuid", volumeUuid);
11837121e18595d4c559044e26bfe6035406a862f466Svet Ganov            pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions);
1184a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            pw.println();
1185fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        }
1186fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey
1187fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        @Override
1188a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int describeContents() {
1189a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return 0;
1190bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
1191a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1192a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        @Override
1193a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void writeToParcel(Parcel dest, int flags) {
1194a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(mode);
1195a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(installFlags);
1196a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(installLocation);
1197a34f53f61be31b7171d6cbcb12490ee143acffffBartosz Fabianowski            dest.writeInt(installReason);
1198a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeLong(sizeBytes);
1199a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appPackageName);
1200a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(appIcon, flags);
1201a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appLabel);
1202a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(originatingUri, flags);
1203a1d12cfdb072acb14fa95d5e771e23396e6bd8e1Todd Kennedy            dest.writeInt(originatingUid);
1204a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(referrerUri, flags);
1205a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(abiOverride);
1206b2b9ab8354da1485178cd8d8e9d89ac915b3f269Jeff Sharkey            dest.writeString(volumeUuid);
12077121e18595d4c559044e26bfe6035406a862f466Svet Ganov            dest.writeStringArray(grantedRuntimePermissions);
1208a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1209a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1210a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final Parcelable.Creator<SessionParams>
1211a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                CREATOR = new Parcelable.Creator<SessionParams>() {
1212a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1213a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionParams createFromParcel(Parcel p) {
1214a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionParams(p);
1215a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
1216a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1217a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1218a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionParams[] newArray(int size) {
1219a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionParams[size];
1220a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
1221a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                };
1222bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
1223bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
12246c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey    /**
1225a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey     * Details for an active install session.
12266c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey     */
1227a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey    public static class SessionInfo implements Parcelable {
1228a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1229a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1230a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int sessionId;
1231a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1232a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String installerPackageName;
1233a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1234a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String resolvedBaseCodePath;
1235a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1236a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public float progress;
1237a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1238a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public boolean sealed;
1239a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1240bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public boolean active;
1241a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1242a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1243a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int mode;
1244a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
124540a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski        public @InstallReason int installReason;
12466d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal        /** {@hide} */
1247a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public long sizeBytes;
1248a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1249a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public String appPackageName;
1250a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1251a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public Bitmap appIcon;
1252a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1253a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public CharSequence appLabel;
1254a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1255a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1256a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionInfo() {
1257a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1258a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1259a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /** {@hide} */
1260a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public SessionInfo(Parcel source) {
1261a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sessionId = source.readInt();
1262a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            installerPackageName = source.readString();
1263a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            resolvedBaseCodePath = source.readString();
1264a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            progress = source.readFloat();
1265a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sealed = source.readInt() != 0;
1266bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            active = source.readInt() != 0;
1267a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1268a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            mode = source.readInt();
12696d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal            installReason = source.readInt();
1270a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            sizeBytes = source.readLong();
1271a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appPackageName = source.readString();
1272a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appIcon = source.readParcelable(null);
1273a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            appLabel = source.readString();
1274a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1275a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
12766c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey        /**
1277a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return the ID for this session.
12786c833e07a05c48ca60ee4d72421bf8b1e78dc710Jeff Sharkey         */
1279a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int getSessionId() {
1280a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return sessionId;
1281a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1282bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1283bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1284a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return the package name of the app that owns this session.
1285bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1286a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable String getInstallerPackageName() {
1287a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return installerPackageName;
1288a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1289bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1290bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1291a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return current overall progress of this session, between 0 and 1.
129216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey         * <p>
1293bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Note that this progress may not directly correspond to the value
1294bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * reported by
1295bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link PackageInstaller.Session#setStagingProgress(float)}, as the
1296bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system may carve out a portion of the overall progress to represent
1297bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * its own internal installation work.
1298bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1299a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public float getProgress() {
1300a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return progress;
1301a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1302bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1303bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1304bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * Return if this session is currently active.
1305bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
1306bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * A session is considered active whenever there is ongoing forward
1307bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * progress being made, such as the installer holding an open
1308bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session} instance while streaming data into place, or the
1309bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * system optimizing code as the result of
1310bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * {@link Session#commit(IntentSender)}.
1311bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * <p>
1312bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * If the installer closes the {@link Session} without committing, the
1313bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * session is considered inactive until the installer opens the session
1314bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey         * again.
1315bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1316bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        public boolean isActive() {
1317bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            return active;
1318bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        }
1319bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey
13206d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal        /**
132104cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         * Return if this session is sealed.
132204cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         * <p>
132304cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         * Once sealed, no further changes may be made to the session. A session
132404cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         * is sealed the moment {@link Session#commit(IntentSender)} is called.
132504cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy         */
132604cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy        public boolean isSealed() {
132704cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy            return sealed;
132804cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy        }
132904cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy
133004cc191c3cb79fd8875d813dcd25b6f797eb34ccTodd Kennedy        /**
13316d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal         * Return the reason for installing this package.
13326d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal         *
133340a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski         * @return The install reason.
13346d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal         */
133540a006285b954607a96b1209de95bbed48d856f7Bartosz Fabianowski        public @InstallReason int getInstallReason() {
13366d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal            return installReason;
13376d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal        }
13386d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal
1339bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        /** {@hide} */
1340bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey        @Deprecated
1341a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public boolean isOpen() {
1342bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            return isActive();
1343a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1344bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1345bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        /**
1346a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return the package name this session is working with. May be {@code null}
1347a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * if unknown.
1348bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey         */
1349a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable String getAppPackageName() {
1350a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return appPackageName;
1351a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
135216c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
13537328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey        /**
1354a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return an icon representing the app being installed. May be {@code null}
1355a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * if unavailable.
13567328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey         */
1357a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable Bitmap getAppIcon() {
1358a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return appIcon;
1359a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
13607328a1b39b3dae1c0cd390c0a3695c6a46b8e9d8Jeff Sharkey
1361a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        /**
1362a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return a label representing the app being installed. May be {@code null}
1363a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * if unavailable.
1364a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         */
1365a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public @Nullable CharSequence getAppLabel() {
1366a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return appLabel;
1367a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
136816c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
1369fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        /**
1370a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * Return an Intent that can be started to view details about this install
1371a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * session. This may surface actions such as pause, resume, or cancel.
1372fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         * <p>
1373a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * In some cases, a matching Activity may not exist, so ensure you safeguard
1374a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * against this.
1375a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         *
1376a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey         * @see PackageInstaller#ACTION_SESSION_DETAILS
1377fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey         */
1378de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        public @Nullable Intent createDetailsIntent() {
1379a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            final Intent intent = new Intent(PackageInstaller.ACTION_SESSION_DETAILS);
1380a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
1381a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            intent.setPackage(installerPackageName);
1382a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1383a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return intent;
1384bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        }
1385bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey
1386de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        /** {@hide} */
1387de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        @Deprecated
1388de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        public @Nullable Intent getDetailsIntent() {
1389de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey            return createDetailsIntent();
1390de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey        }
1391de74231f245c90e5861ec84a9880b5b4ec247480Jeff Sharkey
1392bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey        @Override
1393a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public int describeContents() {
1394a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            return 0;
1395fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        }
1396fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey
1397fbd0e9fa37fc17ccd25e4c1f16195bbd27de3c4cJeff Sharkey        @Override
1398a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public void writeToParcel(Parcel dest, int flags) {
1399a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(sessionId);
1400a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(installerPackageName);
1401a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(resolvedBaseCodePath);
1402a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeFloat(progress);
1403a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(sealed ? 1 : 0);
1404bc7bce38b2e4733a14f6296c75f983bd50f996d1Jeff Sharkey            dest.writeInt(active ? 1 : 0);
1405a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1406a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeInt(mode);
14076d7cb232362d8036875d1d3c3f0e8f5d47a2ad25Sunny Goyal            dest.writeInt(installReason);
1408a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeLong(sizeBytes);
1409a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appPackageName);
1410a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeParcelable(appIcon, flags);
1411a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey            dest.writeString(appLabel != null ? appLabel.toString() : null);
1412a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        }
1413a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey
1414a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey        public static final Parcelable.Creator<SessionInfo>
1415a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                CREATOR = new Parcelable.Creator<SessionInfo>() {
1416a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1417a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionInfo createFromParcel(Parcel p) {
1418a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionInfo(p);
1419a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
142016c8e3f49497b6046972ae650772f65768366be8Jeff Sharkey
1421a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    @Override
1422a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    public SessionInfo[] newArray(int size) {
1423a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                        return new SessionInfo[size];
1424a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                    }
1425a0907436c01fd8c545a6b5c7b28bc3bc9db59270Jeff Sharkey                };
1426bb580670350b76fa2fcc5ee873f99b7970759cbfJeff Sharkey    }
14273a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey}
1428