Notification slider update.

Bug: 27558254
Change-Id: I5e03aacf3aafb900f45d227a031a5dbb328ba18f
This commit is contained in:
Julia Reynolds
2016-04-06 20:31:05 -04:00
parent a4c0b1de1a
commit 4d920ff6eb
11 changed files with 379 additions and 102 deletions

View File

@@ -0,0 +1,27 @@
<!--
Copyright (C) 2016 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M11.2,13.6l1.6,0l-0.8,-2.6z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22.5,9.6L15,9l-3,-7L9,9L1.5,9.6l5.7,5L5.5,22l6.5,-3.9l6.5,3.9l-1.7,-7.4L22.5,9.6zM13.6,16l-0.5,-1.4h-2.3L10.4,16H9l2.3,-6.4h1.4L15,16H13.6z"/>
</vector>

View File

@@ -32,7 +32,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="14dp"
android:paddingTop="15dp"
android:paddingEnd="8dp"
android:id="@+id/notification_guts_header"
android:orientation="horizontal"
@@ -99,6 +99,7 @@
android:clickable="false"
android:focusable="false"
android:paddingEnd="8dp"
android:paddingTop="4dp"
android:visibility="gone">
<TextView
android:id="@+id/title"
@@ -123,21 +124,20 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_height="wrap_content"
android:paddingTop="8dp" >
<ImageView
android:id="@+id/low_importance"
android:src="@*android:drawable/ic_notification_block"
android:id="@+id/auto_importance"
android:src="@drawable/notification_auto_importance"
android:layout_gravity="center_vertical|start"
android:layout_width="24dp"
android:layout_height="24dp"
android:tint="@color/notification_guts_icon_tint"/>
android:layout_width="48dp"
android:layout_height="48dp" />
<SeekBar
android:id="@+id/seekbar"
android:layout_marginStart="56dp"
android:layout_marginEnd="56dp"
android:layout_marginEnd="32dp"
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="48dp"
@@ -149,14 +149,6 @@
style="@android:style/Widget.Material.SeekBar.Discrete"
android:tickMarkTint="@android:color/black" />
<ImageView
android:id="@+id/max_importance"
android:src="@*android:drawable/ic_notification_alert"
android:layout_gravity="center_vertical|end"
android:layout_width="24dp"
android:layout_height="24dp"
android:tint="@color/notification_guts_icon_tint" />
</FrameLayout>
</LinearLayout>
<!-- buttons -->

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/switch_bar" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/power_notification_controls_description"/>
</LinearLayout>

View File

@@ -108,6 +108,7 @@
<!-- The "inside" of a notification, reached via longpress -->
<color name="notification_guts_bg_color">#eeeeee</color>
<color name="notification_guts_slider_color">@*android:color/material_deep_teal_500</color>
<color name="notification_guts_disabled_slider_color">@*android:color/material_grey_300</color>
<color name="notification_guts_secondary_slider_color">#858383</color>
<color name="notification_guts_icon_tint">#8a000000</color>
<color name="notification_guts_disabled_icon_tint">#4d000000</color>

View File

