Implement test: Accepted calls are displayed in Full Screen if and only if Active
Call is enabled.

Test: Active-call on: https://paste.googleplex.com/5135860945649664
      Active-call off: https://paste.googleplex.com/6028226233630720
Bug: 273366005
Change-Id: I344bbd2c12f5082e479682280f4bab242aea07bd
diff --git a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java
index bc29a47..0c0f712 100644
--- a/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java
+++ b/libraries/app-helpers/interfaces/auto/src/android/platform/helpers/IAutoDialHelper.java
@@ -59,6 +59,9 @@
     /** Assumes contact page is open. Press the mobile call button on a contact page. */
     void pressMobileCallOnContact();
 
+    /** Assumes Dialer settings page is open. Press the active call toggle. */
+    void pressActiveCallToggle();
+
     /**
      * Setup expectations: The app is open and there is an ongoing call.
      *
@@ -302,6 +305,13 @@
     boolean isOngoingCallDisplayedOnHome();
 
     /**
+     * Setup expectations: None
+     *
+     * @return Whether the screen currently shows an ongoing call (in full-screen mode).
+     */
+    boolean isOngoingCallInFullScreen();
+
+    /**
      * Setup expectations: The home screen is open
      *
      * <p>This method is used for opening phone app from homescreen
@@ -323,6 +333,13 @@
     int getNumberOfCallHistoryEntries();
 
     /**
+     * Setup expectations: the Dialer Settings page is open.
+     *
+     * <p>Returns true if the Active Call feature is enabled, false otherwise.
+     */
+    boolean isActiveCallEnabled();
+
+    /**
      * Setup expectations: bluetooth is off
      *
      * <p>This method is used for checking if error message is displaye when bluetooth is off
diff --git a/libraries/automotive-helpers/auto-default-config/resources/assets/defaultSpectatioConfig.json b/libraries/automotive-helpers/auto-default-config/resources/assets/defaultSpectatioConfig.json
index 28a7263..a3e9b59 100644
--- a/libraries/automotive-helpers/auto-default-config/resources/assets/defaultSpectatioConfig.json
+++ b/libraries/automotive-helpers/auto-default-config/resources/assets/defaultSpectatioConfig.json
@@ -1811,6 +1811,31 @@
       "TYPE": "TEXT",
       "VALUE": "Dialpad"
     },
+    "DIALER_ACTIVE_CALL_TOGGLE": {
+      "TYPE": "MULTIPLE",
+      "SPECIFIERS": [
+        {
+          "TYPE": "CLASS",
+          "VALUE": "android.widget.Switch"
+        },
+        {
+          "TYPE": "HAS_ANCESTOR",
+          "MAX_DEPTH": 3,
+          "ANCESTOR": {
+            "TYPE": "HAS_DESCENDANT",
+            "MAX_DEPTH": 2,
+            "DESCENDANT": {
+              "TYPE": "TEXT",
+              "VALUE": "Active Call"
+            }
+          }
+        }
+      ]
+    },
+    "DIALER_ONGOING_CALL_CONTROL_BAR": {
+      "TYPE": "RESOURCE_ID",
+      "VALUE": "ongoing_call_control_bar"
+    },
     "LOCATION_ACCESS": {
       "TYPE": "TEXT",
       "VALUE": "Location access"
diff --git a/libraries/automotive-helpers/auto-default-config/src/android/platform/helpers/AutomotiveConfigConstants.java b/libraries/automotive-helpers/auto-default-config/src/android/platform/helpers/AutomotiveConfigConstants.java
index 070faa0..3ea0f1f 100644
--- a/libraries/automotive-helpers/auto-default-config/src/android/platform/helpers/AutomotiveConfigConstants.java
+++ b/libraries/automotive-helpers/auto-default-config/src/android/platform/helpers/AutomotiveConfigConstants.java
@@ -76,8 +76,6 @@
     public static final String CONTACT_SETTINGS = "CONTACT_SETTINGS";
     public static final String DIAL_PAD_FRAGMENT = "DIAL_PAD_FRAGMENT";
 
-    public static final String DIALER_SETTINGS_BUTTON = "DIALER_SETTINGS_BUTTON";
-
     public static final String DIALER_CONNECTED_PHONE_NAME = "DIALER_CONNECTED_PHONE_NAME";
     public static final String DIGIT_ZERO = "0";
     public static final String DIGIT_ONE = "1";
@@ -651,6 +649,9 @@
     public static final String DIALER_CONTACTS = "DIALER_CONTACTS";
     public static final String DIALER_FAVORITES = "DIALER_FAVORITES";
     public static final String DIALER_DIALPAD = "DIALER_DIALPAD";
+    public static final String DIALER_ACTIVE_CALL_TOGGLE = "DIALER_ACTIVE_CALL_TOGGLE";
+    public static final String DIALER_ONGOING_CALL_CONTROL_BAR = "DIALER_ONGOING_CALL_CONTROL_BAR";
+    public static final String DIALER_SETTINGS_BUTTON = "DIALER_SETTINGS_BUTTON";
 
     // Phone Device Identifiers
     public static final String MOBILE_CALL_BUTTON = "MOBILE_CALL_BUTTON";
diff --git a/libraries/automotive-helpers/dial-app-helper/src/android/platform/helpers/DialHelperImpl.java b/libraries/automotive-helpers/dial-app-helper/src/android/platform/helpers/DialHelperImpl.java
index ee74839..45701c3 100644
--- a/libraries/automotive-helpers/dial-app-helper/src/android/platform/helpers/DialHelperImpl.java
+++ b/libraries/automotive-helpers/dial-app-helper/src/android/platform/helpers/DialHelperImpl.java
@@ -98,6 +98,21 @@
 
     /** {@inheritDoc} */
     @Override
