Snap for 7214031 from 3aeaca0a78438caa45650b5f48e5be31dad40976 to mainline-tethering-release

Change-Id: I27ae4814fb48489425e297efc353a514582f9657
diff --git a/tests/tests/permission3/Android.bp b/tests/tests/permission3/Android.bp
index abedeef..ffe42ad 100644
--- a/tests/tests/permission3/Android.bp
+++ b/tests/tests/permission3/Android.bp
@@ -22,6 +22,7 @@
     ],
     static_libs: [
         "kotlin-stdlib",
+        "androidx.core_core",
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
@@ -37,6 +38,7 @@
         ":CtsUsePermissionApp29",
         ":CtsUsePermissionAppLatest",
         ":CtsUsePermissionAppLatestWithBackground",
+        ":CtsUsePermissionAppLocationProvider",
         ":CtsUsePermissionAppWithOverlay",
     ],
     test_suites: [
diff --git a/tests/tests/permission3/AndroidTest.xml b/tests/tests/permission3/AndroidTest.xml
index cdf7308..23df08f 100644
--- a/tests/tests/permission3/AndroidTest.xml
+++ b/tests/tests/permission3/AndroidTest.xml
@@ -43,6 +43,7 @@
         <option name="push" value="CtsUsePermissionApp29.apk->/data/local/tmp/cts/permission3/CtsUsePermissionApp29.apk" />
         <option name="push" value="CtsUsePermissionAppLatest.apk->/data/local/tmp/cts/permission3/CtsUsePermissionAppLatest.apk" />
         <option name="push" value="CtsUsePermissionAppLatestWithBackground.apk->/data/local/tmp/cts/permission3/CtsUsePermissionAppLatestWithBackground.apk" />
+        <option name="push" value="CtsUsePermissionAppLocationProvider.apk->/data/local/tmp/cts/permission3/CtsUsePermissionAppLocationProvider.apk" />
         <option name="push" value="CtsUsePermissionAppWithOverlay.apk->/data/local/tmp/cts/permission3/CtsUsePermissionAppWithOverlay.apk" />
     </target_preparer>
 
diff --git a/tests/tests/permission3/UsePermissionAppLocationProvider/Android.bp b/tests/tests/permission3/UsePermissionAppLocationProvider/Android.bp
new file mode 100644
index 0000000..56c9966
--- /dev/null
+++ b/tests/tests/permission3/UsePermissionAppLocationProvider/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2021 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CtsUsePermissionAppLocationProvider",
+    srcs: [
+        ":CtsUsePermissionAppSrc",
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "kotlin-stdlib",
+    ],
+    certificate: ":cts-testkey2",
+}
diff --git a/tests/tests/permission3/UsePermissionAppLocationProvider/AndroidManifest.xml b/tests/tests/permission3/UsePermissionAppLocationProvider/AndroidManifest.xml
new file mode 100644
index 0000000..16bacf5
--- /dev/null
+++ b/tests/tests/permission3/UsePermissionAppLocationProvider/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission3.cts.usepermission">
+
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+
+    <application>
+        <activity android:name=".AddLocationProviderActivity" android:exported="true" />
+        <activity android:name=".FinishOnCreateActivity" android:exported="true"
+                  android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/tests/permission3/UsePermissionAppLocationProvider/src/android/permission3/cts/usepermission/AddLocationProviderActivity.kt b/tests/tests/permission3/UsePermissionAppLocationProvider/src/android/permission3/cts/usepermission/AddLocationProviderActivity.kt
new file mode 100644
index 0000000..3bb461c
--- /dev/null
+++ b/tests/tests/permission3/UsePermissionAppLocationProvider/src/android/permission3/cts/usepermission/AddLocationProviderActivity.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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 android.permission3.cts.usepermission
+
+import android.app.Activity
+import android.location.Criteria
+import android.location.LocationManager
+import android.os.Bundle
+
+/**
+ * An activity that adds this package as a test location provider.
+ */
+class AddLocationProviderActivity : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        val locationManager = getSystemService(LocationManager::class.java)
+        locationManager.addTestProvider(
+            packageName, false, false, false, false, false, false, false, Criteria.POWER_LOW,
+            Criteria.ACCURACY_COARSE
+        )
+
+        setResult(RESULT_OK)
+        finish()
+    }
+}
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index bea7a16..6a8c512 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -53,6 +53,8 @@
         const val APP_APK_PATH_LATEST = "$APK_DIRECTORY/CtsUsePermissionAppLatest.apk"
         const val APP_APK_PATH_LATEST_WITH_BACKGROUND =
                 "$APK_DIRECTORY/CtsUsePermissionAppLatestWithBackground.apk"
+        const val APP_APK_PATH_LOCATION_PROVIDER =
+            "$APK_DIRECTORY/CtsUsePermissionAppLocationProvider.apk"
         const val APP_APK_PATH_WITH_OVERLAY = "$APK_DIRECTORY/CtsUsePermissionAppWithOverlay.apk"
         const val APP_PACKAGE_NAME = "android.permission3.cts.usepermission"
 
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionUsageInfoTest.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionUsageInfoTest.kt
new file mode 100644
index 0000000..fcfb5fd
--- /dev/null
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionUsageInfoTest.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2021 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 android.permission3.cts
+
+import android.app.Activity
+import android.app.AppOpsManager
+import android.content.ComponentName
+import android.content.Intent
+import android.location.LocationManager
+import android.support.test.uiautomator.By
+import androidx.core.os.BuildCompat
+import com.android.compatibility.common.util.AppOpsUtils.setOpMode
+import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity
+import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import java.util.concurrent.TimeUnit
+
+/**
+ * Tests permission usage info action for location providers.
+ */
+class PermissionUsageInfoTest : BaseUsePermissionTest() {
+    val locationManager = context.getSystemService(LocationManager::class.java)!!
+
+    @Before
+    fun installAppLocationProviderAndAllowMockLocation() {
+        installPackage(APP_APK_PATH_LOCATION_PROVIDER)
+        // The package name of a mock location provider is the caller adding it, so we have to let
+        // the test app add itself.
+        setOpMode(APP_PACKAGE_NAME, AppOpsManager.OPSTR_MOCK_LOCATION, AppOpsManager.MODE_ALLOWED)
+    }
+
+    @Before
+    fun allowMockLocation() {
+        // Allow ourselves to reliably remove the test location provider.
+        setOpMode(
+            context.packageName, AppOpsManager.OPSTR_MOCK_LOCATION, AppOpsManager.MODE_ALLOWED
+        )
+    }
+
+    @After
+    fun removeTestLocationProvider() {
+        locationManager.removeTestProvider(APP_PACKAGE_NAME)
+    }
+
+    @Test
+    fun testLocationProviderPermissionUsageInfo() {
+        val locationProviderPackageName: String
+        if (BuildCompat.isAtLeastS()) {
+            // Add the test app as location provider.
+            val future = startActivityForFuture(
+                Intent().apply {
+                    component = ComponentName(
+                        APP_PACKAGE_NAME, "$APP_PACKAGE_NAME.AddLocationProviderActivity"
+                    )
+                }
+            )
+            val result = future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)
+            assertEquals(Activity.RESULT_OK, result.resultCode)
+            assertTrue(
+                callWithShellPermissionIdentity {
+                    locationManager.isProviderPackage(APP_PACKAGE_NAME)
+                }
+            )
+            locationProviderPackageName = APP_PACKAGE_NAME
+        } else {
+            // Test location provider doesn't count as location provier package before S.
+            val locationManager = context.getSystemService(LocationManager::class.java)!!
+            locationProviderPackageName = packageManager.getInstalledApplications(0)
+                .map { it.packageName }
+                .filter {
+                    callWithShellPermissionIdentity { locationManager.isProviderPackage(it) }
+                }
+                .firstOrNull {
+                    Intent(Intent.ACTION_VIEW_PERMISSION_USAGE)
+                        .setPackage(it)
+                        .resolveActivity(packageManager) != null
+                }
+                .let {
+                    assumeTrue(it != null)
+                    it!!
+                }
+        }
+
+        runWithShellPermissionIdentity {
+            context.startActivity(
+                Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS).apply {
+                    putExtra(Intent.EXTRA_PACKAGE_NAME, locationProviderPackageName)
+                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                }
+            )
+        }
+        click(By.res("com.android.permissioncontroller:id/icon"))
+    }
+}