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.Activity; | 7 import android.app.Activity; |
8 import android.graphics.Bitmap; | |
8 import android.media.AudioManager; | 9 import android.media.AudioManager; |
9 import android.text.TextUtils; | 10 import android.text.TextUtils; |
10 | 11 |
11 import org.chromium.base.ApplicationStatus; | 12 import org.chromium.base.ApplicationStatus; |
12 import org.chromium.base.Log; | 13 import org.chromium.base.Log; |
13 import org.chromium.chrome.R; | 14 import org.chromium.chrome.R; |
14 import org.chromium.chrome.browser.metrics.MediaSessionUMA; | 15 import org.chromium.chrome.browser.metrics.MediaSessionUMA; |
15 import org.chromium.chrome.browser.tab.EmptyTabObserver; | 16 import org.chromium.chrome.browser.tab.EmptyTabObserver; |
16 import org.chromium.chrome.browser.tab.Tab; | 17 import org.chromium.chrome.browser.tab.Tab; |
17 import org.chromium.chrome.browser.tab.TabObserver; | 18 import org.chromium.chrome.browser.tab.TabObserver; |
18 import org.chromium.chrome.browser.util.UrlUtilities; | 19 import org.chromium.chrome.browser.util.UrlUtilities; |
19 import org.chromium.content_public.browser.WebContents; | 20 import org.chromium.content_public.browser.WebContents; |
20 import org.chromium.content_public.browser.WebContentsObserver; | 21 import org.chromium.content_public.browser.WebContentsObserver; |
21 import org.chromium.content_public.common.MediaMetadata; | 22 import org.chromium.content_public.common.MediaMetadata; |
22 import org.chromium.ui.base.WindowAndroid; | 23 import org.chromium.ui.base.WindowAndroid; |
23 | 24 |
24 import java.net.URI; | 25 import java.net.URI; |
25 import java.net.URISyntaxException; | 26 import java.net.URISyntaxException; |
26 | 27 |
27 /** | 28 /** |
28 * A tab helper responsible for enabling/disabling media controls and passing | 29 * A tab helper responsible for enabling/disabling media controls and passing |
29 * media actions from the controls to the {@link org.chromium.content.browser.Me diaSession} | 30 * media actions from the controls to the {@link org.chromium.content.browser.Me diaSession} |
30 */ | 31 */ |
31 public class MediaSessionTabHelper { | 32 public class MediaSessionTabHelper { |
32 private static final String TAG = "MediaSession"; | 33 private static final String TAG = "MediaSession"; |
33 | 34 |
34 private static final String UNICODE_PLAY_CHARACTER = "\u25B6"; | 35 private static final String UNICODE_PLAY_CHARACTER = "\u25B6"; |
35 | 36 |
36 private Tab mTab; | 37 private Tab mTab; |
38 private Bitmap mFavicon = null; | |
39 private String mOrigin = null; | |
37 private WebContents mWebContents; | 40 private WebContents mWebContents; |
38 private WebContentsObserver mWebContentsObserver; | 41 private WebContentsObserver mWebContentsObserver; |
39 private int mPreviousVolumeControlStream = AudioManager.USE_DEFAULT_STREAM_T YPE; | 42 private int mPreviousVolumeControlStream = AudioManager.USE_DEFAULT_STREAM_T YPE; |
40 private MediaNotificationInfo.Builder mNotificationInfoBuilder = null; | 43 private MediaNotificationInfo.Builder mNotificationInfoBuilder = null; |
41 private MediaMetadata mFallbackMetadata; | 44 private MediaMetadata mFallbackMetadata; |
42 | 45 |
43 private MediaNotificationListener mControlsListener = new MediaNotificationL istener() { | 46 private MediaNotificationListener mControlsListener = new MediaNotificationL istener() { |
44 @Override | 47 @Override |
45 public void onPlay(int actionSource) { | 48 public void onPlay(int actionSource) { |
46 MediaSessionUMA | 49 MediaSessionUMA |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 super.destroy(); | 89 super.destroy(); |
87 } | 90 } |
88 | 91 |
89 @Override | 92 @Override |
90 public void mediaSessionStateChanged(boolean isControllable, boolean isPaused, | 93 public void mediaSessionStateChanged(boolean isControllable, boolean isPaused, |
91 MediaMetadata metadata) { | 94 MediaMetadata metadata) { |
92 if (!isControllable) { | 95 if (!isControllable) { |
93 hideNotification(); | 96 hideNotification(); |
94 return; | 97 return; |
95 } | 98 } |
96 String origin = mTab.getUrl(); | |
97 try { | |
98 origin = UrlUtilities.formatUrlForSecurityDisplay(new URI(or igin), true); | |
99 } catch (URISyntaxException e) { | |
100 Log.e(TAG, "Unable to parse the origin from the URL. " | |
101 + "Showing the full URL instead."); | |
102 } | |
103 | 99 |
104 mFallbackMetadata = null; | 100 mFallbackMetadata = null; |
105 | 101 |
106 // The page's title is used as a placeholder if no title is spec ified in the | 102 // The page's title is used as a placeholder if no title is spec ified in the |
107 // metadata. | 103 // metadata. |
108 if (TextUtils.isEmpty(metadata.getTitle())) { | 104 if (TextUtils.isEmpty(metadata.getTitle())) { |
109 mFallbackMetadata = new MediaMetadata( | 105 mFallbackMetadata = new MediaMetadata( |
110 sanitizeMediaTitle(mTab.getTitle()), | 106 sanitizeMediaTitle(mTab.getTitle()), |
111 metadata.getArtist(), | 107 metadata.getArtist(), |
112 metadata.getAlbum()); | 108 metadata.getAlbum()); |
113 metadata = mFallbackMetadata; | 109 metadata = mFallbackMetadata; |
114 } | 110 } |
115 | 111 |
116 mNotificationInfoBuilder = new MediaNotificationInfo.Builder() | 112 mNotificationInfoBuilder = new MediaNotificationInfo.Builder() |
117 .setMetadata(metadata) | 113 .setMetadata(metadata) |
118 .setPaused(isPaused) | 114 .setPaused(isPaused) |
119 .setOrigin(origin) | 115 .setOrigin(mOrigin) |
120 .setTabId(mTab.getId()) | 116 .setTabId(mTab.getId()) |
121 .setPrivate(mTab.isIncognito()) | 117 .setPrivate(mTab.isIncognito()) |
122 .setIcon(R.drawable.audio_playing) | 118 .setIcon(R.drawable.audio_playing) |
119 .setLargeIcon(mFavicon) | |
123 .setActions(MediaNotificationInfo.ACTION_PLAY_PAUSE | 120 .setActions(MediaNotificationInfo.ACTION_PLAY_PAUSE |
124 | MediaNotificationInfo.ACTION_SWIPEAWAY) | 121 | MediaNotificationInfo.ACTION_SWIPEAWAY) |
125 .setContentIntent(Tab.createBringTabToFrontIntent(mTab.g etId())) | 122 .setContentIntent(Tab.createBringTabToFrontIntent(mTab.g etId())) |
126 .setId(R.id.media_playback_notification) | 123 .setId(R.id.media_playback_notification) |
127 .setListener(mControlsListener); | 124 .setListener(mControlsListener); |
128 | 125 |
129 MediaNotificationManager.show(ApplicationStatus.getApplicationCo ntext(), | 126 MediaNotificationManager.show(ApplicationStatus.getApplicationCo ntext(), |
130 mNotificationInfoBuilder.build()); | 127 mNotificationInfoBuilder.build()); |
131 | 128 |
132 Activity activity = getActivityFromTab(mTab); | 129 Activity activity = getActivityFromTab(mTab); |
(...skipping 19 matching lines...) Expand all Loading... | |
152 } | 149 } |
153 | 150 |
154 private final TabObserver mTabObserver = new EmptyTabObserver() { | 151 private final TabObserver mTabObserver = new EmptyTabObserver() { |
155 @Override | 152 @Override |
156 public void onContentChanged(Tab tab) { | 153 public void onContentChanged(Tab tab) { |
157 assert tab == mTab; | 154 assert tab == mTab; |
158 setWebContents(tab.getWebContents()); | 155 setWebContents(tab.getWebContents()); |
159 } | 156 } |
160 | 157 |
161 @Override | 158 @Override |
159 public void onFaviconUpdated(Tab tab, Bitmap icon) { | |
160 assert tab == mTab; | |
161 updateFavicon(icon); | |
mlamouri (slow - plz ping)
2016/04/07 19:47:34
Maybe `updateFavicon` could return a boolean sayin
Zhiqiang Zhang (Slow)
2016/04/11 09:26:28
Done.
| |
162 | |
163 if (mNotificationInfoBuilder == null) return; | |
164 | |
165 mNotificationInfoBuilder.setLargeIcon(mFavicon); | |
166 MediaNotificationManager.show(ApplicationStatus.getApplicationContex t(), | |
167 mNotificationInfoBuilder.build()); | |
168 } | |
169 | |
170 @Override | |
171 public void onUrlUpdated(Tab tab) { | |
172 assert tab == mTab; | |
173 | |
174 String origin = mTab.getUrl(); | |
175 try { | |
176 origin = UrlUtilities.formatUrlForSecurityDisplay(new URI(origin ), true); | |
177 } catch (URISyntaxException e) { | |
178 Log.e(TAG, "Unable to parse the origin from the URL. " | |
179 + "Using the full URL instead."); | |
180 } | |
181 | |
182 if (mOrigin != null && mOrigin.equals(origin)) return; | |
183 mOrigin = origin; | |
184 mFavicon = null; | |
185 | |
186 if (mNotificationInfoBuilder == null) return; | |
187 | |
188 mNotificationInfoBuilder.setLargeIcon(mFavicon); | |
mlamouri (slow - plz ping)
2016/04/07 19:47:34
Shouldn't you call mNotificationInfoBuilder.setOri
Zhiqiang Zhang (Slow)
2016/04/11 09:26:28
I think not. mNotificationInfoBuilder can be null
| |
189 MediaNotificationManager.show(ApplicationStatus.getApplicationContex t(), | |
190 mNotificationInfoBuilder.build()); | |
191 } | |
192 | |
193 @Override | |
162 public void onTitleUpdated(Tab tab) { | 194 public void onTitleUpdated(Tab tab) { |
163 assert tab == mTab; | 195 assert tab == mTab; |
164 if (mNotificationInfoBuilder == null || mFallbackMetadata == null) r eturn; | 196 if (mNotificationInfoBuilder == null || mFallbackMetadata == null) r eturn; |
165 | 197 |
166 mFallbackMetadata = new MediaMetadata(mFallbackMetadata); | 198 mFallbackMetadata = new MediaMetadata(mFallbackMetadata); |
167 mFallbackMetadata.setTitle(sanitizeMediaTitle(mTab.getTitle())); | 199 mFallbackMetadata.setTitle(sanitizeMediaTitle(mTab.getTitle())); |
168 mNotificationInfoBuilder.setMetadata(mFallbackMetadata); | 200 mNotificationInfoBuilder.setMetadata(mFallbackMetadata); |
169 | 201 |
170 MediaNotificationManager.show(ApplicationStatus.getApplicationContex t(), | 202 MediaNotificationManager.show(ApplicationStatus.getApplicationContex t(), |
171 mNotificationInfoBuilder.build()); | 203 mNotificationInfoBuilder.build()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 assert false; | 265 assert false; |
234 return MediaSessionUMA.MEDIA_SESSION_ACTION_SOURCE_MAX; | 266 return MediaSessionUMA.MEDIA_SESSION_ACTION_SOURCE_MAX; |
235 } | 267 } |
236 | 268 |
237 private Activity getActivityFromTab(Tab tab) { | 269 private Activity getActivityFromTab(Tab tab) { |
238 WindowAndroid windowAndroid = tab.getWindowAndroid(); | 270 WindowAndroid windowAndroid = tab.getWindowAndroid(); |
239 if (windowAndroid == null) return null; | 271 if (windowAndroid == null) return null; |
240 | 272 |
241 return windowAndroid.getActivity().get(); | 273 return windowAndroid.getActivity().get(); |
242 } | 274 } |
275 | |
276 private void updateFavicon(Bitmap icon) { | |
277 if (icon == null) return; | |
278 if (icon.getWidth() < 112 || icon.getHeight() < 112) return; | |
mlamouri (slow - plz ping)
2016/04/07 19:47:34
Why 112px instead of the values from the design do
Zhiqiang Zhang (Slow)
2016/04/11 09:26:28
Done.
| |
279 if (mFavicon != null | |
280 && (icon.getWidth() < mFavicon.getWidth() | |
281 || icon.getHeight() < mFavicon.getHeight())) { | |
282 return; | |
283 } | |
284 mFavicon = icon; | |
285 } | |
243 } | 286 } |
OLD | NEW |