Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43929440 authored by Sergey Volnov's avatar Sergey Volnov
Browse files

Got rid of cancellation signals in the Content Capture Data Sharing

Motivation: if the Content Capture service want's to end the session, it
can close the read-fd, while not have finished reading, and that would
result in an exception in the system server, that can later be
propagated to the caller as an error.

Similarly, timeout of the sharing session can be reflected as an error
with a specific error code.

Test: built Android locally and perfomed a manual test.
Bug: 145203958
Change-Id: Iaeb45e0ab68da9fe30dce1ae4eab2354ef56d827
parent 7c78ce6e
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -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);
  }
}
+1 −1
Original line number Diff line number Diff line
@@ -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 {
+6 −29
Original line number Diff line number Diff line
@@ -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");
            }
        }

+6 −4
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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();
}
Loading