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

Commit 251edb3b authored by Jean-Baptiste Queru's avatar Jean-Baptiste Queru
Browse files

Merge commit 'remotes/korg/cupcake' into merge

parents 7ac5a085 d06b0976
Loading
Loading
Loading
Loading
+92 −4
Original line number Diff line number Diff line
@@ -28,8 +28,11 @@ 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;
@@ -47,13 +50,16 @@ import android.widget.TextView;
 * IAccountsService.
 */
public class AccountUnlockScreen extends RelativeLayout implements KeyguardScreen,
        View.OnClickListener, ServiceConnection {


        View.OnClickListener, ServiceConnection, TextWatcher {
    private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
    private static final String LOCK_PATTERN_CLASS =
            "com.android.settings.ChooseLockPattern";

    /**
     * The amount of millis to stay awake once this screen detects activity
     */
    private static final int AWAKE_POKE_MILLIS = 30000;

    private final KeyguardScreenCallback mCallback;
    private final LockPatternUtils mLockPatternUtils;
    private IAccountsService mAccountsService;
@@ -87,8 +93,10 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree

        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);
@@ -105,6 +113,16 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
        }
    }

    public void afterTextChanged(Editable s) {
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        mCallback.pokeWakelock(AWAKE_POKE_MILLIS);
    }

    @Override
    protected boolean onRequestFocusInDescendants(int direction,
            Rect previouslyFocusedRect) {
@@ -112,6 +130,11 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
        return mLogin.requestFocus(direction, previouslyFocusedRect);
    }

    /** {@inheritDoc} */
    public boolean needsInput() {
        return true;
    }

    /** {@inheritDoc} */
    public void onPause() {

@@ -132,6 +155,7 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree

    /** {@inheritDoc} */
    public void onClick(View v) {
        mCallback.pokeWakelock();
        if (v == mOk) {
            if (checkPassword()) {
                // clear out forgotten password
@@ -167,11 +191,75 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
        return super.dispatchKeyEvent(event);
    }

    /**
     * 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.
     *
     * @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;
        }

        // 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;
    }

    private boolean checkPassword() {
        final String login = mLogin.getText().toString();
        final String password = mPassword.getText().toString();
        try {
            return mAccountsService.shouldUnlock(login, password);
            String account = findIntendedAccount(login);
            if (account == null) {
                return false;
            }
            return mAccountsService.shouldUnlock(account, password);
        } catch (RemoteException e) {
            return false;
        }
+150 −50
Original line number Diff line number Diff line
@@ -16,29 +16,30 @@

package com.android.internal.policy.impl;

import com.android.internal.R;
import com.google.android.collect.Lists;

import android.app.AlertDialog;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.DialogInterface;
import android.media.AudioManager;
import android.os.LocalPowerManager;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.R;
import com.google.android.collect.Lists;

import java.util.ArrayList;

@@ -49,34 +50,41 @@ import java.util.ArrayList;
 */
class GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {

    private static final String TAG = "GlobalActions";

    private StatusBarManager mStatusBar;

    private final Context mContext;
    private final LocalPowerManager mPowerManager;
    private final AudioManager mAudioManager;

    private ArrayList<Action> mItems;
    private AlertDialog mDialog;

    private ToggleAction mSilentModeToggle;
    private ToggleAction mAirplaneModeOn;

    private MyAdapter mAdapter;

    private boolean mKeyguardShowing = false;
    private boolean mDeviceProvisioned = false;
    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;

    /**
     * @param context everything needs a context :)
     * @param powerManager used to turn the screen off (the lock action).
     * @param context everything needs a context :(
     */
    public GlobalActions(Context context, LocalPowerManager powerManager) {
    public GlobalActions(Context context) {
        mContext = context;
        mPowerManager = powerManager;
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

        // receive broadcasts
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        context.registerReceiver(mBroadcastReceiver, filter);

        // get notified of phone state changes
        TelephonyManager telephonyManager =
                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
    }

    /**
@@ -123,29 +131,48 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            }
        };

        mItems = Lists.newArrayList(
                /* Disabled pending bug 1304831 -- key or touch events wake up device before it
                 * can go to sleep.
                // first: lock screen
                new SinglePressAction(com.android.internal.R.drawable.ic_lock_lock, R.string.global_action_lock) {
        mAirplaneModeOn = new ToggleAction(
                R.drawable.ic_lock_airplane_mode,
                R.drawable.ic_lock_airplane_mode_off,
                R.string.global_actions_toggle_airplane_mode,
                R.string.global_actions_airplane_mode_on_status,
                R.string.global_actions_airplane_mode_off_status) {

                    public void onPress() {
                        mPowerManager.goToSleep(SystemClock.uptimeMillis() + 1);
            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);
            }

            @Override
            protected void changeStateFromPress(boolean buttonOn) {
                mState = buttonOn ? State.TurningOn : State.TurningOff;
                mAirplaneState = mState;
            }

            public boolean showDuringKeyguard() {
                        return false;
                return true;
            }

            public boolean showBeforeProvisioning() {
                return false;
            }
                },
                */
                // next: silent mode
        };

        mItems = Lists.newArrayList(
                // silent mode
                mSilentModeToggle,
                // next: airplane mode
                mAirplaneModeOn,
                // last: power off
                new SinglePressAction(com.android.internal.R.drawable.ic_lock_power_off, R.string.global_action_power_off) {
                new SinglePressAction(
                        com.android.internal.R.drawable.ic_lock_power_off,
                        R.string.global_action_power_off) {

                    public void onPress() {
                        // shutdown by making sure radio and power are handled accordingly.
@@ -180,10 +207,11 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
    }

    private void prepareDialog() {
        // TODO: May need another 'Vibrate' toggle button, but for now treat them the same
        final boolean silentModeOn =
                mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
        mSilentModeToggle.updateState(silentModeOn);
        mSilentModeToggle.updateState(
                silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
        mAirplaneModeOn.updateState(mAirplaneState);
        mAdapter.notifyDataSetChanged();
        if (mKeyguardShowing) {
            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
@@ -192,6 +220,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        }
    }


    /** {@inheritDoc} */
    public void onDismiss(DialogInterface dialog) {
        mStatusBar.disable(StatusBarManager.DISABLE_NONE);
@@ -229,6 +258,16 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            return count;
        }

        @Override
        public boolean isEnabled(int position) {
            return getItem(position).isEnabled();
        }

        @Override
        public boolean areAllItemsEnabled() {
            return false;
        }

        public Action getItem(int position) {

            int filteredPos = 0;
@@ -259,7 +298,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac

        public View getView(int position, View convertView, ViewGroup parent) {
            Action action = getItem(position);
            return action.create(mContext, (LinearLayout) convertView, LayoutInflater.from(mContext));
            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
        }
    }

@@ -273,7 +312,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
     * What each item in the global actions dialog must be able to support.
     */
    private interface Action {
        LinearLayout create(Context context, LinearLayout convertView, LayoutInflater inflater);
        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);

        void onPress();

@@ -288,6 +327,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
         *   device is provisioned.
         */
        boolean showBeforeProvisioning();

        boolean isEnabled();
    }

    /**
@@ -303,12 +344,17 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            mMessageResId = messageResId;
        }

        public boolean isEnabled() {
            return true;
        }

        abstract public void onPress();

        public LinearLayout create(Context context, LinearLayout convertView, LayoutInflater inflater) {
            LinearLayout v = (LinearLayout) ((convertView != null) ?
        public View create(
                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
            View v = (convertView != null) ?
                    convertView :
                    inflater.inflate(R.layout.global_actions_item, null));
                    inflater.inflate(R.layout.global_actions_item, parent, false);

            ImageView icon = (ImageView) v.findViewById(R.id.icon);
            TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -326,9 +372,26 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
     * A toggle action knows whether it is on or off, and displays an icon
     * and status message accordingly.
     */
    static abstract class ToggleAction implements Action {
    private static abstract class ToggleAction implements Action {

        enum State {
            Off(false),
            TurningOn(true),
            TurningOff(true),
            On(false);

        private boolean mOn = false;
            private final boolean inTransition;

            State(boolean intermediate) {
                inTransition = intermediate;
            }

            public boolean inTransition() {
                return inTransition;
            }
        }

        protected State mState = State.Off;

        // prefs
        private final int mEnabledIconResId;
@@ -356,12 +419,12 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
            mDisabledStatusMessageResId = disabledStatusMessageResId;
        }

        public LinearLayout create(Context context, LinearLayout convertView,
        public View create(Context context, View convertView, ViewGroup parent,
                LayoutInflater inflater) {
            LinearLayout v = (LinearLayout) ((convertView != null) ?
            View v = (convertView != null) ?
                    convertView :
                    inflater.inflate(R
                            .layout.global_actions_item, null));
                            .layout.global_actions_item, parent, false);

            ImageView icon = (ImageView) v.findViewById(R.id.icon);
            TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -369,23 +432,50 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac

            messageView.setText(mMessageResId);

            boolean on = ((mState == State.On) || (mState == State.TurningOn));
            icon.setImageDrawable(context.getResources().getDrawable(
                    (mOn ? mEnabledIconResId : mDisabledIconResid)));
            statusView.setText(mOn ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
                    (on ? mEnabledIconResId : mDisabledIconResid)));
            statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
            statusView.setVisibility(View.VISIBLE);

            final boolean enabled = isEnabled();
            messageView.setEnabled(enabled);
            statusView.setEnabled(enabled);
            icon.setEnabled(enabled);
            v.setEnabled(enabled);

            return v;
        }

        public void onPress() {
            updateState(!mOn);
            onToggle(mOn);
        public final void onPress() {
            if (mState.inTransition()) {
                Log.w(TAG, "shouldn't be able to toggle when in transition");
                return;
            }

            final boolean nowOn = !(mState == State.On);
            onToggle(nowOn);
            changeStateFromPress(nowOn);
        }

        public boolean isEnabled() {
            return !mState.inTransition();
        }

        /**
         * Implementations may override this if their state can be in on of the intermediate
         * states until some notification is received (e.g airplane mode is 'turning off' until
         * we know the wireless connections are back online
         * @param buttonOn Whether the button was turned on or off
         */
        protected void changeStateFromPress(boolean buttonOn) {
            mState = buttonOn ? State.On : State.Off;
        }

        abstract void onToggle(boolean on);

        public void updateState(boolean on) {
            mOn = on;
        public void updateState(State state) {
            mState = state;
        }
    }

@@ -401,6 +491,16 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        }
    };

    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
        @Override
        public void onServiceStateChanged(ServiceState serviceState) {
            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
            mAirplaneModeOn.updateState(mAirplaneState);
            mAdapter.notifyDataSetChanged();
        }
    };

    private static final int MESSAGE_DISMISS = 0;
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
+6 −1
Original line number Diff line number Diff line
@@ -22,6 +22,12 @@ package com.android.internal.policy.impl;
 */
public interface KeyguardScreen {

    /**
     * Return true if your view needs input, so should allow the soft
     * keyboard to be displayed.
     */
    boolean needsInput();
    
    /**
     * This screen is no longer in front of the user.
     */
@@ -36,5 +42,4 @@ public interface KeyguardScreen {
     * This view is going away; a hook to do cleanup.
     */
    void cleanUp();

}
+2 −2
Original line number Diff line number Diff line
@@ -375,12 +375,12 @@ public class KeyguardUpdateMonitor {
    }

    /**
     * Is the keyboard currently open?
     * Is the (hard) keyboard currently open?
     */
    boolean queryKeyboardOpen() {
        final Configuration configuration = mContext.getResources().getConfiguration();

        return configuration.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO;
        return configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
    }

    /**
+14 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.policy.impl;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.view.View;
import android.widget.FrameLayout;
@@ -36,6 +37,7 @@ public abstract class KeyguardViewBase extends FrameLayout {

    private KeyguardViewCallback mCallback;
    private AudioManager mAudioManager;
    private TelephonyManager mTelephonyManager = null;

    public KeyguardViewBase(Context context) {
        super(context);
@@ -131,8 +133,18 @@ public abstract class KeyguardViewBase extends FrameLayout {
        final int keyCode = event.getKeyCode();
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_HEADSETHOOK: 
                case KeyEvent.KEYCODE_PLAYPAUSE:
                    /* Suppress PLAYPAUSE toggle when phone is ringing or
                     * in-call to avoid music playback */
                    if (mTelephonyManager == null) {
                        mTelephonyManager = (TelephonyManager) getContext().getSystemService(
                                Context.TELEPHONY_SERVICE);
                    }
                    if (mTelephonyManager != null &&
                            mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
                        return true;  // suppress key event
                    }
                case KeyEvent.KEYCODE_HEADSETHOOK: 
                case KeyEvent.KEYCODE_STOP: 
                case KeyEvent.KEYCODE_NEXTSONG: 
                case KeyEvent.KEYCODE_PREVIOUSSONG: 
@@ -167,6 +179,7 @@ public abstract class KeyguardViewBase extends FrameLayout {
            }
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_MUTE:
                case KeyEvent.KEYCODE_HEADSETHOOK: 
                case KeyEvent.KEYCODE_PLAYPAUSE: 
                case KeyEvent.KEYCODE_STOP: 
Loading