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

Commit e30e02f5 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add system layer for voice interaction services.

New window layer that voice interaction service windows
go in to.  Includes a new voice-specific content rectangle
that voice activities are placed in to.

Add specific animations for this layer, sliding down from
the top (though this can be customized by the voice interaction
service).

Also add the concept of activities running for voice interaction
services for purposes of adjusting the animation used for them,
again sliding from the top, but not (yet?) customizable by the
voice interaction service.

Change-Id: Ic9e0e8c843c2e2972d6abb4087dce0019326155d
parent bbd8e6ff
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -26386,7 +26386,7 @@ package android.service.voice {
    field public static final int TOUCHABLE_INSETS_CONTENT = 1; // 0x1
    field public static final int TOUCHABLE_INSETS_CONTENT = 1; // 0x1
    field public static final int TOUCHABLE_INSETS_FRAME = 0; // 0x0
    field public static final int TOUCHABLE_INSETS_FRAME = 0; // 0x0
    field public static final int TOUCHABLE_INSETS_REGION = 3; // 0x3
    field public static final int TOUCHABLE_INSETS_REGION = 3; // 0x3
    field public int contentTopInsets;
    field public final android.graphics.Rect contentInsets;
    field public int touchableInsets;
    field public int touchableInsets;
    field public final android.graphics.Region touchableRegion;
    field public final android.graphics.Region touchableRegion;
  }
  }
+2 −1
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@ import android.text.method.MovementMethod;
import android.util.Log;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Printer;
import android.view.Gravity;
import android.view.KeyCharacterMap;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
@@ -679,7 +680,7 @@ public class InputMethodService extends AbstractInputMethodService {
        mInflater = (LayoutInflater)getSystemService(
        mInflater = (LayoutInflater)getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
                Context.LAYOUT_INFLATER_SERVICE);
        mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState,
        mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState,
                false);
                WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false);
        if (mHardwareAccelerated) {
        if (mHardwareAccelerated) {
            mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
            mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        }
        }
