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

Commit 8e09179a authored by Aldi Fahrezi's avatar Aldi Fahrezi Committed by Android (Google) Code Review
Browse files

Merge "Add AppFunctions Sidecar" into main

parents 61d5ea82 69b20806
Loading
Loading
Loading
Loading
+47 −22
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
@@ -60,20 +61,39 @@ public abstract class AppFunctionService extends Service {
    @NonNull
    public static final String SERVICE_INTERFACE = "android.app.appfunctions.AppFunctionService";

    private final Binder mBinder =
            new IAppFunctionService.Stub() {
    /**
     * Functional interface to represent the execution logic of an app function.
     *
     * @hide
     */
    @FunctionalInterface
    public interface OnExecuteFunction {
        /**
         * Performs the semantic of executing the function specified by the provided request and
         * return the response through the provided callback.
         */
        void perform(
                @NonNull ExecuteAppFunctionRequest request,
                @NonNull Consumer<ExecuteAppFunctionResponse> callback);
    }

    /** @hide */
    @NonNull
    public static Binder createBinder(
            @NonNull Context context, @NonNull OnExecuteFunction onExecuteFunction) {
        return new IAppFunctionService.Stub() {
            @Override
            public void executeAppFunction(
                    @NonNull ExecuteAppFunctionRequest request,
                    @NonNull IExecuteAppFunctionCallback callback) {
                    if (AppFunctionService.this.checkCallingPermission(BIND_APP_FUNCTION_SERVICE)
                if (context.checkCallingPermission(BIND_APP_FUNCTION_SERVICE)
                        == PERMISSION_DENIED) {
                    throw new SecurityException("Can only be called by the system server.");
                }
                SafeOneTimeExecuteAppFunctionCallback safeCallback =
                        new SafeOneTimeExecuteAppFunctionCallback(callback);
                try {
                        AppFunctionService.this.onExecuteFunction(request, safeCallback::onResult);
                    onExecuteFunction.perform(request, safeCallback::onResult);
                } catch (Exception ex) {
                    // Apps should handle exceptions. But if they don't, report the error on
                    // behalf of them.
@@ -83,6 +103,11 @@ public abstract class AppFunctionService extends Service {
                }
            }
        };
    }

    private final Binder mBinder = createBinder(
            AppFunctionService.this,
            AppFunctionService.this::onExecuteFunction);

    @NonNull
    @Override
+31 −0
Original line number Diff line number Diff line
// 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"],
}

java_sdk_library {
    name: "com.google.android.appfunctions.sidecar",
    owner: "google",
    srcs: ["java/**/*.java"],
    api_packages: ["com.google.android.appfunctions.sidecar"],
    dex_preopt: {
        enabled: false,
    },
    system_ext_specific: true,
    no_dist: true,
    unsafe_ignore_missing_latest_api: true,
}
+49 −0
Original line number Diff line number Diff line
// Signature format: 2.0
package com.google.android.appfunctions.sidecar {

  public final class AppFunctionManager {
    ctor public AppFunctionManager(android.content.Context);
    method public void executeAppFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<com.google.android.appfunctions.sidecar.ExecuteAppFunctionResponse>);
  }

  public abstract class AppFunctionService extends android.app.Service {
    ctor public AppFunctionService();
    method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
    method @MainThread public abstract void onExecuteFunction(@NonNull com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest, @NonNull java.util.function.Consumer<com.google.android.appfunctions.sidecar.ExecuteAppFunctionResponse>);
    field @NonNull public static final String BIND_APP_FUNCTION_SERVICE = "android.permission.BIND_APP_FUNCTION_SERVICE";
    field @NonNull public static final String SERVICE_INTERFACE = "android.app.appfunctions.AppFunctionService";
  }

  public final class ExecuteAppFunctionRequest {
    method @NonNull public android.os.Bundle getExtras();
    method @NonNull public String getFunctionIdentifier();
    method @NonNull public android.app.appsearch.GenericDocument getParameters();
    method @NonNull public String getTargetPackageName();
  }

  public static final class ExecuteAppFunctionRequest.Builder {
    ctor public ExecuteAppFunctionRequest.Builder(@NonNull String, @NonNull String);
    method @NonNull public com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest build();
    method @NonNull public com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest.Builder setExtras(@NonNull android.os.Bundle);
    method @NonNull public com.google.android.appfunctions.sidecar.ExecuteAppFunctionRequest.Builder setParameters(@NonNull android.app.appsearch.GenericDocument);
  }

  public final class ExecuteAppFunctionResponse {
    method @Nullable public String getErrorMessage();
    method @NonNull public android.os.Bundle getExtras();
    method public int getResultCode();
    method @NonNull public android.app.appsearch.GenericDocument getResultDocument();
    method public boolean isSuccess();
    method @NonNull public static com.google.android.appfunctions.sidecar.ExecuteAppFunctionResponse newFailure(int, @Nullable String, @Nullable android.os.Bundle);
    method @NonNull public static com.google.android.appfunctions.sidecar.ExecuteAppFunctionResponse newSuccess(@NonNull android.app.appsearch.GenericDocument, @Nullable android.os.Bundle);
    field public static final String PROPERTY_RETURN_VALUE = "returnValue";
    field public static final int RESULT_APP_UNKNOWN_ERROR = 2; // 0x2
    field public static final int RESULT_DENIED = 1; // 0x1
    field public static final int RESULT_INTERNAL_ERROR = 3; // 0x3
    field public static final int RESULT_INVALID_ARGUMENT = 4; // 0x4
    field public static final int RESULT_OK = 0; // 0x0
    field public static final int RESULT_TIMED_OUT = 5; // 0x5
  }

}
+1 −0
Original line number Diff line number Diff line
// Signature format: 2.0
+1 −0
Original line number Diff line number Diff line
// Signature format: 2.0
Loading