OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.media.ui; | 5 package org.chromium.chrome.browser.media.ui; |
6 | 6 |
7 import android.app.PendingIntent; | 7 import android.app.PendingIntent; |
8 import android.app.Service; | 8 import android.app.Service; |
9 import android.content.Context; | 9 import android.content.Context; |
10 import android.content.Intent; | 10 import android.content.Intent; |
11 import android.graphics.Bitmap; | |
12 import android.graphics.Canvas; | |
13 import android.graphics.drawable.BitmapDrawable; | |
14 import android.graphics.drawable.Drawable; | |
11 import android.os.IBinder; | 15 import android.os.IBinder; |
12 import android.provider.Browser; | 16 import android.provider.Browser; |
13 import android.support.v4.app.NotificationCompat; | 17 import android.support.v4.app.NotificationCompat; |
14 import android.widget.RemoteViews; | 18 import android.widget.RemoteViews; |
15 | 19 |
20 import org.chromium.base.ApiCompatibilityUtils; | |
16 import org.chromium.chrome.R; | 21 import org.chromium.chrome.R; |
17 import org.chromium.chrome.browser.IntentHandler.TabOpenType; | 22 import org.chromium.chrome.browser.IntentHandler.TabOpenType; |
18 | 23 |
19 /** | 24 /** |
20 * A class for notifications that provide information and optional media control s for a given media. | 25 * A class for notifications that provide information and optional media control s for a given media. |
21 * Internally implements a Service for transforming notification Intents into | 26 * Internally implements a Service for transforming notification Intents into |
22 * {@link MediaPlaybackListener} calls for all registered listeners. | 27 * {@link MediaPlaybackListener} calls for all registered listeners. |
23 */ | 28 */ |
24 public class NotificationMediaPlaybackControls { | 29 public class NotificationMediaPlaybackControls { |
25 private static final Object LOCK = new Object(); | 30 private static final Object LOCK = new Object(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 | 149 |
145 // ListenerService running for the notification. Only non-null when showing. | 150 // ListenerService running for the notification. Only non-null when showing. |
146 private ListenerService mService; | 151 private ListenerService mService; |
147 | 152 |
148 private final String mPlayDescription; | 153 private final String mPlayDescription; |
149 | 154 |
150 private final String mPauseDescription; | 155 private final String mPauseDescription; |
151 | 156 |
152 private NotificationCompat.Builder mNotificationBuilder; | 157 private NotificationCompat.Builder mNotificationBuilder; |
153 | 158 |
159 private Bitmap mNotificationIconBitmap; | |
160 | |
154 private MediaNotificationInfo mMediaNotificationInfo; | 161 private MediaNotificationInfo mMediaNotificationInfo; |
155 | 162 |
156 private NotificationMediaPlaybackControls(Context context) { | 163 private NotificationMediaPlaybackControls(Context context) { |
157 mContext = context; | 164 mContext = context; |
158 mPlayDescription = context.getResources().getString(R.string.accessibili ty_play); | 165 mPlayDescription = context.getResources().getString(R.string.accessibili ty_play); |
159 mPauseDescription = context.getResources().getString(R.string.accessibil ity_pause); | 166 mPauseDescription = context.getResources().getString(R.string.accessibil ity_pause); |
160 } | 167 } |
161 | 168 |
162 private void showNotification(MediaNotificationInfo mediaNotificationInfo) { | 169 private void showNotification(MediaNotificationInfo mediaNotificationInfo) { |
163 mContext.startService(new Intent(mContext, ListenerService.class)); | 170 mContext.startService(new Intent(mContext, ListenerService.class)); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 | 234 |
228 private void updateNotification() { | 235 private void updateNotification() { |
229 if (mService == null) return; | 236 if (mService == null) return; |
230 | 237 |
231 if (mMediaNotificationInfo == null) { | 238 if (mMediaNotificationInfo == null) { |
232 // Notification was hidden before we could update it. | 239 // Notification was hidden before we could update it. |
233 assert mNotificationBuilder == null; | 240 assert mNotificationBuilder == null; |
234 return; | 241 return; |
235 } | 242 } |
236 | 243 |
244 // Android doesn't badge the icons for RemoteViews automatically when | |
245 // running the app under the Work profile. | |
246 if (mNotificationIconBitmap == null) { | |
247 Drawable notificationIconDrawable = ApiCompatibilityUtils.getUserBad gedIcon( | |
248 mContext, R.drawable.audio_playing); | |
249 mNotificationIconBitmap = drawableToBitmap(notificationIconDrawable) ; | |
250 } | |
251 | |
237 if (mNotificationBuilder == null) { | 252 if (mNotificationBuilder == null) { |
238 mNotificationBuilder = new NotificationCompat.Builder(mContext) | 253 mNotificationBuilder = new NotificationCompat.Builder(mContext) |
239 .setSmallIcon(R.drawable.audio_playing) | 254 .setSmallIcon(R.drawable.audio_playing) |
240 .setAutoCancel(false) | 255 .setAutoCancel(false) |
241 .setOngoing(true); | 256 .setOngoing(true); |
242 } | 257 } |
243 mNotificationBuilder.setContentIntent(createContentIntent()); | 258 mNotificationBuilder.setContentIntent(createContentIntent()); |
244 | 259 |
245 RemoteViews contentView = createContentView(); | 260 RemoteViews contentView = createContentView(); |
246 | 261 |
247 contentView.setTextViewText(R.id.title, getTitle()); | 262 contentView.setTextViewText(R.id.title, getTitle()); |
248 contentView.setTextViewText(R.id.status, getStatus()); | 263 contentView.setTextViewText(R.id.status, getStatus()); |
249 contentView.setImageViewResource(R.id.icon, R.drawable.audio_playing); | 264 contentView.setImageViewBitmap(R.id.icon, mNotificationIconBitmap); |
250 | 265 |
251 if (mMediaNotificationInfo.isPaused) { | 266 if (mMediaNotificationInfo.isPaused) { |
252 contentView.setImageViewResource(R.id.playpause, R.drawable.ic_vidco ntrol_play); | 267 contentView.setImageViewResource(R.id.playpause, R.drawable.ic_vidco ntrol_play); |
253 contentView.setContentDescription(R.id.playpause, mPlayDescription); | 268 contentView.setContentDescription(R.id.playpause, mPlayDescription); |
254 contentView.setOnClickPendingIntent(R.id.playpause, | 269 contentView.setOnClickPendingIntent(R.id.playpause, |
255 mService.getPendingIntent(ListenerService.ACTION_PLAY)); | 270 mService.getPendingIntent(ListenerService.ACTION_PLAY)); |
256 } else { | 271 } else { |
257 contentView.setImageViewResource(R.id.playpause, R.drawable.ic_vidco ntrol_pause); | 272 contentView.setImageViewResource(R.id.playpause, R.drawable.ic_vidco ntrol_pause); |
258 contentView.setContentDescription(R.id.playpause, mPauseDescription) ; | 273 contentView.setContentDescription(R.id.playpause, mPauseDescription) ; |
259 contentView.setOnClickPendingIntent(R.id.playpause, | 274 contentView.setOnClickPendingIntent(R.id.playpause, |
260 mService.getPendingIntent(ListenerService.ACTION_PAUSE)); | 275 mService.getPendingIntent(ListenerService.ACTION_PAUSE)); |
261 } | 276 } |
262 | 277 |
263 mNotificationBuilder.setContent(contentView); | 278 mNotificationBuilder.setContent(contentView); |
264 mNotificationBuilder.setVisibility( | 279 mNotificationBuilder.setVisibility( |
265 mMediaNotificationInfo.isPrivate ? NotificationCompat.VISIBILITY _PRIVATE | 280 mMediaNotificationInfo.isPrivate ? NotificationCompat.VISIBILITY _PRIVATE |
266 : NotificationCompat.VISIBILITY _PUBLIC); | 281 : NotificationCompat.VISIBILITY _PUBLIC); |
267 | 282 |
268 mService.startForeground(R.id.media_playback_notification, mNotification Builder.build()); | 283 mService.startForeground(R.id.media_playback_notification, mNotification Builder.build()); |
269 } | 284 } |
285 | |
286 private Bitmap drawableToBitmap(Drawable drawable) { | |
287 Bitmap bitmap = null; | |
288 | |
289 if (drawable instanceof BitmapDrawable) { | |
290 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; | |
291 if (bitmapDrawable.getBitmap() != null) { | |
292 return bitmapDrawable.getBitmap(); | |
aurimas (slooooooooow)
2015/07/30 16:51:28
Almost every time we should return here. Otherwise
| |
293 } | |
294 } | |
295 | |
296 if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() < = 0) { | |
297 bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); | |
298 } else { | |
299 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), | |
300 drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); | |
301 } | |
302 | |
303 Canvas canvas = new Canvas(bitmap); | |
304 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); | |
305 drawable.draw(canvas); | |
306 return bitmap; | |
307 } | |
270 } | 308 } |
OLD | NEW |