[pm/incremental] start monitoring progress on storage creation

For Incremental installs, the installation progress will be equal to the
loading progress, which is the percentage of filled blocks divided by
the total number of blocks. The installation progress reported from the
client will be ignored. This is for a smoother visual transition between
installed state and loading state, as reflected in the launcher UI.

See timestamp 00:26 in video:
https://drive.google.com/file/d/11Z4IwUvaoMx0QZVboq7idxu4PUZZcGw-/view?usp=sharing&resourcekey=0-EQDzWobRTJxTQCCGUfbXQA

It reflects the <25% of loading progress instead of the 100% installation
progress, though not very visible.

BUG: 172082017
Test: manual
Change-Id: I30bac011fc4fe431960570640e6ced55b01c0234
This commit is contained in:
Songchun Fan
2020-11-18 12:19:29 -08:00
parent 558c605944
commit 31fa0fc9c1
2 changed files with 28 additions and 4 deletions

View File

@@ -36,6 +36,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.DataLoaderParams;
import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.IPackageLoadingProgressCallback;
import android.content.pm.InstallationFileParcel;
import android.text.TextUtils;
@@ -70,7 +71,8 @@ public final class IncrementalFileStorages {
@Nullable StorageHealthCheckParams healthCheckParams,
@Nullable IStorageHealthListener healthListener,
@NonNull List<InstallationFileParcel> addedFiles,
@NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException {
@NonNull PerUidReadTimeouts[] perUidReadTimeouts,
IPackageLoadingProgressCallback progressCallback) throws IOException {
// TODO(b/136132412): validity check if session should not be incremental
IncrementalManager incrementalManager = (IncrementalManager) context.getSystemService(
Context.INCREMENTAL_SERVICE);
@@ -95,7 +97,11 @@ public final class IncrementalFileStorages {
throw new IOException("Unknown file location: " + file.location);
}
}
// Register progress loading callback after files have been added
if (progressCallback != null) {
incrementalManager.registerLoadingProgressCallback(stageDir.getAbsolutePath(),
progressCallback);
}
result.startLoading();
return result;
@@ -180,6 +186,7 @@ public final class IncrementalFileStorages {
try {
mDefaultStorage.unBind(mStageDir.getAbsolutePath());
mDefaultStorage.unregisterLoadingProgressListener();
} catch (IOException ignored) {
}
mDefaultStorage = null;

View File

@@ -71,6 +71,7 @@ import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstallerSession;
import android.content.pm.IPackageInstallerSessionFileSystemConnector;
import android.content.pm.IPackageLoadingProgressCallback;
import android.content.pm.InstallationFile;
import android.content.pm.InstallationFileParcel;
import android.content.pm.PackageInfo;
@@ -319,6 +320,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private float mProgress = 0;
@GuardedBy("mLock")
private float mReportedProgress = -1;
@GuardedBy("mLock")
private float mIncrementalProgress = 0;
/** State of the session. */
@GuardedBy("mLock")
@@ -1182,7 +1185,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mLock")
private void computeProgressLocked(boolean forcePublish) {
mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f)
// This method is triggered when the client progress is updated or the incremental progress
// is updated. For incremental installs, ignore the progress values reported from client.
// Instead, only use the progress reported by IncFs as the percentage of loading completion.
final float loadingProgress =
isIncrementalInstallation() ? mIncrementalProgress : mClientProgress;
mProgress = MathUtils.constrain(loadingProgress * 0.8f, 0f, 0.8f)
+ MathUtils.constrain(mInternalProgress * 0.2f, 0f, 0.2f);
// Only publish when meaningful change
@@ -3704,7 +3712,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir,
params, statusListener, healthCheckParams, healthListener, addedFiles,
perUidReadTimeouts);
perUidReadTimeouts,
new IPackageLoadingProgressCallback.Stub() {
@Override
public void onPackageLoadingProgressChanged(float progress) {
synchronized (mLock) {
mIncrementalProgress = progress;
computeProgressLocked(true);
}
}
});
return false;
} catch (IOException e) {
throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(),