Add password expiration test to DeviceAdminSample.
Change-Id: Ib5b398dc068227529d83be2b55c33225f9bbce80
This commit is contained in:
@@ -140,6 +140,24 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout android:orientation="horizontal" android:gravity="center"
|
||||||
|
android:layout_width="match_parent" android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<EditText android:id="@+id/password_expiration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/password_expiration_hint"
|
||||||
|
android:inputType="number">
|
||||||
|
</EditText>
|
||||||
|
|
||||||
|
<Button android:id="@+id/update_expiration_button"
|
||||||
|
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||||
|
android_layout_gravity="east|center_vertical"
|
||||||
|
android:text="@string/update_expiration_label">
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:orientation="horizontal" android:gravity="center"
|
<LinearLayout android:orientation="horizontal" android:gravity="center"
|
||||||
android:layout_width="match_parent" android:layout_height="wrap_content">
|
android:layout_width="match_parent" android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
orientation modes. Often you want to set the desired mode in your manifest
|
orientation modes. Often you want to set the desired mode in your manifest
|
||||||
instead of programmatically.</string>
|
instead of programmatically.</string>
|
||||||
<string name="screen_orientation">Screen Orientation</string>
|
<string name="screen_orientation">Screen Orientation</string>
|
||||||
|
|
||||||
<string name="activity_translucent">App/Activity/Translucent</string>
|
<string name="activity_translucent">App/Activity/Translucent</string>
|
||||||
<string name="translucent_background">Example of how you can make an
|
<string name="translucent_background">Example of how you can make an
|
||||||
activity have a translucent background, compositing over
|
activity have a translucent background, compositing over
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
can resize to adjust for the IME.</string>
|
can resize to adjust for the IME.</string>
|
||||||
<string name="soft_input_modes_initial_text">Text editor.\n\nTap to show the IME,
|
<string name="soft_input_modes_initial_text">Text editor.\n\nTap to show the IME,
|
||||||
which will cause this window to resize as requested.</string>
|
which will cause this window to resize as requested.</string>
|
||||||
|
|
||||||
<string name="activity_persistent">App/Activity/Persistent State</string>
|
<string name="activity_persistent">App/Activity/Persistent State</string>
|
||||||
<string name="persistent_msg">Demonstration of persistent activity state with getPreferences(0).edit() and getPreferences(0).</string>
|
<string name="persistent_msg">Demonstration of persistent activity state with getPreferences(0).edit() and getPreferences(0).</string>
|
||||||
|
|
||||||
@@ -540,6 +540,8 @@
|
|||||||
<string name="password_minimum_numeric_hint">Minimum Numeric</string>
|
<string name="password_minimum_numeric_hint">Minimum Numeric</string>
|
||||||
<string name="password_minimum_nonletter_hint">Minimum Non-Letter</string>
|
<string name="password_minimum_nonletter_hint">Minimum Non-Letter</string>
|
||||||
<string name="password_history_length_hint">Password History Length</string>
|
<string name="password_history_length_hint">Password History Length</string>
|
||||||
|
<string name="password_expiration_hint">Password Expiration Timeout (minutes) </string>
|
||||||
|
<string name="update_expiration_label">Update</string>
|
||||||
<string name="set_password">Set Password</string>
|
<string name="set_password">Set Password</string>
|
||||||
<string name="password_hint">Password</string>
|
<string name="password_hint">Password</string>
|
||||||
<string name="reset_password">Reset Password</string>
|
<string name="reset_password">Reset Password</string>
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
<force-lock />
|
<force-lock />
|
||||||
<wipe-data />
|
<wipe-data />
|
||||||
<set-global-proxy />
|
<set-global-proxy />
|
||||||
|
<expire-password />
|
||||||
</uses-policies>
|
</uses-policies>
|
||||||
</device-admin>
|
</device-admin>
|
||||||
<!-- END_INCLUDE(meta_data) -->
|
<!-- END_INCLUDE(meta_data) -->
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.example.android.apis.app;
|
|||||||
|
|
||||||
import com.example.android.apis.R;
|
import com.example.android.apis.R;
|
||||||
|
|
||||||
|
import android.R.menu;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
@@ -44,7 +45,9 @@ import android.widget.AdapterView.OnItemSelectedListener;
|
|||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,6 +56,11 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class DeviceAdminSample extends DeviceAdminReceiver {
|
public class DeviceAdminSample extends DeviceAdminReceiver {
|
||||||
|
|
||||||
|
private static final String TAG = "DeviceAdminSample";
|
||||||
|
private static final long MS_PER_DAY = 86400 * 1000;
|
||||||
|
private static final long MS_PER_HOUR = 3600 * 1000;
|
||||||
|
private static final long MS_PER_MINUTE = 60 * 1000;
|
||||||
|
|
||||||
static SharedPreferences getSamplePreferences(Context context) {
|
static SharedPreferences getSamplePreferences(Context context) {
|
||||||
return context.getSharedPreferences(DeviceAdminReceiver.class.getName(), 0);
|
return context.getSharedPreferences(DeviceAdminReceiver.class.getName(), 0);
|
||||||
}
|
}
|
||||||
@@ -66,15 +74,16 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
static String PREF_PASSWORD_MINIMUM_SYMBOLS = "password_minimum_symbols";
|
static String PREF_PASSWORD_MINIMUM_SYMBOLS = "password_minimum_symbols";
|
||||||
static String PREF_PASSWORD_MINIMUM_NONLETTER = "password_minimum_nonletter";
|
static String PREF_PASSWORD_MINIMUM_NONLETTER = "password_minimum_nonletter";
|
||||||
static String PREF_PASSWORD_HISTORY_LENGTH = "password_history_length";
|
static String PREF_PASSWORD_HISTORY_LENGTH = "password_history_length";
|
||||||
|
static String PREF_PASSWORD_EXPIRATION_TIMEOUT = "password_expiration_timeout";
|
||||||
static String PREF_MAX_FAILED_PW = "max_failed_pw";
|
static String PREF_MAX_FAILED_PW = "max_failed_pw";
|
||||||
|
|
||||||
void showToast(Context context, CharSequence msg) {
|
void showToast(Context context, CharSequence msg) {
|
||||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, "Sample Device Admin: " + msg, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnabled(Context context, Intent intent) {
|
public void onEnabled(Context context, Intent intent) {
|
||||||
showToast(context, "Sample Device Admin: enabled");
|
showToast(context, "enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,22 +93,43 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisabled(Context context, Intent intent) {
|
public void onDisabled(Context context, Intent intent) {
|
||||||
showToast(context, "Sample Device Admin: disabled");
|
showToast(context, "disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPasswordChanged(Context context, Intent intent) {
|
public void onPasswordChanged(Context context, Intent intent) {
|
||||||
showToast(context, "Sample Device Admin: pw changed");
|
showToast(context, "pw changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPasswordFailed(Context context, Intent intent) {
|
public void onPasswordFailed(Context context, Intent intent) {
|
||||||
showToast(context, "Sample Device Admin: pw failed");
|
showToast(context, "pw failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPasswordSucceeded(Context context, Intent intent) {
|
public void onPasswordSucceeded(Context context, Intent intent) {
|
||||||
showToast(context, "Sample Device Admin: pw succeeded");
|
showToast(context, "pw succeeded");
|
||||||
|
}
|
||||||
|
|
||||||
|
static String countdownString(long time) {
|
||||||
|
long days = time / MS_PER_DAY;
|
||||||
|
long hours = (time / MS_PER_HOUR) % 24;
|
||||||
|
long minutes = (time / MS_PER_MINUTE) % 60;
|
||||||
|
return days + "d" + hours + "h" + minutes + "m";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPasswordExpiring(Context context, Intent intent) {
|
||||||
|
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
|
||||||
|
Context.DEVICE_POLICY_SERVICE);
|
||||||
|
long expr = dpm.getPasswordExpiration(new ComponentName(context, DeviceAdminSample.class));
|
||||||
|
long delta = expr - System.currentTimeMillis();
|
||||||
|
boolean expired = delta < 0L;
|
||||||
|
String msg = expired ? "Password expired " : "Password will expire "
|
||||||
|
+ countdownString(Math.abs(delta))
|
||||||
|
+ (expired ? " ago" : " from now");
|
||||||
|
showToast(context, msg);
|
||||||
|
Log.v(TAG, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,6 +142,7 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
*/
|
*/
|
||||||
public static class Controller extends Activity {
|
public static class Controller extends Activity {
|
||||||
static final int RESULT_ENABLE = 1;
|
static final int RESULT_ENABLE = 1;
|
||||||
|
private static final long MS_PER_MINUTE = 60*1000;
|
||||||
|
|
||||||
DevicePolicyManager mDPM;
|
DevicePolicyManager mDPM;
|
||||||
ActivityManager mAM;
|
ActivityManager mAM;
|
||||||
@@ -130,6 +161,7 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
|
DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
|
||||||
DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
|
DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
|
||||||
};
|
};
|
||||||
|
|
||||||
Spinner mPasswordQuality;
|
Spinner mPasswordQuality;
|
||||||
EditText mPasswordLength;
|
EditText mPasswordLength;
|
||||||
EditText mPasswordMinimumLetters;
|
EditText mPasswordMinimumLetters;
|
||||||
@@ -139,6 +171,7 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
EditText mPasswordMinimumSymbols;
|
EditText mPasswordMinimumSymbols;
|
||||||
EditText mPasswordMinimumNonLetter;
|
EditText mPasswordMinimumNonLetter;
|
||||||
EditText mPasswordHistoryLength;
|
EditText mPasswordHistoryLength;
|
||||||
|
EditText mPasswordExpirationTimeout;
|
||||||
Button mSetPasswordButton;
|
Button mSetPasswordButton;
|
||||||
|
|
||||||
EditText mPassword;
|
EditText mPassword;
|
||||||
@@ -158,6 +191,8 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
EditText mProxyList;
|
EditText mProxyList;
|
||||||
Button mProxyButton;
|
Button mProxyButton;
|
||||||
|
|
||||||
|
private Button mPasswordExpirationButton;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -294,6 +329,16 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mPasswordExpirationTimeout = (EditText)findViewById(R.id.password_expiration);
|
||||||
|
mPasswordExpirationButton = (Button) findViewById(R.id.update_expiration_button);
|
||||||
|
mPasswordExpirationButton.setOnClickListener(new OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
setPasswordExpiration(
|
||||||
|
Long.parseLong(mPasswordExpirationTimeout.getText().toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mSetPasswordButton = (Button)findViewById(R.id.set_password);
|
mSetPasswordButton = (Button)findViewById(R.id.set_password);
|
||||||
mSetPasswordButton.setOnClickListener(mSetPasswordListener);
|
mSetPasswordButton.setOnClickListener(mSetPasswordListener);
|
||||||
|
|
||||||
@@ -390,6 +435,7 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
final int pwMinSymbols = prefs.getInt(PREF_PASSWORD_MINIMUM_SYMBOLS, 0);
|
final int pwMinSymbols = prefs.getInt(PREF_PASSWORD_MINIMUM_SYMBOLS, 0);
|
||||||
final int pwMinNonLetter = prefs.getInt(PREF_PASSWORD_MINIMUM_NONLETTER, 0);
|
final int pwMinNonLetter = prefs.getInt(PREF_PASSWORD_MINIMUM_NONLETTER, 0);
|
||||||
final int pwHistoryLength = prefs.getInt(PREF_PASSWORD_HISTORY_LENGTH, 0);
|
final int pwHistoryLength = prefs.getInt(PREF_PASSWORD_HISTORY_LENGTH, 0);
|
||||||
|
final long pwExpirationTimeout = prefs.getLong(PREF_PASSWORD_EXPIRATION_TIMEOUT, 0L);
|
||||||
final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
|
final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
|
||||||
|
|
||||||
for (int i=0; i<mPasswordQualityValues.length; i++) {
|
for (int i=0; i<mPasswordQualityValues.length; i++) {
|
||||||
@@ -405,6 +451,7 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
mPasswordMinimumNumeric.setText(Integer.toString(pwMinNumeric));
|
mPasswordMinimumNumeric.setText(Integer.toString(pwMinNumeric));
|
||||||
mPasswordMinimumNonLetter.setText(Integer.toString(pwMinNonLetter));
|
mPasswordMinimumNonLetter.setText(Integer.toString(pwMinNonLetter));
|
||||||
mPasswordHistoryLength.setText(Integer.toString(pwHistoryLength));
|
mPasswordHistoryLength.setText(Integer.toString(pwHistoryLength));
|
||||||
|
mPasswordExpirationTimeout.setText(Long.toString(pwExpirationTimeout/MS_PER_MINUTE));
|
||||||
mMaxFailedPw.setText(Integer.toString(maxFailedPw));
|
mMaxFailedPw.setText(Integer.toString(maxFailedPw));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,6 +467,7 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
final int pwMinSymbols = prefs.getInt(PREF_PASSWORD_MINIMUM_SYMBOLS, 0);
|
final int pwMinSymbols = prefs.getInt(PREF_PASSWORD_MINIMUM_SYMBOLS, 0);
|
||||||
final int pwMinNonLetter = prefs.getInt(PREF_PASSWORD_MINIMUM_NONLETTER, 0);
|
final int pwMinNonLetter = prefs.getInt(PREF_PASSWORD_MINIMUM_NONLETTER, 0);
|
||||||
final int pwHistoryLength = prefs.getInt(PREF_PASSWORD_HISTORY_LENGTH, 0);
|
final int pwHistoryLength = prefs.getInt(PREF_PASSWORD_HISTORY_LENGTH, 0);
|
||||||
|
final long pwExpiration = prefs.getLong(PREF_PASSWORD_EXPIRATION_TIMEOUT, 0L);
|
||||||
final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
|
final int maxFailedPw = prefs.getInt(PREF_MAX_FAILED_PW, 0);
|
||||||
|
|
||||||
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
|
boolean active = mDPM.isAdminActive(mDeviceAdminSample);
|
||||||
@@ -434,6 +482,7 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
mDPM.setPasswordMinimumNonLetter(mDeviceAdminSample, pwMinNonLetter);
|
mDPM.setPasswordMinimumNonLetter(mDeviceAdminSample, pwMinNonLetter);
|
||||||
mDPM.setPasswordHistoryLength(mDeviceAdminSample, pwHistoryLength);
|
mDPM.setPasswordHistoryLength(mDeviceAdminSample, pwHistoryLength);
|
||||||
mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, maxFailedPw);
|
mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, maxFailedPw);
|
||||||
|
mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,6 +540,22 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
updatePolicies();
|
updatePolicies();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPasswordExpiration(long expiration) {
|
||||||
|
SharedPreferences prefs = getSamplePreferences(this);
|
||||||
|
long exp = expiration * MS_PER_MINUTE; // convert from UI units to ms
|
||||||
|
prefs.edit().putLong(PREF_PASSWORD_EXPIRATION_TIMEOUT, exp).commit();
|
||||||
|
updatePolicies();
|
||||||
|
// Show confirmation dialog
|
||||||
|
long confirm = mDPM.getPasswordExpiration(mDeviceAdminSample);
|
||||||
|
String date = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT)
|
||||||
|
.format(new Date(confirm));
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setMessage("Password will expire on " + date)
|
||||||
|
.setPositiveButton("OK", null)
|
||||||
|
.create()
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
void setMaxFailedPw(int length) {
|
void setMaxFailedPw(int length) {
|
||||||
SharedPreferences prefs = getSamplePreferences(this);
|
SharedPreferences prefs = getSamplePreferences(this);
|
||||||
prefs.edit().putInt(PREF_MAX_FAILED_PW, length).commit();
|
prefs.edit().putInt(PREF_MAX_FAILED_PW, length).commit();
|
||||||
@@ -508,9 +573,9 @@ public class DeviceAdminSample extends DeviceAdminReceiver {
|
|||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case RESULT_ENABLE:
|
case RESULT_ENABLE:
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
Log.i("DeviceAdminSample", "Admin enabled!");
|
Log.i(TAG, "Admin enabled!");
|
||||||
} else {
|
} else {
|
||||||
Log.i("DeviceAdminSample", "Admin enable FAILED!");
|
Log.i(TAG, "Admin enable FAILED!");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user