Merge "Install preloaded apps into the demo user" into nyc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c77a2be407
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -110,6 +110,7 @@ public class RetailDemoModeService extends SystemService {
|
|||||||
private CameraManager mCameraManager;
|
private CameraManager mCameraManager;
|
||||||
private String[] mCameraIdsWithFlash;
|
private String[] mCameraIdsWithFlash;
|
||||||
private Configuration mSystemUserConfiguration;
|
private Configuration mSystemUserConfiguration;
|
||||||
|
private PreloadAppsInstaller mPreloadAppsInstaller;
|
||||||
|
|
||||||
final Object mActivityLock = new Object();
|
final Object mActivityLock = new Object();
|
||||||
// Whether the newly created demo user has interacted with the screen yet
|
// Whether the newly created demo user has interacted with the screen yet
|
||||||
@@ -203,6 +204,7 @@ public class RetailDemoModeService extends SystemService {
|
|||||||
synchronized (mActivityLock) {
|
synchronized (mActivityLock) {
|
||||||
mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis();
|
mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis();
|
||||||
}
|
}
|
||||||
|
mPreloadAppsInstaller = new PreloadAppsInstaller();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Notification createResetNotification() {
|
private Notification createResetNotification() {
|
||||||
@@ -253,6 +255,8 @@ public class RetailDemoModeService extends SystemService {
|
|||||||
um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
|
um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
|
||||||
Settings.Secure.putIntForUser(getContext().getContentResolver(),
|
Settings.Secure.putIntForUser(getContext().getContentResolver(),
|
||||||
Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
|
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());
|
grantRuntimePermissionToCamera(userInfo.getUserHandle());
|
||||||
}
|
}
|
||||||
@@ -458,6 +462,12 @@ public class RetailDemoModeService extends SystemService {
|
|||||||
}
|
}
|
||||||
MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, 1);
|
MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, 1);
|
||||||
mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
|
mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mPreloadAppsInstaller.installApps(userId);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() {
|
private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() {
|
||||||
|
|||||||
Reference in New Issue
Block a user