diff options
3 files changed, 75 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/slice/SliceFullAccessList.java b/services/core/java/com/android/server/slice/SliceFullAccessList.java index 591e809ad3d1..5e0cd035a67d 100644 --- a/services/core/java/com/android/server/slice/SliceFullAccessList.java +++ b/services/core/java/com/android/server/slice/SliceFullAccessList.java @@ -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)); diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java index 5db0fc0d9e00..c4871dfe8d5c 100644 --- a/services/core/java/com/android/server/slice/SliceManagerService.java +++ b/services/core/java/com/android/server/slice/SliceManagerService.java @@ -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()); - mAccessList.readXml(parser); + 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) { - mAccessList.grantFullAccess(pkg, Binder.getCallingUserHandle().getIdentifier()); + 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,7 +464,9 @@ public class SliceManagerService extends ISliceManager.Stub { } private boolean isGrantedFullAccess(String pkg, int userId) { - return mAccessList.hasFullAccess(pkg, userId); + synchronized (mAccessList) { + return mAccessList.hasFullAccess(pkg, userId); + } } private static ServiceThread createHandler() { @@ -469,7 +491,9 @@ public class SliceManagerService extends ISliceManager.Stub { try { XmlSerializer out = XmlPullParserFactory.newInstance().newSerializer(); out.setOutput(stream, Encoding.UTF_8.name()); - mAccessList.writeXml(out); + 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; diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java index 7c14d083d3c9..b784c6006a86 100644 --- a/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java +++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java @@ -67,6 +67,15 @@ public class SliceFullAccessListTest extends UiServiceTestCase { } @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); mAccessList.grantFullAccess("pkg1", 0); |