diff --git a/core/res/res/drawable/ic_qs_ui_mode_night.xml b/core/res/res/drawable/ic_qs_ui_mode_night.xml
new file mode 100644
index 0000000000000..72278272e330a
--- /dev/null
+++ b/core/res/res/drawable/ic_qs_ui_mode_night.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fb72da519f53f..a372171e9bd81 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1484,6 +1484,7 @@
+
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 3562a8f814086..a4337cc8ce79c 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -35,6 +35,7 @@
+
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index fcf920064e92d..02d826f5790c3 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -175,6 +175,9 @@
+
+
+
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index a067cd2022479..e02be38d32e95 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -114,7 +114,7 @@
- wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,work,cast,night
+ wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,dark,saver,work,cast,night
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f47d4b5aac6d0..5fdcbcb9ccb23 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -865,6 +865,8 @@
On at %s
Until %s
+
+ Dark Theme
NFC
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 2956ad0600a70..daaee4cd53362 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -41,6 +41,7 @@ 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.RotationLockTile;
+import com.android.systemui.qs.tiles.UiModeNightTile;
import com.android.systemui.qs.tiles.UserTile;
import com.android.systemui.qs.tiles.WifiTile;
import com.android.systemui.qs.tiles.WorkModeTile;
@@ -73,6 +74,7 @@ public class QSFactoryImpl implements QSFactory {
private final Provider mNightDisplayTileProvider;
private final Provider mNfcTileProvider;
private final Provider mMemoryTileProvider;
+ private final Provider mUiModeNightTileProvider;
private QSTileHost mHost;
@@ -94,7 +96,8 @@ public class QSFactoryImpl implements QSFactory {
Provider dataSaverTileProvider,
Provider nightDisplayTileProvider,
Provider nfcTileProvider,
- Provider memoryTileProvider) {
+ Provider memoryTileProvider,
+ Provider uiModeNightTileProvider) {
mWifiTileProvider = wifiTileProvider;
mBluetoothTileProvider = bluetoothTileProvider;
mCellularTileProvider = cellularTileProvider;
@@ -113,6 +116,7 @@ public class QSFactoryImpl implements QSFactory {
mNightDisplayTileProvider = nightDisplayTileProvider;
mNfcTileProvider = nfcTileProvider;
mMemoryTileProvider = memoryTileProvider;
+ mUiModeNightTileProvider = uiModeNightTileProvider;
}
public void setHost(QSTileHost host) {
@@ -164,6 +168,8 @@ public class QSFactoryImpl implements QSFactory {
return mNightDisplayTileProvider.get();
case "nfc":
return mNfcTileProvider.get();
+ case "dark":
+ return mUiModeNightTileProvider.get();
}
// Intent tiles.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
new file mode 100644
index 0000000000000..8d2f8952cc6e5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019 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.app.UiModeManager;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.widget.Switch;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.systemui.R;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+import javax.inject.Inject;
+
+/**
+ * Quick Settings tile for: Night Mode / Dark Theme / Dark Mode.
+ *
+ * The string id of this tile is "dark" because "night" was already
+ * taken by {@link NightDisplayTile}.
+ */
+public class UiModeNightTile extends QSTileImpl implements
+ ConfigurationController.ConfigurationListener {
+
+ private final Icon mIcon = ResourceIcon.get(
+ com.android.internal.R.drawable.ic_qs_ui_mode_night);
+ private UiModeManager mUiModeManager;
+
+ @Inject
+ public UiModeNightTile(QSHost host, ConfigurationController configurationController) {
+ super(host);
+ mUiModeManager = mContext.getSystemService(UiModeManager.class);
+ configurationController.observe(getLifecycle(), this);
+ }
+
+ @Override
+ public void onUiModeChanged() {
+ refreshState();
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleClick() {
+ boolean newState = !mState.value;
+ mUiModeManager.setNightMode(newState ? UiModeManager.MODE_NIGHT_YES
+ : UiModeManager.MODE_NIGHT_NO);
+ refreshState(newState);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ boolean nightMode = (mContext.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
+
+ state.value = nightMode;
+ state.label = mContext.getString(R.string.quick_settings_ui_mode_night_label);
+ state.contentDescription = state.label;
+ state.icon = mIcon;
+ state.expandedAccessibilityClassName = Switch.class.getName();
+ state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.QS_UI_MODE_NIGHT;
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return new Intent(Settings.ACTION_DISPLAY_SETTINGS);
+ }
+
+ @Override
+ protected void handleSetListening(boolean listening) {
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return getState().label;
+ }
+}
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index a88ae9e8b9525..3babb6d943f5b 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7175,6 +7175,13 @@ message MetricsEvent {
// Salt generation for the above hashed direct share target
FIELD_HASHED_TARGET_SALT_GEN = 1705;
+ // OPEN: QS dark theme tile shown
+ // ACTION: QS dark theme tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: Q
+ QS_UI_MODE_NIGHT = 1706;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS