am f702286c: Merge "Remove HotwordRecognition APIs" into klp-dev
* commit 'f702286c94f0df9fc147135c19f12ef34e8594c9': Remove HotwordRecognition APIs
This commit is contained in:
@@ -195,8 +195,6 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/view/IWindowSession.aidl \
|
||||
core/java/android/speech/IRecognitionListener.aidl \
|
||||
core/java/android/speech/IRecognitionService.aidl \
|
||||
core/java/android/speech/hotword/IHotwordRecognitionListener.aidl \
|
||||
core/java/android/speech/hotword/IHotwordRecognitionService.aidl \
|
||||
core/java/android/speech/tts/ITextToSpeechCallback.aidl \
|
||||
core/java/android/speech/tts/ITextToSpeechService.aidl \
|
||||
core/java/com/android/internal/app/IAppOpsCallback.aidl \
|
||||
|
||||
@@ -22805,35 +22805,6 @@ package android.speech {
|
||||
|
||||
}
|
||||
|
||||
package android.speech.hotword {
|
||||
|
||||
public abstract class HotwordRecognitionService extends android.app.Service {
|
||||
ctor public HotwordRecognitionService();
|
||||
method public android.os.IBinder onBind(android.content.Intent);
|
||||
method public abstract void onStartHotwordRecognition(android.speech.hotword.HotwordRecognitionService.Callback);
|
||||
method public abstract void onStopHotwordRecognition();
|
||||
field public static final int ERROR_AUDIO = 1; // 0x1
|
||||
field public static final int ERROR_CLIENT = 4; // 0x4
|
||||
field public static final int ERROR_FAILED = 3; // 0x3
|
||||
field public static final int ERROR_RECOGNIZER_BUSY = 2; // 0x2
|
||||
field public static final int ERROR_SERVICE_ALREADY_STARTED = 6; // 0x6
|
||||
field public static final int ERROR_TIMEOUT = 5; // 0x5
|
||||
field public static final int ERROR_UNAVAILABLE = 7; // 0x7
|
||||
field public static final int EVENT_TYPE_PROMPT_CHANGED = 1; // 0x1
|
||||
field public static final java.lang.String KEY_PROMPT_TEXT = "prompt_text";
|
||||
field public static final java.lang.String SERVICE_INTERFACE = "android.speech.hotword.HotwordRecognitionService";
|
||||
}
|
||||
|
||||
public static class HotwordRecognitionService.Callback {
|
||||
method public void onError(int) throws android.os.RemoteException;
|
||||
method public void onHotwordEvent(int, android.os.Bundle) throws android.os.RemoteException;
|
||||
method public void onHotwordRecognitionStarted() throws android.os.RemoteException;
|
||||
method public void onHotwordRecognitionStopped() throws android.os.RemoteException;
|
||||
method public void onHotwordRecognized(android.content.Intent) throws android.os.RemoteException;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.speech.tts {
|
||||
|
||||
public abstract interface SynthesisCallback {
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package android.speech.hotword;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Used for receiving notifications from the HotwordRecognitionService when the
|
||||
* hotword recognition related events occur.
|
||||
* All the callbacks are executed on the application main thread.
|
||||
* {@hide}
|
||||
*/
|
||||
public interface HotwordRecognitionListener {
|
||||
/**
|
||||
* Called when the service starts listening for hotword.
|
||||
*/
|
||||
void onHotwordRecognitionStarted();
|
||||
|
||||
/**
|
||||
* Called when the service stops listening for hotword.
|
||||
*/
|
||||
void onHotwordRecognitionStopped();
|
||||
|
||||
/**
|
||||
* Called on an event of interest to the client.
|
||||
*
|
||||
* @param eventType the event type.
|
||||
* @param eventBundle a Bundle containing the hotword event(s).
|
||||
*/
|
||||
void onHotwordEvent(int eventType, Bundle eventBundle);
|
||||
|
||||
/**
|
||||
* Called back when hotword is detected.
|
||||
*
|
||||
* @param intent for the activity to launch, post hotword detection.
|
||||
*/
|
||||
void onHotwordRecognized(Intent intent);
|
||||
|
||||
/**
|
||||
* Called when the HotwordRecognitionService encounters an error.
|
||||
*
|
||||
* @param errorCode the error code describing the error that was encountered.
|
||||
*/
|
||||
void onHotwordError(int errorCode);
|
||||
}
|
||||
@@ -1,287 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package android.speech.hotword;
|
||||
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* This class provides a base class for hotword detection service implementations.
|
||||
* This class should be extended only if you wish to implement a new hotword recognizer.
|
||||
*/
|
||||
public abstract class HotwordRecognitionService extends Service {
|
||||
/**
|
||||
* The {@link Intent} that must be declared as handled by the service.
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.SERVICE_ACTION)
|
||||
public static final String SERVICE_INTERFACE =
|
||||
"android.speech.hotword.HotwordRecognitionService";
|
||||
|
||||
/** Log messages identifier */
|
||||
private static final String TAG = "HotwordRecognitionService";
|
||||
|
||||
/** Debugging flag */
|
||||
private static final boolean DBG = false;
|
||||
|
||||
/**
|
||||
* Key used to retrieve a string to be displayed to the user.
|
||||
*/
|
||||
public static final String KEY_PROMPT_TEXT = "prompt_text";
|
||||
|
||||
/**
|
||||
* Event type used to indicate to the user that the prompt for
|
||||
* hotword recognition has changed.
|
||||
*/
|
||||
public static final int EVENT_TYPE_PROMPT_CHANGED = 1;
|
||||
|
||||
/** Audio recording error. */
|
||||
public static final int ERROR_AUDIO = 1;
|
||||
|
||||
/** RecognitionService busy. */
|
||||
public static final int ERROR_RECOGNIZER_BUSY = 2;
|
||||
|
||||
/** This indicates a permanent failure and the clients shouldn't retry on this */
|
||||
public static final int ERROR_FAILED = 3;
|
||||
|
||||
/** Client-side errors */
|
||||
public static final int ERROR_CLIENT = 4;
|
||||
|
||||
/** The service timed out */
|
||||
public static final int ERROR_TIMEOUT = 5;
|
||||
|
||||
/** The service received concurrent start calls */
|
||||
public static final int ERROR_SERVICE_ALREADY_STARTED = 6;
|
||||
|
||||
/** Hotword recognition is unavailable on the device */
|
||||
public static final int ERROR_UNAVAILABLE = 7;
|
||||
|
||||
private static final int MSG_START_RECOGNITION = 1;
|
||||
private static final int MSG_STOP_RECOGNITION = 2;
|
||||
|
||||
/**
|
||||
* The current callback of an application that invoked the
|
||||
* {@link HotwordRecognitionService#onStartHotwordRecognition(Callback)} method
|
||||
*/
|
||||
private Callback mCurrentCallback = null;
|
||||
|
||||
// Handle the client dying.
|
||||
private final IBinder.DeathRecipient mCallbackDeathRecipient = new IBinder.DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
if (DBG) Log.i(TAG, "HotwordRecognitionService listener died");
|
||||
mCurrentCallback = null;
|
||||
}
|
||||
};
|
||||
|
||||
private final Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_START_RECOGNITION:
|
||||
dispatchStartRecognition((IHotwordRecognitionListener) msg.obj);
|
||||
break;
|
||||
case MSG_STOP_RECOGNITION:
|
||||
dispatchStopRecognition((IHotwordRecognitionListener) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** Binder of the hotword recognition service */
|
||||
private RecognitionServiceBinder mBinder = new RecognitionServiceBinder(this);
|
||||
|
||||
private void dispatchStartRecognition(IHotwordRecognitionListener listener) {
|
||||
if (mCurrentCallback == null) {
|
||||
if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder());
|
||||
try {
|
||||
listener.asBinder().linkToDeath(mCallbackDeathRecipient, 0);
|
||||
} catch (RemoteException e) {
|
||||
if (DBG) Log.d(TAG, "listener died before linkToDeath()");
|
||||
}
|
||||
mCurrentCallback = new Callback(listener);
|
||||
HotwordRecognitionService.this.onStartHotwordRecognition(mCurrentCallback);
|
||||
} else {
|
||||
try {
|
||||
listener.onHotwordError(ERROR_RECOGNIZER_BUSY);
|
||||
} catch (RemoteException e) {
|
||||
if (DBG) Log.d(TAG, "onError call from startRecognition failed");
|
||||
}
|
||||
if (DBG) Log.d(TAG, "concurrent startRecognition received - ignoring this call");
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchStopRecognition(IHotwordRecognitionListener listener) {
|
||||
try {
|
||||
if (mCurrentCallback == null) {
|
||||
listener.onHotwordError(ERROR_CLIENT);
|
||||
Log.w(TAG, "stopRecognition called with no preceding startRecognition - ignoring");
|
||||
} else if (mCurrentCallback.mListener.asBinder() != listener.asBinder()) {
|
||||
listener.onHotwordError(ERROR_RECOGNIZER_BUSY);
|
||||
Log.w(TAG, "stopRecognition called by a different caller - ignoring");
|
||||
} else { // the correct state
|
||||
mCurrentCallback.onHotwordRecognitionStopped();
|
||||
mCurrentCallback = null;
|
||||
HotwordRecognitionService.this.onStopHotwordRecognition();
|
||||
}
|
||||
} catch (RemoteException e) { // occurs if onError fails
|
||||
if (DBG) Log.d(TAG, "onError call from stopRecognition failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(final Intent intent) {
|
||||
if (DBG) Log.d(TAG, "onBind, intent=" + intent);
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (DBG) Log.d(TAG, "onDestroy");
|
||||
if (mCurrentCallback != null) {
|
||||
mCurrentCallback.mListener.asBinder().unlinkToDeath(mCallbackDeathRecipient, 0);
|
||||
mCurrentCallback = null;
|
||||
}
|
||||
mBinder.clearReference();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the service to start a recognition.
|
||||
*
|
||||
* @param callback that receives the callbacks from the service.
|
||||
*/
|
||||
public abstract void onStartHotwordRecognition(Callback callback);
|
||||
|
||||
/**
|
||||
* Notifies the service to stop recognition.
|
||||
*/
|
||||
public abstract void onStopHotwordRecognition();
|
||||
|
||||
/** Binder of the hotword recognition service */
|
||||
private static class RecognitionServiceBinder extends IHotwordRecognitionService.Stub {
|
||||
private HotwordRecognitionService mInternalService;
|
||||
|
||||
public RecognitionServiceBinder(HotwordRecognitionService service) {
|
||||
mInternalService = service;
|
||||
}
|
||||
|
||||
public void startHotwordRecognition(IHotwordRecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "startRecognition called by: " + listener.asBinder());
|
||||
if (mInternalService != null && mInternalService.checkPermissions(listener)) {
|
||||
mInternalService.mHandler.sendMessage(
|
||||
Message.obtain(mInternalService.mHandler, MSG_START_RECOGNITION, listener));
|
||||
}
|
||||
}
|
||||
|
||||
public void stopHotwordRecognition(IHotwordRecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "stopRecognition called by: " + listener.asBinder());
|
||||
if (mInternalService != null && mInternalService.checkPermissions(listener)) {
|
||||
mInternalService.mHandler.sendMessage(
|
||||
Message.obtain(mInternalService.mHandler, MSG_STOP_RECOGNITION, listener));
|
||||
}
|
||||
}
|
||||
|
||||
private void clearReference() {
|
||||
mInternalService = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the caller has sufficient permissions
|
||||
*
|
||||
* @param listener to send the error message to in case of error.
|
||||
* @return {@code true} if the caller has enough permissions, {@code false} otherwise.
|
||||
*/
|
||||
private boolean checkPermissions(IHotwordRecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "checkPermissions");
|
||||
if (checkCallingOrSelfPermission(android.Manifest.permission.HOTWORD_RECOGNITION) ==
|
||||
PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
Log.e(TAG, "Recognition service called without HOTWORD_RECOGNITION permissions");
|
||||
listener.onHotwordError(ERROR_FAILED);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "onHotwordError(ERROR_FAILED) message failed", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class acts passes on the callbacks received from the Hotword service
|
||||
* to the listener.
|
||||
*/
|
||||
public static class Callback {
|
||||
private final IHotwordRecognitionListener mListener;
|
||||
|
||||
private Callback(IHotwordRecognitionListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the service starts listening for hotword.
|
||||
*/
|
||||
public void onHotwordRecognitionStarted() throws RemoteException {
|
||||
mListener.onHotwordRecognitionStarted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the service starts listening for hotword.
|
||||
*/
|
||||
public void onHotwordRecognitionStopped() throws RemoteException {
|
||||
mListener.onHotwordRecognitionStopped();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on an event of interest to the client.
|
||||
*
|
||||
* @param eventType the event type.
|
||||
* @param eventBundle a Bundle containing the hotword event(s).
|
||||
*/
|
||||
public void onHotwordEvent(int eventType, Bundle eventBundle) throws RemoteException {
|
||||
mListener.onHotwordEvent(eventType, eventBundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called back when hotword is detected.
|
||||
*
|
||||
* @param activityIntent for the activity to launch, post hotword detection.
|
||||
*/
|
||||
public void onHotwordRecognized(Intent activityIntent) throws RemoteException {
|
||||
mListener.onHotwordRecognized(activityIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the HotwordRecognitionService encounters an error.
|
||||
*
|
||||
* @param errorCode the error code describing the error that was encountered.
|
||||
*/
|
||||
public void onError(int errorCode) throws RemoteException {
|
||||
mListener.onHotwordError(errorCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package android.speech.hotword;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* This class provides access to the Hotword recognition service.
|
||||
* This class's methods must be invoked on the main application thread.
|
||||
* {@hide}
|
||||
*/
|
||||
public class HotwordRecognizer {
|
||||
/** DEBUG value to enable verbose debug prints */
|
||||
private final static boolean DBG = false;
|
||||
|
||||
/** Log messages identifier */
|
||||
private static final String TAG = "HotwordRecognizer";
|
||||
|
||||
/** action codes */
|
||||
private static final int MSG_START = 1;
|
||||
private static final int MSG_STOP = 2;
|
||||
|
||||
/** The underlying HotwordRecognitionService endpoint */
|
||||
private IHotwordRecognitionService mService;
|
||||
|
||||
/** The connection to the actual service */
|
||||
private Connection mConnection;
|
||||
|
||||
/** Context with which the manager was created */
|
||||
private final Context mContext;
|
||||
|
||||
/** Component to direct service intent to */
|
||||
private final ComponentName mServiceComponent;
|
||||
|
||||
/** Handler that will execute the main tasks */
|
||||
private Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_START:
|
||||
handleStartRecognition();
|
||||
break;
|
||||
case MSG_STOP:
|
||||
handleStopRecognition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Temporary queue, saving the messages until the connection will be established, afterwards,
|
||||
* only mHandler will receive the messages
|
||||
*/
|
||||
private final Queue<Message> mPendingTasks = new LinkedList<Message>();
|
||||
|
||||
/** The Listener that will receive all the callbacks */
|
||||
private final InternalListener mListener = new InternalListener();
|
||||
|
||||
/**
|
||||
* Checks whether a hotword recognition service is available on the system. If this method
|
||||
* returns {@code false}, {@link HotwordRecognizer#createHotwordRecognizer(Context)} will
|
||||
* fail.
|
||||
*
|
||||
* @param context with which {@code HotwordRecognizer} will be created
|
||||
* @return {@code true} if recognition is available, {@code false} otherwise
|
||||
*/
|
||||
public static boolean isHotwordRecognitionAvailable(final Context context) {
|
||||
final List<ResolveInfo> list = context.getPackageManager().queryIntentServices(
|
||||
new Intent(HotwordRecognitionService.SERVICE_INTERFACE), 0);
|
||||
return list != null && list.size() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@code HotwordRecognizer}.
|
||||
*
|
||||
* @param context in which to create {@code HotwordRecognizer}
|
||||
* @return a new {@code HotwordRecognizer}
|
||||
*/
|
||||
public static HotwordRecognizer createHotwordRecognizer(final Context context) {
|
||||
ComponentName serviceComponent = null;
|
||||
// Resolve to a default ComponentName.
|
||||
final List<ResolveInfo> list = context.getPackageManager().queryIntentServices(
|
||||
new Intent(HotwordRecognitionService.SERVICE_INTERFACE), 0);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
final ResolveInfo ri = list.get(i);
|
||||
if (!ri.serviceInfo.enabled) {
|
||||
continue;
|
||||
}
|
||||
if ((ri.serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM)
|
||||
!= PackageManager.MATCH_DEFAULT_ONLY) {
|
||||
serviceComponent = new ComponentName(
|
||||
ri.serviceInfo.packageName, ri.serviceInfo.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If all else fails, pick the first one.
|
||||
if (serviceComponent == null && !list.isEmpty()) {
|
||||
serviceComponent = new ComponentName(
|
||||
list.get(0).serviceInfo.packageName, list.get(0).serviceInfo.name);
|
||||
}
|
||||
return createHotwordRecognizer(context, serviceComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@code HotwordRecognizer}.
|
||||
*
|
||||
* Use this version of the method to specify a specific service to direct this
|
||||
* {@link HotwordRecognizer} to. Normally you would not use this; use
|
||||
* {@link #createHotwordRecognizer(Context)} instead to use the system default recognition
|
||||
* service.
|
||||
*
|
||||
* @param context in which to create {@code HotwordRecognizer}
|
||||
* @param serviceComponent the {@link ComponentName} of a specific service to direct this
|
||||
* {@code HotwordRecognizer} to
|
||||
* @return a new {@code HotwordRecognizer}
|
||||
*/
|
||||
public static HotwordRecognizer createHotwordRecognizer(
|
||||
final Context context, final ComponentName serviceComponent) {
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("Context cannot be null)");
|
||||
}
|
||||
checkIsCalledFromMainThread();
|
||||
return new HotwordRecognizer(context, serviceComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts recognizing hotword and sets the listener that will receive the callbacks.
|
||||
*
|
||||
* @param listener listener that will receive all the callbacks from the created
|
||||
* {@link HotwordRecognizer}, this must not be null.
|
||||
*/
|
||||
public void startRecognition(HotwordRecognitionListener listener) {
|
||||
checkIsCalledFromMainThread();
|
||||
if (mConnection == null) { // first time connection
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener must not be null");
|
||||
}
|
||||
|
||||
mConnection = new Connection();
|
||||
Intent serviceIntent = new Intent(HotwordRecognitionService.SERVICE_INTERFACE);
|
||||
mListener.mInternalListener = listener;
|
||||
|
||||
if (mServiceComponent == null) {
|
||||
Log.e(TAG, "no selected voice recognition service");
|
||||
mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT);
|
||||
return;
|
||||
} else {
|
||||
serviceIntent.setComponent(mServiceComponent);
|
||||
}
|
||||
|
||||
if (!mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) {
|
||||
Log.e(TAG, "bind to recognition service failed");
|
||||
mConnection = null;
|
||||
mService = null;
|
||||
mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT);
|
||||
return;
|
||||
}
|
||||
putMessage(Message.obtain(mHandler, MSG_START));
|
||||
} else {
|
||||
mListener.onHotwordError(HotwordRecognitionService.ERROR_SERVICE_ALREADY_STARTED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops recognizing hotword.
|
||||
*/
|
||||
public void stopRecognition() {
|
||||
checkIsCalledFromMainThread();
|
||||
putMessage(Message.obtain(mHandler, MSG_STOP));
|
||||
}
|
||||
|
||||
// Private constructor.
|
||||
private HotwordRecognizer(Context context, ComponentName serviceComponent) {
|
||||
mContext = context;
|
||||
mServiceComponent = serviceComponent;
|
||||
}
|
||||
|
||||
private void handleStartRecognition() {
|
||||
if (!checkOpenConnection()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.startHotwordRecognition(mListener);
|
||||
if (DBG) Log.d(TAG, "service startRecognition command succeeded");
|
||||
} catch (final RemoteException e) {
|
||||
Log.e(TAG, "startRecognition() failed", e);
|
||||
mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleStopRecognition() {
|
||||
if (!checkOpenConnection()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.stopHotwordRecognition(mListener);
|
||||
if (mConnection != null) {
|
||||
mContext.unbindService(mConnection);
|
||||
}
|
||||
if (DBG) Log.d(TAG, "service stopRecognition command succeeded");
|
||||
} catch (final RemoteException e) {
|
||||
Log.e(TAG, "stopRecognition() failed", e);
|
||||
mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT);
|
||||
} finally {
|
||||
mPendingTasks.clear();
|
||||
mService = null;
|
||||
mConnection = null;
|
||||
mListener.mInternalListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkOpenConnection() {
|
||||
if (mService != null) {
|
||||
return true;
|
||||
}
|
||||
mListener.onHotwordError(HotwordRecognitionService.ERROR_CLIENT);
|
||||
Log.e(TAG, "not connected to the recognition service");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void checkIsCalledFromMainThread() {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new RuntimeException(
|
||||
"HotwordRecognizer should be used only from the application's main thread");
|
||||
}
|
||||
}
|
||||
|
||||
private void putMessage(Message msg) {
|
||||
if (mService == null) {
|
||||
mPendingTasks.offer(msg);
|
||||
} else {
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic ServiceConnection that records the mService variable.
|
||||
* Additionally, on creation it invokes
|
||||
* {@link IHotwordRecognitionService#startHotwordRecognition(IHotwordRecognitionListener)}.
|
||||
*/
|
||||
private class Connection implements ServiceConnection {
|
||||
|
||||
public void onServiceConnected(final ComponentName name, final IBinder service) {
|
||||
// always done on the application main thread, so no need to send message to mHandler
|
||||
mService = IHotwordRecognitionService.Stub.asInterface(service);
|
||||
if (DBG) Log.d(TAG, "onServiceConnected - Success");
|
||||
while (!mPendingTasks.isEmpty()) {
|
||||
mHandler.sendMessage(mPendingTasks.poll());
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(final ComponentName name) {
|
||||
// always done on the application main thread, so no need to send message to mHandler
|
||||
mService = null;
|
||||
mConnection = null;
|
||||
mPendingTasks.clear();
|
||||
if (DBG) Log.d(TAG, "onServiceDisconnected - Success");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal wrapper of IHotwordRecognitionListener which will propagate the results to
|
||||
* HotwordRecognitionListener.
|
||||
*/
|
||||
private class InternalListener extends IHotwordRecognitionListener.Stub {
|
||||
private HotwordRecognitionListener mInternalListener;
|
||||
|
||||
private final static int MSG_ON_START = 1;
|
||||
private final static int MSG_ON_STOP = 2;
|
||||
private final static int MSG_ON_EVENT = 3;
|
||||
private final static int MSG_ON_RECOGNIZED = 4;
|
||||
private final static int MSG_ON_ERROR = 5;
|
||||
|
||||
private final Handler mInternalHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (mInternalListener == null) {
|
||||
return;
|
||||
}
|
||||
switch (msg.what) {
|
||||
case MSG_ON_START:
|
||||
mInternalListener.onHotwordRecognitionStarted();
|
||||
break;
|
||||
case MSG_ON_STOP:
|
||||
mInternalListener.onHotwordRecognitionStopped();
|
||||
break;
|
||||
case MSG_ON_EVENT:
|
||||
mInternalListener.onHotwordEvent(msg.arg1, (Bundle) msg.obj);
|
||||
break;
|
||||
case MSG_ON_RECOGNIZED:
|
||||
mInternalListener.onHotwordRecognized((Intent) msg.obj);
|
||||
break;
|
||||
case MSG_ON_ERROR:
|
||||
mInternalListener.onHotwordError((Integer) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onHotwordRecognitionStarted() throws RemoteException {
|
||||
Message.obtain(mInternalHandler, MSG_ON_START).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHotwordRecognitionStopped() throws RemoteException {
|
||||
Message.obtain(mInternalHandler, MSG_ON_STOP).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHotwordEvent(final int eventType, final Bundle params) {
|
||||
Message.obtain(mInternalHandler, MSG_ON_EVENT, eventType, eventType, params)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHotwordRecognized(Intent activityIntent) throws RemoteException {
|
||||
Message.obtain(mInternalHandler, MSG_ON_RECOGNIZED, activityIntent)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHotwordError(final int error) {
|
||||
Message.obtain(mInternalHandler, MSG_ON_ERROR, error).sendToTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.speech.hotword;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Listener for hotword detection events.
|
||||
* This indicates when the hotword was detected, and also notifies the
|
||||
* client of the intermediate events that may be used to show visual feedback
|
||||
* to the user.
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IHotwordRecognitionListener {
|
||||
/**
|
||||
* Called when the service starts listening for hotword.
|
||||
*/
|
||||
void onHotwordRecognitionStarted();
|
||||
|
||||
/**
|
||||
* Called when the service starts listening for hotword.
|
||||
*/
|
||||
void onHotwordRecognitionStopped();
|
||||
|
||||
/**
|
||||
* Called on an event of interest to the client.
|
||||
*
|
||||
* @param eventType the event type.
|
||||
* @param eventBundle a Bundle containing the hotword event(s).
|
||||
*/
|
||||
void onHotwordEvent(in int eventType, in Bundle eventBundle);
|
||||
|
||||
/**
|
||||
* Called back when hotword is detected.
|
||||
*
|
||||
* @param intent for the activity to launch, post hotword detection.
|
||||
*/
|
||||
void onHotwordRecognized(in Intent intent);
|
||||
|
||||
/**
|
||||
* Called when the HotwordRecognitionService encounters an error.
|
||||
*
|
||||
* @param errorCode the error code describing the error that was encountered.
|
||||
*/
|
||||
void onHotwordError(in int errorCode);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.speech.hotword;
|
||||
|
||||
import android.speech.hotword.IHotwordRecognitionListener;
|
||||
|
||||
/**
|
||||
* A service interface to Hotword recognition.
|
||||
* Call startHotwordDetection with a listener when you want to begin detecting
|
||||
* hotword;
|
||||
* The service would automatically stop detection when hotword is detected;
|
||||
* So it's a create-once use-once service.
|
||||
* The service doesn't support nested calls to start detection and disallows them.
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IHotwordRecognitionService {
|
||||
/**
|
||||
* Start hotword recognition.
|
||||
* The clients should rely on the callback to figure out if the detection was
|
||||
* started.
|
||||
*
|
||||
* @param listener a listener to notify of hotword events.
|
||||
*/
|
||||
void startHotwordRecognition(in IHotwordRecognitionListener listener);
|
||||
|
||||
/**
|
||||
* Stop hotword recognition.
|
||||
* Stops the recognition only if it was started by the same caller.
|
||||
*
|
||||
* @param listener a listener to notify of hotword events.
|
||||
*/
|
||||
void stopHotwordRecognition(in IHotwordRecognitionListener listener);
|
||||
}
|
||||
@@ -2444,13 +2444,6 @@
|
||||
android:description="@string/permdesc_accessNetworkConditions"
|
||||
android:protectionLevel="signature|system" />
|
||||
|
||||
<!-- Allows an application to request HotwordRecognition.
|
||||
@hide This is not a third-party API (intended for system apps). -->
|
||||
<permission android:name="android.permission.HOTWORD_RECOGNITION"
|
||||
android:label="@string/permlab_hotwordRecognition"
|
||||
android:description="@string/permdesc_hotwordRecognition"
|
||||
android:protectionLevel="signature|system" />
|
||||
|
||||
<!-- The system process is explicitly the only one allowed to launch the
|
||||
confirmation UI for full backup/restore -->
|
||||
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
|
||||
|
||||
@@ -1911,11 +1911,6 @@
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permdesc_accessNetworkConditions">Allows an application to listen for observations on network conditions. Should never be needed for normal apps.</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_hotwordRecognition">request hotword recognition</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permdesc_hotwordRecognition">Allows an application to request for hotword recognition. Should never be needed for normal apps.</string>
|
||||
|
||||
<!-- Policy administration -->
|
||||
|
||||
<!-- Title of policy access to limiting the user's password choices -->
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
|
||||
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
|
||||
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
|
||||
<!-- Permission to perform hotword recognition -->
|
||||
<uses-permission android:name="android.permission.HOTWORD_RECOGNITION" />
|
||||
|
||||
<application android:label="@string/app_name"
|
||||
android:process="com.android.systemui"
|
||||
|
||||
@@ -49,9 +49,6 @@ import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.speech.hotword.HotwordRecognitionListener;
|
||||
import android.speech.hotword.HotwordRecognitionService;
|
||||
import android.speech.hotword.HotwordRecognizer;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@@ -69,10 +66,6 @@ import java.util.List;
|
||||
|
||||
public class KeyguardHostView extends KeyguardViewBase {
|
||||
private static final String TAG = "KeyguardHostView";
|
||||
// Don't enable hotword on limited-memory devices.
|
||||
private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic();
|
||||
// Indicates if hotword is enabled, should it also be available on secure keyguard(s).
|
||||
private static final boolean ENABLE_HOTWORD_SECURE = false;
|
||||
|
||||
// Transport control states.
|
||||
static final int TRANSPORT_GONE = 0;
|
||||
@@ -88,13 +81,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
// Found in KeyguardAppWidgetPickActivity.java
|
||||
static final int APPWIDGET_HOST_ID = 0x4B455947;
|
||||
|
||||
// TODO: Fix this to be non-static.
|
||||
// We need to be careful here to make stopRecognition calls on the same instance
|
||||
// that started it. Since KeyguardHostView is a view, it keeps getting
|
||||
// recreated every now and then, and unless we figure out a better way,
|
||||
// this needs to be a static field.
|
||||
private static HotwordRecognizer sHotwordClient;
|
||||
|
||||
private final int MAX_WIDGETS = 5;
|
||||
|
||||
private AppWidgetHost mAppWidgetHost;
|
||||
@@ -218,11 +204,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
|
||||
Log.v(TAG, "Keyguard secure camera disabled by DPM");
|
||||
}
|
||||
|
||||
// Create Hotword recognizer, for the first time.
|
||||
if (ENABLE_HOTWORD && sHotwordClient == null) {
|
||||
sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext());
|
||||
}
|
||||
}
|
||||
|
||||
private void getInitialTransportState() {
|
||||
@@ -320,21 +301,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onPhoneStateChanged(int phoneState) {
|
||||
// We need to stop hotword detection when a call state is not idle anymore.
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)
|
||||
&& TelephonyManager.CALL_STATE_IDLE != phoneState) {
|
||||
if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle");
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onUserSwitching(int userId) {
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static final boolean isMusicPlaying(int playbackState) {
|
||||
@@ -818,9 +784,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
// If the alternate unlock was suppressed, it can now be safely
|
||||
// enabled because the user has left keyguard.
|
||||
KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)){
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
|
||||
// If there's a pending runnable because the user interacted with a widget
|
||||
// and we're leaving keyguard, then run it.
|
||||
@@ -985,9 +948,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
|
||||
// Emulate Activity life cycle
|
||||
if (oldView != null) {
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
oldView.onPause();
|
||||
oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
|
||||
}
|
||||
@@ -1041,11 +1001,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
mViewStateManager.showUsabilityHints();
|
||||
}
|
||||
|
||||
// Start hotword detection on insecure Keyguard.
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
|
||||
maybeStartHotwordDetector();
|
||||
}
|
||||
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
@@ -1068,11 +1023,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
cameraPage.onScreenTurnedOff();
|
||||
}
|
||||
|
||||
// Stop hotword detection on insecure Keyguard.
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
|
||||
clearFocus();
|
||||
}
|
||||
|
||||
@@ -1157,9 +1107,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
new CameraWidgetFrame.Callbacks() {
|
||||
@Override
|
||||
public void onLaunchingCamera() {
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
setSliderHandleAlpha(0);
|
||||
}
|
||||
|
||||
@@ -1689,9 +1636,6 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
}
|
||||
|
||||
public void showAssistant() {
|
||||
if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
|
||||
|
||||
@@ -1706,125 +1650,4 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
mActivityLauncher.launchActivityWithAnimation(
|
||||
intent, false, opts.toBundle(), null, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start the hotword detector if:
|
||||
* <li> ENABLE_HOTWORD is true and
|
||||
* <li> Hotword detection is not already running and
|
||||
* <li> TelephonyManager is in CALL_STATE_IDLE
|
||||
* <li> and Screen is turned on.
|
||||
*/
|
||||
private void maybeStartHotwordDetector() {
|
||||
if (!ENABLE_HOTWORD) return;
|
||||
|
||||
if (sHotwordClient != null) {
|
||||
if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()");
|
||||
// Don't start hotword detection if the screen is off.
|
||||
if (!mIsScreenOn) {
|
||||
if (DEBUG) Log.d(TAG, "screen was off, not starting");
|
||||
return;
|
||||
}
|
||||
|
||||
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
|
||||
if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) {
|
||||
if (DEBUG) Log.d(TAG, "Call underway, not starting");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sHotwordClient.startRecognition(mHotwordCallback);
|
||||
} catch(Exception ex) {
|
||||
// Don't allow hotword errors to make the keyguard unusable
|
||||
Log.e(TAG, "Failed to start hotword recognition", ex);
|
||||
sHotwordClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop hotword detector if:
|
||||
* <li> ENABLE_HOTWORD is true
|
||||
* <li> and hotword is running.
|
||||
*/
|
||||
private void maybeStopHotwordDetector() {
|
||||
if (!ENABLE_HOTWORD) return;
|
||||
|
||||
if (sHotwordClient != null) {
|
||||
if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()");
|
||||
try {
|
||||
sHotwordClient.stopRecognition();
|
||||
} catch(Exception ex) {
|
||||
// Don't allow hotword errors to make the keyguard unusable
|
||||
Log.e(TAG, "Failed to start hotword recognition", ex);
|
||||
} finally {
|
||||
sHotwordClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() {
|
||||
private static final String TAG = "HotwordRecognitionListener";
|
||||
|
||||
public void onHotwordRecognitionStarted() {
|
||||
if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()");
|
||||
}
|
||||
|
||||
public void onHotwordRecognitionStopped() {
|
||||
if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()");
|
||||
}
|
||||
|
||||
public void onHotwordEvent(int eventType, Bundle eventBundle) {
|
||||
if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType);
|
||||
if (eventType == HotwordRecognitionService.EVENT_TYPE_PROMPT_CHANGED) {
|
||||
if (eventBundle != null
|
||||
&& eventBundle.containsKey(HotwordRecognitionService.KEY_PROMPT_TEXT)) {
|
||||
new KeyguardMessageArea
|
||||
.Helper((View) getSecurityView(mCurrentSecuritySelection))
|
||||
.setMessage(eventBundle.getString(
|
||||
HotwordRecognitionService.KEY_PROMPT_TEXT),true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onHotwordRecognized(final Intent intent) {
|
||||
if (DEBUG) Log.d(TAG, "onHotwordRecognized");
|
||||
maybeStopHotwordDetector();
|
||||
// See if an activity can handle this intent.
|
||||
if (getContext().getPackageManager().resolveActivity(intent, 0) == null)
|
||||
return;
|
||||
if (SecurityMode.None == mCurrentSecuritySelection) {
|
||||
if (intent != null) {
|
||||
mActivityLauncher.launchActivity(intent, true, true, null, null);
|
||||
}
|
||||
mCallback.userActivity(0);
|
||||
} else if (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()) {
|
||||
setOnDismissAction(new OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
if (intent != null) {
|
||||
mActivityLauncher.launchActivity(intent, true, true, null, null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
getSecurityView(mCurrentSecuritySelection).showBouncer(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void onHotwordError(int errorCode) {
|
||||
if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode);
|
||||
// TODO: Inspect the error code and handle the errors appropriately
|
||||
// instead of blindly failing.
|
||||
maybeStopHotwordDetector();
|
||||
}
|
||||
};
|
||||
|
||||
private boolean shouldRunHotwordInSecurityMode(SecurityMode mode) {
|
||||
// Enable hotoword for insecure keyguard,
|
||||
// and for pattern unlock if ENABLE_HOTWORD_SECURE is true.
|
||||
return ENABLE_HOTWORD
|
||||
&& ((SecurityMode.None == mode)
|
||||
|| (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user