Add a QS tile for Reduce Bright Colors
The flow will be the same as that of our other accessibility feature, Color Inversion. 1) RBC is in the stock list of tiles users can move to the panel 2) (TODO) The first time the feature is turned on, it gets moved to the panel Long-pressing the tile navigates to the RBC subpage, where users can adjust the intensity slider. TODOs: call into CDS for config availability, get a tile icon, update strings, set a callback for adding tile, so the first time the feature is turned on, it gets moved to the panel Test: long-pressing opens the RBC settings page, atest ReduceBrightColorsTileTest Bug: b/128465252 Change-Id: I26959fedf71298830fa5325307f555c8e2bc3901
This commit is contained in:
@@ -114,7 +114,7 @@
|
||||
|
||||
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
|
||||
<string name="quick_settings_tiles_stock" translatable="false">
|
||||
wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse
|
||||
wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness
|
||||
</string>
|
||||
|
||||
<!-- The tiles to display in QuickSettings -->
|
||||
|
||||
@@ -1014,6 +1014,11 @@
|
||||
<string name="quick_settings_dark_mode_secondary_label_on_at">On at <xliff:g id="time" example="10 pm">%s</xliff:g></string>
|
||||
<!-- QuickSettings: Secondary text for when the Dark theme or some other tile will be on until some user-selected time. [CHAR LIMIT=20] -->
|
||||
<string name="quick_settings_dark_mode_secondary_label_until">Until <xliff:g id="time" example="7 am">%s</xliff:g></string>
|
||||
<!-- TODO(b/170970602): remove translatable=false when RBC has official name and strings -->
|
||||
<!-- QuickSettings: Label for the toggle that controls whether Reduce Bright Colors is enabled. [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_reduce_bright_colors_label" translatable="false">Reduce Bright Colors</string>
|
||||
<!-- QuickSettings: Secondary text for intensity level of Reduce Bright Colors. [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_reduce_bright_colors_secondary_label" translatable="false"> <xliff:g id="intensity" example="50">%d</xliff:g>%% reduction</string>
|
||||
|
||||
<!-- QuickSettings: NFC tile [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_settings_nfc_label">NFC</string>
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.android.systemui.qs.tiles.HotspotTile;
|
||||
import com.android.systemui.qs.tiles.LocationTile;
|
||||
import com.android.systemui.qs.tiles.NfcTile;
|
||||
import com.android.systemui.qs.tiles.NightDisplayTile;
|
||||
import com.android.systemui.qs.tiles.ReduceBrightColorsTile;
|
||||
import com.android.systemui.qs.tiles.RotationLockTile;
|
||||
import com.android.systemui.qs.tiles.ScreenRecordTile;
|
||||
import com.android.systemui.qs.tiles.UiModeNightTile;
|
||||
@@ -78,6 +79,7 @@ public class QSFactoryImpl implements QSFactory {
|
||||
private final Provider<GarbageMonitor.MemoryTile> mMemoryTileProvider;
|
||||
private final Provider<UiModeNightTile> mUiModeNightTileProvider;
|
||||
private final Provider<ScreenRecordTile> mScreenRecordTileProvider;
|
||||
private final Provider<ReduceBrightColorsTile> mReduceBrightColorsTileProvider;
|
||||
|
||||
private final Lazy<QSHost> mQsHostLazy;
|
||||
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
|
||||
@@ -105,7 +107,8 @@ public class QSFactoryImpl implements QSFactory {
|
||||
Provider<NfcTile> nfcTileProvider,
|
||||
Provider<GarbageMonitor.MemoryTile> memoryTileProvider,
|
||||
Provider<UiModeNightTile> uiModeNightTileProvider,
|
||||
Provider<ScreenRecordTile> screenRecordTileProvider) {
|
||||
Provider<ScreenRecordTile> screenRecordTileProvider,
|
||||
Provider<ReduceBrightColorsTile> reduceBrightColorsTileProvider) {
|
||||
mQsHostLazy = qsHostLazy;
|
||||
mCustomTileBuilderProvider = customTileBuilderProvider;
|
||||
|
||||
@@ -129,6 +132,7 @@ public class QSFactoryImpl implements QSFactory {
|
||||
mMemoryTileProvider = memoryTileProvider;
|
||||
mUiModeNightTileProvider = uiModeNightTileProvider;
|
||||
mScreenRecordTileProvider = screenRecordTileProvider;
|
||||
mReduceBrightColorsTileProvider = reduceBrightColorsTileProvider;
|
||||
}
|
||||
|
||||
public QSTile createTile(String tileSpec) {
|
||||
@@ -180,6 +184,8 @@ public class QSFactoryImpl implements QSFactory {
|
||||
return mUiModeNightTileProvider.get();
|
||||
case "screenrecord":
|
||||
return mScreenRecordTileProvider.get();
|
||||
case "reduce_brightness":
|
||||
return mReduceBrightColorsTileProvider.get();
|
||||
}
|
||||
|
||||
// Custom tiles
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.plugins.qs.QSTile;
|
||||
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.settings.UserTracker;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** Quick settings tile: Reduce Bright Colors **/
|
||||
public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> {
|
||||
|
||||
//TODO(b/170973645): get icon drawable
|
||||
private final Icon mIcon = null;
|
||||
private final SecureSetting mActivatedSetting;
|
||||
|
||||
@Inject
|
||||
public ReduceBrightColorsTile(
|
||||
QSHost host,
|
||||
@Background Looper backgroundLooper,
|
||||
@Main Handler mainHandler,
|
||||
MetricsLogger metricsLogger,
|
||||
StatusBarStateController statusBarStateController,
|
||||
ActivityStarter activityStarter,
|
||||
QSLogger qsLogger,
|
||||
UserTracker userTracker,
|
||||
SecureSettings secureSettings
|
||||
) {
|
||||
super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
|
||||
activityStarter, qsLogger);
|
||||
|
||||
mActivatedSetting = new SecureSetting(secureSettings, mainHandler,
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, userTracker.getUserId()) {
|
||||
@Override
|
||||
protected void handleValueChanged(int value, boolean observedChange) {
|
||||
refreshState();
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
// TODO(b/170970675): Call into ColorDisplayService to get availability/config status
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleDestroy() {
|
||||
super.handleDestroy();
|
||||
mActivatedSetting.setListening(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BooleanState newTileState() {
|
||||
return new BooleanState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetListening(boolean listening) {
|
||||
super.handleSetListening(listening);
|
||||
mActivatedSetting.setListening(listening);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleUserSwitch(int newUserId) {
|
||||
mActivatedSetting.setUserId(newUserId);
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getLongClickIntent() {
|
||||
return new Intent(Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleClick() {
|
||||
mActivatedSetting.setValue(mState.value ? 0 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTileLabel() {
|
||||
return mContext.getString(R.string.quick_settings_reduce_bright_colors_label);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleUpdateState(BooleanState state, Object arg) {
|
||||
state.value = mActivatedSetting.getValue() == 1;
|
||||
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
|
||||
state.label = mContext.getString(R.string.quick_settings_reduce_bright_colors_label);
|
||||
state.expandedAccessibilityClassName = Switch.class.getName();
|
||||
state.contentDescription = state.label;
|
||||
|
||||
final int intensity = Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0, mActivatedSetting.getCurrentUser());
|
||||
state.secondaryLabel = state.value ? mContext.getString(
|
||||
R.string.quick_settings_reduce_bright_colors_secondary_label, intensity) : "";
|
||||
|
||||
state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
|
||||
? state.label
|
||||
: TextUtils.concat(state.label, ", ", state.secondaryLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ public class AutoTileManager implements UserAwareController {
|
||||
public static final String WORK = "work";
|
||||
public static final String NIGHT = "night";
|
||||
public static final String CAST = "cast";
|
||||
public static final String BRIGHTNESS = "reduce_brightness";
|
||||
static final String SETTING_SEPARATOR = ":";
|
||||
|
||||
private UserHandle mCurrentUser;
|
||||
@@ -124,6 +125,9 @@ public class AutoTileManager implements UserAwareController {
|
||||
mCastController.addCallback(mCastCallback);
|
||||
}
|
||||
|
||||
// TODO(b/170970675): Set a listener/controller and callback for Reduce Bright Colors
|
||||
// state changes. Call into ColorDisplayService to get availability/config status
|
||||
|
||||
int settingsN = mAutoAddSettingList.size();
|
||||
for (int i = 0; i < settingsN; i++) {
|
||||
if (!mAutoTracker.isAdded(mAutoAddSettingList.get(i).mSpec)) {
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 static junit.framework.Assert.assertEquals;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.qs.QSTileHost;
|
||||
import com.android.systemui.qs.logging.QSLogger;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.util.settings.FakeSettings;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
@SmallTest
|
||||
public class ReduceBrightColorsTileTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private QSTileHost mHost;
|
||||
@Mock
|
||||
private MetricsLogger mMetricsLogger;
|
||||
@Mock
|
||||
private StatusBarStateController mStatusBarStateController;
|
||||
@Mock
|
||||
private ActivityStarter mActivityStarter;
|
||||
@Mock
|
||||
private QSLogger mQSLogger;
|
||||
@Mock
|
||||
private UserTracker mUserTracker;
|
||||
|
||||
private FakeSettings mFakeSettings;
|
||||
private TestableLooper mTestableLooper;
|
||||
private ReduceBrightColorsTile mTile;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
|
||||
when(mHost.getContext()).thenReturn(mContext);
|
||||
mFakeSettings = new FakeSettings();
|
||||
|
||||
mTile = new ReduceBrightColorsTile(
|
||||
mHost,
|
||||
mTestableLooper.getLooper(),
|
||||
new Handler(mTestableLooper.getLooper()),
|
||||
mMetricsLogger,
|
||||
mStatusBarStateController,
|
||||
mActivityStarter,
|
||||
mQSLogger,
|
||||
mUserTracker,
|
||||
mFakeSettings
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotActive() {
|
||||
mTile.refreshState();
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
|
||||
assertEquals(mTile.getState().label.toString(),
|
||||
mContext.getString(R.string.quick_settings_reduce_bright_colors_label));
|
||||
assertEquals(mTile.getState().secondaryLabel.toString(), "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActive() {
|
||||
mFakeSettings.putIntForUser(
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
|
||||
1,
|
||||
mUserTracker.getUserId());
|
||||
mTile.refreshState();
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
assertActiveState();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActive_clicked_isActive() {
|
||||
mTile.refreshState();
|
||||
mTestableLooper.processAllMessages();
|
||||
// Validity check
|
||||
assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
|
||||
|
||||
mTile.handleClick();
|
||||
mTile.refreshState();
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
assertActiveState();
|
||||
}
|
||||
|
||||
private void assertActiveState() {
|
||||
assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
|
||||
assertEquals(mTile.getState().label.toString(),
|
||||
mContext.getString(R.string.quick_settings_reduce_bright_colors_label));
|
||||
|
||||
final int intensity = Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0, mUserTracker.getUserId());
|
||||
|
||||
assertEquals(
|
||||
mContext.getString(
|
||||
R.string.quick_settings_reduce_bright_colors_secondary_label, intensity),
|
||||
mTile.getState().secondaryLabel.toString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user