blob: 1c16bdc0d7bb9452252f2d9e6560f8947cd1b02c [file] [log] [blame]
Selim Cinek024ca592014-09-01 15:11:28 +02001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar;
18
Julia Reynoldsa07af882015-12-17 08:32:48 -050019import android.app.INotificationManager;
Selim Cinek024ca592014-09-01 15:11:28 +020020import android.content.Context;
Julia Reynolds21c30542016-01-15 15:00:02 -050021import android.content.pm.PackageInfo;
22import android.content.pm.PackageManager;
Selim Cinek024ca592014-09-01 15:11:28 +020023import android.graphics.Canvas;
24import android.graphics.drawable.Drawable;
Julia Reynoldsa07af882015-12-17 08:32:48 -050025import android.os.RemoteException;
26import android.os.ServiceManager;
27import android.service.notification.NotificationListenerService;
28import android.service.notification.StatusBarNotification;
Selim Cinek024ca592014-09-01 15:11:28 +020029import android.util.AttributeSet;
Julia Reynoldsa07af882015-12-17 08:32:48 -050030import android.view.View;
Julia Reynolds7727ad22016-01-22 14:38:46 -050031import android.widget.ImageView;
Julia Reynoldsead00aa2015-12-07 08:23:48 -050032import android.widget.LinearLayout;
Julia Reynoldsa07af882015-12-17 08:32:48 -050033import android.widget.RadioButton;
34import android.widget.SeekBar;
35import android.widget.TextView;
Julia Reynoldsead00aa2015-12-07 08:23:48 -050036
Julia Reynoldsb1a235f2016-02-09 12:57:02 -050037import com.android.internal.logging.MetricsLogger;
38import com.android.internal.logging.MetricsProto.MetricsEvent;
Julia Reynolds21c30542016-01-15 15:00:02 -050039import com.android.settingslib.Utils;
Selim Cinek024ca592014-09-01 15:11:28 +020040import com.android.systemui.R;
Julia Reynolds40779452016-02-23 13:43:32 -050041import com.android.systemui.tuner.TunerService;
Selim Cinek024ca592014-09-01 15:11:28 +020042
43/**
44 * The guts of a notification revealed when performing a long press.
45 */
Julia Reynolds40779452016-02-23 13:43:32 -050046public class NotificationGuts extends LinearLayout implements TunerService.Tunable {
47 public static final String SHOW_SLIDER = "show_importance_slider";
Selim Cinek024ca592014-09-01 15:11:28 +020048
49 private Drawable mBackground;
50 private int mClipTopAmount;
51 private int mActualHeight;
Selim Cinekd84a5932015-12-15 11:45:36 -080052 private boolean mExposed;
Julia Reynolds0714f622016-01-07 13:24:09 -050053 private INotificationManager mINotificationManager;
Julia Reynoldsb1a235f2016-02-09 12:57:02 -050054 private int mStartingImportance;
Julia Reynolds40779452016-02-23 13:43:32 -050055 private boolean mShowSlider;
56
57 private SeekBar mSeekBar;
58 private RadioButton mBlock;
59 private RadioButton mSilent;
60 private RadioButton mReset;
Selim Cinek024ca592014-09-01 15:11:28 +020061
62 public NotificationGuts(Context context, AttributeSet attrs) {
63 super(context, attrs);
64 setWillNotDraw(false);
Julia Reynolds40779452016-02-23 13:43:32 -050065 TunerService.get(mContext).addTunable(this, SHOW_SLIDER);
Selim Cinek024ca592014-09-01 15:11:28 +020066 }
67
68 @Override
69 protected void onDraw(Canvas canvas) {
70 draw(canvas, mBackground);
71 }
72
73 private void draw(Canvas canvas, Drawable drawable) {
74 if (drawable != null) {
75 drawable.setBounds(0, mClipTopAmount, getWidth(), mActualHeight);
76 drawable.draw(canvas);
77 }
78 }
79
80 @Override
81 protected void onFinishInflate() {
82 super.onFinishInflate();
83 mBackground = mContext.getDrawable(R.drawable.notification_guts_bg);
84 if (mBackground != null) {
85 mBackground.setCallback(this);
86 }
87 }
88
89 @Override
90 protected boolean verifyDrawable(Drawable who) {
91 return super.verifyDrawable(who) || who == mBackground;
92 }
93
94 @Override
95 protected void drawableStateChanged() {
96 drawableStateChanged(mBackground);
97 }
98
99 private void drawableStateChanged(Drawable d) {
100 if (d != null && d.isStateful()) {
101 d.setState(getDrawableState());
102 }
103 }
104
105 @Override
106 public void drawableHotspotChanged(float x, float y) {
107 if (mBackground != null) {
108 mBackground.setHotspot(x, y);
109 }
110 }
111
Julia Reynolds40779452016-02-23 13:43:32 -0500112 void bindImportance(final PackageManager pm, final StatusBarNotification sbn,
113 final ExpandableNotificationRow row, final int importance) {
Julia Reynoldsb1a235f2016-02-09 12:57:02 -0500114 mStartingImportance = importance;
Julia Reynolds0714f622016-01-07 13:24:09 -0500115 mINotificationManager = INotificationManager.Stub.asInterface(
Julia Reynoldsa07af882015-12-17 08:32:48 -0500116 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
Julia Reynolds21c30542016-01-15 15:00:02 -0500117 boolean systemApp = false;
118 try {
Julia Reynolds21c30542016-01-15 15:00:02 -0500119 final PackageInfo info =
120 pm.getPackageInfo(sbn.getPackageName(), PackageManager.GET_SIGNATURES);
121 systemApp = Utils.isSystemPackage(pm, info);
122 } catch (PackageManager.NameNotFoundException e) {
123 // unlikely.
124 }
Julia Reynolds40779452016-02-23 13:43:32 -0500125
126 final View importanceSlider = row.findViewById(R.id.importance_slider);
127 final View importanceButtons = row.findViewById(R.id.importance_buttons);
128 if (mShowSlider) {
129 bindSlider(importanceSlider, sbn, systemApp);
130 importanceSlider.setVisibility(View.VISIBLE);
131 importanceButtons.setVisibility(View.GONE);
132 } else {
133 bindToggles(importanceButtons, sbn, systemApp);
134 importanceButtons.setVisibility(View.VISIBLE);
135 importanceSlider.setVisibility(View.GONE);
136 }
137 }
138
139 void saveImportance(final StatusBarNotification sbn) {
140 int progress;
141 if (mSeekBar!= null && mSeekBar.isShown()) {
142 progress = mSeekBar.getProgress();
143 } else {
144 if (mBlock.isChecked()) {
145 progress = NotificationListenerService.Ranking.IMPORTANCE_NONE;
146 } else if (mSilent.isChecked()) {
147 progress = NotificationListenerService.Ranking.IMPORTANCE_DEFAULT;
148 } else {
149 progress = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
150 }
151 }
152 MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
153 progress - mStartingImportance);
154 try {
155 mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(), progress);
156 } catch (RemoteException e) {
157 // :(
158 }
159 }
160
161 private void bindToggles(final View importanceButtons, final StatusBarNotification sbn,
162 final boolean systemApp) {
163 mBlock = (RadioButton) importanceButtons.findViewById(R.id.block_importance);
164 mSilent = (RadioButton) importanceButtons.findViewById(R.id.silent_importance);
165 mReset = (RadioButton) importanceButtons.findViewById(R.id.reset_importance);
Julia Reynolds7727ad22016-01-22 14:38:46 -0500166 if (systemApp) {
Julia Reynolds40779452016-02-23 13:43:32 -0500167 mBlock.setVisibility(View.GONE);
168 mReset.setText(mContext.getString(R.string.do_not_silence));
169 } else {
170 mReset.setText(mContext.getString(R.string.do_not_silence_block));
171 }
172 mReset.setChecked(true);
173 }
174
175 private void bindSlider(final View importanceSlider, final StatusBarNotification sbn,
176 final boolean systemApp) {
177 final TextView importanceSummary = ((TextView) importanceSlider.findViewById(R.id.summary));
178 final TextView importanceTitle = ((TextView) importanceSlider.findViewById(R.id.title));
179 mSeekBar = (SeekBar) importanceSlider.findViewById(R.id.seekbar);
180
181 if (systemApp) {
182 ((ImageView) importanceSlider.findViewById(R.id.low_importance)).getDrawable().setTint(
Julia Reynolds7727ad22016-01-22 14:38:46 -0500183 mContext.getColor(R.color.notification_guts_disabled_icon_tint));
184 }
Julia Reynolds21c30542016-01-15 15:00:02 -0500185 final int minProgress = systemApp ?
Julia Reynoldsf0f629f2016-02-25 09:34:04 -0500186 NotificationListenerService.Ranking.IMPORTANCE_MIN
Julia Reynolds21c30542016-01-15 15:00:02 -0500187 : NotificationListenerService.Ranking.IMPORTANCE_NONE;
188 mSeekBar.setMax(NotificationListenerService.Ranking.IMPORTANCE_MAX);
Julia Reynolds0714f622016-01-07 13:24:09 -0500189 mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
Julia Reynoldsa07af882015-12-17 08:32:48 -0500190 @Override
191 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Julia Reynolds21c30542016-01-15 15:00:02 -0500192 if (progress < minProgress) {
193 seekBar.setProgress(minProgress);
194 progress = minProgress;
195 }
Julia Reynoldsa07af882015-12-17 08:32:48 -0500196 updateTitleAndSummary(progress);
197 if (fromUser) {
Julia Reynoldsb1a235f2016-02-09 12:57:02 -0500198 MetricsLogger.action(mContext, MetricsEvent.ACTION_MODIFY_IMPORTANCE_SLIDER);
Julia Reynoldsa07af882015-12-17 08:32:48 -0500199 }
200 }
201
202 @Override
203 public void onStartTrackingTouch(SeekBar seekBar) {
204 // no-op
205 }
206
207 @Override
208 public void onStopTrackingTouch(SeekBar seekBar) {
209 // no-op
210 }
211
212 private void updateTitleAndSummary(int progress) {
213 switch (progress) {
214 case NotificationListenerService.Ranking.IMPORTANCE_NONE:
Julia Reynoldsef37f282016-02-12 09:11:27 -0500215 importanceSummary.setText(mContext.getString(
Julia Reynoldsa07af882015-12-17 08:32:48 -0500216 R.string.notification_importance_blocked));
Julia Reynoldsef37f282016-02-12 09:11:27 -0500217 importanceTitle.setText(mContext.getString(R.string.blocked_importance));
Julia Reynoldsa07af882015-12-17 08:32:48 -0500218 break;
Julia Reynoldsf0f629f2016-02-25 09:34:04 -0500219 case NotificationListenerService.Ranking.IMPORTANCE_MIN:
220 importanceSummary.setText(mContext.getString(
221 R.string.notification_importance_min));
222 importanceTitle.setText(mContext.getString(R.string.min_importance));
223 break;
Julia Reynoldsa07af882015-12-17 08:32:48 -0500224 case NotificationListenerService.Ranking.IMPORTANCE_LOW:
Julia Reynoldsef37f282016-02-12 09:11:27 -0500225 importanceSummary.setText(mContext.getString(
Julia Reynoldsa07af882015-12-17 08:32:48 -0500226 R.string.notification_importance_low));
Julia Reynoldsef37f282016-02-12 09:11:27 -0500227 importanceTitle.setText(mContext.getString(R.string.low_importance));
Julia Reynoldsa07af882015-12-17 08:32:48 -0500228 break;
229 case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
Julia Reynoldsef37f282016-02-12 09:11:27 -0500230 importanceSummary.setText(mContext.getString(
Julia Reynoldsa07af882015-12-17 08:32:48 -0500231 R.string.notification_importance_default));
Julia Reynoldsef37f282016-02-12 09:11:27 -0500232 importanceTitle.setText(mContext.getString(R.string.default_importance));
Julia Reynoldsa07af882015-12-17 08:32:48 -0500233 break;
234 case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
Julia Reynoldsef37f282016-02-12 09:11:27 -0500235 importanceSummary.setText(mContext.getString(
Julia Reynoldsa07af882015-12-17 08:32:48 -0500236 R.string.notification_importance_high));
Julia Reynoldsef37f282016-02-12 09:11:27 -0500237 importanceTitle.setText(mContext.getString(R.string.high_importance));
Julia Reynoldsa07af882015-12-17 08:32:48 -0500238 break;
239 case NotificationListenerService.Ranking.IMPORTANCE_MAX:
Julia Reynoldsef37f282016-02-12 09:11:27 -0500240 importanceSummary.setText(mContext.getString(
Julia Reynoldsa07af882015-12-17 08:32:48 -0500241 R.string.notification_importance_max));
Julia Reynoldsef37f282016-02-12 09:11:27 -0500242 importanceTitle.setText(mContext.getString(R.string.max_importance));
Julia Reynoldsa07af882015-12-17 08:32:48 -0500243 break;
244 }
245 }
246 });
Julia Reynolds40779452016-02-23 13:43:32 -0500247 mSeekBar.setProgress(mStartingImportance);
Julia Reynoldsa07af882015-12-17 08:32:48 -0500248 }
249
Selim Cinek024ca592014-09-01 15:11:28 +0200250 public void setActualHeight(int actualHeight) {
251 mActualHeight = actualHeight;
252 invalidate();
253 }
254
255 public int getActualHeight() {
256 return mActualHeight;
257 }
258
259 public void setClipTopAmount(int clipTopAmount) {
260 mClipTopAmount = clipTopAmount;
261 invalidate();
262 }
263
264 @Override
265 public boolean hasOverlappingRendering() {
266
267 // Prevents this view from creating a layer when alpha is animating.
268 return false;
269 }
Selim Cinekd84a5932015-12-15 11:45:36 -0800270
271 public void setExposed(boolean exposed) {
272 mExposed = exposed;
273 }
274
275 public boolean areGutsExposed() {
276 return mExposed;
277 }
Julia Reynolds40779452016-02-23 13:43:32 -0500278
279 @Override
280 public void onTuningChanged(String key, String newValue) {
281 if (SHOW_SLIDER.equals(key)) {
282 mShowSlider = newValue != null && Integer.parseInt(newValue) != 0;
283 }
284 }
Selim Cinek024ca592014-09-01 15:11:28 +0200285}