summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt7
-rwxr-xr-xapi/system-current.txt2
-rw-r--r--core/java/android/service/contentcapture/ContentCaptureService.java35
-rw-r--r--core/java/android/service/contentcapture/DataShareReadAdapter.java10
-rw-r--r--core/java/android/service/contentcapture/IDataShareCallback.aidl2
-rw-r--r--core/java/android/service/contentcapture/IDataShareReadAdapter.aidl2
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java35
-rw-r--r--core/java/android/view/contentcapture/DataShareWriteAdapter.java14
-rw-r--r--core/java/android/view/contentcapture/IContentCaptureManager.aidl3
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java103
10 files changed, 84 insertions, 129 deletions
diff --git a/api/current.txt b/api/current.txt
index c09dad40e532..af5a9dbdf336 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -56157,6 +56157,9 @@ package android.view.contentcapture {
method public void removeData(@NonNull android.view.contentcapture.DataRemovalRequest);
method public void setContentCaptureEnabled(boolean);
method public void shareData(@NonNull android.view.contentcapture.DataShareRequest, @NonNull java.util.concurrent.Executor, @NonNull android.view.contentcapture.DataShareWriteAdapter);
+ field public static final int DATA_SHARE_ERROR_CONCURRENT_REQUEST = 2; // 0x2
+ field public static final int DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED = 3; // 0x3
+ field public static final int DATA_SHARE_ERROR_UNKNOWN = 1; // 0x1
}
public abstract class ContentCaptureSession implements java.lang.AutoCloseable {
@@ -56218,9 +56221,7 @@ package android.view.contentcapture {
public interface DataShareWriteAdapter {
method public default void onError(int);
method public void onRejected();
- method public void onWrite(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.CancellationSignal);
- field public static final int ERROR_CONCURRENT_REQUEST = 1; // 0x1
- field public static final int ERROR_UNKNOWN = 2; // 0x2
+ method public void onWrite(@NonNull android.os.ParcelFileDescriptor);
}
}
diff --git a/api/system-current.txt b/api/system-current.txt
index d1ff478a8590..703f5acaa613 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -10186,7 +10186,7 @@ package android.service.contentcapture {
public interface DataShareReadAdapter {
method public void onError(int);
- method public void onStart(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.CancellationSignal);
+ method public void onStart(@NonNull android.os.ParcelFileDescriptor);
}
public final class SnapshotData implements android.os.Parcelable {
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index ac2532dcea7d..5a8521fead87 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -34,10 +34,8 @@ import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.os.Binder;
import android.os.Bundle;
-import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
-import android.os.ICancellationSignal;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -544,14 +542,11 @@ public abstract class ContentCaptureService extends Service {
Preconditions.checkNotNull(adapter);
Preconditions.checkNotNull(executor);
- ICancellationSignal cancellationSignalTransport =
- CancellationSignal.createTransport();
-
- DataShareReadAdapterDelegate delegate = new DataShareReadAdapterDelegate(
- executor, cancellationSignalTransport, adapter);
+ DataShareReadAdapterDelegate delegate =
+ new DataShareReadAdapterDelegate(executor, adapter);
try {
- callback.accept(cancellationSignalTransport, delegate);
+ callback.accept(delegate);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to accept data sharing", e);
}
@@ -658,38 +653,20 @@ public abstract class ContentCaptureService extends Service {
private final Object mLock = new Object();
private final WeakReference<DataShareReadAdapter> mAdapterReference;
private final WeakReference<Executor> mExecutorReference;
- private final WeakReference<ICancellationSignal> mCancellationSignalReference;
- DataShareReadAdapterDelegate(Executor executor,
- ICancellationSignal cancellationSignalTransport, DataShareReadAdapter adapter) {
+ DataShareReadAdapterDelegate(Executor executor, DataShareReadAdapter adapter) {
Preconditions.checkNotNull(executor);
- Preconditions.checkNotNull(cancellationSignalTransport);
Preconditions.checkNotNull(adapter);
mExecutorReference = new WeakReference<>(executor);
- mCancellationSignalReference = new WeakReference<>(cancellationSignalTransport);
mAdapterReference = new WeakReference<>(adapter);
}
@Override
- public void start(ParcelFileDescriptor fd, ICancellationSignal remoteCancellationSignal)
+ public void start(ParcelFileDescriptor fd)
throws RemoteException {
synchronized (mLock) {
- ICancellationSignal serverControlledCancellationSignal =
- mCancellationSignalReference.get();
-
- if (serverControlledCancellationSignal == null) {
- Slog.w(TAG, "Can't execute onStart(), reference to cancellation signal has "
- + "been GC'ed");
- return;
- }
-
- CancellationSignal cancellationSignal =
- CancellationSignal.fromTransport(serverControlledCancellationSignal);
- cancellationSignal.setRemote(remoteCancellationSignal);
-
- executeAdapterMethodLocked(
- adapter -> adapter.onStart(fd, cancellationSignal), "onStart");
+ executeAdapterMethodLocked(adapter -> adapter.onStart(fd), "onStart");
}
}
diff --git a/core/java/android/service/contentcapture/DataShareReadAdapter.java b/core/java/android/service/contentcapture/DataShareReadAdapter.java
index ca6820110ea9..b9fce6873c5f 100644
--- a/core/java/android/service/contentcapture/DataShareReadAdapter.java
+++ b/core/java/android/service/contentcapture/DataShareReadAdapter.java
@@ -18,7 +18,6 @@ package android.service.contentcapture;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
/**
@@ -34,13 +33,16 @@ public interface DataShareReadAdapter {
* Signals the start of the data sharing session.
*
* @param fd file descriptor to use for reading data, that's being shared
- * @param cancellationSignal cancellation signal to use if data is no longer needed and the
- * session needs to be terminated.
**/
- void onStart(@NonNull ParcelFileDescriptor fd, @NonNull CancellationSignal cancellationSignal);
+ void onStart(@NonNull ParcelFileDescriptor fd);
/**
* Signals that the session failed to start or terminated unsuccessfully.
+ *
+ * <p>Important: together with the error, file sharing stream might be closed, and therefore
+ * reading from {@code fd} from {@link #onStart} will result in the end of stream. The order of
+ * these 2 events is not defined, and it's important that the service treats end of stream
+ * correctly in this situation.
**/
void onError(int errorCode);
}
diff --git a/core/java/android/service/contentcapture/IDataShareCallback.aidl b/core/java/android/service/contentcapture/IDataShareCallback.aidl
index d972adadb53c..84d372580e7c 100644
--- a/core/java/android/service/contentcapture/IDataShareCallback.aidl
+++ b/core/java/android/service/contentcapture/IDataShareCallback.aidl
@@ -21,6 +21,6 @@ import android.service.contentcapture.IDataShareReadAdapter;
/** @hide */
oneway interface IDataShareCallback {
- void accept(in ICancellationSignal cancellationSignal, in IDataShareReadAdapter adapter);
+ void accept(in IDataShareReadAdapter adapter);
void reject();
}
diff --git a/core/java/android/service/contentcapture/IDataShareReadAdapter.aidl b/core/java/android/service/contentcapture/IDataShareReadAdapter.aidl
index 73da5d515edc..91c8ff1fc662 100644
--- a/core/java/android/service/contentcapture/IDataShareReadAdapter.aidl
+++ b/core/java/android/service/contentcapture/IDataShareReadAdapter.aidl
@@ -20,6 +20,6 @@ import android.os.ICancellationSignal;
/** @hide */
oneway interface IDataShareReadAdapter {
- void start(in ParcelFileDescriptor fd, in ICancellationSignal cancellationSignal);
+ void start(in ParcelFileDescriptor fd);
void error(int errorCode);
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index cede3b5cf9fe..b7b54c8c74b9 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -32,10 +32,8 @@ import android.content.ContentCaptureOptions;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Binder;
-import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
-import android.os.ICancellationSignal;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -209,6 +207,15 @@ public final class ContentCaptureManager {
private static final String TAG = ContentCaptureManager.class.getSimpleName();
+ /** Error happened during the data sharing session. */
+ public static final int DATA_SHARE_ERROR_UNKNOWN = 1;
+
+ /** Request has been rejected, because a concurrent data share sessions is in progress. */
+ public static final int DATA_SHARE_ERROR_CONCURRENT_REQUEST = 2;
+
+ /** Request has been interrupted because of data share session timeout. */
+ public static final int DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED = 3;
+
/** @hide */
public static final int RESULT_CODE_OK = 0;
/** @hide */
@@ -656,12 +663,9 @@ public final class ContentCaptureManager {
Preconditions.checkNotNull(dataShareWriteAdapter);
Preconditions.checkNotNull(executor);
- ICancellationSignal cancellationSignalTransport = CancellationSignal.createTransport();
-
try {
- mService.shareData(request, cancellationSignalTransport,
- new DataShareAdapterDelegate(executor,
- cancellationSignalTransport, dataShareWriteAdapter));
+ mService.shareData(request,
+ new DataShareAdapterDelegate(executor, dataShareWriteAdapter));
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -719,32 +723,19 @@ public final class ContentCaptureManager {
private final WeakReference<DataShareWriteAdapter> mAdapterReference;
private final WeakReference<Executor> mExecutorReference;
- private final WeakReference<ICancellationSignal> mCancellationSignal;
- private DataShareAdapterDelegate(Executor executor,
- ICancellationSignal cancellationSignalTransport, DataShareWriteAdapter adapter) {
+ private DataShareAdapterDelegate(Executor executor, DataShareWriteAdapter adapter) {
Preconditions.checkNotNull(executor);
- Preconditions.checkNotNull(cancellationSignalTransport);
Preconditions.checkNotNull(adapter);
mExecutorReference = new WeakReference<>(executor);
mAdapterReference = new WeakReference<>(adapter);
- mCancellationSignal = new WeakReference<>(cancellationSignalTransport);
}
@Override
public void write(ParcelFileDescriptor destination)
throws RemoteException {
- ICancellationSignal cancellationSignalTransport = mCancellationSignal.get();
- if (cancellationSignalTransport == null) {
- Slog.w(TAG, "Can't execute write(), reference to cancellation signal has been "
- + "GC'ed");
- }
- CancellationSignal cancellationSignal =
- CancellationSignal.fromTransport(cancellationSignalTransport);
-
- executeAdapterMethodLocked(adapter -> adapter.onWrite(destination, cancellationSignal),
- "onWrite");
+ executeAdapterMethodLocked(adapter -> adapter.onWrite(destination), "onWrite");
}
@Override
diff --git a/core/java/android/view/contentcapture/DataShareWriteAdapter.java b/core/java/android/view/contentcapture/DataShareWriteAdapter.java
index f791fea7ee8d..2beaededf8b1 100644
--- a/core/java/android/view/contentcapture/DataShareWriteAdapter.java
+++ b/core/java/android/view/contentcapture/DataShareWriteAdapter.java
@@ -17,18 +17,11 @@
package android.view.contentcapture;
import android.annotation.NonNull;
-import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
/** Adapter class used by apps to share data with the Content Capture service. */
public interface DataShareWriteAdapter {
- /** Request has been rejected, because a concurrent data share sessions is in progress. */
- int ERROR_CONCURRENT_REQUEST = 1;
-
- /** Data share session timed out. */
- int ERROR_UNKNOWN = 2;
-
/**
* Method invoked when the data share session has been started and the app needs to start
* writing into the file used for sharing.
@@ -36,12 +29,9 @@ public interface DataShareWriteAdapter {
* <p>App needs to handle explicitly cases when the file descriptor is closed and handle
* gracefully if IOExceptions happen.
*
- * @param destination file descriptor used to write data into
- * @param cancellationSignal cancellation signal that the app can use to subscribe to cancel
- * operations.
+ * @param destination file descriptor used to write data into.
*/
- void onWrite(@NonNull ParcelFileDescriptor destination,
- @NonNull CancellationSignal cancellationSignal);
+ void onWrite(@NonNull ParcelFileDescriptor destination);
/** Data share sessions has been rejected by the Content Capture service. */
void onRejected();
diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
index 5217e68eac50..01ead4601e59 100644
--- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl
+++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
@@ -69,8 +69,7 @@ oneway interface IContentCaptureManager {
/**
* Requests sharing of a binary data with the content capture service.
*/
- void shareData(in DataShareRequest request, in ICancellationSignal cancellationSignal,
- in IDataShareWriteAdapter adapter);
+ void shareData(in DataShareRequest request, in IDataShareWriteAdapter adapter);
/**
* Returns whether the content capture feature is enabled for the calling user.
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 5602d1a851e8..31ea5faa05f1 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -45,10 +45,8 @@ import android.database.ContentObserver;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
-import android.os.ICancellationSignal;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -73,7 +71,6 @@ import android.view.contentcapture.ContentCaptureHelper;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.DataRemovalRequest;
import android.view.contentcapture.DataShareRequest;
-import android.view.contentcapture.DataShareWriteAdapter;
import android.view.contentcapture.IContentCaptureManager;
import android.view.contentcapture.IDataShareWriteAdapter;
@@ -648,7 +645,6 @@ public final class ContentCaptureManagerService extends
@Override
public void shareData(@NonNull DataShareRequest request,
- @NonNull ICancellationSignal clientCancellationSignal,
@NonNull IDataShareWriteAdapter clientAdapter) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(clientAdapter);
@@ -662,7 +658,8 @@ public final class ContentCaptureManagerService extends
if (mPackagesWithShareRequests.size() >= MAX_CONCURRENT_FILE_SHARING_REQUESTS
|| mPackagesWithShareRequests.contains(request.getPackageName())) {
try {
- clientAdapter.error(DataShareWriteAdapter.ERROR_CONCURRENT_REQUEST);
+ clientAdapter.error(
+ ContentCaptureManager.DATA_SHARE_ERROR_CONCURRENT_REQUEST);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to send error message to client");
}
@@ -670,8 +667,8 @@ public final class ContentCaptureManagerService extends
}
service.onDataSharedLocked(request,
- new DataShareCallbackDelegate(request, clientCancellationSignal,
- clientAdapter, ContentCaptureManagerService.this));
+ new DataShareCallbackDelegate(request, clientAdapter,
+ ContentCaptureManagerService.this));
}
}
@@ -922,41 +919,36 @@ public final class ContentCaptureManagerService extends
private static class DataShareCallbackDelegate extends IDataShareCallback.Stub {
@NonNull private final DataShareRequest mDataShareRequest;
- @NonNull
- private final WeakReference<ICancellationSignal> mClientCancellationSignalReference;
@NonNull private final WeakReference<IDataShareWriteAdapter> mClientAdapterReference;
@NonNull private final WeakReference<ContentCaptureManagerService> mParentServiceReference;
DataShareCallbackDelegate(@NonNull DataShareRequest dataShareRequest,
- @NonNull ICancellationSignal clientCancellationSignal,
@NonNull IDataShareWriteAdapter clientAdapter,
ContentCaptureManagerService parentService) {
mDataShareRequest = dataShareRequest;
- mClientCancellationSignalReference = new WeakReference<>(clientCancellationSignal);
mClientAdapterReference = new WeakReference<>(clientAdapter);
mParentServiceReference = new WeakReference<>(parentService);
}
@Override
- public void accept(ICancellationSignal serviceCancellationSignal,
- IDataShareReadAdapter serviceAdapter) throws RemoteException {
+ public void accept(IDataShareReadAdapter serviceAdapter) throws RemoteException {
Slog.i(TAG, "Data share request accepted by Content Capture service");
final ContentCaptureManagerService parentService = mParentServiceReference.get();
- final ICancellationSignal clientCancellationSignal =
- mClientCancellationSignalReference.get();
final IDataShareWriteAdapter clientAdapter = mClientAdapterReference.get();
- if (parentService == null || clientCancellationSignal == null
- || clientAdapter == null) {
+ if (parentService == null || clientAdapter == null) {
Slog.w(TAG, "Can't fulfill accept() request, because remote objects have been "
+ "GC'ed");
return;
}
+ final WeakReference<IDataShareReadAdapter> serviceAdapterReference =
+ new WeakReference<>(serviceAdapter);
+
Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe();
if (clientPipe == null) {
- clientAdapter.error(DataShareWriteAdapter.ERROR_UNKNOWN);
- serviceAdapter.error(DataShareWriteAdapter.ERROR_UNKNOWN);
+ clientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ serviceAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
return;
}
@@ -967,31 +959,18 @@ public final class ContentCaptureManagerService extends
if (servicePipe == null) {
bestEffortCloseFileDescriptors(sourceIn, sinkIn);
- clientAdapter.error(DataShareWriteAdapter.ERROR_UNKNOWN);
- serviceAdapter.error(DataShareWriteAdapter.ERROR_UNKNOWN);
+ clientAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
+ serviceAdapter.error(ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
return;
}
ParcelFileDescriptor sourceOut = servicePipe.second;
ParcelFileDescriptor sinkOut = servicePipe.first;
- ICancellationSignal cancellationSignalTransport =
- CancellationSignal.createTransport();
parentService.mPackagesWithShareRequests.add(mDataShareRequest.getPackageName());
clientAdapter.write(sourceIn);
- serviceAdapter.start(sinkOut, cancellationSignalTransport);
-
- CancellationSignal cancellationSignal =
- CancellationSignal.fromTransport(cancellationSignalTransport);
-
- cancellationSignal.setOnCancelListener(() -> {
- try {
- clientCancellationSignal.cancel();
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to propagate cancel operation to the caller", e);
- }
- });
+ serviceAdapter.start(sinkOut);
// File descriptor received by the client app will be a copy of the current one. Close
// the one that belongs to the system server, so there's only 1 open left for the
@@ -1016,6 +995,9 @@ public final class ContentCaptureManagerService extends
}
} catch (IOException e) {
Slog.e(TAG, "Failed to pipe client and service streams", e);
+
+ sendErrorSignal(mClientAdapterReference, serviceAdapterReference,
+ ContentCaptureManager.DATA_SHARE_ERROR_UNKNOWN);
}
});
@@ -1025,7 +1007,7 @@ public final class ContentCaptureManagerService extends
sinkIn,
sourceOut,
sinkOut,
- new WeakReference<>(serviceCancellationSignal)),
+ serviceAdapterReference),
MAX_DATA_SHARE_FILE_DESCRIPTORS_TTL_MS);
}
@@ -1047,15 +1029,10 @@ public final class ContentCaptureManagerService extends
ParcelFileDescriptor sinkIn,
ParcelFileDescriptor sourceOut,
ParcelFileDescriptor sinkOut,
- WeakReference<ICancellationSignal> serviceCancellationSignalReference) {
+ WeakReference<IDataShareReadAdapter> serviceAdapterReference) {
final ContentCaptureManagerService parentService = mParentServiceReference.get();
- final ICancellationSignal clientCancellationSignal =
- mClientCancellationSignalReference.get();
- final ICancellationSignal serviceCancellationSignal =
- serviceCancellationSignalReference.get();
- if (parentService == null || clientCancellationSignal == null
- || serviceCancellationSignal == null) {
+ if (parentService == null) {
Slog.w(TAG, "Can't enforce data sharing TTL, because remote objects have been "
+ "GC'ed");
return;
@@ -1067,7 +1044,7 @@ public final class ContentCaptureManagerService extends
// Interaction finished successfully <=> all data has been written to Content
// Capture Service. If it hasn't been read successfully, service would be able
- // to signal through the cancellation signal.
+ // to signal by closing the input stream while not have finished reading.
boolean finishedSuccessfully = !sinkIn.getFileDescriptor().valid()
&& !sourceOut.getFileDescriptor().valid();
@@ -1087,16 +1064,8 @@ public final class ContentCaptureManagerService extends
bestEffortCloseFileDescriptors(sourceIn, sinkIn, sourceOut, sinkOut);
if (!finishedSuccessfully) {
- try {
- clientCancellationSignal.cancel();
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to cancel() the client operation", e);
- }
- try {
- serviceCancellationSignal.cancel();
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to cancel() the service operation", e);
- }
+ sendErrorSignal(mClientAdapterReference, serviceAdapterReference,
+ ContentCaptureManager.DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED);
}
}
}
@@ -1139,5 +1108,31 @@ public final class ContentCaptureManagerService extends
bestEffortCloseFileDescriptor(fd);
}
}
+
+ private static void sendErrorSignal(
+ WeakReference<IDataShareWriteAdapter> clientAdapterReference,
+ WeakReference<IDataShareReadAdapter> serviceAdapterReference,
+ int errorCode) {
+
+ final IDataShareWriteAdapter clientAdapter = clientAdapterReference.get();
+ final IDataShareReadAdapter serviceAdapter = serviceAdapterReference.get();
+
+ if (clientAdapter == null || serviceAdapter == null) {
+ Slog.w(TAG, "Can't propagate error() to read/write data share adapters, because "
+ + "remote objects have been GC'ed");
+ return;
+ }
+
+ try {
+ clientAdapter.error(errorCode);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to call error() the client operation", e);
+ }
+ try {
+ serviceAdapter.error(errorCode);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to call error() the service operation", e);
+ }
+ }
}
}