+    public void pressActiveCallToggle() {
+        BySelector toggleSelector =
+                getUiElementFromConfig(AutomotiveConfigConstants.DIALER_ACTIVE_CALL_TOGGLE);
+
+        UiObject2 activeCallToggle = getSpectatioUiUtil().findUiObject(toggleSelector);
+
+        getSpectatioUiUtil()
+                .validateUiObject(
+                        activeCallToggle, AutomotiveConfigConstants.DIALER_ACTIVE_CALL_TOGGLE);
+
+        getSpectatioUiUtil().clickAndWait(activeCallToggle);
+    }
+
+    /** {@inheritDoc} */
+    @Override
     public void pressContactResult(String expectedName) {
         BySelector searchResultSelector =
                 getUiElementFromConfig(AutomotiveConfigConstants.CONTACT_SEARCH_RESULT);
@@ -253,6 +268,25 @@
                         dialedContactName, AutomotiveConfigConstants.DIALED_CONTACT_TITLE);
         return dialedContactName.getText();
     }
+    /** {@inheritDoc} */
+    @Override
+    public boolean isActiveCallEnabled() {
+        return buttonChecked(AutomotiveConfigConstants.DIALER_ACTIVE_CALL_TOGGLE);
+    }
+
+    /**
+     * Assumes passed in BySelector title is a checkable button that is currently onscreen
+     *
+     * @param buttonName - The button whose status is to be checked.
+     * @return - Whether or not the button element with the given name as a descriptor is checked.
+     */
+    public boolean buttonChecked(String buttonName) {
+        BySelector toggleSelector = getUiElementFromConfig(buttonName);
+        UiObject2 toggleButton = getSpectatioUiUtil().findUiObject(toggleSelector);
+        getSpectatioUiUtil().validateUiObject(toggleButton, buttonName);
+
+        return toggleButton.isChecked();
+    }
 
     /** {@inheritDoc} */
     public void inCallDialPad(String phoneNumber) {
@@ -589,17 +623,22 @@
     /** {@inheritDoc} */
     @Override
     public void openDialerSettings() {
-        BySelector dialerSettingsSelector =
+        BySelector settingsButtonSelector =
                 getUiElementFromConfig(AutomotiveConfigConstants.DIALER_SETTINGS_BUTTON);
 
         ArrayList<UiObject2> buttonCandidates =
-                new ArrayList<>(getSpectatioUiUtil().findUiObjects(dialerSettingsSelector));
+                new ArrayList<>(getSpectatioUiUtil().findUiObjects(settingsButtonSelector));
 
-        UiObject2 dialerSettingsButton = buttonCandidates.get(1);
+        // This is an awkward hard-coding to compensate for the fact that currently the
+        // search button and the settings button have identical metadata.
+        // (The Settings button is the second of the two, hence index 1)
+        // TODO: b/287706588 - Rewrite this UiObject selection to use a new Content Descriptor
+        UiObject2 contactMenuButton = buttonCandidates.get(1);
+
         getSpectatioUiUtil()
                 .validateUiObject(
-                        dialerSettingsButton, AutomotiveConfigConstants.DIALER_SETTINGS_BUTTON);
-        getSpectatioUiUtil().clickAndWait(dialerSettingsButton);
+                        contactMenuButton, AutomotiveConfigConstants.DIALER_SETTINGS_BUTTON);
+        getSpectatioUiUtil().clickAndWait(contactMenuButton);
     }
 
     /** {@inheritDoc} */
