Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de39757a authored by Austin Tankiang's avatar Austin Tankiang
Browse files

Allow the popup to gracefully handle activity destruction

Currently, on activity destruction, sometimes the popup would still be
alive (e.g. on configuration change). So, in that case, on activity
destruction, save the popup state and manually dismiss it. Then on next
init, restore the state.

Bug: 407675188
Test: atest 'DocumentsUIGoogleTests:com.android.documentsui.JobPanelUiTest'
Flag: com.android.documentsui.flags.visual_signals_ro
Change-Id: I3f6af9fa35bfd980b87cb76515ad668a38f86f34
parent 7c8ae62c
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
@@ -78,7 +80,8 @@ private class VerticalMarginItemDecoration(
class JobPanelController(
    private val activityContext: Context,
    private val viewModel: JobPanelViewModel,
) : BroadcastReceiver() {
) : BroadcastReceiver(),
    DefaultLifecycleObserver {
    companion object {
        private const val TAG = "JobPanelController"
        private const val MAX_PROGRESS = 100
@@ -324,6 +327,10 @@ class JobPanelController(
                ))
                itemAnimator = null
                adapter = listAdapter
                if (viewModel.listState != null) {
                    layoutManager?.onRestoreInstanceState(viewModel.listState)
                    viewModel.listState = null
                }
            }
            progressListAdapter = listAdapter
            val popupWidth =
@@ -338,7 +345,10 @@ class JobPanelController(
                /* height= */ ViewGroup.LayoutParams.WRAP_CONTENT,
                /* focusable= */ true
            ).apply {
                setOnDismissListener { progressListAdapter = null }
                setOnDismissListener {
                    progressListAdapter = null
                    popup = null
                }
                showAsDropDown(
                    /* anchor= */ view,
                    /* xoff= */ 0,
@@ -347,11 +357,24 @@ class JobPanelController(
                )
            }
        }
        // Restore the popup if we had saved state.
        if (viewModel.listState != null) {
            progressIcon.callOnClick()
        }
        menuItem = newMenuItem
        // Don't animate for the initial state update.
        updateMenuItem(viewModel.getMenuState(), animate = false)
    }

    override fun onDestroy(owner: LifecycleOwner) {
        // We need to save the popup's UI state and manually dismiss the popup, as it somehow
        // stays alive even if the activity is destroyed due to a configuration change.
        viewModel.listState = popup?.contentView
            ?.findViewById<RecyclerView>(R.id.job_progress_list)?.layoutManager
            ?.onSaveInstanceState()
        popup?.dismiss()
    }

    override fun onReceive(context: Context?, intent: Intent) {
        val progresses = intent.getParcelableArrayListExtra(
            FileOperationService.EXTRA_PROGRESS,
+2 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.documentsui

import android.os.Parcelable
import android.util.Log
import androidx.lifecycle.ViewModel
import com.android.documentsui.base.SharedMinimal.DEBUG
@@ -49,6 +50,7 @@ class JobPanelViewModel : ViewModel() {
    /** List of jobs currently tracked. */
    private val _currentJobs = LinkedHashMap<String, ProgressViewModel>()
    val currentJobs: Map<String, ProgressViewModel> get() = _currentJobs
    var listState: Parcelable? = null

    /**
     * Gets the state of the toolbar progress icon based off the current jobs tracked.
+4 −2
Original line number Diff line number Diff line
@@ -148,8 +148,10 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler
                mInjector.getModel()::getItemUri,
                mInjector.getModel()::getItemCount);
        if (isVisualSignalsFlagEnabled()) {
            menuManager.setJobPanelController(new JobPanelController(this,
                    new ViewModelProvider(this).get(JobPanelViewModel.class)));
            JobPanelController jobPanelController = new JobPanelController(this,
                    new ViewModelProvider(this).get(JobPanelViewModel.class));
            getLifecycle().addObserver(jobPanelController);
            menuManager.setJobPanelController(jobPanelController);
        }
        mInjector.menuManager = menuManager;