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

Commit 03d1a2ae authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Handle exceptions in AppFunctionManagerServiceImpl" into main

parents 00ba458e 43db210f
Loading
Loading
Loading
Loading
+52 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.Binder;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Slog;
import android.app.appsearch.AppSearchResult;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.appfunctions.RemoteServiceCaller.RunServiceCallCallback;
@@ -81,6 +82,17 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
        final SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback =
                new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback);

        try {
            executeAppFunctionInternal(requestInternal, safeExecuteAppFunctionCallback);
        } catch (Exception e) {
            safeExecuteAppFunctionCallback.onResult(mapExceptionToExecuteAppFunctionResponse(e));
        }
    }

    private void executeAppFunctionInternal(
            ExecuteAppFunctionAidlRequest requestInternal,
            SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback) {

        String validatedCallingPackage;
        UserHandle targetUser;
        try {
@@ -119,7 +131,7 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
            return;
        }

        mCallerValidator
        var unused = mCallerValidator
                .verifyCallerCanExecuteAppFunction(
                        validatedCallingPackage,
                        targetPackageName,
@@ -159,6 +171,12 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
                            } finally {
                                Binder.restoreCallingIdentity(token);
                            }
                        })
                .exceptionally(
                        ex -> {
                            safeExecuteAppFunctionCallback.onResult(
                                    mapExceptionToExecuteAppFunctionResponse(ex));
                            return null;
                        });
    }

@@ -235,4 +253,37 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub {
                            /* extras= */ null));
        }
    }

    private ExecuteAppFunctionResponse mapExceptionToExecuteAppFunctionResponse(Throwable e) {
        if (e instanceof AppSearchException) {
            AppSearchException appSearchException = (AppSearchException) e;
            return ExecuteAppFunctionResponse.newFailure(
                    mapAppSearchResultFailureCodeToExecuteAppFunctionResponse(
                            appSearchException.getResultCode()),
                    appSearchException.getMessage(),
                    /* extras= */ null);
        }

        return ExecuteAppFunctionResponse.newFailure(
                ExecuteAppFunctionResponse.RESULT_INTERNAL_ERROR,
                e.getMessage(),
                /* extras= */ null);
    }

    private int mapAppSearchResultFailureCodeToExecuteAppFunctionResponse(int resultCode) {
        if (resultCode == AppSearchResult.RESULT_OK) {
            throw new IllegalArgumentException(
                    "This method can only be used to convert failure result codes.");
        }

        switch (resultCode) {
            case AppSearchResult.RESULT_NOT_FOUND:
                return ExecuteAppFunctionResponse.RESULT_INVALID_ARGUMENT;
            case AppSearchResult.RESULT_INVALID_ARGUMENT:
            case AppSearchResult.RESULT_INTERNAL_ERROR:
            case AppSearchResult.RESULT_SECURITY_ERROR:
                // fall-through
        }
        return ExecuteAppFunctionResponse.RESULT_INTERNAL_ERROR;
    }
}
+37 −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 com.android.server.appfunctions;

import android.app.appsearch.AppSearchResult;

/** Exception to wrap failure result codes returned by AppSearch. */
public class AppSearchException extends RuntimeException {
    private final int resultCode;

    public AppSearchException(int resultCode, String message) {
        super(message);
        this.resultCode = resultCode;
    }

    /**
     * Returns the result code used to create this exception, typically one of the {@link
     * AppSearchResult} result codes.
     */
    public int getResultCode() {
        return resultCode;
    }
}
+11 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.app.admin.DevicePolicyManager;
import android.app.appsearch.AppSearchBatchResult;
import android.app.appsearch.AppSearchManager;
import android.app.appsearch.AppSearchManager.SearchContext;
import android.app.appsearch.AppSearchResult;
import android.app.appsearch.GenericDocument;
import android.app.appsearch.GetByDocumentIdRequest;
import android.content.Context;
@@ -38,8 +39,9 @@ import android.os.Binder;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import java.util.Objects;

import com.android.internal.infra.AndroidFuture;
import java.util.Objects;

/* Validates that caller has the correct privilege to call an AppFunctionManager Api. */
class CallerValidatorImpl implements CallerValidator {
@@ -144,7 +146,14 @@ class CallerValidatorImpl implements CallerValidator {
        if (result.isSuccess()) {
            return result.getSuccesses().get(documentId);
        }
        throw new IllegalArgumentException("No document in the result for id: " + documentId);

        AppSearchResult<GenericDocument> failedResult = result.getFailures().get(documentId);
        throw new AppSearchException(
                failedResult.getResultCode(),
                "Unable to retrieve document with id: "
                        + documentId
                        + " due to "
                        + failedResult.getErrorMessage());
    }

    private static boolean getRestrictCallersWithExecuteAppFunctionsProperty(