summaryrefslogtreecommitdiff
path: root/packages/NeuralNetworks
diff options
context:
space:
mode:
author Sandeep Bandaru <sandeepbandaru@google.com> 2024-11-26 18:44:20 +0000
committer Sandeep Bandaru <sandeepbandaru@google.com> 2024-12-04 22:30:24 +0000
commit46f44cebc7f9a122a66e8b31834aaf8f8ba9a80e (patch)
treef6562132ae86d1b1c40d77c13d80e34f08461ebd /packages/NeuralNetworks
parentc8b00c8aea04c1db4d30cfddb35b36367d3e08ca (diff)
Fix hidden API usages to alternative API usages
After moving the code to mainline module, all interactions from platform should be via APIs or relevant util classes cloned and jarjar'd within the module. This change moves such usages to existing APIs or makes a module-utils copy of such classes to be used independantly in the module. Flag: build.release_ondevice_intelligence_module Bug: 376427781 Change-Id: I5bc5fa5b7e2e2ba2899b4cbba536103d66a6aa19
Diffstat (limited to 'packages/NeuralNetworks')
-rw-r--r--packages/NeuralNetworks/framework/Android.bp30
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/DownloadCallback.java9
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.aidl2
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.java10
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.aidl2
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.java18
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/ICancellationSignal.aidl24
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl4
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IRemoteCallback.aidl24
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/InferenceInfo.aidl2
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceException.java8
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceFrameworkInitializer.java54
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java98
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/TokenInfo.aidl2
-rw-r--r--packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/utils/BinderUtils.java96
-rw-r--r--packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl4
-rw-r--r--packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl6
-rw-r--r--packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IRemoteStorageService.aidl2
-rw-r--r--packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java282
-rw-r--r--packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java229
-rw-r--r--packages/NeuralNetworks/service/Android.bp29
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java22
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java5
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerLocal.java (renamed from packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerInternal.java)16
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java248
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java8
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceIntelligenceService.java15
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceSandboxedInferenceService.java16
-rw-r--r--packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/callbacks/ListenableDownloadCallback.java4
29 files changed, 949 insertions, 320 deletions
diff --git a/packages/NeuralNetworks/framework/Android.bp b/packages/NeuralNetworks/framework/Android.bp
new file mode 100644
index 000000000000..6f45daae0802
--- /dev/null
+++ b/packages/NeuralNetworks/framework/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+ name: "framework-ondeviceintelligence-sources",
+ srcs: [
+ "java/**/*.aidl",
+ "java/**/*.java",
+ ],
+ path: "java",
+ visibility: [
+ "//frameworks/base:__subpackages__",
+ "//packages/modules/NeuralNetworks:__subpackages__",
+ ],
+}
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/DownloadCallback.java b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/DownloadCallback.java
index 30c6e1924942..95fb2888a3e9 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/DownloadCallback.java
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/DownloadCallback.java
@@ -23,8 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.PersistableBundle;
-
-import androidx.annotation.IntDef;
+import android.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -53,14 +52,14 @@ public interface DownloadCallback {
/**
* Sent when feature download has been initiated already, hence no need to request download
- * again. Caller can query {@link OnDeviceIntelligenceManager#getFeatureStatus} to check if
+ * again. Caller can query {@link OnDeviceIntelligenceManager#getFeatureDetails} to check if
* download has been completed.
*/
int DOWNLOAD_FAILURE_STATUS_DOWNLOADING = 3;
/**
* Sent when feature download did not start due to errors (e.g. remote exception of features not
- * available). Caller can query {@link OnDeviceIntelligenceManager#getFeatureStatus} to check
+ * available). Caller can query {@link OnDeviceIntelligenceManager#getFeatureDetails} to check
* if feature-status is {@link FeatureDetails#FEATURE_STATUS_DOWNLOADABLE}.
*/
int DOWNLOAD_FAILURE_STATUS_UNAVAILABLE = 4;
@@ -72,7 +71,7 @@ public interface DownloadCallback {
DOWNLOAD_FAILURE_STATUS_NETWORK_FAILURE,
DOWNLOAD_FAILURE_STATUS_DOWNLOADING,
DOWNLOAD_FAILURE_STATUS_UNAVAILABLE
- }, open = true)
+ })
@Retention(RetentionPolicy.SOURCE)
@interface DownloadFailureStatus {
}
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.aidl b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.aidl
index 18494d754674..47cfb4a60dc4 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.aidl
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.aidl
@@ -19,4 +19,4 @@ package android.app.ondeviceintelligence;
/**
* @hide
*/
-parcelable Feature;
+@JavaOnlyStableParcelable parcelable Feature;
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.java b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.java
index bcc56073e51c..88f4de2989e4 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.java
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/Feature.java
@@ -26,6 +26,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
+import java.util.Objects;
+
/**
* Represents a typical feature associated with on-device intelligence.
*
@@ -56,9 +58,8 @@ public final class Feature implements Parcelable {
this.mModelName = modelName;
this.mType = type;
this.mVariant = variant;
- this.mFeatureParams = featureParams;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mFeatureParams);
+ this.mFeatureParams = Objects.requireNonNull(featureParams,
+ "featureParams should be non-null.");
}
/** Returns the unique and immutable identifier of this feature. */
@@ -167,8 +168,6 @@ public final class Feature implements Parcelable {
this.mType = type;
this.mVariant = variant;
this.mFeatureParams = featureParams;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mFeatureParams);
}
public static final @NonNull Parcelable.Creator<Feature> CREATOR
@@ -200,6 +199,7 @@ public final class Feature implements Parcelable {
/**
* Provides a builder instance to create a feature for given id.
+ *
* @param id the unique identifier for the feature.
*/
public Builder(int id) {
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.aidl b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.aidl
index 0589bf8bacb9..c5b3532796cd 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.aidl
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.aidl
@@ -19,4 +19,4 @@ package android.app.ondeviceintelligence;
/**
* @hide
*/
-parcelable FeatureDetails;
+@JavaOnlyStableParcelable parcelable FeatureDetails;
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.java b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.java
index 44930f2c34f4..063cfb8c321e 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.java
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/FeatureDetails.java
@@ -19,18 +19,18 @@ package android.app.ondeviceintelligence;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcelable;
import android.os.PersistableBundle;
-import androidx.annotation.IntDef;
-
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.text.MessageFormat;
+import java.util.Objects;
/**
* Represents a status of a requested {@link Feature}.
@@ -69,7 +69,7 @@ public final class FeatureDetails implements Parcelable {
FEATURE_STATUS_DOWNLOADING,
FEATURE_STATUS_AVAILABLE,
FEATURE_STATUS_SERVICE_UNAVAILABLE
- }, open = true)
+ })
@Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Status {
@@ -79,18 +79,12 @@ public final class FeatureDetails implements Parcelable {
@Status int featureStatus,
@NonNull PersistableBundle featureDetailParams) {
this.mFeatureStatus = featureStatus;
- com.android.internal.util.AnnotationValidations.validate(
- Status.class, null, mFeatureStatus);
- this.mFeatureDetailParams = featureDetailParams;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mFeatureDetailParams);
+ this.mFeatureDetailParams = Objects.requireNonNull(featureDetailParams);
}
public FeatureDetails(
@Status int featureStatus) {
this.mFeatureStatus = featureStatus;
- com.android.internal.util.AnnotationValidations.validate(
- Status.class, null, mFeatureStatus);
this.mFeatureDetailParams = new PersistableBundle();
}
@@ -155,11 +149,7 @@ public final class FeatureDetails implements Parcelable {
PersistableBundle.CREATOR);
this.mFeatureStatus = status;
- com.android.internal.util.AnnotationValidations.validate(
- Status.class, null, mFeatureStatus);
this.mFeatureDetailParams = persistableBundle;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mFeatureDetailParams);
}
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/ICancellationSignal.aidl b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/ICancellationSignal.aidl
new file mode 100644
index 000000000000..1fe201f8f1f8
--- /dev/null
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/ICancellationSignal.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.ondeviceintelligence;
+
+/**
+ * @hide
+ */
+oneway interface ICancellationSignal {
+ void cancel();
+}
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl
index 1977a3923578..fac5ec6064f8 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl
@@ -16,8 +16,8 @@
package android.app.ondeviceintelligence;
- import com.android.internal.infra.AndroidFuture;
- import android.os.ICancellationSignal;
+ import com.android.modules.utils.AndroidFuture;
+ import android.app.ondeviceintelligence.ICancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IRemoteCallback.aidl b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IRemoteCallback.aidl
new file mode 100644
index 000000000000..6f07693dd39c
--- /dev/null
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/IRemoteCallback.aidl
@@ -0,0 +1,24 @@
+/*
+* Copyright 2024, The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package android.app.ondeviceintelligence;
+
+import android.os.Bundle;
+
+/* @hide */
+oneway interface IRemoteCallback {
+ void sendResult(in Bundle data);
+}
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/InferenceInfo.aidl b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/InferenceInfo.aidl
index 6d70fc4577a2..6f6325408979 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/InferenceInfo.aidl
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/InferenceInfo.aidl
@@ -19,4 +19,4 @@ package android.app.ondeviceintelligence;
/**
* @hide
*/
-parcelable InferenceInfo;
+@JavaOnlyStableParcelable parcelable InferenceInfo;
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceException.java b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceException.java
index 03ff563a88c0..2881c9d217dc 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceException.java
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceException.java
@@ -20,13 +20,14 @@ package android.app.ondeviceintelligence;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.PersistableBundle;
-import androidx.annotation.IntDef;
-
import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
@@ -124,8 +125,9 @@ public class OnDeviceIntelligenceException extends Exception {
PROCESSING_ERROR_SERVICE_UNAVAILABLE,
ON_DEVICE_INTELLIGENCE_SERVICE_UNAVAILABLE,
PROCESSING_UPDATE_STATUS_CONNECTION_FAILED
- }, open = true)
+ })
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+ @Retention(RetentionPolicy.SOURCE)
@interface OnDeviceIntelligenceError {
}
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceFrameworkInitializer.java b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceFrameworkInitializer.java
new file mode 100644
index 000000000000..7d35dd7f2237
--- /dev/null
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceFrameworkInitializer.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.ondeviceintelligence;
+
+import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
+
+import android.annotation.FlaggedApi;
+import android.annotation.SystemApi;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+
+/**
+ * Class for performing registration for OnDeviceIntelligence service.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+@FlaggedApi(FLAG_ENABLE_ON_DEVICE_INTELLIGENCE)
+public class OnDeviceIntelligenceFrameworkInitializer {
+ private OnDeviceIntelligenceFrameworkInitializer() {
+ }
+
+ /**
+ * Called by {@link SystemServiceRegistry}'s static initializer and registers
+ * OnDeviceIntelligence service to {@link Context}, so that {@link Context#getSystemService} can
+ * return them.
+ *
+ * @throws IllegalStateException if this is called from anywhere besides {@link
+ * SystemServiceRegistry}
+ */
+ public static void registerServiceWrappers() {
+ SystemServiceRegistry.registerContextAwareService(Context.ON_DEVICE_INTELLIGENCE_SERVICE,
+ OnDeviceIntelligenceManager.class,
+ (context, serviceBinder) -> {
+ IOnDeviceIntelligenceManager manager =
+ IOnDeviceIntelligenceManager.Stub.asInterface(serviceBinder);
+ return new OnDeviceIntelligenceManager(context, manager);
+ });
+ }
+} \ No newline at end of file
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
index 91651e317b18..dc0665a5cea7 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
@@ -23,18 +23,18 @@ import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.CurrentTimeMillisLong;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.app.ondeviceintelligence.utils.BinderUtils;
import android.content.Context;
import android.graphics.Bitmap;
-import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.IBinder;
-import android.os.ICancellationSignal;
import android.os.OutcomeReceiver;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
@@ -42,9 +42,7 @@ import android.os.RemoteException;
import android.system.OsConstants;
import android.util.Log;
-import androidx.annotation.IntDef;
-
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -80,10 +78,39 @@ public final class OnDeviceIntelligenceManager {
public static final String AUGMENT_REQUEST_CONTENT_BUNDLE_KEY =
"AugmentRequestContentBundleKey";
+ /**
+ * Timeout to be used for unbinding to the configured remote {@link
+ * android.service.ondeviceintelligence.OnDeviceIntelligenceService} if there are no requests in
+ * the queue. A value of -1 represents to never unbind.
+ *
+ * @hide
+ */
+ public static final String ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS =
+ "on_device_intelligence_unbind_timeout_ms";
+
+ /**
+ * Timeout that represents maximum idle time before which a callback should be populated.
+ *
+ * @hide
+ */
+ public static final String ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS =
+ "on_device_intelligence_idle_timeout_ms";
+
+ /**
+ * Timeout to be used for unbinding to the configured remote {@link
+ * android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService} if there are no
+ * requests in the queue. A value of -1 represents to never unbind.
+ *
+ * @hide
+ */
+ public static final String ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS =
+ "on_device_inference_unbind_timeout_ms";
+
private static final String TAG = "OnDeviceIntelligence";
private final Context mContext;
private final IOnDeviceIntelligenceManager mService;
+
/**
* @hide
*/
@@ -105,11 +132,11 @@ public final class OnDeviceIntelligenceManager {
try {
RemoteCallback callback = new RemoteCallback(result -> {
if (result == null) {
- Binder.withCleanCallingIdentity(
+ BinderUtils.withCleanCallingIdentity(
() -> callbackExecutor.execute(() -> versionConsumer.accept(0)));
}
long version = result.getLong(API_VERSION_BUNDLE_KEY);
- Binder.withCleanCallingIdentity(
+ BinderUtils.withCleanCallingIdentity(
() -> callbackExecutor.execute(() -> versionConsumer.accept(version)));
});
mService.getVersion(callback);
@@ -151,14 +178,14 @@ public final class OnDeviceIntelligenceManager {
new IFeatureCallback.Stub() {
@Override
public void onSuccess(Feature result) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> featureReceiver.onResult(result)));
}
@Override
public void onFailure(int errorCode, String errorMessage,
PersistableBundle errorParams) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> featureReceiver.onError(
new OnDeviceIntelligenceException(
errorCode, errorMessage, errorParams))));
@@ -185,14 +212,14 @@ public final class OnDeviceIntelligenceManager {
new IListFeaturesCallback.Stub() {
@Override
public void onSuccess(List<Feature> result) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> featureListReceiver.onResult(result)));
}
@Override
public void onFailure(int errorCode, String errorMessage,
PersistableBundle errorParams) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> featureListReceiver.onError(
new OnDeviceIntelligenceException(
errorCode, errorMessage, errorParams))));
@@ -223,14 +250,14 @@ public final class OnDeviceIntelligenceManager {
@Override
public void onSuccess(FeatureDetails result) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> featureDetailsReceiver.onResult(result)));
}
@Override
public void onFailure(int errorCode, String errorMessage,
PersistableBundle errorParams) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> featureDetailsReceiver.onError(
new OnDeviceIntelligenceException(errorCode,
errorMessage, errorParams))));
@@ -268,27 +295,27 @@ public final class OnDeviceIntelligenceManager {
@Override
public void onDownloadStarted(long bytesToDownload) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> callback.onDownloadStarted(bytesToDownload)));
}
@Override
public void onDownloadProgress(long bytesDownloaded) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> callback.onDownloadProgress(bytesDownloaded)));
}
@Override
public void onDownloadFailed(int failureStatus, String errorMessage,
PersistableBundle errorParams) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> callback.onDownloadFailed(failureStatus, errorMessage,
errorParams)));
}
@Override
public void onDownloadCompleted(PersistableBundle downloadParams) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> callback.onDownloadCompleted(downloadParams)));
}
};
@@ -325,14 +352,14 @@ public final class OnDeviceIntelligenceManager {
ITokenInfoCallback callback = new ITokenInfoCallback.Stub() {
@Override
public void onSuccess(TokenInfo tokenInfo) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> outcomeReceiver.onResult(tokenInfo)));
}
@Override
public void onFailure(int errorCode, String errorMessage,
PersistableBundle errorParams) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> outcomeReceiver.onError(
new OnDeviceIntelligenceException(
errorCode, errorMessage, errorParams))));
@@ -377,7 +404,7 @@ public final class OnDeviceIntelligenceManager {
IResponseCallback callback = new IResponseCallback.Stub() {
@Override
public void onSuccess(@InferenceParams Bundle result) {
- Binder.withCleanCallingIdentity(() -> {
+ BinderUtils.withCleanCallingIdentity(() -> {
callbackExecutor.execute(() -> processingCallback.onResult(result));
});
}
@@ -385,7 +412,7 @@ public final class OnDeviceIntelligenceManager {
@Override
public void onFailure(int errorCode, String errorMessage,
PersistableBundle errorParams) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> processingCallback.onError(
new OnDeviceIntelligenceException(
errorCode, errorMessage, errorParams))));
@@ -394,7 +421,7 @@ public final class OnDeviceIntelligenceManager {
@Override
public void onDataAugmentRequest(@NonNull @InferenceParams Bundle request,
@NonNull RemoteCallback contentCallback) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> processingCallback.onDataAugmentRequest(request, result -> {
Bundle bundle = new Bundle();
bundle.putParcelable(AUGMENT_REQUEST_CONTENT_BUNDLE_KEY, result);
@@ -447,7 +474,7 @@ public final class OnDeviceIntelligenceManager {
IStreamingResponseCallback callback = new IStreamingResponseCallback.Stub() {
@Override
public void onNewContent(@InferenceParams Bundle result) {
- Binder.withCleanCallingIdentity(() -> {
+ BinderUtils.withCleanCallingIdentity(() -> {
callbackExecutor.execute(
() -> streamingProcessingCallback.onPartialResult(result));
});
@@ -455,7 +482,7 @@ public final class OnDeviceIntelligenceManager {
@Override
public void onSuccess(@InferenceParams Bundle result) {
- Binder.withCleanCallingIdentity(() -> {
+ BinderUtils.withCleanCallingIdentity(() -> {
callbackExecutor.execute(
() -> streamingProcessingCallback.onResult(result));
});
@@ -464,7 +491,7 @@ public final class OnDeviceIntelligenceManager {
@Override
public void onFailure(int errorCode, String errorMessage,
PersistableBundle errorParams) {
- Binder.withCleanCallingIdentity(() -> {
+ BinderUtils.withCleanCallingIdentity(() -> {
callbackExecutor.execute(
() -> streamingProcessingCallback.onError(
new OnDeviceIntelligenceException(
@@ -476,7 +503,7 @@ public final class OnDeviceIntelligenceManager {
@Override
public void onDataAugmentRequest(@NonNull @InferenceParams Bundle content,
@NonNull RemoteCallback contentCallback) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> streamingProcessingCallback.onDataAugmentRequest(content,
contentResponse -> {
Bundle bundle = new Bundle();
@@ -537,7 +564,7 @@ public final class OnDeviceIntelligenceManager {
REQUEST_TYPE_INFERENCE,
REQUEST_TYPE_PREPARE,
REQUEST_TYPE_EMBEDDINGS
- }, open = true)
+ })
@Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.PARAMETER,
ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
@@ -614,8 +641,17 @@ public final class OnDeviceIntelligenceManager {
if (error != null || cancellationTransport == null) {
Log.e(TAG, "Unable to receive the remote cancellation signal.", error);
} else {
- cancellationSignal.setRemote(
- ICancellationSignal.Stub.asInterface(cancellationTransport));
+ ICancellationSignal remoteCancellationSignal =
+ ICancellationSignal.Stub.asInterface(cancellationTransport);
+ cancellationSignal.setOnCancelListener(
+ () -> {
+ try {
+ remoteCancellationSignal.cancel();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to propagate cancellation signal.",
+ e);
+ }
+ });
}
}, callbackExecutor);
return cancellationFuture;
@@ -638,6 +674,4 @@ public final class OnDeviceIntelligenceManager {
}, executor);
return processingSignalFuture;
}
-
-
-}
+} \ No newline at end of file
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/TokenInfo.aidl b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/TokenInfo.aidl
index 2c19c1eb246c..599b337fd20f 100644
--- a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/TokenInfo.aidl
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/TokenInfo.aidl
@@ -19,4 +19,4 @@ package android.app.ondeviceintelligence;
/**
* @hide
*/
-parcelable TokenInfo;
+@JavaOnlyStableParcelable parcelable TokenInfo;
diff --git a/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/utils/BinderUtils.java b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/utils/BinderUtils.java
new file mode 100644
index 000000000000..2916f030e3d0
--- /dev/null
+++ b/packages/NeuralNetworks/framework/java/android/app/ondeviceintelligence/utils/BinderUtils.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.ondeviceintelligence.utils;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+
+import java.util.function.Supplier;
+
+/**
+ * Collection of utilities for {@link Binder} and related classes.
+ * @hide
+ */
+public class BinderUtils {
+ /**
+ * Convenience method for running the provided action enclosed in
+ * {@link Binder#clearCallingIdentity}/{@link Binder#restoreCallingIdentity}
+ *
+ * Any exception thrown by the given action will be caught and rethrown after the call to
+ * {@link Binder#restoreCallingIdentity}
+ *
+ * Note that this is copied from Binder#withCleanCallingIdentity with minor changes
+ * since it is not public.
+ *
+ * @hide
+ */
+ public static final <T extends Exception> void withCleanCallingIdentity(
+ @NonNull ThrowingRunnable<T> action) throws T {
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ action.run();
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ /**
+ * Like a Runnable, but declared to throw an exception.
+ *
+ * @param <T> The exception class which is declared to be thrown.
+ */
+ @FunctionalInterface
+ public interface ThrowingRunnable<T extends Exception> {
+ /** @see java.lang.Runnable */
+ void run() throws T;
+ }
+
+ /**
+ * Convenience method for running the provided action enclosed in
+ * {@link Binder#clearCallingIdentity}/{@link Binder#restoreCallingIdentity} returning the
+ * result.
+ *
+ * <p>Any exception thrown by the given action will be caught and rethrown after
+ * the call to {@link Binder#restoreCallingIdentity}.
+ *
+ * Note that this is copied from Binder#withCleanCallingIdentity with minor changes
+ * since it is not public.
+ *
+ * @hide
+ */
+ public static final <T, E extends Exception> T withCleanCallingIdentity(
+ @NonNull ThrowingSupplier<T, E> action) throws E {
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ return action.get();
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ /**
+ * An equivalent of {@link Supplier}
+ *
+ * @param <T> The class which is declared to be returned.
+ * @param <E> The exception class which is declared to be thrown.
+ */
+ @FunctionalInterface
+ public interface ThrowingSupplier<T, E extends Exception> {
+ /** @see java.util.function.Supplier */
+ T get() throws E;
+ }
+} \ No newline at end of file
diff --git a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
index 45c43502d6de..cba18c1ef36d 100644
--- a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
+++ b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
@@ -18,14 +18,14 @@ package android.service.ondeviceintelligence;
import android.os.PersistableBundle;
import android.os.ParcelFileDescriptor;
-import android.os.ICancellationSignal;
+import android.app.ondeviceintelligence.ICancellationSignal;
import android.os.RemoteCallback;
import android.app.ondeviceintelligence.IDownloadCallback;
import android.app.ondeviceintelligence.Feature;
import android.app.ondeviceintelligence.IFeatureCallback;
import android.app.ondeviceintelligence.IListFeaturesCallback;
import android.app.ondeviceintelligence.IFeatureDetailsCallback;
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
import android.service.ondeviceintelligence.IRemoteProcessingService;
diff --git a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl
index 1af3b0f374f1..504fdd9b17f9 100644
--- a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl
+++ b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl
@@ -21,11 +21,11 @@ import android.app.ondeviceintelligence.IResponseCallback;
import android.app.ondeviceintelligence.ITokenInfoCallback;
import android.app.ondeviceintelligence.IProcessingSignal;
import android.app.ondeviceintelligence.Feature;
-import android.os.IRemoteCallback;
-import android.os.ICancellationSignal;
+import android.app.ondeviceintelligence.IRemoteCallback;
+import android.app.ondeviceintelligence.ICancellationSignal;
import android.os.PersistableBundle;
import android.os.Bundle;
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
import android.service.ondeviceintelligence.IRemoteStorageService;
import android.service.ondeviceintelligence.IProcessingUpdateStatusCallback;
diff --git a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IRemoteStorageService.aidl b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IRemoteStorageService.aidl
index a6f49e17d80e..253df890b198 100644
--- a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IRemoteStorageService.aidl
+++ b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/IRemoteStorageService.aidl
@@ -20,7 +20,7 @@ import android.app.ondeviceintelligence.Feature;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallback;
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
/**
* Interface for a concrete implementation to provide access to storage read access
diff --git a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
index d82fe1ca885c..6907e2bdf2b3 100644
--- a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
+++ b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
@@ -18,8 +18,6 @@ package android.service.ondeviceintelligence;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
import android.annotation.CallSuper;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
@@ -27,11 +25,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.app.ondeviceintelligence.DownloadCallback;
import android.app.ondeviceintelligence.Feature;
import android.app.ondeviceintelligence.FeatureDetails;
+import android.app.ondeviceintelligence.ICancellationSignal;
import android.app.ondeviceintelligence.IDownloadCallback;
import android.app.ondeviceintelligence.IFeatureCallback;
import android.app.ondeviceintelligence.IFeatureDetailsCallback;
@@ -39,14 +37,14 @@ import android.app.ondeviceintelligence.IListFeaturesCallback;
import android.app.ondeviceintelligence.OnDeviceIntelligenceException;
import android.app.ondeviceintelligence.OnDeviceIntelligenceManager;
import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.StateParams;
+import android.app.ondeviceintelligence.utils.BinderUtils;
import android.content.Intent;
-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.Message;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
@@ -55,10 +53,11 @@ import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -92,6 +91,18 @@ import java.util.function.LongConsumer;
@SystemApi
@FlaggedApi(FLAG_ENABLE_ON_DEVICE_INTELLIGENCE)
public abstract class OnDeviceIntelligenceService extends Service {
+ private static final int MSG_ON_READY = 1;
+ private static final int MSG_GET_VERSION = 2;
+ private static final int MSG_LIST_FEATURES = 3;
+ private static final int MSG_GET_FEATURE = 4;
+ private static final int MSG_GET_FEATURE_DETAILS = 5;
+ private static final int MSG_DOWNLOAD_FEATURE = 6;
+ private static final int MSG_GET_READ_ONLY_FILE_DESCRIPTOR = 7;
+ private static final int MSG_GET_READ_ONLY_FEATURE_FILE_DESCRIPTOR_MAP = 8;
+ private static final int MSG_REGISTER_REMOTE_SERVICES = 9;
+ private static final int MSG_INFERENCE_SERVICE_CONNECTED = 10;
+ private static final int MSG_INFERENCE_SERVICE_DISCONNECTED = 11;
+
private static final String TAG = OnDeviceIntelligenceService.class.getSimpleName();
private volatile IRemoteProcessingService mRemoteProcessingService;
@@ -101,19 +112,71 @@ public abstract class OnDeviceIntelligenceService extends Service {
@Override
public void onCreate() {
super.onCreate();
- mHandler = new Handler(Looper.getMainLooper(), null /* callback */, true /* async */);
+ mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ switch (msg.what) {
+ case MSG_ON_READY:
+ OnDeviceIntelligenceService.this.onReady();
+ break;
+ case MSG_GET_VERSION:
+ OnDeviceIntelligenceService.this.onGetVersion(
+ (LongConsumer) msg.obj);
+ break;
+ case MSG_LIST_FEATURES:
+ OnDeviceIntelligenceService.this.onListFeatures(
+ msg.arg1,
+ (OutcomeReceiver<List<Feature>, OnDeviceIntelligenceException>) msg.obj);
+ break;
+ case MSG_GET_FEATURE:
+ GetFeatureParams params = (GetFeatureParams) msg.obj;
+ OnDeviceIntelligenceService.this.onGetFeature(
+ msg.arg1,
+ msg.arg2,
+ params.callback);
+ break;
+ case MSG_GET_FEATURE_DETAILS:
+ FeatureDetailsParams detailsParams = (FeatureDetailsParams) msg.obj;
+ OnDeviceIntelligenceService.this.onGetFeatureDetails(
+ msg.arg1,
+ detailsParams.feature,
+ detailsParams.callback);
+ break;
+ case MSG_DOWNLOAD_FEATURE:
+ DownloadParams downloadParams = (DownloadParams) msg.obj;
+ OnDeviceIntelligenceService.this.onDownloadFeature(
+ msg.arg1,
+ downloadParams.feature,
+ downloadParams.cancellationSignal,
+ downloadParams.callback);
+ break;
+ case MSG_GET_READ_ONLY_FILE_DESCRIPTOR:
+ FileDescriptorParams fdParams = (FileDescriptorParams) msg.obj;
+ OnDeviceIntelligenceService.this.onGetReadOnlyFileDescriptor(
+ fdParams.fileName,
+ fdParams.future);
+ break;
+ case MSG_GET_READ_ONLY_FEATURE_FILE_DESCRIPTOR_MAP:
+ FeatureFileDescriptorParams ffdParams =
+ (FeatureFileDescriptorParams) msg.obj;
+ OnDeviceIntelligenceService.this.onGetReadOnlyFeatureFileDescriptorMap(
+ ffdParams.feature,
+ ffdParams.consumer);
+ break;
+ case MSG_REGISTER_REMOTE_SERVICES:
+ mRemoteProcessingService = (IRemoteProcessingService) msg.obj;
+ break;
+ case MSG_INFERENCE_SERVICE_CONNECTED:
+ OnDeviceIntelligenceService.this.onInferenceServiceConnected();
+ break;
+ case MSG_INFERENCE_SERVICE_DISCONNECTED:
+ OnDeviceIntelligenceService.this.onInferenceServiceDisconnected();
+ break;
+ }
+ }
+ };
}
- /**
- * The {@link Intent} that must be declared as handled by the service. To be supported, the
- * service must also require the
- * {@link android.Manifest.permission#BIND_ON_DEVICE_INTELLIGENCE_SERVICE}
- * permission so that other applications can not abuse it.
- */
- @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
- public static final String SERVICE_INTERFACE =
- "android.service.ondeviceintelligence.OnDeviceIntelligenceService";
-
/**
* @hide
@@ -126,45 +189,37 @@ public abstract class OnDeviceIntelligenceService extends Service {
/** {@inheritDoc} */
@Override
public void ready() {
- mHandler.executeOrSendMessage(
- obtainMessage(OnDeviceIntelligenceService::onReady,
- OnDeviceIntelligenceService.this));
+ mHandler.sendEmptyMessage(MSG_ON_READY);
}
@Override
public void getVersion(RemoteCallback remoteCallback) {
Objects.requireNonNull(remoteCallback);
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onGetVersion,
- OnDeviceIntelligenceService.this, l -> {
- Bundle b = new Bundle();
- b.putLong(
- OnDeviceIntelligenceManager.API_VERSION_BUNDLE_KEY,
- l);
- remoteCallback.sendResult(b);
- }));
+ Message msg = Message.obtain(mHandler, MSG_GET_VERSION,
+ (LongConsumer) (l -> {
+ Bundle b = new Bundle();
+ b.putLong(OnDeviceIntelligenceManager.API_VERSION_BUNDLE_KEY, l);
+ remoteCallback.sendResult(b);
+ }));
+ mHandler.sendMessage(msg);
}
@Override
public void listFeatures(int callerUid,
IListFeaturesCallback listFeaturesCallback) {
Objects.requireNonNull(listFeaturesCallback);
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onListFeatures,
- OnDeviceIntelligenceService.this, callerUid,
- wrapListFeaturesCallback(listFeaturesCallback)));
+ Message msg = Message.obtain(mHandler, MSG_LIST_FEATURES,
+ callerUid, 0, wrapListFeaturesCallback(listFeaturesCallback));
+ mHandler.sendMessage(msg);
}
@Override
public void getFeature(int callerUid, int id, IFeatureCallback featureCallback) {
Objects.requireNonNull(featureCallback);
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onGetFeature,
- OnDeviceIntelligenceService.this, callerUid,
- id, wrapFeatureCallback(featureCallback)));
+ Message msg = Message.obtain(mHandler, MSG_GET_FEATURE,
+ callerUid, id,
+ new GetFeatureParams(wrapFeatureCallback(featureCallback)));
+ mHandler.sendMessage(msg);
}
@@ -173,11 +228,11 @@ public abstract class OnDeviceIntelligenceService extends Service {
IFeatureDetailsCallback featureDetailsCallback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(featureDetailsCallback);
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onGetFeatureDetails,
- OnDeviceIntelligenceService.this, callerUid,
- feature, wrapFeatureDetailsCallback(featureDetailsCallback)));
+ Message msg = Message.obtain(mHandler, MSG_GET_FEATURE_DETAILS,
+ new FeatureDetailsParams(feature,
+ wrapFeatureDetailsCallback(featureDetailsCallback)));
+ msg.arg1 = callerUid;
+ mHandler.sendMessage(msg);
}
@Override
@@ -186,18 +241,24 @@ public abstract class OnDeviceIntelligenceService extends Service {
IDownloadCallback downloadCallback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(downloadCallback);
- ICancellationSignal transport = null;
+
+ CancellationSignal cancellationSignal = new CancellationSignal();
if (cancellationSignalFuture != null) {
- transport = CancellationSignal.createTransport();
+ ICancellationSignal transport = new ICancellationSignal.Stub() {
+ @Override
+ public void cancel() {
+ cancellationSignal.cancel();
+ }
+ };
cancellationSignalFuture.complete(transport);
}
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onDownloadFeature,
- OnDeviceIntelligenceService.this, callerUid,
- feature,
- CancellationSignal.fromTransport(transport),
+
+ Message msg = Message.obtain(mHandler, MSG_DOWNLOAD_FEATURE,
+ new DownloadParams(feature,
+ cancellationSignalFuture != null ? cancellationSignal : null,
wrapDownloadCallback(downloadCallback)));
+ msg.arg1 = callerUid;
+ mHandler.sendMessage(msg);
}
@Override
@@ -205,11 +266,9 @@ public abstract class OnDeviceIntelligenceService extends Service {
AndroidFuture<ParcelFileDescriptor> future) {
Objects.requireNonNull(fileName);
Objects.requireNonNull(future);
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onGetReadOnlyFileDescriptor,
- OnDeviceIntelligenceService.this, fileName,
- future));
+ Message msg = Message.obtain(mHandler, MSG_GET_READ_ONLY_FILE_DESCRIPTOR,
+ new FileDescriptorParams(fileName, future));
+ mHandler.sendMessage(msg);
}
@Override
@@ -217,16 +276,15 @@ public abstract class OnDeviceIntelligenceService extends Service {
Feature feature, RemoteCallback remoteCallback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(remoteCallback);
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onGetReadOnlyFeatureFileDescriptorMap,
- OnDeviceIntelligenceService.this, feature,
- parcelFileDescriptorMap -> {
- Bundle bundle = new Bundle();
- parcelFileDescriptorMap.forEach(bundle::putParcelable);
- remoteCallback.sendResult(bundle);
- tryClosePfds(parcelFileDescriptorMap.values());
- }));
+ Message msg = Message.obtain(mHandler,
+ MSG_GET_READ_ONLY_FEATURE_FILE_DESCRIPTOR_MAP,
+ new FeatureFileDescriptorParams(feature, parcelFileDescriptorMap -> {
+ Bundle bundle = new Bundle();
+ parcelFileDescriptorMap.forEach(bundle::putParcelable);
+ remoteCallback.sendResult(bundle);
+ tryClosePfds(parcelFileDescriptorMap.values());
+ }));
+ mHandler.sendMessage(msg);
}
@Override
@@ -237,18 +295,12 @@ public abstract class OnDeviceIntelligenceService extends Service {
@Override
public void notifyInferenceServiceConnected() {
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onInferenceServiceConnected,
- OnDeviceIntelligenceService.this));
+ mHandler.sendEmptyMessage(MSG_INFERENCE_SERVICE_CONNECTED);
}
@Override
public void notifyInferenceServiceDisconnected() {
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceIntelligenceService::onInferenceServiceDisconnected,
- OnDeviceIntelligenceService.this));
+ mHandler.sendEmptyMessage(MSG_INFERENCE_SERVICE_DISCONNECTED);
}
};
}
@@ -257,13 +309,77 @@ public abstract class OnDeviceIntelligenceService extends Service {
}
/**
+ * The {@link Intent} that must be declared as handled by the service. To be supported, the
+ * service must also require the
+ * {@link android.Manifest.permission#BIND_ON_DEVICE_INTELLIGENCE_SERVICE}
+ * permission so that other applications can not abuse it.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE =
+ "android.service.ondeviceintelligence.OnDeviceIntelligenceService";
+
+ // Parameter holder classes
+ private static class GetFeatureParams {
+ final OutcomeReceiver<Feature, OnDeviceIntelligenceException> callback;
+
+ GetFeatureParams(OutcomeReceiver<Feature, OnDeviceIntelligenceException> callback) {
+ this.callback = callback;
+ }
+ }
+
+ private static class FeatureDetailsParams {
+ final Feature feature;
+ final OutcomeReceiver<FeatureDetails, OnDeviceIntelligenceException> callback;
+
+ FeatureDetailsParams(Feature feature,
+ OutcomeReceiver<FeatureDetails, OnDeviceIntelligenceException> callback) {
+ this.feature = feature;
+ this.callback = callback;
+ }
+ }
+
+ private static class DownloadParams {
+ final Feature feature;
+ final CancellationSignal cancellationSignal;
+ final DownloadCallback callback;
+
+ DownloadParams(Feature feature, CancellationSignal cancellationSignal,
+ DownloadCallback callback) {
+ this.feature = feature;
+ this.cancellationSignal = cancellationSignal;
+ this.callback = callback;
+ }
+ }
+
+ private static class FileDescriptorParams {
+ final String fileName;
+ final AndroidFuture<ParcelFileDescriptor> future;
+
+ FileDescriptorParams(String fileName, AndroidFuture<ParcelFileDescriptor> future) {
+ this.fileName = fileName;
+ this.future = future;
+ }
+ }
+
+ private static class FeatureFileDescriptorParams {
+ final Feature feature;
+ final Consumer<Map<String, ParcelFileDescriptor>> consumer;
+
+ FeatureFileDescriptorParams(Feature feature,
+ Consumer<Map<String, ParcelFileDescriptor>> consumer) {
+ this.feature = feature;
+ this.consumer = consumer;
+ }
+ }
+
+ /**
* Using this signal to assertively a signal each time service binds successfully, used only in
* tests to get a signal that service instance is ready. This is needed because we cannot rely
* on {@link #onCreate} or {@link #onBind} to be invoke on each binding.
*
* @hide
*/
- @TestApi
+ @SystemApi
public void onReady() {
}
@@ -306,7 +422,7 @@ public abstract class OnDeviceIntelligenceService extends Service {
new IProcessingUpdateStatusCallback.Stub() {
@Override
public void onSuccess(PersistableBundle result) {
- Binder.withCleanCallingIdentity(() -> {
+ BinderUtils.withCleanCallingIdentity(() -> {
callbackExecutor.execute(
() -> statusReceiver.onResult(result));
});
@@ -314,7 +430,7 @@ public abstract class OnDeviceIntelligenceService extends Service {
@Override
public void onFailure(int errorCode, String errorMessage) {
- Binder.withCleanCallingIdentity(() -> callbackExecutor.execute(
+ BinderUtils.withCleanCallingIdentity(() -> callbackExecutor.execute(
() -> statusReceiver.onError(
new OnDeviceIntelligenceException(
errorCode, errorMessage))));
@@ -459,7 +575,7 @@ public abstract class OnDeviceIntelligenceService extends Service {
private void onGetReadOnlyFileDescriptor(@NonNull String fileName,
@NonNull AndroidFuture<ParcelFileDescriptor> future) {
Slog.v(TAG, "onGetReadOnlyFileDescriptor " + fileName);
- Binder.withCleanCallingIdentity(() -> {
+ BinderUtils.withCleanCallingIdentity(() -> {
Slog.v(TAG,
"onGetReadOnlyFileDescriptor: " + fileName + " under internal app storage.");
File f = new File(getBaseContext().getFilesDir(), fileName);
@@ -476,7 +592,11 @@ public abstract class OnDeviceIntelligenceService extends Service {
} finally {
future.complete(pfd);
if (pfd != null) {
- pfd.close();
+ try {
+ pfd.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Error closing FD", e);
+ }
}
}
});
diff --git a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
index a6aee247ebca..315dbaf919e5 100644
--- a/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
+++ b/packages/NeuralNetworks/framework/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
@@ -19,8 +19,6 @@ 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 com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
import android.annotation.CallSuper;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
@@ -31,7 +29,9 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.Service;
import android.app.ondeviceintelligence.Feature;
+import android.app.ondeviceintelligence.ICancellationSignal;
import android.app.ondeviceintelligence.IProcessingSignal;
+import android.app.ondeviceintelligence.IRemoteCallback;
import android.app.ondeviceintelligence.IResponseCallback;
import android.app.ondeviceintelligence.IStreamingResponseCallback;
import android.app.ondeviceintelligence.ITokenInfoCallback;
@@ -48,11 +48,9 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
-import android.os.HandlerExecutor;
import android.os.IBinder;
-import android.os.ICancellationSignal;
-import android.os.IRemoteCallback;
import android.os.Looper;
+import android.os.Message;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
@@ -61,7 +59,8 @@ import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
+import com.android.modules.utils.HandlerExecutor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -74,7 +73,7 @@ import java.util.function.Consumer;
/**
* Abstract base class for performing inference in a isolated process. This service exposes its
- * methods via {@link OnDeviceIntelligenceManager}.
+ * methods via {@link android.app.ondeviceintelligence.OnDeviceIntelligenceManager}.
*
* <p> A service that provides methods to perform on-device inference both in streaming and
* non-streaming fashion. Also, provides a way to register a storage service that will be used to
@@ -100,6 +99,12 @@ import java.util.function.Consumer;
public abstract class OnDeviceSandboxedInferenceService extends Service {
private static final String TAG = OnDeviceSandboxedInferenceService.class.getSimpleName();
+ private static final int MSG_TOKEN_INFO_REQUEST = 1;
+ private static final int MSG_PROCESS_REQUEST_STREAMING = 2;
+ private static final int MSG_PROCESS_REQUEST = 3;
+ private static final int MSG_UPDATE_PROCESSING_STATE = 4;
+
+
/**
* @hide
*/
@@ -133,12 +138,12 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
* @hide
*/
public static final String MODEL_LOADED_BROADCAST_INTENT =
- "android.service.ondeviceintelligence.MODEL_LOADED";
+ "android.service.ondeviceintelligence.MODEL_LOADED";
/**
* @hide
*/
public static final String MODEL_UNLOADED_BROADCAST_INTENT =
- "android.service.ondeviceintelligence.MODEL_UNLOADED";
+ "android.service.ondeviceintelligence.MODEL_UNLOADED";
/**
* @hide
@@ -152,12 +157,115 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
@Override
public void onCreate() {
super.onCreate();
- mHandler = new Handler(Looper.getMainLooper(), null /* callback */, true /* async */);
+ mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_TOKEN_INFO_REQUEST:
+ TokenInfoParams params = (TokenInfoParams) msg.obj;
+ OnDeviceSandboxedInferenceService.this.onTokenInfoRequest(
+ msg.arg1,
+ params.feature,
+ params.request,
+ params.cancellationSignal,
+ params.callback);
+ break;
+ case MSG_PROCESS_REQUEST_STREAMING:
+ StreamingRequestParams streamParams = (StreamingRequestParams) msg.obj;
+ OnDeviceSandboxedInferenceService.this.onProcessRequestStreaming(
+ msg.arg1,
+ streamParams.feature,
+ streamParams.request,
+ msg.arg2,
+ streamParams.cancellationSignal,
+ streamParams.processingSignal,
+ streamParams.callback);
+ break;
+ case MSG_PROCESS_REQUEST:
+ RequestParams requestParams = (RequestParams) msg.obj;
+ OnDeviceSandboxedInferenceService.this.onProcessRequest(
+ msg.arg1,
+ requestParams.feature,
+ requestParams.request,
+ msg.arg2,
+ requestParams.cancellationSignal,
+ requestParams.processingSignal,
+ requestParams.callback);
+ break;
+ case MSG_UPDATE_PROCESSING_STATE:
+ UpdateStateParams stateParams = (UpdateStateParams) msg.obj;
+ OnDeviceSandboxedInferenceService.this.onUpdateProcessingState(
+ stateParams.processingState,
+ stateParams.callback);
+ break;
+ }
+ }
+ };
+ }
+
+ // Parameter holder classes
+ private static class TokenInfoParams {
+ final Feature feature;
+ final Bundle request;
+ final CancellationSignal cancellationSignal;
+ final OutcomeReceiver<TokenInfo, OnDeviceIntelligenceException> callback;
+
+ TokenInfoParams(Feature feature, Bundle request, CancellationSignal cancellationSignal,
+ OutcomeReceiver<TokenInfo, OnDeviceIntelligenceException> callback) {
+ this.feature = feature;
+ this.request = request;
+ this.cancellationSignal = cancellationSignal;
+ this.callback = callback;
+ }
+ }
+
+ private static class StreamingRequestParams {
+ final Feature feature;
+ final Bundle request;
+ final CancellationSignal cancellationSignal;
+ final ProcessingSignal processingSignal;
+ final StreamingProcessingCallback callback;
+
+ StreamingRequestParams(Feature feature, Bundle request,
+ CancellationSignal cancellationSignal, ProcessingSignal processingSignal,
+ StreamingProcessingCallback callback) {
+ this.feature = feature;
+ this.request = request;
+ this.cancellationSignal = cancellationSignal;
+ this.processingSignal = processingSignal;
+ this.callback = callback;
+ }
+ }
+
+ private static class RequestParams {
+ final Feature feature;
+ final Bundle request;
+ final CancellationSignal cancellationSignal;
+ final ProcessingSignal processingSignal;
+ final ProcessingCallback callback;
+
+ RequestParams(Feature feature, Bundle request,
+ CancellationSignal cancellationSignal, ProcessingSignal processingSignal,
+ ProcessingCallback callback) {
+ this.feature = feature;
+ this.request = request;
+ this.cancellationSignal = cancellationSignal;
+ this.processingSignal = processingSignal;
+ this.callback = callback;
+ }
+ }
+
+ private static class UpdateStateParams {
+ final Bundle processingState;
+ final OutcomeReceiver<PersistableBundle, OnDeviceIntelligenceException> callback;
+
+ UpdateStateParams(Bundle processingState,
+ OutcomeReceiver<PersistableBundle, OnDeviceIntelligenceException> callback) {
+ this.processingState = processingState;
+ this.callback = callback;
+ }
}
- /**
- * @hide
- */
@Nullable
@Override
public final IBinder onBind(@NonNull Intent intent) {
@@ -168,8 +276,7 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
IRemoteCallback remoteCallback) throws RemoteException {
Objects.requireNonNull(storageService);
mRemoteStorageService = storageService;
- remoteCallback.sendResult(
- Bundle.EMPTY); //to notify caller uid to system-server.
+ remoteCallback.sendResult(Bundle.EMPTY);
}
@Override
@@ -178,34 +285,42 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
ITokenInfoCallback tokenInfoCallback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(tokenInfoCallback);
- ICancellationSignal transport = null;
+ CancellationSignal cancellationSignal = new CancellationSignal();
if (cancellationSignalFuture != null) {
- transport = CancellationSignal.createTransport();
+ ICancellationSignal transport = new ICancellationSignal.Stub() {
+ @Override
+ public void cancel() {
+ cancellationSignal.cancel();
+ }
+ };
cancellationSignalFuture.complete(transport);
}
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceSandboxedInferenceService::onTokenInfoRequest,
- OnDeviceSandboxedInferenceService.this,
- callerUid, feature,
- request,
- CancellationSignal.fromTransport(transport),
+ Message msg = Message.obtain(mHandler, MSG_TOKEN_INFO_REQUEST,
+ callerUid, 0,
+ new TokenInfoParams(feature, request,
+ cancellationSignalFuture != null ? cancellationSignal : null,
wrapTokenInfoCallback(tokenInfoCallback)));
+ mHandler.sendMessage(msg);
}
@Override
- public void processRequestStreaming(int callerUid, Feature feature, Bundle request,
- int requestType,
+ public void processRequestStreaming(int callerUid, Feature feature,
+ Bundle request, int requestType,
AndroidFuture cancellationSignalFuture,
AndroidFuture processingSignalFuture,
IStreamingResponseCallback callback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(callback);
- ICancellationSignal transport = null;
+ CancellationSignal cancellationSignal = new CancellationSignal();
if (cancellationSignalFuture != null) {
- transport = CancellationSignal.createTransport();
+ ICancellationSignal transport = new ICancellationSignal.Stub() {
+ @Override
+ public void cancel() {
+ cancellationSignal.cancel();
+ }
+ };
cancellationSignalFuture.complete(transport);
}
IProcessingSignal processingSignalTransport = null;
@@ -214,30 +329,32 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
processingSignalFuture.complete(processingSignalTransport);
}
-
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceSandboxedInferenceService::onProcessRequestStreaming,
- OnDeviceSandboxedInferenceService.this, callerUid,
- feature,
- request,
- requestType,
- CancellationSignal.fromTransport(transport),
+ Message msg = Message.obtain(mHandler, MSG_PROCESS_REQUEST_STREAMING,
+ callerUid, requestType,
+ new StreamingRequestParams(feature, request,
+ cancellationSignalFuture != null ? cancellationSignal : null,
ProcessingSignal.fromTransport(processingSignalTransport),
wrapStreamingResponseCallback(callback)));
+ mHandler.sendMessage(msg);
}
@Override
- public void processRequest(int callerUid, Feature feature, Bundle request,
- int requestType,
+ public void processRequest(int callerUid, Feature feature,
+ Bundle request, int requestType,
AndroidFuture cancellationSignalFuture,
AndroidFuture processingSignalFuture,
IResponseCallback callback) {
Objects.requireNonNull(feature);
Objects.requireNonNull(callback);
- ICancellationSignal transport = null;
+
+ CancellationSignal cancellationSignal = new CancellationSignal();
if (cancellationSignalFuture != null) {
- transport = CancellationSignal.createTransport();
+ ICancellationSignal transport = new ICancellationSignal.Stub() {
+ @Override
+ public void cancel() {
+ cancellationSignal.cancel();
+ }
+ };
cancellationSignalFuture.complete(transport);
}
IProcessingSignal processingSignalTransport = null;
@@ -245,14 +362,14 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
processingSignalTransport = ProcessingSignal.createTransport();
processingSignalFuture.complete(processingSignalTransport);
}
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceSandboxedInferenceService::onProcessRequest,
- OnDeviceSandboxedInferenceService.this, callerUid, feature,
- request, requestType,
- CancellationSignal.fromTransport(transport),
+
+ Message msg = Message.obtain(mHandler, MSG_PROCESS_REQUEST,
+ callerUid, requestType,
+ new RequestParams(feature, request,
+ cancellationSignalFuture != null ? cancellationSignal : null,
ProcessingSignal.fromTransport(processingSignalTransport),
wrapResponseCallback(callback)));
+ mHandler.sendMessage(msg);
}
@Override
@@ -260,11 +377,11 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
IProcessingUpdateStatusCallback callback) {
Objects.requireNonNull(processingState);
Objects.requireNonNull(callback);
- mHandler.executeOrSendMessage(
- obtainMessage(
- OnDeviceSandboxedInferenceService::onUpdateProcessingState,
- OnDeviceSandboxedInferenceService.this, processingState,
+
+ Message msg = Message.obtain(mHandler, MSG_UPDATE_PROCESSING_STATE,
+ new UpdateStateParams(processingState,
wrapOutcomeReceiver(callback)));
+ mHandler.sendMessage(msg);
}
};
}
@@ -471,7 +588,7 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
IResponseCallback callback) {
return new ProcessingCallback() {
@Override
- public void onResult(@androidx.annotation.NonNull Bundle result) {
+ public void onResult(@NonNull Bundle result) {
try {
callback.onSuccess(result);
} catch (RemoteException e) {
@@ -507,7 +624,7 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
IStreamingResponseCallback callback) {
return new StreamingProcessingCallback() {
@Override
- public void onPartialResult(@androidx.annotation.NonNull Bundle partialResult) {
+ public void onPartialResult(@NonNull Bundle partialResult) {
try {
callback.onNewContent(partialResult);
} catch (RemoteException e) {
@@ -516,7 +633,7 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
}
@Override
- public void onResult(@androidx.annotation.NonNull Bundle result) {
+ public void onResult(@NonNull Bundle result) {
try {
callback.onSuccess(result);
} catch (RemoteException e) {
@@ -549,7 +666,7 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
}
private RemoteCallback wrapRemoteCallback(
- @androidx.annotation.NonNull Consumer<Bundle> contentCallback) {
+ @NonNull Consumer<Bundle> contentCallback) {
return new RemoteCallback(
result -> {
if (result != null) {
@@ -604,7 +721,7 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
@Override
public void onError(
- @androidx.annotation.NonNull OnDeviceIntelligenceException error) {
+ @NonNull OnDeviceIntelligenceException error) {
try {
callback.onFailure(error.getErrorCode(), error.getMessage());
} catch (RemoteException e) {
diff --git a/packages/NeuralNetworks/service/Android.bp b/packages/NeuralNetworks/service/Android.bp
new file mode 100644
index 000000000000..05c603f5ebce
--- /dev/null
+++ b/packages/NeuralNetworks/service/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+ name: "service-ondeviceintelligence-sources",
+ srcs: [
+ "java/**/*.java",
+ ],
+ path: "java",
+ visibility: [
+ "//frameworks/base:__subpackages__",
+ "//packages/modules/NeuralNetworks:__subpackages__",
+ ],
+}
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java
index 7dd8f2fdcecb..53ef9e889997 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java
@@ -42,7 +42,7 @@ import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
@@ -50,6 +50,8 @@ import java.util.concurrent.TimeoutException;
/**
* Util methods for ensuring the Bundle passed in various methods are read-only and restricted to
* some known types.
+ *
+ * @hide
*/
public class BundleUtil {
private static final String TAG = "BundleUtil";
@@ -76,7 +78,7 @@ public class BundleUtil {
* {@link ClassNotFoundException} exception is swallowed and `null` is returned
* instead. We want to ensure cleanup of null entries in such case.
*/
- bundle.putObject(key, null);
+ bundle.putParcelable(key, null);
continue;
}
if (canMarshall(obj) || obj instanceof CursorWindow) {
@@ -122,7 +124,7 @@ public class BundleUtil {
* {@link ClassNotFoundException} exception is swallowed and `null` is returned
* instead. We want to ensure cleanup of null entries in such case.
*/
- bundle.putObject(key, null);
+ bundle.putParcelable(key, null);
continue;
}
if (canMarshall(obj)) {
@@ -167,7 +169,7 @@ public class BundleUtil {
* {@link ClassNotFoundException} exception is swallowed and `null` is returned
* instead. We want to ensure cleanup of null entries in such case.
*/
- bundle.putObject(key, null);
+ bundle.putParcelable(key, null);
continue;
}
if (canMarshall(obj)) {
@@ -317,9 +319,13 @@ public class BundleUtil {
};
}
- private static boolean canMarshall(Object obj) {
- return obj instanceof byte[] || obj instanceof PersistableBundle
- || PersistableBundle.isValidType(obj);
+ private static boolean canMarshall(Object value) {
+ return (value instanceof byte[]) || (value instanceof Integer) || (value instanceof Long) ||
+ (value instanceof Double) || (value instanceof String) ||
+ (value instanceof int[]) || (value instanceof long[]) ||
+ (value instanceof double[]) || (value instanceof String[]) ||
+ (value instanceof PersistableBundle) || (value == null) ||
+ (value instanceof Boolean) || (value instanceof boolean[]);
}
private static void ensureValidBundle(Bundle bundle) {
@@ -364,7 +370,7 @@ public class BundleUtil {
}
} catch (ErrnoException e) {
throw new BadParcelableException(
- "Invalid File descriptor passed in the Bundle.", e);
+ "Invalid File descriptor passed in the Bundle.");
}
}
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
index bef3f8048da1..e8a1b322f661 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
@@ -28,6 +28,9 @@ import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
+/**
+ * @hide
+ */
public class InferenceInfoStore {
private static final String TAG = "InferenceInfoStore";
private final TreeSet<InferenceInfo> inferenceInfos;
@@ -98,4 +101,4 @@ public class InferenceInfoStore {
info.startTimeMs).setEndTimeMillis(info.endTimeMs).setSuspendedTimeMillis(
info.suspendedTimeMs).build();
}
-} \ No newline at end of file
+}
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerInternal.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerLocal.java
index 1450dc0803d6..6badc53ae97e 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerInternal.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerLocal.java
@@ -16,7 +16,21 @@
package com.android.server.ondeviceintelligence;
-public interface OnDeviceIntelligenceManagerInternal {
+import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE;
+
+import android.annotation.FlaggedApi;
+import android.annotation.SystemApi;
+import android.annotation.SystemApi.Client;
+
+/**
+ * Exposes APIs to {@code system_server} components outside of the module boundaries.
+ * <p> This API should be access using {@link com.android.server.LocalManagerRegistry}. </p>
+ *
+ * @hide
+ */
+@SystemApi(client = Client.SYSTEM_SERVER)
+@FlaggedApi(FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+public interface OnDeviceIntelligenceManagerLocal {
/**
* Gets the uid for the process that is currently hosting the
* {@link android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService} registered on
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
index b0d69e67dac5..607ec1c71094 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
@@ -16,38 +16,42 @@
package com.android.server.ondeviceintelligence;
+import static android.app.ondeviceintelligence.flags.Flags.enableOnDeviceIntelligenceModule;
+
+import static android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.DEVICE_CONFIG_UPDATE_BUNDLE_KEY;
-import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_LOADED_BUNDLE_KEY;
-import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_UNLOADED_BUNDLE_KEY;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_LOADED_BROADCAST_INTENT;
+import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_LOADED_BUNDLE_KEY;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_UNLOADED_BROADCAST_INTENT;
+import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_UNLOADED_BUNDLE_KEY;
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.validatePfdReadOnly;
import static com.android.server.ondeviceintelligence.BundleUtil.wrapWithValidation;
-
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
-import android.app.AppGlobals;
import android.app.ondeviceintelligence.DownloadCallback;
import android.app.ondeviceintelligence.Feature;
import android.app.ondeviceintelligence.FeatureDetails;
+import android.app.ondeviceintelligence.ICancellationSignal;
import android.app.ondeviceintelligence.IDownloadCallback;
import android.app.ondeviceintelligence.IFeatureCallback;
import android.app.ondeviceintelligence.IFeatureDetailsCallback;
import android.app.ondeviceintelligence.IListFeaturesCallback;
import android.app.ondeviceintelligence.IOnDeviceIntelligenceManager;
import android.app.ondeviceintelligence.IProcessingSignal;
+import android.app.ondeviceintelligence.IRemoteCallback;
import android.app.ondeviceintelligence.IResponseCallback;
import android.app.ondeviceintelligence.IStreamingResponseCallback;
import android.app.ondeviceintelligence.ITokenInfoCallback;
import android.app.ondeviceintelligence.InferenceInfo;
import android.app.ondeviceintelligence.OnDeviceIntelligenceException;
+import android.app.ondeviceintelligence.utils.BinderUtils;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -58,16 +62,12 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
-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;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -82,17 +82,14 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
-import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.infra.AndroidFuture;
-import com.android.internal.infra.ServiceConnector;
-import com.android.internal.os.BackgroundThread;
-import com.android.server.LocalServices;
+import com.android.modules.utils.AndroidFuture;
+import com.android.modules.utils.BackgroundThread;
+import com.android.modules.utils.ServiceConnector;
+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;
@@ -182,9 +179,11 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
public void onStart() {
publishBinderService(
Context.ON_DEVICE_INTELLIGENCE_SERVICE, getOnDeviceIntelligenceManagerService(),
- /* allowIsolated = */true);
- LocalServices.addService(OnDeviceIntelligenceManagerInternal.class,
- this::getRemoteInferenceServiceUid);
+ /* allowIsolated = */ true);
+ if (enableOnDeviceIntelligenceModule()) {
+ LocalManagerRegistry.addManager(OnDeviceIntelligenceManagerLocal.class,
+ this::getRemoteInferenceServiceUid);
+ }
}
@Override
@@ -203,10 +202,10 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
public void onUserUnlocked(@NonNull TargetUser user) {
Slog.d(TAG, "onUserUnlocked: " + user.getUserHandle());
//connect to remote services(if available) during boot.
- if(user.getUserHandle().equals(UserHandle.SYSTEM)) {
+ if (user.getUserHandle().equals(UserHandle.SYSTEM)) {
try {
- ensureRemoteInferenceServiceInitialized();
- ensureRemoteIntelligenceServiceInitialized();
+ ensureRemoteInferenceServiceInitialized(/* throwServiceIfInvalid */ false);
+ ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ false);
} catch (Exception e) {
Slog.w(TAG, "Couldn't pre-start remote ondeviceintelligence services.", e);
}
@@ -251,7 +250,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
remoteCallback.sendResult(null);
return;
}
- ensureRemoteIntelligenceServiceInitialized();
+ ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ true);
mRemoteOnDeviceIntelligenceService.postAsync(
service -> {
AndroidFuture future = new AndroidFuture();
@@ -279,7 +278,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
PersistableBundle.EMPTY);
return;
}
- ensureRemoteIntelligenceServiceInitialized();
+ ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ true);
int callerUid = Binder.getCallingUid();
mRemoteOnDeviceIntelligenceService.postAsync(
service -> {
@@ -317,7 +316,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
PersistableBundle.EMPTY);
return;
}
- ensureRemoteIntelligenceServiceInitialized();
+ ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ true);
int callerUid = Binder.getCallingUid();
mRemoteOnDeviceIntelligenceService.postAsync(
service -> {
@@ -361,7 +360,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
PersistableBundle.EMPTY);
return;
}
- ensureRemoteIntelligenceServiceInitialized();
+ ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ true);
int callerUid = Binder.getCallingUid();
mRemoteOnDeviceIntelligenceService.postAsync(
service -> {
@@ -404,7 +403,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
"OnDeviceIntelligenceManagerService is unavailable",
PersistableBundle.EMPTY);
}
- ensureRemoteIntelligenceServiceInitialized();
+ ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ true);
int callerUid = Binder.getCallingUid();
mRemoteOnDeviceIntelligenceService.postAsync(
service -> {
@@ -444,7 +443,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
"OnDeviceIntelligenceManagerService is unavailable",
PersistableBundle.EMPTY);
}
- ensureRemoteInferenceServiceInitialized();
+ ensureRemoteInferenceServiceInitialized(/* throwServiceIfInvalid */ true);
int callerUid = Binder.getCallingUid();
result = mRemoteInferenceService.postAsync(
service -> {
@@ -488,7 +487,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
"OnDeviceIntelligenceManagerService is unavailable",
PersistableBundle.EMPTY);
}
- ensureRemoteInferenceServiceInitialized();
+ ensureRemoteInferenceServiceInitialized(/* throwServiceIfInvalid */ true);
int callerUid = Binder.getCallingUid();
result = mRemoteInferenceService.postAsync(
service -> {
@@ -534,7 +533,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
"OnDeviceIntelligenceManagerService is unavailable",
PersistableBundle.EMPTY);
}
- ensureRemoteInferenceServiceInitialized();
+ ensureRemoteInferenceServiceInitialized(/* throwServiceIfInvalid */ true);
int callerUid = Binder.getCallingUid();
result = mRemoteInferenceService.postAsync(
service -> {
@@ -559,20 +558,31 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
}
@Override
- public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
- String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
- new OnDeviceIntelligenceShellCommand(OnDeviceIntelligenceManagerService.this).exec(
- this, in, out, err, args, callback, resultReceiver);
+ public int handleShellCommand(@NonNull ParcelFileDescriptor in,
+ @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
+ @NonNull String[] args) {
+ return new com.android.server.ondeviceintelligence.OnDeviceIntelligenceShellCommand(
+ OnDeviceIntelligenceManagerService.this).exec(
+ this,
+ in.getFileDescriptor(),
+ out.getFileDescriptor(),
+ err.getFileDescriptor(),
+ args);
}
};
}
- private void ensureRemoteIntelligenceServiceInitialized() {
+ private boolean ensureRemoteIntelligenceServiceInitialized(boolean throwIfServiceInvalid) {
synchronized (mLock) {
if (mRemoteOnDeviceIntelligenceService == null) {
String serviceName = getServiceNames()[0];
- Binder.withCleanCallingIdentity(() -> validateServiceElevated(serviceName, false));
- mRemoteOnDeviceIntelligenceService = new RemoteOnDeviceIntelligenceService(mContext,
+ if (!BinderUtils.withCleanCallingIdentity(
+ () -> validateServiceElevated(serviceName, false,
+ throwIfServiceInvalid))) {
+ return false;
+ }
+ mRemoteOnDeviceIntelligenceService = new RemoteOnDeviceIntelligenceService(
+ mContext,
ComponentName.unflattenFromString(serviceName),
UserHandle.SYSTEM.getIdentifier());
mRemoteOnDeviceIntelligenceService.setServiceLifecycleCallbacks(
@@ -591,6 +601,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
});
}
}
+ return true;
}
@NonNull
@@ -604,13 +615,21 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
AndroidFuture<Void> result = null;
try {
sanitizeStateParams(processingState);
- ensureRemoteInferenceServiceInitialized();
- result = mRemoteInferenceService.post(
- service -> service.updateProcessingState(
- processingState, callback));
- result.whenCompleteAsync(
- (c, e) -> BundleUtil.tryCloseResource(processingState),
- resourceClosingExecutor);
+ if (ensureRemoteInferenceServiceInitialized(/* throwServiceIfInvalid */
+ false)) {
+ result = mRemoteInferenceService.post(
+ service -> service.updateProcessingState(
+ processingState, callback));
+ result.whenCompleteAsync(
+ (c, e) -> BundleUtil.tryCloseResource(processingState),
+ resourceClosingExecutor);
+ } else {
+ callback.onFailure(
+ OnDeviceIntelligenceException.PROCESSING_ERROR_SERVICE_UNAVAILABLE,
+ "Remote service cannot be initialized.");
+ }
+ } catch (RemoteException e) {
+ Slog.w("Failed to invoke updateProcessingState", e);
} finally {
if (result == null) {
resourceClosingExecutor.execute(
@@ -622,11 +641,14 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
};
}
- private void ensureRemoteInferenceServiceInitialized() {
+ private boolean ensureRemoteInferenceServiceInitialized(boolean throwIfServiceInvalid) {
synchronized (mLock) {
if (mRemoteInferenceService == null) {
String serviceName = getServiceNames()[1];
- Binder.withCleanCallingIdentity(() -> validateServiceElevated(serviceName, true));
+ if (!BinderUtils.withCleanCallingIdentity(
+ () -> validateServiceElevated(serviceName, true, throwIfServiceInvalid))) {
+ return false;
+ }
mRemoteInferenceService = new RemoteOnDeviceSandboxedInferenceService(mContext,
ComponentName.unflattenFromString(serviceName),
UserHandle.SYSTEM.getIdentifier());
@@ -636,7 +658,11 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
public void onConnected(
@NonNull IOnDeviceSandboxedInferenceService service) {
try {
- ensureRemoteIntelligenceServiceInitialized();
+ if (!ensureRemoteIntelligenceServiceInitialized(
+ /* throwServiceIfInvalid */
+ false)) {
+ return;
+ }
service.registerRemoteStorageService(
getIRemoteStorageService(), new IRemoteCallback.Stub() {
@Override
@@ -659,20 +685,29 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
@Override
public void onDisconnected(
@NonNull IOnDeviceSandboxedInferenceService service) {
- ensureRemoteIntelligenceServiceInitialized();
+ if (!ensureRemoteIntelligenceServiceInitialized(
+ /* throwServiceIfInvalid */
+ false)) {
+ return;
+ }
mRemoteOnDeviceIntelligenceService.run(
IOnDeviceIntelligenceService::notifyInferenceServiceDisconnected);
}
@Override
public void onBinderDied() {
- ensureRemoteIntelligenceServiceInitialized();
+ if (!ensureRemoteIntelligenceServiceInitialized(
+ /* throwServiceIfInvalid */
+ false)) {
+ return;
+ }
mRemoteOnDeviceIntelligenceService.run(
IOnDeviceIntelligenceService::notifyInferenceServiceDisconnected);
}
});
}
}
+ return true;
}
private void registerModelLoadingBroadcasts(IOnDeviceSandboxedInferenceService service) {
@@ -743,9 +778,13 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
if (mTemporaryConfigNamespace != null) {
return mTemporaryConfigNamespace;
}
-
- return mContext.getResources().getString(
- R.string.config_defaultOnDeviceIntelligenceDeviceConfigNamespace);
+ return mContext.getResources()
+ .getString(
+ mContext.getResources()
+ .getIdentifier(
+ "config_defaultOnDeviceIntelligenceDeviceConfigNamespace",
+ "string",
+ "android"));
}
}
@@ -759,7 +798,11 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
}
Bundle bundle = new Bundle();
bundle.putParcelable(DEVICE_CONFIG_UPDATE_BUNDLE_KEY, persistableBundle);
- ensureRemoteInferenceServiceInitialized();
+ if (!ensureRemoteIntelligenceServiceInitialized(
+ /* throwServiceIfInvalid */
+ false)) {
+ return;
+ }
mRemoteInferenceService.run(service -> service.updateProcessingState(bundle,
new IProcessingUpdateStatusCallback.Stub() {
@Override
@@ -782,7 +825,13 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
public void getReadOnlyFileDescriptor(
String filePath,
AndroidFuture<ParcelFileDescriptor> future) {
- ensureRemoteIntelligenceServiceInitialized();
+ if (!ensureRemoteIntelligenceServiceInitialized(
+ /* throwServiceIfInvalid */
+ false)) {
+ future.completeExceptionally(new OnDeviceIntelligenceException(
+ OnDeviceIntelligenceException.PROCESSING_ERROR_NOT_AVAILABLE));
+ return;
+ }
AndroidFuture<ParcelFileDescriptor> pfdFuture = new AndroidFuture<>();
mRemoteOnDeviceIntelligenceService.run(
service -> service.getReadOnlyFileDescriptor(
@@ -805,7 +854,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
public void getReadOnlyFeatureFileDescriptorMap(
Feature feature,
RemoteCallback remoteCallback) {
- ensureRemoteIntelligenceServiceInitialized();
+ ensureRemoteIntelligenceServiceInitialized(/* throwServiceIfInvalid */ true);
mRemoteOnDeviceIntelligenceService.run(
service -> service.getReadOnlyFeatureFileDescriptorMap(
feature,
@@ -829,40 +878,48 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
};
}
- private void validateServiceElevated(String serviceName, boolean checkIsolated) {
+ private boolean validateServiceElevated(String serviceName, boolean checkIsolated,
+ boolean throwIfServiceInvalid) {
try {
if (TextUtils.isEmpty(serviceName)) {
- throw new IllegalStateException(
- "Remote service is not configured to complete the request");
+ if (throwIfServiceInvalid) {
+ throw new IllegalStateException(
+ "Remote service is not configured to complete the request");
+ }
+ return false;
}
ComponentName serviceComponent = ComponentName.unflattenFromString(
serviceName);
- ServiceInfo serviceInfo = AppGlobals.getPackageManager().getServiceInfo(
+ ServiceInfo serviceInfo = mContext.getPackageManager().getServiceInfo(
serviceComponent,
PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- UserHandle.SYSTEM.getIdentifier());
- if (serviceInfo != null) {
- if (!checkIsolated) {
- checkServiceRequiresPermission(serviceInfo,
- Manifest.permission.BIND_ON_DEVICE_INTELLIGENCE_SERVICE);
- return;
- }
-
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+ if (!checkIsolated) {
checkServiceRequiresPermission(serviceInfo,
- Manifest.permission.BIND_ON_DEVICE_SANDBOXED_INFERENCE_SERVICE);
- if (!isIsolatedService(serviceInfo)) {
- throw new SecurityException(
- "Call required an isolated service, but the configured service: "
- + serviceName + ", is not isolated");
- }
- } else {
+ Manifest.permission.BIND_ON_DEVICE_INTELLIGENCE_SERVICE);
+ return true;
+ }
+
+ checkServiceRequiresPermission(serviceInfo,
+ Manifest.permission.BIND_ON_DEVICE_SANDBOXED_INFERENCE_SERVICE);
+ if (!isIsolatedService(serviceInfo)) {
+ throw new SecurityException(
+ "Call required an isolated service, but the configured service: "
+ + serviceName + ", is not isolated");
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ if (throwIfServiceInvalid) {
throw new IllegalStateException(
"Remote service is not configured to complete the request.");
}
- } catch (RemoteException e) {
- throw new IllegalStateException("Could not fetch service info for remote services", e);
+ return false;
+ } catch (SecurityException e) {
+ if (throwIfServiceInvalid) {
+ throw e;
+ }
+ return false;
}
+ return true;
}
private static void checkServiceRequiresPermission(ServiceInfo serviceInfo,
@@ -870,8 +927,8 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
final String permission = serviceInfo.permission;
if (!requiredPermission.equals(permission)) {
throw new SecurityException(String.format(
- "Service %s requires %s permission. Found %s permission",
- serviceInfo.getComponentName(),
+ "%s requires %s permission. Found %s permission",
+ serviceInfo,
requiredPermission,
serviceInfo.permission));
}
@@ -909,10 +966,22 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
return mTemporaryServiceNames;
}
}
- return new String[]{mContext.getResources().getString(
- R.string.config_defaultOnDeviceIntelligenceService),
- mContext.getResources().getString(
- R.string.config_defaultOnDeviceSandboxedInferenceService)};
+ return new String[]{
+ mContext.getResources()
+ .getString(
+ mContext.getResources()
+ .getIdentifier(
+ "config_defaultOnDeviceIntelligenceService",
+ "string",
+ "android")),
+ mContext.getResources()
+ .getString(
+ mContext.getResources()
+ .getIdentifier(
+ "config_defaultOnDeviceSandboxedInferenceService",
+ "string",
+ "android"))
+ };
}
protected String[] getBroadcastKeys() throws Resources.NotFoundException {
@@ -923,7 +992,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
}
}
- return new String[]{ MODEL_LOADED_BROADCAST_INTENT, MODEL_UNLOADED_BROADCAST_INTENT };
+ return new String[]{MODEL_LOADED_BROADCAST_INTENT, MODEL_UNLOADED_BROADCAST_INTENT};
}
@RequiresPermission(Manifest.permission.USE_ON_DEVICE_INTELLIGENCE)
@@ -1068,7 +1137,7 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
private synchronized Handler getTemporaryHandler() {
if (mTemporaryHandler == null) {
- mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
+ mTemporaryHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
synchronized (mLock) {
@@ -1090,10 +1159,13 @@ public class OnDeviceIntelligenceManagerService extends SystemService {
return mTemporaryHandler;
}
+ // Using #getLong here as the timeout settings are only applicable to the services running in
+ // SYSTEM user only.
+ @SuppressWarnings("NonUserGetterCalled")
private long getIdleTimeoutMs() {
- return Settings.Secure.getLongForUser(mContext.getContentResolver(),
- Settings.Secure.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS, TimeUnit.HOURS.toMillis(1),
- mContext.getUserId());
+ return Settings.Secure.getLong(mContext.getContentResolver(),
+ ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS,
+ TimeUnit.HOURS.toMillis(1));
}
private int getRemoteInferenceServiceUid() {
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java
index d2c84fa1b18a..c641de8b47b1 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceShellCommand.java
@@ -18,12 +18,16 @@ package com.android.server.ondeviceintelligence;
import android.annotation.NonNull;
import android.os.Binder;
-import android.os.ShellCommand;
+
+import com.android.modules.utils.BasicShellCommandHandler;
import java.io.PrintWriter;
import java.util.Objects;
-final class OnDeviceIntelligenceShellCommand extends ShellCommand {
+/**
+ * @hide
+ */
+final class OnDeviceIntelligenceShellCommand extends BasicShellCommandHandler {
private static final String TAG = OnDeviceIntelligenceShellCommand.class.getSimpleName();
@NonNull
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceIntelligenceService.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceIntelligenceService.java
index ac9747aa83b3..0c43a309c456 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceIntelligenceService.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceIntelligenceService.java
@@ -16,6 +16,7 @@
package com.android.server.ondeviceintelligence;
+import static android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.BIND_INCLUDE_CAPABILITIES;
@@ -26,13 +27,15 @@ import android.provider.Settings;
import android.service.ondeviceintelligence.IOnDeviceIntelligenceService;
import android.service.ondeviceintelligence.OnDeviceIntelligenceService;
-import com.android.internal.infra.ServiceConnector;
+import com.android.modules.utils.ServiceConnector;
import java.util.concurrent.TimeUnit;
/**
* Manages the connection to the remote on-device intelligence service. Also, handles unbinding
* logic set by the service implementation via a Secure Settings flag.
+ *
+ * @hide
*/
public class RemoteOnDeviceIntelligenceService extends
ServiceConnector.Impl<IOnDeviceIntelligenceService> {
@@ -56,11 +59,13 @@ public class RemoteOnDeviceIntelligenceService extends
return LONG_TIMEOUT;
}
+ // Using #getLong here as the timeout settings are only applicable to the services running in
+ // SYSTEM user only.
@Override
+ @SuppressWarnings("NonUserGetterCalled")
protected long getAutoDisconnectTimeoutMs() {
- return Settings.Secure.getLongForUser(mContext.getContentResolver(),
- Settings.Secure.ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS,
- TimeUnit.SECONDS.toMillis(30),
- mContext.getUserId());
+ return Settings.Secure.getLong(mContext.getContentResolver(),
+ ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS,
+ TimeUnit.SECONDS.toMillis(30));
}
}
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceSandboxedInferenceService.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceSandboxedInferenceService.java
index 18b13838ea7c..8c5d5a7ba736 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceSandboxedInferenceService.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/RemoteOnDeviceSandboxedInferenceService.java
@@ -16,6 +16,7 @@
package com.android.server.ondeviceintelligence;
+import static android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.BIND_INCLUDE_CAPABILITIES;
@@ -26,7 +27,7 @@ import android.provider.Settings;
import android.service.ondeviceintelligence.IOnDeviceSandboxedInferenceService;
import android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService;
-import com.android.internal.infra.ServiceConnector;
+import com.android.modules.utils.ServiceConnector;
import java.util.concurrent.TimeUnit;
@@ -35,6 +36,8 @@ import java.util.concurrent.TimeUnit;
* Manages the connection to the remote on-device sand boxed inference service. Also, handles
* unbinding
* logic set by the service implementation via a SecureSettings flag.
+ *
+ * @hide
*/
public class RemoteOnDeviceSandboxedInferenceService extends
ServiceConnector.Impl<IOnDeviceSandboxedInferenceService> {
@@ -65,12 +68,13 @@ public class RemoteOnDeviceSandboxedInferenceService extends
return LONG_TIMEOUT;
}
-
+ // Using #getLong here as the timeout settings are only applicable to the services running in
+ // SYSTEM user only.
@Override
+ @SuppressWarnings("NonUserGetterCalled")
protected long getAutoDisconnectTimeoutMs() {
- return Settings.Secure.getLongForUser(mContext.getContentResolver(),
- Settings.Secure.ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS,
- TimeUnit.SECONDS.toMillis(30),
- mContext.getUserId());
+ return Settings.Secure.getLong(mContext.getContentResolver(),
+ ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS,
+ TimeUnit.SECONDS.toMillis(30));
}
}
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/callbacks/ListenableDownloadCallback.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/callbacks/ListenableDownloadCallback.java
index 32f0698a8f9c..249bcd37db5d 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/callbacks/ListenableDownloadCallback.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/callbacks/ListenableDownloadCallback.java
@@ -21,7 +21,7 @@ import android.os.Handler;
import android.os.PersistableBundle;
import android.os.RemoteException;
-import com.android.internal.infra.AndroidFuture;
+import com.android.modules.utils.AndroidFuture;
import java.util.concurrent.TimeoutException;
@@ -32,6 +32,8 @@ import java.util.concurrent.TimeoutException;
* some cases. Instead, in such cases we rely on the remote service sending progress updates and if
* there are *no* progress callbacks in the duration of {@link #idleTimeoutMs}, we can assume the
* download will not complete and enabling faster cleanup.
+ *
+ * @hide
*/
public class ListenableDownloadCallback extends IDownloadCallback.Stub implements Runnable {
private final IDownloadCallback callback;