@@ -1225,38 +1225,69 @@
<string name="do_not_silence_block">Don\'t silence or block</string>
<!-- [CHAR LIMIT=NONE] Importance Tuner setting title -->
<string name="tuner_full_importance_settings">Show full importance settings</string>
<string name="tuner_full_importance_settings">Power notification controls</string>
<string name="tuner_full_importance_settings_on">On</string>
<string name="tuner_full_importance_settings_off">Off</string>
<string name="power_notification_controls_description">With power notification controls, you can set an importance level from 0 to 5 for an app\'s notifications.
\n\n<b>Level 5</b>
\n- Show at the top of the notification list
\n- Allow full screen interruption
\n- Always peek
\n\n<b>Level 4</b>
\n- Prevent full screen interruption
\n- Always peek
\n\n<b>Level 3</b>
\n- Prevent full screen interruption
\n- Never peek
\n\n<b>Level 2</b>
\n- Prevent full screen interruption
\n- Never peek
\n- Never make sound and vibration
\n\n<b>Level 1</b>
\n- Prevent full screen interruption
\n- Never peek
\n- Never make sound or vibrate
\n- Hide from lock screen and status bar
\n- Show at the bottom of the notification list
\n\n<b>Level 0</b>
\n- Block all notifications from the app
</string>
<!-- Notification importance title, user unspecified status-->
<string name="user_unspecified_importance">Importance: Automatic</string>
<!-- Notification importance title, blocked status-->
<string name="blocked_importance">Blocked</string>
<string name="blocked_importance">Importance: Level 0</string>
<!-- Notification importance title, min status-->
<string name="min_importance">Min importance</string>
<string name="min_importance">Importance: Level 1</string>
<!-- Notification importance title, low status-->
<string name="low_importance">Low importance</string>
<string name="low_importance">Importance: Level 2</string>
<!-- Notification importance title, normal status-->
<string name="default_importance">Normal importance</string>
<string name="default_importance">Importance: Level 3</string>
<!-- Notification importance title, high status-->
<string name="high_importance">High importance</string>
<string name="high_importance">Importance: Level 4</string>
<!-- Notification importance title, max status-->
<string name="max_importance">Urgent importance</string>
<string name="max_importance">Importance: Level 5</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: blocked importance level description -->
<string name="notification_importance_blocked">Never show these notifications</string>
<string name="notification_importance_user_unspecified">App determines importance for each notification.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: blocked importance level description -->
<string name="notification_importance_blocked">Never show notifications from this app.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: min importance level description -->
<string name="notification_importance_min">Silently show at the bottom of the notification list</string>
<string name="notification_importance_min">No full screen interruption, peeking, sound, or vibration. Hide from lock screen and status bar.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: low importance level description -->
<string name="notification_importance_low">Silently show these notifications</string>
<string name="notification_importance_low">No full screen interruption, peeking, sound, or vibration.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: normal importance level description -->
<string name="notification_importance_default">Allow these notification to make sounds</string>
<string name="notification_importance_default">No full screen interruption or peeking.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: high importance level description -->
<string name="notification_importance_high">Peek onto the screen and allow sound and allow sound</string>
<string name="notification_importance_high">Always peek. No full screen interruption.</string>
<!-- [CHAR LIMIT=100] Notification Importance slider: max importance level description -->
<string name="notification_importance_max">Show at the top of the notifications list, peek onto the screen and allow sound</string>
<string name="notification_importance_max">Always peek, and allow full screen interruption.</string>
<!-- Notification: Control panel: Label for button that launches notification settings. [CHAR LIMIT=NONE] -->
<string name="notification_more_settings">More settings</string>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:title="@string/other">
<com.android.systemui.tuner.TunerSwitch
android:key="overview_nav_bar_gesture"
android:title="@string/overview_nav_bar_gesture"
android:summary="@string/overview_nav_bar_gesture_desc" />
<!-- importance -->
<Preference
android:key="power_notification_controls"
android:title="@string/tuner_full_importance_settings"
android:fragment="com.android.systemui.tuner.PowerNotificationControlsFragment"/>
</PreferenceScreen>

View File

@@ -135,21 +135,10 @@
android:fragment="com.android.systemui.tuner.NavBarTuner" />
-->
<PreferenceScreen
android:key="other"
android:title="@string/other" >
<com.android.systemui.tuner.TunerSwitch
android:key="overview_nav_bar_gesture"
android:title="@string/overview_nav_bar_gesture"
android:summary="@string/overview_nav_bar_gesture_desc" />
<!-- importance -->
<com.android.systemui.tuner.TunerSwitch
android:key="show_importance_slider"
android:title="@string/tuner_full_importance_settings" />
</PreferenceScreen>
<Preference
android:key="other"
android:title="@string/other"
android:fragment="com.android.systemui.tuner.OtherPrefs" />
<!-- Warning, this goes last. -->
<Preference

View File

