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

Commit ed23887b authored by Zimuzo Ezeozue's avatar Zimuzo Ezeozue Committed by Android (Google) Code Review
Browse files

Merge changes I2a817d71,I86f800c4 into sc-dev

* changes:
  Avoid waiting for the async notifyAnrDelayStarted
  Implement ANR delay with app IO blocked reason
parents c99e9aff e3a9d5f0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IVold;

import java.util.List;
import java.util.Set;

/**
@@ -112,4 +113,10 @@ public abstract class StorageManagerInternal {
     * @param bytes number of bytes which need to be freed
     */
    public abstract void freeCache(@Nullable String volumeUuid, long bytes);

    /**
     * Returns the {@link VolumeInfo#getId()} values for the volumes matching
     * {@link VolumeInfo#isPrimary()}
     */
    public abstract List<String> getPrimaryVolumeIds();
}
+3 −4
Original line number Diff line number Diff line
@@ -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
                }
            });
        }
+1 −2
Original line number Diff line number Diff line
@@ -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);
}
 No newline at end of file
+53 −7
Original line number Diff line number Diff line
@@ -578,6 +578,12 @@ class StorageManagerService extends IStorageManager.Stub
     */
    private static final int PBKDF2_HASH_ROUNDS = 1024;

    private static final String ANR_DELAY_MILLIS_DEVICE_CONFIG_KEY =
            "anr_delay_millis";

    private static final String ANR_DELAY_NOTIFY_EXTERNAL_STORAGE_SERVICE_DEVICE_CONFIG_KEY =
            "anr_delay_notify_external_storage_service";

    /**
     * Mounted OBB tracking information. Used to track the current state of all
     * OBBs.
@@ -948,25 +954,51 @@ class StorageManagerService extends IStorageManager.Stub
        }
    }

    // TODO(b/170486601): Check transcoding status based on events pushed from the MediaProvider
    private class ExternalStorageServiceAnrController implements AnrController {
        @Override
        public long getAnrDelayMillis(String packageName, int uid) {
            int delay = SystemProperties.getInt("sys.fuse.transcode_anr_delay", 0);
            Log.d(TAG, "getAnrDelayMillis: " + packageName + ". Delaying for " + delay + "ms");
            if (!isAppIoBlocked(uid)) {
                return 0;
            }

            int delay = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
                    ANR_DELAY_MILLIS_DEVICE_CONFIG_KEY, 0);
            Slog.v(TAG, "getAnrDelayMillis for " + packageName + ". " + delay + "ms");
            return delay;
        }

        @Override
        public void onAnrDelayStarted(String packageName, int uid) {
            Log.d(TAG, "onAnrDelayStarted: " + packageName);
            if (!isAppIoBlocked(uid)) {
                return;
            }

            boolean notifyExternalStorageService = DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
                    ANR_DELAY_NOTIFY_EXTERNAL_STORAGE_SERVICE_DEVICE_CONFIG_KEY, true);
            if (notifyExternalStorageService) {
                Slog.d(TAG, "onAnrDelayStarted for " + packageName
                        + ". Notifying external storage service");
                try {
                    mStorageSessionController.notifyAnrDelayStarted(packageName, uid, 0 /* tid */,
                            StorageManager.APP_IO_BLOCKED_REASON_TRANSCODING);
                } catch (ExternalStorageServiceException e) {
                    Slog.e(TAG, "Failed to notify ANR delay started for " + packageName, e);
                }
            } else {
                // TODO(b/170973510): Implement framework spinning dialog for ANR delay
            }
        }

        @Override
        public boolean onAnrDelayCompleted(String packageName, int uid) {
            boolean show = SystemProperties.getBoolean("sys.fuse.transcode_anr_dialog_show", true);
            Log.d(TAG, "onAnrDelayCompleted: " + packageName + ". Show: " + show);
            return show;
            if (isAppIoBlocked(uid)) {
                Slog.d(TAG, "onAnrDelayCompleted for " + packageName + ". Showing ANR dialog...");
                return true;
            } else {
                Slog.d(TAG, "onAnrDelayCompleted for " + packageName + ". Skipping ANR dialog...");
                return false;
            }
        }
    }

@@ -4690,5 +4722,19 @@ class StorageManagerService extends IStorageManager.Stub
                Binder.restoreCallingIdentity(token);
            }
        }

        @Override
        public List<String> getPrimaryVolumeIds() {
            final List<String> primaryVolumeIds = new ArrayList<>();
            synchronized (mLock) {
                for (int i = 0; i < mVolumes.size(); i++) {
                    final VolumeInfo vol = mVolumes.valueAt(i);
                    if (vol.isPrimary()) {
                        primaryVolumeIds.add(vol.getId());
                    }
                }
            }
            return primaryVolumeIds;
        }
    }
}
+34 −10
Original line number Diff line number Diff line
@@ -53,11 +53,13 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
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}
@@ -72,6 +74,7 @@ public final class StorageUserConnection {
    private final Context mContext;
    private final int mUserId;
    private final StorageSessionController mSessionController;
    private final StorageManagerInternal mSmInternal;
    private final ActiveConnection mActiveConnection = new ActiveConnection();
    @GuardedBy("mLock") private final Map<String, Session> mSessions = new HashMap<>();
    @GuardedBy("mLock") private final Set<Integer> mUidsBlockedOnIo = new ArraySet<>();
@@ -81,6 +84,7 @@ public final class StorageUserConnection {
        mContext = Objects.requireNonNull(context);
        mUserId = Preconditions.checkArgumentNonnegative(userId);
        mSessionController = controller;
        mSmInternal = LocalServices.getService(StorageManagerInternal.class);
        mHandlerThread = new HandlerThread("StorageUserConnectionThread-" + mUserId);
        mHandlerThread.start();
    }
@@ -152,9 +156,13 @@ public final class StorageUserConnection {
     */
    public void notifyAnrDelayStarted(String packageName, int uid, int tid, int reason)
            throws ExternalStorageServiceException {
        List<String> primarySessionIds = mSmInternal.getPrimaryVolumeIds();
        synchronized (mSessionsLock) {
            for (String sessionId : mSessions.keySet()) {
                if (primarySessionIds.contains(sessionId)) {
                    mActiveConnection.notifyAnrDelayStarted(packageName, uid, tid, reason);
                    return;
                }
            }
        }
    }
@@ -201,8 +209,7 @@ public final class StorageUserConnection {
                return;
            }
        }
        StorageManagerInternal sm = LocalServices.getService(StorageManagerInternal.class);
        sm.resetUser(mUserId);
        mSmInternal.resetUser(mUserId);
    }

    /**
@@ -317,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));
@@ -401,13 +425,13 @@ public final class StorageUserConnection {

        public void notifyAnrDelayStarted(String packgeName, int uid, int tid, int reason)
                throws ExternalStorageServiceException {
            asyncBestEffort(service -> {
                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);
                    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) {