Download File
Download Project
Settings
Line Wrap
Themes
default
ambiance
bespin
dracula
eclipse
material
mbo
mdn-like
neat
solarized dark
ttcn
zenburn
EnableCosuActivity.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.app.Activity; import android.app.DownloadManager; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.PackageInstaller; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.android.setupwizardlib.SetupWizardLayout; import com.android.setupwizardlib.view.NavigationBar; import com.afwsamples.testdpc.DeviceAdminReceiver; import com.afwsamples.testdpc.R; import com.afwsamples.testdpc.policy.locktask.KioskModeActivity; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; /** * This activity is started after provisioning is complete in {@link DeviceAdminReceiver} for * COSU devices. It loads a config file and downloads, install, hides and enables apps according * to the data in the config file. */ public class EnableCosuActivity extends Activity { public static final String BUNDLE_KEY_COSU_CONFIG = "cosu-demo-config-location"; private static final String MODE_CUSTOM = "custom"; private static final String MODE_DEFAULT = "default"; private static final String MODE_SINGLE = "single"; private DownloadManager mDownloadManager; private TextView mStatusText; private Long mConfigDownloadId; private CosuConfig mConfig; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // verify device owner status DevicePolicyManager dpm = (DevicePolicyManager) getSystemService( Context.DEVICE_POLICY_SERVICE); if (!dpm.isDeviceOwnerApp(getPackageName())) { Log.e(CosuUtils.TAG, "TestDPC is not the device owner, cannot set up COSU device."); finish(); return; } // read the admin bundle PersistableBundle persistableBundle = getIntent().getParcelableExtra( DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE); if (persistableBundle == null) { Log.e(CosuUtils.TAG, "No admin extra bundle"); finish(); return; } setContentView(R.layout.enable_cosu_activity); SetupWizardLayout layout = (SetupWizardLayout) findViewById(R.id.setup_wizard_layout); NavigationBar navigationBar = layout.getNavigationBar(); navigationBar.getNextButton().setVisibility(View.GONE); navigationBar.getBackButton().setVisibility(View.GONE); layout.showProgressBar(); mStatusText = (TextView) findViewById(R.id.status_text); mDownloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); // register the download and install receiver registerReceiver(mDownloadReceiver, new IntentFilter( DownloadManager.ACTION_DOWNLOAD_COMPLETE)); registerReceiver(mInstallReceiver, new IntentFilter(CosuUtils.ACTION_INSTALL_COMPLETE)); // download the config file String configDownloadLocation = (String) persistableBundle.get(BUNDLE_KEY_COSU_CONFIG); if (configDownloadLocation == null) { Log.e(CosuUtils.TAG, "No download-location specified"); finishWithFailure(); return; } if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, "Downloading config file"); mConfigDownloadId = CosuUtils.startDownload(mDownloadManager, mHandler, configDownloadLocation); mStatusText.setText(getString(R.string.setup_cosu_status_download)); } private void onConfigFileDownloaded() { mStatusText.setText(getString(R.string.setup_cosu_status_parse)); if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, "Config file downloaded"); ParcelFileDescriptor pfd; try { pfd = mDownloadManager.openDownloadedFile(mConfigDownloadId); } catch (FileNotFoundException e) { Log.e(CosuUtils.TAG, "Download file not found.", e); finishWithFailure(); return; } InputStream in = new FileInputStream(pfd.getFileDescriptor()); mConfig = CosuConfig.createConfig(this, in); if (mConfig == null) { finishWithFailure(); return; } Log.d(CosuUtils.TAG, "CosuConfig:"); Log.d(CosuUtils.TAG, mConfig.toString()); if (!mConfig.applyPolicies(DeviceAdminReceiver.getComponentName(this))) { finishWithFailure(); return; } mConfig.initiateDownloadAndInstall(mHandler); mStatusText.setText(getString(R.string.setup_cosu_status_apps)); if (mConfig.areAllInstallsFinished()) { startCosuMode(); } } /** * Start the actual COSU mode and drop the user into different screens depending on the value * of mode. * default: Launch the home screen with a default launcher * custom: Launch KioskModeActivity (custom launcher) with only the kiosk apps present * single: Launch the first of the kiosk apps */ private void startCosuMode() { Intent launchIntent = null; String mode = mConfig.getMode(); String[] kioskApps = mConfig.getKioskApps(); if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, "Starting Cosu mode: " + mode); if (mode == null) { mode = MODE_DEFAULT; } if (MODE_CUSTOM.equals(mode)) { // Start the KioskModeActivity with all apps in kioskApps launchIntent = new Intent(this, KioskModeActivity.class); launchIntent.putExtra(KioskModeActivity.LOCKED_APP_PACKAGE_LIST, kioskApps); getPackageManager().setComponentEnabledSetting( new ComponentName(getPackageName(), KioskModeActivity.class.getName()), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); } else if (MODE_SINGLE.equals(mode)) { // Start the first app in kioskApps if (kioskApps.length != 0) { if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, " Launching app " + kioskApps[0]); launchIntent = getPackageManager().getLaunchIntentForPackage(kioskApps[0]); } } else { // MODE_DEFAULT // Start the default launcher with a home intent launchIntent = new Intent(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_HOME); } if (launchIntent == null) { Log.e(CosuUtils.TAG, "No launch intent specified. Mode=" + mode); finishWithFailure(); return; } launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(launchIntent); Toast.makeText(this, R.string.setup_cosu_success, Toast.LENGTH_LONG).show(); unregisterReceiver(mInstallReceiver); unregisterReceiver(mDownloadReceiver); // check that no timeout messages remain on the handler and remove them if (mHandler.hasMessages(CosuUtils.MSG_DOWNLOAD_TIMEOUT)) { Log.w(CosuUtils.TAG, "Download timeout messages remaining on handler thread."); mHandler.removeMessages(CosuUtils.MSG_DOWNLOAD_TIMEOUT); } finish(); } private void finishWithFailure() { Toast.makeText(this, R.string.setup_cosu_failure, Toast.LENGTH_LONG).show(); unregisterReceiver(mInstallReceiver); unregisterReceiver(mDownloadReceiver); mHandler.removeMessages(CosuUtils.MSG_DOWNLOAD_TIMEOUT); finish(); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case CosuUtils.MSG_DOWNLOAD_COMPLETE: { if (mConfigDownloadId.equals(msg.obj)) { onConfigFileDownloaded(); removeMessages(CosuUtils.MSG_DOWNLOAD_TIMEOUT, mConfigDownloadId); } else { Long id = mConfig.onDownloadComplete((Long) msg.obj); if (id != null) { removeMessages(CosuUtils.MSG_DOWNLOAD_TIMEOUT, id); } if (mConfig.areAllInstallsFinished()) { startCosuMode(); } } } break; case CosuUtils.MSG_DOWNLOAD_TIMEOUT: { long id = ((Long) msg.obj).longValue(); if (id == mConfigDownloadId) { Log.e(CosuUtils.TAG, "Time out during download of config file"); mDownloadManager.remove(mConfigDownloadId); } else { mDownloadManager.remove(id); Log.e(CosuUtils.TAG, "Time out during app download with id: " + id); } finishWithFailure(); } break; case CosuUtils.MSG_INSTALL_COMPLETE: { mConfig.onInstallComplete((String) msg.obj); if (mConfig.areAllInstallsFinished()) { startCosuMode(); } } break; } } }; private BroadcastReceiver mDownloadReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { return; } final long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0); if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, "Download complete with id: " + id); mHandler.sendMessage(mHandler.obtainMessage(CosuUtils.MSG_DOWNLOAD_COMPLETE, new Long(id))); } }; private BroadcastReceiver mInstallReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!CosuUtils.ACTION_INSTALL_COMPLETE.equals(intent.getAction())) { return; } int result = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); String packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME); if (CosuUtils.DEBUG) Log.d(CosuUtils.TAG, "PackageInstallerCallback: result=" + result + " packageName=" + packageName); switch (result) { case PackageInstaller.STATUS_PENDING_USER_ACTION: { // this should not happen in M, but will happen in L and L-MR1 startActivity((Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT)); } break; case PackageInstaller.STATUS_SUCCESS: { mHandler.sendMessage(mHandler.obtainMessage(CosuUtils.MSG_INSTALL_COMPLETE, packageName)); } break; default: { Log.e(CosuUtils.TAG, "Install failed."); finishWithFailure(); return; } } } }; }