Download File
Download Project
Settings
Line Wrap
Themes
default
ambiance
bespin
dracula
eclipse
material
mbo
mdn-like
neat
solarized dark
ttcn
zenburn
CosuConfig.java
/* * Copyright (C) 2015 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.afwsamples.testdpc.cosu; import android.annotation.TargetApi; import android.app.DownloadManager; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.ParcelFileDescriptor; import android.util.Log; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Set; /** * This class represents the specific cosu set up we want to achieve. The set up is read from an * XML config file. Additional apps are downloaded and the specified policies are applied. */ /* package */ class CosuConfig { private static final String TAG_APP = "app"; private static final String TAG_COSU_CONFIG = "cosu-config"; private static final String TAG_DOWNLOAD_APPS = "download-apps"; private static final String TAG_ENABLE_APPS = "enable-apps"; private static final String TAG_HIDE_APPS = "hide-apps"; private static final String TAG_KIOSK_APPS = "kiosk-apps"; private static final String TAG_POLICIES = "policies"; private static final String TAG_USER_RESTRICTION = "user-restriction"; private static final String TAG_GLOBAL_SETTING = "global-setting"; private static final String TAG_DISABLE_STATUS_BAR = "disable-status-bar"; private static final String TAG_DISABLE_KEYGUARD = "disable-keyguard"; private static final String TAG_DISABLE_CAMERA = "disable-camera"; private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture"; private static final String ATTRIBUTE_DOWNLOAD_LOCATION = "download-location"; private static final String ATTRIBUTE_MODE = "mode"; private static final String ATTRIBUTE_PACKAGE_NAME = "package-name"; private static final String ATTRIBUTE_VALUE = "value"; private static final String ATTRIBUTE_NAME = "name"; private static final String NEW_LINE = System.getProperty("line.separator"); private Context mContext; private DownloadManager mDownloadManager; private Set
mHideApps = new HashSet<>(); private Set
mEnableSystemApps = new HashSet<>(); private Set
mKioskApps = new HashSet<>(); private Set
mDownloadApps = new HashSet<>(); private String mMode; private Set
mUserRestrictions = new HashSet<>(); private Set
mGlobalSettings = new HashSet<>(); private boolean mDisableStatusBar = false; private boolean mDisableKeyguard = false; private boolean mDisableScreenCapture = false; private boolean mDisableCamera = false; /** * Parses the config xml file given in the form of an InputStream. */ private CosuConfig(Context context, InputStream in) throws XmlPullParserException, IOException { mContext = context; mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE); try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, null); while (parser.next() != XmlPullParser.END_DOCUMENT) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); if (TAG_COSU_CONFIG.equals(name)) { mMode = parser.getAttributeValue(null, ATTRIBUTE_MODE); } else if (TAG_POLICIES.equals(name)) { readPolicies(parser); } else if (TAG_ENABLE_APPS.equals(name)) { readApps(parser, mEnableSystemApps); } else if (TAG_HIDE_APPS.equals(name)) { readApps(parser, mHideApps); } else if (TAG_KIOSK_APPS.equals(name)) { readApps(parser, mKioskApps); } else if (TAG_DOWNLOAD_APPS.equals(name)) { readDownloadApps(parser, mDownloadApps); } } } finally { in.close(); } } public static CosuConfig createConfig(Context context, InputStream in) { try { return new CosuConfig(context, in); } catch (XmlPullParserException | IOException e) { Log.e(CosuUtils.TAG, "Exception during config creation.", e); return null; } } public boolean applyPolicies(ComponentName admin) { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( Context.DEVICE_POLICY_SERVICE); try { dpm.setLockTaskPackages(admin, getKioskApps()); } catch (SecurityException e) { Log.d(CosuUtils.TAG, "Exception when setting lock task packages", e); return false; } // hide apps for (String pkg : mHideApps) { dpm.setApplicationHidden(admin, pkg, true); } // enable system apps for (String pkg : mEnableSystemApps) { try { dpm.enableSystemApp(admin, pkg); } catch (IllegalArgumentException e) { Log.w(CosuUtils.TAG, "Failed to enable " + pkg + ". Operation is only allowed for system apps."); } } // set user restrictions for (String userRestriction : mUserRestrictions) { dpm.addUserRestriction(admin, userRestriction); } for (GlobalSetting globalSetting : mGlobalSettings) { dpm.setGlobalSetting(admin, globalSetting.key, globalSetting.value); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { disableKeyGuardAndStatusBar(dpm, admin); } dpm.setScreenCaptureDisabled(admin, mDisableScreenCapture); dpm.setCameraDisabled(admin, mDisableCamera); return true; } @TargetApi(Build.VERSION_CODES.M) private void disableKeyGuardAndStatusBar(DevicePolicyManager dpm, ComponentName admin) { dpm.setStatusBarDisabled(admin, mDisableStatusBar); dpm.setKeyguardDisabled(admin, mDisableKeyguard); } public void initiateDownloadAndInstall(Handler handler) { for (DownloadAppInfo ai : mDownloadApps) { ai.downloadId = CosuUtils.startDownload(mDownloadManager, handler, ai.downloadLocation); } } public String getMode() { return mMode; } public String[] getKioskApps() { return mKioskApps.toArray(new String[mKioskApps.size()]); } public boolean areAllInstallsFinished() { for (DownloadAppInfo ai : mDownloadApps) { if (!ai.installCompleted) { return false; } } return true; } public Long onDownloadComplete(Long id) { for (DownloadAppInfo ai : mDownloadApps) { if (id.equals(ai.downloadId)) { if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, "Package download complete: " + ai.packageName); ai.downloadCompleted = true; try { ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(id); InputStream in = new FileInputStream(pfd.getFileDescriptor()); CosuUtils.installPackage(mContext, in, ai.packageName); } catch (IOException e) { Log.e(CosuUtils.TAG, "Error installing package: " + ai.packageName, e); // We are still marking the package as "installed", just so we don't block the // entire flow. ai.installCompleted = true; } return ai.downloadId; } } Log.w(CosuUtils.TAG, "Unknown download id: " + id); return null; } public void onInstallComplete(String packageName) { if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, "Package install complete: " + packageName); for (DownloadAppInfo ai : mDownloadApps) { if (packageName.equals(ai.packageName)) { ai.installCompleted = true; return; } } } /** * Read a number of apps from the xml parser */ private void readApps(XmlPullParser parser, Set
apps) throws XmlPullParserException, IOException { while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); if (TAG_APP.equals(name)) { String packageName = parser.getAttributeValue(null, ATTRIBUTE_PACKAGE_NAME); if (packageName != null) { apps.add(packageName); } skipCurrentTag(parser); } } } /** * Read a number of apps with download information from the xml parser */ private void readDownloadApps(XmlPullParser parser, Set
apps) throws XmlPullParserException, IOException { while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); if (TAG_APP.equals(name)) { String packageName = parser.getAttributeValue(null, ATTRIBUTE_PACKAGE_NAME); String downloadLocation = parser.getAttributeValue(null, ATTRIBUTE_DOWNLOAD_LOCATION); if (packageName != null && downloadLocation != null) { apps.add(new DownloadAppInfo(packageName, downloadLocation)); } skipCurrentTag(parser); } } } /** * Read the policies to be set */ private void readPolicies(XmlPullParser parser) throws IOException, XmlPullParserException { while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); if (TAG_USER_RESTRICTION.equals(name)) { String userRestriction = parser.getAttributeValue(null, ATTRIBUTE_NAME); if (userRestriction != null) { mUserRestrictions.add(userRestriction); } } else if (TAG_GLOBAL_SETTING.equals(name)) { String setting = parser.getAttributeValue(null, ATTRIBUTE_NAME); String value = parser.getAttributeValue(null, ATTRIBUTE_VALUE); if (setting != null && value != null) { mGlobalSettings.add(new GlobalSetting(setting, value)); } } else if (TAG_DISABLE_STATUS_BAR.equals(name)) { mDisableStatusBar = Boolean.parseBoolean(parser.getAttributeValue(null, ATTRIBUTE_VALUE)); } else if (TAG_DISABLE_KEYGUARD.equals(name)) { mDisableKeyguard = Boolean.parseBoolean(parser.getAttributeValue(null, ATTRIBUTE_VALUE)); } else if (TAG_DISABLE_CAMERA.equals(name)) { mDisableCamera = Boolean.parseBoolean(parser.getAttributeValue(null, ATTRIBUTE_VALUE)); } else if (TAG_DISABLE_SCREEN_CAPTURE.equals(name)) { mDisableScreenCapture = Boolean.parseBoolean(parser.getAttributeValue(null, ATTRIBUTE_VALUE)); } skipCurrentTag(parser); } } /** * Continue to the end of the current xml tag */ private void skipCurrentTag(XmlPullParser parser) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { } } private class DownloadAppInfo { public final String packageName; public final String downloadLocation; public Long downloadId; public boolean downloadCompleted; public boolean installCompleted; public DownloadAppInfo(String packageName, String downloadLocation) { this.packageName = packageName; this.downloadLocation = downloadLocation; this.downloadCompleted = false; this.installCompleted = false; } @Override public String toString() { return "packageName: " + packageName + " downloadLocation: " + downloadLocation; } } private class GlobalSetting { public final String key; public final String value; public GlobalSetting(String key, String value) { this.key = key; this.value = value; } @Override public String toString() { return "setting: " + key + " value: " + value; } } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Mode: ").append(mMode).append(NEW_LINE); builder.append("Disable status bar: ").append(mDisableStatusBar).append(NEW_LINE); builder.append("Disable keyguard: ").append(mDisableKeyguard).append(NEW_LINE); builder.append("Disable screen capture: ").append(mDisableScreenCapture).append(NEW_LINE); builder.append("Disable camera: ").append(mDisableCamera).append(NEW_LINE); builder.append("User restrictions:").append(NEW_LINE); dumpSet(builder, mUserRestrictions); builder.append("Global settings:").append(NEW_LINE); dumpSet(builder, mGlobalSettings); builder.append("Hide apps:").append(NEW_LINE); dumpSet(builder, mHideApps); builder.append("Enable system apps:").append(NEW_LINE); dumpSet(builder, mEnableSystemApps); builder.append("Kiosk apps:").append(NEW_LINE); dumpSet(builder, mKioskApps); builder.append("Download apps:").append(NEW_LINE); dumpSet(builder, mDownloadApps); return builder.toString(); } private void dumpSet(StringBuilder builder, Set> set) { for (Object obj : set) { builder.append(" ").append(obj.toString()).append(NEW_LINE); } } }