AccountUnlockScreenpublic class AccountUnlockScreen extends android.widget.RelativeLayout implements android.content.ServiceConnection, KeyguardScreen, android.text.TextWatcher, View.OnClickListenerWhen the user forgets their password a bunch of times, we fall back on their
account's login/password to unlock the phone (and reset their lock pattern).
This class is useful only on platforms that support the
IAccountsService. |
Fields Summary |
---|
private static final String | LOCK_PATTERN_PACKAGE | private static final String | LOCK_PATTERN_CLASS | private static final int | AWAKE_POKE_MILLISThe amount of millis to stay awake once this screen detects activity | private final KeyguardScreenCallback | mCallback | private final com.android.internal.widget.LockPatternUtils | mLockPatternUtils | private android.accounts.IAccountsService | mAccountsService | private android.widget.TextView | mTopHeader | private android.widget.TextView | mInstructions | private android.widget.EditText | mLogin | private android.widget.EditText | mPassword | private android.widget.Button | mOk | private android.widget.Button | mEmergencyCall |
Constructors Summary |
---|
public AccountUnlockScreen(android.content.Context context, KeyguardScreenCallback callback, com.android.internal.widget.LockPatternUtils lockPatternUtils)AccountUnlockScreen constructor.
super(context);
mCallback = callback;
mLockPatternUtils = lockPatternUtils;
LayoutInflater.from(context).inflate(
R.layout.keyguard_screen_glogin_unlock, this, true);
mTopHeader = (TextView) findViewById(R.id.topHeader);
mInstructions = (TextView) findViewById(R.id.instructions);
mLogin = (EditText) findViewById(R.id.login);
mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
mLogin.addTextChangedListener(this);
mPassword = (EditText) findViewById(R.id.password);
mPassword.addTextChangedListener(this);
mOk = (Button) findViewById(R.id.ok);
mOk.setOnClickListener(this);
mEmergencyCall = (Button) findViewById(R.id.emergencyCall);
mEmergencyCall.setOnClickListener(this);
Log.v("AccountUnlockScreen", "debug: Connecting to accounts service");
final boolean connected = mContext.bindService(AccountsServiceConstants.SERVICE_INTENT,
this, Context.BIND_AUTO_CREATE);
if (!connected) {
Log.v("AccountUnlockScreen", "debug: Couldn't connect to accounts service");
throw new IllegalStateException("couldn't bind to accounts service");
}
|
Methods Summary |
---|
public void | afterTextChanged(android.text.Editable s)
| public void | beforeTextChanged(java.lang.CharSequence s, int start, int count, int after)
| private boolean | checkPassword()
final String login = mLogin.getText().toString();
final String password = mPassword.getText().toString();
try {
String account = findIntendedAccount(login);
if (account == null) {
return false;
}
return mAccountsService.shouldUnlock(account, password);
} catch (RemoteException e) {
return false;
}
| public void | cleanUp(){@inheritDoc}
mContext.unbindService(this);
| public boolean | dispatchKeyEvent(android.view.KeyEvent event)
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
mCallback.goToLockScreen();
return true;
}
return super.dispatchKeyEvent(event);
| private java.lang.String | findIntendedAccount(java.lang.String username)Given the string the user entered in the 'username' field, find
the stored account that they probably intended. Prefer, in order:
- an exact match for what was typed, or
- a case-insensitive match for what was typed, or
- if they didn't include a domain, an exact match of the username, or
- if they didn't include a domain, a case-insensitive
match of the username.
If there is a tie for the best match, choose neither --
the user needs to be more specific.
String[] accounts = null;
try {
accounts = mAccountsService.getAccounts();
} catch (RemoteException e) {
return null;
}
if (accounts == null) {
return null;
}
// Try to figure out which account they meant if they
// typed only the username (and not the domain), or got
// the case wrong.
String bestAccount = null;
int bestScore = 0;
for (String a: accounts) {
int score = 0;
if (username.equals(a)) {
score = 4;
} else if (username.equalsIgnoreCase(a)) {
score = 3;
} else if (username.indexOf('@") < 0) {
int i = a.indexOf('@");
if (i >= 0) {
String aUsername = a.substring(0, i);
if (username.equals(aUsername)) {
score = 2;
} else if (username.equalsIgnoreCase(aUsername)) {
score = 1;
}
}
}
if (score > bestScore) {
bestAccount = a;
bestScore = score;
} else if (score == bestScore) {
bestAccount = null;
}
}
return bestAccount;
| public boolean | needsInput(){@inheritDoc}
return true;
| public void | onClick(android.view.View v){@inheritDoc}
mCallback.pokeWakelock();
if (v == mOk) {
if (checkPassword()) {
// clear out forgotten password
mLockPatternUtils.setPermanentlyLocked(false);
// launch the 'choose lock pattern' activity so
// the user can pick a new one if they want to
Intent intent = new Intent();
intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
// close the keyguard
mCallback.keyguardDone(true);
} else {
mInstructions.setText(R.string.lockscreen_glogin_invalid_input);
mPassword.setText("");
}
}
if (v == mEmergencyCall) {
mCallback.takeEmergencyCallAction();
}
| public void | onPause(){@inheritDoc}
| protected boolean | onRequestFocusInDescendants(int direction, android.graphics.Rect previouslyFocusedRect)
// send focus to the login field
return mLogin.requestFocus(direction, previouslyFocusedRect);
| public void | onResume(){@inheritDoc}
// start fresh
mLogin.setText("");
mPassword.setText("");
mLogin.requestFocus();
| public void | onServiceConnected(android.content.ComponentName name, android.os.IBinder service){@inheritDoc}
Log.v("AccountUnlockScreen", "debug: About to grab as interface");
mAccountsService = IAccountsService.Stub.asInterface(service);
| public void | onServiceDisconnected(android.content.ComponentName name){@inheritDoc}
mAccountsService = null;
| public void | onTextChanged(java.lang.CharSequence s, int start, int before, int count)
mCallback.pokeWakelock(AWAKE_POKE_MILLIS);
|
|