DeviceOwner: Add a new sample

This sample demonstrates device owner feature of Android for Work.

Change-Id: I5cb35e2be8a115e8187d0d90180be5ecdb58c03e
diff --git a/admin/DeviceOwner/Application/.gitignore b/admin/DeviceOwner/Application/.gitignore
new file mode 100644
index 0000000..1bac3a5
--- /dev/null
+++ b/admin/DeviceOwner/Application/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 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.
+src/template/
+src/common/
+build.gradle
diff --git a/admin/DeviceOwner/Application/README-fragmentview.txt b/admin/DeviceOwner/Application/README-fragmentview.txt
new file mode 100644
index 0000000..b346a5f
--- /dev/null
+++ b/admin/DeviceOwner/Application/README-fragmentview.txt
@@ -0,0 +1,37 @@
+<!--
+        Copyright 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.
+-->
+
+Steps to implement FragmentView template:
+-in template-params.xml.ftl:
+    -add the following line to common imports
+        <common src="activities"/>
+
+-Add a Fragment to show behavior.  In your MainActivity.java class, it will reference a Fragment
+ called (yourProjectName)Fragment.java.  Create that file in your project, using the "main" source
+ folder instead of "common" or "templates".
+   For instance, if your package name is com.example.foo, create the file
+   src/main/java/com/example/foo/FooFragment.java
+
+
+-Within this fragment, make sure that the onCreate method has the line
+ "setHasOptionsMenu(true);", to enable the fragment to handle menu events.
+
+-In order to override menu events, override onOptionsItemSelected.
+
+-refer to sampleSamples/fragmentViewSample for a reference implementation of a
+project built on this template.
+
+
diff --git a/admin/DeviceOwner/Application/README-singleview.txt b/admin/DeviceOwner/Application/README-singleview.txt
new file mode 100644
index 0000000..57fa134
--- /dev/null
+++ b/admin/DeviceOwner/Application/README-singleview.txt
@@ -0,0 +1,47 @@
+<#--
+        Copyright 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.
+-->
+
+Steps to implement SingleView template:
+-in template-params.xml.ftl:
+    -add the following line to common imports
+        <common src="activities"/>
+
+    -add a string for the action button's text using the element name "sample_action".
+    This element should be a child of <strings>:
+        <strings>
+        ...
+        <sample_action>ButtonText</sample_action>
+        ...
+        </strings>
+
+
+
+-Add a Fragment to handle behavior.  In your MainActivity.java class, it will reference a Fragment
+ called (yourProjectName)Fragment.java.  Create that file in your project, using the "main" source
+ folder instead of "common" or "templates".
+   For instance, if your package name is com.example.foo, create the file
+   src/main/java/com/example/foo/FooFragment.java
+
+
+-Within this fragment, make sure that the onCreate method has the line
+ "setHasOptionsMenu(true);", to enable the fragment to handle menu events.
+
+-In order to override menu events, override onOptionsItemSelected.
+
+-refer to sampleSamples/singleViewSample for a reference implementation of a
+project built on this template.
+
+
diff --git a/admin/DeviceOwner/Application/proguard-project.txt b/admin/DeviceOwner/Application/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/admin/DeviceOwner/Application/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/admin/DeviceOwner/Application/src/main/AndroidManifest.xml b/admin/DeviceOwner/Application/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..fb61ac9
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 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.
+-->
+<manifest
+    package="com.example.android.deviceowner"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme">
+
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <receiver
+            android:name=".DeviceOwnerReceiver"
+            android:description="@string/app_name"
+            android:label="@string/app_name"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data
+                android:name="android.app.device_admin"
+                android:resource="@xml/device_owner_receiver"/>
+            <intent-filter>
+                <action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/>
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+
+</manifest>
diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerFragment.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerFragment.java
new file mode 100644
index 0000000..b5c6254
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerFragment.java
@@ -0,0 +1,334 @@
+/*
+ * 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.example.android.deviceowner;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.SimpleAdapter;
+import android.widget.Spinner;
+import android.widget.Switch;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Demonstrates the usage of the most common device management APIs for the device owner case.
+ * In addition to various features available for profile owners, device owners can perform extra
+ * actions, such as configuring global settings and enforcing a preferred Activity for a specific
+ * IntentFilter.
+ */
+public class DeviceOwnerFragment extends Fragment {
+
+    // Keys for SharedPreferences
+    private static final String PREFS_DEVICE_OWNER = "DeviceOwnerFragment";
+    private static final String PREF_LAUNCHER = "launcher";
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    // View references
+    private Switch mSwitchAutoTime;
+    private Switch mSwitchAutoTimeZone;
+    private Spinner mAvailableLaunchers;
+    private Button mButtonLauncher;
+
+    // Adapter for the spinner to show list of available launchers
+    private LauncherAdapter mAdapter;
+
+    /**
+     * Handles events on the Switches.
+     */
+    private Switch.OnCheckedChangeListener mOnCheckedChangeListener
+            = new Switch.OnCheckedChangeListener() {
+
+        @Override
+        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+            switch (buttonView.getId()) {
+                case R.id.switch_auto_time:
+                    setBooleanGlobalSetting(Settings.Global.AUTO_TIME, isChecked);
+                    retrieveCurrentSettings(getActivity());
+                    break;
+                case R.id.switch_auto_time_zone:
+                    setBooleanGlobalSetting(Settings.Global.AUTO_TIME_ZONE, isChecked);
+                    retrieveCurrentSettings(getActivity());
+                    break;
+            }
+        }
+
+    };
+
+    /**
+     * Handles click events on the Button.
+     */
+    private View.OnClickListener mOnClickListener
+            = new View.OnClickListener() {
+
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.set_preferred_launcher:
+                    if (loadPersistentPreferredLauncher(getActivity()) == null) {
+                        setPreferredLauncher();
+                    } else {
+                        clearPreferredLauncher();
+                    }
+                    retrieveCurrentSettings(getActivity());
+                    break;
+            }
+        }
+
+    };
+
+    /**
+     * @return A newly instantiated {@link DeviceOwnerFragment}.
+     */
+    public static DeviceOwnerFragment newInstance() {
+        return new DeviceOwnerFragment();
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.fragment_device_owner, container, false);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        // Retain references
+        mSwitchAutoTime = (Switch) view.findViewById(R.id.switch_auto_time);
+        mSwitchAutoTimeZone = (Switch) view.findViewById(R.id.switch_auto_time_zone);
+        mAvailableLaunchers = (Spinner) view.findViewById(R.id.available_launchers);
+        mButtonLauncher = (Button) view.findViewById(R.id.set_preferred_launcher);
+        // Bind event handlers
+        mSwitchAutoTime.setOnCheckedChangeListener(mOnCheckedChangeListener);
+        mSwitchAutoTimeZone.setOnCheckedChangeListener(mOnCheckedChangeListener);
+        mButtonLauncher.setOnClickListener(mOnClickListener);
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        mDevicePolicyManager =
+                (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
+    }
+
+    @Override
+    public void onDetach() {
+        mDevicePolicyManager = null;
+        super.onDetach();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        Activity activity = getActivity();
+        if (activity != null) {
+            retrieveCurrentSettings(activity);
+        }
+    }
+
+    /**
+     * Retrieves the current global settings and changes the UI accordingly.
+     *
+     * @param activity The activity
+     */
+    private void retrieveCurrentSettings(Activity activity) {
+        // Global settings
+        setCheckedSafely(mSwitchAutoTime,
+                getBooleanGlobalSetting(activity.getContentResolver(), Settings.Global.AUTO_TIME));
+        setCheckedSafely(mSwitchAutoTimeZone,
+                getBooleanGlobalSetting(activity.getContentResolver(),
+                        Settings.Global.AUTO_TIME_ZONE));
+
+        // Launcher
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_HOME);
+        List<ResolveInfo> list = activity.getPackageManager()
+                .queryIntentActivities(intent, /* default flags */ 0);
+        mAdapter = new LauncherAdapter(activity, list);
+        mAvailableLaunchers.setAdapter(mAdapter);
+        String packageName = loadPersistentPreferredLauncher(activity);
+        if (packageName == null) { // No preferred launcher is set
+            mAvailableLaunchers.setEnabled(true);
+            mButtonLauncher.setText(R.string.set_as_preferred);
+        } else {
+            int position = -1;
+            for (int i = 0; i < list.size(); ++i) {
+                if (list.get(i).activityInfo.packageName.equals(packageName)) {
+                    position = i;
+                    break;
+                }
+            }
+            if (position != -1) {
+                mAvailableLaunchers.setSelection(position);
+                mAvailableLaunchers.setEnabled(false);
+                mButtonLauncher.setText(R.string.clear_preferred);
+            }
+        }
+    }
+
+    /**
+     * Retrieves the current boolean value of the specified global setting.
+     *
+     * @param resolver The ContentResolver
+     * @param setting  The setting to be retrieved
+     * @return The current boolean value
+     */
+    private static boolean getBooleanGlobalSetting(ContentResolver resolver, String setting) {
+        return 0 != Settings.Global.getInt(resolver, setting, 0);
+    }
+
+    /**
+     * Sets the boolean value of the specified global setting.
+     *
+     * @param setting The setting to be set
+     * @param value   The value to be set
+     */
+    private void setBooleanGlobalSetting(String setting, boolean value) {
+        mDevicePolicyManager.setGlobalSetting(
+                // The ComponentName of the device owner
+                DeviceOwnerReceiver.getComponentName(getActivity()),
+                // The settings to be set
+                setting,
+                // The value we write here is a string representation for SQLite
+                value ? "1" : "0");
+    }
+
+    /**
+     * A utility method to set the checked state of the button without invoking its listener.
+     *
+     * @param button  The button
+     * @param checked The value to be set
+     */
+    private void setCheckedSafely(CompoundButton button, boolean checked) {
+        button.setOnCheckedChangeListener(null);
+        button.setChecked(checked);
+        button.setOnCheckedChangeListener(mOnCheckedChangeListener);
+    }
+
+    /**
+     * Loads the package name from SharedPreferences.
+     *
+     * @param activity The activity
+     * @return The package name of the launcher currently set as preferred, or null if there is no
+     * preferred launcher.
+     */
+    private static String loadPersistentPreferredLauncher(Activity activity) {
+        return activity.getSharedPreferences(PREFS_DEVICE_OWNER, Context.MODE_PRIVATE)
+                .getString(PREF_LAUNCHER, null);
+    }
+
+    /**
+     * Saves the package name into SharedPreferences.
+     *
+     * @param activity    The activity
+     * @param packageName The package name to be saved. Pass null to remove the preferred launcher.
+     */
+    private static void savePersistentPreferredLauncher(Activity activity, String packageName) {
+        SharedPreferences.Editor editor = activity.getSharedPreferences(PREFS_DEVICE_OWNER,
+                Context.MODE_PRIVATE).edit();
+        if (packageName == null) {
+            editor.remove(PREF_LAUNCHER);
+        } else {
+            editor.putString(PREF_LAUNCHER, packageName);
+        }
+        editor.apply();
+    }
+
+    /**
+     * Sets the selected launcher as preferred.
+     */
+    private void setPreferredLauncher() {
+        Activity activity = getActivity();
+        if (activity == null) {
+            return;
+        }
+        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
+        filter.addCategory(Intent.CATEGORY_HOME);
+        filter.addCategory(Intent.CATEGORY_DEFAULT);
+        ComponentName componentName = mAdapter.getComponentName(
+                mAvailableLaunchers.getSelectedItemPosition());
+        mDevicePolicyManager.addPersistentPreferredActivity(
+                DeviceOwnerReceiver.getComponentName(activity), filter, componentName);
+        savePersistentPreferredLauncher(activity, componentName.getPackageName());
+    }
+
+    /**
+     * Clears the launcher currently set as preferred.
+     */
+    private void clearPreferredLauncher() {
+        Activity activity = getActivity();
+        if (activity == null) {
+            return;
+        }
+        mDevicePolicyManager.clearPackagePersistentPreferredActivities(
+                DeviceOwnerReceiver.getComponentName(activity),
+                loadPersistentPreferredLauncher(activity));
+        savePersistentPreferredLauncher(activity, null);
+    }
+
+    /**
+     * Shows list of {@link ResolveInfo} in a {@link Spinner}.
+     */
+    private static class LauncherAdapter extends SimpleAdapter {
+
+        private static final String KEY_PACKAGE_NAME = "package_name";
+        private static final String KEY_ACTIVITY_NAME = "activity_name";
+
+        public LauncherAdapter(Context context, List<ResolveInfo> list) {
+            super(context, createData(list), android.R.layout.simple_list_item_1,
+                    new String[]{KEY_PACKAGE_NAME},
+                    new int[]{android.R.id.text1});
+        }
+
+        private static List<HashMap<String, String>> createData(List<ResolveInfo> list) {
+            List<HashMap<String, String>> data = new ArrayList<>();
+            for (ResolveInfo info : list) {
+                HashMap<String, String> map = new HashMap<>();
+                map.put(KEY_PACKAGE_NAME, info.activityInfo.packageName);
+                map.put(KEY_ACTIVITY_NAME, info.activityInfo.name);
+                data.add(map);
+            }
+            return data;
+        }
+
+        public ComponentName getComponentName(int position) {
+            @SuppressWarnings("unchecked")
+            HashMap<String, String> map = (HashMap<String, String>) getItem(position);
+            return new ComponentName(map.get(KEY_PACKAGE_NAME), map.get(KEY_ACTIVITY_NAME));
+        }
+
+    }
+
+}
diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerReceiver.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerReceiver.java
new file mode 100644
index 0000000..f5969fc
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/DeviceOwnerReceiver.java
@@ -0,0 +1,56 @@
+/*
+ * 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.example.android.deviceowner;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * Handles events related to device owner.
+ */
+public class DeviceOwnerReceiver extends DeviceAdminReceiver {
+
+    /**
+     * Called on the new profile when device owner provisioning has completed. Device owner
+     * provisioning is the process of setting up the device so that its main profile is managed by
+     * the mobile device management (MDM) application set up as the device owner.
+     */
+    @Override
+    public void onProfileProvisioningComplete(Context context, Intent intent) {
+        // Enable the profile
+        DevicePolicyManager manager =
+                (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        ComponentName componentName = getComponentName(context);
+        manager.setProfileName(componentName, context.getString(R.string.profile_name));
+        // Open the main screen
+        Intent launch = new Intent(context, MainActivity.class);
+        launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        context.startActivity(launch);
+    }
+
+    /**
+     * @return A newly instantiated {@link android.content.ComponentName} for this
+     * DeviceAdminReceiver.
+     */
+    public static ComponentName getComponentName(Context context) {
+        return new ComponentName(context.getApplicationContext(), DeviceOwnerReceiver.class);
+    }
+
+}
diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/InstructionFragment.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/InstructionFragment.java
new file mode 100644
index 0000000..2a889c3
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/InstructionFragment.java
@@ -0,0 +1,45 @@
+/*
+ * 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.example.android.deviceowner;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Shows instruction about this device owner.
+ */
+public class InstructionFragment extends Fragment {
+
+    /**
+     * @return A newly instantiated {@link InstructionFragment}.
+     */
+    public static InstructionFragment newInstance() {
+        return new InstructionFragment();
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.fragment_instruction, container, false);
+    }
+
+}
diff --git a/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/MainActivity.java b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/MainActivity.java
new file mode 100644
index 0000000..5a331ab
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/java/com/example/android/deviceowner/MainActivity.java
@@ -0,0 +1,55 @@
+/*
+ * 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.example.android.deviceowner;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+
+public class MainActivity extends Activity {
+
+    private static final String TAG = "MainActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main_real);
+        if (savedInstanceState == null) {
+            DevicePolicyManager manager =
+                    (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+            if (manager.isDeviceOwnerApp(getApplicationContext().getPackageName())) {
+                // This app is set up as the device owner. Show the main features.
+                Log.d(TAG, "The app is the device owner.");
+                showFragment(DeviceOwnerFragment.newInstance());
+            } else {
+                // This app is not set up as the device owner. Show instructions.
+                Log.d(TAG, "The app is not the device owner.");
+                showFragment(InstructionFragment.newInstance());
+            }
+        }
+    }
+
+    private void showFragment(Fragment fragment) {
+        getFragmentManager().beginTransaction()
+                .replace(R.id.container, fragment)
+                .commit();
+    }
+
+}
diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-hdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..282e540
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-mdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..4ecfdf6
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dfb6cab
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/admin/DeviceOwner/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/admin/DeviceOwner/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..650302e
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/admin/DeviceOwner/Application/src/main/res/layout/activity_main_real.xml b/admin/DeviceOwner/Application/src/main/res/layout/activity_main_real.xml
new file mode 100644
index 0000000..384e9f9
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/layout/activity_main_real.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<FrameLayout
+    android:id="@+id/container"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.example.android.deviceowner.MainActivity"
+    tools:ignore="MergeRootFrame"/>
diff --git a/admin/DeviceOwner/Application/src/main/res/layout/fragment_device_owner.xml b/admin/DeviceOwner/Application/src/main/res/layout/fragment_device_owner.xml
new file mode 100644
index 0000000..aeae219
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/layout/fragment_device_owner.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="com.example.android.deviceowner.DeviceOwnerFragment">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/margin_medium"
+            android:text="@string/label_global_settings"
+            android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+        <Switch
+            android:id="@+id/switch_auto_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/margin_medium"
+            android:paddingEnd="@dimen/margin_medium"
+            android:paddingStart="@dimen/margin_medium"
+            android:text="@string/label_auto_time"
+            android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+        <Switch
+            android:id="@+id/switch_auto_time_zone"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/margin_medium"
+            android:paddingEnd="@dimen/margin_medium"
+            android:paddingStart="@dimen/margin_medium"
+            android:text="@string/label_auto_time_zone"
+            android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+        <Space
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/margin_medium"/>
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="@dimen/margin_medium"
+            android:text="@string/label_launcher"
+            android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+        <Spinner
+            android:id="@+id/available_launchers"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/margin_medium"
+            android:layout_marginTop="@dimen/margin_medium"/>
+
+        <Button
+            android:id="@+id/set_preferred_launcher"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/margin_medium"
+            android:text="@string/set_as_preferred"/>
+
+    </LinearLayout>
+
+</ScrollView>
\ No newline at end of file
diff --git a/admin/DeviceOwner/Application/src/main/res/layout/fragment_instruction.xml b/admin/DeviceOwner/Application/src/main/res/layout/fragment_instruction.xml
new file mode 100644
index 0000000..9d09e39
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/layout/fragment_instruction.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context="com.example.android.deviceowner.InstructionFragment">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="@dimen/margin_medium"
+        android:text="@string/set_up_instruction"
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+</LinearLayout>
diff --git a/admin/DeviceOwner/Application/src/main/res/values/strings.xml b/admin/DeviceOwner/Application/src/main/res/values/strings.xml
new file mode 100644
index 0000000..af7d038
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/values/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<resources>
+
+    <string name="set_up_instruction">
+        The app is not set up as the device owner of this device. Use NfcProvisioning sample to set
+        up this app as the device owner of this device (This requires factory resetting the device).
+    </string>
+
+    <string name="profile_name">Sample Device Owner</string>
+
+    <string name="label_global_settings">Global settings</string>
+    <string name="label_auto_time">Automatic date &amp; time</string>
+    <string name="label_auto_time_zone">Automatic time zone</string>
+
+    <string name="label_launcher">Home Launcher</string>
+    <string name="set_as_preferred">Set as preferred</string>
+    <string name="clear_preferred">Clear preferred</string>
+
+</resources>
diff --git a/admin/DeviceOwner/Application/src/main/res/xml/device_owner_receiver.xml b/admin/DeviceOwner/Application/src/main/res/xml/device_owner_receiver.xml
new file mode 100644
index 0000000..20109f0
--- /dev/null
+++ b/admin/DeviceOwner/Application/src/main/res/xml/device_owner_receiver.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<device-admin>
+    <uses-policies>
+        <limit-password/>
+        <watch-login/>
+        <reset-password/>
+        <force-lock/>
+        <wipe-data/>
+        <expire-password/>
+        <encrypted-storage/>
+        <disable-camera/>
+    </uses-policies>
+</device-admin>
diff --git a/admin/DeviceOwner/build.gradle b/admin/DeviceOwner/build.gradle
new file mode 100644
index 0000000..2b8d1ef
--- /dev/null
+++ b/admin/DeviceOwner/build.gradle
@@ -0,0 +1,11 @@
+
+// BEGIN_EXCLUDE
+import com.example.android.samples.build.SampleGenPlugin
+apply plugin: SampleGenPlugin
+
+samplegen {
+  pathToBuild "../../../../build"
+  pathToSamplesCommon "../../common"
+}
+apply from: "../../../../build/build.gradle"
+// END_EXCLUDE
diff --git a/admin/DeviceOwner/buildSrc/build.gradle b/admin/DeviceOwner/buildSrc/build.gradle
new file mode 100644
index 0000000..8c294c2
--- /dev/null
+++ b/admin/DeviceOwner/buildSrc/build.gradle
@@ -0,0 +1,15 @@
+repositories {
+    mavenCentral()
+}
+dependencies {
+    compile 'org.freemarker:freemarker:2.3.20'
+}
+
+sourceSets {
+    main {
+        groovy {
+            srcDir new File(rootDir, "../../../../../build/buildSrc/src/main/groovy")
+        }
+    }
+}
+
diff --git a/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.jar b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.properties b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0973c31
--- /dev/null
+++ b/admin/DeviceOwner/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Jan 20 16:50:15 JST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/admin/DeviceOwner/gradlew b/admin/DeviceOwner/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/admin/DeviceOwner/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/admin/DeviceOwner/gradlew.bat b/admin/DeviceOwner/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/admin/DeviceOwner/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windowz variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+if "%@eval[2+2]" == "4" goto 4NT_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+goto execute

+

+:4NT_args

+@rem Get arguments from the 4NT Shell from JP Software

+set CMD_LINE_ARGS=%$

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/admin/DeviceOwner/screenshots/1-main.png b/admin/DeviceOwner/screenshots/1-main.png
new file mode 100644
index 0000000..db827d1
--- /dev/null
+++ b/admin/DeviceOwner/screenshots/1-main.png
Binary files differ
diff --git a/admin/DeviceOwner/screenshots/icon-web.png b/admin/DeviceOwner/screenshots/icon-web.png
new file mode 100755
index 0000000..ac670da
--- /dev/null
+++ b/admin/DeviceOwner/screenshots/icon-web.png
Binary files differ
diff --git a/admin/DeviceOwner/settings.gradle b/admin/DeviceOwner/settings.gradle
new file mode 100644
index 0000000..9464a35
--- /dev/null
+++ b/admin/DeviceOwner/settings.gradle
@@ -0,0 +1 @@
+include 'Application'
diff --git a/admin/DeviceOwner/template-params.xml b/admin/DeviceOwner/template-params.xml
new file mode 100644
index 0000000..27930d0
--- /dev/null
+++ b/admin/DeviceOwner/template-params.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 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.
+-->
+<sample>
+    <name>DeviceOwner</name>
+    <group>Admin</group>
+    <package>com.example.android.deviceowner</package>
+    <minSdk>21</minSdk>
+
+    <strings>
+        <intro>
+<![CDATA[
+This app demonstrates how to use device owner features. Use the NfcProvisioning sample to set up
+this app as the device owner of your test device (This requires wiping out the device and resseting
+it as an unprovisioned device). As a device owner, this app can configure global settings, and
+enforce use of a specific launcher.
+]]>
+        </intro>
+    </strings>
+
+    <template src="base"/>
+
+    <metadata>
+        <status>PUBLISHED</status>
+        <categories>Device Admin</categories>
+        <technologies>Android</technologies>
+        <languages>Java</languages>
+        <solutions>Mobile</solutions>
+        <level>ADVANCED</level>
+        <icon>screenshots/icon-web.png</icon>
+        <screenshots>
+            <img>screenshots/1-main.png</img>
+        </screenshots>
+        <api_refs>
+            <android>android.app.admin.DevicePolicyManager</android>
+            <android>android.provider.Settings</android>
+        </api_refs>
+
+        <description>
+<![CDATA[
+This sample demonstrates how to use some device owner features. As a device owner, you can configure
+global settings such as automatic time and timezone. You can mandate a specific launcher by
+preferred intent handler.
+]]>
+        </description>
+
+        <intro>
+<![CDATA[
+In order to set global settings, use [DevicePolicyManager#setGlobalSetting][1] and specify one of
+the [Settings.Global][2] keys available. Note that you need to specify its value as a String. As
+most of the keys accept boolean values, you will mostly use "1" for true and "0" for false.
+
+You can mandate a specific launcher by adding a persistent preferred activity for an IntentFilter
+with Intent.CATEGORY_HOME category. Call [DevicePolicyManager#addPersistentPreferredActivity][3] to
+register the activity. You can clear the registration with
+[clearPackagePersistentPreferredActivities][4].
+
+As a device owner, you can also use the features available for managed profile owner. See
+[BasicManagedProfile][5].
+
+[1]: http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String)
+[2]: http://developer.android.com/reference/android/provider/Settings.Global.html
+[3]: http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName)
+[4]: http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String)
+[5]: https://developer.android.com/samples/BasicManagedProfile/index.html
+]]>
+        </intro>
+    </metadata>
+</sample>