OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.chromecast.shell; | |
6 | |
7 import android.content.BroadcastReceiver; | |
8 import android.content.ComponentName; | |
9 import android.content.Context; | |
10 import android.content.Intent; | |
11 import android.content.IntentFilter; | |
12 import android.content.ServiceConnection; | |
13 import android.net.Uri; | |
14 import android.os.IBinder; | |
15 import android.os.PatternMatcher; | |
16 import android.support.v4.content.LocalBroadcastManager; | |
17 | |
18 import org.chromium.base.Log; | |
19 import org.chromium.content_public.browser.WebContents; | |
20 | |
21 /** | |
22 * A layer of indirection between CastContentWindowAndroid and CastWebContents(A ctivity|Service). | |
23 * <p> | |
24 * On builds with CAST_ANDROID_USE_SERVICE set to false, it will use CastWebCont entsActivity, | |
25 * otherwise, it will use CastWebContentsService. | |
26 */ | |
27 public class CastWebContentsComponent { | |
28 /** | |
29 * Callback interface for when the associated component is closed or the | |
30 * WebContents is detached. | |
31 */ | |
32 public interface OnComponentClosedHandler { void onComponentClosed(); } | |
33 | |
34 /** | |
35 * Callback interface for passing along keyDown events. This only applies | |
36 * to CastWebContentsActivity, really. | |
37 */ | |
38 public interface OnKeyDownHandler { void onKeyDown(int keyCode); } | |
39 | |
40 interface Delegate { | |
41 void start(Context context, WebContents webContents); | |
42 void stop(Context context); | |
43 } | |
44 | |
45 class ActivityDelegate implements Delegate { | |
Simeon
2017/05/15 19:47:24
Does this need to be package-private?
thoren
2017/05/15 22:25:24
Nope. Went ahead and made it private.
| |
46 private static final String TAG = CastWebContentsComponent.TAG + ".Activ ityDelegate"; | |
Simeon
2017/05/15 19:47:24
We don't want dots in tag names because the log el
thoren
2017/05/15 22:25:24
It was being printed, but I went ahead and changed
| |
47 | |
48 @Override | |
49 public void start(Context context, WebContents webContents) { | |
50 if (DEBUG) Log.d(TAG, "start"); | |
51 | |
52 Intent intent = new Intent(Intent.ACTION_VIEW, getInstanceUri(mInsta nceId), context, | |
53 CastWebContentsActivity.class); | |
54 intent.putExtra(ACTION_EXTRA_WEB_CONTENTS, webContents); | |
55 // FLAG_ACTIVITY_SINGLE_TOP will try to reuse existing activity. | |
56 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY _MULTIPLE_TASK | |
57 | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
58 context.startActivity(intent); | |
59 } | |
60 | |
61 @Override | |
62 public void stop(Context context) { | |
63 if (DEBUG) Log.d(TAG, "stop"); | |
64 | |
65 Intent intent = new Intent( | |
66 CastWebContentsActivity.ACTION_STOP_ACTIVITY, getInstanceUri (mInstanceId)); | |
67 LocalBroadcastManager.getInstance(context).sendBroadcastSync(intent) ; | |
68 } | |
69 } | |
70 | |
71 class ServiceDelegate implements Delegate { | |
Simeon
2017/05/15 19:47:24
Does this need to be package-private?
thoren
2017/05/15 22:25:23
Done.
| |
72 private static final String TAG = CastWebContentsComponent.TAG + ".Servi ceDelegate"; | |
73 | |
74 private ServiceConnection mConnection = new ServiceConnection() { | |
75 @Override | |
76 public void onServiceConnected(ComponentName name, IBinder service) {} | |
77 | |
78 @Override | |
79 public void onServiceDisconnected(ComponentName name) { | |
80 if (DEBUG) Log.d(TAG, "onServiceDisconnected"); | |
81 | |
82 if (mComponentClosedHandler != null) mComponentClosedHandler.onC omponentClosed(); | |
83 } | |
84 }; | |
85 | |
86 @Override | |
87 public void start(Context context, WebContents webContents) { | |
88 if (DEBUG) Log.d(TAG, "start"); | |
89 | |
90 Intent intent = new Intent(Intent.ACTION_VIEW, getInstanceUri(mInsta nceId), context, | |
91 CastWebContentsService.class); | |
92 intent.putExtra(ACTION_EXTRA_WEB_CONTENTS, webContents); | |
93 context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); | |
94 } | |
95 | |
96 @Override | |
97 public void stop(Context context) { | |
98 if (DEBUG) Log.d(TAG, "stop"); | |
99 | |
100 context.unbindService(mConnection); | |
101 } | |
102 } | |
103 | |
104 class Receiver extends BroadcastReceiver { | |
Simeon
2017/05/15 19:47:24
Does this need to be package-private?
thoren
2017/05/15 22:25:23
Done.
| |
105 @Override | |
106 public void onReceive(Context context, Intent intent) { | |
107 if (intent.getAction().equals(ACTION_ACTIVITY_STOPPED)) { | |
108 if (DEBUG) Log.d(TAG, "onReceive ACTION_ACTIVITY_STOPPED"); | |
109 | |
110 if (mComponentClosedHandler != null) mComponentClosedHandler.onC omponentClosed(); | |
111 } else if (intent.getAction().equals(ACTION_KEY_EVENT)) { | |
112 if (DEBUG) Log.d(TAG, "onReceive ACTION_KEY_EVENT"); | |
113 | |
114 int keyCode = intent.getIntExtra(ACTION_EXTRA_KEY_CODE, 0); | |
115 if (mKeyDownHandler != null) mKeyDownHandler.onKeyDown(keyCode); | |
116 } | |
117 } | |
118 } | |
119 | |
120 private static final String TAG = "cr_CastWebComponent"; | |
121 private static final boolean DEBUG = true; | |
Simeon
2017/05/15 19:47:24
We might want to make this false in the final patc
thoren
2017/05/15 22:25:24
Not that useful. Done.
| |
122 | |
123 private static final String ACTION_DATA_SCHEME = "cast"; | |
124 private static final String ACTION_DATA_AUTHORITY = "webcontents"; | |
125 private static final String ACTION_EXTRA_WEB_CONTENTS = | |
126 "com.google.android.apps.castshell.intent.extra.WEB_CONTENTS"; | |
Simeon
2017/05/15 19:47:24
These are redeclared in CastWebContentsService and
thoren
2017/05/15 22:25:24
Done.
| |
127 private static final String ACTION_EXTRA_KEY_CODE = | |
128 "com.google.android.apps.castshell.intent.extra.KEY_CODE"; | |
129 private static final String ACTION_KEY_EVENT = | |
130 "com.google.android.apps.castshell.intent.action.KEY_EVENT"; | |
131 private static final String ACTION_ACTIVITY_STOPPED = | |
132 "com.google.android.apps.castshell.intent.action.ACTIVITY_STOPPED"; | |
133 | |
134 private Delegate mDelegate; | |
135 private OnComponentClosedHandler mComponentClosedHandler; | |
136 private OnKeyDownHandler mKeyDownHandler; | |
137 private Receiver mReceiver; | |
138 private String mInstanceId; | |
139 | |
140 public CastWebContentsComponent(String instanceId) { | |
141 mInstanceId = instanceId; | |
142 if (BuildConfig.CAST_ANDROID_USE_SERVICE) { | |
143 mDelegate = new ServiceDelegate(); | |
144 } else { | |
145 mDelegate = new ActivityDelegate(); | |
146 } | |
147 } | |
148 | |
149 public void setOnComponentClosedHandler(OnComponentClosedHandler onComponent ClosedHandler) { | |
150 mComponentClosedHandler = onComponentClosedHandler; | |
151 } | |
152 | |
153 public void setOnKeyDownHandler(OnKeyDownHandler onKeyDownHandler) { | |
154 mKeyDownHandler = onKeyDownHandler; | |
155 } | |
156 | |
157 public void start(Context context, WebContents webContents) { | |
158 if (DEBUG) Log.d(TAG, "start"); | |
159 | |
160 Uri instanceUri = getInstanceUri(mInstanceId); | |
161 mReceiver = new Receiver(); | |
162 IntentFilter filter = new IntentFilter(); | |
163 filter.addDataScheme(instanceUri.getScheme()); | |
164 filter.addDataAuthority(instanceUri.getAuthority(), null); | |
165 filter.addDataPath(instanceUri.getPath(), PatternMatcher.PATTERN_LITERAL ); | |
166 filter.addAction(ACTION_ACTIVITY_STOPPED); | |
167 filter.addAction(ACTION_KEY_EVENT); | |
168 LocalBroadcastManager.getInstance(context).registerReceiver(mReceiver, f ilter); | |
169 | |
170 mDelegate.start(context, webContents); | |
171 } | |
172 | |
173 public void stop(Context context) { | |
174 if (DEBUG) Log.d(TAG, "stop"); | |
175 | |
176 LocalBroadcastManager.getInstance(context).unregisterReceiver(mReceiver) ; | |
177 mDelegate.stop(context); | |
178 } | |
179 | |
180 public static void onComponentClosed(Context context, String instanceId) { | |
181 if (DEBUG) Log.d(TAG, "onComponentClosed"); | |
182 | |
183 Intent intent = new Intent(ACTION_ACTIVITY_STOPPED, getInstanceUri(insta nceId)); | |
184 LocalBroadcastManager.getInstance(context).sendBroadcastSync(intent); | |
185 } | |
186 | |
187 public static void onKeyDown(Context context, String instanceId, int keyCode ) { | |
188 if (DEBUG) Log.d(TAG, "onKeyDown"); | |
189 | |
190 Intent intent = new Intent(ACTION_KEY_EVENT, getInstanceUri(instanceId)) ; | |
191 intent.putExtra(ACTION_EXTRA_KEY_CODE, keyCode); | |
192 LocalBroadcastManager.getInstance(context).sendBroadcastSync(intent); | |
193 } | |
194 | |
195 private static Uri getInstanceUri(String instanceId) { | |
196 Uri instanceUri = new Uri.Builder() | |
197 .scheme(ACTION_DATA_SCHEME) | |
198 .authority(ACTION_DATA_AUTHORITY) | |
199 .path(instanceId) | |
200 .build(); | |
201 return instanceUri; | |
202 } | |
203 } | |
OLD | NEW |