Fix 2527411: Extend sample DPM app to test setMaximumTimeToLock()

Change-Id: I1a0ff93a27d7d27b66acbacf953eb0984e85e4cf
diff --git a/samples/ApiDemos/res/layout/device_admin_sample.xml b/samples/ApiDemos/res/layout/device_admin_sample.xml
index cbd4dc9..2827c01 100644
--- a/samples/ApiDemos/res/layout/device_admin_sample.xml
+++ b/samples/ApiDemos/res/layout/device_admin_sample.xml
@@ -4,9 +4,9 @@
      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.
@@ -27,47 +27,47 @@
         android:paddingBottom="4dip"
         android:text="@string/sample_device_admin_summary"/>
 
-	<LinearLayout android:orientation="horizontal" android:gravity="center"
-	    android:layout_width="match_parent" android:layout_height="wrap_content">
+    <LinearLayout android:orientation="horizontal" android:gravity="center"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
 
-	    <Button android:id="@+id/enable"
-	        android:layout_width="wrap_content" android:layout_height="wrap_content" 
-	        android:text="@string/enable_admin">
-	        <requestFocus />
-	    </Button>
-	
-	    <Button android:id="@+id/disable"
-	        android:layout_width="wrap_content" android:layout_height="wrap_content" 
-	        android:text="@string/disable_admin">
-	    </Button>
-	    
+        <Button android:id="@+id/enable"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="@string/enable_admin">
+            <requestFocus />
+        </Button>
+
+        <Button android:id="@+id/disable"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="@string/disable_admin">
+        </Button>
+
     </LinearLayout>
 
     <LinearLayout android:orientation="horizontal" android:gravity="center"
         android:layout_width="match_parent" android:layout_height="wrap_content">
 
-	    <Spinner android:id="@+id/password_quality"
-	        android:layout_width="wrap_content"
-	        android:layout_height="wrap_content"
-	        android:drawSelectorOnTop="true"
-	        android:prompt="@string/password_quality">
-	    </Spinner>
-    
+        <Spinner android:id="@+id/password_quality"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawSelectorOnTop="true"
+            android:prompt="@string/password_quality">
+        </Spinner>
+
         <EditText android:id="@+id/password_length"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:hint="@string/password_length_hint"
             android:inputType="number">
         </EditText>
-            
+
     </LinearLayout>
 
     <Button android:id="@+id/set_password"
-        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
         android_layout_gravity="east|center_vertical"
         android:text="@string/set_password">
     </Button>
-        
+
     <LinearLayout android:orientation="horizontal" android:gravity="center"
         android:layout_width="match_parent" android:layout_height="wrap_content">
 
@@ -78,15 +78,15 @@
             android:hint="@string/password_hint"
             android:freezesText="true">
         </EditText>
-            
+
         <Button android:id="@+id/reset_password"
-            android:layout_width="wrap_content" android:layout_height="wrap_content" 
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
             android:layout_weight="0"
             android:text="@string/reset_password">
         </Button>
-        
+
     </LinearLayout>
-        
+
     <LinearLayout android:orientation="horizontal" android:gravity="center"
         android:layout_width="match_parent" android:layout_height="wrap_content">
 
@@ -96,25 +96,45 @@
             android:hint="@string/max_failed_pw_hint"
             android:inputType="number">
         </EditText>
-            
+
     </LinearLayout>
-        
+
     <LinearLayout android:orientation="horizontal" android:gravity="center"
         android:layout_width="match_parent" android:layout_height="wrap_content">
 
         <Button android:id="@+id/force_lock"
-            android:layout_width="wrap_content" android:layout_height="wrap_content" 
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
             android:layout_weight="0"
             android:text="@string/force_lock">
         </Button>
-        
+
         <Button android:id="@+id/wipe_data"
-            android:layout_width="wrap_content" android:layout_height="wrap_content" 
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
             android:layout_weight="0"
             android:text="@string/wipe_data">
         </Button>
-        
+
     </LinearLayout>
-    
+
+    <LinearLayout android:orientation="horizontal" android:gravity="center"
+        android:layout_width="match_parent" android:layout_height="wrap_content">
+
+        <EditText android:id="@+id/timeout"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:hint="@string/timeout_hint"
+            android:inputType="number"
+            android:freezesText="true">
+        </EditText>
+
+        <Button android:id="@+id/set_timeout"
+            android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:text="@string/set_timeout_label">
+        </Button>
+
+    </LinearLayout>
+
 </LinearLayout>
 
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 799d67f..802fc80 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -43,7 +43,7 @@
     <string name="activity_setwallpaper">App/Activity/SetWallpaper</string>
     <string name="set_wallpaper">Set Wallpaper</string>
     <string name="randomize">Randomize</string>
-    
+
     <string name="activity_translucent">App/Activity/Translucent</string>
     <string name="translucent_background">Example of how you can make an
             activity have a translucent background, compositing over
@@ -146,7 +146,7 @@
     <string name="startfail_service">Start failed delivery</string>
     <string name="service_created">Service created.</string>
     <string name="service_destroyed">Service destroyed.</string>