@@ -22,12 +22,14 @@ import android.app.INotificationManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.View;
@@ -60,10 +62,18 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab
private int mActualHeight;
private boolean mExposed;
private INotificationManager mINotificationManager;
private int mStartingImportance;
private int mStartingUserImportance;
private int mNotificationImportance;
private boolean mShowSlider;
private SeekBar mSeekBar;
private ImageView mAutoButton;
private ColorStateList mActiveSliderTint;
private ColorStateList mInactiveSliderTint;
private TextView mImportanceSummary;
private TextView mImportanceTitle;
private boolean mAuto;
private RadioButton mBlock;
private RadioButton mSilent;
private RadioButton mReset;
@@ -145,9 +155,14 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab
void bindImportance(final PackageManager pm, final StatusBarNotification sbn,
final ExpandableNotificationRow row, final int importance) {
mStartingImportance = importance;
mINotificationManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
mStartingUserImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
try {
mStartingUserImportance =
mINotificationManager.getImportance(sbn.getPackageName(), sbn.getUid());
} catch (RemoteException e) {}
mNotificationImportance = importance;
boolean systemApp = false;
try {
final PackageInfo info =
@@ -160,29 +175,25 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab
final View importanceSlider = row.findViewById(R.id.importance_slider);
final View importanceButtons = row.findViewById(R.id.importance_buttons);
if (mShowSlider) {
bindSlider(importanceSlider, sbn, systemApp);
bindSlider(importanceSlider, systemApp);
importanceSlider.setVisibility(View.VISIBLE);
importanceButtons.setVisibility(View.GONE);
} else {
mStartingImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
try {
mStartingImportance =
mINotificationManager.getImportance(sbn.getPackageName(), sbn.getUid());
} catch (RemoteException e) {}
bindToggles(importanceButtons, mStartingImportance, systemApp);
bindToggles(importanceButtons, mStartingUserImportance, systemApp);
importanceButtons.setVisibility(View.VISIBLE);
importanceSlider.setVisibility(View.GONE);
}
}
public boolean hasImportanceChanged() {
return mStartingImportance != getSelectedImportance();
return mStartingUserImportance != getSelectedImportance();
}
void saveImportance(final StatusBarNotification sbn) {
int progress = getSelectedImportance();
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
progress - mStartingImportance);
progress - mStartingUserImportance);
try {
mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(), progress);
} catch (RemoteException e) {
@@ -192,14 +203,18 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab
private int getSelectedImportance() {
if (mSeekBar!= null && mSeekBar.isShown()) {
return mSeekBar.getProgress();
if (mSeekBar.isEnabled()) {
return mSeekBar.getProgress();
} else {
return Ranking.IMPORTANCE_UNSPECIFIED;
}
} else {
if (mBlock.isChecked()) {
return NotificationListenerService.Ranking.IMPORTANCE_NONE;
return Ranking.IMPORTANCE_NONE;
} else if (mSilent.isChecked()) {
return NotificationListenerService.Ranking.IMPORTANCE_LOW;
return Ranking.IMPORTANCE_LOW;
} else {
return NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
return Ranking.IMPORTANCE_UNSPECIFIED;
}
}
}
@@ -229,16 +244,14 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab
}
}
private void bindSlider(final View importanceSlider, final StatusBarNotification sbn,
final boolean systemApp) {
final TextView importanceSummary = ((TextView) importanceSlider.findViewById(R.id.summary));
final TextView importanceTitle = ((TextView) importanceSlider.findViewById(R.id.title));
private void bindSlider(final View importanceSlider, final boolean systemApp) {
mActiveSliderTint = loadColorStateList(R.color.notification_guts_slider_color);
mInactiveSliderTint = loadColorStateList(R.color.notification_guts_disabled_slider_color);
mImportanceSummary = ((TextView) importanceSlider.findViewById(R.id.summary));
mImportanceTitle = ((TextView) importanceSlider.findViewById(R.id.title));
mSeekBar = (SeekBar) importanceSlider.findViewById(R.id.seekbar);
if (systemApp) {
((ImageView) importanceSlider.findViewById(R.id.low_importance)).getDrawable().setTint(
mContext.getColor(R.color.notification_guts_disabled_icon_tint));
}
final int minProgress = systemApp ?
NotificationListenerService.Ranking.IMPORTANCE_MIN
: NotificationListenerService.Ranking.IMPORTANCE_NONE;
@@ -267,42 +280,80 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab
// no-op
}
private void updateTitleAndSummary(int progress) {
switch (progress) {
case NotificationListenerService.Ranking.IMPORTANCE_NONE:
importanceSummary.setText(mContext.getString(
R.string.notification_importance_blocked));
importanceTitle.setText(mContext.getString(R.string.blocked_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_MIN:
importanceSummary.setText(mContext.getString(
R.string.notification_importance_min));
importanceTitle.setText(mContext.getString(R.string.min_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_LOW:
importanceSummary.setText(mContext.getString(
R.string.notification_importance_low));
importanceTitle.setText(mContext.getString(R.string.low_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
importanceSummary.setText(mContext.getString(
R.string.notification_importance_default));
importanceTitle.setText(mContext.getString(R.string.default_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
importanceSummary.setText(mContext.getString(
R.string.notification_importance_high));
importanceTitle.setText(mContext.getString(R.string.high_importance));
break;
case NotificationListenerService.Ranking.IMPORTANCE_MAX:
importanceSummary.setText(mContext.getString(
R.string.notification_importance_max));
importanceTitle.setText(mContext.getString(R.string.max_importance));
break;
}
});
mSeekBar.setProgress(mNotificationImportance);
mAutoButton = (ImageView) importanceSlider.findViewById(R.id.auto_importance);
mAutoButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mAuto = !mAuto;
applyAuto();
}
});
mSeekBar.setProgress(mStartingImportance);
mAuto = mStartingUserImportance == Ranking.IMPORTANCE_UNSPECIFIED;
applyAuto();
}
private void applyAuto() {
mSeekBar.setEnabled(!mAuto);
final ColorStateList tint = mAuto ? mInactiveSliderTint : mActiveSliderTint;
Drawable icon = mAutoButton.getDrawable().mutate();
icon.setTintList(tint);
mAutoButton.setImageDrawable(icon);
mSeekBar.setProgressTintList(tint);
mSeekBar.setThumbTintList(tint);
if (mAuto) {
mSeekBar.setProgress(mNotificationImportance);
mImportanceSummary.setText(mContext.getString(
R.string.notification_importance_user_unspecified));
mImportanceTitle.setText(mContext.getString(
R.string.user_unspecified_importance));
} else {
updateTitleAndSummary(mSeekBar.getProgress());
}
}
private void updateTitleAndSummary(int progress) {
switch (progress) {
case Ranking.IMPORTANCE_NONE:
mImportanceSummary.setText(mContext.getString(
R.string.notification_importance_blocked));
mImportanceTitle.setText(mContext.getString(R.string.blocked_importance));
break;
case Ranking.IMPORTANCE_MIN:
mImportanceSummary.setText(mContext.getString(
R.string.notification_importance_min));
mImportanceTitle.setText(mContext.getString(R.string.min_importance));
break;
case Ranking.IMPORTANCE_LOW:
mImportanceSummary.setText(mContext.getString(
R.string.notification_importance_low));
mImportanceTitle.setText(mContext.getString(R.string.low_importance));
break;
case Ranking.IMPORTANCE_DEFAULT:
mImportanceSummary.setText(mContext.getString(
R.string.notification_importance_default));
mImportanceTitle.setText(mContext.getString(R.string.default_importance));
break;
case Ranking.IMPORTANCE_HIGH:
mImportanceSummary.setText(mContext.getString(
R.string.notification_importance_high));
mImportanceTitle.setText(mContext.getString(R.string.high_importance));
break;
case Ranking.IMPORTANCE_MAX:
mImportanceSummary.setText(mContext.getString(
R.string.notification_importance_max));
mImportanceTitle.setText(mContext.getString(R.string.max_importance));
break;
}
}
private ColorStateList loadColorStateList(int colorResId) {
return ColorStateList.valueOf(mContext.getColor(colorResId));
}
public void closeControls(int x, int y, boolean notify) {
@@ -353,7 +404,6 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab
@Override
public boolean hasOverlappingRendering() {
// Prevents this view from creating a layer when alpha is animating.
return false;
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2016 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.tuner;
import android.os.Bundle;
import android.support.v14.preference.PreferenceFragment;
import com.android.systemui.R;
public class OtherPrefs extends PreferenceFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.other_settings);
}
}

View File

@@ -0,0 +1,93 @@
/**
* Copyright (c) 2016, 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.tuner;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
import android.annotation.Nullable;
import android.app.Fragment;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Switch;
import android.widget.TextView;
public class PowerNotificationControlsFragment extends Fragment {
private static final String KEY_SHOW_PNC = "show_importance_slider";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.power_notification_controls_settings, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final View switchBar = view.findViewById(R.id.switch_bar);
final Switch switchWidget = (Switch) switchBar.findViewById(android.R.id.switch_widget);
final TextView switchText = (TextView) switchBar.findViewById(R.id.switch_text);
switchWidget.setChecked(isEnabled());
switchText.setText(isEnabled()
? getString(R.string.switch_bar_on)
: getString(R.string.switch_bar_off));
switchWidget.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean newState = !isEnabled();
MetricsLogger.action(getContext(),
MetricsEvent.ACTION_TUNER_POWER_NOTIFICATION_CONTROLS, newState);
Settings.Secure.putInt(getContext().getContentResolver(),
KEY_SHOW_PNC, newState ? 1 : 0);
switchWidget.setChecked(newState);
switchText.setText(newState
? getString(R.string.switch_bar_on)
: getString(R.string.switch_bar_off));
}
});
}
@Override
public void onResume() {
super.onResume();
MetricsLogger.visibility(
getContext(), MetricsEvent.TUNER_POWER_NOTIFICATION_CONTROLS, true);
}
@Override
public void onPause() {
super.onPause();
MetricsLogger.visibility(
getContext(), MetricsEvent.TUNER_POWER_NOTIFICATION_CONTROLS, false);
}
private boolean isEnabled() {
int setting = Settings.Secure.getInt(getContext().getContentResolver(), KEY_SHOW_PNC, 0);
return setting == 1;
}
}

View File

@@ -2152,6 +2152,12 @@ message MetricsEvent {
// User tried to dock an unresizable app.
ACTION_WINDOW_DOCK_UNRESIZABLE = 391;
// System UI Tuner > Other > Power notification controls
TUNER_POWER_NOTIFICATION_CONTROLS = 392;
// System UI Tuner > Other > Power notification controls > Toggle on/off
ACTION_TUNER_POWER_NOTIFICATION_CONTROLS = 393;
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}