Loading services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * 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 services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java +10 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -203,6 +204,7 @@ public class RetailDemoModeService extends SystemService { synchronized (mActivityLock) { mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis(); } mPreloadAppsInstaller = new PreloadAppsInstaller(); } private Notification createResetNotification() { Loading Loading @@ -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()); } Loading Loading @@ -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() { Loading Loading
services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * 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
services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java +10 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -203,6 +204,7 @@ public class RetailDemoModeService extends SystemService { synchronized (mActivityLock) { mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis(); } mPreloadAppsInstaller = new PreloadAppsInstaller(); } private Notification createResetNotification() { Loading Loading @@ -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()); } Loading Loading @@ -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() { Loading