Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/media/MediaCaptureNotificationService.java

Issue 2123863004: ScreenCapture for Android phase1, part II (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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; 5 package org.chromium.chrome.browser.media;
6 6
7 import android.app.Notification; 7 import android.app.Notification;
8 import android.app.NotificationManager; 8 import android.app.NotificationManager;
9 import android.app.PendingIntent; 9 import android.app.PendingIntent;
10 import android.app.Service; 10 import android.app.Service;
11 import android.content.Context; 11 import android.content.Context;
12 import android.content.Intent; 12 import android.content.Intent;
13 import android.content.SharedPreferences; 13 import android.content.SharedPreferences;
14 import android.os.IBinder; 14 import android.os.IBinder;
15 import android.support.v4.app.NotificationCompat; 15 import android.support.v4.app.NotificationCompat;
16 import android.util.SparseIntArray; 16 import android.util.SparseIntArray;
17 17
18 import org.chromium.base.ContextUtils; 18 import org.chromium.base.ContextUtils;
19 import org.chromium.base.Log; 19 import org.chromium.base.Log;
20 import org.chromium.chrome.R; 20 import org.chromium.chrome.R;
21 import org.chromium.chrome.browser.tab.Tab; 21 import org.chromium.chrome.browser.tab.Tab;
22 import org.chromium.chrome.browser.tab.TabWebContentsDelegateAndroid;
22 23
23 import java.net.MalformedURLException; 24 import java.net.MalformedURLException;
24 import java.net.URL; 25 import java.net.URL;
25 import java.util.HashSet; 26 import java.util.HashSet;
26 import java.util.Iterator; 27 import java.util.Iterator;
27 import java.util.Set; 28 import java.util.Set;
28 29
29 /** 30 /**
30 * Service that creates/destroys the WebRTC notification when media capture star ts/stops. 31 * Service that creates/destroys the WebRTC notification when media capture star ts/stops.
31 */ 32 */
32 public class MediaCaptureNotificationService extends Service { 33 public class MediaCaptureNotificationService extends Service {
34 private static final String ACTION_MEDIA_CAPTURE_UPDATE =
35 "org.chromium.chrome.browser.media.SCREEN_CAPTURE_UPDATE";
36 private static final String ACTION_SCREEN_CAPTURE_STOP =
37 "org.chromium.chrome.browser.media.SCREEN_CAPTURE_STOP";
33 38
34 private static final String NOTIFICATION_NAMESPACE = "MediaCaptureNotificati onService"; 39 private static final String NOTIFICATION_NAMESPACE = "MediaCaptureNotificati onService";
35 40
36 private static final String NOTIFICATION_ID_EXTRA = "NotificationId"; 41 private static final String NOTIFICATION_ID_EXTRA = "NotificationId";
37 private static final String NOTIFICATION_MEDIA_TYPE_EXTRA = "NotificationMed iaType"; 42 private static final String NOTIFICATION_MEDIA_TYPE_EXTRA = "NotificationMed iaType";
38 private static final String NOTIFICATION_MEDIA_URL_EXTRA = "NotificationMedi aUrl"; 43 private static final String NOTIFICATION_MEDIA_URL_EXTRA = "NotificationMedi aUrl";
39 44
40 private static final String WEBRTC_NOTIFICATION_IDS = "WebRTCNotificationIds "; 45 private static final String WEBRTC_NOTIFICATION_IDS = "WebRTCNotificationIds ";
41 private static final String TAG = "MediaCapture"; 46 private static final String TAG = "MediaCapture";
42 47
43 private static final int MEDIATYPE_NO_MEDIA = 0; 48 private static final int MEDIATYPE_NO_MEDIA = 0;
44 private static final int MEDIATYPE_AUDIO_AND_VIDEO = 1; 49 private static final int MEDIATYPE_AUDIO_AND_VIDEO = 1;
45 private static final int MEDIATYPE_VIDEO_ONLY = 2; 50 private static final int MEDIATYPE_VIDEO_ONLY = 2;
46 private static final int MEDIATYPE_AUDIO_ONLY = 3; 51 private static final int MEDIATYPE_AUDIO_ONLY = 3;
52 private static final int MEDIATYPE_SCREEN_CAPTURE = 4;
47 53
48 private NotificationManager mNotificationManager; 54 private NotificationManager mNotificationManager;
49 private Context mContext; 55 private Context mContext;
50 private SharedPreferences mSharedPreferences; 56 private SharedPreferences mSharedPreferences;
51 private final SparseIntArray mNotifications = new SparseIntArray(); 57 private final SparseIntArray mNotifications = new SparseIntArray();
52 58
53 @Override 59 @Override
54 public void onCreate() { 60 public void onCreate() {
55 mContext = getApplicationContext(); 61 mContext = getApplicationContext();
56 mNotificationManager = (NotificationManager) mContext.getSystemService( 62 mNotificationManager = (NotificationManager) mContext.getSystemService(
(...skipping 19 matching lines...) Expand all
76 private boolean doesNotificationExist(int notificationId) { 82 private boolean doesNotificationExist(int notificationId) {
77 return mNotifications.indexOfKey(notificationId) >= 0; 83 return mNotifications.indexOfKey(notificationId) >= 0;
78 } 84 }
79 85
80 @Override 86 @Override
81 public int onStartCommand(Intent intent, int flags, int startId) { 87 public int onStartCommand(Intent intent, int flags, int startId) {
82 if (intent == null || intent.getExtras() == null) { 88 if (intent == null || intent.getExtras() == null) {
83 cancelPreviousWebRtcNotifications(); 89 cancelPreviousWebRtcNotifications();
84 stopSelf(); 90 stopSelf();
85 } else { 91 } else {
86 updateNotification( 92 String action = intent.getAction();
87 intent.getIntExtra(NOTIFICATION_ID_EXTRA, Tab.INVALID_TAB_ID ), 93 int notificationId = intent.getIntExtra(NOTIFICATION_ID_EXTRA, Tab.I NVALID_TAB_ID);
88 intent.getIntExtra(NOTIFICATION_MEDIA_TYPE_EXTRA, MEDIATYPE_ NO_MEDIA), 94 int mediaType = intent.getIntExtra(NOTIFICATION_MEDIA_TYPE_EXTRA, ME DIATYPE_NO_MEDIA);
89 intent.getStringExtra(NOTIFICATION_MEDIA_URL_EXTRA)); 95 String url = intent.getStringExtra(NOTIFICATION_MEDIA_URL_EXTRA);
96
97 if (ACTION_MEDIA_CAPTURE_UPDATE.equals(action)) {
98 updateNotification(notificationId, mediaType, url);
99 } else if (ACTION_SCREEN_CAPTURE_STOP.equals(action)) {
100 // Notify native to stop screen capture when the STOP button in notification
101 // is clicked.
102 TabWebContentsDelegateAndroid.notifyStopped(notificationId);
103 }
90 } 104 }
91 return super.onStartCommand(intent, flags, startId); 105 return super.onStartCommand(intent, flags, startId);
92 } 106 }
93 107
94 /** 108 /**
95 * Cancel all previously existing notifications. Essential while doing a cle an start (may be 109 * Cancel all previously existing notifications. Essential while doing a cle an start (may be
96 * after a browser crash which caused old notifications to exist). 110 * after a browser crash which caused old notifications to exist).
97 */ 111 */
98 private void cancelPreviousWebRtcNotifications() { 112 private void cancelPreviousWebRtcNotifications() {
99 Set<String> notificationIds = 113 Set<String> notificationIds =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 } 153 }
140 } 154 }
141 155
142 /** 156 /**
143 * Creates a notification for the provided notificationId and mediaType. 157 * Creates a notification for the provided notificationId and mediaType.
144 * @param notificationId Unique id of the notification. 158 * @param notificationId Unique id of the notification.
145 * @param mediaType Media type of the notification. 159 * @param mediaType Media type of the notification.
146 * @param url Url of the current webrtc call. 160 * @param url Url of the current webrtc call.
147 */ 161 */
148 private void createNotification(int notificationId, int mediaType, String ur l) { 162 private void createNotification(int notificationId, int mediaType, String ur l) {
149 int notificationContentTextId = 0; 163 NotificationCompat.Builder builder =
150 int notificationIconId = 0; 164 new NotificationCompat.Builder(mContext)
151 if (mediaType == MEDIATYPE_AUDIO_AND_VIDEO) { 165 .setAutoCancel(false)
152 notificationContentTextId = R.string.video_audio_call_notification_t ext_2; 166 .setOngoing(true)
153 notificationIconId = R.drawable.webrtc_video; 167 .setContentTitle(mContext.getString(R.string.app_name))
154 } else if (mediaType == MEDIATYPE_VIDEO_ONLY) { 168 .setSmallIcon(getNotificationIconId(mediaType))
155 notificationContentTextId = R.string.video_call_notification_text_2; 169 .setLocalOnly(true);
156 notificationIconId = R.drawable.webrtc_video;
157 } else if (mediaType == MEDIATYPE_AUDIO_ONLY) {
158 notificationContentTextId = R.string.audio_call_notification_text_2;
159 notificationIconId = R.drawable.webrtc_audio;
160 }
161 170
162 NotificationCompat.Builder builder = new NotificationCompat.Builder(mCon text) 171 StringBuilder contentText =
163 .setAutoCancel(false) 172 new StringBuilder(getNotificationContentText(mediaType, url)).ap pend('.');
164 .setOngoing(true)
165 .setContentTitle(mContext.getString(R.string.app_name))
166 .setSmallIcon(notificationIconId)
167 .setLocalOnly(true);
168
169 StringBuilder contentText = new StringBuilder(
170 mContext.getResources().getString(notificationContentTextId)).ap pend('.');
171 Intent tabIntent = Tab.createBringTabToFrontIntent(notificationId); 173 Intent tabIntent = Tab.createBringTabToFrontIntent(notificationId);
172 if (tabIntent != null) { 174 if (tabIntent != null) {
173 PendingIntent contentIntent = PendingIntent.getActivity( 175 PendingIntent contentIntent = PendingIntent.getActivity(
174 mContext, notificationId, tabIntent, 0); 176 mContext, notificationId, tabIntent, 0);
175 builder.setContentIntent(contentIntent); 177 builder.setContentIntent(contentIntent);
176 contentText.append( 178 if (mediaType == MEDIATYPE_SCREEN_CAPTURE) {
177 mContext.getResources().getString(R.string.media_notificatio n_link_text, url)); 179 // Add a "Stop" button to the screen capture notification and tu rn the notification
180 // into a high priority one.
181 builder.setPriority(Notification.PRIORITY_HIGH);
182 builder.setVibrate(new long[0]);
183 builder.addAction(R.drawable.ic_vidcontrol_stop,
184 mContext.getResources().getString(R.string.accessibility _stop),
185 buildStopCapturePendingIntent(notificationId));
186 } else {
187 contentText.append(mContext.getResources().getString(
188 R.string.media_notification_link_text, url));
189 }
178 } else { 190 } else {
179 contentText.append(" ").append(url); 191 contentText.append(" ").append(url);
180 } 192 }
181 builder.setContentText(contentText); 193 builder.setContentText(contentText);
182 194
183 Notification notification = new NotificationCompat.BigTextStyle(builder) 195 Notification notification = new NotificationCompat.BigTextStyle(builder)
184 .bigText(contentText).build(); 196 .bigText(contentText).build();
185 mNotificationManager.notify(NOTIFICATION_NAMESPACE, notificationId, noti fication); 197 mNotificationManager.notify(NOTIFICATION_NAMESPACE, notificationId, noti fication);
186 mNotifications.put(notificationId, mediaType); 198 mNotifications.put(notificationId, mediaType);
187 updateSharedPreferencesEntry(notificationId, false); 199 updateSharedPreferencesEntry(notificationId, false);
188 } 200 }
189 201
190 /** 202 /**
203 * Builds notification content text for the provided mediaType and url.
204 * @param mediaType Media type of the notification.
205 * @param url Url of the current webrtc call.
206 * @return A string builder initialized to the contents of the specified str ing.
207 */
208 private String getNotificationContentText(int mediaType, String url) {
209 if (mediaType == MEDIATYPE_SCREEN_CAPTURE) {
210 return mContext.getResources().getString(
211 R.string.screen_capture_notification_text, url);
212 }
213
214 int notificationContentTextId = 0;
215 if (mediaType == MEDIATYPE_AUDIO_AND_VIDEO) {
216 notificationContentTextId = R.string.video_audio_call_notification_t ext_2;
217 } else if (mediaType == MEDIATYPE_VIDEO_ONLY) {
218 notificationContentTextId = R.string.video_call_notification_text_2;
219 } else if (mediaType == MEDIATYPE_AUDIO_ONLY) {
220 notificationContentTextId = R.string.audio_call_notification_text_2;
221 }
222
223 return mContext.getResources().getString(notificationContentTextId);
224 }
225
226 /**
227 * @param mediaType Media type of the notification.
228 * @return An icon id of the provided mediaType.
229 */
230 private int getNotificationIconId(int mediaType) {
231 int notificationIconId = 0;
232 if (mediaType == MEDIATYPE_AUDIO_AND_VIDEO) {
233 notificationIconId = R.drawable.webrtc_video;
234 } else if (mediaType == MEDIATYPE_VIDEO_ONLY) {
235 notificationIconId = R.drawable.webrtc_video;
236 } else if (mediaType == MEDIATYPE_AUDIO_ONLY) {
237 notificationIconId = R.drawable.webrtc_audio;
238 } else if (mediaType == MEDIATYPE_SCREEN_CAPTURE) {
239 notificationIconId = R.drawable.webrtc_video;
240 }
241 return notificationIconId;
242 }
243
244 /**
191 * Update shared preferences entry with ids of the visible notifications. 245 * Update shared preferences entry with ids of the visible notifications.
192 * @param notificationId Id of the notification. 246 * @param notificationId Id of the notification.
193 * @param remove Boolean describing if the notification was added or removed . 247 * @param remove Boolean describing if the notification was added or removed .
194 */ 248 */
195 private void updateSharedPreferencesEntry(int notificationId, boolean remove ) { 249 private void updateSharedPreferencesEntry(int notificationId, boolean remove ) {
196 Set<String> notificationIds = 250 Set<String> notificationIds =
197 new HashSet<String>(mSharedPreferences.getStringSet(WEBRTC_NOTIF ICATION_IDS, 251 new HashSet<String>(mSharedPreferences.getStringSet(WEBRTC_NOTIF ICATION_IDS,
198 new HashSet<String>())); 252 new HashSet<String>()));
199 if (remove && !notificationIds.isEmpty() 253 if (remove && !notificationIds.isEmpty()
200 && notificationIds.contains(String.valueOf(notificationId))) { 254 && notificationIds.contains(String.valueOf(notificationId))) {
(...skipping 19 matching lines...) Expand all
220 } 274 }
221 275
222 @Override 276 @Override
223 public IBinder onBind(Intent intent) { 277 public IBinder onBind(Intent intent) {
224 return null; 278 return null;
225 } 279 }
226 280
227 /** 281 /**
228 * @param audio If audio is being captured. 282 * @param audio If audio is being captured.
229 * @param video If video is being captured. 283 * @param video If video is being captured.
284 * @param screen If screen is being captured.
230 * @return A constant identify what media is being captured. 285 * @return A constant identify what media is being captured.
231 */ 286 */
232 public static int getMediaType(boolean audio, boolean video) { 287 public static int getMediaType(boolean audio, boolean video, boolean screen) {
233 if (audio && video) { 288 if (screen) {
289 return MEDIATYPE_SCREEN_CAPTURE;
290 } else if (audio && video) {
234 return MEDIATYPE_AUDIO_AND_VIDEO; 291 return MEDIATYPE_AUDIO_AND_VIDEO;
235 } else if (audio) { 292 } else if (audio) {
236 return MEDIATYPE_AUDIO_ONLY; 293 return MEDIATYPE_AUDIO_ONLY;
237 } else if (video) { 294 } else if (video) {
238 return MEDIATYPE_VIDEO_ONLY; 295 return MEDIATYPE_VIDEO_ONLY;
239 } else { 296 } else {
240 return MEDIATYPE_NO_MEDIA; 297 return MEDIATYPE_NO_MEDIA;
241 } 298 }
242 } 299 }
243 300
244 private static boolean shouldStartService(Context context, int mediaType, in t tabId) { 301 private static boolean shouldStartService(Context context, int mediaType, in t tabId) {
245 if (mediaType != MEDIATYPE_NO_MEDIA) return true; 302 if (mediaType != MEDIATYPE_NO_MEDIA) return true;
246 SharedPreferences sharedPreferences = 303 SharedPreferences sharedPreferences =
247 ContextUtils.getAppSharedPreferences(); 304 ContextUtils.getAppSharedPreferences();
248 Set<String> notificationIds = 305 Set<String> notificationIds =
249 sharedPreferences.getStringSet(WEBRTC_NOTIFICATION_IDS, null); 306 sharedPreferences.getStringSet(WEBRTC_NOTIFICATION_IDS, null);
250 if (notificationIds != null 307 if (notificationIds != null
251 && !notificationIds.isEmpty() 308 && !notificationIds.isEmpty()
252 && notificationIds.contains(String.valueOf(tabId))) { 309 && notificationIds.contains(String.valueOf(tabId))) {
253 return true; 310 return true;
254 } 311 }
255 return false; 312 return false;
256 } 313 }
257 314
258 /** 315 /**
259 * Send an intent to MediaCaptureNotificationService to either create, updat e or destroy the 316 * Send an intent to MediaCaptureNotificationService to either create, updat e or destroy the
260 * notification identified by tabId. 317 * notification identified by tabId.
261 * @param tabId Unique notification id. 318 * @param tabId Unique notification id.
262 * @param audio If audio is being captured. 319 * @param mediaType The media type that is being captured.
263 * @param video If video is being captured.
264 * @param fullUrl Url of the current webrtc call. 320 * @param fullUrl Url of the current webrtc call.
265 */ 321 */
266 public static void updateMediaNotificationForTab( 322 public static void updateMediaNotificationForTab(
267 Context context, int tabId, boolean audio, boolean video, String ful lUrl) { 323 Context context, int tabId, int mediaType, String fullUrl) {
268 int mediaType = getMediaType(audio, video);
269 if (!shouldStartService(context, mediaType, tabId)) return; 324 if (!shouldStartService(context, mediaType, tabId)) return;
270 Intent intent = new Intent(context, MediaCaptureNotificationService.clas s); 325 Intent intent = new Intent(context, MediaCaptureNotificationService.clas s);
326 intent.setAction(ACTION_MEDIA_CAPTURE_UPDATE);
271 intent.putExtra(NOTIFICATION_ID_EXTRA, tabId); 327 intent.putExtra(NOTIFICATION_ID_EXTRA, tabId);
272 String baseUrl = fullUrl; 328 String baseUrl = fullUrl;
273 try { 329 try {
274 URL url = new URL(fullUrl); 330 URL url = new URL(fullUrl);
275 baseUrl = url.getProtocol() + "://" + url.getHost(); 331 baseUrl = url.getProtocol() + "://" + url.getHost();
276 } catch (MalformedURLException e) { 332 } catch (MalformedURLException e) {
277 Log.w(TAG, "Error parsing the webrtc url, %s ", fullUrl); 333 Log.w(TAG, "Error parsing the webrtc url, %s ", fullUrl);
278 } 334 }
279 intent.putExtra(NOTIFICATION_MEDIA_URL_EXTRA, baseUrl); 335 intent.putExtra(NOTIFICATION_MEDIA_URL_EXTRA, baseUrl);
280 intent.putExtra(NOTIFICATION_MEDIA_TYPE_EXTRA, mediaType); 336 intent.putExtra(NOTIFICATION_MEDIA_TYPE_EXTRA, mediaType);
281 context.startService(intent); 337 context.startService(intent);
282 } 338 }
283 339
284 /** 340 /**
285 * Clear any previous media notifications. 341 * Clear any previous media notifications.
286 */ 342 */
287 public static void clearMediaNotifications(Context context) { 343 public static void clearMediaNotifications(Context context) {
288 SharedPreferences sharedPreferences = 344 SharedPreferences sharedPreferences =
289 ContextUtils.getAppSharedPreferences(); 345 ContextUtils.getAppSharedPreferences();
290 Set<String> notificationIds = 346 Set<String> notificationIds =
291 sharedPreferences.getStringSet(WEBRTC_NOTIFICATION_IDS, null); 347 sharedPreferences.getStringSet(WEBRTC_NOTIFICATION_IDS, null);
292 if (notificationIds == null || notificationIds.isEmpty()) return; 348 if (notificationIds == null || notificationIds.isEmpty()) return;
293 349
294 context.startService(new Intent(context, MediaCaptureNotificationService .class)); 350 context.startService(new Intent(context, MediaCaptureNotificationService .class));
295 } 351 }
352
353 /**
354 * Build PendingIntent for the actions of screen capture notification.
355 */
356 private PendingIntent buildStopCapturePendingIntent(int notificationId) {
357 Intent intent = new Intent(this, MediaCaptureNotificationService.class);
358 intent.setAction(ACTION_SCREEN_CAPTURE_STOP);
359 intent.putExtra(NOTIFICATION_ID_EXTRA, notificationId);
360 return PendingIntent.getService(
361 mContext, notificationId, intent, PendingIntent.FLAG_UPDATE_CURR ENT);
362 }
296 } 363 }
OLDNEW
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698