| 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 |