Loading services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +67 −62 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.appfunctions.AppFunctionExecutors.THREAD_POOL_E import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.WorkerThread; import android.app.appfunctions.AppFunctionStaticMetadataHelper; import android.app.appfunctions.ExecuteAppFunctionAidlRequest; import android.app.appfunctions.ExecuteAppFunctionResponse; Loading @@ -45,7 +46,6 @@ import com.android.server.SystemService.TargetUser; import com.android.server.appfunctions.RemoteServiceCaller.RunServiceCallCallback; import com.android.server.appfunctions.RemoteServiceCaller.ServiceUsageCompleteListener; import java.io.IOException; import java.util.Objects; import java.util.concurrent.CompletionException; Loading Loading @@ -83,23 +83,6 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { mServiceConfig = serviceConfig; } @Override public void executeAppFunction( @NonNull ExecuteAppFunctionAidlRequest requestInternal, @NonNull IExecuteAppFunctionCallback executeAppFunctionCallback) { Objects.requireNonNull(requestInternal); Objects.requireNonNull(executeAppFunctionCallback); final SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback = new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback); try { executeAppFunctionInternal(requestInternal, safeExecuteAppFunctionCallback); } catch (Exception e) { safeExecuteAppFunctionCallback.onResult(mapExceptionToExecuteAppFunctionResponse(e)); } } /** Called when the user is unlocked. */ public void onUserUnlocked(TargetUser user) { Objects.requireNonNull(user); Loading @@ -120,16 +103,20 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { } } private void executeAppFunctionInternal( ExecuteAppFunctionAidlRequest requestInternal, SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback) { @Override public void executeAppFunction( @NonNull ExecuteAppFunctionAidlRequest requestInternal, @NonNull IExecuteAppFunctionCallback executeAppFunctionCallback) { Objects.requireNonNull(requestInternal); Objects.requireNonNull(executeAppFunctionCallback); final SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback = new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback); String validatedCallingPackage; UserHandle targetUser; try { validatedCallingPackage = mCallerValidator.validateCallingPackage(requestInternal.getCallingPackage()); targetUser = mCallerValidator.verifyTargetUserHandle( requestInternal.getUserHandle(), validatedCallingPackage); } catch (SecurityException exception) { Loading @@ -141,6 +128,30 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { return; } int callingUid = Binder.getCallingUid(); int callingPid = Binder.getCallingUid(); THREAD_POOL_EXECUTOR.execute( () -> { try { executeAppFunctionInternal( requestInternal, callingUid, callingPid, safeExecuteAppFunctionCallback); } catch (Exception e) { safeExecuteAppFunctionCallback.onResult( mapExceptionToExecuteAppFunctionResponse(e)); } }); } @WorkerThread private void executeAppFunctionInternal( ExecuteAppFunctionAidlRequest requestInternal, int callingUid, int callingPid, SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback) { UserHandle targetUser = requestInternal.getUserHandle(); // TODO(b/354956319): Add and honor the new enterprise policies. if (mCallerValidator.isUserOrganizationManaged(targetUser)) { safeExecuteAppFunctionCallback.onResult( Loading @@ -165,7 +176,9 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { var unused = mCallerValidator .verifyCallerCanExecuteAppFunction( validatedCallingPackage, callingUid, callingPid, requestInternal.getCallingPackage(), targetPackageName, requestInternal.getClientRequest().getFunctionIdentifier()) .thenAccept( Loading @@ -191,8 +204,6 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { /* extras= */ null)); return; } final long token = Binder.clearCallingIdentity(); try { bindAppFunctionServiceUnchecked( requestInternal, serviceIntent, Loading @@ -201,9 +212,6 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { /* bindFlags= */ Context.BIND_AUTO_CREATE, /* timeoutInMillis= */ mServiceConfig .getExecuteAppFunctionTimeoutMillis()); } finally { Binder.restoreCallingIdentity(token); } }) .exceptionally( ex -> { Loading Loading @@ -332,9 +340,9 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { Slog.d(TAG, "AppSearch Manager not found for user: " + user.getUserIdentifier()); return; } try (FutureGlobalSearchSession futureGlobalSearchSession = FutureGlobalSearchSession futureGlobalSearchSession = new FutureGlobalSearchSession( perUserAppSearchManager, AppFunctionExecutors.THREAD_POOL_EXECUTOR)) { perUserAppSearchManager, AppFunctionExecutors.THREAD_POOL_EXECUTOR); AppFunctionMetadataObserver appFunctionMetadataObserver = new AppFunctionMetadataObserver( user.getUserHandle(), Loading @@ -351,11 +359,8 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { if (ex != null) { Slog.e(TAG, "Failed to register observer: ", ex); } futureGlobalSearchSession.close(); }); } catch (IOException ex) { Slog.e(TAG, "Failed to close observer session: ", ex); } } private void trySyncRuntimeMetadata(@NonNull TargetUser user) { Loading services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java +5 −3 Original line number Diff line number Diff line Loading @@ -60,9 +60,9 @@ public interface CallerValidator { * Validates that the caller can execute the specified app function. * * <p>The caller can execute if the app function's package name is the same as the caller's * package or the caller has either {@link Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED} or * {@link Manifest.permission.EXECUTE_APP_FUNCTIONS} granted. In some cases, app functions can * still opt-out of caller having {@link Manifest.permission.EXECUTE_APP_FUNCTIONS}. * package or the caller has either {@link Manifest.permission#EXECUTE_APP_FUNCTIONS_TRUSTED} or * {@link Manifest.permission#EXECUTE_APP_FUNCTIONS} granted. In some cases, app functions can * still opt-out of caller having {@link Manifest.permission#EXECUTE_APP_FUNCTIONS}. * * @param callerPackageName The calling package (as previously validated). * @param targetPackageName The package that owns the app function to execute. Loading @@ -70,6 +70,8 @@ public interface CallerValidator { * @return Whether the caller can execute the specified app function. */ AndroidFuture<Boolean> verifyCallerCanExecuteAppFunction( int callingUid, int callingPid, @NonNull String callerPackageName, @NonNull String targetPackageName, @NonNull String functionId); Loading services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java +32 −41 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCT import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCTION_STATIC_NAMESPACE; import static android.app.appfunctions.AppFunctionStaticMetadataHelper.STATIC_PROPERTY_RESTRICT_CALLERS_WITH_EXECUTE_APP_FUNCTIONS; import static android.app.appfunctions.AppFunctionStaticMetadataHelper.getDocumentIdForAppFunction; import static com.android.server.appfunctions.AppFunctionExecutors.THREAD_POOL_EXECUTOR; import android.Manifest; Loading @@ -41,6 +42,7 @@ import android.os.UserHandle; import android.os.UserManager; import com.android.internal.infra.AndroidFuture; import java.util.Objects; /* Validates that caller has the correct privilege to call an AppFunctionManager Api. */ Loading Loading @@ -82,7 +84,6 @@ class CallerValidatorImpl implements CallerValidator { } @Override @BinderThread @RequiresPermission( anyOf = { Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, Loading @@ -90,6 +91,8 @@ class CallerValidatorImpl implements CallerValidator { }, conditional = true) public AndroidFuture<Boolean> verifyCallerCanExecuteAppFunction( int callingUid, int callingPid, @NonNull String callerPackageName, @NonNull String targetPackageName, @NonNull String functionId) { Loading @@ -97,11 +100,11 @@ class CallerValidatorImpl implements CallerValidator { return AndroidFuture.completedFuture(true); } int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); boolean hasTrustedExecutionPermission = mContext.checkPermission( Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, pid, uid) Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (hasTrustedExecutionPermission) { Loading @@ -109,15 +112,14 @@ class CallerValidatorImpl implements CallerValidator { } boolean hasExecutionPermission = mContext.checkPermission(Manifest.permission.EXECUTE_APP_FUNCTIONS, pid, uid) mContext.checkPermission( Manifest.permission.EXECUTE_APP_FUNCTIONS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (!hasExecutionPermission) { return AndroidFuture.completedFuture(false); } final long token = Binder.clearCallingIdentity(); try { FutureAppSearchSession futureAppSearchSession = new FutureAppSearchSessionImpl( mContext.getSystemService(AppSearchManager.class), Loading @@ -132,17 +134,12 @@ class CallerValidatorImpl implements CallerValidator { .addIds(documentId) .build()) .thenApply( batchResult -> getGenericDocumentFromBatchResult(batchResult, documentId)) .thenApply( CallerValidatorImpl::getRestrictCallersWithExecuteAppFunctionsProperty) .thenApply( restrictCallersWithExecuteAppFunctions -> !restrictCallersWithExecuteAppFunctions && hasExecutionPermission); } finally { Binder.restoreCallingIdentity(token); } batchResult -> getGenericDocumentFromBatchResult(batchResult, documentId)) .thenApply(document -> !getRestrictCallersWithExecuteAppFunctionsProperty(document)) .whenComplete( (result, throwable) -> { futureAppSearchSession.close(); }); } private static GenericDocument getGenericDocumentFromBatchResult( Loading @@ -167,19 +164,13 @@ class CallerValidatorImpl implements CallerValidator { } @Override @BinderThread public boolean isUserOrganizationManaged(@NonNull UserHandle targetUser) { final long callingIdentityToken = Binder.clearCallingIdentity(); try { if (Objects.requireNonNull(mContext.getSystemService(DevicePolicyManager.class)) .isDeviceManaged()) { return true; } return Objects.requireNonNull(mContext.getSystemService(UserManager.class)) .isManagedProfile(targetUser.getIdentifier()); } finally { Binder.restoreCallingIdentity(callingIdentityToken); } } /** Loading services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSession.java +3 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,9 @@ public interface FutureAppSearchSession extends Closeable { AndroidFuture<FutureSearchResults> search( @NonNull String queryExpression, @NonNull SearchSpec searchSpec); @Override void close(); /** A future API wrapper of {@link android.app.appsearch.SearchResults}. */ interface FutureSearchResults { Loading services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSessionImpl.java +9 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ import android.app.appsearch.SetSchemaResponse; import com.android.internal.infra.AndroidFuture; import java.io.IOException; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; Loading Loading @@ -183,7 +182,15 @@ public class FutureAppSearchSessionImpl implements FutureAppSearchSession { } @Override public void close() throws IOException {} public void close() { getSessionAsync() .whenComplete( (appSearchSession, throwable) -> { if (appSearchSession != null) { appSearchSession.close(); } }); } private static final class FutureSearchResultsImpl implements FutureSearchResults { private final SearchResults mSearchResults; Loading Loading
services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +67 −62 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.server.appfunctions.AppFunctionExecutors.THREAD_POOL_E import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.WorkerThread; import android.app.appfunctions.AppFunctionStaticMetadataHelper; import android.app.appfunctions.ExecuteAppFunctionAidlRequest; import android.app.appfunctions.ExecuteAppFunctionResponse; Loading @@ -45,7 +46,6 @@ import com.android.server.SystemService.TargetUser; import com.android.server.appfunctions.RemoteServiceCaller.RunServiceCallCallback; import com.android.server.appfunctions.RemoteServiceCaller.ServiceUsageCompleteListener; import java.io.IOException; import java.util.Objects; import java.util.concurrent.CompletionException; Loading Loading @@ -83,23 +83,6 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { mServiceConfig = serviceConfig; } @Override public void executeAppFunction( @NonNull ExecuteAppFunctionAidlRequest requestInternal, @NonNull IExecuteAppFunctionCallback executeAppFunctionCallback) { Objects.requireNonNull(requestInternal); Objects.requireNonNull(executeAppFunctionCallback); final SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback = new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback); try { executeAppFunctionInternal(requestInternal, safeExecuteAppFunctionCallback); } catch (Exception e) { safeExecuteAppFunctionCallback.onResult(mapExceptionToExecuteAppFunctionResponse(e)); } } /** Called when the user is unlocked. */ public void onUserUnlocked(TargetUser user) { Objects.requireNonNull(user); Loading @@ -120,16 +103,20 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { } } private void executeAppFunctionInternal( ExecuteAppFunctionAidlRequest requestInternal, SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback) { @Override public void executeAppFunction( @NonNull ExecuteAppFunctionAidlRequest requestInternal, @NonNull IExecuteAppFunctionCallback executeAppFunctionCallback) { Objects.requireNonNull(requestInternal); Objects.requireNonNull(executeAppFunctionCallback); final SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback = new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback); String validatedCallingPackage; UserHandle targetUser; try { validatedCallingPackage = mCallerValidator.validateCallingPackage(requestInternal.getCallingPackage()); targetUser = mCallerValidator.verifyTargetUserHandle( requestInternal.getUserHandle(), validatedCallingPackage); } catch (SecurityException exception) { Loading @@ -141,6 +128,30 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { return; } int callingUid = Binder.getCallingUid(); int callingPid = Binder.getCallingUid(); THREAD_POOL_EXECUTOR.execute( () -> { try { executeAppFunctionInternal( requestInternal, callingUid, callingPid, safeExecuteAppFunctionCallback); } catch (Exception e) { safeExecuteAppFunctionCallback.onResult( mapExceptionToExecuteAppFunctionResponse(e)); } }); } @WorkerThread private void executeAppFunctionInternal( ExecuteAppFunctionAidlRequest requestInternal, int callingUid, int callingPid, SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback) { UserHandle targetUser = requestInternal.getUserHandle(); // TODO(b/354956319): Add and honor the new enterprise policies. if (mCallerValidator.isUserOrganizationManaged(targetUser)) { safeExecuteAppFunctionCallback.onResult( Loading @@ -165,7 +176,9 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { var unused = mCallerValidator .verifyCallerCanExecuteAppFunction( validatedCallingPackage, callingUid, callingPid, requestInternal.getCallingPackage(), targetPackageName, requestInternal.getClientRequest().getFunctionIdentifier()) .thenAccept( Loading @@ -191,8 +204,6 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { /* extras= */ null)); return; } final long token = Binder.clearCallingIdentity(); try { bindAppFunctionServiceUnchecked( requestInternal, serviceIntent, Loading @@ -201,9 +212,6 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { /* bindFlags= */ Context.BIND_AUTO_CREATE, /* timeoutInMillis= */ mServiceConfig .getExecuteAppFunctionTimeoutMillis()); } finally { Binder.restoreCallingIdentity(token); } }) .exceptionally( ex -> { Loading Loading @@ -332,9 +340,9 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { Slog.d(TAG, "AppSearch Manager not found for user: " + user.getUserIdentifier()); return; } try (FutureGlobalSearchSession futureGlobalSearchSession = FutureGlobalSearchSession futureGlobalSearchSession = new FutureGlobalSearchSession( perUserAppSearchManager, AppFunctionExecutors.THREAD_POOL_EXECUTOR)) { perUserAppSearchManager, AppFunctionExecutors.THREAD_POOL_EXECUTOR); AppFunctionMetadataObserver appFunctionMetadataObserver = new AppFunctionMetadataObserver( user.getUserHandle(), Loading @@ -351,11 +359,8 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { if (ex != null) { Slog.e(TAG, "Failed to register observer: ", ex); } futureGlobalSearchSession.close(); }); } catch (IOException ex) { Slog.e(TAG, "Failed to close observer session: ", ex); } } private void trySyncRuntimeMetadata(@NonNull TargetUser user) { Loading
services/appfunctions/java/com/android/server/appfunctions/CallerValidator.java +5 −3 Original line number Diff line number Diff line Loading @@ -60,9 +60,9 @@ public interface CallerValidator { * Validates that the caller can execute the specified app function. * * <p>The caller can execute if the app function's package name is the same as the caller's * package or the caller has either {@link Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED} or * {@link Manifest.permission.EXECUTE_APP_FUNCTIONS} granted. In some cases, app functions can * still opt-out of caller having {@link Manifest.permission.EXECUTE_APP_FUNCTIONS}. * package or the caller has either {@link Manifest.permission#EXECUTE_APP_FUNCTIONS_TRUSTED} or * {@link Manifest.permission#EXECUTE_APP_FUNCTIONS} granted. In some cases, app functions can * still opt-out of caller having {@link Manifest.permission#EXECUTE_APP_FUNCTIONS}. * * @param callerPackageName The calling package (as previously validated). * @param targetPackageName The package that owns the app function to execute. Loading @@ -70,6 +70,8 @@ public interface CallerValidator { * @return Whether the caller can execute the specified app function. */ AndroidFuture<Boolean> verifyCallerCanExecuteAppFunction( int callingUid, int callingPid, @NonNull String callerPackageName, @NonNull String targetPackageName, @NonNull String functionId); Loading
services/appfunctions/java/com/android/server/appfunctions/CallerValidatorImpl.java +32 −41 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCT import static android.app.appfunctions.AppFunctionStaticMetadataHelper.APP_FUNCTION_STATIC_NAMESPACE; import static android.app.appfunctions.AppFunctionStaticMetadataHelper.STATIC_PROPERTY_RESTRICT_CALLERS_WITH_EXECUTE_APP_FUNCTIONS; import static android.app.appfunctions.AppFunctionStaticMetadataHelper.getDocumentIdForAppFunction; import static com.android.server.appfunctions.AppFunctionExecutors.THREAD_POOL_EXECUTOR; import android.Manifest; Loading @@ -41,6 +42,7 @@ import android.os.UserHandle; import android.os.UserManager; import com.android.internal.infra.AndroidFuture; import java.util.Objects; /* Validates that caller has the correct privilege to call an AppFunctionManager Api. */ Loading Loading @@ -82,7 +84,6 @@ class CallerValidatorImpl implements CallerValidator { } @Override @BinderThread @RequiresPermission( anyOf = { Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, Loading @@ -90,6 +91,8 @@ class CallerValidatorImpl implements CallerValidator { }, conditional = true) public AndroidFuture<Boolean> verifyCallerCanExecuteAppFunction( int callingUid, int callingPid, @NonNull String callerPackageName, @NonNull String targetPackageName, @NonNull String functionId) { Loading @@ -97,11 +100,11 @@ class CallerValidatorImpl implements CallerValidator { return AndroidFuture.completedFuture(true); } int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); boolean hasTrustedExecutionPermission = mContext.checkPermission( Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, pid, uid) Manifest.permission.EXECUTE_APP_FUNCTIONS_TRUSTED, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (hasTrustedExecutionPermission) { Loading @@ -109,15 +112,14 @@ class CallerValidatorImpl implements CallerValidator { } boolean hasExecutionPermission = mContext.checkPermission(Manifest.permission.EXECUTE_APP_FUNCTIONS, pid, uid) mContext.checkPermission( Manifest.permission.EXECUTE_APP_FUNCTIONS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (!hasExecutionPermission) { return AndroidFuture.completedFuture(false); } final long token = Binder.clearCallingIdentity(); try { FutureAppSearchSession futureAppSearchSession = new FutureAppSearchSessionImpl( mContext.getSystemService(AppSearchManager.class), Loading @@ -132,17 +134,12 @@ class CallerValidatorImpl implements CallerValidator { .addIds(documentId) .build()) .thenApply( batchResult -> getGenericDocumentFromBatchResult(batchResult, documentId)) .thenApply( CallerValidatorImpl::getRestrictCallersWithExecuteAppFunctionsProperty) .thenApply( restrictCallersWithExecuteAppFunctions -> !restrictCallersWithExecuteAppFunctions && hasExecutionPermission); } finally { Binder.restoreCallingIdentity(token); } batchResult -> getGenericDocumentFromBatchResult(batchResult, documentId)) .thenApply(document -> !getRestrictCallersWithExecuteAppFunctionsProperty(document)) .whenComplete( (result, throwable) -> { futureAppSearchSession.close(); }); } private static GenericDocument getGenericDocumentFromBatchResult( Loading @@ -167,19 +164,13 @@ class CallerValidatorImpl implements CallerValidator { } @Override @BinderThread public boolean isUserOrganizationManaged(@NonNull UserHandle targetUser) { final long callingIdentityToken = Binder.clearCallingIdentity(); try { if (Objects.requireNonNull(mContext.getSystemService(DevicePolicyManager.class)) .isDeviceManaged()) { return true; } return Objects.requireNonNull(mContext.getSystemService(UserManager.class)) .isManagedProfile(targetUser.getIdentifier()); } finally { Binder.restoreCallingIdentity(callingIdentityToken); } } /** Loading
services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSession.java +3 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,9 @@ public interface FutureAppSearchSession extends Closeable { AndroidFuture<FutureSearchResults> search( @NonNull String queryExpression, @NonNull SearchSpec searchSpec); @Override void close(); /** A future API wrapper of {@link android.app.appsearch.SearchResults}. */ interface FutureSearchResults { Loading
services/appfunctions/java/com/android/server/appfunctions/FutureAppSearchSessionImpl.java +9 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ import android.app.appsearch.SetSchemaResponse; import com.android.internal.infra.AndroidFuture; import java.io.IOException; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; Loading Loading @@ -183,7 +182,15 @@ public class FutureAppSearchSessionImpl implements FutureAppSearchSession { } @Override public void close() throws IOException {} public void close() { getSessionAsync() .whenComplete( (appSearchSession, throwable) -> { if (appSearchSession != null) { appSearchSession.close(); } }); } private static final class FutureSearchResultsImpl implements FutureSearchResults { private final SearchResults mSearchResults; Loading