-    
+
     <string name="foreground_service_started">Service is in the foreground</string>
     <string name="foreground_service_label">Sample Foreground Service</string>
 
@@ -235,7 +235,7 @@
     <string name="activity_external_storage">Content/Storage/External Storage</string>
     <string name="create">Create</string>
     <string name="delete">Delete</string>
-    
+
     <string name="activity_styled_text">Content/Resources/<i>Styled</i> <b>Text</b></string>
     <string name="styled_text_rsrc">Initialized from a resource:</string>
     <string name="styled_text">Plain, <b>bold</b>, <i>italic</i>, <b><i>bold-italic</i></b></string>
@@ -249,11 +249,11 @@
     <!-- ============================== -->
     <!--  app/intents examples strings     -->
     <!-- ============================== -->
-    
+
     <string name="activity_intents">App/Intents</string>
     <string name="intents">Example of launching various Intents.</string>
     <string name="get_music">Get Music</string>
-        
+
     <!-- =================================== -->
     <!--  app/notification examples strings  -->
     <!-- =================================== -->
@@ -440,18 +440,18 @@
 
     <string name="msg_launcher_shortcuts">This activity creates shortcuts for the launcher (home screen), and receives intents from those shortcuts.  To try it, return to the launcher and long-press to create a shortcut.</string>
     <string name="label_intent">Intent:</string>
-    
+
     <!-- ============================== -->
     <!--  app/device policies examples strings     -->
     <!-- ============================== -->
-    
+
     <string name="activity_sample_device_admin">App/Device Admin</string>
     <string name="sample_device_admin">Sample Device Admin</string>
     <string name="sample_device_admin_description">Sample code for writing
         a DeviceAdmin class.  This implementation provides a UI (in ApiDemos)
         for you to directly control what the DeviceAdmin does with the
         system.</string>
-        
+
     <string name="sample_device_admin_summary">Demonstration of a DeviceAdmin
         class for administering the user\'s device.</string>
     <string name="enable_admin">Enable Admin</string>
@@ -464,7 +464,9 @@
     <string name="max_failed_pw_hint">Password Attempts Wipe Data</string>
     <string name="force_lock">Force Lock</string>
     <string name="wipe_data">Wipe Data</string>
-    
+    <string name="timeout_hint">Max screen timeout</string>
+    <string name="set_timeout_label">Set Timeout</string>
+
     <!-- ============================== -->
     <!--  app/voice recognition examples strings  -->
     <!-- ============================== -->
@@ -472,7 +474,7 @@
     <string name="voice_recognition_prompt">This activity demonstrates the voice recognition APIs.</string>
     <string name="speak_button">Speak!</string>
     <string name="voice_recognition_results">Results:</string>
-    
+
     <!-- ============================ -->
     <!--  graphics examples strings  -->
     <!-- ============================ -->
@@ -480,7 +482,7 @@
     <string name="hide_me">Hide Me!</string>
 
     <string name="density_title">Density: Unknown Screen</string>
-    
+
     <!-- ============================ -->
     <!--  media examples strings  -->
     <!-- ============================ -->
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
index d29f123..f7ee2d7 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
@@ -51,15 +51,15 @@
     static SharedPreferences getSamplePreferences(Context context) {
         return context.getSharedPreferences(DeviceAdminReceiver.class.getName(), 0);
     }
-    
+
     static String PREF_PASSWORD_QUALITY = "password_quality";
     static String PREF_PASSWORD_LENGTH = "password_length";
     static String PREF_MAX_FAILED_PW = "max_failed_pw";
-    
+
     void showToast(Context context, CharSequence msg) {
         Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
     }
-    
+
     @Override
     public void onEnabled(Context context, Intent intent) {
         showToast(context, "Sample Device Admin: enabled");
@@ -94,20 +94,20 @@
      * <p>UI control for the sample device admin.  This provides an interface
      * to enable, disable, and perform other operations with it to see
      * their effect.</p>
-     * 
+     *
      * <p>Note that this is implemented as an inner class only keep the sample
      * all together; typically this code would appear in some separate class.
      */
     public static class Controller extends Activity {
         static final int RESULT_ENABLE = 1;
-        
+
         DevicePolicyManager mDPM;
         ActivityManager mAM;
         ComponentName mDeviceAdminSample;
-        
+
         Button mEnableButton;
         Button mDisableButton;
-        
+
         // Password quality spinner choices
         // This list must match the list found in samples/ApiDemos/res/values/arrays.xml
         final static int mPasswordQualityValues[] = new int[] {
@@ -120,15 +120,19 @@
         Spinner mPasswordQuality;
         EditText mPasswordLength;
         Button mSetPasswordButton;
-        
+
         EditText mPassword;
         Button mResetPasswordButton;
-        
+
         EditText mMaxFailedPw;
-        
+
         Button mForceLockButton;
         Button mWipeDataButton;
-        
+
+        private Button mTimeoutButton;
+
+        private EditText mTimeout;
+
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
@@ -136,7 +140,7 @@
             mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
             mAM = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
             mDeviceAdminSample = new ComponentName(Controller.this, DeviceAdminSample.class);
-            
+
             setContentView(R.layout.device_admin_sample);
 
             // Watch for button clicks.
@@ -144,7 +148,7 @@
             mEnableButton.setOnClickListener(mEnableListener);
             mDisableButton = (Button)findViewById(R.id.disable);
             mDisableButton.setOnClickListener(mDisableListener);
-            
+
             mPasswordQuality = (Spinner)findViewById(R.id.password_quality);
             ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                     this, R.array.password_qualities, android.R.layout.simple_spinner_item);
@@ -176,11 +180,11 @@
             });
             mSetPasswordButton = (Button)findViewById(R.id.set_password);
             mSetPasswordButton.setOnClickListener(mSetPasswordListener);
