OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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.remote; | 5 package org.chromium.chrome.browser.media.remote; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.content.Intent; | 8 import android.content.Intent; |
9 import android.graphics.Bitmap; | 9 import android.graphics.Bitmap; |
10 import android.graphics.Color; | 10 import android.graphics.Color; |
11 import android.os.Bundle; | 11 import android.os.Bundle; |
12 import android.os.Handler; | 12 import android.os.Handler; |
13 import android.support.v4.app.FragmentActivity; | 13 import android.support.v4.app.FragmentActivity; |
| 14 import android.support.v4.media.session.PlaybackStateCompat; |
14 import android.text.TextUtils; | 15 import android.text.TextUtils; |
15 import android.view.KeyEvent; | 16 import android.view.KeyEvent; |
16 import android.view.View; | 17 import android.view.View; |
17 import android.view.ViewGroup; | 18 import android.view.ViewGroup; |
18 import android.view.Window; | 19 import android.view.Window; |
19 import android.view.WindowManager; | 20 import android.view.WindowManager; |
20 import android.widget.ImageView; | 21 import android.widget.ImageView; |
21 import android.widget.MediaController; | |
22 import android.widget.MediaController.MediaPlayerControl; | |
23 import android.widget.TextView; | 22 import android.widget.TextView; |
24 | 23 |
25 import com.google.android.gms.cast.CastMediaControlIntent; | 24 import com.google.android.gms.cast.CastMediaControlIntent; |
26 | 25 |
27 import org.chromium.chrome.R; | 26 import org.chromium.chrome.R; |
28 import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState; | 27 import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState; |
29 import org.chromium.chrome.browser.metrics.MediaNotificationUma; | 28 import org.chromium.chrome.browser.metrics.MediaNotificationUma; |
| 29 import org.chromium.third_party.android.media.MediaController; |
30 | 30 |
31 /** | 31 /** |
32 * The activity that's opened by clicking the video flinging (casting) notificat
ion. | 32 * The activity that's opened by clicking the video flinging (casting) notificat
ion. |
33 * | 33 * |
34 * TODO(aberent): Refactor to merge some common logic with {@link CastNotificati
onControl}. | 34 * TODO(aberent): Refactor to merge some common logic with {@link CastNotificati
onControl}. |
35 */ | 35 */ |
36 public class ExpandedControllerActivity | 36 public class ExpandedControllerActivity |
37 extends FragmentActivity implements MediaRouteController.UiListener { | 37 extends FragmentActivity implements MediaRouteController.UiListener { |
38 private static final int PROGRESS_UPDATE_PERIOD_IN_MS = 1000; | 38 private static final int PROGRESS_UPDATE_PERIOD_IN_MS = 1000; |
39 // The alpha value for the poster/placeholder image, an integer between 0 an
d 256 (opaque). | 39 // The alpha value for the poster/placeholder image, an integer between 0 an
d 256 (opaque). |
40 private static final int POSTER_IMAGE_ALPHA = 200; | 40 private static final int POSTER_IMAGE_ALPHA = 200; |
41 | 41 |
42 // Subclass of {@link android.widget.MediaController} that never hides itsel
f. | |
43 class AlwaysShownMediaController extends MediaController { | |
44 public AlwaysShownMediaController(Context context) { | |
45 super(context); | |
46 } | |
47 | |
48 @Override | |
49 public void show(int timeout) { | |
50 // Never auto-hide the controls. | |
51 super.show(0); | |
52 } | |
53 | |
54 @Override | |
55 public boolean dispatchKeyEvent(KeyEvent event) { | |
56 int keyCode = event.getKeyCode(); | |
57 // MediaController hides the controls when back or menu are pressed. | |
58 // Close the activity on back and ignore menu. | |
59 if (keyCode == KeyEvent.KEYCODE_BACK) { | |
60 finish(); | |
61 return true; | |
62 } else if (keyCode == KeyEvent.KEYCODE_MENU) { | |
63 return true; | |
64 } | |
65 return super.dispatchKeyEvent(event); | |
66 } | |
67 | |
68 @Override | |
69 public void hide() { | |
70 // Don't allow the controls to hide until explicitly asked to do so
from the host | |
71 // activity. | |
72 } | |
73 | |
74 /** | |
75 * Actually hides the controls which prevents some window leaks. | |
76 */ | |
77 public void cleanup() { | |
78 super.hide(); | |
79 } | |
80 }; | |
81 | |
82 private Handler mHandler; | 42 private Handler mHandler; |
83 private AlwaysShownMediaController mMediaController; | 43 // We don't use the standard android.media.MediaController, but a custom one
. |
| 44 // See the class itself for details. |
| 45 private MediaController mMediaController; |
84 private FullscreenMediaRouteButton mMediaRouteButton; | 46 private FullscreenMediaRouteButton mMediaRouteButton; |
85 private MediaRouteController mMediaRouteController; | 47 private MediaRouteController mMediaRouteController; |
86 private RemoteVideoInfo mVideoInfo; | 48 private RemoteVideoInfo mVideoInfo; |
87 private String mScreenName; | 49 private String mScreenName; |
88 | 50 |
89 /** | 51 /** |
90 * Handle actions from on-screen media controls. | 52 * Handle actions from on-screen media controls. |
91 */ | 53 */ |
92 private MediaPlayerControl mMediaPlayerControl = new MediaPlayerControl() { | 54 private MediaController.Delegate mControllerDelegate = new MediaController.D
elegate() { |
93 @Override | 55 @Override |
94 public boolean canPause() { | 56 public void play() { |
95 return true; | 57 if (mMediaRouteController == null) return; |
96 } | 58 mMediaRouteController.resume(); |
97 | 59 RecordCastAction.recordFullscreenControlsAction( |
98 @Override | 60 RecordCastAction.FULLSCREEN_CONTROLS_RESUME, |
99 public boolean canSeekBackward() { | 61 mMediaRouteController.getMediaStateListener() != null); |
100 return getDuration() > 0 && getCurrentPosition() > 0; | |
101 } | |
102 | |
103 @Override | |
104 public boolean canSeekForward() { | |
105 return getDuration() > 0 && getCurrentPosition() < getDuration(); | |
106 } | |
107 | |
108 @Override | |
109 public int getAudioSessionId() { | |
110 // TODO(avayvod): not sure 0 is a valid value to return. | |
111 return 0; | |
112 } | |
113 | |
114 @Override | |
115 public int getBufferPercentage() { | |
116 int duration = getDuration(); | |
117 if (duration == 0) return 0; | |
118 return (getCurrentPosition() * 100) / duration; | |
119 } | |
120 | |
121 @Override | |
122 public int getCurrentPosition() { | |
123 if (mMediaRouteController == null) return 0; | |
124 return (int) mMediaRouteController.getPosition(); | |
125 } | |
126 | |
127 @Override | |
128 public int getDuration() { | |
129 if (mMediaRouteController == null) return 0; | |
130 return (int) mMediaRouteController.getDuration(); | |
131 } | |
132 | |
133 @Override | |
134 public boolean isPlaying() { | |
135 if (mMediaRouteController == null) return false; | |
136 return mMediaRouteController.isPlaying(); | |
137 } | 62 } |
138 | 63 |
139 @Override | 64 @Override |
140 public void pause() { | 65 public void pause() { |
141 if (mMediaRouteController == null) return; | 66 if (mMediaRouteController == null) return; |
142 mMediaRouteController.pause(); | 67 mMediaRouteController.pause(); |
143 RecordCastAction.recordFullscreenControlsAction( | 68 RecordCastAction.recordFullscreenControlsAction( |
144 RecordCastAction.FULLSCREEN_CONTROLS_PAUSE, | 69 RecordCastAction.FULLSCREEN_CONTROLS_PAUSE, |
145 mMediaRouteController.getMediaStateListener() != null); | 70 mMediaRouteController.getMediaStateListener() != null); |
146 } | 71 } |
147 | 72 |
148 @Override | 73 @Override |
149 public void start() { | 74 public long getDuration() { |
150 if (mMediaRouteController == null) return; | 75 if (mMediaRouteController == null) return 0; |
151 mMediaRouteController.resume(); | 76 return mMediaRouteController.getDuration(); |
152 RecordCastAction.recordFullscreenControlsAction( | |
153 RecordCastAction.FULLSCREEN_CONTROLS_RESUME, | |
154 mMediaRouteController.getMediaStateListener() != null); | |
155 } | 77 } |
156 | 78 |
157 @Override | 79 @Override |
158 public void seekTo(int pos) { | 80 public long getPosition() { |
| 81 if (mMediaRouteController == null) return 0; |
| 82 return mMediaRouteController.getPosition(); |
| 83 } |
| 84 |
| 85 @Override |
| 86 public void seekTo(long pos) { |
159 if (mMediaRouteController == null) return; | 87 if (mMediaRouteController == null) return; |
160 mMediaRouteController.seekTo(pos); | 88 mMediaRouteController.seekTo(pos); |
161 RecordCastAction.recordFullscreenControlsAction( | 89 RecordCastAction.recordFullscreenControlsAction( |
162 RecordCastAction.FULLSCREEN_CONTROLS_SEEK, | 90 RecordCastAction.FULLSCREEN_CONTROLS_SEEK, |
163 mMediaRouteController.getMediaStateListener() != null); | 91 mMediaRouteController.getMediaStateListener() != null); |
164 } | 92 } |
165 }; | |
166 | 93 |
167 private Runnable mControlsUpdater = new Runnable() { | |
168 @Override | 94 @Override |
169 public void run() { | 95 public boolean isPlaying() { |
170 mMediaController.show(); | 96 if (mMediaRouteController == null) return false; |
| 97 return mMediaRouteController.isPlaying(); |
| 98 } |
| 99 |
| 100 @Override |
| 101 public long getActionFlags() { |
| 102 long flags = |
| 103 PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTI
ON_FAST_FORWARD; |
| 104 if (mMediaRouteController != null && mMediaRouteController.isPlaying
()) { |
| 105 flags |= PlaybackStateCompat.ACTION_PAUSE; |
| 106 } else { |
| 107 flags |= PlaybackStateCompat.ACTION_PLAY; |
| 108 } |
| 109 return flags; |
171 } | 110 } |
172 }; | 111 }; |
173 | 112 |
| 113 private Runnable mProgressUpdater = new Runnable() { |
| 114 @Override |
| 115 public void run() { |
| 116 if (mMediaRouteController.isPlaying()) { |
| 117 mMediaController.updateProgress(); |
| 118 mHandler.postDelayed(this, PROGRESS_UPDATE_PERIOD_IN_MS); |
| 119 } else { |
| 120 mHandler.removeCallbacks(this); |
| 121 } |
| 122 } |
| 123 }; |
| 124 |
174 @Override | 125 @Override |
175 protected void onCreate(Bundle savedInstanceState) { | 126 protected void onCreate(Bundle savedInstanceState) { |
176 super.onCreate(savedInstanceState); | 127 super.onCreate(savedInstanceState); |
177 | 128 |
178 MediaNotificationUma.recordClickSource(getIntent()); | 129 MediaNotificationUma.recordClickSource(getIntent()); |
179 | 130 |
180 mMediaRouteController = | 131 mMediaRouteController = |
181 RemoteMediaPlayerController.instance().getCurrentlyPlayingMediaR
outeController(); | 132 RemoteMediaPlayerController.instance().getCurrentlyPlayingMediaR
outeController(); |
182 | 133 |
183 if (mMediaRouteController == null || mMediaRouteController.routeIsDefaul
tRoute()) { | 134 if (mMediaRouteController == null || mMediaRouteController.routeIsDefaul
tRoute()) { |
(...skipping 10 matching lines...) Expand all Loading... |
194 // requestWindowFeature must be called before adding content. | 145 // requestWindowFeature must be called before adding content. |
195 setContentView(R.layout.expanded_cast_controller); | 146 setContentView(R.layout.expanded_cast_controller); |
196 mHandler = new Handler(); | 147 mHandler = new Handler(); |
197 | 148 |
198 ViewGroup rootView = (ViewGroup) findViewById(android.R.id.content); | 149 ViewGroup rootView = (ViewGroup) findViewById(android.R.id.content); |
199 rootView.setBackgroundColor(Color.BLACK); | 150 rootView.setBackgroundColor(Color.BLACK); |
200 | 151 |
201 mMediaRouteController.addUiListener(this); | 152 mMediaRouteController.addUiListener(this); |
202 | 153 |
203 // Create and initialize the media control UI. | 154 // Create and initialize the media control UI. |
204 mMediaController = new AlwaysShownMediaController(this); | 155 mMediaController = (MediaController) findViewById(R.id.cast_media_contro
ller); |
205 mMediaController.setEnabled(true); | 156 mMediaController.setDelegate(mControllerDelegate); |
206 mMediaController.setMediaPlayer(mMediaPlayerControl); | |
207 mMediaController.setAnchorView(rootView); | |
208 | 157 |
209 View button = getLayoutInflater().inflate(R.layout.cast_controller_media
_route_button, | 158 View button = getLayoutInflater().inflate(R.layout.cast_controller_media
_route_button, |
210 rootView, false); | 159 rootView, false); |
211 | 160 |
212 if (button instanceof FullscreenMediaRouteButton) { | 161 if (button instanceof FullscreenMediaRouteButton) { |
213 mMediaRouteButton = (FullscreenMediaRouteButton) button; | 162 mMediaRouteButton = (FullscreenMediaRouteButton) button; |
214 rootView.addView(mMediaRouteButton); | 163 rootView.addView(mMediaRouteButton); |
215 mMediaRouteButton.bringToFront(); | 164 mMediaRouteButton.bringToFront(); |
216 mMediaRouteButton.initialize(mMediaRouteController); | 165 mMediaRouteButton.initialize(mMediaRouteController); |
217 } else { | 166 } else { |
218 mMediaRouteButton = null; | 167 mMediaRouteButton = null; |
219 } | 168 } |
220 | 169 |
221 // Initialize the video info. | 170 // Initialize the video info. |
222 mVideoInfo = new RemoteVideoInfo(null, 0, RemoteVideoInfo.PlayerState.ST
OPPED, 0, null); | 171 setVideoInfo(new RemoteVideoInfo(null, 0, RemoteVideoInfo.PlayerState.ST
OPPED, 0, null)); |
| 172 |
| 173 mMediaController.refresh(); |
| 174 |
| 175 scheduleProgressUpdate(); |
223 } | 176 } |
224 | 177 |
225 @Override | 178 @Override |
226 protected void onResume() { | 179 protected void onResume() { |
227 super.onResume(); | 180 super.onResume(); |
228 | |
229 if (mVideoInfo.state == PlayerState.FINISHED) finish(); | 181 if (mVideoInfo.state == PlayerState.FINISHED) finish(); |
230 if (mMediaRouteController == null) return; | 182 if (mMediaRouteController == null) return; |
231 | 183 |
232 // Lifetime of the media element is bound to that of the {@link MediaSta
teListener} | 184 // Lifetime of the media element is bound to that of the {@link MediaSta
teListener} |
233 // of the {@link MediaRouteController}. | 185 // of the {@link MediaRouteController}. |
234 RecordCastAction.recordFullscreenControlsShown( | 186 RecordCastAction.recordFullscreenControlsShown( |
235 mMediaRouteController.getMediaStateListener() != null); | 187 mMediaRouteController.getMediaStateListener() != null); |
236 | 188 |
237 mMediaRouteController.prepareMediaRoute(); | 189 mMediaRouteController.prepareMediaRoute(); |
238 | 190 |
239 ImageView iv = (ImageView) findViewById(R.id.cast_background_image); | 191 ImageView iv = (ImageView) findViewById(R.id.cast_background_image); |
240 if (iv == null) return; | 192 if (iv == null) return; |
241 Bitmap posterBitmap = mMediaRouteController.getPoster(); | 193 Bitmap posterBitmap = mMediaRouteController.getPoster(); |
242 if (posterBitmap != null) iv.setImageBitmap(posterBitmap); | 194 if (posterBitmap != null) iv.setImageBitmap(posterBitmap); |
243 iv.setImageAlpha(POSTER_IMAGE_ALPHA); | 195 iv.setImageAlpha(POSTER_IMAGE_ALPHA); |
244 | |
245 // Can't show the media controller until attached to window. | |
246 scheduleControlsUpdate(); | |
247 } | 196 } |
248 | 197 |
249 @Override | 198 @Override |
250 protected void onDestroy() { | 199 protected void onDestroy() { |
251 cleanup(); | 200 cleanup(); |
252 super.onDestroy(); | 201 super.onDestroy(); |
253 } | 202 } |
254 | 203 |
255 @Override | 204 @Override |
256 public boolean dispatchKeyEvent(KeyEvent event) { | 205 public boolean dispatchKeyEvent(KeyEvent event) { |
257 int keyCode = event.getKeyCode(); | 206 int keyCode = event.getKeyCode(); |
258 if ((keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYC
ODE_VOLUME_UP) | 207 if ((keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYC
ODE_VOLUME_UP) |
259 || mVideoInfo.state == PlayerState.FINISHED) { | 208 || mVideoInfo.state == PlayerState.FINISHED) { |
260 return super.dispatchKeyEvent(event); | 209 return super.dispatchKeyEvent(event); |
261 } | 210 } |
262 | 211 |
263 return handleVolumeKeyEvent(mMediaRouteController, event); | 212 return handleVolumeKeyEvent(mMediaRouteController, event); |
264 } | 213 } |
265 | 214 |
266 private void cleanup() { | 215 private void cleanup() { |
267 if (mHandler != null) mHandler.removeCallbacks(mControlsUpdater); | 216 if (mHandler != null) mHandler.removeCallbacks(mProgressUpdater); |
268 if (mMediaRouteController != null) mMediaRouteController.removeUiListene
r(this); | 217 if (mMediaRouteController != null) mMediaRouteController.removeUiListene
r(this); |
269 mMediaRouteController = null; | 218 mMediaRouteController = null; |
270 mControlsUpdater = null; | 219 mProgressUpdater = null; |
271 mMediaController.cleanup(); | |
272 mMediaController = null; | |
273 } | 220 } |
274 | 221 |
275 /** | 222 /** |
276 * Sets the remote's video information to display. | 223 * Sets the remote's video information to display. |
277 */ | 224 */ |
278 private final void setVideoInfo(RemoteVideoInfo videoInfo) { | 225 private final void setVideoInfo(RemoteVideoInfo videoInfo) { |
279 if ((mVideoInfo == null) ? (videoInfo == null) : mVideoInfo.equals(video
Info)) return; | 226 if ((mVideoInfo == null) ? (videoInfo == null) : mVideoInfo.equals(video
Info)) return; |
280 | 227 |
281 mVideoInfo = videoInfo; | 228 mVideoInfo = videoInfo; |
282 updateUi(); | 229 onVideoInfoChanged(); |
283 } | 230 } |
284 | 231 |
285 private void scheduleControlsUpdate() { | 232 private void scheduleProgressUpdate() { |
286 mHandler.removeCallbacks(mControlsUpdater); | 233 mHandler.removeCallbacks(mProgressUpdater); |
287 mHandler.post(mControlsUpdater); | 234 if (mMediaRouteController.isPlaying()) { |
| 235 mHandler.post(mProgressUpdater); |
| 236 } |
288 } | 237 } |
289 | 238 |
290 /** | 239 /** |
291 * Sets the name to display for the device. | 240 * Sets the name to display for the device. |
292 */ | 241 */ |
293 private void setScreenName(String screenName) { | 242 private void setScreenName(String screenName) { |
294 if (TextUtils.equals(mScreenName, screenName)) return; | 243 if (TextUtils.equals(mScreenName, screenName)) return; |
295 | 244 |
296 mScreenName = screenName; | 245 mScreenName = screenName; |
| 246 onScreenNameChanged(); |
| 247 } |
| 248 |
| 249 private void onVideoInfoChanged() { |
297 updateUi(); | 250 updateUi(); |
298 } | 251 } |
299 | 252 |
| 253 private void onScreenNameChanged() { |
| 254 updateUi(); |
| 255 } |
| 256 |
300 private void updateUi() { | 257 private void updateUi() { |
301 if (mMediaController == null || mMediaRouteController == null) return; | 258 if (mMediaController == null || mMediaRouteController == null) return; |
302 | 259 |
303 String deviceName = mMediaRouteController.getRouteName(); | 260 String deviceName = mMediaRouteController.getRouteName(); |
304 String castText = ""; | 261 String castText = ""; |
305 if (deviceName != null) { | 262 if (deviceName != null) { |
306 castText = getResources().getString(R.string.cast_casting_video, dev
iceName); | 263 castText = getResources().getString(R.string.cast_casting_video, dev
iceName); |
307 } | 264 } |
308 TextView castTextView = (TextView) findViewById(R.id.cast_screen_title); | 265 TextView castTextView = (TextView) findViewById(R.id.cast_screen_title); |
309 castTextView.setText(castText); | 266 castTextView.setText(castText); |
310 | 267 |
311 scheduleControlsUpdate(); | 268 mMediaController.refresh(); |
312 } | 269 } |
313 | 270 |
314 @Override | 271 @Override |
315 public void onRouteSelected(String name, MediaRouteController mediaRouteCont
roller) { | 272 public void onRouteSelected(String name, MediaRouteController mediaRouteCont
roller) { |
316 setScreenName(name); | 273 setScreenName(name); |
317 } | 274 } |
318 | 275 |
319 @Override | 276 @Override |
320 public void onRouteUnselected(MediaRouteController mediaRouteController) { | 277 public void onRouteUnselected(MediaRouteController mediaRouteController) { |
321 finish(); | 278 finish(); |
322 } | 279 } |
323 | 280 |
324 @Override | 281 @Override |
325 public void onPrepared(MediaRouteController mediaRouteController) { | 282 public void onPrepared(MediaRouteController mediaRouteController) { |
326 // No implementation. | 283 // No implementation. |
327 } | 284 } |
328 | 285 |
329 @Override | 286 @Override |
330 public void onError(int error, String message) { | 287 public void onError(int error, String message) { |
331 if (error == CastMediaControlIntent.ERROR_CODE_SESSION_START_FAILED) fin
ish(); | 288 if (error == CastMediaControlIntent.ERROR_CODE_SESSION_START_FAILED) fin
ish(); |
332 } | 289 } |
333 | 290 |
334 @Override | 291 @Override |
335 public void onPlaybackStateChanged(PlayerState newState) { | 292 public void onPlaybackStateChanged(PlayerState newState) { |
336 RemoteVideoInfo videoInfo = new RemoteVideoInfo(mVideoInfo); | 293 RemoteVideoInfo videoInfo = new RemoteVideoInfo(mVideoInfo); |
337 videoInfo.state = newState; | 294 videoInfo.state = newState; |
338 setVideoInfo(videoInfo); | 295 setVideoInfo(videoInfo); |
339 | 296 |
340 scheduleControlsUpdate(); | 297 scheduleProgressUpdate(); |
341 | 298 |
342 if (newState == PlayerState.FINISHED || newState == PlayerState.INVALIDA
TED) { | 299 if (newState == PlayerState.FINISHED || newState == PlayerState.INVALIDA
TED) { |
343 // If we are switching to a finished state, stop the notifications. | 300 // If we are switching to a finished state, stop the notifications. |
344 finish(); | 301 finish(); |
345 } | 302 } |
346 } | 303 } |
347 | 304 |
348 @Override | 305 @Override |
349 public void onDurationUpdated(long durationMillis) { | 306 public void onDurationUpdated(long durationMillis) { |
350 RemoteVideoInfo videoInfo = new RemoteVideoInfo(mVideoInfo); | 307 RemoteVideoInfo videoInfo = new RemoteVideoInfo(mVideoInfo); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 * @param context the Context to start this activity within. | 355 * @param context the Context to start this activity within. |
399 */ | 356 */ |
400 public static void startActivity(Context context) { | 357 public static void startActivity(Context context) { |
401 if (context == null) return; | 358 if (context == null) return; |
402 | 359 |
403 Intent intent = new Intent(context, ExpandedControllerActivity.class); | 360 Intent intent = new Intent(context, ExpandedControllerActivity.class); |
404 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 361 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
405 context.startActivity(intent); | 362 context.startActivity(intent); |
406 } | 363 } |
407 } | 364 } |
OLD | NEW |