diff options
| author | Jason Monk <jmonk@google.com> | 2018-01-16 17:57:20 -0500 |
|---|---|---|
| committer | Jason Monk <jmonk@google.com> | 2018-01-16 17:57:20 -0500 |
| commit | 5f8cc27e14e93e604c45afc0fd3bbd15600ffffb (patch) | |
| tree | 01c0f8b9aad2b0c417eade89824574ef53465b90 /core/java/android | |
| parent | b9e06a8458487892758e5ef1d374182f9a6c6c46 (diff) | |
Add SliceManager#getSliceDescendants
Allows SliceProviders to give consumers a list of slices they might
be interested in.
Test: cts
Bug: 68378569
Change-Id: I2d7d50388055937cabe3378502db56201f051897
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/slice/SliceManager.java | 32 | ||||
| -rw-r--r-- | core/java/android/app/slice/SliceProvider.java | 50 |
2 files changed, 82 insertions, 0 deletions
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java index 0e7c64f07245..74864cb1a371 100644 --- a/core/java/android/app/slice/SliceManager.java +++ b/core/java/android/app/slice/SliceManager.java @@ -31,12 +31,15 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.util.ArrayMap; +import android.util.Log; import android.util.Pair; import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; @@ -48,6 +51,8 @@ import java.util.concurrent.Executor; @SystemService(Context.SLICE_SERVICE) public class SliceManager { + private static final String TAG = "SliceManager"; + private final ISliceManager mService; private final Context mContext; private final ArrayMap<Pair<Uri, SliceCallback>, ISliceListener> mListenerLookup = @@ -233,6 +238,33 @@ public class SliceManager { } /** + * Obtains a list of slices that are descendants of the specified Uri. + * <p> + * Not all slice providers will implement this functionality, in which case, + * an empty collection will be returned. + * + * @param uri The uri to look for descendants under. + * @return All slices within the space. + * @see SliceProvider#onGetSliceDescendants(Uri) + */ + public @NonNull Collection<Uri> getSliceDescendants(@NonNull Uri uri) { + ContentResolver resolver = mContext.getContentResolver(); + IContentProvider provider = resolver.acquireProvider(uri); + try { + Bundle extras = new Bundle(); + extras.putParcelable(SliceProvider.EXTRA_BIND_URI, uri); + final Bundle res = provider.call(resolver.getPackageName(), + SliceProvider.METHOD_GET_DESCENDANTS, null, extras); + return res.getParcelableArrayList(SliceProvider.EXTRA_SLICE_DESCENDANTS); + } catch (RemoteException e) { + Log.e(TAG, "Unable to get slice descendants", e); + } finally { + resolver.releaseProvider(provider); + } + return Collections.emptyList(); + } + + /** * Turns a slice Uri into slice content. * * @param uri The URI to a slice provider diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index 06614b5ecbfe..aa41f14d8cb5 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -36,6 +36,9 @@ import android.os.StrictMode.ThreadPolicy; import android.os.UserHandle; import android.util.Log; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -113,11 +116,19 @@ public abstract class SliceProvider extends ContentProvider { /** * @hide */ + public static final String METHOD_GET_DESCENDANTS = "get_descendants"; + /** + * @hide + */ public static final String EXTRA_INTENT = "slice_intent"; /** * @hide */ public static final String EXTRA_SLICE = "slice"; + /** + * @hide + */ + public static final String EXTRA_SLICE_DESCENDANTS = "slice_descendants"; private static final boolean DEBUG = false; @@ -175,6 +186,20 @@ public abstract class SliceProvider extends ContentProvider { } /** + * Obtains a list of slices that are descendants of the specified Uri. + * <p> + * Implementing this is optional for a SliceProvider, but does provide a good + * discovery mechanism for finding slice Uris. + * + * @param uri The uri to look for descendants under. + * @return All slices within the space. + * @see SliceManager#getSliceDescendants(Uri) + */ + public @NonNull Collection<Uri> onGetSliceDescendants(@NonNull Uri uri) { + return Collections.emptyList(); + } + + /** * This method must be overridden if an {@link IntentFilter} is specified on the SliceProvider. * In that case, this method can be called and is expected to return a non-null Uri representing * a slice. Otherwise this will throw {@link UnsupportedOperationException}. @@ -282,10 +307,35 @@ public abstract class SliceProvider extends ContentProvider { "Slice binding requires the permission BIND_SLICE"); } handleUnpinSlice(uri); + } else if (method.equals(METHOD_GET_DESCENDANTS)) { + Uri uri = extras.getParcelable(EXTRA_BIND_URI); + Bundle b = new Bundle(); + b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS, + new ArrayList<>(handleGetDescendants(uri))); + return b; } return super.call(method, arg, extras); } + private Collection<Uri> handleGetDescendants(Uri uri) { + if (Looper.myLooper() == Looper.getMainLooper()) { + return onGetSliceDescendants(uri); + } else { + CountDownLatch latch = new CountDownLatch(1); + Collection<Uri>[] output = new Collection[1]; + Handler.getMain().post(() -> { + output[0] = onGetSliceDescendants(uri); + latch.countDown(); + }); + try { + latch.await(); + return output[0]; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + private void handlePinSlice(Uri sliceUri) { if (Looper.myLooper() == Looper.getMainLooper()) { onSlicePinned(sliceUri); |
