Handle user stopping in AppSearch.
When a user stops, we can close its AppSearchImpl instance to release resources. We'll also remove it from our cache of unlocked users so future API calls won't execute on a locked user. Bug: 179407490 Test: atest --rebuild-module-info CtsAppSearchHostTestCases Change-Id: I09953d32ad4aaf2989386e99c93623b58d564c27
This commit is contained in:
@@ -230,6 +230,18 @@ public class AppSearchManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserStopping(@NonNull TargetUser user) {
|
||||
synchronized (mUnlockedUserIdsLocked) {
|
||||
mUnlockedUserIdsLocked.remove(user.getUserIdentifier());
|
||||
try {
|
||||
mImplInstanceManager.closeAndRemoveAppSearchImplForUser(user.getUserIdentifier());
|
||||
} catch (Throwable t) {
|
||||
Log.e(TAG, "Error handling user stopping.", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyUserUnlocked(int callingUserId) {
|
||||
if (isUserLocked(callingUserId)) {
|
||||
throw new IllegalStateException("User " + callingUserId + " is locked or not running.");
|
||||
|
||||
@@ -117,10 +117,28 @@ public final class ImplInstanceManager {
|
||||
*/
|
||||
public void removeAppSearchImplForUser(@UserIdInt int userId) {
|
||||
synchronized (mInstancesLocked) {
|
||||
// no need to close and persist data to disk since we are removing them now.
|
||||
mInstancesLocked.remove(userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close and remove an instance of {@link AppSearchImpl} for the given user.
|
||||
*
|
||||
* <p>All mutation apply to this {@link AppSearchImpl} will be persisted to disk.
|
||||
*
|
||||
* @param userId The multi-user userId of the user that need to be removed.
|
||||
*/
|
||||
public void closeAndRemoveAppSearchImplForUser(@UserIdInt int userId) {
|
||||
synchronized (mInstancesLocked) {
|
||||
AppSearchImpl appSearchImpl = mInstancesLocked.get(userId);
|
||||
if (appSearchImpl != null) {
|
||||
appSearchImpl.close();
|
||||
mInstancesLocked.remove(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of AppSearchImpl for the given user.
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.appsearch.testing;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.appsearch.AppSearchBatchResult;
|
||||
import android.app.appsearch.AppSearchManager;
|
||||
import android.app.appsearch.AppSearchResult;
|
||||
@@ -37,6 +38,7 @@ import android.app.appsearch.SetSchemaResponse;
|
||||
import android.app.appsearch.StorageInfo;
|
||||
import android.app.appsearch.exceptions.AppSearchException;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
@@ -58,18 +60,29 @@ public class AppSearchSessionShimImpl implements AppSearchSessionShim {
|
||||
private final AppSearchSession mAppSearchSession;
|
||||
private final ExecutorService mExecutor;
|
||||
|
||||
/** Creates the SearchSessionShim with given SearchContext. */
|
||||
@NonNull
|
||||
public static ListenableFuture<AppSearchSessionShim> createSearchSession(
|
||||
@NonNull AppSearchManager.SearchContext searchContext) {
|
||||
return createSearchSession(searchContext, Executors.newCachedThreadPool());
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
return createSearchSession(context, searchContext, Executors.newCachedThreadPool());
|
||||
}
|
||||
|
||||
/** Creates the SearchSession with given ExecutorService. */
|
||||
/** Creates the SearchSessionShim with given SearchContext for the given user. */
|
||||
@NonNull
|
||||
public static ListenableFuture<AppSearchSessionShim> createSearchSession(
|
||||
@NonNull AppSearchManager.SearchContext searchContext, @UserIdInt int userId) {
|
||||
Context context = ApplicationProvider.getApplicationContext()
|
||||
.createContextAsUser(new UserHandle(userId), /*flags=*/ 0);
|
||||
return createSearchSession(context, searchContext, Executors.newCachedThreadPool());
|
||||
}
|
||||
|
||||
/** Creates the SearchSession with given Context and ExecutorService. */
|
||||
@NonNull
|
||||
public static ListenableFuture<AppSearchSessionShim> createSearchSession(
|
||||
@NonNull Context context,
|
||||
@NonNull AppSearchManager.SearchContext searchContext,
|
||||
@NonNull ExecutorService executor) {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
AppSearchManager appSearchManager = context.getSystemService(AppSearchManager.class);
|
||||
SettableFuture<AppSearchResult<AppSearchSession>> future = SettableFuture.create();
|
||||
appSearchManager.createSearchSession(searchContext, executor, future::set);
|
||||
|
||||
Reference in New Issue
Block a user