OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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.content_shell; | 5 package org.chromium.content_shell; |
6 | 6 |
7 import android.content.Context; | |
8 import android.graphics.drawable.ClipDrawable; | |
9 import android.text.TextUtils; | |
10 import android.util.AttributeSet; | |
11 import android.view.KeyEvent; | |
12 import android.view.View; | |
13 import android.view.ViewGroup; | |
14 import android.view.inputmethod.EditorInfo; | |
15 import android.view.inputmethod.InputMethodManager; | |
16 import android.widget.EditText; | |
17 import android.widget.FrameLayout; | |
18 import android.widget.ImageButton; | |
19 import android.widget.LinearLayout; | |
20 import android.widget.TextView; | |
21 import android.widget.TextView.OnEditorActionListener; | |
22 | |
23 import org.chromium.base.annotations.CalledByNative; | 7 import org.chromium.base.annotations.CalledByNative; |
24 import org.chromium.base.annotations.JNINamespace; | 8 import org.chromium.base.annotations.JNINamespace; |
25 import org.chromium.content.browser.ContentView; | 9 //import org.chromium.content_public.browser.LoadUrlParams; |
26 import org.chromium.content.browser.ContentViewClient; | 10 //import org.chromium.content_public.browser.NavigationController; |
27 import org.chromium.content.browser.ContentViewCore; | 11 //import org.chromium.content_public.browser.WebContents; |
28 import org.chromium.content.browser.ContentViewRenderView; | 12 //import org.chromium.ui.base.WindowAndroid; |
29 import org.chromium.content_public.browser.LoadUrlParams; | 13 |
30 import org.chromium.content_public.browser.NavigationController; | 14 //import org.chromium.ui.PlatformWindowAndroid; |
31 import org.chromium.content_public.browser.WebContents; | |
32 import org.chromium.ui.base.WindowAndroid; | |
33 | 15 |
34 /** | 16 /** |
35 * Container for the various UI components that make up a shell window. | 17 * Container for the various UI components that make up a shell window. |
36 */ | 18 */ |
37 @JNINamespace("content") | 19 @JNINamespace("content") |
38 public class Shell extends LinearLayout { | 20 public class Shell { |
39 | 21 |
40 private static final long COMPLETED_PROGRESS_TIMEOUT_MS = 200; | 22 // private WebContents mWebContents; |
41 | 23 // private NavigationController mNavigationController; |
42 private final Runnable mClearProgressRunnable = new Runnable() { | |
43 @Override | |
44 public void run() { | |
45 mProgressDrawable.setLevel(0); | |
46 } | |
47 }; | |
48 | |
49 private ContentViewCore mContentViewCore; | |
50 private WebContents mWebContents; | |
51 private NavigationController mNavigationController; | |
52 private ContentViewClient mContentViewClient; | |
53 private EditText mUrlTextView; | |
54 private ImageButton mPrevButton; | |
55 private ImageButton mNextButton; | |
56 private ImageButton mStopReloadButton; | |
57 | |
58 private ClipDrawable mProgressDrawable; | |
59 | 24 |
60 private long mNativeShell; | 25 private long mNativeShell; |
61 private ContentViewRenderView mContentViewRenderView; | |
62 private WindowAndroid mWindow; | |
63 | 26 |
64 private boolean mLoading = false; | 27 private boolean mLoading = false; |
65 private boolean mIsFullscreen = false; | 28 private boolean mIsFullscreen = false; |
66 | 29 |
67 /** | 30 /** |
68 * Constructor for inflating via XML. | 31 * Constructor for inflating via XML. |
69 */ | 32 */ |
70 public Shell(Context context, AttributeSet attrs) { | 33 public Shell() { |
71 super(context, attrs); | |
72 } | 34 } |
73 | 35 |
74 /** | 36 /** |
75 * Set the SurfaceView being renderered to as soon as it is available. | 37 * Set the SurfaceView being renderered to as soon as it is available. |
76 */ | 38 */ |
77 public void setContentViewRenderView(ContentViewRenderView contentViewRender
View) { | 39 // public void setPlatformWindowAndroid(PlatformWindowAndroid platformWindowA
ndroid) { |
78 FrameLayout contentViewHolder = (FrameLayout) findViewById(R.id.contentv
iew_holder); | 40 // FrameLayout contentViewHolder = (FrameLayout) findViewById(R.id.conten
tview_holder); |
79 if (contentViewRenderView == null) { | 41 // if (contentViewRenderView == null) { |
80 if (mContentViewRenderView != null) { | 42 // if (mPlatformWindowAndroid != null) { |
81 contentViewHolder.removeView(mContentViewRenderView); | 43 // contentViewHolder.removeView(mPlatformWindowAndroid); |
82 } | 44 // } |
83 } else { | 45 // } else { |
84 contentViewHolder.addView(contentViewRenderView, | 46 // contentViewHolder.addView(platformWindowAndroid, |
85 new FrameLayout.LayoutParams( | 47 // new FrameLayout.LayoutParams( |
86 FrameLayout.LayoutParams.MATCH_PARENT, | 48 // FrameLayout.LayoutParams.MATCH_PARENT, |
87 FrameLayout.LayoutParams.MATCH_PARENT)); | 49 // FrameLayout.LayoutParams.MATCH_PARENT)); |
88 } | 50 // } |
89 mContentViewRenderView = contentViewRenderView; | 51 // mPlatformWindowAndroid = platformWindowAndroid; |
90 } | 52 // } |
91 | 53 |
92 /** | 54 /** |
93 * Initializes the Shell for use. | 55 * Initializes the Shell for use. |
94 * | 56 * |
95 * @param nativeShell The pointer to the native Shell object. | 57 * @param nativeShell The pointer to the native Shell object. |
96 * @param window The owning window for this shell. | |
97 * @param client The {@link ContentViewClient} to be bound to any current or
new | |
98 * {@link ContentViewCore}s associated with this shell. | |
99 */ | 58 */ |
100 public void initialize(long nativeShell, WindowAndroid window, ContentViewCl
ient client) { | 59 public void initialize(long nativeShell) { |
101 mNativeShell = nativeShell; | 60 mNativeShell = nativeShell; |
102 mWindow = window; | |
103 mContentViewClient = client; | |
104 } | 61 } |
105 | 62 |
106 /** | 63 /** |
107 * Closes the shell and cleans up the native instance, which will handle des
troying all | 64 * Closes the shell and cleans up the native instance, which will handle des
troying all |
108 * dependencies. | 65 * dependencies. |
109 */ | 66 */ |
110 public void close() { | 67 public void close() { |
111 if (mNativeShell == 0) return; | 68 if (mNativeShell == 0) return; |
112 nativeCloseShell(mNativeShell); | 69 nativeCloseShell(mNativeShell); |
113 } | 70 } |
114 | 71 |
115 @CalledByNative | 72 @CalledByNative |
116 private void onNativeDestroyed() { | 73 private void onNativeDestroyed() { |
117 mWindow = null; | |
118 mNativeShell = 0; | 74 mNativeShell = 0; |
119 mContentViewCore.destroy(); | |
120 } | 75 } |
121 | 76 |
122 /** | 77 /** |
123 * @return Whether the Shell has been destroyed. | 78 * @return Whether the Shell has been destroyed. |
124 * @see #onNativeDestroyed() | 79 * @see #onNativeDestroyed() |
125 */ | 80 */ |
126 public boolean isDestroyed() { | 81 public boolean isDestroyed() { |
127 return mNativeShell == 0; | 82 return mNativeShell == 0; |
128 } | 83 } |
129 | 84 |
130 /** | 85 /** |
131 * @return Whether or not the Shell is loading content. | 86 * @return Whether or not the Shell is loading content. |
132 */ | 87 */ |
133 public boolean isLoading() { | 88 public boolean isLoading() { |
134 return mLoading; | 89 return mLoading; |
135 } | 90 } |
136 | 91 |
137 @Override | |
138 protected void onFinishInflate() { | |
139 super.onFinishInflate(); | |
140 | |
141 mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackgro
und(); | |
142 initializeUrlField(); | |
143 initializeNavigationButtons(); | |
144 } | |
145 | |
146 private void initializeUrlField() { | |
147 mUrlTextView = (EditText) findViewById(R.id.url); | |
148 mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() { | |
149 @Override | |
150 public boolean onEditorAction(TextView v, int actionId, KeyEvent eve
nt) { | |
151 if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null | |
152 || event.getKeyCode() != KeyEvent.KEYCODE_ENTER | |
153 || event.getAction() != KeyEvent.ACTION_DOWN)) { | |
154 return false; | |
155 } | |
156 loadUrl(mUrlTextView.getText().toString()); | |
157 setKeyboardVisibilityForUrl(false); | |
158 mContentViewCore.getContainerView().requestFocus(); | |
159 return true; | |
160 } | |
161 }); | |
162 mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() { | |
163 @Override | |
164 public void onFocusChange(View v, boolean hasFocus) { | |
165 setKeyboardVisibilityForUrl(hasFocus); | |
166 mNextButton.setVisibility(hasFocus ? GONE : VISIBLE); | |
167 mPrevButton.setVisibility(hasFocus ? GONE : VISIBLE); | |
168 mStopReloadButton.setVisibility(hasFocus ? GONE : VISIBLE); | |
169 if (!hasFocus) { | |
170 mUrlTextView.setText(mWebContents.getUrl()); | |
171 } | |
172 } | |
173 }); | |
174 mUrlTextView.setOnKeyListener(new OnKeyListener() { | |
175 @Override | |
176 public boolean onKey(View v, int keyCode, KeyEvent event) { | |
177 if (keyCode == KeyEvent.KEYCODE_BACK) { | |
178 mContentViewCore.getContainerView().requestFocus(); | |
179 return true; | |
180 } | |
181 return false; | |
182 } | |
183 }); | |
184 } | |
185 | |
186 /** | 92 /** |
187 * Loads an URL. This will perform minimal amounts of sanitizing of the URL
to attempt to | 93 * Loads an URL. This will perform minimal amounts of sanitizing of the URL
to attempt to |
188 * make it valid. | 94 * make it valid. |
189 * | 95 * |
190 * @param url The URL to be loaded by the shell. | 96 * @param url The URL to be loaded by the shell. |
191 */ | 97 */ |
192 public void loadUrl(String url) { | 98 public void loadUrl(String url) { |
193 if (url == null) return; | 99 if (url == null) return; |
194 | 100 // TODO(mfomitchev): need mNavigationController for this |
195 if (TextUtils.equals(url, mWebContents.getUrl())) { | 101 // if (TextUtils.equals(url, mWebContents.getUrl())) { |
196 mNavigationController.reload(true); | 102 // mNavigationController.reload(true); |
197 } else { | 103 // } else { |
198 mNavigationController.loadUrl(new LoadUrlParams(sanitizeUrl(url))); | 104 // mNavigationController.loadUrl(new LoadUrlParams(sanitizeUrl(url)))
; |
199 } | 105 // } |
200 mUrlTextView.clearFocus(); | |
201 // TODO(aurimas): Remove this when crbug.com/174541 is fixed. | |
202 mContentViewCore.getContainerView().clearFocus(); | |
203 mContentViewCore.getContainerView().requestFocus(); | |
204 } | 106 } |
205 | 107 |
206 /** | 108 /** |
207 * Given an URL, this performs minimal sanitizing to ensure it will be valid
. | 109 * Given an URL, this performs minimal sanitizing to ensure it will be valid
. |
208 * @param url The url to be sanitized. | 110 * @param url The url to be sanitized. |
209 * @return The sanitized URL. | 111 * @return The sanitized URL. |
210 */ | 112 */ |
211 public static String sanitizeUrl(String url) { | 113 public static String sanitizeUrl(String url) { |
212 if (url == null) return null; | 114 if (url == null) return null; |
213 if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" +
url; | 115 if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" +
url; |
214 return url; | 116 return url; |
215 } | 117 } |
216 | 118 |
217 private void initializeNavigationButtons() { | 119 // @CalledByNative |
218 mPrevButton = (ImageButton) findViewById(R.id.prev); | 120 // private void toggleFullscreenModeForTab(boolean enterFullscreen) { |
219 mPrevButton.setOnClickListener(new OnClickListener() { | 121 // mIsFullscreen = enterFullscreen; |
220 @Override | 122 // LinearLayout toolBar = (LinearLayout) findViewById(R.id.toolbar); |
221 public void onClick(View v) { | 123 // toolBar.setVisibility(enterFullscreen ? GONE : VISIBLE); |
222 if (mNavigationController.canGoBack()) mNavigationController.goB
ack(); | 124 // } |
223 } | |
224 }); | |
225 | 125 |
226 mNextButton = (ImageButton) findViewById(R.id.next); | 126 // @CalledByNative |
227 mNextButton.setOnClickListener(new OnClickListener() { | 127 // private boolean isFullscreenForTabOrPending() { |
228 @Override | 128 // return mIsFullscreen; |
229 public void onClick(View v) { | 129 // } |
230 if (mNavigationController.canGoForward()) mNavigationController.
goForward(); | |
231 } | |
232 }); | |
233 mStopReloadButton = (ImageButton) findViewById(R.id.stop_reload_button); | |
234 mStopReloadButton.setOnClickListener(new OnClickListener() { | |
235 @Override | |
236 public void onClick(View v) { | |
237 if (mLoading) mWebContents.stop(); | |
238 else mNavigationController.reload(true); | |
239 } | |
240 }); | |
241 } | |
242 | 130 |
243 @SuppressWarnings("unused") | 131 // @SuppressWarnings("unused") |
244 @CalledByNative | 132 // @CalledByNative |
245 private void onUpdateUrl(String url) { | 133 // private void setIsLoading(boolean loading) { |
246 mUrlTextView.setText(url); | 134 // mLoading = loading; |
247 } | 135 // if (mLoading) { |
| 136 // mStopReloadButton |
| 137 // .setImageResource(android.R.drawable.ic_menu_close_clear_c
ancel); |
| 138 // } else { |
| 139 // mStopReloadButton.setImageResource(R.drawable.ic_refresh); |
| 140 // } |
| 141 // } |
248 | 142 |
249 @SuppressWarnings("unused") | 143 // /** |
250 @CalledByNative | 144 // * Initializes the ContentView based on the native tab contents pointer pa
ssed in. |
251 private void onLoadProgressChanged(double progress) { | 145 // * @param webContents A {@link WebContents} object. |
252 removeCallbacks(mClearProgressRunnable); | 146 // */ |
253 mProgressDrawable.setLevel((int) (10000.0 * progress)); | 147 // @SuppressWarnings("unused") |
254 if (progress == 1.0) postDelayed(mClearProgressRunnable, COMPLETED_PROGR
ESS_TIMEOUT_MS); | 148 // @CalledByNative |
255 } | 149 // private void initFromNativeTabContents(WebContents webContents) { |
| 150 // Context context = getContext(); |
| 151 // mContentViewCore = new ContentViewCore(context); |
| 152 // ContentView cv = new ContentView(context, mContentViewCore); |
| 153 // mContentViewCore.initialize(cv, cv, webContents, mWindow); |
| 154 // mContentViewCore.setContentViewClient(mContentViewClient); |
| 155 // mWebContents = mContentViewCore.getWebContents(); |
| 156 // mNavigationController = mWebContents.getNavigationController(); |
| 157 // if (getParent() != null) mContentViewCore.onShow(); |
| 158 // if (mWebContents.getUrl() != null) { |
| 159 // mUrlTextView.setText(mWebContents.getUrl()); |
| 160 // } |
| 161 // ((FrameLayout) findViewById(R.id.contentview_holder)).addView(cv, |
| 162 // new FrameLayout.LayoutParams( |
| 163 // FrameLayout.LayoutParams.MATCH_PARENT, |
| 164 // FrameLayout.LayoutParams.MATCH_PARENT)); |
| 165 // cv.requestFocus(); |
| 166 // mContentViewRenderView.setCurrentContentViewCore(mContentViewCore); |
| 167 // } |
256 | 168 |
257 @CalledByNative | 169 // /** |
258 private void toggleFullscreenModeForTab(boolean enterFullscreen) { | 170 // * Enable/Disable navigation(Prev/Next) button if navigation is allowed/di
sallowed |
259 mIsFullscreen = enterFullscreen; | 171 // * in respective direction. |
260 LinearLayout toolBar = (LinearLayout) findViewById(R.id.toolbar); | 172 // * @param controlId Id of button to update |
261 toolBar.setVisibility(enterFullscreen ? GONE : VISIBLE); | 173 // * @param enabled enable/disable value |
262 } | 174 // */ |
| 175 // @CalledByNative |
| 176 // private void enableUiControl(int controlId, boolean enabled) { |
| 177 // if (controlId == 0) { |
| 178 // mPrevButton.setEnabled(enabled); |
| 179 // } else if (controlId == 1) { |
| 180 // mNextButton.setEnabled(enabled); |
| 181 // } |
| 182 // } |
263 | 183 |
264 @CalledByNative | 184 // /** |
265 private boolean isFullscreenForTabOrPending() { | 185 // * @return The {@link WebContents} currently managing the content shown by
this Shell. |
266 return mIsFullscreen; | 186 // */ |
267 } | 187 // public WebContents getWebContents() { |
| 188 // return mWebContents; |
| 189 // } |
268 | 190 |
269 @SuppressWarnings("unused") | 191 // private void setKeyboardVisibilityForUrl(boolean visible) { |
270 @CalledByNative | 192 // InputMethodManager imm = (InputMethodManager) getContext().getSystemSe
rvice( |
271 private void setIsLoading(boolean loading) { | 193 // Context.INPUT_METHOD_SERVICE); |
272 mLoading = loading; | 194 // if (visible) { |
273 if (mLoading) { | 195 // imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT); |
274 mStopReloadButton | 196 // } else { |
275 .setImageResource(android.R.drawable.ic_menu_close_clear_can
cel); | 197 // imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0); |
276 } else { | 198 // } |
277 mStopReloadButton.setImageResource(R.drawable.ic_refresh); | 199 // } |
278 } | |
279 } | |
280 | |
281 /** | |
282 * Initializes the ContentView based on the native tab contents pointer pass
ed in. | |
283 * @param webContents A {@link WebContents} object. | |
284 */ | |
285 @SuppressWarnings("unused") | |
286 @CalledByNative | |
287 private void initFromNativeTabContents(WebContents webContents) { | |
288 Context context = getContext(); | |
289 mContentViewCore = new ContentViewCore(context); | |
290 ContentView cv = new ContentView(context, mContentViewCore); | |
291 mContentViewCore.initialize(cv, cv, webContents, mWindow); | |
292 mContentViewCore.setContentViewClient(mContentViewClient); | |
293 mWebContents = mContentViewCore.getWebContents(); | |
294 mNavigationController = mWebContents.getNavigationController(); | |
295 if (getParent() != null) mContentViewCore.onShow(); | |
296 if (mWebContents.getUrl() != null) { | |
297 mUrlTextView.setText(mWebContents.getUrl()); | |
298 } | |
299 ((FrameLayout) findViewById(R.id.contentview_holder)).addView(cv, | |
300 new FrameLayout.LayoutParams( | |
301 FrameLayout.LayoutParams.MATCH_PARENT, | |
302 FrameLayout.LayoutParams.MATCH_PARENT)); | |
303 cv.requestFocus(); | |
304 mContentViewRenderView.setCurrentContentViewCore(mContentViewCore); | |
305 } | |
306 | |
307 /** | |
308 * Enable/Disable navigation(Prev/Next) button if navigation is allowed/disa
llowed | |
309 * in respective direction. | |
310 * @param controlId Id of button to update | |
311 * @param enabled enable/disable value | |
312 */ | |
313 @CalledByNative | |
314 private void enableUiControl(int controlId, boolean enabled) { | |
315 if (controlId == 0) { | |
316 mPrevButton.setEnabled(enabled); | |
317 } else if (controlId == 1) { | |
318 mNextButton.setEnabled(enabled); | |
319 } | |
320 } | |
321 | |
322 /** | |
323 * @return The {@link ViewGroup} currently shown by this Shell. | |
324 */ | |
325 public ViewGroup getContentView() { | |
326 return mContentViewCore.getContainerView(); | |
327 } | |
328 | |
329 /** | |
330 * @return The {@link ContentViewCore} currently managing the view shown by
this Shell. | |
331 */ | |
332 public ContentViewCore getContentViewCore() { | |
333 return mContentViewCore; | |
334 } | |
335 | |
336 /** | |
337 * @return The {@link WebContents} currently managing the content shown by t
his Shell. | |
338 */ | |
339 public WebContents getWebContents() { | |
340 return mWebContents; | |
341 } | |
342 | |
343 private void setKeyboardVisibilityForUrl(boolean visible) { | |
344 InputMethodManager imm = (InputMethodManager) getContext().getSystemServ
ice( | |
345 Context.INPUT_METHOD_SERVICE); | |
346 if (visible) { | |
347 imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT); | |
348 } else { | |
349 imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0); | |
350 } | |
351 } | |
352 | 200 |
353 private static native void nativeCloseShell(long shellPtr); | 201 private static native void nativeCloseShell(long shellPtr); |
354 } | 202 } |
OLD | NEW |