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

Commit a04e56ce authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Show chevron on DndTile if it'd show dialog

Also, have SecureSetting return cached value while it's listening.

Test: manual
Test: atest SystemUITests
Fixes: 206255187
Change-Id: I28f2621a952b31dddc683ebb789c1702797dcf78
parent 64c7c715
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -54,19 +54,23 @@ public abstract class SecureSetting extends ContentObserver implements Listenabl
    }

    public int getValue() {
        return mSecureSettings.getIntForUser(mSettingName, mDefaultValue, mUserId);
        return mListening ? mObservedValue : getValueFromProvider();
    }

    public void setValue(int value) {
        mSecureSettings.putIntForUser(mSettingName, value, mUserId);
    }

    private int getValueFromProvider() {
        return mSecureSettings.getIntForUser(mSettingName, mDefaultValue, mUserId);
    }

    @Override
    public void setListening(boolean listening) {
        if (listening == mListening) return;
        mListening = listening;
        if (listening) {
            mObservedValue = getValue();
            mObservedValue = getValueFromProvider();
            mSecureSettings.registerContentObserverForUser(
                    mSecureSettings.getUriFor(mSettingName), false, this, mUserId);
        } else {
@@ -77,9 +81,10 @@ public abstract class SecureSetting extends ContentObserver implements Listenabl

    @Override
    public void onChange(boolean selfChange) {
        final int value = getValue();
        handleValueChanged(value, value != mObservedValue);
        final int value = getValueFromProvider();
        final boolean changed = value != mObservedValue;
        mObservedValue = value;
        handleValueChanged(value, changed);
    }

    public void setUserId(int userId) {
+31 −5
Original line number Diff line number Diff line
@@ -61,10 +61,12 @@ import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.SecureSetting;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.volume.ZenModePanel;

import javax.inject.Inject;
@@ -81,6 +83,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
    private final ZenModeController mController;
    private final DndDetailAdapter mDetailAdapter;
    private final SharedPreferences mSharedPreferences;
    private final SecureSetting mSettingZenDuration;

    private boolean mListening;
    private boolean mShowingDetail;
@@ -96,7 +99,8 @@ public class DndTile extends QSTileImpl<BooleanState> {
            ActivityStarter activityStarter,
            QSLogger qsLogger,
            ZenModeController zenModeController,
            @Main SharedPreferences sharedPreferences
            @Main SharedPreferences sharedPreferences,
            SecureSettings secureSettings
    ) {
        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                statusBarStateController, activityStarter, qsLogger);
@@ -104,8 +108,17 @@ public class DndTile extends QSTileImpl<BooleanState> {
        mSharedPreferences = sharedPreferences;
        mDetailAdapter = new DndDetailAdapter();
        mController.observe(getLifecycle(), mZenCallback);
        mSettingZenDuration = new SecureSetting(secureSettings, mUiHandler,
                Settings.Secure.ZEN_DURATION, getHost().getUserId()) {
            @Override
            protected void handleValueChanged(int value, boolean observedChange) {
                refreshState();
            }
        };
    }



    public static void setVisible(Context context, boolean visible) {
        Prefs.putBoolean(context, Prefs.Key.DND_TILE_VISIBLE, visible);
    }
@@ -144,14 +157,18 @@ public class DndTile extends QSTileImpl<BooleanState> {
        if (mState.value) {
            mController.setZen(ZEN_MODE_OFF, null, TAG);
        } else {
            showDetail(true);
            enableZenMode(view);
        }
    }

    @Override
    public void showDetail(boolean show) {
        int zenDuration = Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.ZEN_DURATION, 0);
    protected void handleUserSwitch(int newUserId) {
        super.handleUserSwitch(newUserId);
        mSettingZenDuration.setUserId(newUserId);
    }

    private void enableZenMode(@Nullable View view) {
        int zenDuration = mSettingZenDuration.getValue();
        boolean showOnboarding = Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0) != 0
                && Settings.Secure.getInt(mContext.getContentResolver(),
@@ -270,6 +287,8 @@ public class DndTile extends QSTileImpl<BooleanState> {
        state.dualLabelContentDescription = mContext.getResources().getString(
                R.string.accessibility_quick_settings_open_settings, getTileLabel());
        state.expandedAccessibilityClassName = Switch.class.getName();
        state.forceExpandIcon =
                mSettingZenDuration.getValue() == Settings.Secure.ZEN_DURATION_PROMPT;
    }

    @Override
@@ -296,6 +315,13 @@ public class DndTile extends QSTileImpl<BooleanState> {
        } else {
            Prefs.unregisterListener(mContext, mPrefListener);
        }
        mSettingZenDuration.setListening(listening);
    }

    @Override
    protected void handleDestroy() {
        super.handleDestroy();
        mSettingZenDuration.setListening(false);
    }

    @Override
+150 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.qs.tiles

import android.content.ContextWrapper
import android.content.SharedPreferences
import android.os.Handler
import android.provider.Settings
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.statusbar.policy.ZenModeController
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.settings.SecureSettings
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import java.io.File

@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class DndTileTest : SysuiTestCase() {

    companion object {
        private const val DEFAULT_USER = 0
        private const val KEY = Settings.Secure.ZEN_DURATION
    }

    @Mock
    private lateinit var qsHost: QSHost
    @Mock
    private lateinit var metricsLogger: MetricsLogger
    @Mock
    private lateinit var statusBarStateController: StatusBarStateController
    @Mock
    private lateinit var activityStarter: ActivityStarter
    @Mock
    private lateinit var qsLogger: QSLogger
    @Mock
    private lateinit var uiEventLogger: UiEventLogger
    @Mock
    private lateinit var zenModeController: ZenModeController
    @Mock
    private lateinit var sharedPreferences: SharedPreferences

    private lateinit var secureSettings: SecureSettings
    private lateinit var testableLooper: TestableLooper
    private lateinit var tile: DndTile

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        testableLooper = TestableLooper.get(this)
        secureSettings = FakeSettings()

        Mockito.`when`(qsHost.userId).thenReturn(DEFAULT_USER)
        Mockito.`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)

        val wrappedContext = object : ContextWrapper(context) {
            override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
                return sharedPreferences
            }
        }
        Mockito.`when`(qsHost.context).thenReturn(wrappedContext)

        tile = DndTile(
            qsHost,
            testableLooper.looper,
            Handler(testableLooper.looper),
            FalsingManagerFake(),
            metricsLogger,
            statusBarStateController,
            activityStarter,
            qsLogger,
            zenModeController,
            sharedPreferences,
            secureSettings
        )
    }

    @After
    fun tearDown() {
        tile.handleSetListening(false)
    }

    @Test
    fun testForceExpandIcon_durationAskAlways_true() {
        secureSettings.putIntForUser(KEY, Settings.Secure.ZEN_DURATION_PROMPT, DEFAULT_USER)

        tile.refreshState()
        testableLooper.processAllMessages()

        assertThat(tile.state.forceExpandIcon).isTrue()
    }

    @Test
    fun testForceExpandIcon_durationNotAskAlways_false() {
        secureSettings.putIntForUser(KEY, 60, DEFAULT_USER)

        tile.refreshState()
        testableLooper.processAllMessages()

        assertThat(tile.state.forceExpandIcon).isFalse()
    }

    @Test
    fun testForceExpandIcon_changeWhileListening() {
        secureSettings.putIntForUser(KEY, 60, DEFAULT_USER)

        tile.refreshState()
        testableLooper.processAllMessages()

        assertThat(tile.state.forceExpandIcon).isFalse()

        tile.handleSetListening(true)

        secureSettings.putIntForUser(KEY, Settings.Secure.ZEN_DURATION_PROMPT, DEFAULT_USER)
        testableLooper.processAllMessages()

        assertThat(tile.state.forceExpandIcon).isTrue()
    }
}
 No newline at end of file