| 1 | // Copyright (c) 2012 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.content.browser; |
| 6 | |
| 7 | import android.content.ActivityNotFoundException; |
| 8 | import android.content.Context; |
| 9 | import android.content.Intent; |
| 10 | import android.graphics.RectF; |
| 11 | import android.util.Log; |
| 12 | import android.view.ActionMode; |
| 13 | import android.view.KeyEvent; |
| 14 | |
| 15 | import org.chromium.content.browser.SelectActionModeCallback.ActionHandler; |
| 16 | |
| 17 | import java.net.URISyntaxException; |
| 18 | |
| 19 | /** |
| 20 | * Main callback class used by ContentView. |
| 21 | * |
| 22 | * This contains the superset of callbacks required to implement the browser UI and the callbacks |
| 23 | * required to implement the WebView API. |
| 24 | * The memory and reference ownership of this class is unusual - see the .cc file and ContentView |
| 25 | * for more details. |
| 26 | * |
| 27 | * TODO(mkosiba): Rid this guy of default implementations. This class is used by both WebView and |
| 28 | * the browser and we don't want a the browser-specific default implementation to accidentally leak |
| 29 | * over to WebView. |
| 30 | */ |
| 31 | public class ContentViewClient { |
| 32 | // Tag used for logging. |
| 33 | private static final String TAG = "ContentViewClient"; |
| 34 | |
| 35 | public void onUpdateTitle(String title) { |
| 36 | } |
| 37 | |
| 38 | /** |
| 39 | * Called whenever the background color of the page changes as notified by WebKit. |
| 40 | * @param color The new ARGB color of the page background. |
| 41 | */ |
| 42 | public void onBackgroundColorChanged(int color) { |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * Lets client listen on the scaling changes on delayed, throttled |
| 47 | * and best-effort basis. Used for WebView.onScaleChanged. |
| 48 | */ |
| 49 | public void onScaleChanged(float oldScale, float newScale) { |
| 50 | } |
| 51 | |
| 52 | /** |
| 53 | * Notifies the client that the position of the top controls has changed. |
| 54 | * @param topControlsOffsetYPix The Y offset of the top controls in physical pixels. |
| 55 | * @param contentOffsetYPix The Y offset of the content in physical pixels. |
| 56 | * @param overdrawBottomHeightPix The overdraw height. |
| 57 | */ |
| 58 | public void onOffsetsForFullscreenChanged( |
| 59 | float topControlsOffsetYPix, float contentOffsetYPix, float overdrawBottomHeightPix) { |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Notifies the client that the renderer backing the ContentView has crashed. |
| 64 | * @param crashedWhileOomProtected True iff the renderer died while being bound with a high |
| 65 | * priority binding, which indicates that it was probably an actual crash (as opposed to the |
| 66 | * renderer being killed by the OS out-of-memory killer). |
| 67 | */ |
| 68 | public void onRendererCrash(boolean processWasOomProtected) { |
| 69 | } |
| 70 | |
| 71 | public boolean shouldOverrideKeyEvent(KeyEvent event) { |
| 72 | int keyCode = event.getKeyCode(); |
| 73 | // We need to send almost every key to WebKit. However: |
| 74 | // 1. We don't want to block the device on the renderer for |
| 75 | // some keys like menu, home, call. |
| 76 | // 2. There are no WebKit equivalents for some of these keys |
| 77 | // (see app/keyboard_codes_win.h) |
| 78 | // Note that these are not the same set as KeyEvent.isSystemKey: |
| 79 | // for instance, AKEYCODE_MEDIA_* will be dispatched to webkit. |
| 80 | if (keyCode == KeyEvent.KEYCODE_MENU || |
| 81 | keyCode == KeyEvent.KEYCODE_HOME || |
| 82 | keyCode == KeyEvent.KEYCODE_BACK || |
| 83 | keyCode == KeyEvent.KEYCODE_CALL || |
| 84 | keyCode == KeyEvent.KEYCODE_ENDCALL || |
| 85 | keyCode == KeyEvent.KEYCODE_POWER || |
| 86 | keyCode == KeyEvent.KEYCODE_HEADSETHOOK || |
| 87 | keyCode == KeyEvent.KEYCODE_CAMERA || |
| 88 | keyCode == KeyEvent.KEYCODE_FOCUS || |
| 89 | keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || |
| 90 | keyCode == KeyEvent.KEYCODE_VOLUME_MUTE || |
| 91 | keyCode == KeyEvent.KEYCODE_VOLUME_UP) { |
| 92 | return true; |
| 93 | } |
| 94 | |
| 95 | // We also have to intercept some shortcuts before we send them to the ContentView. |
| 96 | if (event.isCtrlPressed() && ( |
| 97 | keyCode == KeyEvent.KEYCODE_TAB || |
| 98 | keyCode == KeyEvent.KEYCODE_W || |
| 99 | keyCode == KeyEvent.KEYCODE_F4)) { |
| 100 | return true; |
| 101 | } |
| 102 | |
| 103 | return false; |
| 104 | } |
| 105 | |
| 106 | // Called when an ImeEvent is sent to the page. Can be used to know when some text is entered |
| 107 | // in a page. |
| 108 | public void onImeEvent() { |
| 109 | } |
| 110 | |
| 111 | /** |
| 112 | * Notified when a change to the IME was requested. |
| 113 | * |
| 114 | * @param requestShow Whether the IME was requested to be shown (may already be showing |
| 115 | * though). |
| 116 | */ |
| 117 | public void onImeStateChangeRequested(boolean requestShow) { |
| 118 | } |
| 119 | |
| 120 | // TODO (dtrainor): Should expose getScrollX/Y from ContentView or make |
| 121 | // computeHorizontalScrollOffset()/computeVerticalScrollOffset() public. |
| 122 | /** |
| 123 | * Gives the UI the chance to override each scroll event. |
| 124 | * @param dx The amount scrolled in the X direction (in physical pixels). |
| 125 | * @param dy The amount scrolled in the Y direction (in physical pixels). |
| 126 | * @param scrollX The current X scroll offset (in physical pixels). |
| 127 | * @param scrollY The current Y scroll offset (in physical pixels). |
| 128 | * @return Whether or not the UI consumed and handled this event. |
| 129 | */ |
| 130 | public boolean shouldOverrideScroll(float dx, float dy, float scrollX, float scrollY) { |
| 131 | return false; |
| 132 | } |
| 133 | |
| 134 | /** |
| 135 | * Returns an ActionMode.Callback for in-page selection. |
| 136 | */ |
| 137 | public ActionMode.Callback getSelectActionModeCallback( |
| 138 | Context context, ActionHandler actionHandler, boolean incognito) { |
| 139 | return new SelectActionModeCallback(context, actionHandler, incognito); |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Called when the contextual ActionBar is shown. |
| 144 | */ |
| 145 | public void onContextualActionBarShown() { |
| 146 | } |
| 147 | |
| 148 | /** |
| 149 | * Called when the contextual ActionBar is hidden. |
| 150 | */ |
| 151 | public void onContextualActionBarHidden() { |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Called when a new content intent is requested to be started. |
| 156 | */ |
| 157 | public void onStartContentIntent(Context context, String intentUrl) { |
| 158 | Intent intent; |
| 159 | // Perform generic parsing of the URI to turn it into an Intent. |
| 160 | try { |
| 161 | intent = Intent.parseUri(intentUrl, Intent.URI_INTENT_SCHEME); |
| 162 | } catch (URISyntaxException ex) { |
| 163 | Log.w(TAG, "Bad URI " + intentUrl + ": " + ex.getMessage()); |
| 164 | return; |
| 165 | } |
| 166 | |
| 167 | try { |
| 168 | context.startActivity(intent); |
| 169 | } catch (ActivityNotFoundException ex) { |
| 170 | Log.w(TAG, "No application can handle " + intentUrl); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | public void onExternalVideoSurfaceRequested(int playerId) { |
| 175 | } |
| 176 | |
| 177 | public void onGeometryChanged(int playerId, RectF rect) { |
| 178 | } |
| 179 | |
| 180 | public ContentVideoViewClient getContentVideoViewClient() { |
| 181 | return null; |
| 182 | } |
| 183 | } |