Merge "Decouple FUSE mount from main thread for demo user" into rvc-dev am: 931d7d2703
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12261202 Change-Id: Ifc957093c96f71273939e8f1bab5013ad9d0b506
This commit is contained in:
@@ -29,6 +29,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.ParcelableException;
|
import android.os.ParcelableException;
|
||||||
@@ -64,9 +65,6 @@ public final class StorageUserConnection {
|
|||||||
private static final String TAG = "StorageUserConnection";
|
private static final String TAG = "StorageUserConnection";
|
||||||
|
|
||||||
private static final int DEFAULT_REMOTE_TIMEOUT_SECONDS = 20;
|
private static final int DEFAULT_REMOTE_TIMEOUT_SECONDS = 20;
|
||||||
// TODO(b/161702661): Workaround for demo user to have shorter timeout.
|
|
||||||
// This allows the DevicePolicyManagerService#enableSystemApp call to succeed without ANR.
|
|
||||||
private static final int DEMO_USER_REMOTE_TIMEOUT_SECONDS = 5;
|
|
||||||
|
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -75,6 +73,7 @@ public final class StorageUserConnection {
|
|||||||
private final ActiveConnection mActiveConnection = new ActiveConnection();
|
private final ActiveConnection mActiveConnection = new ActiveConnection();
|
||||||
private final boolean mIsDemoUser;
|
private final boolean mIsDemoUser;
|
||||||
@GuardedBy("mLock") private final Map<String, Session> mSessions = new HashMap<>();
|
@GuardedBy("mLock") private final Map<String, Session> mSessions = new HashMap<>();
|
||||||
|
@GuardedBy("mLock") @Nullable private HandlerThread mHandlerThread;
|
||||||
|
|
||||||
public StorageUserConnection(Context context, int userId, StorageSessionController controller) {
|
public StorageUserConnection(Context context, int userId, StorageSessionController controller) {
|
||||||
mContext = Objects.requireNonNull(context);
|
mContext = Objects.requireNonNull(context);
|
||||||
@@ -82,6 +81,10 @@ public final class StorageUserConnection {
|
|||||||
mSessionController = controller;
|
mSessionController = controller;
|
||||||
mIsDemoUser = LocalServices.getService(UserManagerInternal.class)
|
mIsDemoUser = LocalServices.getService(UserManagerInternal.class)
|
||||||
.getUserInfo(userId).isDemo();
|
.getUserInfo(userId).isDemo();
|
||||||
|
if (mIsDemoUser) {
|
||||||
|
mHandlerThread = new HandlerThread("StorageUserConnectionThread-" + mUserId);
|
||||||
|
mHandlerThread.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,6 +191,9 @@ public final class StorageUserConnection {
|
|||||||
*/
|
*/
|
||||||
public void close() {
|
public void close() {
|
||||||
mActiveConnection.close();
|
mActiveConnection.close();
|
||||||
|
if (mIsDemoUser) {
|
||||||
|
mHandlerThread.quit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns all created sessions. */
|
/** Returns all created sessions. */
|
||||||
@@ -207,8 +213,7 @@ public final class StorageUserConnection {
|
|||||||
|
|
||||||
private void waitForLatch(CountDownLatch latch, String reason) throws TimeoutException {
|
private void waitForLatch(CountDownLatch latch, String reason) throws TimeoutException {
|
||||||
try {
|
try {
|
||||||
if (!latch.await(mIsDemoUser ? DEMO_USER_REMOTE_TIMEOUT_SECONDS
|
if (!latch.await(DEFAULT_REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
|
||||||
: DEFAULT_REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
|
|
||||||
// TODO(b/140025078): Call ActivityManager ANR API?
|
// TODO(b/140025078): Call ActivityManager ANR API?
|
||||||
Slog.wtf(TAG, "Failed to bind to the ExternalStorageService for user " + mUserId);
|
Slog.wtf(TAG, "Failed to bind to the ExternalStorageService for user " + mUserId);
|
||||||
throw new TimeoutException("Latch wait for " + reason + " elapsed");
|
throw new TimeoutException("Latch wait for " + reason + " elapsed");
|
||||||
@@ -424,15 +429,32 @@ public final class StorageUserConnection {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Slog.i(TAG, "Binding to the ExternalStorageService for user " + mUserId);
|
Slog.i(TAG, "Binding to the ExternalStorageService for user " + mUserId);
|
||||||
if (mContext.bindServiceAsUser(new Intent().setComponent(name), mServiceConnection,
|
if (mIsDemoUser) {
|
||||||
Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
|
// Schedule on a worker thread for demo user to avoid deadlock
|
||||||
UserHandle.of(mUserId))) {
|
if (mContext.bindServiceAsUser(new Intent().setComponent(name),
|
||||||
Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
|
mServiceConnection,
|
||||||
return mLatch;
|
Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
|
||||||
|
mHandlerThread.getThreadHandler(),
|
||||||
|
UserHandle.of(mUserId))) {
|
||||||
|
Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
|
||||||
|
return mLatch;
|
||||||
|
} else {
|
||||||
|
mIsConnecting = false;
|
||||||
|
throw new ExternalStorageServiceException(
|
||||||
|
"Failed to bind to the ExternalStorageService for user " + mUserId);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mIsConnecting = false;
|
if (mContext.bindServiceAsUser(new Intent().setComponent(name),
|
||||||
throw new ExternalStorageServiceException(
|
mServiceConnection,
|
||||||
"Failed to bind to the ExternalStorageService for user " + mUserId);
|
Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
|
||||||
|
UserHandle.of(mUserId))) {
|
||||||
|
Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
|
||||||
|
return mLatch;
|
||||||
|
} else {
|
||||||
|
mIsConnecting = false;
|
||||||
|
throw new ExternalStorageServiceException(
|
||||||
|
"Failed to bind to the ExternalStorageService for user " + mUserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user