Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tasks not cleaned up after ActivityScenario.launch #2152

Open
mgroth0 opened this issue Feb 18, 2024 · 6 comments
Open

Tasks not cleaned up after ActivityScenario.launch #2152

mgroth0 opened this issue Feb 18, 2024 · 6 comments

Comments

@mgroth0
Copy link

mgroth0 commented Feb 18, 2024

Description

I am trying for the first time to use ActivityScenario.launch in instrumented tests for a physical device. No matter what I do, I cannot get the tasks to be cleaned up.

Steps to Reproduce

  1. Using Samsung Galaxy. Close all apps first.
  2. Use code below

main

class MainActivity : ComponentActivity()

test

class LaunchAndroidInstrumentedTests {
    @Test
    fun activityStarts() {
        val scenario = ActivityScenario.launch(MainActivity::class.java)
        scenario.close()
    }
}

Expected Results

When the test is done, there are no running apps.

Actual Results

When the test is done, my phone shows 2 running apps.

If I run adb shell dumpsys activity recents, I see this at the bottom of the output

Visible recent tasks (most recent first):
  * RecentTaskInfo #0:
    id=5745 userId=0 hasTask=false lastActiveTime=3723437970
    baseIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=matt.launch.test/androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity }
    realActivity={matt.launch.test/androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity}
    isExcluded=false activityType=standard windowingMode=fullscreen supportsSplitScreenMultiWindow=true supportsMultiWindow=true
    taskDescription { colorBackground=#ff303030 colorPrimary=#ff212121 iconRes=/0 iconBitmap=false resizeMode=RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION minWidth=-1 minHeight=-1 colorBackgroundFloating=#ff424242 }
    lastSnapshotData { taskSize=Point(1080, 2316) contentInsets=Rect(0, 67 - 0, 126) bufferSize=Point(1080, 2316) }
  * RecentTaskInfo #1:
    id=5744 userId=0 hasTask=false lastActiveTime=3723437784
    baseIntent=Intent { flg=0x10008000 cmp=matt.launch/.MainActivity }
    realActivity={matt.launch/matt.launch.MainActivity}
    isExcluded=false activityType=standard windowingMode=fullscreen supportsSplitScreenMultiWindow=true supportsMultiWindow=true
    taskDescription { colorBackground=#fff0f0f3 colorPrimary=#ff191c1e iconRes=/0 iconBitmap=false resizeMode=RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION minWidth=-1 minHeight=-1 colorBackgroundFloating=#fff0f0f3 }
    lastSnapshotData { taskSize=Point(1080, 2316) contentInsets=Rect(0, 67 - 0, 126) bufferSize=Point(1080, 2316) }

To summarize, the EmptyActivity and MainActivity were not properly cleaned up. On my phone, they actually show as two different apps in the recent app list. Both are blank white screens, but one of them says "matt.launch.MainActivity". The other one has no text.

AndroidX Test and Android OS Versions

androidx.test: 1.5.0
android OS: 13

Link to a public git repo demonstrating the problem:

I did not make one because I am hoping there is a quick solution or that it will be easy to reproduce with the code I copied and pasted above. If there is not quick solution and it is not simple to reproduce, I will be happy to make a repo. Please just let me know.

@brettchabot
Copy link
Collaborator

I think this is working as intended. ActivityScenario.close essentially just calls Activity.finish. I'm not super familiar with recent tasks but I believe it will show anything recently launched.

@mgroth0
Copy link
Author

mgroth0 commented Feb 27, 2024

Hey, thanks for the response.

Please let me clarify before you close this. The issue here is that blank white screen apps are being left open on my phone after tests complete "normally". This has to be unexpected behavior.

Also, the docs for finish state:

    /**
     * Call this when your activity is done and should be closed.  The
     * ActivityResult is propagated back to whoever launched you via
     * onActivityResult().
     */
    public void finish() {
        finish(DONT_FINISH_TASK_WITH_ACTIVITY);
    }

Alternatively, there is finishAndRemoveTask:

    /**
     * Call this when your activity is done and should be closed and the task should be completely
     * removed as a part of finishing the root activity of the task.
     */
    public void finishAndRemoveTask() {
        finish(FINISH_TASK_WITH_ROOT_ACTIVITY);
    }

finishAndRemoveTask is what I expect instrument tests to cleanup with.

@brettchabot brettchabot reopened this Feb 27, 2024
@brettchabot
Copy link
Collaborator

Thanks for the pointer. We probably could consider calling finishAndRemoveTask on the EmptyActivity if test is running on API >= 21, but more investigation would be needed on any potential side effects.

I'd be nervous about changing existing behavior and modifying ActivityScenario.close to call finishAndRemoveTask instead of finish. One could easily argue that it is more expected for a recently used Activity to show up in Recent tasks

@mgroth0
Copy link
Author

mgroth0 commented Feb 27, 2024

Thank you for sharing your thoughts.

I can see the valid arguments for ending an ActivityScenario with finish so that the task stays in the task list, especially for that to at least be an option. It is the original behavior, and I think it matches the behavior of a user closing the app by just hitting the home button?

As for finishAndRemoveTask, I think this matches the behavior of the user exiting the app, and then going to the Recent Tasks and removing it. I think this is another normal way for users to close apps. I think the main benefit is that this is the most clean way of disposing of a test completely. If you consider that the device likely did not have the app in the task list before the test started (since tests should start with a device that is as close as possible to a blank slate), then this also means that it diposing the test returns the device to a state most similar to where it was before, and is more prepared to begin another test.

I wonder if selecting the activity dispose strategy could be a part of the ActivityScenario API, to support both methods?

@brettchabot
Copy link
Collaborator

In general our philosophy with ActivityScenario is to try to focus on the most common use cases. There is a concern that too much niche functionality over complicates the API surface and makes it harder to use and maintain.

If calling finishAndRemoveTask is important for your use case could you write your own custom logic on teardown to dispose of the activity?

@mgroth0
Copy link
Author

mgroth0 commented Feb 29, 2024

I can try. Please feel free to close this in the meantime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants