Exclusively use qualified activities to launch apps

Do not use the `monkey` to launch apps anymore, the tool became too
verbose on Android 9 without a quiet flag.  Instead the apps are now
launched through their qualified activities, always.

Also cater for the Activity Manager verbosely warning us about
apps being already active and only brought to the foreground.

Issue: INFRA-169
Change-Id: I62b311a9163e8a8e7cda509df7961d3da8ca6c1b
diff --git a/deploy.py b/deploy.py
index c1f130a..bfb6ea3 100755
--- a/deploy.py
+++ b/deploy.py
@@ -314,60 +314,33 @@
         self.adb(*command)
 
     @contextlib.contextmanager
-    def launch(self, package_or_activity: str):
+    def launch(self, activity: str):
         """Launch an app and eventually goes back to the home screen.
 
-        There are two ways to start an application:
-
-        1. Start the main activity (advertised in the launcher), only
-           the package name is needed (e.g. `com.android.settings`);
-        2. Start a specific activity, the qualified activity name is
-           needed (e.g. `com.android.settings/.Settings`).
-
         Example:
 
         >>> device = DeviceUnderTest(...)
-        >>> with device.launch("com.android.settings"):
+        >>> with device.launch("com.android.settings/.Settings"):
         ...     device.ui(text="Bluetooth").exists
         True
         >>> device.ui(text="Bluetooth").exists
         False
 
-        :param package_or_activity: The package name or the qualified
-            activity name.
+        :param activity: The qualified activity name.
         :raise DeviceCommandError: If the app manager command failed.
-        :raise InvalidIntentError: If the package or activity could not
-            be resolved.
+        :raise InvalidIntentError: If the activity could not be
+            resolved.
         """
-        if "/" in package_or_activity:
-            [package, activity] = package_or_activity.split("/", maxsplit=1)
-        else:
-            package, activity = package_or_activity, ""
-
-        if activity:
-            command = [
-                "shell",
-                "am",
-                "start",
-                "-a",
-                "android.intent.action.MAIN",
-                package_or_activity,
-            ]
-        else:
-            # Use the monkey to avoid specifying the exact activity name.
-            command = [
-                "shell",
-                "monkey",
-                "-p",
-                package,
-                "-c",
-                "android.intent.category.LAUNCHER",
-                "1",
-            ]
+        command = ["shell", "am", "start", "-a", "android.intent.action.MAIN", activity]
 
         try:
             process = self.adb(*command)
-            if process.stderr:
+            # Ignore warnings as they should not impede the app launch.  For instance,
+            # Android is verbose about apps not started *again*, because they are e.g.
+            # already active in the background or in the foreground, and that's fine.
+            if process.stderr and not process.stderr.startswith(
+                "Warning: Activity not started"
+            ):
                 raise InvalidIntentError(self.serial, " ".join(command), process.stderr)
             yield
         finally:
@@ -502,7 +475,7 @@
             _LOG.info("Install %s", app)
             device.install(self.prebuilts_path / app.apk)
 
-        with device.launch("com.lunarlabs.panda"):
+        with device.launch("com.lunarlabs.panda/.ggb.Activity.MainActivity"):
             _LOG.info("Initiate first run of viSer")
 
             # Input the credentials
@@ -544,7 +517,7 @@
         )
         device.push(self.settings_file, self.target_settings_file)
 
-        with device.launch("com.lunarlabs.panda"):
+        with device.launch("com.lunarlabs.panda/.ggb.Activity.MainActivity"):
             device.ui(description="Open navigation drawer").click()
             device.ui(
                 text="Settings", className="android.widget.CheckedTextView"