@@ -370,6 +370,12 @@ impl<'a> Device<'a> {
370370 Ok ( ( ) )
371371 }
372372
373+ /**
374+ * This is the legacy function that doesn't support applicationIdSuffix, which
375+ * is required for running different build variants (such as debug and release).
376+ *
377+ * It is kept for backwards compatibility.
378+ */
373379 #[ allow( clippy:: too_many_arguments) ]
374380 pub fn run (
375381 & self ,
@@ -381,6 +387,32 @@ impl<'a> Device<'a> {
381387 build_app_bundle : bool ,
382388 reinstall_deps : bool ,
383389 activity : String ,
390+ ) -> Result < duct:: Handle , RunError > {
391+ return self . run_with_application_id_suffix (
392+ config,
393+ env,
394+ noise_level,
395+ profile,
396+ filter_level,
397+ build_app_bundle,
398+ reinstall_deps,
399+ activity,
400+ None
401+ ) ;
402+ }
403+
404+ #[ allow( clippy:: too_many_arguments) ]
405+ pub fn run_with_application_id_suffix (
406+ & self ,
407+ config : & Config ,
408+ env : & Env ,
409+ noise_level : NoiseLevel ,
410+ profile : Profile ,
411+ filter_level : Option < FilterLevel > ,
412+ build_app_bundle : bool ,
413+ reinstall_deps : bool ,
414+ activity : String ,
415+ application_id_suffix : Option < String > ,
384416 ) -> Result < duct:: Handle , RunError > {
385417 if build_app_bundle {
386418 bundletool:: install ( reinstall_deps) . map_err ( RunError :: BundletoolInstallFailed ) ?;
@@ -402,7 +434,8 @@ impl<'a> Device<'a> {
402434 self . install_apk ( config, env, profile)
403435 . map_err ( RunError :: ApkInstallFailed ) ?;
404436 }
405- let activity = format ! ( "{}/{}" , config. app( ) . identifier( ) , activity) ;
437+
438+ let activity = Device :: resolve_activity_name ( config. app ( ) . identifier ( ) . to_string ( ) , application_id_suffix, activity) ;
406439 let activity_ = activity. clone ( ) ;
407440 let cmd = self
408441 . adb ( env)
@@ -518,4 +551,44 @@ impl<'a> Device<'a> {
518551 }
519552 Ok ( ( ) )
520553 }
554+
555+ /**
556+ * The activity name is the fully qualified class name of the activity to launch.
557+ * Here are the expected formats for the activity name: of the release and debug variants
558+ *
559+ * Release variants have 2 acceptable formats:
560+ * * `com.example.app/.MainActivity`
561+ * * `com.example.app/com.example.app.MainActivity`
562+ *
563+ * Debug variants have 1 acceptable format:
564+ * * `com.example.app.debug/com.example.app.MainActivity`
565+ */
566+ fn resolve_activity_name (
567+ app_identifier : String ,
568+ application_id_suffix : Option < String > ,
569+ activity : String ,
570+ ) -> String {
571+ let identifier: String = match application_id_suffix {
572+ Some ( suffix) => format ! ( "{}{}" , app_identifier, suffix) ,
573+ None => app_identifier,
574+ } ;
575+
576+ return format ! ( "{}/{}" , identifier, activity) ;
577+ }
521578}
579+
580+ #[ cfg( test) ]
581+ mod test {
582+ use rstest:: rstest;
583+ use super :: * ;
584+ #[ rstest(
585+ app_identifier, application_id_suffix, activity, expected,
586+ case( "com.example.app" , Some ( ".debug" ) , "com.example.app.MainActivity" , "com.example.app.debug/com.example.app.MainActivity" ) ,
587+ case( "com.example.app" , None , ".MainActivity" , "com.example.app/.MainActivity" ) ,
588+ case( "com.example.app" , None , "com.example.app.MainActivity" , "com.example.app/com.example.app.MainActivity" ) ,
589+ ) ]
590+ fn test_resolve_activity_name ( app_identifier : String , application_id_suffix : Option < & str > , activity : String , expected : String ) {
591+ let activity = Device :: resolve_activity_name ( app_identifier, application_id_suffix. map ( |s| s. to_string ( ) ) , activity) ;
592+ assert_eq ! ( activity, expected) ;
593+ }
594+ }
0 commit comments