Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0469e9b1 authored by Jean-Baptiste Queru's avatar Jean-Baptiste Queru
Browse files

eclair snapshot

parent 94a679da
Loading
Loading
Loading
Loading
+116 −79
Original line number Diff line number Diff line
@@ -19,38 +19,39 @@ package com.android.internal.policy.impl;
import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;

import android.accounts.AccountsServiceConstants;
import android.accounts.IAccountsService;
import android.content.ComponentName;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OperationCanceledException;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.AccountManagerCallback;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.Editable;
import android.text.InputFilter;
import android.text.LoginFilter;
import android.text.TextWatcher;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;

import java.io.IOException;

/**
 * When 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).
 *
 * <p>This class is useful only on platforms that support the
 * IAccountsService.
 */
public class AccountUnlockScreen extends RelativeLayout implements KeyguardScreen,
        View.OnClickListener, ServiceConnection, TextWatcher {
        View.OnClickListener, TextWatcher {
    private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
    private static final String LOCK_PATTERN_CLASS =
            "com.android.settings.ChooseLockPattern";
@@ -62,7 +63,6 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree

    private final KeyguardScreenCallback mCallback;
    private final LockPatternUtils mLockPatternUtils;
    private IAccountsService mAccountsService;

    private TextView mTopHeader;
    private TextView mInstructions;
@@ -71,11 +71,13 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
    private Button mOk;
    private Button mEmergencyCall;

    /**
     * Shown while making asynchronous check of password.
     */
    private ProgressDialog mCheckingDialog;

    /**
     * AccountUnlockScreen constructor.
     *
     * @throws IllegalStateException if the IAccountsService is not
     * available on the current platform.
     */
    public AccountUnlockScreen(Context context,
                               KeyguardScreenCallback callback,
@@ -88,6 +90,9 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
                R.layout.keyguard_screen_glogin_unlock, this, true);

        mTopHeader = (TextView) findViewById(R.id.topHeader);
        mTopHeader.setText(mLockPatternUtils.isPermanentlyLocked() ?
                R.string.lockscreen_glogin_too_many_attempts :
                R.string.lockscreen_glogin_forgot_pattern);

        mInstructions = (TextView) findViewById(R.id.instructions);

@@ -103,14 +108,6 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree

        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");
        }
    }

    public void afterTextChanged(Editable s) {
@@ -150,16 +147,29 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree

    /** {@inheritDoc} */
    public void cleanUp() {
        mContext.unbindService(this);
        if (mCheckingDialog != null) {
            mCheckingDialog.hide();
        }
    }

    /** {@inheritDoc} */
    public void onClick(View v) {
        mCallback.pokeWakelock();
        if (v == mOk) {
            if (checkPassword()) {
            asyncCheckPassword();
        }

        if (v == mEmergencyCall) {
            mCallback.takeEmergencyCallAction();
        }
    }

    private void onCheckPasswordResult(boolean success) {
        if (success) {
            // clear out forgotten password
            mLockPatternUtils.setPermanentlyLocked(false);
            mLockPatternUtils.setLockPatternEnabled(false);
            mLockPatternUtils.saveLockPattern(null);

            // launch the 'choose lock pattern' activity so
            // the user can pick a new one if they want to
@@ -176,16 +186,15 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
        }
    }

        if (v == mEmergencyCall) {
            mCallback.takeEmergencyCallAction();
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN
                && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            if (mLockPatternUtils.isPermanentlyLocked()) {
                mCallback.goToLockScreen();
            } else {
                mCallback.forgotPattern(false);
            }
            return true;
        }
        return super.dispatchKeyEvent(event);
@@ -207,33 +216,25 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
     * @return an account name from the database, or null if we can't
     * find a single best match.
     */
    private String findIntendedAccount(String username) {
        String[] accounts = null;
        try {
            accounts = mAccountsService.getAccounts();
        } catch (RemoteException e) {
            return null;
        }
        if (accounts == null) {
            return null;
        }
    private Account findIntendedAccount(String username) {
        Account[] accounts = AccountManager.get(mContext).getAccounts();

        // 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;
        Account bestAccount = null;
        int bestScore = 0;
        for (String a: accounts) {
        for (Account a: accounts) {
            int score = 0;
            if (username.equals(a)) {
            if (username.equals(a.name)) {
                score = 4;
            } else if (username.equalsIgnoreCase(a)) {
            } else if (username.equalsIgnoreCase(a.name)) {
                score = 3;
            } else if (username.indexOf('@') < 0) {
                int i = a.indexOf('@');
                int i = a.name.indexOf('@');
                if (i >= 0) {
                    String aUsername = a.substring(0, i);
                    String aUsername = a.name.substring(0, i);
                    if (username.equals(aUsername)) {
                        score = 2;
                    } else if (username.equalsIgnoreCase(aUsername)) {
@@ -251,28 +252,64 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
        return bestAccount;
    }

    private boolean checkPassword() {
    private void asyncCheckPassword() {
        mCallback.pokeWakelock(AWAKE_POKE_MILLIS);
        final String login = mLogin.getText().toString();
        final String password = mPassword.getText().toString();
        try {
            String account = findIntendedAccount(login);
        Account account = findIntendedAccount(login);
        if (account == null) {
                return false;
            onCheckPasswordResult(false);
            return;
        }
            return mAccountsService.shouldUnlock(account, password);
        } catch (RemoteException e) {
            return false;
        getProgressDialog().show();
        Bundle options = new Bundle();
        options.putString(AccountManager.KEY_PASSWORD, password);
        AccountManager.get(mContext).confirmCredentials(account, options, null /* activity */,
                new AccountManagerCallback<Bundle>() {
            public void run(AccountManagerFuture<Bundle> future) {
                try {
                    mCallback.pokeWakelock(AWAKE_POKE_MILLIS);
                    final Bundle result = future.getResult();
                    final boolean verified = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
                    // ensure on UI thread
                    mLogin.post(new Runnable() {
                        public void run() {
                            onCheckPasswordResult(verified);
                        }
                    });
                } catch (OperationCanceledException e) {
                    onCheckPasswordResult(false);
                } catch (IOException e) {
                    onCheckPasswordResult(false);
                } catch (AuthenticatorException e) {
                    onCheckPasswordResult(false);
                } finally {
                    mLogin.post(new Runnable() {
                        public void run() {
                            getProgressDialog().hide();
                        }
                    });
                }

    /** {@inheritDoc} */
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.v("AccountUnlockScreen", "debug: About to grab as interface");
        mAccountsService = IAccountsService.Stub.asInterface(service);
            }
        }, null /* handler */);
    }

    /** {@inheritDoc} */
    public void onServiceDisconnected(ComponentName name) {
        mAccountsService = null;
    private Dialog getProgressDialog() {
        if (mCheckingDialog == null) {
            mCheckingDialog = new ProgressDialog(mContext);
            mCheckingDialog.setMessage(
                    mContext.getString(R.string.lockscreen_glogin_checking_password));
            mCheckingDialog.setIndeterminate(true);
            mCheckingDialog.setCancelable(false);
            mCheckingDialog.getWindow().setType(
                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
            if (!mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_sf_slowBlur)) {
                mCheckingDialog.getWindow().setFlags(
                        WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
                        WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
            }
        }
        return mCheckingDialog;
    }
}
+50 −13
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.policy.impl;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
@@ -26,6 +27,7 @@ import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -40,6 +42,8 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.app.ShutdownThread;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.google.android.collect.Lists;

import java.util.ArrayList;
@@ -69,6 +73,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
    private boolean mKeyguardShowing = false;
    private boolean mDeviceProvisioned = false;
    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
    private boolean mIsWaitingForEcmExit = false;

    /**
     * @param context everything needs a context :(
@@ -81,6 +86,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
        context.registerReceiver(mBroadcastReceiver, filter);

        // get notified of phone state changes
@@ -141,21 +147,28 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
                R.string.global_actions_airplane_mode_off_status) {

            void onToggle(boolean on) {
                // Change the system setting
                Settings.System.putInt(
                        mContext.getContentResolver(),
                        Settings.System.AIRPLANE_MODE_ON,
                        on ? 1 : 0);
                Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
                intent.putExtra("state", on);
                mContext.sendBroadcast(intent);
                if (Boolean.parseBoolean(
                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
                    mIsWaitingForEcmExit = true;
                    // Launch ECM exit dialog
                    Intent ecmDialogIntent =
                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    mContext.startActivity(ecmDialogIntent);
                } else {
                    changeAirplaneModeSystemSetting(on);
                }
            }

            @Override
            protected void changeStateFromPress(boolean buttonOn) {
                // In ECM mode airplane state cannot be changed
                if (!(Boolean.parseBoolean(
                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
                    mState = buttonOn ? State.TurningOn : State.TurningOff;
                    mAirplaneState = mState;
                }
            }

            public boolean showDuringKeyguard() {
                return true;
@@ -200,8 +213,11 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac

        final AlertDialog dialog = ab.create();
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
        if (!mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_sf_slowBlur)) {
            dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
                    WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
        }

        dialog.setOnDismissListener(this);

@@ -490,6 +506,14 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
                if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
                }
            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
                // Airplane mode can be changed after ECM exits if airplane toggle button
                // is pressed during ECM mode
                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
                        mIsWaitingForEcmExit) {
                    mIsWaitingForEcmExit = false;
                    changeAirplaneModeSystemSetting(true);
                }
            }
        }
    };
@@ -514,4 +538,17 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            }
        }
    };

    /**
     * Change the airplane mode system setting
     */
    private void changeAirplaneModeSystemSetting(boolean on) {
        Settings.System.putInt(
                mContext.getContentResolver(),
                Settings.System.AIRPLANE_MODE_ON,
                on ? 1 : 0);
        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        intent.putExtra("state", on);
        mContext.sendBroadcast(intent);
    }
}
+10 −1
Original line number Diff line number Diff line
@@ -28,10 +28,19 @@ public interface KeyguardScreenCallback extends KeyguardViewCallback {
    void goToLockScreen();

    /**
     * Transitino to th unlock screen.
     * Transition to the unlock screen.
     */
    void goToUnlockScreen();

    /**
     * The user reported that they forgot their pattern (or not, when they want to back out of the
     * forgot pattern screen).
     *
     * @param isForgotten True if the user hit the forgot pattern, false if they want to back out
     *        of the account screen.
     */
    void forgotPattern(boolean isForgotten);

    /**
     * @return Whether the keyguard requires some sort of PIN.
     */
+9 −8
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import static android.provider.Telephony.Intents.EXTRA_SHOW_SPN;
import static android.provider.Telephony.Intents.EXTRA_SPN;
import static android.provider.Telephony.Intents.SPN_STRINGS_UPDATED_ACTION;

import com.android.internal.app.ShutdownThread;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.TelephonyIntents;
import android.util.Log;
@@ -67,6 +66,8 @@ public class KeyguardUpdateMonitor {
    private boolean mInPortrait;
    private boolean mKeyboardOpen;

    private boolean mKeyguardBypassEnabled;

    private boolean mDevicePluggedIn;
    
    private boolean mDeviceProvisioned;
@@ -163,6 +164,9 @@ public class KeyguardUpdateMonitor {
            }
        };

        mKeyguardBypassEnabled = context.getResources().getBoolean(
                com.android.internal.R.bool.config_bypass_keyguard_if_slider_open);

        mDeviceProvisioned = Settings.Secure.getInt(
                mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
     
@@ -295,13 +299,6 @@ public class KeyguardUpdateMonitor {
                        shouldShowBatteryInfo(), pluggedIn, batteryLevel);
            }
        }

        // shut down gracefully if our battery is critically low and we are not powered
        if (batteryLevel == 0 &&
                pluggedInStatus != BATTERY_STATUS_CHARGING &&
                pluggedInStatus != BATTERY_STATUS_UNKNOWN) {
            ShutdownThread.shutdown(mContext, false);
        }
    }

    /**
@@ -513,6 +510,10 @@ public class KeyguardUpdateMonitor {
        return mKeyboardOpen;
    }

    public boolean isKeyguardBypassEnabled() {
        return mKeyguardBypassEnabled;
    }

    public boolean isDevicePluggedIn() {
        return mDevicePluggedIn;
    }
+21 −6
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ public class KeyguardViewManager implements KeyguardWindowController {

            final int stretch = ViewGroup.LayoutParams.FILL_PARENT;
            int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
                    | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
                    /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;
            if (!mNeedsInput) {
@@ -108,7 +110,7 @@ public class KeyguardViewManager implements KeyguardWindowController {
            }
            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                    stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,
                    flags, PixelFormat.OPAQUE);
                    flags, PixelFormat.TRANSLUCENT);
            lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
            lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
            lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
@@ -195,10 +197,14 @@ public class KeyguardViewManager implements KeyguardWindowController {
     *
     * @param keyCode The wake key.
     */
    public void wakeWhenReadyTq(int keyCode) {
    public boolean wakeWhenReadyTq(int keyCode) {
        if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
        if (mKeyguardView != null) {
            mKeyguardView.wakeWhenReadyTq(keyCode);
            return true;
        } else {
            Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
            return false;
        }
    }

@@ -209,10 +215,19 @@ public class KeyguardViewManager implements KeyguardWindowController {
        if (DEBUG) Log.d(TAG, "hide()");
        if (mKeyguardHost != null) {
            mKeyguardHost.setVisibility(View.GONE);
            // Don't do this right away, so we can let the view continue to animate
            // as it goes away.
            if (mKeyguardView != null) {
                mKeyguardHost.removeView(mKeyguardView);
                mKeyguardView.cleanUp();
                final KeyguardViewBase lastView = mKeyguardView;
                mKeyguardView = null;
                mKeyguardHost.postDelayed(new Runnable() {
                    public void run() {
                        synchronized (KeyguardViewManager.this) {
                            mKeyguardHost.removeView(lastView);
                            lastView.cleanUp();
                        }
                    }
                }, 500);
            }
        }
    }
Loading