diff --git a/docs/html/images/training/enterprise/pinning_vs_locktaskmode.png b/docs/html/images/training/enterprise/pinning_vs_locktaskmode.png new file mode 100644 index 0000000000000..8fa470b659dac Binary files /dev/null and b/docs/html/images/training/enterprise/pinning_vs_locktaskmode.png differ diff --git a/docs/html/images/training/enterprise/pinning_vs_locktaskmode_2x.png b/docs/html/images/training/enterprise/pinning_vs_locktaskmode_2x.png new file mode 100644 index 0000000000000..d7690f48307f1 Binary files /dev/null and b/docs/html/images/training/enterprise/pinning_vs_locktaskmode_2x.png differ diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js index cd2d771dd9e82..fd76d19d09537 100644 --- a/docs/html/jd_collections.js +++ b/docs/html/jd_collections.js @@ -1661,10 +1661,11 @@ var RESOURCE_COLLECTIONS = { "resources": [ "training/enterprise/app-compatibility.html", "training/enterprise/app-restrictions.html", + "training/enterprise/cosu.html", "https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX", "samples/AppRestrictionSchema/index.html", - "samples/AppRestrictionEnforcer/index.html", - "https://www.youtube.com/watch?v=dH41OutAMNM" + "https://www.youtube.com/watch?v=dH41OutAMNM", + "samples/AppRestrictionEnforcer/index.html" ] }, "training/work/admin": { diff --git a/docs/html/training/enterprise/cosu.jd b/docs/html/training/enterprise/cosu.jd new file mode 100644 index 0000000000000..1d6388b459637 --- /dev/null +++ b/docs/html/training/enterprise/cosu.jd @@ -0,0 +1,503 @@ +page.title=Configuring Corporate-Owned, Single-Use Devices +page.metaDescription=Learn how to develop single-use solutions for Android devices. + +@jd:body + +
+
+ +

This lesson teaches you to

+
    +
  1. How to use LockTask mode
  2. +
  3. Build COSU solutions
  4. +
  5. Create your own DPC app
  6. +
+ + +

You should also read

+ + +
+
+ +

+As an IT administrator, you can configure Android 6.0 Marshmallow and later +devices as corporate-owned, single-use (COSU) devices. These are Android +devices used for a single purpose, such as digital signage, ticket printing, +point of sale, or inventory management. To use Android devices as COSU devices, +you need to develop Android apps that your customers can manage. +

+ +

+Your customers can configure COSU devices: +

+ + +

+App pinning vs. lock task mode +

+ +

Android 5.0 Lollipop introduced two new ways to configure Android devices +for a single purpose: +

+ + + +

+This graphic compares the features of app pinning and lock task mode: +

+ + + +

+ Figure 1. Comparing the features of app pinning in Lollipop + vs. Lock task mode in Marshmallow and later +

+ +

+In Lollipop, you can pin a single application to cover the full screen, but +only apps whitelisted by the device policy controller (DPC) can be locked. +

+ +

+ How to use LockTask mode +

+ +

+ To use LockTask mode, and the APIs that manage COSU devices, there must be + a device owner application installed on the device. Device owners are a + type of device policy controller (DPC) that manages the whole device. For + more information about DPCs, see the + EMM Developer’s Overview. +

+ +

+If you’re creating a new COSU app, we recommend you develop it for +Marshmallow or later, which includes the following COSU features: +

+ + + +

+ Note: If you develop COSU features targeted for + Marshmallow devices, your app can still be compatible with prior + versions of Android. +

+ +

+Additional COSU management features launched with Marshmallow make it easier to +develop and deploy Android devices as a single-use device. If you want to +enforce server-side app restrictions or server-side profile policy controls, +you need to use an EMM or make your application a DPC. Follow the instructions +below as you create your application. +

+ +

+ Build COSU solutions +

+ +

+ There are two different ways to manage COSU devices: +

+ + + +

+Solutions managed by a third-party EMM +

+ +

+In this section, you’ll need to do a small amount of development to +have your device work with a third-party EMM. +

+ +

+Using startLockTask() +

+ +

+If you need to add COSU functionality to an existing app, make sure that +the customer’s EMM supports {@link android.R.attr#lockTaskMode}. +

+ + + +

+Starting from Marshmallow, if your app is whitelisted by an EMM using {@link +android.app.admin.DevicePolicyManager#setLockTaskPackages setLockTaskPackages}, +your activities can automatically start lock task mode when the app is +launched. +

+ +

+Set the lockTaskMode attribute +

+ +

+ The {@link android.R.attr#lockTaskMode} attribute allows you to define + your app’s lock task mode behavior in the AndroidManifest.xml file: +

+ + + +

To have your activity automatically enter {@link android.R.attr#lockTaskMode}, +change the value of this attribute to if_whitelisted. +Doing so causes your app to behave in this manner: +

+ + + +

+Example XML as follows: +

+ +
<activity android:name=".MainActivity" android:lockTaskMode="if_whitelisted">
+ +

+Given either of these options, you still need to create a mechanism for +calling {@link android.app.Activity#stopLockTask()} so that users can +exit {@link android.R.attr#lockTaskMode}. +

+ +

+ Advanced setup—Create your own DPC app +

+ +

+To manage applications in COSU, you need a DPC running as device +owner to set several policies on the device. +

+ +

+Note: This setup is advanced, and requires +a thorough understanding of the EMM concepts described in the +EMM developer overview. +For more information about building a DPC, see +Provision Customer Devices. +

+ +

+To create a DPC app that can manage COSU device configuration, +the DPC needs to: +

+ +
    +
  1. +Provision the device into device owner mode. We recommend that +you support provisioning with near field communication (NFC) bump. +For more information, see +Device Owner Provisioning via NFC. +
  2. + +
  3. +Use the following APIs: + +
  4. +
+ +

+Here’s an example of how to implement an activity that starts lock task mode +and implements the relevant COSU device management APIs: +

+ +
+public class CosuActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mAdminComponentName = DeviceAdminReceiver.getComponentName(this);
+        mDevicePolicyManager = (DevicePolicyManager) getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        mPackageManager = getPackageManager();
+        setDefaultCosuPolicies(true);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        // start lock task mode if it's not already active
+        ActivityManager am = (ActivityManager) getSystemService(
+            Context.ACTIVITY_SERVICE);
+        // ActivityManager.getLockTaskModeState api is not available in pre-M.
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+            if (!am.isInLockTaskMode()) {
+                startLockTask();
+            }
+        } else {
+            if (am.getLockTaskModeState() == 
+                ActivityManager.LOCK_TASK_MODE_NONE) {
+                startLockTask();
+            }
+        }
+    }
+
+    private void setDefaultCosuPolicies(boolean active) {
+        // set user restrictions
+        setUserRestriction(DISALLOW_SAFE_BOOT, active);
+        setUserRestriction(DISALLOW_FACTORY_RESET, active);
+        setUserRestriction(DISALLOW_ADD_USER, active);
+        setUserRestriction(DISALLOW_MOUNT_PHYSICAL_MEDIA, active);
+        setUserRestriction(DISALLOW_ADJUST_VOLUME, active);
+
+        // disable keyguard and status bar
+        mDevicePolicyManager.setKeyguardDisabled(mAdminComponentName, active);
+        mDevicePolicyManager.setStatusBarDisabled(mAdminComponentName, active);
+
+        // enable STAY_ON_WHILE_PLUGGED_IN
+        enableStayOnWhilePluggedIn(active);
+
+        // set System Update policy
+
+        if (active){
+        	mDevicePolicyManager.setSystemUpdatePolicy(mAdminComponentName, 
+                SystemUpdatePolicy.createWindowedInstallPolicy(60,120));
+        }
+        else
+        
+
+        // set this Activity as a lock task package
+
+        mDevicePolicyManager.setLockTaskPackages(mAdminComponentName,
+    	    active ? new String[]{getPackageName()} : new String[]{});
+
+        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MAIN);
+        intentFilter.addCategory(Intent.CATEGORY_HOME);
+        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
+
+        if (active) {
+            // set Cosu activity as home intent receiver so that it is started
+            // on reboot
+            mDevicePolicyManager.addPersistentPreferredActivity(
+                mAdminComponentName, intentFilter, new ComponentName(
+                getPackageName(), CosuModeActivity.class.getName()))
+        } else {
+            mDevicePolicyManager.clearPackagePersistentPreferredActivities(
+                mAdminComponentName, getPackageName());
+        }
+    }
+
+    private void setUserRestriction(String restriction, boolean disallow) {
+        if (disallow) {
+            mDevicePolicyManager.addUserRestriction(mAdminComponentName, 
+                restriction);
+        } else {
+            mDevicePolicyManager.clearUserRestriction(mAdminComponentName,
+                restriction);
+        }
+    }
+
+    private void enableStayOnWhilePluggedIn(boolean enabled) {
+    	if (enabled) {
+    		mDevicePolicyManager.setGlobalSetting(
+    			mAdminComponentName, 
+                        Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+    			BatteryManager.BATTERY_PLUGGED_AC 
+    			| BatteryManager.BATTERY_PLUGGED_USB 
+    			| BatteryManager.BATTERY_PLUGGED_WIRELESS);
+    	} else {
+    		mDevicePolicyManager.setGlobalSetting(
+    			mAdminComponentName, 
+                        Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
+    	}
+
+    }
+
+    // TODO: Implement the rest of the Activity
+}
+
+ + +

+ Develop a test plan for COSU +

+ +

+ If you’re planning to support a third-party EMM, develop an end-to-end + testing plan utilizing the EMM’s app. We also provide testing resources, + which you can use to create your own Test Device Policy Client (Test DPC): +

+ + diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index f49ee153df636..756125405a033 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -1204,6 +1204,10 @@ Building a Device Policy Controller +
  • + Configuring Corporate-Owned, Single-Use Devices + +
  • diff --git a/docs/image_sources/training/enterprise/pinning_vs_locktaskmode.txt b/docs/image_sources/training/enterprise/pinning_vs_locktaskmode.txt new file mode 100644 index 0000000000000..0c1ef376d11d9 --- /dev/null +++ b/docs/image_sources/training/enterprise/pinning_vs_locktaskmode.txt @@ -0,0 +1,5 @@ +The source file for pinning_vs_locktaskmode.png is a +Google Doc owned by Matt Werner, mattwerner@google.com. +You can access the diagram in this doc: + +https://docs.google.com/document/d/1boC0uWSPxEDNGt6iCC6N3QxrvP1siwoZLXdD379Gmzs/edit \ No newline at end of file