Implement "suppress incoming call heads up notification" setting

Bug: 159632870
Bug: 161163282
Test: Manual test
Change-Id: I982bffee9d64b2bdd54665b58c49eb39db9c6e95
diff --git a/res/values/configs.xml b/res/values/configs.xml
index e3ea6e6..48c87f6 100644
--- a/res/values/configs.xml
+++ b/res/values/configs.xml
@@ -50,6 +50,12 @@
     <!-- Config for enabling incoming call HUN fullscreen intent -->
     <bool name="config_show_hun_fullscreen_incall_ui">true</bool>
 
+    <!-- A config determines whether to show a heads up notification when there's a incoming call-->
+    <bool name="config_should_show_incoming_call_hun">true</bool>
+    <!-- A config determines whether to show an entry in setting to config showing a heads up
+    notification when there's a incoming call-->
+    <bool name="config_should_show_incoming_call_hun_setting">false</bool>
+
     <!-- A config determines whether to show type down list on Dialpad -->
     <bool name="config_show_type_down_list_on_dialpad">true</bool>
     <!-- A config determines whether to show user profile for input number only when type down is
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ae39453..47caff8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -201,6 +201,12 @@
     <string name="pref_connected_phone_title">Connected Phone </string>
     <string name="pref_connected_phone_key" translatable="false">connected_phone</string>
 
+    <!-- Title of no incoming call heads-up notification(HUN) setting -->
+    <string name="pref_no_incoming_call_hun_title">Privacy</string>
+    <string name="pref_no_incoming_call_hun_key" translatable="false">no_incoming_call_hun</string>
+    <!-- Summary of no incoming call heads-up notification(HUN) setting -->
+    <string name="pref_no_incoming_call_hun_summary">Only show call alerts in cluster</string>
+
     <!-- Keys and titles of the settings for sorting Contacts in different orders -->
     <!-- Key of given name -->
     <string name="given_name_first_key" translatable="false">given_name</string>
diff --git a/res/xml/settings_page.xml b/res/xml/settings_page.xml
index 7462a1b..11028a3 100644
--- a/res/xml/settings_page.xml
+++ b/res/xml/settings_page.xml
@@ -17,12 +17,20 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:title="@string/setting_title">
 
     <Preference
         android:key="@string/pref_connected_phone_key"
         android:title="@string/pref_connected_phone_title"/>
 
+    <SwitchPreference
+        android:defaultValue="@bool/config_should_show_incoming_call_hun"
+        android:key="@string/pref_no_incoming_call_hun_key"
+        android:title="@string/pref_no_incoming_call_hun_title"
+        android:summary="@string/pref_no_incoming_call_hun_summary"
+        app:isPreferenceVisible="@bool/config_should_show_incoming_call_hun_setting"/>
+
     <ListPreference
         android:key="@string/pref_start_page_key"
         android:title="@string/pref_start_page_title"
diff --git a/src/com/android/car/dialer/telecom/InCallRouter.java b/src/com/android/car/dialer/telecom/InCallRouter.java
index 4ba91e4..c4274fb 100644
--- a/src/com/android/car/dialer/telecom/InCallRouter.java
+++ b/src/com/android/car/dialer/telecom/InCallRouter.java
@@ -21,6 +21,7 @@
 import android.telecom.Call;
 
 import androidx.annotation.MainThread;
+import androidx.preference.PreferenceManager;
 
 import com.android.car.dialer.Constants;
 import com.android.car.dialer.R;
@@ -83,11 +84,15 @@
 
         int state = call.getState();
         if (state == Call.STATE_RINGING) {
-            routeToNotification(call);
+            if (shouldShowIncomingCallHun()) {
+                routeToNotification(call);
+            }
+            // Otherwise, no operations. Incoming call will be displayed outside of Dialer app
+            // such as cluster.
         } else if (state != Call.STATE_DISCONNECTED) {
             // Don't launch the in call page if state is disconnected.
             // Otherwise, the InCallActivity finishes right after onCreate() and flashes.
-            routeToInCallPage(false);
+            routeToFullScreenIncomingCallPage(false);
         }
     }
 
@@ -140,7 +145,7 @@
                 if (call.getState() != Call.STATE_DISCONNECTED) {
                     // Don't launch the in call page if state is disconnected. Otherwise, the
                     // InCallActivity finishes right after onCreate() and flashes.
-                    routeToInCallPage(false);
+                    routeToFullScreenIncomingCallPage(false);
                 }
                 mInCallNotificationController.cancelInCallNotification(call);
                 call.unregisterCallback(this);
@@ -151,7 +156,7 @@
     /**
      * Launches {@link InCallActivity} and presents the on going call in the in call page.
      */
-    void routeToInCallPage(boolean showDialpad) {
+    void routeToFullScreenIncomingCallPage(boolean showDialpad) {
         // It has been configured not to show the fullscreen incall ui.
         if (!mShowFullscreenIncallUi) {
             return;
@@ -161,4 +166,9 @@
         launchIntent.putExtra(Constants.Intents.EXTRA_SHOW_INCOMING_CALL, showDialpad);
         mContext.startActivity(launchIntent);
     }
+
+    private boolean shouldShowIncomingCallHun() {
+        return PreferenceManager.getDefaultSharedPreferences(mContext)
+                .getBoolean(mContext.getString(R.string.pref_no_incoming_call_hun_key), true);
+    }
 }
diff --git a/src/com/android/car/dialer/telecom/InCallServiceImpl.java b/src/com/android/car/dialer/telecom/InCallServiceImpl.java
index d60c9d1..ab75c6e 100644
--- a/src/com/android/car/dialer/telecom/InCallServiceImpl.java
+++ b/src/com/android/car/dialer/telecom/InCallServiceImpl.java
@@ -121,7 +121,7 @@
     @Override
     public void onBringToForeground(boolean showDialpad) {
         L.d(TAG, "onBringToForeground: %s", showDialpad);
-        mInCallRouter.routeToInCallPage(showDialpad);
+        mInCallRouter.routeToFullScreenIncomingCallPage(showDialpad);
     }
 
     public void addCallAudioStateChangedCallback(CallAudioStateCallback callback) {