Merge "Report onFailure when binding detection service failure" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
51537e5930
@@ -68,6 +68,7 @@ import android.os.ParcelFileDescriptor;
|
|||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SharedMemory;
|
import android.os.SharedMemory;
|
||||||
|
import android.service.voice.DetectorFailure;
|
||||||
import android.service.voice.HotwordDetectedResult;
|
import android.service.voice.HotwordDetectedResult;
|
||||||
import android.service.voice.HotwordDetectionService;
|
import android.service.voice.HotwordDetectionService;
|
||||||
import android.service.voice.HotwordDetectionServiceFailure;
|
import android.service.voice.HotwordDetectionServiceFailure;
|
||||||
@@ -623,11 +624,9 @@ abstract class DetectorSession {
|
|||||||
mRemoteDetectionService = remoteDetectionService;
|
mRemoteDetectionService = remoteDetectionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportErrorLocked(int errorCode, @NonNull String errorMessage) {
|
void reportErrorLocked(@NonNull DetectorFailure detectorFailure) {
|
||||||
try {
|
try {
|
||||||
// TODO: Use instanceof(this) to get different detector to set the right error source.
|
mCallback.onDetectionFailure(detectorFailure);
|
||||||
mCallback.onDetectionFailure(
|
|
||||||
new HotwordDetectionServiceFailure(errorCode, errorMessage));
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.w(TAG, "Failed to report onError status: " + e);
|
Slog.w(TAG, "Failed to report onError status: " + e);
|
||||||
if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
||||||
|
|||||||
@@ -51,11 +51,14 @@ import android.os.ServiceManager;
|
|||||||
import android.os.SharedMemory;
|
import android.os.SharedMemory;
|
||||||
import android.provider.DeviceConfig;
|
import android.provider.DeviceConfig;
|
||||||
import android.service.voice.HotwordDetectionService;
|
import android.service.voice.HotwordDetectionService;
|
||||||
|
import android.service.voice.HotwordDetectionServiceFailure;
|
||||||
import android.service.voice.HotwordDetector;
|
import android.service.voice.HotwordDetector;
|
||||||
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
|
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
|
||||||
import android.service.voice.ISandboxedDetectionService;
|
import android.service.voice.ISandboxedDetectionService;
|
||||||
import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback;
|
import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback;
|
||||||
|
import android.service.voice.UnknownFailure;
|
||||||
import android.service.voice.VisualQueryDetectionService;
|
import android.service.voice.VisualQueryDetectionService;
|
||||||
|
import android.service.voice.VisualQueryDetectionServiceFailure;
|
||||||
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
|
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
|
||||||
import android.speech.IRecognitionServiceManager;
|
import android.speech.IRecognitionServiceManager;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -109,6 +112,16 @@ final class HotwordDetectionConnection {
|
|||||||
private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour
|
private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour
|
||||||
private static final int MAX_ISOLATED_PROCESS_NUMBER = 10;
|
private static final int MAX_ISOLATED_PROCESS_NUMBER = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the {@link HotwordDetectionService} is created.
|
||||||
|
*/
|
||||||
|
private static final int DETECTION_SERVICE_TYPE_HOTWORD = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the {@link VisualQueryDetectionService} is created.
|
||||||
|
*/
|
||||||
|
private static final int DETECTION_SERVICE_TYPE_VISUAL_QUERY = 2;
|
||||||
|
|
||||||
// TODO: This may need to be a Handler(looper)
|
// TODO: This may need to be a Handler(looper)
|
||||||
private final ScheduledExecutorService mScheduledExecutorService =
|
private final ScheduledExecutorService mScheduledExecutorService =
|
||||||
Executors.newSingleThreadScheduledExecutor();
|
Executors.newSingleThreadScheduledExecutor();
|
||||||
@@ -186,11 +199,11 @@ final class HotwordDetectionConnection {
|
|||||||
|
|
||||||
mHotwordDetectionServiceConnectionFactory =
|
mHotwordDetectionServiceConnectionFactory =
|
||||||
new ServiceConnectionFactory(hotwordDetectionServiceIntent,
|
new ServiceConnectionFactory(hotwordDetectionServiceIntent,
|
||||||
bindInstantServiceAllowed);
|
bindInstantServiceAllowed, DETECTION_SERVICE_TYPE_HOTWORD);
|
||||||
|
|
||||||
mVisualQueryDetectionServiceConnectionFactory =
|
mVisualQueryDetectionServiceConnectionFactory =
|
||||||
new ServiceConnectionFactory(visualQueryDetectionServiceIntent,
|
new ServiceConnectionFactory(visualQueryDetectionServiceIntent,
|
||||||
bindInstantServiceAllowed);
|
bindInstantServiceAllowed, DETECTION_SERVICE_TYPE_VISUAL_QUERY);
|
||||||
|
|
||||||
|
|
||||||
mLastRestartInstant = Instant.now();
|
mLastRestartInstant = Instant.now();
|
||||||
@@ -604,17 +617,20 @@ final class HotwordDetectionConnection {
|
|||||||
private class ServiceConnectionFactory {
|
private class ServiceConnectionFactory {
|
||||||
private final Intent mIntent;
|
private final Intent mIntent;
|
||||||
private final int mBindingFlags;
|
private final int mBindingFlags;
|
||||||
|
private final int mDetectionServiceType;
|
||||||
|
|
||||||
ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed) {
|
ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed,
|
||||||
|
int detectionServiceType) {
|
||||||
mIntent = intent;
|
mIntent = intent;
|
||||||
mBindingFlags = bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0;
|
mBindingFlags = bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0;
|
||||||
|
mDetectionServiceType = detectionServiceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceConnection createLocked() {
|
ServiceConnection createLocked() {
|
||||||
ServiceConnection connection =
|
ServiceConnection connection =
|
||||||
new ServiceConnection(mContext, mIntent, mBindingFlags, mUser,
|
new ServiceConnection(mContext, mIntent, mBindingFlags, mUser,
|
||||||
ISandboxedDetectionService.Stub::asInterface,
|
ISandboxedDetectionService.Stub::asInterface,
|
||||||
mRestartCount % MAX_ISOLATED_PROCESS_NUMBER);
|
mRestartCount % MAX_ISOLATED_PROCESS_NUMBER, mDetectionServiceType);
|
||||||
connection.connect();
|
connection.connect();
|
||||||
|
|
||||||
updateAudioFlinger(connection, mAudioFlinger);
|
updateAudioFlinger(connection, mAudioFlinger);
|
||||||
@@ -635,15 +651,17 @@ final class HotwordDetectionConnection {
|
|||||||
private boolean mRespectServiceConnectionStatusChanged = true;
|
private boolean mRespectServiceConnectionStatusChanged = true;
|
||||||
private boolean mIsBound = false;
|
private boolean mIsBound = false;
|
||||||
private boolean mIsLoggedFirstConnect = false;
|
private boolean mIsLoggedFirstConnect = false;
|
||||||
|
private final int mDetectionServiceType;
|
||||||
|
|
||||||
ServiceConnection(@NonNull Context context,
|
ServiceConnection(@NonNull Context context,
|
||||||
@NonNull Intent serviceIntent, int bindingFlags, int userId,
|
@NonNull Intent serviceIntent, int bindingFlags, int userId,
|
||||||
@Nullable Function<IBinder, ISandboxedDetectionService> binderAsInterface,
|
@Nullable Function<IBinder, ISandboxedDetectionService> binderAsInterface,
|
||||||
int instanceNumber) {
|
int instanceNumber, int detectionServiceType) {
|
||||||
super(context, serviceIntent, bindingFlags, userId, binderAsInterface);
|
super(context, serviceIntent, bindingFlags, userId, binderAsInterface);
|
||||||
this.mIntent = serviceIntent;
|
this.mIntent = serviceIntent;
|
||||||
this.mBindingFlags = bindingFlags;
|
this.mBindingFlags = bindingFlags;
|
||||||
this.mInstanceNumber = instanceNumber;
|
this.mInstanceNumber = instanceNumber;
|
||||||
|
this.mDetectionServiceType = detectionServiceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // from ServiceConnector.Impl
|
@Override // from ServiceConnector.Impl
|
||||||
@@ -660,14 +678,14 @@ final class HotwordDetectionConnection {
|
|||||||
mIsBound = connected;
|
mIsBound = connected;
|
||||||
|
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) {
|
||||||
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
||||||
HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED,
|
HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED,
|
||||||
mVoiceInteractionServiceUid);
|
mVoiceInteractionServiceUid);
|
||||||
}
|
}
|
||||||
} else if (!mIsLoggedFirstConnect) {
|
} else if (!mIsLoggedFirstConnect) {
|
||||||
mIsLoggedFirstConnect = true;
|
mIsLoggedFirstConnect = true;
|
||||||
if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) {
|
||||||
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
||||||
HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED,
|
HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED,
|
||||||
mVoiceInteractionServiceUid);
|
mVoiceInteractionServiceUid);
|
||||||
@@ -684,7 +702,7 @@ final class HotwordDetectionConnection {
|
|||||||
@Override
|
@Override
|
||||||
public void binderDied() {
|
public void binderDied() {
|
||||||
super.binderDied();
|
super.binderDied();
|
||||||
Slog.w(TAG, "binderDied");
|
Slog.w(TAG, "binderDied mDetectionServiceType = " + mDetectionServiceType);
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (!mRespectServiceConnectionStatusChanged) {
|
if (!mRespectServiceConnectionStatusChanged) {
|
||||||
Slog.v(TAG, "Ignored #binderDied event");
|
Slog.v(TAG, "Ignored #binderDied event");
|
||||||
@@ -693,13 +711,10 @@ final class HotwordDetectionConnection {
|
|||||||
}
|
}
|
||||||
//TODO(b265535257): report error to either service only.
|
//TODO(b265535257): report error to either service only.
|
||||||
synchronized (HotwordDetectionConnection.this.mLock) {
|
synchronized (HotwordDetectionConnection.this.mLock) {
|
||||||
runForEachDetectorSessionLocked((session) -> {
|
runForEachDetectorSessionLocked(this::reportBinderDiedLocked);
|
||||||
session.reportErrorLocked(DetectorSession.HOTWORD_DETECTION_SERVICE_DIED,
|
|
||||||
"Detection service is dead.");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// Can improve to log exit reason if needed
|
// Can improve to log exit reason if needed
|
||||||
if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) {
|
||||||
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
|
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
|
||||||
mDetectorType,
|
mDetectorType,
|
||||||
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH,
|
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH,
|
||||||
@@ -711,7 +726,7 @@ final class HotwordDetectionConnection {
|
|||||||
protected boolean bindService(
|
protected boolean bindService(
|
||||||
@NonNull android.content.ServiceConnection serviceConnection) {
|
@NonNull android.content.ServiceConnection serviceConnection) {
|
||||||
try {
|
try {
|
||||||
if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) {
|
||||||
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
||||||
HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE,
|
HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE,
|
||||||
mVoiceInteractionServiceUid);
|
mVoiceInteractionServiceUid);
|
||||||
@@ -723,7 +738,12 @@ final class HotwordDetectionConnection {
|
|||||||
mExecutor,
|
mExecutor,
|
||||||
serviceConnection);
|
serviceConnection);
|
||||||
if (!bindResult) {
|
if (!bindResult) {
|
||||||
if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
Slog.w(TAG,
|
||||||
|
"bindService failure mDetectionServiceType = " + mDetectionServiceType);
|
||||||
|
synchronized (HotwordDetectionConnection.this.mLock) {
|
||||||
|
runForEachDetectorSessionLocked(this::reportBindServiceFailureLocked);
|
||||||
|
}
|
||||||
|
if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) {
|
||||||
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
||||||
HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
|
HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
|
||||||
mVoiceInteractionServiceUid);
|
mVoiceInteractionServiceUid);
|
||||||
@@ -731,7 +751,7 @@ final class HotwordDetectionConnection {
|
|||||||
}
|
}
|
||||||
return bindResult;
|
return bindResult;
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
|
if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) {
|
||||||
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
|
||||||
HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
|
HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL,
|
||||||
mVoiceInteractionServiceUid);
|
mVoiceInteractionServiceUid);
|
||||||
@@ -752,6 +772,42 @@ final class HotwordDetectionConnection {
|
|||||||
mRespectServiceConnectionStatusChanged = false;
|
mRespectServiceConnectionStatusChanged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reportBinderDiedLocked(DetectorSession detectorSession) {
|
||||||
|
if (mDetectionServiceType == DETECTION_SERVICE_TYPE_HOTWORD && (
|
||||||
|
detectorSession instanceof DspTrustedHotwordDetectorSession
|
||||||
|
|| detectorSession instanceof SoftwareTrustedHotwordDetectorSession)) {
|
||||||
|
detectorSession.reportErrorLocked(new HotwordDetectionServiceFailure(
|
||||||
|
HotwordDetectionServiceFailure.ERROR_CODE_BINDING_DIED,
|
||||||
|
"Detection service is dead."));
|
||||||
|
} else if (mDetectionServiceType == DETECTION_SERVICE_TYPE_VISUAL_QUERY
|
||||||
|
&& detectorSession instanceof VisualQueryDetectorSession) {
|
||||||
|
detectorSession.reportErrorLocked(new VisualQueryDetectionServiceFailure(
|
||||||
|
VisualQueryDetectionServiceFailure.ERROR_CODE_BINDING_DIED,
|
||||||
|
"Detection service is dead."));
|
||||||
|
} else {
|
||||||
|
detectorSession.reportErrorLocked(new UnknownFailure(
|
||||||
|
"Detection service is dead with unknown detection service type."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reportBindServiceFailureLocked(DetectorSession detectorSession) {
|
||||||
|
if (mDetectionServiceType == DETECTION_SERVICE_TYPE_HOTWORD && (
|
||||||
|
detectorSession instanceof DspTrustedHotwordDetectorSession
|
||||||
|
|| detectorSession instanceof SoftwareTrustedHotwordDetectorSession)) {
|
||||||
|
detectorSession.reportErrorLocked(new HotwordDetectionServiceFailure(
|
||||||
|
HotwordDetectionServiceFailure.ERROR_CODE_BIND_FAILURE,
|
||||||
|
"Bind detection service failure."));
|
||||||
|
} else if (mDetectionServiceType == DETECTION_SERVICE_TYPE_VISUAL_QUERY
|
||||||
|
&& detectorSession instanceof VisualQueryDetectorSession) {
|
||||||
|
detectorSession.reportErrorLocked(new VisualQueryDetectionServiceFailure(
|
||||||
|
VisualQueryDetectionServiceFailure.ERROR_CODE_BIND_FAILURE,
|
||||||
|
"Bind detection service failure."));
|
||||||
|
} else {
|
||||||
|
detectorSession.reportErrorLocked(new UnknownFailure(
|
||||||
|
"Bind detection service failure with unknown detection service type."));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("GuardedBy")
|
@SuppressWarnings("GuardedBy")
|
||||||
|
|||||||
Reference in New Issue
Block a user