-            
+
             mPassword = (EditText)findViewById(R.id.password);
             mResetPasswordButton = (Button)findViewById(R.id.reset_password);
             mResetPasswordButton.setOnClickListener(mResetPasswordListener);
-            
+
             mMaxFailedPw = (EditText)findViewById(R.id.max_failed_pw);
             mMaxFailedPw.addTextChangedListener(new TextWatcher() {
                 public void afterTextChanged(Editable s) {
@@ -199,11 +203,15 @@
                     }
                 }
             });
-            
+
             mForceLockButton = (Button)findViewById(R.id.force_lock);
             mForceLockButton.setOnClickListener(mForceLockListener);
             mWipeDataButton = (Button)findViewById(R.id.wipe_data);
             mWipeDataButton.setOnClickListener(mWipeDataListener);
+
+            mTimeout = (EditText) findViewById(R.id.timeout);
+            mTimeoutButton = (Button) findViewById(R.id.set_timeout);
+            mTimeoutButton.setOnClickListener(mSetTimeoutListener);
         }
 
         void updateButtonStates() {
@@ -230,14 +238,14 @@
                 mWipeDataButton.setEnabled(false);
             }
         }
-        
+
         void updateControls() {
             SharedPreferences prefs = getSamplePreferences(this);
             final int pwQuality = prefs.getInt(PREF_PASSWORD_QUALITY,
                     DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
             final int pwLength = prefs.getInt(PREF_PASSWORD_LENGTH, 0);
             final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
-            
+
             for (int i=0; i<mPasswordQualityValues.length; i++) {
                 if (mPasswordQualityValues[i] == pwQuality) {
                     mPasswordQuality.setSelection(i);
@@ -246,14 +254,14 @@
             mPasswordLength.setText(Integer.toString(pwLength));
             mMaxFailedPw.setText(Integer.toString(maxFailedPw));
         }
-        
+
         void updatePolicies() {
             SharedPreferences prefs = getSamplePreferences(this);
             final int pwQuality = prefs.getInt(PREF_PASSWORD_QUALITY,
                     DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
             final int pwLength = prefs.getInt(PREF_PASSWORD_LENGTH, 0);
             final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
-            
+
             boolean active = mDPM.isAdminActive(mDeviceAdminSample);
             if (active) {
                 mDPM.setPasswordQuality(mDeviceAdminSample, pwQuality);
@@ -261,25 +269,25 @@
                 mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, maxFailedPw);
             }
         }
-        
+
         void setPasswordQuality(int quality) {
             SharedPreferences prefs = getSamplePreferences(this);
             prefs.edit().putInt(PREF_PASSWORD_QUALITY, quality).commit();
             updatePolicies();
         }
-        
+
         void setPasswordLength(int length) {
             SharedPreferences prefs = getSamplePreferences(this);
             prefs.edit().putInt(PREF_PASSWORD_LENGTH, length).commit();
             updatePolicies();
         }
-        
+
         void setMaxFailedPw(int length) {
             SharedPreferences prefs = getSamplePreferences(this);
             prefs.edit().putInt(PREF_MAX_FAILED_PW, length).commit();
             updatePolicies();
         }
-        
+
         @Override
         protected void onResume() {
             super.onResume();
@@ -297,7 +305,7 @@
                     }
                     return;
             }
-            
+
             super.onActivityResult(requestCode, resultCode, data);
         }
 
@@ -397,5 +405,24 @@
                 builder.show();
             }
         };
+
+        private OnClickListener mSetTimeoutListener = new OnClickListener() {
+
+            public void onClick(View v) {
+                if (mAM.isUserAMonkey()) {
+                    // Don't trust monkeys to do the right thing!
+                    AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
+                    builder.setMessage("You can't lock my screen because you are a monkey!");
+                    builder.setPositiveButton("I admit defeat", null);
+                    builder.show();
+                    return;
+                }
+                boolean active = mDPM.isAdminActive(mDeviceAdminSample);
+                if (active) {
+                    long timeMs = 1000L*Long.parseLong(mTimeout.getText().toString());
+                    mDPM.setMaximumTimeToLock(mDeviceAdminSample, timeMs);
+                }
+            }
+        };
     }
 }