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

Commit b0dffde3 authored by Zim's avatar Zim
Browse files

Kill app when OP_MANAGE_EXTERNAL_STORAGE is denied.

When an app requests the special access permission to be able to manage
external storage, and it is denied, we need to kill the app, in order to
lose the external_storage gid it may have that allows it access to
unreliable USB OTG volumes.

When the app op is granted, we don't kill the app to pickup the new
gid because it may result in bad UX especially since that gid is only
useful to access unreliable USB OTGs that are rarely present.
The next time the app is restarted, it will get the external_storage
gid and will be able to access any mounted USB OTG volumes.

Bug: 144914977
Test: Copy paste of I73c5ce56ee24e5c864d7c9280b83fc3854701a97
Change-Id: I5cb13dc9c51cb8b4e942e529b4a1c7dac180cace
parent f6e58c9f
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
import static android.app.AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES;
import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE;
@@ -4320,11 +4321,7 @@ class StorageManagerService extends IStorageManager.Stub
            return true;
        }

        public void onAppOpsChanged(int code, int uid,
                @Nullable String packageName, int mode) {
            if (code == OP_REQUEST_INSTALL_PACKAGES && mIsFuseEnabled) {
                // When using FUSE, we basically have no other choice but to kill the app
                // after the app op is either granted or rejected.
        private void killAppForOpChange(int code, int uid, String packageName) {
            final IActivityManager am = ActivityManager.getService();
            try {
                am.killApplication(packageName,
@@ -4332,9 +4329,29 @@ class StorageManagerService extends IStorageManager.Stub
                        UserHandle.USER_ALL, AppOpsManager.opToName(code) + " changed.");
            } catch (RemoteException e) {
            }
        }

        public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) {
            if (mIsFuseEnabled) {
                // When using FUSE, we may need to kill the app if the op changes
                switch(code) {
                    case OP_REQUEST_INSTALL_PACKAGES:
                        // Always kill regardless of op change, to remount apps /storage
                        killAppForOpChange(code, uid, packageName);
                        return;
                    case OP_MANAGE_EXTERNAL_STORAGE:
                        if (mode != MODE_ALLOWED) {
                            // Only kill if op is denied, to lose external_storage gid
                            // Killing when op is granted to pickup the gid automatically, results
                            // in a bad UX, especially since the gid only gives access to unreliable
                            // volumes, USB OTGs that are rarely mounted. The app will get the
                            // external_storage gid on next organic restart.
                            killAppForOpChange(code, uid, packageName);
                            return;
                        }
                }
            }

            if (mode == MODE_ALLOWED && (code == OP_READ_EXTERNAL_STORAGE
                    || code == OP_WRITE_EXTERNAL_STORAGE
                    || code == OP_REQUEST_INSTALL_PACKAGES)) {