@@ -759,6 +798,17 @@
         return getSpectatioUiUtil().hasUiElement(ongoingCallSelector);
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public boolean isOngoingCallInFullScreen() {
+        // Whether an ongoing call is currently showing onscreen can be indicated
+        // by whether an ongoing call control bar is currently on the screen,
+        // but other methods of detecting this can be used.
+        BySelector controlBarSelector =
+                getUiElementFromConfig(AutomotiveConfigConstants.DIALER_ONGOING_CALL_CONTROL_BAR);
+        return getSpectatioUiUtil().hasUiElement(controlBarSelector);
+    }
+
     /** This method opens the phone app on tapping the home phone card on home screen */
     public void openPhoneAppFromHome() {
         BySelector homePhoneCardSelector =
diff --git a/tests/automotive/mobly_tests/dialer/Android.bp b/tests/automotive/mobly_tests/dialer/Android.bp
index 162844f..f11cab1 100644
--- a/tests/automotive/mobly_tests/dialer/Android.bp
+++ b/tests/automotive/mobly_tests/dialer/Android.bp
@@ -585,6 +585,8 @@
     },
 }
 
+
+
 python_test_host {
     name: "BTDialerBluetoothSettingsReflection",
     main: "dialer_test_bluetooth_settings_reflection.py",
@@ -639,4 +641,62 @@
             embedded_launcher: true,
         },
     },
+}
+
+python_test_host {
+    name: "BTDialerActiveCallOn",
+    main: "dialer_test_active_call_on.py",
+    srcs: ["dialer_test_active_call_on.py"],
+
+    libs: [
+        "mobly",
+        "utilities",
+        "bluetooth_test",
+        "BluetoothSMSTestLibrary"
+    ],
+    test_suites: [
+        "catbox",
+    ],
+    test_options: {
+        unit_test: false,
+    },
+    data: [
+        // Package the snippet with the mobly test
+        ":AutomotiveSnippet",
+        ":PhoneSnippet",
+    ],
+    version: {
+        py3: {
+            embedded_launcher: true,
+        },
+    },
+}
+
+python_test_host {
+    name: "BTDialerActiveCallOff",
+    main: "dialer_test_active_call_off.py",
+    srcs: ["dialer_test_active_call_off.py"],
+
+    libs: [
+        "mobly",
+        "utilities",
+        "bluetooth_test",
+        "BluetoothSMSTestLibrary"
+    ],
+    test_suites: [
+        "catbox",
+    ],
+    test_options: {
+        unit_test: false,
+    },
+    data: [
+        // Package the snippet with the mobly test
+        ":AutomotiveSnippet",
+        ":PhoneSnippet",
+    ],
+    version: {
+        py3: {
+            embedded_launcher: true,
+        },
+    },
 }
\ No newline at end of file
diff --git a/tests/automotive/mobly_tests/dialer/dialer_test_active_call_off.py b/tests/automotive/mobly_tests/dialer/dialer_test_active_call_off.py
new file mode 100644
index 0000000..325a60b
--- /dev/null
+++ b/tests/automotive/mobly_tests/dialer/dialer_test_active_call_off.py
@@ -0,0 +1,72 @@
+#  Copyright (C) 2023 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.
+"""
+1. Launch Dialer -Settings -  Turn Active Call ON
+https://screenshot.googleplex.com/3QDmSzeiis4TH92
+2. Switch to Launcher or Maps or any page
+3. Call to Paired Device and Answer an incoming call
+4. Verify the  dialer - dial in progress page displayed in Full view when user tap to Answer phone call
+Video Demo: https://drive.google.com/file/d/15HK77k47j8oDonbjY0IegoJnJESEcvwM/view?usp=sharing&resourcekey=0-CUtdhL4Y0z_uwnjl2QMjew
+"""
+
+from bluetooth_sms_test import bluetooth_sms_base_test
+import logging
+from mobly import asserts
+from utilities import phone_device_utils
+from utilities import constants
+from utilities.main_utils import common_main
+
+
+class DialerActiveCallOff(bluetooth_sms_base_test.BluetoothSMSBaseTest):
+
+    def setup_class(self):
+        super().setup_class()
+        self.phone_utils = (phone_device_utils.PhoneDeviceUtils(self.phone_notpaired))
+
+    def setup_test(self):
+        # Pair the devices
+        self.bt_utils.pair_primary_to_secondary()
+
+    def test_active_call_off(self):
+
+        # Navigate to dialer settings
+        self.call_utils.open_phone_app()
+        self.call_utils.open_dialer_settings()
+        # Enable Active Call
+        asserts.assert_false(self.call_utils.is_active_call_enabled(),
+                            "Expected Active Call to be disabled by default, but it was enabled.")
+        self.call_utils.press_home()
+
+        # Call the paired phone device (from an unpaired phone) and answer the call.
+        # call from the unpaired phone to the paired phone
+        callee_number = self.target.mbs.getPhoneNumber()
+        self.phone_utils.call_number_from_home_screen(callee_number)
+
+        # Receive and answer the call
+        self.call_utils.wait_with_log(5)
+        self.discoverer.mbs.clickUIElementWithText(constants.ACCEPT_CALL_TEXT)
+        self.call_utils.wait_with_log(2)
+        # Verify that the in-progress call is displayed in full-screen view.
+        asserts.assert_false(
+            self.call_utils.is_active_call_ongoing_full_screen(),
+            "Without enabling Active Call, accepted phone calls was displayed in fullscreen."
+        )
+
+    def teardown_test(self):
+        # Navigate to dialer settings
+        self.call_utils.end_call_using_adb_command(self.phone_notpaired)
+        super().teardown_test()
+
+if __name__ == '__main__':
+    common_main()
\ No newline at end of file
diff --git a/tests/automotive/mobly_tests/dialer/dialer_test_active_call_on.py b/tests/automotive/mobly_tests/dialer/dialer_test_active_call_on.py
new file mode 100644
index 0000000..0f08a83
--- /dev/null
+++ b/tests/automotive/mobly_tests/dialer/dialer_test_active_call_on.py
@@ -0,0 +1,78 @@
+#  Copyright (C) 2023 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.
+"""
+1. Launch Dialer -Settings -  Turn Active Call ON
+https://screenshot.googleplex.com/3QDmSzeiis4TH92
+2. Switch to Launcher or Maps or any page
+3. Call to Paired Device and Answer an incoming call
+4. Verify the  dialer - dial in progress page displayed in Full view when user tap to Answer phone call
+Video Demo: https://drive.google.com/file/d/15HK77k47j8oDonbjY0IegoJnJESEcvwM/view?usp=sharing&resourcekey=0-CUtdhL4Y0z_uwnjl2QMjew
+"""
+
+from bluetooth_sms_test import bluetooth_sms_base_test
+import logging
+from mobly import asserts
+from utilities import phone_device_utils
+from utilities import constants
+from utilities.main_utils import common_main
+
+
+class DialerActiveCallOn(bluetooth_sms_base_test.BluetoothSMSBaseTest):
+
+    def setup_class(self):
+        super().setup_class()
+        self.phone_utils = (phone_device_utils.PhoneDeviceUtils(self.phone_notpaired))
+
+    def setup_test(self):
+        # Pair the devices
+        self.bt_utils.pair_primary_to_secondary()
+
+    def test_active_call_on(self):
+
+        # Navigate to dialer settings
+        self.call_utils.open_phone_app()
+        self.call_utils.open_dialer_settings()
+        # Enable Active Call
+        self.call_utils.press_active_call_toggle()
+        asserts.assert_true(self.call_utils.is_active_call_enabled(),
+                            "Expected Active Call to be enabled after pressing the toggle.")
+
+        # Call the paired phone device (from an unpaired phone) and answer the call.
+        # call from the unpaired phone to the paired phone
+        callee_number = self.target.mbs.getPhoneNumber()
+        self.phone_utils.call_number_from_home_screen(callee_number)
+        self.call_utils.press_home()
+
+        # Receive and answer the call
+        self.call_utils.wait_with_log(10)
+        self.discoverer.mbs.clickUIElementWithText(constants.ACCEPT_CALL_TEXT)
+        self.call_utils.wait_with_log(2)
+        # Verify that the in-progress call is displayed in full-screen view.
+        asserts.assert_true(
+            self.call_utils.is_active_call_ongoing_full_screen(),
+            "After enabling Active Call, expected received call to be fullscreen, "
+            "but it was not (i.e., no Active Call Control Bar found)"
+        )
+
+    def teardown_test(self):
+        # Navigate to dialer settings
+        self.call_utils.end_call_using_adb_command(self.phone_notpaired)
+        self.call_utils.open_phone_app()
+        self.call_utils.open_dialer_settings()
+        self.call_utils.press_active_call_toggle()
+        super().teardown_test()
+
+
+if __name__ == '__main__':
+    common_main()
\ No newline at end of file
diff --git a/tests/automotive/mobly_tests/utilities/constants.py b/tests/automotive/mobly_tests/utilities/constants.py
index 921d6c1..44a834c 100644
--- a/tests/automotive/mobly_tests/utilities/constants.py
+++ b/tests/automotive/mobly_tests/utilities/constants.py
@@ -41,7 +41,7 @@
 CONNECTED_SUMMARY_STATUS = "Connected"
 DISCONNECTED_SUMMARY_STATUS = "Disconnected"
 DECLINE_CALL_TEXT = "Decline"
