Avoid waiting for the async notifyAnrDelayStarted

The binder interface is already one-way, but previously, we were
blocking for x seconds for a result.

Now, notifyAnrDelayStarted is purely async without any blocking. It is
also a best effort request because we don't attempt to connect if the
service is unavailable.

Test: Manual
Bug: 170486601
Change-Id: I2a817d71970c0c03fe0e3e3d3a4871396f887c93
This commit is contained in:
Zim
2021-03-03 13:13:26 +00:00
committed by Zimuzo Ezeozue
parent 1985e314e2
commit e3a9d5f065
3 changed files with 29 additions and 13 deletions

View File

@@ -239,14 +239,13 @@ public abstract class ExternalStorageService extends Service {
}
@Override
public void notifyAnrDelayStarted(String packageName, int uid, int tid, int reason,
RemoteCallback callback) throws RemoteException {
public void notifyAnrDelayStarted(String packageName, int uid, int tid, int reason)
throws RemoteException {
mHandler.post(() -> {
try {
onAnrDelayStarted(packageName, uid, tid, reason);
sendResult(packageName, null /* throwable */, callback);
} catch (Throwable t) {
sendResult(packageName, t, callback);
// Ignored
}
});
}

View File

@@ -32,6 +32,5 @@ oneway interface IExternalStorageService
in RemoteCallback callback);
void freeCache(@utf8InCpp String sessionId, in String volumeUuid, long bytes,
in RemoteCallback callback);
void notifyAnrDelayStarted(String packageName, int uid, int tid, int reason,
in RemoteCallback callback);
void notifyAnrDelayStarted(String packageName, int uid, int tid, int reason);
}

View File

@@ -59,6 +59,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* Controls the lifecycle of the {@link ActiveConnection} to an {@link ExternalStorageService}
@@ -323,6 +324,23 @@ public final class StorageUserConnection {
}
}
private void asyncBestEffort(Consumer<IExternalStorageService> consumer) {
synchronized (mLock) {
if (mRemoteFuture == null) {
Slog.w(TAG, "Dropping async request service is not bound");
return;
}
IExternalStorageService service = mRemoteFuture.getNow(null);
if (service == null) {
Slog.w(TAG, "Dropping async request service is not connected");
return;
}
consumer.accept(service);
}
}
private void waitForAsyncVoid(AsyncStorageServiceCall asyncCall) throws Exception {
CompletableFuture<Void> opFuture = new CompletableFuture<>();
RemoteCallback callback = new RemoteCallback(result -> setResult(result, opFuture));
@@ -407,13 +425,13 @@ public final class StorageUserConnection {
public void notifyAnrDelayStarted(String packgeName, int uid, int tid, int reason)
throws ExternalStorageServiceException {
try {
waitForAsyncVoid((service, callback) ->
service.notifyAnrDelayStarted(packgeName, uid, tid, reason, callback));
} catch (Exception e) {
throw new ExternalStorageServiceException("Failed to notify ANR delay started: "
+ packgeName, e);
}
asyncBestEffort(service -> {
try {
service.notifyAnrDelayStarted(packgeName, uid, tid, reason);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify ANR delay started", e);
}
});
}
private void setResult(Bundle result, CompletableFuture<Void> future) {