Merge "Add API to get currently pinned slices" into pi-dev
diff --git a/api/current.txt b/api/current.txt
index b3be727..f92896d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7266,6 +7266,7 @@
public class SliceManager {
method public android.app.slice.Slice bindSlice(android.net.Uri, java.util.List<android.app.slice.SliceSpec>);
method public android.app.slice.Slice bindSlice(android.content.Intent, java.util.List<android.app.slice.SliceSpec>);
+ method public java.util.List<android.net.Uri> getPinnedSlices();
method public java.util.List<android.app.slice.SliceSpec> getPinnedSpecs(android.net.Uri);
method public java.util.Collection<android.net.Uri> getSliceDescendants(android.net.Uri);
method public android.net.Uri mapIntentToUri(android.content.Intent);
diff --git a/core/java/android/app/slice/ISliceManager.aidl b/core/java/android/app/slice/ISliceManager.aidl
index 20ec75a..74e3c3e 100644
--- a/core/java/android/app/slice/ISliceManager.aidl
+++ b/core/java/android/app/slice/ISliceManager.aidl
@@ -27,6 +27,7 @@
SliceSpec[] getPinnedSpecs(in Uri uri, String pkg);
int checkSlicePermission(in Uri uri, String pkg, int pid, int uid);
void grantPermissionFromUser(in Uri uri, String pkg, String callingPkg, boolean allSlices);
+ Uri[] getPinnedSlices(String pkg);
byte[] getBackupPayload(int user);
void applyRestore(in byte[] payload, int user);
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index 4f3cd63..c5ea9b2 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -184,6 +184,18 @@
}
/**
+ * Get the list of currently pinned slices for this app.
+ * @see SliceProvider#onSlicePinned
+ */
+ public @NonNull List<Uri> getPinnedSlices() {
+ try {
+ return Arrays.asList(mService.getPinnedSlices(mContext.getPackageName()));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Obtains a list of slices that are descendants of the specified Uri.
* <p>
* Not all slice providers will implement this functionality, in which case,
diff --git a/services/core/java/com/android/server/slice/PinnedSliceState.java b/services/core/java/com/android/server/slice/PinnedSliceState.java
index f9a4ea2..4e7fb96 100644
--- a/services/core/java/com/android/server/slice/PinnedSliceState.java
+++ b/services/core/java/com/android/server/slice/PinnedSliceState.java
@@ -14,9 +14,6 @@
package com.android.server.slice;
-import static android.app.slice.SliceManager.PERMISSION_GRANTED;
-
-import android.app.slice.Slice;
import android.app.slice.SliceProvider;
import android.app.slice.SliceSpec;
import android.content.ContentProviderClient;
@@ -33,7 +30,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -54,18 +50,24 @@
private final ArraySet<String> mPinnedPkgs = new ArraySet<>();
@GuardedBy("mLock")
private final ArrayMap<IBinder, ListenerInfo> mListeners = new ArrayMap<>();
+ private final String mPkg;
@GuardedBy("mLock")
private SliceSpec[] mSupportedSpecs = null;
private final DeathRecipient mDeathRecipient = this::handleRecheckListeners;
private boolean mSlicePinned;
- public PinnedSliceState(SliceManagerService service, Uri uri) {
+ public PinnedSliceState(SliceManagerService service, Uri uri, String pkg) {
mService = service;
mUri = uri;
+ mPkg = pkg;
mLock = mService.getLock();
}
+ public String getPkg() {
+ return mPkg;
+ }
+
public SliceSpec[] getSpecs() {
return mSupportedSpecs;
}
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 51e4709..a7dfd35 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -149,11 +149,25 @@
/// ----- ISliceManager stuff -----
@Override
+ public Uri[] getPinnedSlices(String pkg) {
+ verifyCaller(pkg);
+ ArrayList<Uri> ret = new ArrayList<>();
+ synchronized (mLock) {
+ for (PinnedSliceState state : mPinnedSlicesByUri.values()) {
+ if (Objects.equals(pkg, state.getPkg())) {
+ ret.add(state.getUri());
+ }
+ }
+ }
+ return ret.toArray(new Uri[ret.size()]);
+ }
+
+ @Override
public void pinSlice(String pkg, Uri uri, SliceSpec[] specs, IBinder token) throws RemoteException {
verifyCaller(pkg);
enforceAccess(pkg, uri);
uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
- getOrCreatePinnedSlice(uri).pin(pkg, specs, token);
+ getOrCreatePinnedSlice(uri, pkg).pin(pkg, specs, token);
}
@Override
@@ -302,11 +316,11 @@
}
}
- private PinnedSliceState getOrCreatePinnedSlice(Uri uri) {
+ private PinnedSliceState getOrCreatePinnedSlice(Uri uri, String pkg) {
synchronized (mLock) {
PinnedSliceState manager = mPinnedSlicesByUri.get(uri);
if (manager == null) {
- manager = createPinnedSlice(uri);
+ manager = createPinnedSlice(uri, pkg);
mPinnedSlicesByUri.put(uri, manager);
}
return manager;
@@ -314,8 +328,8 @@
}
@VisibleForTesting
- protected PinnedSliceState createPinnedSlice(Uri uri) {
- return new PinnedSliceState(this, uri);
+ protected PinnedSliceState createPinnedSlice(Uri uri, String pkg) {
+ return new PinnedSliceState(this, uri, pkg);
}
public Object getLock() {
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
index 1052e8f..3c4e333 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
@@ -1,7 +1,5 @@
package com.android.server.slice;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -12,23 +10,18 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.slice.ISliceListener;
-import android.app.slice.Slice;
import android.app.slice.SliceProvider;
import android.app.slice.SliceSpec;
import android.content.ContentProvider;
-import android.content.Context;
import android.content.IContentProvider;
import android.net.Uri;
import android.os.Binder;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
@@ -83,7 +76,7 @@
mIContentProvider = mock(IContentProvider.class);
when(mContentProvider.getIContentProvider()).thenReturn(mIContentProvider);
mContext.getContentResolver().addProvider(AUTH, mContentProvider);
- mPinnedSliceManager = new PinnedSliceState(mSliceService, TEST_URI);
+ mPinnedSliceManager = new PinnedSliceState(mSliceService, TEST_URI, "pkg");
}
@Test
@@ -164,4 +157,4 @@
verify(mSliceService).removePinnedSlice(eq(TEST_URI));
assertFalse(mPinnedSliceManager.hasPinOrListener());
}
-}
\ No newline at end of file
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index 6fc3009..4f446a9 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -18,6 +18,7 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -28,7 +29,6 @@
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
-import android.app.slice.ISliceListener;
import android.app.slice.SliceSpec;
import android.content.pm.PackageManagerInternal;
import android.net.Uri;
@@ -71,7 +71,7 @@
mService = spy(new SliceManagerService(mContext, TestableLooper.get(this).getLooper()));
mCreatedSliceState = mock(PinnedSliceState.class);
- doReturn(mCreatedSliceState).when(mService).createPinnedSlice(eq(TEST_URI));
+ doReturn(mCreatedSliceState).when(mService).createPinnedSlice(eq(TEST_URI), anyString());
}
@After
@@ -85,7 +85,7 @@
mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
- verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
+ verify(mService, times(1)).createPinnedSlice(eq(TEST_URI), eq("pkg"));
}
@Test