-ACCEPT_CALL_TEXT = "Accept"
+ACCEPT_CALL_TEXT = "Answer"
 
 BTSNOOP_LOG_PATH_ON_DEVICE = '/data/misc/bluetooth/logs/btsnoop_hci.log'
 BTSNOOP_LAST_LOG_PATH_ON_DEVICE = (
diff --git a/tests/automotive/mobly_tests/utilities/spectatio_utils.py b/tests/automotive/mobly_tests/utilities/spectatio_utils.py
index 675a2bf..f382333 100644
--- a/tests/automotive/mobly_tests/utilities/spectatio_utils.py
+++ b/tests/automotive/mobly_tests/utilities/spectatio_utils.py
@@ -105,6 +105,10 @@
         logging.info("Opening the dialpad")
         self.device.mbs.openDialPad()
 
+    def open_dialer_settings(self):
+        logging.info("Opening the dialer settings")
+        self.device.mbs.openDialerSettings()
+
     def open_phone_app(self):
         logging.info("Opening phone app")
         self.device.mbs.openPhoneApp()
@@ -121,6 +125,10 @@
         logging.info("Opening bluetooth settings (via the Status Bar)")
         self.device.mbs.openBluetoothSettings()
 
+    def press_active_call_toggle(self):
+        logging.info("Pressing the Active Call toggle")
+        self.device.mbs.pressActiveCallToggle()
+
     def open_dialer_settings(self):
         """Open dialer settings"""
         logging.info('Opening Dialer settings')
@@ -555,6 +563,14 @@
         logging.info('Is Bluetooth Button Enabled')
         return self.device.mbs.isBluetoothButtonEnabled()
 
+    def is_active_call_enabled(self):
+        logging.info("Verifying whether active call is enabled")
+        return self.device.mbs.isActiveCallEnabled()
+
+    def is_active_call_ongoing_full_screen(self):
+        logging.info("Verify whether an ongoing call is currently showing in full-screen mode")
+        return self.device.mbs.isOngoingCallInFullScreen()
+
     def is_bluetooth_phone_button_enabled(self):
         logging.info('Is Bluetooth Palette PhoneButton Enabled')
         return self.device.mbs.isBluetoothPhoneButtonEnabled()
diff --git a/tests/automotive/snippets/phone/src/com/google/android/mobly/snippet/bundled/DialerSnippet.java b/tests/automotive/snippets/phone/src/com/google/android/mobly/snippet/bundled/DialerSnippet.java
index df71139..54ee8ce 100644
--- a/tests/automotive/snippets/phone/src/com/google/android/mobly/snippet/bundled/DialerSnippet.java
+++ b/tests/automotive/snippets/phone/src/com/google/android/mobly/snippet/bundled/DialerSnippet.java
@@ -130,6 +130,16 @@
         mDialerHelper.get().dialFromList(contact);
     }
 
+    @Rpc(description = "Returns whether a call is currently ongoing and in full-screen mode.")
+    public boolean isOngoingCallInFullScreen() {
+        return mDialerHelper.get().isOngoingCallInFullScreen();
+    }
+
+    @Rpc(description = "Return whether the Active Call toggle is chechked")
+    public boolean isActiveCallEnabled() {
+        return mDialerHelper.get().isActiveCallEnabled();
+    }
+
     @Rpc(description = "Dial a number in call dial pad when call is in progress.")
     public void inCallDialPad(String phoneNumber) {
         mDialerHelper.get().inCallDialPad(phoneNumber);
@@ -235,6 +245,18 @@
         mDialerHelper.get().openContacts();
     }
 
+    /** Press 'Device' prompt which comes up when trying to transfer files to a device. */
+    @Rpc(description = "Press 'Device' on a prompt, if present.")
+    public void pressDevice() {
+        mDialerHelper.get().pressDeviceOnPrompt();
+    }
+
+    /** Press Active Call toggle */
+    @Rpc(description = "Press Active Call toggle")
+    public void pressActiveCallToggle() {
+        mDialerHelper.get().pressActiveCallToggle();
+    }
+
     /** Rpc to press the Mobile call action button on a contact page */
     @Rpc(description = "Press the Mobile call button on a contact page")
     public void pressMobileCallOnContact() {