Adding functionality to open by default settings dialog

Allows the user to change how links open by default (either in the app
or in the default browser) by choosing the setting from the dialog.

Bug: 359262490
Test: manual testing
Flag: com.android.window.flags.enable_desktop_windowing_app_to_web
Change-Id: I573c234df65e829179c10728c3b194eb755f42be
diff --git a/libs/WindowManager/Shell/AndroidManifest.xml b/libs/WindowManager/Shell/AndroidManifest.xml
index 3b739c3..1260796 100644
--- a/libs/WindowManager/Shell/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/AndroidManifest.xml
@@ -24,6 +24,7 @@
     <uses-permission android:name="android.permission.WAKEUP_SURFACE_FLINGER" />
     <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
     <uses-permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE" />
+    <uses-permission android:name="android.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION" />
 
     <application>
         <activity
diff --git a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_dismiss_button_background.xml b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
similarity index 100%
rename from libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_dismiss_button_background.xml
rename to libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
diff --git a/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml b/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
index 8ff382b..b5bceda 100644
--- a/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
+++ b/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
@@ -111,7 +111,7 @@
                 </RadioGroup>
 
                 <Button
-                    android:id="@+id/open_by_default_settings_dialog_dismiss_button"
+                    android:id="@+id/open_by_default_settings_dialog_confirm_button"
                     android:layout_width="wrap_content"
                     android:layout_height="36dp"
                     android:text="@string/open_by_default_dialog_dismiss_button_text"
@@ -122,7 +122,7 @@
                     android:textSize="14sp"
                     android:textFontWeight="500"
                     android:textColor="?androidprv:attr/materialColorOnPrimary"
-                    android:background="@drawable/open_by_default_settings_dialog_dismiss_button_background"/>
+                    android:background="@drawable/open_by_default_settings_dialog_confirm_button_background"/>
             </LinearLayout>
         </ScrollView>
     </FrameLayout>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt
index 71bcb59..65132fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/AppToWebUtils.kt
@@ -22,7 +22,13 @@
 import android.content.Intent
 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
 import android.content.pm.PackageManager
+import android.content.pm.verify.domain.DomainVerificationManager
+import android.content.pm.verify.domain.DomainVerificationUserState
 import android.net.Uri
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.protolog.ShellProtoLogGroup
+
+private const val TAG = "AppToWebUtils"
 
 private val GenericBrowserIntent = Intent()
     .setAction(Intent.ACTION_VIEW)
@@ -58,4 +64,25 @@
     val component = intent.resolveActivity(packageManager) ?: return null
     intent.setComponent(component)
     return intent
-}
\ No newline at end of file
+}
+
+/**
+ * Returns the [DomainVerificationUserState] of the user associated with the given
+ * [DomainVerificationManager] and the given package.
+ */
+fun getDomainVerificationUserState(
+    manager: DomainVerificationManager,
+    packageName: String
+): DomainVerificationUserState? {
+    try {
+        return manager.getDomainVerificationUserState(packageName)
+    } catch (e: PackageManager.NameNotFoundException) {
+        ProtoLog.w(
+            ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
+            "%s: Failed to get domain verification user state: %s",
+            TAG,
+            e.message!!
+        )
+        return null
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt
index 4926cbd..a727b54 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialog.kt
@@ -19,6 +19,7 @@
 import android.app.ActivityManager.RunningTaskInfo
 import android.app.TaskInfo
 import android.content.Context
+import android.content.pm.verify.domain.DomainVerificationManager
 import android.graphics.Bitmap
 import android.graphics.PixelFormat
 import android.view.LayoutInflater
@@ -30,6 +31,7 @@
 import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
 import android.view.WindowlessWindowManager
 import android.widget.ImageView
+import android.widget.RadioButton
 import android.widget.TextView
 import android.window.TaskConstants
 import com.android.wm.shell.R
@@ -58,8 +60,17 @@
     private lateinit var appIconView: ImageView
     private lateinit var appNameView: TextView
 
+    private lateinit var openInAppButton: RadioButton
+    private lateinit var openInBrowserButton: RadioButton
+
+    private val domainVerificationManager =
+        context.getSystemService(DomainVerificationManager::class.java)!!
+    private val packageName = taskInfo.baseActivity?.packageName!!
+
+
     init {
         createDialog()
+        initializeRadioButtons()
         bindAppInfo(appIconBitmap, appName)
     }
 
@@ -111,9 +122,30 @@
             closeMenu()
         }
 
+        dialog.setConfirmButtonClickListener {
+            setDefaultLinkHandlingSetting()
+            closeMenu()
+        }
+
         listener.onDialogCreated()
     }
 
+    private fun initializeRadioButtons() {
+        openInAppButton = dialog.requireViewById(R.id.open_in_app_button)
+        openInBrowserButton = dialog.requireViewById(R.id.open_in_browser_button)
+
+        val userState =
+            getDomainVerificationUserState(domainVerificationManager, packageName) ?: return
+        val openInApp = userState.isLinkHandlingAllowed
+        openInAppButton.isChecked = openInApp
+        openInBrowserButton.isChecked = !openInApp
+    }
+
+    private fun setDefaultLinkHandlingSetting() {
+        domainVerificationManager.setDomainVerificationLinkHandlingAllowed(
+            packageName, openInAppButton.isChecked)
+    }
+
     private fun closeMenu() {
         dialogContainer?.releaseView()
         dialogContainer = null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialogView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialogView.kt
index d03a38e..1b914f4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialogView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OpenByDefaultDialogView.kt
@@ -36,9 +36,6 @@
     private lateinit var backgroundDim: Drawable
 
     fun setDismissOnClickListener(callback: (View) -> Unit) {
-        val dismissButton = dialogContainer.requireViewById<Button>(
-            R.id.open_by_default_settings_dialog_dismiss_button)
-        dismissButton.setOnClickListener(callback)
         // Clicks on the background dim should also dismiss the dialog.
         setOnClickListener(callback)
         // We add a no-op on-click listener to the dialog container so that clicks on it won't
@@ -46,6 +43,13 @@
         dialogContainer.setOnClickListener { }
     }
 
+    fun setConfirmButtonClickListener(callback: (View) -> Unit) {
+        val dismissButton = dialogContainer.requireViewById<Button>(
+            R.id.open_by_default_settings_dialog_confirm_button
+        )
+        dismissButton.setOnClickListener(callback)
+    }
+
     override fun onFinishInflate() {
         super.onFinishInflate()
         dialogContainer = requireViewById(R.id.open_by_default_dialog_container)