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

Commit 7c2d7ad6 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Let accessibility users know to connect a headset when the IME connects...

Merge "Let accessibility users know to connect a headset when the IME connects to a password field."
parents fee149ab b0c8db01
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -142,6 +142,9 @@
    <!-- Label for "Wait" key of phone number keyboard.  Must be short to fit on key! [CHAR LIMIT=5]-->
    <string name="label_wait_key">Wait</string>

    <!-- Spoken description to let the user know that when typing in a password, they can plug in a headset in to hear spoken descriptions of the keys they type. [CHAR LIMIT=NONE] -->
    <string name="spoken_use_headphones">Plug in a headset to hear password keys spoken aloud.</string>

    <!-- Spoken description for the currently entered text -->
    <string name="spoken_current_text_is">Current text is "%s"</string>
    <!-- Spoken description when there is no text entered -->
+43 −2
Original line number Diff line number Diff line
@@ -19,15 +19,19 @@ package com.android.inputmethod.accessibility;
import android.content.Context;
import android.content.SharedPreferences;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.EditorInfo;

import com.android.inputmethod.compat.AccessibilityEventCompatUtils;
import com.android.inputmethod.compat.AccessibilityManagerCompatWrapper;
import com.android.inputmethod.compat.AudioManagerCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.MotionEventCompatUtils;
import com.android.inputmethod.latin.R;

public class AccessibilityUtils {
    private static final String TAG = AccessibilityUtils.class.getSimpleName();
@@ -37,8 +41,10 @@ public class AccessibilityUtils {

    private static final AccessibilityUtils sInstance = new AccessibilityUtils();

    private Context mContext;
    private AccessibilityManager mAccessibilityManager;
    private AccessibilityManagerCompatWrapper mCompatManager;
    private AudioManagerCompatWrapper mAudioManager;

    /*
     * Setting this constant to {@code false} will disable all keyboard
@@ -67,9 +73,14 @@ public class AccessibilityUtils {
    }

    private void initInternal(Context context, SharedPreferences prefs) {
        mContext = context;
        mAccessibilityManager = (AccessibilityManager) context
                .getSystemService(Context.ACCESSIBILITY_SERVICE);
        mCompatManager = new AccessibilityManagerCompatWrapper(mAccessibilityManager);

        final AudioManager audioManager = (AudioManager) context
                .getSystemService(Context.AUDIO_SERVICE);
        mAudioManager = new AudioManagerCompatWrapper(audioManager);
    }

    /**
@@ -101,6 +112,22 @@ public class AccessibilityUtils {
                || action == MotionEventCompatUtils.ACTION_HOVER_MOVE;
    }

    /**
     * @return {@code true} if the device should not speak text (eg.
     *         non-control) characters
     */
    public boolean shouldObscureInput(EditorInfo attribute) {
        if (attribute == null)
            return false;

        // Always speak if the user is listening through headphones.
        if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn())
            return false;

        // Don't speak if the IME is connected to a password field.
        return InputTypeCompatUtils.isPasswordInputType(attribute.inputType);
    }

    /**
     * Sends the specified text to the {@link AccessibilityManager} to be
     * spoken.
@@ -117,7 +144,7 @@ public class AccessibilityUtils {
        // class. Instead, we're just forcing a fake AccessibilityEvent into
        // the screen reader to make it speak.
        final AccessibilityEvent event = AccessibilityEvent
                .obtain(AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER);
                .obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED);

        event.setPackageName(PACKAGE);
        event.setClassName(CLASS);
@@ -127,4 +154,18 @@ public class AccessibilityUtils {

        mAccessibilityManager.sendAccessibilityEvent(event);
    }

    /**
     * Handles speaking the "connect a headset to hear passwords" notification
     * when connecting to a password field.
     *
     * @param attribute The input connection's editor info attribute.
     * @param restarting Whether the connection is being restarted.
     */
    public void onStartInputViewInternal(EditorInfo attribute, boolean restarting) {
        if (shouldObscureInput(attribute)) {
            final CharSequence text = mContext.getText(R.string.spoken_use_headphones);
            speak(text);
        }
    }
}
+2 −25
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Paint;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -29,8 +28,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.inputmethod.EditorInfo;

import com.android.inputmethod.compat.AccessibilityEventCompatUtils;
import com.android.inputmethod.compat.AudioManagerCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.MotionEventCompatUtils;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
@@ -48,7 +45,6 @@ public class AccessibleKeyboardViewProxy {
    private FlickGestureDetector mGestureDetector;
    private LatinKeyboardView mView;
    private AccessibleKeyboardActionListener mListener;
    private AudioManagerCompatWrapper mAudioManager;

    private int mScaledEdgeSlop;
    private int mLastHoverKeyIndex = KeyDetector.NOT_A_KEY;
@@ -82,26 +78,6 @@ public class AccessibleKeyboardViewProxy {
        mInputMethod = inputMethod;
        mGestureDetector = new KeyboardFlickGestureDetector(inputMethod);
        mScaledEdgeSlop = ViewConfiguration.get(inputMethod).getScaledEdgeSlop();

        final AudioManager audioManager = (AudioManager) inputMethod
                .getSystemService(Context.AUDIO_SERVICE);
        mAudioManager = new AudioManagerCompatWrapper(audioManager);
    }

    /**
     * @return {@code true} if the device should not speak text (eg. non-control) characters
     */
    private boolean shouldObscureInput() {
        // Always speak if the user is listening through headphones.
        if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn())
            return false;

        final EditorInfo info = mInputMethod.getCurrentInputEditorInfo();
        if (info == null)
            return false;

        // Don't speak if the IME is connected to a password field.
        return InputTypeCompatUtils.isPasswordInputType(info.inputType);
    }

    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event,
@@ -118,7 +94,8 @@ public class AccessibleKeyboardViewProxy {
            if (key == null)
                break;

            final boolean shouldObscure = shouldObscureInput();
            final EditorInfo info = mInputMethod.getCurrentInputEditorInfo();
            final boolean shouldObscure = AccessibilityUtils.getInstance().shouldObscureInput(info);
            final CharSequence description = KeyCodeDescriptionMapper.getInstance()
                    .getDescriptionForKey(mView.getContext(), mView.getKeyboard(), key,
                            shouldObscure);
+6 −0
Original line number Diff line number Diff line
@@ -693,6 +693,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
            return;
        }

        // Forward this event to the accessibility utilities, if enabled.
        final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance();
        if (accessUtils.isTouchExplorationEnabled()) {
            accessUtils.onStartInputViewInternal(attribute, restarting);
        }

        mSubtypeSwitcher.updateParametersOnStartInputView();

        TextEntryState.reset();