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

Commit cecc46da authored by Jiaming Cheng's avatar Jiaming Cheng
Browse files

Fix crash in BrightnessDialog

I couldn't reproduce this brash with the TOT build, but
based on the stack trace attached in the bug, I think
this cl would fix it.

Root cause:
The original code added an OnAttachStateChangeListener to the
window's DecorView to initialize Compose. This caused an
`IllegalStateException` because the DecorView already had a
LifecycleOwner from the Activity. And this Activity is the
`android.app.Activity`, which is extened by the BrightnessDialog,
it did not correctly provide the LifecycleOwner and
SavedStateRegistryOwner required by Jetpack Compose.

In this change:
  - The problematic OnAttachStateChangeListener is removed.
  - Instead of Activity, let BrightnessDialog to extend
`androidx.activity.ComponentActivity`, which provides the
necessary LifecycleOwner and SavedStateRegistryOwner
implementations out of the box.
  - The corresponding unit test was updated to invoke onResume
on the main UI thread via runOnUiThread. This is necessary
because lifecycle methods must be called on the main thread,
a requirement enforced by ComponentActivity.

Bug: 417544544
Flag: com.android.systemui.qs_ui_refactor_compose_fragment
Test: Manually.
Change-Id: Ia3bf5b0a9b84f46db0665049b852d8d6aeebf39e
parent 99b63f9f
Loading
Loading
Loading
Loading
+10 −19
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static android.view.WindowManagerPolicyConstants.EXTRA_FROM_BRIGHTNESS_KE

import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;

import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.Rect;
@@ -41,14 +40,13 @@ import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.activity.ComponentActivity;
import androidx.compose.ui.platform.ComposeView;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel;
import com.android.systemui.compose.ComposeInitializer;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.flags.QsInCompose;
import com.android.systemui.res.R;
@@ -60,8 +58,15 @@ import java.util.List;

import javax.inject.Inject;

/** A dialog that provides controls for adjusting the screen brightness. */
public class BrightnessDialog extends Activity {
/**
 * A dialog that provides controls for adjusting the screen brightness.
 *
 * This class extends `ComponentActivity` instead of the base `android.app.Activity` to support
 * hosting Jetpack Compose content. `ComponentActivity` provides the necessary
 * `LifecycleOwner`and `SavedStateRegistryOwner` that Compose requires to function correctly,
 * preventing crashes and simplifying lifecycle management. See b/417544544.
 */
public class BrightnessDialog extends ComponentActivity {

    @VisibleForTesting
    static final int DIALOG_TIMEOUT_MILLIS = 3000;
@@ -142,20 +147,6 @@ public class BrightnessDialog extends Activity {
        window.getDecorView();
        window.setLayout(WRAP_CONTENT, WRAP_CONTENT);
        getTheme().applyStyle(R.style.Theme_SystemUI_QuickSettings, false);
        if (QsInCompose.isEnabled()) {
            window.getDecorView().addOnAttachStateChangeListener(
                    new View.OnAttachStateChangeListener() {
                        @Override
                        public void onViewAttachedToWindow(@NonNull View v) {
                            ComposeInitializer.INSTANCE.onAttachedToWindow(v);
                        }

                        @Override
                        public void onViewDetachedFromWindow(@NonNull View v) {
                            ComposeInitializer.INSTANCE.onDetachedFromWindow(v);
                        }
                    });
        }
    }

    void setBrightnessDialogViewAttributes(View container) {
+1 −1
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@ class BrightnessDialogTest(val flags: FlagsParameterization) : SysuiTestCase() {

        clock.advanceTime(BrightnessDialog.DIALOG_TIMEOUT_MILLIS.toLong() / 2)
        // Restart the timeout
        activityRule.activity.onResume()
        activityRule.runOnUiThread { activityRule.activity.onResume() }

        clock.advanceTime(BrightnessDialog.DIALOG_TIMEOUT_MILLIS.toLong() / 2)
        // The dialog should not have disappeared yet