+18 −58
Original line number Original line Diff line number Diff line
@@ -37,6 +37,8 @@ public class SoftInputWindow extends Dialog {
    final Callback mCallback;
    final Callback mCallback;
    final KeyEvent.Callback mKeyEventCallback;
    final KeyEvent.Callback mKeyEventCallback;
    final KeyEvent.DispatcherState mDispatcherState;
    final KeyEvent.DispatcherState mDispatcherState;
    final int mWindowType;
    final int mGravity;
    final boolean mTakesFocus;
    final boolean mTakesFocus;
    private final Rect mBounds = new Rect();
    private final Rect mBounds = new Rect();


@@ -64,12 +66,14 @@ public class SoftInputWindow extends Dialog {
     */
     */
    public SoftInputWindow(Context context, String name, int theme, Callback callback,
    public SoftInputWindow(Context context, String name, int theme, Callback callback,
            KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState,
            KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState,
            boolean takesFocus) {
            int windowType, int gravity, boolean takesFocus) {
        super(context, theme);
        super(context, theme);
        mName = name;
        mName = name;
        mCallback = callback;
        mCallback = callback;
        mKeyEventCallback = keyEventCallback;
        mKeyEventCallback = keyEventCallback;
        mDispatcherState = dispatcherState;
        mDispatcherState = dispatcherState;
        mWindowType = windowType;
        mGravity = gravity;
        mTakesFocus = takesFocus;
        mTakesFocus = takesFocus;
        initDockWindow();
        initDockWindow();
    }
    }
@@ -96,47 +100,6 @@ public class SoftInputWindow extends Dialog {
        }
        }
    }
    }


    /**
     * Get the size of the DockWindow.
     * 
     * @return If the DockWindow sticks to the top or bottom of the screen, the
     *         return value is the height of the DockWindow, and its width is
     *         equal to the width of the screen; If the DockWindow sticks to the
     *         left or right of the screen, the return value is the width of the
     *         DockWindow, and its height is equal to the height of the screen.
     */
    public int getSize() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();

        if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) {
            return lp.height;
        } else {
            return lp.width;
        }
    }

    /**
     * Set the size of the DockWindow.
     * 
     * @param size If the DockWindow sticks to the top or bottom of the screen,
     *        <var>size</var> is the height of the DockWindow, and its width is
     *        equal to the width of the screen; If the DockWindow sticks to the
     *        left or right of the screen, <var>size</var> is the width of the
     *        DockWindow, and its height is equal to the height of the screen.
     */
    public void setSize(int size) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();

        if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) {
            lp.width = -1;
            lp.height = size;
        } else {
            lp.width = size;
            lp.height = -1;
        }
        getWindow().setAttributes(lp);
    }

    /**
    /**
     * Set which boundary of the screen the DockWindow sticks to.
     * Set which boundary of the screen the DockWindow sticks to.
     * 
     * 
@@ -147,19 +110,19 @@ public class SoftInputWindow extends Dialog {
     */
     */
    public void setGravity(int gravity) {
    public void setGravity(int gravity) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        WindowManager.LayoutParams lp = getWindow().getAttributes();

        boolean oldIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM);

        lp.gravity = gravity;
        lp.gravity = gravity;

        updateWidthHeight(lp);
        boolean newIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM);

        if (oldIsVertical != newIsVertical) {
            int tmp = lp.width;
            lp.width = lp.height;
            lp.height = tmp;
        getWindow().setAttributes(lp);
        getWindow().setAttributes(lp);
    }
    }

    private void updateWidthHeight(WindowManager.LayoutParams lp) {
        if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) {
            lp.width = WindowManager.LayoutParams.MATCH_PARENT;
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        } else {
            lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
            lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        }
    }
    }


    public boolean onKeyDown(int keyCode, KeyEvent event) {
    public boolean onKeyDown(int keyCode, KeyEvent event) {
@@ -201,14 +164,11 @@ public class SoftInputWindow extends Dialog {
    private void initDockWindow() {
    private void initDockWindow() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        WindowManager.LayoutParams lp = getWindow().getAttributes();


        lp.type = WindowManager.LayoutParams.TYPE_INPUT_METHOD;
        lp.type = mWindowType;
        lp.setTitle(mName);
        lp.setTitle(mName);


        lp.gravity = Gravity.BOTTOM;
        lp.gravity = mGravity;
        lp.width = -1;
        updateWidthHeight(lp);
        // Let the input method window's orientation follow sensor based rotation
        // Turn this off for now, it is very problematic.
        //lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;


        getWindow().setAttributes(lp);
        getWindow().setAttributes(lp);


+14 −5
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region;
import android.inputmethodservice.SoftInputWindow;
import android.inputmethodservice.SoftInputWindow;
import android.os.Binder;
import android.os.Binder;
@@ -32,6 +33,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View;
@@ -262,14 +264,14 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
     */
     */
    public static final class Insets {
    public static final class Insets {
        /**
        /**
         * This is the top part of the UI that is the main content.  It is
         * This is the part of the UI that is the main content.  It is
         * used to determine the basic space needed, to resize/pan the
         * used to determine the basic space needed, to resize/pan the
         * application behind.  It is assumed that this inset does not
         * application behind.  It is assumed that this inset does not
         * change very much, since any change will cause a full resize/pan
         * change very much, since any change will cause a full resize/pan
         * of the application behind.  This value is relative to the top edge
         * of the application behind.  This value is relative to the top edge
         * of the input method window.
         * of the input method window.
         */
         */
        public int contentTopInsets;
        public final Rect contentInsets = new Rect();


        /**
        /**
         * This is the region of the UI that is touchable.  It is used when
         * This is the region of the UI that is touchable.  It is used when
@@ -311,7 +313,8 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
            new ViewTreeObserver.OnComputeInternalInsetsListener() {
            new ViewTreeObserver.OnComputeInternalInsetsListener() {
        public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
        public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
            onComputeInsets(mTmpInsets);
            onComputeInsets(mTmpInsets);
            info.contentInsets.top = info.visibleInsets.top = mTmpInsets.contentTopInsets;
            info.contentInsets.set(mTmpInsets.contentInsets);
            info.visibleInsets.set(mTmpInsets.contentInsets);
            info.touchableRegion.set(mTmpInsets.touchableRegion);
            info.touchableRegion.set(mTmpInsets.touchableRegion);
            info.setTouchableInsets(mTmpInsets.touchableInsets);
            info.setTouchableInsets(mTmpInsets.touchableInsets);
        }
        }
@@ -428,6 +431,8 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
            throw new IllegalStateException("Can't call before onCreate()");
            throw new IllegalStateException("Can't call before onCreate()");
        }
        }
        try {
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            int res = mSystemService.startVoiceActivity(mToken, intent,
            int res = mSystemService.startVoiceActivity(mToken, intent,
                    intent.resolveType(mContext.getContentResolver()));
                    intent.resolveType(mContext.getContentResolver()));
            Instrumentation.checkStartActivityResult(res, intent);
            Instrumentation.checkStartActivityResult(res, intent);
@@ -460,7 +465,8 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
        mInflater = (LayoutInflater)mContext.getSystemService(
        mInflater = (LayoutInflater)mContext.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
                Context.LAYOUT_INFLATER_SERVICE);
        mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
        mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
                mCallbacks, this, mDispatcherState, true);
                mCallbacks, this, mDispatcherState,
                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.TOP, true);
        mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        initViews();
        initViews();
        mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
        mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
@@ -517,7 +523,10 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
        int[] loc = mTmpLocation;
        int[] loc = mTmpLocation;
        View decor = getWindow().getWindow().getDecorView();
        View decor = getWindow().getWindow().getDecorView();
        decor.getLocationInWindow(loc);
        decor.getLocationInWindow(loc);
        outInsets.contentTopInsets = loc[1];
        outInsets.contentInsets.top = 0;
        outInsets.contentInsets.left = 0;
        outInsets.contentInsets.right = 0;
        outInsets.contentInsets.bottom = 0;
        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_FRAME;
        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_FRAME;
        outInsets.touchableRegion.setEmpty();
        outInsets.touchableRegion.setEmpty();
    }
    }
+1 −1
Original line number Original line Diff line number Diff line
@@ -79,7 +79,7 @@ interface IWindowManager
    void removeWindowToken(IBinder token);
    void removeWindowToken(IBinder token);
    void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId,
    void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId,
            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
            int configChanges);
            int configChanges, boolean voiceInteraction);
    void setAppGroupId(IBinder token, int groupId);
    void setAppGroupId(IBinder token, int groupId);
    void setAppOrientation(IApplicationToken token, int requestedOrientation);
    void setAppOrientation(IApplicationToken token, int requestedOrientation);
    int getAppOrientation(IApplicationToken token);
    int getAppOrientation(IApplicationToken token);
Loading