Merge "Add deinit() to CameraRepository" into androidx-master-dev
diff --git a/camera/camera-camera2/src/androidTest/AndroidManifest.xml b/camera/camera-camera2/src/androidTest/AndroidManifest.xml
index da74311..527f391 100644
--- a/camera/camera-camera2/src/androidTest/AndroidManifest.xml
+++ b/camera/camera-camera2/src/androidTest/AndroidManifest.xml
@@ -20,4 +20,14 @@
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
 
+    <application>
+        <activity
+            android:name="androidx.camera.testing.fakes.FakeActivity"
+            android:label="Fake Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
 </manifest>
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeActivity.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeActivity.java
new file mode 100644
index 0000000..3d873ca
--- /dev/null
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.camera.testing.fakes;
+
+import android.app.Activity;
+
+/** A fake {@link Activity} that can be used in tests. */
+public class FakeActivity extends Activity {
+}
diff --git a/webkit/src/androidTest/java/androidx/webkit/WebViewAssetLoaderTest.java b/webkit/src/androidTest/java/androidx/webkit/WebViewAssetLoaderTest.java
index f5a667be..d95ffda 100644
--- a/webkit/src/androidTest/java/androidx/webkit/WebViewAssetLoaderTest.java
+++ b/webkit/src/androidTest/java/androidx/webkit/WebViewAssetLoaderTest.java
@@ -67,12 +67,12 @@
         }
 
         @Override
