Merge "Don't use APIs that are going to be removed"
diff --git a/slices/core/src/main/java/androidx/app/slice/Slice.java b/slices/core/src/main/java/androidx/app/slice/Slice.java
index e61666c..966c877 100644
--- a/slices/core/src/main/java/androidx/app/slice/Slice.java
+++ b/slices/core/src/main/java/androidx/app/slice/Slice.java
@@ -41,9 +41,8 @@
 import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
-import android.content.ContentProvider;
+import android.app.slice.SliceManager;
 import android.content.Context;
-import android.content.Intent;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.Bundle;
@@ -451,39 +450,7 @@
     @TargetApi(28)
     private static Slice callBindSlice(Context context, Uri uri,
             List<SliceSpec> supportedSpecs) {
-        return SliceConvert.wrap(android.app.slice.Slice.bindSlice(
-                context.getContentResolver(), uri, unwrap(supportedSpecs)));
-    }
-
-
-    /**
-     * Turns a slice intent into slice content. Expects an explicit intent. If there is no
-     * {@link ContentProvider} associated with the given intent this will throw
-     * {@link IllegalArgumentException}.
-     *
-     * @hide
-     * @param context The context to use.
-     * @param intent The intent associated with a slice.
-     * @return The Slice provided by the app or null if none is given.
-     * @see Slice
-     * @see SliceProvider#onMapIntentToUri(Intent)
-     * @see Intent
-     */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @SuppressWarnings("NewApi")
-    public static @Nullable Slice bindSlice(Context context, @NonNull Intent intent,
-                List<SliceSpec> supportedSpecs) {
-        if (BuildCompat.isAtLeastP()) {
-            return callBindSlice(context, intent, supportedSpecs);
-        } else {
-            return SliceProviderCompat.bindSlice(context, intent, supportedSpecs);
-        }
-    }
-
-    @TargetApi(28)
-    private static Slice callBindSlice(Context context, Intent intent,
-            List<SliceSpec> supportedSpecs) {
-        return SliceConvert.wrap(android.app.slice.Slice.bindSlice(
-                context, intent, unwrap(supportedSpecs)));
+        return SliceConvert.wrap(context.getSystemService(SliceManager.class)
+                .bindSlice(uri, unwrap(supportedSpecs)));
     }
 }
diff --git a/slices/view/src/androidTest/java/androidx/app/slice/render/RenderTest.java b/slices/view/src/androidTest/java/androidx/app/slice/render/RenderTest.java
index 6cf6182..3a71268 100644
--- a/slices/view/src/androidTest/java/androidx/app/slice/render/RenderTest.java
+++ b/slices/view/src/androidTest/java/androidx/app/slice/render/RenderTest.java
@@ -16,6 +16,8 @@
 
 package androidx.app.slice.render;
 
+import static androidx.app.slice.render.SliceRenderer.SCREENSHOT_DIR;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -51,5 +53,8 @@
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
 
         latch.await(30000, TimeUnit.MILLISECONDS);
+        String path = mContext.getDataDir().toString() + "/" + SCREENSHOT_DIR;
+        InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
+                "mv " + path + " " + "/sdcard/");
     }
 }
diff --git a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java
index d2b8619..056af32 100644
--- a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java
+++ b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java
@@ -23,7 +23,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.os.AsyncTask;
-import android.os.Environment;
 import android.os.Handler;
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
@@ -46,7 +45,7 @@
 public class SliceRenderer {
 
     private static final String TAG = "SliceRenderer";
-    private static final String SCREENSHOT_DIR = "slice-screenshots";
+    public static final String SCREENSHOT_DIR = "slice-screenshots";
     private static File sScreenshotDirectory;
 
     private final Activity mContext;
@@ -106,9 +105,9 @@
     }
 
 
