diff options
| -rw-r--r-- | services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java | 125 | ||||
| -rw-r--r-- | services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java | 10 |
2 files changed, 135 insertions, 0 deletions
diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java new file mode 100644 index 000000000000..848017063bff --- /dev/null +++ b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.retaildemo; + +import android.app.AppGlobals; +import android.app.PackageInstallObserver; +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.util.ArrayMap; +import android.util.Log; +import android.util.Slog; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.Map; + +/** + * Helper class for installing preloaded APKs + */ +class PreloadAppsInstaller { + private static final String SYSTEM_SERVER_PACKAGE_NAME = "android"; + private static String TAG = PreloadAppsInstaller.class.getSimpleName(); + private static final String PRELOAD_APK_EXT = ".apk.preload"; + private static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + private final IPackageManager mPackageManager; + private final File preloadsAppsDirectory; + + private final Map<String, String> mApkToPackageMap; + + PreloadAppsInstaller() { + this(AppGlobals.getPackageManager(), Environment.getDataPreloadsAppsDirectory()); + } + + @VisibleForTesting + PreloadAppsInstaller(IPackageManager packageManager, File preloadsAppsDirectory) { + mPackageManager = packageManager; + mApkToPackageMap = Collections.synchronizedMap(new ArrayMap<>()); + this.preloadsAppsDirectory = preloadsAppsDirectory; + } + + void installApps(int userId) { + File[] files = preloadsAppsDirectory.listFiles(); + if (ArrayUtils.isEmpty(files)) { + return; + } + 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); + } catch (Exception e) { + Slog.e(TAG, "Failed to install existing package " + packageName, e); + } + } else { + try { + installPackage(file, userId); + } catch (Exception e) { + Slog.e(TAG, "Failed to install package from " + file, e); + } + } + } + } + } + + private void installExistingPackage(String packageName, int userId) { + if (DEBUG) { + Log.d(TAG, "installExistingPackage " + packageName + " u" + userId); + } + try { + mPackageManager.installExistingPackageAsUser(packageName, userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + private void installPackage(File file, final int userId) throws IOException, RemoteException { + final String apkName = file.getName(); + if (DEBUG) { + Log.d(TAG, "installPackage " + apkName + " u" + userId); + } + mPackageManager.installPackageAsUser(file.getPath(), new PackageInstallObserver() { + @Override + public void onPackageInstalled(String basePackageName, int returnCode, String msg, + Bundle extras) { + if (DEBUG) { + Log.d(TAG, "Package " + basePackageName + " installed u" + userId + + " returnCode: " + returnCode + " msg: " + msg); + } + 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); + } else if (returnCode == PackageManager.INSTALL_FAILED_ALREADY_EXISTS) { + installExistingPackage(basePackageName, userId); + } + } + }.getBinder(), 0, SYSTEM_SERVER_PACKAGE_NAME, 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 2529564107b2..04049a17e6ce 100644 --- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java +++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java @@ -110,6 +110,7 @@ public class RetailDemoModeService extends SystemService { private CameraManager mCameraManager; private String[] mCameraIdsWithFlash; private Configuration mSystemUserConfiguration; + private PreloadAppsInstaller mPreloadAppsInstaller; final Object mActivityLock = new Object(); // Whether the newly created demo user has interacted with the screen yet @@ -203,6 +204,7 @@ public class RetailDemoModeService extends SystemService { synchronized (mActivityLock) { mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis(); } + mPreloadAppsInstaller = new PreloadAppsInstaller(); } private Notification createResetNotification() { @@ -253,6 +255,8 @@ public class RetailDemoModeService extends SystemService { um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user); Settings.Secure.putIntForUser(getContext().getContentResolver(), Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id); + Settings.Secure.putIntForUser(getContext().getContentResolver(), + Settings.Global.PACKAGE_VERIFIER_ENABLE, 0, userInfo.id); grantRuntimePermissionToCamera(userInfo.getUserHandle()); } @@ -458,6 +462,12 @@ public class RetailDemoModeService extends SystemService { } MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, 1); mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT); + mHandler.post(new Runnable() { + @Override + public void run() { + mPreloadAppsInstaller.installApps(userId); + } + }); } private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() { |