diff options
author | Dianne Hackborn <hackbod@google.com> | 2015-01-14 15:15:34 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2015-01-21 15:07:20 -0800 |
commit | 4e106cedfecd1f6026a79870c2e427853cba7491 (patch) | |
tree | a57b14230a1901e7b3f3e4a9ebed83274b8b5678 | |
parent | 4b94649ce3a57312e7a9bdbb256b5448b5bd8c32 (diff) | |
download | frameworks_base-4e106cedfecd1f6026a79870c2e427853cba7491.zip frameworks_base-4e106cedfecd1f6026a79870c2e427853cba7491.tar.gz frameworks_base-4e106cedfecd1f6026a79870c2e427853cba7491.tar.bz2 |
Bring back voice interaction APIs.
Change-Id: I6039d7c0b188ac342441c56f7d19994b9a80ba17
8 files changed, 94 insertions, 92 deletions
diff --git a/api/current.txt b/api/current.txt index fd45291..76fc820 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3322,6 +3322,7 @@ package android.app { method public int getTaskId(); method public final java.lang.CharSequence getTitle(); method public final int getTitleColor(); + method public android.app.VoiceInteractor getVoiceInteractor(); method public final int getVolumeControlStream(); method public android.view.Window getWindow(); method public android.view.WindowManager getWindowManager(); @@ -3333,6 +3334,7 @@ package android.app { method public boolean isFinishing(); method public boolean isImmersive(); method public boolean isTaskRoot(); + method public boolean isVoiceInteraction(); method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String); method public boolean moveTaskToBack(boolean); method public boolean navigateUpTo(android.content.Intent); @@ -5187,6 +5189,41 @@ package android.app { field public static final int MODE_NIGHT_YES = 2; // 0x2 } + public class VoiceInteractor { + method public boolean submitRequest(android.app.VoiceInteractor.Request); + method public boolean[] supportsCommands(java.lang.String[]); + } + + public static class VoiceInteractor.AbortVoiceRequest extends android.app.VoiceInteractor.Request { + ctor public VoiceInteractor.AbortVoiceRequest(java.lang.CharSequence, android.os.Bundle); + method public void onAbortResult(android.os.Bundle); + } + + public static class VoiceInteractor.CommandRequest extends android.app.VoiceInteractor.Request { + ctor public VoiceInteractor.CommandRequest(java.lang.String, android.os.Bundle); + method public void onCommandResult(boolean, android.os.Bundle); + } + + public static class VoiceInteractor.CompleteVoiceRequest extends android.app.VoiceInteractor.Request { + ctor public VoiceInteractor.CompleteVoiceRequest(java.lang.CharSequence, android.os.Bundle); + method public void onCompleteResult(android.os.Bundle); + } + + public static class VoiceInteractor.ConfirmationRequest extends android.app.VoiceInteractor.Request { + ctor public VoiceInteractor.ConfirmationRequest(java.lang.CharSequence, android.os.Bundle); + method public void onConfirmationResult(boolean, android.os.Bundle); + } + + public static abstract class VoiceInteractor.Request { + ctor public VoiceInteractor.Request(); + method public void cancel(); + method public android.app.Activity getActivity(); + method public android.content.Context getContext(); + method public void onAttached(android.app.Activity); + method public void onCancel(); + method public void onDetached(); + } + public final class WallpaperInfo implements android.os.Parcelable { ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public int describeContents(); @@ -7737,6 +7774,7 @@ package android.content { field public static final java.lang.String CATEGORY_TAB = "android.intent.category.TAB"; field public static final java.lang.String CATEGORY_TEST = "android.intent.category.TEST"; field public static final java.lang.String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST"; + field public static final java.lang.String CATEGORY_VOICE = "android.intent.category.VOICE"; field public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR; field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT"; field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE"; @@ -17768,7 +17806,7 @@ package android.net.http { method public static android.net.http.HttpResponseCache getInstalled(); method public int getNetworkCount(); method public int getRequestCount(); - method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException; + method public static synchronized android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException; method public long maxSize(); method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException; method public long size(); @@ -25506,12 +25544,14 @@ package android.provider { field public static final java.lang.String ACTION_SYNC_SETTINGS = "android.settings.SYNC_SETTINGS"; field public static final java.lang.String ACTION_USAGE_ACCESS_SETTINGS = "android.settings.USAGE_ACCESS_SETTINGS"; field public static final java.lang.String ACTION_USER_DICTIONARY_SETTINGS = "android.settings.USER_DICTIONARY_SETTINGS"; + field public static final java.lang.String ACTION_VOICE_CONTROL_AIRPLANE_MODE = "android.settings.VOICE_CONTROL_AIRPLANE_MODE"; field public static final java.lang.String ACTION_VOICE_INPUT_SETTINGS = "android.settings.VOICE_INPUT_SETTINGS"; field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS"; field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS"; field public static final java.lang.String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS"; field public static final java.lang.String AUTHORITY = "settings"; field public static final java.lang.String EXTRA_ACCOUNT_TYPES = "account_types"; + field public static final java.lang.String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled"; field public static final java.lang.String EXTRA_AUTHORITIES = "authorities"; field public static final java.lang.String EXTRA_INPUT_METHOD_ID = "input_method_id"; } @@ -27461,14 +27501,52 @@ package android.service.voice { ctor public VoiceInteractionSession(android.content.Context); ctor public VoiceInteractionSession(android.content.Context, android.os.Handler); method public void finish(); + method public android.view.LayoutInflater getLayoutInflater(); + method public android.app.Dialog getWindow(); + method public void hideWindow(); + method public void onAbortVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle); + method public void onBackPressed(); + method public abstract void onCancel(android.service.voice.VoiceInteractionSession.Request); method public void onCloseSystemDialogs(); + method public abstract void onCommand(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.String, android.os.Bundle); + method public void onCompleteVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle); + method public void onComputeInsets(android.service.voice.VoiceInteractionSession.Insets); + method public abstract void onConfirm(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle); method public void onCreate(android.os.Bundle); + method public android.view.View onCreateContentView(); method public void onDestroy(); + method public boolean[] onGetSupportedCommands(android.service.voice.VoiceInteractionSession.Caller, java.lang.String[]); method public boolean onKeyDown(int, android.view.KeyEvent); method public boolean onKeyLongPress(int, android.view.KeyEvent); method public boolean onKeyMultiple(int, int, android.view.KeyEvent); method public boolean onKeyUp(int, android.view.KeyEvent); + method public void onTaskFinished(android.content.Intent, int); + method public void onTaskStarted(android.content.Intent, int); method public void setContentView(android.view.View); + method public void setTheme(int); + method public void showWindow(); + method public void startVoiceActivity(android.content.Intent); + } + + public static class VoiceInteractionSession.Caller { + } + + public static final class VoiceInteractionSession.Insets { + ctor public VoiceInteractionSession.Insets(); + 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_REGION = 3; // 0x3 + field public final android.graphics.Rect contentInsets; + field public int touchableInsets; + field public final android.graphics.Region touchableRegion; + } + + public static class VoiceInteractionSession.Request { + method public void sendAbortVoiceResult(android.os.Bundle); + method public void sendCancelResult(); + method public void sendCommandResult(boolean, android.os.Bundle); + method public void sendCompleteVoiceResult(android.os.Bundle); + method public void sendConfirmResult(boolean, android.os.Bundle); } public abstract class VoiceInteractionSessionService extends android.app.Service { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 938a820..23b05c4 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1242,22 +1242,18 @@ public class Activity extends ContextThemeWrapper } /** - * @hide * Check whether this activity is running as part of a voice interaction with the user. * If true, it should perform its interaction with the user through the * {@link VoiceInteractor} returned by {@link #getVoiceInteractor}. */ - @SystemApi public boolean isVoiceInteraction() { return mVoiceInteractor != null; } /** - * @hide * Retrieve the active {@link VoiceInteractor} that the user is going through to * interact with this activity. */ - @SystemApi public VoiceInteractor getVoiceInteractor() { return mVoiceInteractor; } diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java index c225d3a..7f9693f 100644 --- a/core/java/android/app/VoiceInteractor.java +++ b/core/java/android/app/VoiceInteractor.java @@ -16,7 +16,6 @@ package android.app; -import android.annotation.SystemApi; import android.content.Context; import android.os.Bundle; import android.os.IBinder; @@ -34,7 +33,6 @@ import com.android.internal.os.SomeArgs; import java.util.ArrayList; /** - * @hide * Interface for an {@link Activity} to interact with the user through voice. Use * {@link android.app.Activity#getVoiceInteractor() Activity.getVoiceInteractor} * to retrieve the interface, if the activity is currently involved in a voice interaction. @@ -56,7 +54,6 @@ import java.util.ArrayList; * request, rather than holding on to the activity instance yourself, either explicitly * or implicitly through a non-static inner class. */ -@SystemApi public class VoiceInteractor { static final String TAG = "VoiceInteractor"; static final boolean DEBUG = true; @@ -322,7 +319,7 @@ public class VoiceInteractor { * complete an action (e.g. booking a table might have several possible times that the * user could select from or an app might need the user to agree to a terms of service). * The result of the confirmation will be returned through an asynchronous call to - * either {@link #onCommandResult(android.os.Bundle)} or + * either {@link #onCommandResult(boolean, android.os.Bundle)} or * {@link #onCancel()}. * * <p>The command is a string that describes the generic operation to be performed. diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 2fe727c..37a46be 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2808,14 +2808,12 @@ public class Intent implements Parcelable, Cloneable { @SdkConstant(SdkConstantType.INTENT_CATEGORY) public static final String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE"; /** - * @hide * Categories for activities that can participate in voice interaction. * An activity that supports this category must be prepared to run with * no UI shown at all (though in some case it may have a UI shown), and * rely on {@link android.app.VoiceInteractor} to interact with the user. */ @SdkConstant(SdkConstantType.INTENT_CATEGORY) - @SystemApi public static final String CATEGORY_VOICE = "android.intent.category.VOICE"; /** * Set if the activity should be considered as an alternative action to diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 687db7c..e055203 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -18,7 +18,6 @@ package android.provider; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.SystemApi; import android.app.SearchManager; import android.app.WallpaperManager; import android.content.ComponentName; @@ -132,7 +131,6 @@ public final class Settings { "android.settings.AIRPLANE_MODE_SETTINGS"; /** - * @hide * Activity Action: Modify Airplane mode settings using the users voice. * <p> * In some cases, a matching Activity may not exist, so ensure you safeguard against this. @@ -154,7 +152,6 @@ public final class Settings { * Output: Nothing. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - @SystemApi public static final String ACTION_VOICE_CONTROL_AIRPLANE_MODE = "android.settings.VOICE_CONTROL_AIRPLANE_MODE"; @@ -991,13 +988,11 @@ public final class Settings { public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier"; /** - * @hide * Activity Extra: Enable or disable Airplane Mode. * <p> * This can be passed as an extra field to the {@link #ACTION_VOICE_CONTROL_AIRPLANE_MODE} * intent as a boolean. */ - @SystemApi public static final String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled"; private static final String JID_RESOURCE_PREFIX = "android"; diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java index 0cde4f2..65e6988 100644 --- a/core/java/android/service/voice/VoiceInteractionService.java +++ b/core/java/android/service/voice/VoiceInteractionService.java @@ -40,15 +40,16 @@ import java.util.Locale; /** * Top-level service of the current global voice interactor, which is providing - * support for hotwording etc. + * support for hotwording, the back-end of a {@link android.app.VoiceInteractor}, etc. * The current VoiceInteractionService that has been selected by the user is kept * always running by the system, to allow it to do things like listen for hotwords - * in the background. + * in the background to instigate voice interactions. * * <p>Because this service is always running, it should be kept as lightweight as * possible. Heavy-weight operations (including showing UI) should be implemented - * in the associated {@link android.service.voice.VoiceInteractionSessionService} - * that only runs while the operation is active. + * in the associated {@link android.service.voice.VoiceInteractionSessionService} when + * an actual voice interaction is taking place, and that service should run in a + * separate process from this one. */ public class VoiceInteractionService extends Service { /** diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 749f813..19d14bf 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -16,7 +16,6 @@ package android.service.voice; -import android.annotation.SystemApi; import android.app.Dialog; import android.app.Instrumentation; import android.content.Context; @@ -54,7 +53,15 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; /** - * An active interaction session, started by a {@link VoiceInteractionService}. + * An active voice interaction session, providing a facility for the implementation + * to interact with the user in the voice interaction layer. This interface is no shown + * by default, but you can request that it be shown with {@link #showWindow()}, which + * will result in a later call to {@link #onCreateContentView()} in which the UI can be + * built + * + * <p>A voice interaction session can be self-contained, ultimately calling {@link #finish} + * when done. It can also initiate voice interactions with applications by calling + * {@link #startVoiceActivity}</p>. */ public abstract class VoiceInteractionSession implements KeyEvent.Callback { static final String TAG = "VoiceInteractionSession"; @@ -168,10 +175,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } }; - /** - * @hide - */ - @SystemApi public static class Request { final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() { @Override @@ -255,10 +258,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } } - /** - * @hide - */ - @SystemApi public static class Caller { final String packageName; final int uid; @@ -354,10 +353,8 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { final MyCallbacks mCallbacks = new MyCallbacks(); /** - * @hide * Information about where interesting parts of the input method UI appear. */ - @SystemApi public static final class Insets { /** * This is the part of the UI that is the main content. It is @@ -477,10 +474,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content); } - /** - * @hide - */ - @SystemApi public void showWindow() { if (DEBUG) Log.v(TAG, "Showing window: mWindowAdded=" + mWindowAdded + " mWindowVisible=" + mWindowVisible); @@ -509,10 +502,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } } - /** - * @hide - */ - @SystemApi public void hideWindow() { if (mWindowVisible) { mWindow.hide(); @@ -521,13 +510,11 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide * You can call this to customize the theme used by your IME's window. * This must be set before {@link #onCreate}, so you * will typically call it in your constructor with the resource ID * of your custom theme. */ - @SystemApi public void setTheme(int theme) { if (mWindow != null) { throw new IllegalStateException("Must be called before onCreate()"); @@ -536,7 +523,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide * Ask that a new activity be started for voice interaction. This will create a * new dedicated task in the activity manager for this voice interaction session; * this means that {@link Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK} @@ -557,7 +543,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { * always have {@link Intent#CATEGORY_VOICE Intent.CATEGORY_VOICE} added to it, since * this is part of a voice interaction. */ - @SystemApi public void startVoiceActivity(Intent intent) { if (mToken == null) { throw new IllegalStateException("Can't call before onCreate()"); @@ -573,19 +558,15 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide * Convenience for inflating views. */ - @SystemApi public LayoutInflater getLayoutInflater() { return mInflater; } /** - * @hide * Retrieve the window being used to show the session's UI. */ - @SystemApi public Dialog getWindow() { return mWindow; } @@ -631,10 +612,8 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide * Hook in which to create the session's UI. */ - @SystemApi public View onCreateContentView() { return null; } @@ -647,42 +626,22 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } - /** - * @hide - */ - @SystemApi public boolean onKeyDown(int keyCode, KeyEvent event) { return false; } - /** - * @hide - */ - @SystemApi public boolean onKeyLongPress(int keyCode, KeyEvent event) { return false; } - /** - * @hide - */ - @SystemApi public boolean onKeyUp(int keyCode, KeyEvent event) { return false; } - /** - * @hide - */ - @SystemApi public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) { return false; } - /** - * @hide - */ - @SystemApi public void onBackPressed() { finish(); } @@ -697,14 +656,12 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide * Compute the interesting insets into your UI. The default implementation * uses the entire window frame as the insets. The default touchable * insets are {@link Insets#TOUCHABLE_INSETS_FRAME}. * * @param outInsets Fill in with the current UI insets. */ - @SystemApi public void onComputeInsets(Insets outInsets) { int[] loc = mTmpLocation; View decor = getWindow().getWindow().getDecorView(); @@ -718,8 +675,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide - * @SystemApi * Called when a task initiated by {@link #startVoiceActivity(android.content.Intent)} * has actually started. * @@ -731,8 +686,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide - * @SystemApi * Called when the last activity of a task initiated by * {@link #startVoiceActivity(android.content.Intent)} has finished. The default * implementation calls {@link #finish()} on the assumption that this represents @@ -748,8 +701,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide - * @SystemApi * Request to query for what extended commands the session supports. * * @param caller Who is making the request. @@ -764,8 +715,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide - * @SystemApi * Request to confirm with the user before proceeding with an unrecoverable operation, * corresponding to a {@link android.app.VoiceInteractor.ConfirmationRequest * VoiceInteractor.ConfirmationRequest}. @@ -781,8 +730,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { Bundle extras); /** - * @hide - * @SystemApi * Request to complete the voice interaction session because the voice activity successfully * completed its interaction using voice. Corresponds to * {@link android.app.VoiceInteractor.CompleteVoiceRequest @@ -804,8 +751,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide - * @SystemApi * Request to abort the voice interaction session because the voice activity can not * complete its interaction using voice. Corresponds to * {@link android.app.VoiceInteractor.AbortVoiceRequest @@ -824,8 +769,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { } /** - * @hide - * @SystemApi * Process an arbitrary extended command from the caller, * corresponding to a {@link android.app.VoiceInteractor.CommandRequest * VoiceInteractor.CommandRequest}. @@ -840,8 +783,6 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback { public abstract void onCommand(Caller caller, Request request, String command, Bundle extras); /** - * @hide - * @SystemApi * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request} * that was previously delivered to {@link #onConfirm} or {@link #onCommand}. * diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index f5d4867..c32ba67 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -39,7 +39,6 @@ import android.os.Handler; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; -import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.service.voice.IVoiceInteractionService; @@ -426,9 +425,6 @@ public class VoiceInteractionManagerService extends SystemService { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); - if (!SystemProperties.getBoolean("persist.test.voice_interaction", false)) { - throw new SecurityException("Voice interaction not supported"); - } try { return mImpl.startVoiceActivityLocked(callingPid, callingUid, token, intent, resolvedType); |