-    private static File getScreenshotDirectory() {
+    private File getScreenshotDirectory() {
         if (sScreenshotDirectory == null) {
-            File storage = Environment.getExternalStorageDirectory();
+            File storage = mContext.getDataDir();
             sScreenshotDirectory = new File(storage, SCREENSHOT_DIR);
             if (!sScreenshotDirectory.exists()) {
                 if (!sScreenshotDirectory.mkdirs()) {
diff --git a/slices/view/src/main/java/androidx/app/slice/SliceManagerBase.java b/slices/view/src/main/java/androidx/app/slice/SliceManagerBase.java
new file mode 100644
index 0000000..8731658
--- /dev/null
+++ b/slices/view/src/main/java/androidx/app/slice/SliceManagerBase.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.app.slice;
+
+import static androidx.app.slice.widget.SliceLiveData.SUPPORTED_SPECS;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.util.ArrayMap;
+import android.util.Pair;
+
+import java.util.concurrent.Executor;
+
+/**
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public abstract class SliceManagerBase extends SliceManager {
+    private final ArrayMap<Pair<Uri, SliceCallback>, SliceListenerImpl> mListenerLookup =
+            new ArrayMap<>();
+    protected final Context mContext;
+
+    SliceManagerBase(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback) {
+        final Handler h = new Handler(Looper.getMainLooper());
+        registerSliceCallback(uri, new Executor() {
+            @Override
+            public void execute(@NonNull Runnable command) {
+                h.post(command);
+            }
+        }, callback);
+    }
+
+    @Override
+    public void registerSliceCallback(@NonNull Uri uri, @NonNull Executor executor,
+            @NonNull SliceCallback callback) {
+        pinSlice(uri);
+        getListener(uri, callback, new SliceListenerImpl(uri, executor, callback)).startListening();
+    }
+
+    @Override
+    public void unregisterSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback) {
+        unpinSlice(uri);
+        SliceListenerImpl impl = mListenerLookup.remove(new Pair<>(uri, callback));
+        if (impl != null) impl.stopListening();
+    }
+
+    private SliceListenerImpl getListener(Uri uri, SliceCallback callback,
+            SliceListenerImpl listener) {
+        Pair<Uri, SliceCallback> key = new Pair<>(uri, callback);
+        if (mListenerLookup.containsKey(key)) {
+            mListenerLookup.get(key).stopListening();
+        }
+        mListenerLookup.put(key, listener);
+        return listener;
+    }
+
+    private class SliceListenerImpl {
+
+        private Uri mUri;
+        private final Executor mExecutor;
+        private final SliceCallback mCallback;
+
+        SliceListenerImpl(Uri uri, Executor executor, SliceCallback callback) {
+            mUri = uri;
+            mExecutor = executor;
+            mCallback = callback;
+        }
+
+        void startListening() {
+            mContext.getContentResolver().registerContentObserver(mUri, true, mObserver);
+        }
+
+        void stopListening() {
+            mContext.getContentResolver().unregisterContentObserver(mObserver);
+        }
+
+        private final Runnable mUpdateSlice = new Runnable() {
+            @Override
+            public void run() {
+                final Slice s = Slice.bindSlice(mContext, mUri, SUPPORTED_SPECS);
+                mExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onSliceUpdated(s);
+                    }
+                });
+            }
+        };
+
+        private final ContentObserver mObserver = new ContentObserver(
+                new Handler(Looper.getMainLooper())) {
+            @Override
+            public void onChange(boolean selfChange) {
+                AsyncTask.execute(mUpdateSlice);
+            }
+        };
+    }
+}
diff --git a/slices/view/src/main/java/androidx/app/slice/SliceManagerCompat.java b/slices/view/src/main/java/androidx/app/slice/SliceManagerCompat.java
index 67613a5..1f301b7 100644
--- a/slices/view/src/main/java/androidx/app/slice/SliceManagerCompat.java
+++ b/slices/view/src/main/java/androidx/app/slice/SliceManagerCompat.java
@@ -20,19 +20,12 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.database.ContentObserver;
 import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Looper;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
-import android.util.ArrayMap;
-import android.util.Pair;
 
 import java.util.List;
-import java.util.concurrent.Executor;
 
 import androidx.app.slice.compat.SliceProviderCompat;
 import androidx.app.slice.widget.SliceLiveData;
@@ -42,38 +35,10 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
-class SliceManagerCompat extends SliceManager {
-    private final ArrayMap<Pair<Uri, SliceCallback>, SliceListenerImpl> mListenerLookup =
-            new ArrayMap<>();
-    private final Context mContext;
+class SliceManagerCompat extends SliceManagerBase {
 
     SliceManagerCompat(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback) {
-        final Handler h = new Handler(Looper.getMainLooper());
-        registerSliceCallback(uri, new Executor() {
-            @Override
-            public void execute(@NonNull Runnable command) {
-                h.post(command);
-            }
-        }, callback);
-    }
-
-    @Override
-    public void registerSliceCallback(@NonNull Uri uri, @NonNull Executor executor,
-            @NonNull SliceCallback callback) {
-        pinSlice(uri);
-        getListener(uri, callback, new SliceListenerImpl(uri, executor, callback)).startListening();
-    }
-
-    @Override
-    public void unregisterSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback) {
-        unpinSlice(uri);
-        SliceListenerImpl impl = mListenerLookup.remove(new Pair<>(uri, callback));
-        if (impl != null) impl.stopListening();
+        super(context);
     }
 
     @Override
@@ -102,56 +67,4 @@
     public Slice bindSlice(@NonNull Intent intent) {
         return SliceProviderCompat.bindSlice(mContext, intent, SUPPORTED_SPECS);
     }
-
-    private SliceListenerImpl getListener(Uri uri, SliceCallback callback,
-            SliceListenerImpl listener) {
-        Pair<Uri, SliceCallback> key = new Pair<>(uri, callback);
-        if (mListenerLookup.containsKey(key)) {
-            mListenerLookup.get(key).stopListening();
-        }
-        mListenerLookup.put(key, listener);
-        return listener;
-    }
-
-    private class SliceListenerImpl {
-
-        private Uri mUri;
-        private final Executor mExecutor;
-        private final SliceCallback mCallback;
-
-        SliceListenerImpl(Uri uri, Executor executor, SliceCallback callback) {
-            mUri = uri;
-            mExecutor = executor;
-            mCallback = callback;
-        }
-
-        void startListening() {
-            mContext.getContentResolver().registerContentObserver(mUri, true, mObserver);
-        }
-
-        void stopListening() {
-            mContext.getContentResolver().unregisterContentObserver(mObserver);
-        }
-
-        private final Runnable mUpdateSlice = new Runnable() {
-            @Override
-            public void run() {
-                final Slice s = Slice.bindSlice(mContext, mUri, SUPPORTED_SPECS);
-                mExecutor.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        mCallback.onSliceUpdated(s);
-                    }
-                });
-            }
-        };
-
-        private final ContentObserver mObserver = new ContentObserver(
-                new Handler(Looper.getMainLooper())) {
-            @Override
-            public void onChange(boolean selfChange) {
-                AsyncTask.execute(mUpdateSlice);
-            }
-        };
-    }
 }
diff --git a/slices/view/src/main/java/androidx/app/slice/SliceManagerWrapper.java b/slices/view/src/main/java/androidx/app/slice/SliceManagerWrapper.java
index 8b2265c..a60f418 100644
--- a/slices/view/src/main/java/androidx/app/slice/SliceManagerWrapper.java
+++ b/slices/view/src/main/java/androidx/app/slice/SliceManagerWrapper.java
@@ -19,7 +19,6 @@
 import static androidx.app.slice.SliceConvert.unwrap;
 import static androidx.app.slice.widget.SliceLiveData.SUPPORTED_SPECS;
 
-import android.app.slice.Slice;
 import android.app.slice.SliceSpec;
 import android.content.Context;
 import android.content.Intent;
@@ -30,50 +29,28 @@
 import android.support.annotation.RestrictTo;
 
 import java.util.List;
-import java.util.WeakHashMap;
-import java.util.concurrent.Executor;
 
 /**
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 @RequiresApi(api = 28)
-class SliceManagerWrapper extends SliceManager {
+class SliceManagerWrapper extends SliceManagerBase {
+
     private final android.app.slice.SliceManager mManager;
-    private final WeakHashMap<SliceCallback, android.app.slice.SliceManager.SliceCallback>
-            mCallbacks = new WeakHashMap<>();
     private final List<SliceSpec> mSpecs;
-    private final Context mContext;
 
     SliceManagerWrapper(Context context) {
         this(context, context.getSystemService(android.app.slice.SliceManager.class));
     }
 
     SliceManagerWrapper(Context context, android.app.slice.SliceManager manager) {
-        mContext = context;
+        super(context);
         mManager = manager;
         mSpecs = unwrap(SUPPORTED_SPECS);
     }
 
     @Override
-    public void registerSliceCallback(@NonNull Uri uri,
-            @NonNull SliceCallback callback) {
-        mManager.registerSliceCallback(uri, addCallback(callback), mSpecs);
-    }
-
-    @Override
-    public void registerSliceCallback(@NonNull Uri uri, @NonNull Executor executor,
-            @NonNull SliceCallback callback) {
-        mManager.registerSliceCallback(uri, addCallback(callback), mSpecs, executor);
-    }
-
-    @Override
-    public void unregisterSliceCallback(@NonNull Uri uri,
-            @NonNull SliceCallback callback) {
-        mManager.unregisterSliceCallback(uri, mCallbacks.get(callback));
-    }
-
-    @Override
     public void pinSlice(@NonNull Uri uri) {
         mManager.pinSlice(uri, mSpecs);
     }
@@ -101,18 +78,4 @@
         return SliceConvert.wrap(android.app.slice.Slice.bindSlice(
                 mContext, intent, unwrap(SUPPORTED_SPECS)));
     }
-
-    private android.app.slice.SliceManager.SliceCallback addCallback(final SliceCallback callback) {
-        android.app.slice.SliceManager.SliceCallback ret = mCallbacks.get(callback);
-        if (ret == null) {
-            ret = new android.app.slice.SliceManager.SliceCallback() {
-                @Override
-                public void onSliceUpdated(Slice s) {
-                    callback.onSliceUpdated(SliceConvert.wrap(s));
-                }
-            };
-            mCallbacks.put(callback, ret);
-        }
-        return ret;
-    }
 }