-        public InputStream openAsset(Uri uri) {
+        public InputStream openAsset(String path) {
             return null;
         }
 
         @Override
-        public InputStream openResource(Uri uri) {
+        public InputStream openResource(String path) {
             return null;
         }
     }
@@ -171,8 +171,8 @@
 
         PathHandler assetsPathHandler = new AssetsPathHandler(new MockAssetHelper() {
             @Override
-            public InputStream openAsset(Uri url) {
-                if (url.getPath().equals("www/test.html")) {
+            public InputStream openAsset(String path) {
+                if (path.equals("www/test.html")) {
                     try {
                         return new ByteArrayInputStream(testHtmlContents.getBytes(ENCODING));
                     } catch (IOException e) {
@@ -198,8 +198,8 @@
 
         PathHandler resourcesPathHandler = new ResourcesPathHandler(new MockAssetHelper() {
             @Override
-            public InputStream openResource(Uri uri) {
-                if (uri.getPath().equals("raw/test.html")) {
+            public InputStream openResource(String path) {
+                if (path.equals("raw/test.html")) {
                     try {
                         return new ByteArrayInputStream(testHtmlContents.getBytes(ENCODING));
                     } catch (IOException e) {
@@ -402,7 +402,7 @@
 
         AssetHelper mockAssetHelper = new MockAssetHelper() {
             @Override
-            public InputStream openResource(Uri uri) {
+            public InputStream openResource(String path) {
                 try {
                     return new ByteArrayInputStream(testHtmlContents.getBytes(ENCODING));
                 } catch (IOException e) {
diff --git a/webkit/src/androidTest/java/androidx/webkit/internal/AssetHelperTest.java b/webkit/src/androidTest/java/androidx/webkit/internal/AssetHelperTest.java
index 5696e8a9..82aec1c 100644
--- a/webkit/src/androidTest/java/androidx/webkit/internal/AssetHelperTest.java
+++ b/webkit/src/androidTest/java/androidx/webkit/internal/AssetHelperTest.java
@@ -17,7 +17,6 @@
 package androidx.webkit.internal;
 
 import android.content.Context;
-import android.net.Uri;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
@@ -61,7 +60,7 @@
     @Test
     @SmallTest
     public void testOpenExistingResource() {
-        InputStream stream = mAssetHelper.openResource(Uri.parse("raw/test.txt"));
+        InputStream stream = mAssetHelper.openResource("raw/test.txt");
 
         Assert.assertNotNull("failed to open resource raw/test.txt", stream);
         Assert.assertEquals(readAsString(stream), TEST_STRING);
@@ -70,7 +69,7 @@
     @Test
     @SmallTest
     public void testOpenExistingResourceWithLeadingSlash() {
-        InputStream stream = mAssetHelper.openResource(Uri.parse("/raw/test"));
+        InputStream stream = mAssetHelper.openResource("/raw/test");
 
         Assert.assertNotNull("failed to open resource /raw/test.txt with leading slash", stream);
         Assert.assertEquals(readAsString(stream), TEST_STRING);
@@ -79,7 +78,7 @@
     @Test
     @SmallTest
     public void testOpenExistingResourceWithNoExtension() {
-        InputStream stream = mAssetHelper.openResource(Uri.parse("raw/test"));
+        InputStream stream = mAssetHelper.openResource("raw/test");
 
         Assert.assertNotNull("failed to open resource raw/test with no extension", stream);
         Assert.assertEquals(readAsString(stream), TEST_STRING);
@@ -89,19 +88,19 @@
     @SmallTest
     public void testOpenInvalidResources() {
         Assert.assertNull("raw/nonexist_file.html doesn't exist - should fail",
-                          mAssetHelper.openResource(Uri.parse("raw/nonexist_file.html")));
+                          mAssetHelper.openResource("raw/nonexist_file.html"));
 
         Assert.assertNull("test.txt doesn't have a resource type - should fail",
-                          mAssetHelper.openResource(Uri.parse("test.txt")));
+                          mAssetHelper.openResource("test.txt"));
 
         Assert.assertNull("resource with \"/android_res\" prefix should fail",
-                          mAssetHelper.openResource(Uri.parse("/android_res/raw/test.txt")));
+                          mAssetHelper.openResource("/android_res/raw/test.txt"));
     }
 
     @Test
     @SmallTest
     public void testOpenExistingAsset() {
-        InputStream stream = mAssetHelper.openAsset(Uri.parse("text/test.txt"));
+        InputStream stream = mAssetHelper.openAsset("text/test.txt");
 
         Assert.assertNotNull("failed to open asset text/test.txt", stream);
         Assert.assertEquals(readAsString(stream), TEST_STRING);
@@ -110,7 +109,7 @@
     @Test
     @SmallTest
     public void testOpenExistingAssetWithLeadingSlash() {
-        InputStream stream = mAssetHelper.openAsset(Uri.parse("/text/test.txt"));
+        InputStream stream = mAssetHelper.openAsset("/text/test.txt");
 
         Assert.assertNotNull("failed to open asset /text/test.txt with leading slash", stream);
         Assert.assertEquals(readAsString(stream), TEST_STRING);
@@ -120,10 +119,10 @@
     @SmallTest
     public void testOpenInvalidAssets() {
         Assert.assertNull("nonexist_file.html doesn't exist - should fail",
-                          mAssetHelper.openAsset(Uri.parse("nonexist_file.html")));
+                          mAssetHelper.openAsset("nonexist_file.html"));
 
         Assert.assertNull("asset with \"/android_asset\" prefix should fail",
-                          mAssetHelper.openAsset(Uri.parse("/android_asset/test.txt")));
+                          mAssetHelper.openAsset("/android_asset/test.txt"));
     }
 
     @Test
@@ -140,6 +139,18 @@
 
     @Test
     @MediumTest
+    public void testOpenFileNameWhichResemblesUriScheme() throws Throwable {
+        File testFile = new File(mInternalStorageTestDir, "obb/obb:11/test/some_file.txt");
+        WebkitUtils.writeToFile(testFile, TEST_STRING);
+
+        InputStream stream = AssetHelper.openFile(testFile);
+        Assert.assertNotNull("Should be able to open \"" + testFile + "\" from internal storage",
+                stream);
+        Assert.assertEquals(readAsString(stream), TEST_STRING);
+    }
+
+    @Test
+    @MediumTest
     public void testOpenNonExistingFileInInternalStorage() throws Throwable {
         File testFile = new File(mInternalStorageTestDir, "some/path/to/non_exist_file.txt");
         InputStream stream = AssetHelper.openFile(testFile);
@@ -195,10 +206,10 @@
         InputStream svgStream = null;
         InputStream svgzStream = null;
         try {
-            svgStream = assertOpen(Uri.parse("star.svg"));
+            svgStream = assertOpen("star.svg");
             byte[] expectedData = readFully(svgStream);
 
-            svgzStream = assertOpen(Uri.parse("star.svgz"));
+            svgzStream = assertOpen("star.svgz");
             byte[] actualData = readFully(svgzStream);
 
             Assert.assertArrayEquals(
@@ -209,9 +220,9 @@
         }
     }
 
-    private InputStream assertOpen(Uri uri) {
-        InputStream stream = mAssetHelper.openAsset(uri);
-        Assert.assertNotNull("Failed to open \"" + uri + "\"", stream);
+    private InputStream assertOpen(String path) {
+        InputStream stream = mAssetHelper.openAsset(path);
+        Assert.assertNotNull("Failed to open \"" + path + "\"", stream);
         return stream;
     }
 
diff --git a/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java b/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java
index 1625d57..a8d0418 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewAssetLoader.java
@@ -159,11 +159,7 @@
         @WorkerThread
         @Nullable
         public WebResourceResponse handle(@NonNull String path) {
-            Uri uri = new Uri.Builder()
-                    .path(path)
-                    .build();
-
-            InputStream is = mAssetHelper.openAsset(uri);
+            InputStream is = mAssetHelper.openAsset(path);
             String mimeType = AssetHelper.guessMimeType(path);
             return new WebResourceResponse(mimeType, null, is);
         }
@@ -209,11 +205,7 @@
         @WorkerThread
         @Nullable
         public WebResourceResponse handle(@NonNull String path) {
-            Uri uri = new Uri.Builder()
-                    .path(path)
-                    .build();
-
-            InputStream is = mAssetHelper.openResource(uri);
+            InputStream is = mAssetHelper.openResource(path);
             String mimeType = AssetHelper.guessMimeType(path);
             return new WebResourceResponse(mimeType, null, is);
         }
diff --git a/webkit/src/main/java/androidx/webkit/internal/AssetHelper.java b/webkit/src/main/java/androidx/webkit/internal/AssetHelper.java
index e6d5d2e..72dae3d 100644
--- a/webkit/src/main/java/androidx/webkit/internal/AssetHelper.java
+++ b/webkit/src/main/java/androidx/webkit/internal/AssetHelper.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.res.AssetManager;
 import android.content.res.Resources;
-import android.net.Uri;
 import android.os.Build;
 import android.util.Log;
 import android.util.TypedValue;
@@ -32,7 +31,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URLConnection;
-import java.util.List;
 import java.util.zip.GZIPInputStream;
 
 /**
@@ -54,18 +52,27 @@
     }
 
     @Nullable
-    private static InputStream handleSvgzStream(@NonNull Uri uri, @Nullable InputStream stream) {
-        if (stream != null && uri.getLastPathSegment().endsWith(".svgz")) {
+    private static InputStream handleSvgzStream(@NonNull String path,
+            @Nullable InputStream stream) {
+        if (stream != null && path.endsWith(".svgz")) {
             try {
                 stream = new GZIPInputStream(stream);
             } catch (IOException e) {
-                Log.e(TAG, "Error decompressing " + uri + " - " + e.getMessage());
+                Log.e(TAG, "Error decompressing " + path + " - " + e.getMessage());
                 return null;
             }
         }
         return stream;
     }
 
+    @NonNull
+    private static String removeLeadingSlash(@NonNull String path) {
+        if (path.length() > 1 && path.charAt(0) == '/') {
+            path = path.substring(1);
+        }
+        return path;
+    }
+
     private int getFieldId(@NonNull String assetType, @NonNull String assetName) {
         String packageName = mContext.getPackageName();
         int id = mContext.getResources().getIdentifier(assetName, assetType, packageName);
@@ -81,19 +88,20 @@
     /**
      * Open an InputStream for an Android resource.
      *
-     * @param uri The uri to load. The path must be of the form "asset_type/asset_name.ext".
+     * @param path Path of the form "resource_type/resource_name.ext".
      * @return An InputStream to the Android resource.
      */
     @Nullable
-    public InputStream openResource(@NonNull Uri uri) {
+    public InputStream openResource(@NonNull String path) {
+        path = removeLeadingSlash(path);
         // The path must be of the form "asset_type/asset_name.ext".
-        List<String> pathSegments = uri.getPathSegments();
-        if (pathSegments.size() != 2) {
-            Log.e(TAG, "Incorrect resource path: " + uri);
+        String[] pathSegments = path.split("/");
+        if (pathSegments.length != 2) {
+            Log.e(TAG, "Incorrect resource path: " + path);
             return null;
         }
-        String assetType = pathSegments.get(0);
-        String assetName = pathSegments.get(1);
+        String assetType = pathSegments[0];
+        String assetName = pathSegments[1];
 
         // Drop the file extension.
         assetName = assetName.split("\\.")[0];
@@ -101,13 +109,13 @@
             int fieldId = getFieldId(assetType, assetName);
             int valueType = getValueType(fieldId);
             if (valueType == TypedValue.TYPE_STRING) {
-                return handleSvgzStream(uri, mContext.getResources().openRawResource(fieldId));
+                return handleSvgzStream(path, mContext.getResources().openRawResource(fieldId));
             } else {
-                Log.e(TAG, "Asset not of type string: " + uri);
+                Log.e(TAG, "Asset not of type string: " + path);
                 return null;
             }
         } catch (Resources.NotFoundException e) {
-            Log.e(TAG, "Resource not found from URL: " + uri, e);
+            Log.e(TAG, "Resource not found from the path: " + path, e);
             return null;
         }
     }
@@ -115,21 +123,17 @@
     /**
      * Open an InputStream for an Android asset.
      *
-     * @param uri The uri to load.
+     * @param path Path to the asset file to load.
      * @return An InputStream to the Android asset.
      */
     @Nullable
-    public InputStream openAsset(@NonNull Uri uri) {
-        String path = uri.getPath();
-        // Strip leading slash if present.
-        if (path.length() > 1 && path.charAt(0) == '/') {
-            path = path.substring(1);
-        }
+    public InputStream openAsset(@NonNull String path) {
+        path = removeLeadingSlash(path);
         try {
             AssetManager assets = mContext.getAssets();
-            return handleSvgzStream(uri, assets.open(path, AssetManager.ACCESS_STREAMING));
+            return handleSvgzStream(path, assets.open(path, AssetManager.ACCESS_STREAMING));
         } catch (IOException e) {
-            Log.e(TAG, "Unable to open asset URL: " + uri);
+            Log.e(TAG, "Unable to open asset path: " + path);
             return null;
         }
     }
@@ -144,7 +148,7 @@
     public static InputStream openFile(@NonNull File file) {
         try {
             FileInputStream fis = new FileInputStream(file);
-            return handleSvgzStream(Uri.parse(file.getPath()), fis);
+            return handleSvgzStream(file.getPath(), fis);
         } catch (IOException e) {
             Log.e(TAG, "Error opening the requested file " + file, e);
             return null;