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

Commit 68ff6aac authored by Jason Monk's avatar Jason Monk
Browse files

Clear slice access grants on package clear/remove

Test: uiservicestests
Bug: 68751119
Change-Id: Ie5bd29a8c02cdfe7b634d2a302c625524ffcb89a
parent 9d3986bd
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -63,6 +63,15 @@ public class SliceFullAccessList {
        pkgs.add(pkg);
    }

    public void removeGrant(String pkg, int userId) {
        ArraySet<String> pkgs = mFullAccessPkgs.get(userId, null);
        if (pkgs == null) {
            pkgs = new ArraySet<>();
            mFullAccessPkgs.put(userId, pkgs);
        }
        pkgs.remove(pkg);
    }

    public void writeXml(XmlSerializer out) throws IOException {
        out.startTag(null, TAG_LIST);
        out.attribute(null, ATT_VERSION, String.valueOf(DB_VERSION));
+57 −4
Original line number Diff line number Diff line
@@ -31,9 +31,11 @@ import android.app.slice.ISliceListener;
import android.app.slice.ISliceManager;
import android.app.slice.SliceManager;
import android.app.slice.SliceSpec;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
@@ -92,6 +94,7 @@ public class SliceManagerService extends ISliceManager.Stub {
    private final Handler mHandler;
    private final ContentObserver mObserver;
    private final AtomicFile mSliceAccessFile;
    @GuardedBy("mAccessList")
    private final SliceFullAccessList mAccessList;

    public SliceManagerService(Context context) {
@@ -127,11 +130,19 @@ public class SliceManagerService extends ISliceManager.Stub {
                InputStream input = mSliceAccessFile.openRead();
                XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
                parser.setInput(input, Encoding.UTF_8.name());
                synchronized (mAccessList) {
                    mAccessList.readXml(parser);
                }
            } catch (IOException | XmlPullParserException e) {
                Slog.d(TAG, "Can't read slice access file", e);
            }
        }

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addDataScheme("package");
        mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
    }

    ///  ----- Lifecycle stuff -----
@@ -223,7 +234,9 @@ public class SliceManagerService extends ISliceManager.Stub {
        getContext().enforceCallingOrSelfPermission(permission.MANAGE_SLICE_PERMISSIONS,
                "Slice granting requires MANAGE_SLICE_PERMISSIONS");
        if (allSlices) {
            synchronized (mAccessList) {
                mAccessList.grantFullAccess(pkg, Binder.getCallingUserHandle().getIdentifier());
            }
            mHandler.post(mSaveAccessList);
        } else {
            synchronized (mLock) {
@@ -245,6 +258,13 @@ public class SliceManagerService extends ISliceManager.Stub {
    }

    ///  ----- internal code -----
    private void removeFullAccess(String pkg, int userId) {
        synchronized (mAccessList) {
            mAccessList.removeGrant(pkg, userId);
        }
        mHandler.post(mSaveAccessList);
    }

    protected void removePinnedSlice(Uri uri) {
        synchronized (mLock) {
            mPinnedSlicesByUri.remove(uri).destroy();
@@ -444,8 +464,10 @@ public class SliceManagerService extends ISliceManager.Stub {
    }

    private boolean isGrantedFullAccess(String pkg, int userId) {
        synchronized (mAccessList) {
            return mAccessList.hasFullAccess(pkg, userId);
        }
    }

    private static ServiceThread createHandler() {
        ServiceThread handlerThread = new ServiceThread(TAG,
@@ -469,7 +491,9 @@ public class SliceManagerService extends ISliceManager.Stub {
                try {
                    XmlSerializer out = XmlPullParserFactory.newInstance().newSerializer();
                    out.setOutput(stream, Encoding.UTF_8.name());
                    synchronized (mAccessList) {
                        mAccessList.writeXml(out);
                    }
                    out.flush();
                    mSliceAccessFile.finishWrite(stream);
                } catch (IOException | XmlPullParserException e) {
@@ -480,6 +504,35 @@ public class SliceManagerService extends ISliceManager.Stub {
        }
    };

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final int userId  = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
            if (userId == UserHandle.USER_NULL) {
                Slog.w(TAG, "Intent broadcast does not contain user handle: " + intent);
                return;
            }
            Uri data = intent.getData();
            String pkg = data != null ? data.getSchemeSpecificPart() : null;
            if (pkg == null) {
                Slog.w(TAG, "Intent broadcast does not contain package name: " + intent);
                return;
            }
            switch (intent.getAction()) {
                case Intent.ACTION_PACKAGE_REMOVED:
                    final boolean replacing =
                            intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                    if (!replacing) {
                        removeFullAccess(pkg, userId);
                    }
                    break;
                case Intent.ACTION_PACKAGE_DATA_CLEARED:
                    removeFullAccess(pkg, userId);
                    break;
            }
        }
    };

    public static class Lifecycle extends SystemService {
        private SliceManagerService mService;

+9 −0
Original line number Diff line number Diff line
@@ -66,6 +66,15 @@ public class SliceFullAccessListTest extends UiServiceTestCase {
        assertFalse(mAccessList.hasFullAccess("pkg", 0));
    }

    @Test
    public void testRemoveAccess() {
        mAccessList.grantFullAccess("pkg", 0);
        assertTrue(mAccessList.hasFullAccess("pkg", 0));

        mAccessList.removeGrant("pkg", 0);
        assertFalse(mAccessList.hasFullAccess("pkg", 0));
    }

    @Test
    public void testSerialization() throws XmlPullParserException, IOException {
        mAccessList.grantFullAccess("pkg", 0);