Skip to content
Snippets Groups Projects
Commit 737a7b71 authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Fix race condition for VQDS functionalities" into main

parents 0dd91528 f9835510
No related branches found
No related tags found
No related merge requests found
......@@ -94,7 +94,9 @@ public class VisualQueryDetector {
*/
public void updateState(@Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory) {
mInitializationDelegate.updateState(options, sharedMemory);
synchronized (mInitializationDelegate.getLock()) {
mInitializationDelegate.updateState(options, sharedMemory);
}
}
......@@ -116,18 +118,21 @@ public class VisualQueryDetector {
if (DEBUG) {
Slog.i(TAG, "#startRecognition");
}
// check if the detector is active with the initialization delegate
mInitializationDelegate.startRecognition();
try {
mManagerService.startPerceiving(new BinderCallback(mExecutor, mCallback));
} catch (SecurityException e) {
Slog.e(TAG, "startRecognition failed: " + e);
return false;
} catch (RemoteException e) {
e.rethrowFromSystemServer();
synchronized (mInitializationDelegate.getLock()) {
// check if the detector is active with the initialization delegate
mInitializationDelegate.startRecognition();
try {
mManagerService.startPerceiving(new BinderCallback(
mExecutor, mCallback, mInitializationDelegate.getLock()));
} catch (SecurityException e) {
Slog.e(TAG, "startRecognition failed: " + e);
return false;
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return true;
}
return true;
}
/**
......@@ -140,15 +145,17 @@ public class VisualQueryDetector {
if (DEBUG) {
Slog.i(TAG, "#stopRecognition");
}
// check if the detector is active with the initialization delegate
mInitializationDelegate.startRecognition();
try {
mManagerService.stopPerceiving();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
synchronized (mInitializationDelegate.getLock()) {
// check if the detector is active with the initialization delegate
mInitializationDelegate.stopRecognition();
try {
mManagerService.stopPerceiving();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return true;
}
return true;
}
/**
......@@ -160,12 +167,16 @@ public class VisualQueryDetector {
if (DEBUG) {
Slog.i(TAG, "#destroy");
}
mInitializationDelegate.destroy();
synchronized (mInitializationDelegate.getLock()) {
mInitializationDelegate.destroy();
}
}
/** @hide */
public void dump(String prefix, PrintWriter pw) {
// TODO: implement this
synchronized (mInitializationDelegate.getLock()) {
mInitializationDelegate.dump(prefix, pw);
}
}
/** @hide */
......@@ -175,7 +186,9 @@ public class VisualQueryDetector {
/** @hide */
void registerOnDestroyListener(Consumer<AbstractDetector> onDestroyListener) {
mInitializationDelegate.registerOnDestroyListener(onDestroyListener);
synchronized (mInitializationDelegate.getLock()) {
mInitializationDelegate.registerOnDestroyListener(onDestroyListener);
}
}
/**
......@@ -282,6 +295,15 @@ public class VisualQueryDetector {
public boolean isUsingSandboxedDetectionService() {
return true;
}
@Override
public void dump(String prefix, PrintWriter pw) {
// No-op
}
private Object getLock() {
return mLock;
}
}
private static class BinderCallback
......@@ -289,31 +311,43 @@ public class VisualQueryDetector {
private final Executor mExecutor;
private final VisualQueryDetector.Callback mCallback;
BinderCallback(Executor executor, VisualQueryDetector.Callback callback) {
private final Object mLock;
BinderCallback(Executor executor, VisualQueryDetector.Callback callback, Object lock) {
this.mExecutor = executor;
this.mCallback = callback;
this.mLock = lock;
}
/** Called when the detected result is valid. */
@Override
public void onQueryDetected(@NonNull String partialQuery) {
Slog.v(TAG, "BinderCallback#onQueryDetected");
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> mCallback.onQueryDetected(partialQuery)));
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
mCallback.onQueryDetected(partialQuery);
}
});
}
@Override
public void onQueryFinished() {
Slog.v(TAG, "BinderCallback#onQueryFinished");
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> mCallback.onQueryFinished()));
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
mCallback.onQueryFinished();
}
});
}
@Override
public void onQueryRejected() {
Slog.v(TAG, "BinderCallback#onQueryRejected");
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> mCallback.onQueryRejected()));
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
mCallback.onQueryRejected();
}
});
}
/** Called when the detection fails due to an error. */
......
......@@ -106,96 +106,104 @@ final class VisualQueryDetectorSession extends DetectorSession {
@Override
public void onAttentionGained() {
Slog.v(TAG, "BinderCallback#onAttentionGained");
mEgressingData = true;
if (mAttentionListener == null) {
return;
}
try {
mAttentionListener.onAttentionGained();
} catch (RemoteException e) {
Slog.e(TAG, "Error delivering attention gained event.", e);
synchronized (mLock) {
mEgressingData = true;
if (mAttentionListener == null) {
return;
}
try {
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
"Attention listener failed to switch to GAINED state."));
} catch (RemoteException ex) {
Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
mAttentionListener.onAttentionGained();
} catch (RemoteException e) {
Slog.e(TAG, "Error delivering attention gained event.", e);
try {
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
"Attention listener fails to switch to GAINED state."));
} catch (RemoteException ex) {
Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
}
}
return;
}
}
@Override
public void onAttentionLost() {
Slog.v(TAG, "BinderCallback#onAttentionLost");
mEgressingData = false;
if (mAttentionListener == null) {
return;
}
try {
mAttentionListener.onAttentionLost();
} catch (RemoteException e) {
Slog.e(TAG, "Error delivering attention lost event.", e);
synchronized (mLock) {
mEgressingData = false;
if (mAttentionListener == null) {
return;
}
try {
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
"Attention listener failed to switch to LOST state."));
} catch (RemoteException ex) {
Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
mAttentionListener.onAttentionLost();
} catch (RemoteException e) {
Slog.e(TAG, "Error delivering attention lost event.", e);
try {
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_ATTENTION_STATE,
"Attention listener fails to switch to LOST state."));
} catch (RemoteException ex) {
Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
}
}
return;
}
}
@Override
public void onQueryDetected(@NonNull String partialQuery) throws RemoteException {
Objects.requireNonNull(partialQuery);
Slog.v(TAG, "BinderCallback#onQueryDetected");
if (!mEgressingData) {
Slog.v(TAG, "Query should not be egressed within the unattention state.");
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_STREAMING_STATE,
"Cannot stream queries without attention signals."));
return;
synchronized (mLock) {
Objects.requireNonNull(partialQuery);
if (!mEgressingData) {
Slog.v(TAG, "Query should not be egressed within the unattention state.");
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_STREAMING_STATE,
"Cannot stream queries without attention signals."));
return;
}
mQueryStreaming = true;
callback.onQueryDetected(partialQuery);
Slog.i(TAG, "Egressed from visual query detection process.");
}
mQueryStreaming = true;
callback.onQueryDetected(partialQuery);
Slog.i(TAG, "Egressed from visual query detection process.");
}
@Override
public void onQueryFinished() throws RemoteException {
Slog.v(TAG, "BinderCallback#onQueryFinished");
if (!mQueryStreaming) {
Slog.v(TAG, "Query streaming state signal FINISHED is block since there is"
+ " no active query being streamed.");
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_STREAMING_STATE,
"Cannot send FINISHED signal with no query streamed."));
return;
synchronized (mLock) {
if (!mQueryStreaming) {
Slog.v(TAG, "Query streaming state signal FINISHED is block since there is"
+ " no active query being streamed.");
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_STREAMING_STATE,
"Cannot send FINISHED signal with no query streamed."));
return;
}
callback.onQueryFinished();
mQueryStreaming = false;
}
callback.onQueryFinished();
mQueryStreaming = false;
}
@Override
public void onQueryRejected() throws RemoteException {
Slog.v(TAG, "BinderCallback#onQueryRejected");
if (!mQueryStreaming) {
Slog.v(TAG, "Query streaming state signal REJECTED is block since there is"
+ " no active query being streamed.");
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_STREAMING_STATE,
"Cannot send REJECTED signal with no query streamed."));
return;
synchronized (mLock) {
if (!mQueryStreaming) {
Slog.v(TAG, "Query streaming state signal REJECTED is block since there is"
+ " no active query being streamed.");
callback.onVisualQueryDetectionServiceFailure(
new VisualQueryDetectionServiceFailure(
ERROR_CODE_ILLEGAL_STREAMING_STATE,
"Cannot send REJECTED signal with no query streamed."));
return;
}
callback.onQueryRejected();
mQueryStreaming = false;
}
callback.onQueryRejected();
mQueryStreaming = false;
}
};
return mRemoteDetectionService.run(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment