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

Commit 6943ad3a authored by Sandeep Bandaru's avatar Sandeep Bandaru
Browse files

Support pull based approach for metadata fetching

This CL extends the OnDeviceIntelligenceService to support
fetching metadata for a given feature used via a pull-based approach.

*   Added new APIs in OnDeviceIntelligenceService and OnDeviceSandboxedInferenceService.
*   Refactored code to improve readability.

Context: go/odim-api-improvements

Flag: android.app.ondeviceintelligence.flags.on_device_intelligence_25q4
Bug: 372658837
Test: cts
Change-Id: I8444e202c553b749fef3f5b92b3ef9809e1eb523
parent 7c9f31af
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -48,4 +48,5 @@ oneway interface IOnDeviceIntelligenceService {
    void notifyInferenceServiceConnected();
    void notifyInferenceServiceDisconnected();
    void ready();
    void getFeatureMetadata(in Feature feature, in RemoteCallback remoteCallback);
}
+3 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.service.ondeviceintelligence;

import android.app.ondeviceintelligence.Feature;
import android.os.ParcelFileDescriptor;
import android.os.Bundle;
import android.os.RemoteCallback;

import com.android.internal.infra.AndroidFuture;
@@ -31,4 +32,5 @@ import com.android.internal.infra.AndroidFuture;
oneway interface IRemoteStorageService {
    void getReadOnlyFileDescriptor(in String filePath, in AndroidFuture<ParcelFileDescriptor> future);
    void getReadOnlyFeatureFileDescriptorMap(in Feature feature, in RemoteCallback remoteCallback);
    void getFeatureMetadata(in Feature feature, in RemoteCallback remoteCallback);
}
+28 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.service.ondeviceintelligence;

import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ON_DEVICE_INTELLIGENCE_25Q4;

import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;

@@ -136,7 +137,8 @@ public abstract class OnDeviceIntelligenceService extends Service {
                    mHandler.executeOrSendMessage(
                            obtainMessage(
                                    OnDeviceIntelligenceService::onGetVersion,
                                    OnDeviceIntelligenceService.this, l -> {
                                    OnDeviceIntelligenceService.this,
                                    l -> {
                                        Bundle b = new Bundle();
                                        b.putLong(
                                                OnDeviceIntelligenceManager.API_VERSION_BUNDLE_KEY,
@@ -228,6 +230,19 @@ public abstract class OnDeviceIntelligenceService extends Service {
                                    }));
                }

                @Override
                public void getFeatureMetadata(
                        Feature feature, RemoteCallback remoteCallback) {
                    Objects.requireNonNull(feature);
                    Objects.requireNonNull(remoteCallback);
                    mHandler.executeOrSendMessage(
                            obtainMessage(
                                    OnDeviceIntelligenceService::onGetFeatureMetadata,
                                    OnDeviceIntelligenceService.this,
                                    feature,
                                    remoteCallback::sendResult));
                }

                @Override
                public void registerRemoteServices(
                        IRemoteProcessingService remoteProcessingService) {
@@ -400,7 +415,6 @@ public abstract class OnDeviceIntelligenceService extends Service {
        };
    }


    private DownloadCallback wrapDownloadCallback(IDownloadCallback downloadCallback) {
        return new DownloadCallback() {
            @Override
@@ -478,6 +492,17 @@ public abstract class OnDeviceIntelligenceService extends Service {
        });
    }


    /**
     * Provide implementation for a scenario when caller wants to get feature-specific metadata.
     *
     * @param feature the feature for which metadata needs to be fetched.
     * @param metadataConsumer callback to be populated with the corresponding metadata bundle.
     */
    @FlaggedApi(FLAG_ON_DEVICE_INTELLIGENCE_25Q4)
    public void onGetFeatureMetadata(
            @NonNull Feature feature, @NonNull Consumer<Bundle> metadataConsumer) {}

    /**
     * Provide implementation for a scenario when caller wants to get all feature related
     * file-descriptors that might be required for processing a request for the corresponding the
@@ -497,7 +522,7 @@ public abstract class OnDeviceIntelligenceService extends Service {
     * the download completes successfully, success callback should be populated.
     *
     * @param callerUid          UID of the caller that initiated this call chain.
     * @param feature            the feature for which files need to be downlaoded.
     * @param feature            the feature for which files need to be downloaded.
     *                           process.
     * @param cancellationSignal signal to attach a listener to, and receive cancellation signals
     *                           from thw client.
+32 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.service.ondeviceintelligence;

import static android.app.ondeviceintelligence.OnDeviceIntelligenceManager.AUGMENT_REQUEST_CONTENT_BUNDLE_KEY;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ON_DEVICE_INTELLIGENCE_25Q4;

import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;

@@ -431,6 +432,25 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
        }
    }

    /**
     * Provides access to feature-specific metadata via the {@link OnDeviceIntelligenceService}.
     *
     * @param feature Feature for which the associated metadata should be fetched.
     * @param executor Executor to run the consumer callback on.
     * @param resultConsumer Consumer to receive the corresponding metadata bundle.
     */
    @FlaggedApi(FLAG_ON_DEVICE_INTELLIGENCE_25Q4)
    public final void fetchFeatureMetadata(
            @NonNull Feature feature,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull Consumer<Bundle> resultConsumer) {
        try {
            mRemoteStorageService.getFeatureMetadata(
                    feature, wrapAsBundleRemoteCallback(resultConsumer, executor));
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Returns the {@link Executor} to use for incoming IPC from request sender into your service
@@ -467,6 +487,18 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
        });
    }

    private RemoteCallback wrapAsBundleRemoteCallback(
        @NonNull Consumer<Bundle> resultConsumer,
        @NonNull Executor executor) {
        return new RemoteCallback(result -> {
            if (result == null) {
                executor.execute(() -> resultConsumer.accept(Bundle.EMPTY));
            } else {
                executor.execute(() -> resultConsumer.accept(result));
            }
        });
    }

    private ProcessingCallback wrapResponseCallback(
            IResponseCallback callback) {
        return new ProcessingCallback() {
+7 −66
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceSer
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.REGISTER_MODEL_UPDATE_CALLBACK_BUNDLE_KEY;

import static com.android.server.ondeviceintelligence.BundleUtil.sanitizeInferenceParams;
import static com.android.server.ondeviceintelligence.BundleUtil.validatePfdReadOnly;
import static com.android.server.ondeviceintelligence.BundleUtil.sanitizeStateParams;
import static com.android.server.ondeviceintelligence.BundleUtil.wrapWithValidation;

@@ -62,7 +61,6 @@ import android.os.ICancellationSignal;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.RemoteException;
@@ -89,11 +87,9 @@ import com.android.internal.infra.ServiceConnector;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalManagerRegistry;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
import com.android.server.ondeviceintelligence.callbacks.ListenableDownloadCallback;

import java.io.FileDescriptor;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -624,7 +620,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
                                try {
                                    ensureRemoteIntelligenceServiceInitialized();
                                    service.registerRemoteStorageService(
                                            getIRemoteStorageService(), new IRemoteCallback.Stub() {
                                            getRemoteStorageService(), new IRemoteCallback.Stub() {
                                                @Override
                                                public void sendResult(Bundle bundle) {
                                                    final int uid = Binder.getCallingUid();
@@ -762,57 +758,12 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
    }

    @NonNull
    private IRemoteStorageService.Stub getIRemoteStorageService() {
        return new IRemoteStorageService.Stub() {
            @Override
            public void getReadOnlyFileDescriptor(
                    String filePath,
                    AndroidFuture<ParcelFileDescriptor> future) {
                ensureRemoteIntelligenceServiceInitialized();
                AndroidFuture<ParcelFileDescriptor> pfdFuture = new AndroidFuture<>();
                mRemoteOnDeviceIntelligenceService.run(
                        service -> service.getReadOnlyFileDescriptor(
                                filePath, pfdFuture));
                pfdFuture.whenCompleteAsync((pfd, error) -> {
                    try {
                        if (error != null) {
                            future.completeExceptionally(error);
                        } else {
                            validatePfdReadOnly(pfd);
                            future.complete(pfd);
                        }
                    } finally {
                        tryClosePfd(pfd);
                    }
                }, callbackExecutor);
            }

            @Override
            public void getReadOnlyFeatureFileDescriptorMap(
                    Feature feature,
                    RemoteCallback remoteCallback) {
                ensureRemoteIntelligenceServiceInitialized();
                mRemoteOnDeviceIntelligenceService.run(
                        service -> service.getReadOnlyFeatureFileDescriptorMap(
                                feature,
                                new RemoteCallback(result -> callbackExecutor.execute(() -> {
                                    try {
                                        if (result == null) {
                                            remoteCallback.sendResult(null);
                                        }
                                        for (String key : result.keySet()) {
                                            ParcelFileDescriptor pfd = result.getParcelable(key,
                                                    ParcelFileDescriptor.class);
                                            validatePfdReadOnly(pfd);
                                        }
                                        remoteCallback.sendResult(result);
                                    } finally {
                                        resourceClosingExecutor.execute(
                                                () -> BundleUtil.tryCloseResource(result));
                                    }
                                }))));
            }
        };
    private IRemoteStorageService.Stub getRemoteStorageService() {
        return new RemoteStorageService(
                this::ensureRemoteIntelligenceServiceInitialized,
                mRemoteOnDeviceIntelligenceService,
                callbackExecutor,
                resourceClosingExecutor);
    }

    private void validateServiceElevated(String serviceName, boolean checkIsolated) {
@@ -1042,16 +993,6 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
        return processingSignalFuture;
    }

    private static void tryClosePfd(ParcelFileDescriptor pfd) {
        if (pfd != null) {
            try {
                pfd.close();
            } catch (IOException e) {
                Log.e(TAG, "Failed to close parcel file descriptor ", e);
            }
        }
    }

    private synchronized Handler getTemporaryHandler() {
        if (mTemporaryHandler == null) {
            mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
Loading