Give SliceManagerService a concept of pinned slices.
Allow launcher/assistant to pin slices. Also allow other apps
with access to a slice to pin it dynamically by adding a listener
to it. Dynamic pinnings can expire when the host app dies because
the binder will no longer be alive.
Public docs and unhiding will come in a later CL with CTS tests.
Bug: 68378571
Test: runtest --path frameworks/base/services/tests/uiservicestests
Change-Id: I1dd9a839f547fc949922b766ba4b54e6d50f3125
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index e99f676..f8e19c1 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -17,8 +17,11 @@
package android.app.slice;
import android.annotation.SystemService;
+import android.app.slice.ISliceListener.Stub;
import android.content.Context;
+import android.net.Uri;
import android.os.Handler;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
@@ -36,4 +39,93 @@
mService = ISliceManager.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.SLICE_SERVICE));
}
+
+ /**
+ */
+ public void addSliceListener(Uri uri, SliceListener listener, SliceSpec[] specs) {
+ try {
+ mService.addSliceListener(uri, mContext.getPackageName(), listener.mStub, specs);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ */
+ public void removeSliceListener(Uri uri, SliceListener listener) {
+ try {
+ mService.removeSliceListener(uri, mContext.getPackageName(), listener.mStub);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ */
+ public void pinSlice(Uri uri, SliceSpec[] specs) {
+ try {
+ mService.pinSlice(mContext.getPackageName(), uri, specs);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ */
+ public void unpinSlice(Uri uri) {
+ try {
+ mService.unpinSlice(mContext.getPackageName(), uri);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ */
+ public boolean hasSliceAccess() {
+ try {
+ return mService.hasSliceAccess(mContext.getPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ */
+ public SliceSpec[] getPinnedSpecs(Uri uri) {
+ try {
+ return mService.getPinnedSpecs(uri, mContext.getPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ */
+ public abstract static class SliceListener {
+ private final Handler mHandler;
+
+ /**
+ */
+ public SliceListener() {
+ this(Handler.getMain());
+ }
+
+ /**
+ */
+ public SliceListener(Handler h) {
+ mHandler = h;
+ }
+
+ /**
+ */
+ public abstract void onSliceUpdated(Slice s);
+
+ private final ISliceListener.Stub mStub = new Stub() {
+ @Override
+ public void onSliceUpdated(Slice s) throws RemoteException {
+ mHandler.post(() -> SliceListener.this.onSliceUpdated(s));
+ }
+ };
+ }
}