| /* |
| * Copyright (C) 2012 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.android.keyguard.test; |
| |
| import com.android.internal.policy.IKeyguardShowCallback; |
| import com.android.internal.policy.IKeyguardExitCallback; |
| import com.android.internal.policy.IKeyguardService; |
| |
| import android.app.Activity; |
| import android.app.AlertDialog; |
| import android.app.admin.DevicePolicyManager; |
| import android.content.ComponentName; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.ServiceConnection; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import android.os.IBinder; |
| import android.os.RemoteException; |
| import android.os.SystemClock; |
| import android.provider.Settings; |
| import android.util.Log; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.view.WindowManagerPolicy; |
| |
| import com.android.internal.widget.LockPatternUtils; |
| import com.android.internal.widget.LockPatternView.Cell; |
| |
| import java.util.List; |
| |
| public class KeyguardTestActivity extends Activity implements OnClickListener { |
| private static final String KEYGUARD_PACKAGE = "com.android.keyguard"; |
| private static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService"; |
| private static final String TAG = "LockScreenTestActivity"; |
| private static final int MODE_NONE = 0; |
| private static final int MODE_PIN = 1; |
| private static final int MODE_PASSWORD = 2; |
| private static final int MODE_PATTERN = 3; |
| private static final int MODE_SIM_PIN = 4; |
| private static final int MODE_SIM_PUK = 5; |
| private static final String SECURITY_MODE = "security_mode"; |
| Handler mHandler = new Handler(); |
| |
| IKeyguardService mService = null; |
| |
| KeyguardShowCallback mKeyguardShowCallback = new KeyguardShowCallback(); |
| KeyguardExitCallback mKeyguardExitCallback = new KeyguardExitCallback(); |
| |
| RemoteServiceConnection mConnection; |
| private boolean mSentSystemReady; |
| |
| class KeyguardShowCallback extends IKeyguardShowCallback.Stub { |
| |
| @Override |
| public void onShown(IBinder windowToken) throws RemoteException { |
| Log.v(TAG, "Keyguard is shown, windowToken = " + windowToken); |
| } |
| } |
| |
| class KeyguardExitCallback extends IKeyguardExitCallback.Stub { |
| |
| @Override |
| public void onKeyguardExitResult(final boolean success) throws RemoteException { |
| mHandler.post(new Runnable() { |
| @Override |
| public void run() { |
| new AlertDialog.Builder(KeyguardTestActivity.this) |
| .setMessage("Result: " + success) |
| .setPositiveButton("OK", null) |
| .show(); |
| } |
| }); |
| } |
| }; |
| |
| private class RemoteServiceConnection implements ServiceConnection { |
| public void onServiceConnected(ComponentName className, IBinder service) { |
| Log.v(TAG, "onServiceConnected()"); |
| mService = IKeyguardService.Stub.asInterface(service); |
| try { |
| mService.asBinder().linkToDeath(new IBinder.DeathRecipient() { |
| @Override |
| public void binderDied() { |
| new AlertDialog.Builder(KeyguardTestActivity.this) |
| .setMessage("Oops! Keygued died") |
| .setPositiveButton("OK", null) |
| .show(); |
| } |
| }, 0); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Couldn't linkToDeath"); |
| e.printStackTrace(); |
| } |
| // try { |
| // mService.onSystemReady(); |
| // } catch (RemoteException e) { |
| // Log.v(TAG, "Remote service died trying to call onSystemReady"); |
| // e.printStackTrace(); |
| // } |
| } |
| |
| public void onServiceDisconnected(ComponentName className) { |
| Log.v(TAG, "onServiceDisconnected()"); |
| mService = null; |
| } |
| }; |
| |
| private void bindService() { |
| if (mConnection == null) { |
| mConnection = new RemoteServiceConnection(); |
| Intent intent = new Intent(); |
| intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS); |
| Log.v(TAG, "BINDING SERVICE: " + KEYGUARD_CLASS); |
| if (!bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) { |
| Log.v(TAG, "FAILED TO BIND TO KEYGUARD!"); |
| } |
| } else { |
| Log.v(TAG, "Service already bound"); |
| } |
| } |
| |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.keyguard_test_activity); |
| final int[] buttons = { |
| R.id.on_screen_turned_off, R.id.on_screen_turned_on, |
| R.id.do_keyguard, R.id.verify_unlock |
| }; |
| for (int i = 0; i < buttons.length; i++) { |
| findViewById(buttons[i]).setOnClickListener(this); |
| } |
| Log.v(TAG, "Binding service..."); |
| bindService(); |
| } |
| |
| @Override |
| protected void onSaveInstanceState(Bundle outState) { |
| super.onSaveInstanceState(outState); |
| outState.putInt(SECURITY_MODE, mSecurityMode); |
| } |
| |
| @Override |
| protected void onRestoreInstanceState(Bundle savedInstanceState) { |
| super.onRestoreInstanceState(savedInstanceState); |
| setMode(savedInstanceState.getInt(SECURITY_MODE)); |
| } |
| |
| // TODO: Find a secure way to inject mock into keyguard... |
| // @Override |
| // public boolean onCreateOptionsMenu(Menu menu) { |
| // MenuInflater inflater = getMenuInflater(); |
| // inflater.inflate(R.menu.optionmenu, menu); |
| // return true; |
| // } |
| |
| private void setMode(int mode) { |
| mTestSimPin = false; |
| mTestSimPuk = false; |
| mLockPasswordEnabled = false; |
| mLockPatternEnabled = false; |
| switch(mode) { |
| case MODE_NONE: |
| mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; |
| break; |
| case MODE_PIN: |
| mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; |
| mLockPasswordEnabled = true; |
| break; |
| case MODE_PASSWORD: |
| mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; |
| mLockPasswordEnabled = true; |
| break; |
| case MODE_PATTERN: |
| mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; |
| mLockPatternEnabled = true; |
| break; |
| case MODE_SIM_PIN: |
| mTestSimPin = true; |
| break; |
| case MODE_SIM_PUK: |
| mTestSimPuk = true; |
| break; |
| } |
| mSecurityMode = mode; |
| } |
| |
| @Override |
| public boolean onOptionsItemSelected(MenuItem item) { |
| // Handle item selection |
| switch (item.getItemId()) { |
| case R.id.none_menu_item: |
| setMode(MODE_NONE); |
| break; |
| case R.id.pin_menu_item: |
| setMode(MODE_PIN); |
| break; |
| case R.id.password_menu_item: |
| setMode(MODE_PASSWORD); |
| break; |
| case R.id.pattern_menu_item: |
| setMode(MODE_PATTERN); |
| break; |
| case R.id.sim_pin_menu_item: |
| setMode(MODE_SIM_PIN); |
| break; |
| case R.id.sim_puk_menu_item: |
| setMode(MODE_SIM_PUK); |
| break; |
| case R.id.add_widget_item: |
| startWidgetPicker(); |
| break; |
| default: |
| return super.onOptionsItemSelected(item); |
| } |
| try { |
| mService.doKeyguardTimeout(null); |
| } catch (RemoteException e) { |
| Log.e(TAG, "Remote service died"); |
| e.printStackTrace(); |
| } |
| return true; |
| } |
| |
| private void startWidgetPicker() { |
| startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS)); |
| } |
| |
| @Override |
| public void onClick(View v) { |
| try { |
| switch (v.getId()) { |
| case R.id.on_screen_turned_on: |
| mService.onScreenTurnedOn(mKeyguardShowCallback); |
| break; |
| case R.id.on_screen_turned_off: |
| mService.onScreenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER); |
| break; |
| case R.id.do_keyguard: |
| if (!mSentSystemReady) { |
| mSentSystemReady = true; |
| mService.onSystemReady(); |
| } |
| mService.doKeyguardTimeout(null); |
| break; |
| case R.id.verify_unlock: |
| mService.doKeyguardTimeout(null); |
| // Wait for keyguard to lock and then try this... |
| mHandler.postDelayed(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| mService.verifyUnlock(mKeyguardExitCallback); |
| } catch (RemoteException e) { |
| Log.e(TAG, "Failed verifyUnlock()", e); |
| } |
| } |
| }, 5000); |
| break; |
| } |
| } catch (RemoteException e) { |
| Log.e(TAG, "onClick(): Failed due to remote exeption", e); |
| } |
| } |
| |
| @Override |
| protected void onPause() { |
| super.onPause(); |
| try { |
| if (mService != null) { |
| mService.setHidden(true); |
| } |
| } catch (RemoteException e) { |
| Log.e(TAG, "Remote service died"); |
| e.printStackTrace(); |
| } |
| } |
| |
| protected void onResume() { |
| super.onResume(); |
| try { |
| if (mService != null) { |
| mService.setHidden(false); |
| } |
| } catch (RemoteException e) { |
| Log.e(TAG, "Remote service died"); |
| e.printStackTrace(); |
| } |
| } |
| |
| public int mSecurityModeMock; |
| private boolean mTestSimPin; |
| private boolean mTestSimPuk; |
| private boolean mLockPasswordEnabled; |
| public boolean mLockPatternEnabled; |
| private int mSecurityMode; |
| |
| class LockPatternUtilsMock extends LockPatternUtils { |
| private long mDeadline; |
| public LockPatternUtilsMock(Context context) { |
| super(context); |
| } |
| |
| @Override |
| public boolean checkPattern(List<Cell> pattern) { |
| return pattern.size() > 4; |
| } |
| |
| @Override |
| public boolean checkPassword(String password) { |
| return password.length() > 4; |
| } |
| @Override |
| public long setLockoutAttemptDeadline() { |
| final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS; |
| mDeadline = deadline; |
| return deadline; |
| } |
| @Override |
| public boolean isLockScreenDisabled() { |
| return false; |
| } |
| @Override |
| public long getLockoutAttemptDeadline() { |
| return mDeadline; |
| } |
| @Override |
| public void reportFailedPasswordAttempt() { |
| // Ignored |
| } |
| @Override |
| public void reportSuccessfulPasswordAttempt() { |
| // Ignored |
| } |
| @Override |
| public boolean isLockPatternEnabled() { |
| return mLockPatternEnabled; |
| } |
| |
| @Override |
| public boolean isLockPasswordEnabled() { |
| return mLockPasswordEnabled; |
| } |
| |
| @Override |
| public int getKeyguardStoredPasswordQuality() { |
| return mSecurityModeMock; |
| } |
| |
| public boolean isSecure() { |
| return mLockPatternEnabled || mLockPasswordEnabled || mTestSimPin || mTestSimPuk; |
| } |
| |
| } |
| } |