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

Commit d18a2ceb authored by Zim's avatar Zim Committed by Zimuzo Ezeozue
Browse files

Get ANR delay from the MediaProvider

StorageManagerService registers an AnrController with the
ActivityManager so that when an app is about to ANR, it receives a
callback to get an ANR delay. This request is forwarded to the
MediaProvider that checks if the uid is blocked on a transcoding job
and if so returns an appropriate delay

Bug: 170486601
Test: Manual
CTS-Coverage-Bug: 179658703
Change-Id: I9787d8127ed9757a23be7337bd4454a488d44141
parent 4fb93dab
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10385,6 +10385,7 @@ package android.service.storage {
    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method public abstract void onEndSession(@NonNull String) throws java.io.IOException;
    method public void onFreeCache(@NonNull java.util.UUID, long) throws java.io.IOException;
    method public long onGetAnrDelayMillis(@NonNull String, int);
    method public abstract void onStartSession(@NonNull String, int, @NonNull android.os.ParcelFileDescriptor, @NonNull java.io.File, @NonNull java.io.File) throws java.io.IOException;
    method public abstract void onVolumeStateChanged(@NonNull android.os.storage.StorageVolume) throws java.io.IOException;
    field public static final int FLAG_SESSION_ATTRIBUTE_INDEXABLE = 2; // 0x2
+48 −0
Original line number Diff line number Diff line
@@ -95,6 +95,21 @@ public abstract class ExternalStorageService extends Service {
    public static final String EXTRA_ERROR =
            "android.service.storage.extra.error";

    /**
     * {@link Bundle} key for a package name {@link String} value.
     *
     * {@hide}
     */
    public static final String EXTRA_PACKAGE_NAME = "android.service.storage.extra.package_name";

    /**
     * {@link Bundle} key for a {@link Long} value.
     *
     * {@hide}
     */
    public static final String EXTRA_ANR_TIMEOUT_MS =
            "android.service.storage.extra.anr_timeout_ms";

    /** @hide */
    @IntDef(flag = true, prefix = {"FLAG_SESSION_"},
        value = {FLAG_SESSION_TYPE_FUSE, FLAG_SESSION_ATTRIBUTE_INDEXABLE})
@@ -162,6 +177,15 @@ public abstract class ExternalStorageService extends Service {
        throw new UnsupportedOperationException("onFreeCacheRequested not implemented");
    }

    /**
     * Called when {@code packageName} is about to ANR
     *
     * @return ANR dialog delay in milliseconds
     */
    public long onGetAnrDelayMillis(@NonNull String packageName, int uid) {
        throw new UnsupportedOperationException("onGetAnrDelayMillis not implemented");
    }

    @Override
    @NonNull
    public final IBinder onBind(@NonNull Intent intent) {
@@ -222,6 +246,19 @@ public abstract class ExternalStorageService extends Service {
            });
        }

        @Override
        public void getAnrDelayMillis(String packageName, int uid, RemoteCallback callback)
                throws RemoteException {
            mHandler.post(() -> {
                try {
                    long timeoutMs = onGetAnrDelayMillis(packageName, uid);
                    sendTimeoutResult(packageName, timeoutMs, null /* throwable */, callback);
                } catch (Throwable t) {
                    sendTimeoutResult(packageName, 0 /* timeoutMs */, t, callback);
                }
            });
        }

        private void sendResult(String sessionId, Throwable throwable, RemoteCallback callback) {
            Bundle bundle = new Bundle();
            bundle.putString(EXTRA_SESSION_ID, sessionId);
@@ -230,5 +267,16 @@ public abstract class ExternalStorageService extends Service {
            }
            callback.sendResult(bundle);
        }

        private void sendTimeoutResult(String packageName, long timeoutMs, Throwable throwable,
                RemoteCallback callback) {
            Bundle bundle = new Bundle();
            bundle.putString(EXTRA_PACKAGE_NAME, packageName);
            bundle.putLong(EXTRA_ANR_TIMEOUT_MS, timeoutMs);
            if (throwable != null) {
                bundle.putParcelable(EXTRA_ERROR, new ParcelableException(throwable));
            }
            callback.sendResult(bundle);
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -32,4 +32,5 @@ oneway interface IExternalStorageService
        in RemoteCallback callback);
    void freeCache(@utf8InCpp String sessionId, in String volumeUuid, long bytes,
        in RemoteCallback callback);
    void getAnrDelayMillis(String packageName, int uid, in RemoteCallback callback);
}
 No newline at end of file
+6 −3
Original line number Diff line number Diff line
@@ -939,9 +939,12 @@ class StorageManagerService extends IStorageManager.Stub
        if (transcodeEnabled) {
            LocalServices.getService(ActivityManagerInternal.class)
                    .registerAnrController((packageName, uid) -> {
                        // TODO: Retrieve delay from ExternalStorageService that can check
                        // transcoding status
                        return SystemProperties.getInt("sys.fuse.transcode_anr_delay_ms", 0);
                        try {
                            return mStorageSessionController.getAnrDelayMillis(packageName, uid);
                        } catch (ExternalStorageServiceException e) {
                            Log.e(TAG, "Failed to get ANR delay for " + packageName, e);
                            return 0;
                        }
                    });
        }
    }
+23 −0
Original line number Diff line number Diff line
@@ -157,6 +157,29 @@ public final class StorageSessionController {
        }
    }

    /**
     * Called when {@code packageName} is about to ANR
     *
     * @return ANR dialog delay in milliseconds
     */
    public long getAnrDelayMillis(String packageName, int uid)
            throws ExternalStorageServiceException {
        synchronized (mLock) {
            int size = mConnections.size();
            for (int i = 0; i < size; i++) {
                int key = mConnections.keyAt(i);
                StorageUserConnection connection = mConnections.get(key);
                if (connection != null) {
                    long delay = connection.getAnrDelayMillis(packageName, uid);
                    if (delay > 0) {
                        return delay;
                    }
                }
            }
        }
        return 0;
    }

    /**
     * Removes and returns the {@link StorageUserConnection} for {@code vol}.
     *
Loading