From 51ce8ee3b1b95dfca1da05dbce74ba0096dd988f Mon Sep 17 00:00:00 2001 From: Fyodor Kupolov Date: Wed, 27 Jul 2016 17:45:12 -0700 Subject: [PATCH] Set secure setting when all preloaded apps are installed Bug: 30280710 Change-Id: Id87b51c53b1e553a6ab0a257be93baf7d31b6fe5 --- core/java/android/provider/Settings.java | 6 +++ .../server/retaildemo/PreloadAppsInstaller.java | 61 ++++++++++++++++++---- .../server/retaildemo/RetailDemoModeService.java | 2 +- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 5e4cd3331306..5da55b164f54 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6299,6 +6299,12 @@ public final class Settings { public static final String SYSTEM_NAVIGATION_KEYS_ENABLED = "system_navigation_keys_enabled"; + /** + * Whether preloaded APKs have been installed for the user. + * @hide + */ + public static final String DEMO_USER_SETUP_COMPLETE + = "demo_user_setup_complete"; /** * This are the settings to be backed up. diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java index 848017063bff..c0bf9b331f7c 100644 --- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java +++ b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java @@ -18,12 +18,14 @@ package com.android.server.retaildemo; import android.app.AppGlobals; import android.app.PackageInstallObserver; +import android.content.Context; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Environment; import android.os.RemoteException; import android.os.UserHandle; +import android.provider.Settings; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; @@ -47,15 +49,17 @@ class PreloadAppsInstaller { private final IPackageManager mPackageManager; private final File preloadsAppsDirectory; + private final Context mContext; private final Map mApkToPackageMap; - PreloadAppsInstaller() { - this(AppGlobals.getPackageManager(), Environment.getDataPreloadsAppsDirectory()); + PreloadAppsInstaller(Context context) { + this(context, AppGlobals.getPackageManager(), Environment.getDataPreloadsAppsDirectory()); } @VisibleForTesting - PreloadAppsInstaller(IPackageManager packageManager, File preloadsAppsDirectory) { + PreloadAppsInstaller(Context context, IPackageManager packageManager, File preloadsAppsDirectory) { + mContext = context; mPackageManager = packageManager; mApkToPackageMap = Collections.synchronizedMap(new ArrayMap<>()); this.preloadsAppsDirectory = preloadsAppsDirectory; @@ -66,28 +70,34 @@ class PreloadAppsInstaller { if (ArrayUtils.isEmpty(files)) { return; } + AppInstallCounter counter = new AppInstallCounter(mContext, userId); + int expectedCount = 0; for (File file : files) { String apkName = file.getName(); if (apkName.endsWith(PRELOAD_APK_EXT) && file.isFile()) { String packageName = mApkToPackageMap.get(apkName); if (packageName != null) { try { - installExistingPackage(packageName, userId); + expectedCount++; + installExistingPackage(packageName, userId, counter); } catch (Exception e) { Slog.e(TAG, "Failed to install existing package " + packageName, e); } } else { try { - installPackage(file, userId); + installPackage(file, userId, counter); + expectedCount++; } catch (Exception e) { Slog.e(TAG, "Failed to install package from " + file, e); } } } } + counter.setExpectedAppsCount(expectedCount); } - private void installExistingPackage(String packageName, int userId) { + private void installExistingPackage(String packageName, int userId, + AppInstallCounter counter) { if (DEBUG) { Log.d(TAG, "installExistingPackage " + packageName + " u" + userId); } @@ -95,10 +105,13 @@ class PreloadAppsInstaller { mPackageManager.installExistingPackageAsUser(packageName, userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } finally { + counter.appInstallFinished(); } } - private void installPackage(File file, final int userId) throws IOException, RemoteException { + private void installPackage(File file, final int userId, AppInstallCounter counter) + throws IOException, RemoteException { final String apkName = file.getName(); if (DEBUG) { Log.d(TAG, "installPackage " + apkName + " u" + userId); @@ -111,15 +124,45 @@ class PreloadAppsInstaller { Log.d(TAG, "Package " + basePackageName + " installed u" + userId + " returnCode: " + returnCode + " msg: " + msg); } + // Don't notify the counter for now, we'll do it in installExistingPackage if (returnCode == PackageManager.INSTALL_SUCCEEDED) { mApkToPackageMap.put(apkName, basePackageName); // Install on user 0 so that the package is cached when demo user is re-created - installExistingPackage(basePackageName, UserHandle.USER_SYSTEM); + installExistingPackage(basePackageName, UserHandle.USER_SYSTEM, counter); } else if (returnCode == PackageManager.INSTALL_FAILED_ALREADY_EXISTS) { - installExistingPackage(basePackageName, userId); + installExistingPackage(basePackageName, userId, counter); } } }.getBinder(), 0, SYSTEM_SERVER_PACKAGE_NAME, userId); } + private static class AppInstallCounter { + private int expectedCount = -1; // -1 means expectedCount not set + private int finishedCount; + private final Context mContext; + private final int userId; + + AppInstallCounter(Context context, int userId) { + mContext = context; + this.userId = userId; + } + + synchronized void appInstallFinished() { + this.finishedCount++; + checkIfAllFinished(); + } + + synchronized void setExpectedAppsCount(int expectedCount) { + this.expectedCount = expectedCount; + checkIfAllFinished(); + } + + private void checkIfAllFinished() { + if (expectedCount == finishedCount) { + Log.i(TAG, "All preloads finished installing for user " + userId); + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.DEMO_USER_SETUP_COMPLETE, "1", userId); + } + } + } } \ No newline at end of file diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java index 1a605929bdc5..c6078fde7b76 100644 --- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java +++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java @@ -287,7 +287,7 @@ public class RetailDemoModeService extends SystemService { synchronized (mActivityLock) { mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis(); } - mPreloadAppsInstaller = new PreloadAppsInstaller(); + mPreloadAppsInstaller = new PreloadAppsInstaller(context); } private Notification createResetNotification() { -- 2.11.0