diff options
author | Andras Becsi <andras.becsi@digia.com> | 2014-03-18 13:16:26 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-03-20 15:55:39 +0100 |
commit | 3f0f86b0caed75241fa71c95a5d73bc0164348c5 (patch) | |
tree | 92b9fb00f2e9e90b0be2262093876d4f43b6cd13 /chromium/content/browser/android | |
parent | e90d7c4b152c56919d963987e2503f9909a666d2 (diff) |
Update to new stable branch 1750
This also includes an updated ninja and chromium dependencies
needed on Windows.
Change-Id: Icd597d80ed3fa4425933c9f1334c3c2e31291c42
Reviewed-by: Zoltan Arvai <zarvai@inf.u-szeged.hu>
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'chromium/content/browser/android')
36 files changed, 1000 insertions, 751 deletions
diff --git a/chromium/content/browser/android/OWNERS b/chromium/content/browser/android/OWNERS index a5cf4a90179..4fd5d774a7c 100644 --- a/chromium/content/browser/android/OWNERS +++ b/chromium/content/browser/android/OWNERS @@ -1,5 +1,8 @@ bulach@chromium.org -joth@chromium.org +sievers@chromium.org +skyostil@chromium.org tedchoc@chromium.org yfriedman@chromium.org -sievers@chromium.org + +# Input handling related +jdduke@chromium.org diff --git a/chromium/content/browser/android/child_process_launcher_android.cc b/chromium/content/browser/android/child_process_launcher_android.cc index 962fee861f7..cf915e4a42a 100644 --- a/chromium/content/browser/android/child_process_launcher_android.cc +++ b/chromium/content/browser/android/child_process_launcher_android.cc @@ -70,7 +70,7 @@ static void SetSurfacePeer( // the ChildProcess could not be created. static void OnChildProcessStarted(JNIEnv*, jclass, - jint client_context, + jlong client_context, jint handle) { StartChildProcessCallback* callback = reinterpret_cast<StartChildProcessCallback*>(client_context); @@ -122,7 +122,7 @@ void StartChildProcess( j_file_ids.obj(), j_file_fds.obj(), j_file_auto_close.obj(), - reinterpret_cast<jint>(new StartChildProcessCallback(callback))); + reinterpret_cast<intptr_t>(new StartChildProcessCallback(callback))); } void StopChildProcess(base::ProcessHandle handle) { @@ -131,6 +131,13 @@ void StopChildProcess(base::ProcessHandle handle) { Java_ChildProcessLauncher_stop(env, static_cast<jint>(handle)); } +bool IsChildProcessOomProtected(base::ProcessHandle handle) { + JNIEnv* env = AttachCurrentThread(); + DCHECK(env); + return Java_ChildProcessLauncher_isOomProtected(env, + static_cast<jint>(handle)); +} + void EstablishSurfacePeer( JNIEnv* env, jclass clazz, jint pid, jobject surface, jint primary_id, jint secondary_id) { diff --git a/chromium/content/browser/android/child_process_launcher_android.h b/chromium/content/browser/android/child_process_launcher_android.h index b90ff2338c6..71a6f04c712 100644 --- a/chromium/content/browser/android/child_process_launcher_android.h +++ b/chromium/content/browser/android/child_process_launcher_android.h @@ -29,6 +29,8 @@ void StartChildProcess( // StartChildProcess. void StopChildProcess(base::ProcessHandle handle); +bool IsChildProcessOomProtected(base::ProcessHandle handle); + bool RegisterChildProcessLauncher(JNIEnv* env); } // namespace content diff --git a/chromium/content/browser/android/content_settings.cc b/chromium/content/browser/android/content_settings.cc index d087d6bd2c2..7c6407fd177 100644 --- a/chromium/content/browser/android/content_settings.cc +++ b/chromium/content/browser/android/content_settings.cc @@ -26,7 +26,7 @@ ContentSettings::~ContentSettings() { ScopedJavaLocalRef<jobject> obj = content_settings_.get(env); if (obj.obj()) { Java_ContentSettings_onNativeContentSettingsDestroyed(env, obj.obj(), - reinterpret_cast<jint>(this)); + reinterpret_cast<intptr_t>(this)); } } @@ -46,13 +46,13 @@ void ContentSettings::WebContentsDestroyed(WebContents* web_contents) { delete this; } -static jint Init(JNIEnv* env, jobject obj, jint nativeContentViewCore) { +static jlong Init(JNIEnv* env, jobject obj, jlong nativeContentViewCore) { WebContents* web_contents = reinterpret_cast<ContentViewCoreImpl*>(nativeContentViewCore) ->GetWebContents(); ContentSettings* content_settings = new ContentSettings(env, obj, web_contents); - return reinterpret_cast<jint>(content_settings); + return reinterpret_cast<intptr_t>(content_settings); } } // namespace content diff --git a/chromium/content/browser/android/content_startup_flags.cc b/chromium/content/browser/android/content_startup_flags.cc index b755e4dc783..7d950343443 100644 --- a/chromium/content/browser/android/content_startup_flags.cc +++ b/chromium/content/browser/android/content_startup_flags.cc @@ -4,6 +4,7 @@ #include "content/browser/android/content_startup_flags.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" @@ -60,32 +61,41 @@ void SetContentCommandLineFlags(int max_render_process_count, parsed_command_line->AppendSwitch(switches::kEnableBeginFrameScheduling); parsed_command_line->AppendSwitch(switches::kEnableDeadlineScheduling); + parsed_command_line->AppendSwitch(switches::kDisableGestureDebounce); parsed_command_line->AppendSwitch(switches::kEnableGestureTapHighlight); parsed_command_line->AppendSwitch(switches::kEnablePinch); parsed_command_line->AppendSwitch(switches::kEnableOverlayFullscreenVideo); parsed_command_line->AppendSwitch(switches::kEnableOverlayScrollbars); parsed_command_line->AppendSwitch(switches::kEnableOverscrollNotifications); + parsed_command_line->AppendSwitchASCII(switches::kTouchAckTimeoutDelayMs, + "200"); // Run the GPU service as a thread in the browser instead of as a // standalone process. parsed_command_line->AppendSwitch(switches::kInProcessGPU); parsed_command_line->AppendSwitch(switches::kDisableGpuShaderDiskCache); - // Always use fixed layout and viewport tag. - parsed_command_line->AppendSwitch(switches::kEnableFixedLayout); parsed_command_line->AppendSwitch(switches::kEnableViewport); - - // Disable <canvas> path antialiasing. - parsed_command_line->AppendSwitch(switches::kDisable2dCanvasAntialiasing); + parsed_command_line->AppendSwitch(switches::kEnableViewportMeta); + parsed_command_line->AppendSwitch( + switches::kMainFrameResizesAreOrientationChanges); // Disable anti-aliasing. parsed_command_line->AppendSwitch( cc::switches::kDisableCompositedAntialiasing); + parsed_command_line->AppendSwitch(switches::kUIPrioritizeInGpuProcess); + if (!plugin_descriptor.empty()) { parsed_command_line->AppendSwitchNative( switches::kRegisterPepperPlugins, plugin_descriptor); } + + // Disable profiler timing by default. + if (!parsed_command_line->HasSwitch(switches::kProfilerTiming)) { + parsed_command_line->AppendSwitchASCII( + switches::kProfilerTiming, switches::kProfilerTimingDisabledValue); + } } } // namespace content diff --git a/chromium/content/browser/android/content_video_view.cc b/chromium/content/browser/android/content_video_view.cc index b8d5c64d542..9ee541aab0d 100644 --- a/chromium/content/browser/android/content_video_view.cc +++ b/chromium/content/browser/android/content_video_view.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "content/browser/media/android/browser_media_player_manager.h" +#include "content/browser/power_save_blocker_impl.h" #include "content/common/android/surface_texture_peer.h" #include "content/public/common/content_switches.h" #include "jni/ContentVideoView_jni.h" @@ -48,8 +49,9 @@ ContentVideoView::ContentVideoView( JNIEnv *env = AttachCurrentThread(); j_content_video_view_ = JavaObjectWeakGlobalRef(env, Java_ContentVideoView_createContentVideoView(env, context.obj(), - reinterpret_cast<int>(this), client.obj()).obj()); + reinterpret_cast<intptr_t>(this), client.obj()).obj()); g_content_video_view = this; + CreatePowerSaveBlocker(); } ContentVideoView::~ContentVideoView() { @@ -59,23 +61,26 @@ ContentVideoView::~ContentVideoView() { } void ContentVideoView::OpenVideo() { - JNIEnv *env = AttachCurrentThread(); + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); - if (!content_video_view.is_null()) + if (!content_video_view.is_null()) { + CreatePowerSaveBlocker(); Java_ContentVideoView_openVideo(env, content_video_view.obj()); + } } void ContentVideoView::OnMediaPlayerError(int error_type) { - JNIEnv *env = AttachCurrentThread(); + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); if (!content_video_view.is_null()) { + power_save_blocker_.reset(); Java_ContentVideoView_onMediaPlayerError(env, content_video_view.obj(), error_type); } } void ContentVideoView::OnVideoSizeChanged(int width, int height) { - JNIEnv *env = AttachCurrentThread(); + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); if (!content_video_view.is_null()) { Java_ContentVideoView_onVideoSizeChanged(env, content_video_view.obj(), @@ -84,7 +89,7 @@ void ContentVideoView::OnVideoSizeChanged(int width, int height) { } void ContentVideoView::OnBufferingUpdate(int percent) { - JNIEnv *env = AttachCurrentThread(); + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); if (!content_video_view.is_null()) { Java_ContentVideoView_onBufferingUpdate(env, content_video_view.obj(), @@ -93,10 +98,12 @@ void ContentVideoView::OnBufferingUpdate(int percent) { } void ContentVideoView::OnPlaybackComplete() { - JNIEnv *env = AttachCurrentThread(); + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); - if (!content_video_view.is_null()) + if (!content_video_view.is_null()) { + power_save_blocker_.reset(); Java_ContentVideoView_onPlaybackComplete(env, content_video_view.obj()); + } } void ContentVideoView::OnExitFullscreen() { @@ -104,7 +111,7 @@ void ContentVideoView::OnExitFullscreen() { } void ContentVideoView::UpdateMediaMetadata() { - JNIEnv *env = AttachCurrentThread(); + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); if (!content_video_view.is_null()) UpdateMediaMetadata(env, content_video_view.obj()); @@ -140,15 +147,18 @@ void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) { } void ContentVideoView::Play(JNIEnv*, jobject obj) { + CreatePowerSaveBlocker(); manager_->FullscreenPlayerPlay(); } void ContentVideoView::Pause(JNIEnv*, jobject obj) { + power_save_blocker_.reset(); manager_->FullscreenPlayerPause(); } void ContentVideoView::ExitFullscreen( JNIEnv*, jobject, jboolean release_media_player) { + power_save_blocker_.reset(); j_content_video_view_.reset(); manager_->ExitFullscreen(release_media_player); } @@ -172,10 +182,33 @@ ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) { return j_content_video_view_.get(env); } +gfx::NativeView ContentVideoView::GetNativeView() { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); + if (content_video_view.is_null()) + return NULL; + + return reinterpret_cast<gfx::NativeView>( + Java_ContentVideoView_getNativeViewAndroid(env, + content_video_view.obj())); + +} + +void ContentVideoView::CreatePowerSaveBlocker() { + if (power_save_blocker_) return; + + power_save_blocker_ = PowerSaveBlocker::Create( + PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, + "Playing video").Pass(); + static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())-> + InitDisplaySleepBlocker(GetNativeView()); +} + void ContentVideoView::DestroyContentVideoView(bool native_view_destroyed) { - JNIEnv *env = AttachCurrentThread(); + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); if (!content_video_view.is_null()) { + j_content_video_view_.reset(); Java_ContentVideoView_destroyContentVideoView(env, content_video_view.obj(), native_view_destroyed); j_content_video_view_.reset(); diff --git a/chromium/content/browser/android/content_video_view.h b/chromium/content/browser/android/content_video_view.h index 2a86830def3..633b9031fbf 100644 --- a/chromium/content/browser/android/content_video_view.h +++ b/chromium/content/browser/android/content_video_view.h @@ -13,10 +13,12 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/timer/timer.h" +#include "ui/gfx/native_widget_types.h" namespace content { class BrowserMediaPlayerManager; +class PowerSaveBlocker; // Native mirror of ContentVideoView.java. This class is responsible for // creating the Java video view and pass all the player status change to @@ -80,10 +82,23 @@ class ContentVideoView { // no further calls to the native object is allowed. void DestroyContentVideoView(bool native_view_destroyed); + // Returns the associated NativeView + gfx::NativeView GetNativeView(); + + void CreatePowerSaveBlocker(); + // Object that manages the fullscreen media player. It is responsible for // handling all the playback controls. BrowserMediaPlayerManager* manager_; + // PowerSaveBlock to keep screen on for fullscreen video. + // There is already blocker when inline video started, and it requires the + // ContentView's container displayed to take effect; but in WebView, apps + // could use another container to hold ContentVideoView, and the blocker in + // ContentView's container can not keep screen on; so we need another blocker + // here, it is no harm, just an additonal blocker. + scoped_ptr<PowerSaveBlocker> power_save_blocker_; + // Weak reference of corresponding Java object. JavaObjectWeakGlobalRef j_content_video_view_; diff --git a/chromium/content/browser/android/content_view_core_impl.cc b/chromium/content/browser/android/content_view_core_impl.cc index dd15c1f67b8..f5450f45110 100644 --- a/chromium/content/browser/android/content_view_core_impl.cc +++ b/chromium/content/browser/android/content_view_core_impl.cc @@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/json/json_writer.h" #include "base/logging.h" +#include "base/metrics/histogram.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "cc/layers/layer.h" @@ -18,6 +19,9 @@ #include "content/browser/android/interstitial_page_delegate_android.h" #include "content/browser/android/load_url_params.h" #include "content/browser/android/touch_point.h" +#include "content/browser/frame_host/interstitial_page_impl.h" +#include "content/browser/frame_host/navigation_controller_impl.h" +#include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/media/android/browser_media_player_manager.h" #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/input/web_input_event_builders_android.h" @@ -27,9 +31,6 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/browser/ssl/ssl_host_state.h" -#include "content/browser/web_contents/interstitial_page_impl.h" -#include "content/browser/web_contents/navigation_controller_impl.h" -#include "content/browser/web_contents/navigation_entry_impl.h" #include "content/browser/web_contents/web_contents_view_android.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" @@ -48,8 +49,8 @@ #include "jni/ContentViewCore_jni.h" #include "third_party/WebKit/public/web/WebBindings.h" #include "third_party/WebKit/public/web/WebInputEvent.h" -#include "ui/android/view_android.h" -#include "ui/android/window_android.h" +#include "ui/base/android/view_android.h" +#include "ui/base/android/window_android.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/screen.h" #include "ui/gfx/size_conversions.h" @@ -63,17 +64,20 @@ using base::android::ConvertUTF16ToJavaString; using base::android::ConvertUTF8ToJavaString; using base::android::ScopedJavaGlobalRef; using base::android::ScopedJavaLocalRef; -using WebKit::WebGestureEvent; -using WebKit::WebInputEvent; +using blink::WebGestureEvent; +using blink::WebInputEvent; // Describes the type and enabled state of a select popup item. -// Keep in sync with the value defined in SelectPopupDialog.java -enum PopupItemType { - POPUP_ITEM_TYPE_GROUP = 0, - POPUP_ITEM_TYPE_DISABLED, - POPUP_ITEM_TYPE_ENABLED +namespace { + +enum { +#define DEFINE_POPUP_ITEM_TYPE(name, value) POPUP_ITEM_TYPE_##name = value, +#include "content/browser/android/popup_item_type_list.h" +#undef DEFINE_POPUP_ITEM_TYPE }; +} //namespace + namespace content { namespace { @@ -103,7 +107,8 @@ ScopedJavaLocalRef<jobject> CreateJavaRect( static_cast<int>(rect.y()), static_cast<int>(rect.right()), static_cast<int>(rect.bottom()))); -}; +} + } // namespace // Enables a callback when the underlying WebContents is destroyed, to enable @@ -159,24 +164,21 @@ ContentViewCoreImpl::ContentViewCoreImpl(JNIEnv* env, jobject obj, WebContents* web_contents, ui::ViewAndroid* view_android, ui::WindowAndroid* window_android) - : java_ref_(env, obj), + : WebContentsObserver(web_contents), + java_ref_(env, obj), web_contents_(static_cast<WebContentsImpl*>(web_contents)), root_layer_(cc::Layer::Create()), - tab_crashed_(false), vsync_interval_(base::TimeDelta::FromMicroseconds( kDefaultVSyncIntervalMicros)), expected_browser_composite_time_(base::TimeDelta::FromMicroseconds( kDefaultVSyncIntervalMicros * kDefaultBrowserCompositeVSyncFraction)), view_android_(view_android), - window_android_(window_android) { + window_android_(window_android), + device_orientation_(0), + geolocation_needs_pause_(false) { CHECK(web_contents) << "A ContentViewCoreImpl should be created with a valid WebContents."; - // When a tab is restored (from a saved state), it does not have a renderer - // process. We treat it like the tab is crashed. If the content is loaded - // when the tab is shown, tab_crashed_ will be reset. - UpdateTabCrashedFlag(); - // TODO(leandrogracia): make use of the hardware_accelerated argument. const gfx::Display& display = @@ -202,13 +204,18 @@ ContentViewCoreImpl::~ContentViewCoreImpl() { java_ref_.reset(); if (!j_obj.is_null()) { Java_ContentViewCore_onNativeContentViewCoreDestroyed( - env, j_obj.obj(), reinterpret_cast<jint>(this)); + env, j_obj.obj(), reinterpret_cast<intptr_t>(this)); } // Make sure nobody calls back into this object while we are tearing things // down. notification_registrar_.RemoveAll(); } +base::android::ScopedJavaLocalRef<jobject> +ContentViewCoreImpl::GetWebContentsAndroid(JNIEnv* env, jobject obj) { + return web_contents_->GetJavaWebContents(); +} + void ContentViewCoreImpl::OnJavaContentViewCoreDestroyed(JNIEnv* env, jobject obj) { DCHECK(env->IsSameObject(java_ref_.get(env).obj(), obj)); @@ -219,16 +226,13 @@ void ContentViewCoreImpl::InitWebContents() { DCHECK(web_contents_); notification_registrar_.Add( this, NOTIFICATION_RENDER_VIEW_HOST_CHANGED, - Source<NavigationController>(&web_contents_->GetController())); + Source<WebContents>(web_contents_)); notification_registrar_.Add( this, NOTIFICATION_RENDERER_PROCESS_CREATED, content::NotificationService::AllBrowserContextsAndSources()); notification_registrar_.Add( this, NOTIFICATION_WEB_CONTENTS_CONNECTED, Source<WebContents>(web_contents_)); - notification_registrar_.Add( - this, NOTIFICATION_WEB_CONTENTS_SWAPPED, - Source<WebContents>(web_contents_)); static_cast<WebContentsViewAndroid*>(web_contents_->GetView())-> SetContentViewCore(this); @@ -248,6 +252,12 @@ void ContentViewCoreImpl::Observe(int type, if (switched_details->first) { old_pid = GetRenderProcessIdFromRenderViewHost( switched_details->first); + + RenderWidgetHostViewAndroid* view = + static_cast<RenderWidgetHostViewAndroid*>( + switched_details->first->GetView()); + if (view) + view->SetContentViewCore(NULL); } int new_pid = GetRenderProcessIdFromRenderViewHost( web_contents_->GetRenderViewHost()); @@ -261,6 +271,8 @@ void ContentViewCoreImpl::Observe(int type, } } SetFocusInternal(HasFocus()); + if (geolocation_needs_pause_) + PauseOrResumeGeolocation(true); break; } case NOTIFICATION_RENDERER_PROCESS_CREATED: { @@ -289,16 +301,14 @@ void ContentViewCoreImpl::Observe(int type, } break; } - case NOTIFICATION_WEB_CONTENTS_SWAPPED: { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); - if (!obj.is_null()) { - Java_ContentViewCore_onWebContentsSwapped(env, obj.obj()); - } - } } } +void ContentViewCoreImpl::RenderViewReady() { + if (device_orientation_ != 0) + SendOrientationChangeEventInternal(); +} + RenderWidgetHostViewAndroid* ContentViewCoreImpl::GetRenderWidgetHostViewAndroid() { RenderWidgetHostView* rwhv = NULL; @@ -335,9 +345,6 @@ void ContentViewCoreImpl::OnShow(JNIEnv* env, jobject obj) { void ContentViewCoreImpl::Show() { GetWebContents()->WasShown(); - // Displaying WebContents may trigger a lazy reload, spawning a new renderer - // for the tab. - UpdateTabCrashedFlag(); } void ContentViewCoreImpl::Hide() { @@ -351,24 +358,32 @@ void ContentViewCoreImpl::PauseVideo() { host->Send(new ViewMsg_PauseVideo(host->GetRoutingID())); } +void ContentViewCoreImpl::PauseOrResumeGeolocation(bool should_pause) { + geolocation_needs_pause_ = should_pause; + RenderViewHostImpl* rvh = + static_cast<RenderViewHostImpl*>(web_contents_->GetRenderViewHost()); + if (rvh) { + scoped_refptr<GeolocationDispatcherHost> geolocation_dispatcher = + static_cast<RenderProcessHostImpl*>( + web_contents_->GetRenderProcessHost())-> + geolocation_dispatcher_host(); + if (geolocation_dispatcher.get()) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&GeolocationDispatcherHost::PauseOrResume, + geolocation_dispatcher, + rvh->GetRoutingID(), + should_pause)); + geolocation_needs_pause_ = false; + } + } +} + void ContentViewCoreImpl::OnTabCrashed() { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) return; Java_ContentViewCore_resetVSyncNotification(env, obj.obj()); - - // Note that we might reach this place multiple times while the - // ContentViewCore remains crashed. E.g. if two tabs share the render process - // and the process crashes, this will be called for each tab. If the user - // reload one tab, a new render process is created and it can be shared by the - // other tab. But if user closes the reloaded tab before reloading the other - // tab, the new render process will be shut down. This will trigger the other - // tab's OnTabCrashed() called again as two tabs share the same - // BrowserRenderProcessHost. The Java side will distinguish this case using - // tab_crashed_ passed below. - Java_ContentViewCore_onTabCrash(env, obj.obj(), tab_crashed_); - tab_crashed_ = true; } // All positions and sizes are in CSS pixels. @@ -383,15 +398,19 @@ void ContentViewCoreImpl::UpdateFrameInfo( const gfx::Vector2dF& controls_offset, const gfx::Vector2dF& content_offset, float overdraw_bottom_height) { - if (window_android_) - window_android_->set_content_offset( - gfx::ScaleVector2d(content_offset, dpi_scale_)); - JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) return; + if (window_android_) { + gfx::Vector2dF window_offset( + Java_ContentViewCore_getLocationInWindowX(env, obj.obj()), + Java_ContentViewCore_getLocationInWindowY(env, obj.obj())); + window_android_->set_content_offset( + gfx::ScaleVector2d(content_offset, dpi_scale_) + window_offset); + } + Java_ContentViewCore_updateFrameInfo( env, obj.obj(), scroll_offset.x(), @@ -408,7 +427,7 @@ void ContentViewCoreImpl::UpdateFrameInfo( overdraw_bottom_height); } -void ContentViewCoreImpl::SetTitle(const string16& title) { +void ContentViewCoreImpl::SetTitle(const base::string16& title) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) @@ -457,7 +476,7 @@ void ContentViewCoreImpl::ShowSelectPopupMenu( ScopedJavaLocalRef<jintArray> enabled_array(env, env->NewIntArray(items.size())); - std::vector<string16> labels; + std::vector<base::string16> labels; labels.reserve(items.size()); for (size_t i = 0; i < items.size(); ++i) { labels.push_back(items[i].label); @@ -491,6 +510,14 @@ void ContentViewCoreImpl::UnhandledFlingStartEvent() { Java_ContentViewCore_unhandledFlingStartEvent(env, j_obj.obj()); } +void ContentViewCoreImpl::OnScrollUpdateGestureConsumed() { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); + if (j_obj.is_null()) + return; + Java_ContentViewCore_onScrollUpdateGestureConsumed(env, j_obj.obj()); +} + void ContentViewCoreImpl::HasTouchEventHandlers(bool need_touch_events) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); @@ -589,28 +616,13 @@ void ContentViewCoreImpl::ShowDisambiguationPopup( java_bitmap.obj()); } -ScopedJavaLocalRef<jobject> ContentViewCoreImpl::CreateOnePointTouchGesture( - int32 start_x, int32 start_y, int32 delta_x, int32 delta_y) { - JNIEnv* env = AttachCurrentThread(); - - ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); - if (obj.is_null()) - return ScopedJavaLocalRef<jobject>(); - return Java_ContentViewCore_createOnePointTouchGesture( - env, obj.obj(), start_x, start_y, delta_x, delta_y); -} - -ScopedJavaLocalRef<jobject> ContentViewCoreImpl::CreateTwoPointTouchGesture( - int32 start_x0, int32 start_y0, int32 delta_x0, int32 delta_y0, - int32 start_x1, int32 start_y1, int32 delta_x1, int32 delta_y1) { +ScopedJavaLocalRef<jobject> ContentViewCoreImpl::CreateTouchEventSynthesizer() { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) return ScopedJavaLocalRef<jobject>(); - return Java_ContentViewCore_createTwoPointTouchGesture( - env, obj.obj(), start_x0, start_y0, delta_x0, delta_y0, - start_x1, start_y1, delta_x1, delta_y1); + return Java_ContentViewCore_createTouchEventSynthesizer(env, obj.obj()); } void ContentViewCoreImpl::NotifyExternalSurface( @@ -652,6 +664,17 @@ ScopedJavaLocalRef<jobject> ContentViewCoreImpl::GetContext() { return Java_ContentViewCore_getContext(env, obj.obj()); } +bool ContentViewCoreImpl::ShouldBlockMediaRequest(const GURL& url) { + JNIEnv* env = AttachCurrentThread(); + + ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); + if (obj.is_null()) + return true; + ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, url.spec()); + return Java_ContentViewCore_shouldBlockMediaRequest(env, obj.obj(), + j_url.obj()); +} + gfx::Size ContentViewCoreImpl::GetPhysicalBackingSize() const { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); @@ -712,16 +735,22 @@ void ContentViewCoreImpl::RemoveLayer(scoped_refptr<cc::Layer> layer) { void ContentViewCoreImpl::LoadUrl( NavigationController::LoadURLParams& params) { GetWebContents()->GetController().LoadURLWithParams(params); - UpdateTabCrashedFlag(); } -void ContentViewCoreImpl::SetNeedsBeginFrame(bool enabled) { +void ContentViewCoreImpl::AddBeginFrameSubscriber() { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); + if (obj.is_null()) + return; + Java_ContentViewCore_addVSyncSubscriber(env, obj.obj()); +} + +void ContentViewCoreImpl::RemoveBeginFrameSubscriber() { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) return; - Java_ContentViewCore_setVSyncNotificationEnabled( - env, obj.obj(), static_cast<jboolean>(enabled)); + Java_ContentViewCore_removeVSyncSubscriber(env, obj.obj()); } void ContentViewCoreImpl::SetNeedsAnimate() { @@ -858,13 +887,10 @@ void ContentViewCoreImpl::SetFocusInternal(bool focused) { void ContentViewCoreImpl::SendOrientationChangeEvent(JNIEnv* env, jobject obj, jint orientation) { - RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); - if (rwhv) - rwhv->UpdateScreenInfo(rwhv->GetNativeView()); - - RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( - web_contents_->GetRenderViewHost()); - rvhi->SendOrientationChangeEvent(orientation); + if (device_orientation_ != orientation) { + device_orientation_ = orientation; + SendOrientationChangeEventInternal(); + } } jboolean ContentViewCoreImpl::SendTouchEvent(JNIEnv* env, @@ -874,8 +900,8 @@ jboolean ContentViewCoreImpl::SendTouchEvent(JNIEnv* env, jobjectArray pts) { RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); if (rwhv) { - using WebKit::WebTouchEvent; - WebKit::WebTouchEvent event; + using blink::WebTouchEvent; + blink::WebTouchEvent event; TouchPoint::BuildWebTouchEvent(env, type, time_ms, GetDpiScale(), pts, event); rwhv->SendTouchEvent(event); @@ -909,9 +935,9 @@ jboolean ContentViewCoreImpl::SendMouseMoveEvent(JNIEnv* env, if (!rwhv) return false; - WebKit::WebMouseEvent event = WebMouseEventBuilder::Build( + blink::WebMouseEvent event = WebMouseEventBuilder::Build( WebInputEvent::MouseMove, - WebKit::WebMouseEvent::ButtonNone, + blink::WebMouseEvent::ButtonNone, time_ms / 1000.0, x / GetDpiScale(), y / GetDpiScale(), 0, 1); rwhv->SendMouseEvent(event); @@ -936,7 +962,7 @@ jboolean ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv* env, } else { return false; } - WebKit::WebMouseWheelEvent event = WebMouseWheelEventBuilder::Build( + blink::WebMouseWheelEvent event = WebMouseWheelEventBuilder::Build( direction, time_ms / 1000.0, x / GetDpiScale(), y / GetDpiScale()); rwhv->SendMouseWheelEvent(event); @@ -944,24 +970,18 @@ jboolean ContentViewCoreImpl::SendMouseWheelEvent(JNIEnv* env, } WebGestureEvent ContentViewCoreImpl::MakeGestureEvent( - WebInputEvent::Type type, long time_ms, float x, float y) const { + WebInputEvent::Type type, int64 time_ms, float x, float y) const { return WebGestureEventBuilder::Build( type, time_ms / 1000.0, x / GetDpiScale(), y / GetDpiScale()); } void ContentViewCoreImpl::SendGestureEvent( - const WebKit::WebGestureEvent& event) { + const blink::WebGestureEvent& event) { RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); if (rwhv) rwhv->SendGestureEvent(event); } -void ContentViewCoreImpl::UpdateTabCrashedFlag() { - // Since RenderWidgetHostView is associated with the lifetime of the renderer - // process, we use it to test whether there is a renderer process. - tab_crashed_ = !(web_contents_->GetRenderWidgetHostView()); -} - void ContentViewCoreImpl::ScrollBegin(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( @@ -1039,20 +1059,28 @@ void ContentViewCoreImpl::ShowPressState(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( - WebInputEvent::GestureTapDown, time_ms, x, y); + WebInputEvent::GestureShowPress, time_ms, x, y); SendGestureEvent(event); } -void ContentViewCoreImpl::ShowPressCancel(JNIEnv* env, - jobject obj, - jlong time_ms, - jfloat x, - jfloat y) { +void ContentViewCoreImpl::TapCancel(JNIEnv* env, + jobject obj, + jlong time_ms, + jfloat x, + jfloat y) { WebGestureEvent event = MakeGestureEvent( WebInputEvent::GestureTapCancel, time_ms, x, y); SendGestureEvent(event); } +void ContentViewCoreImpl::TapDown(JNIEnv* env, jobject obj, + jlong time_ms, + jfloat x, jfloat y) { + WebGestureEvent event = MakeGestureEvent( + WebInputEvent::GestureTapDown, time_ms, x, y); + SendGestureEvent(event); +} + void ContentViewCoreImpl::DoubleTap(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) { WebGestureEvent event = MakeGestureEvent( @@ -1131,44 +1159,8 @@ void ContentViewCoreImpl::MoveCaret(JNIEnv* env, jobject obj, } } -jboolean ContentViewCoreImpl::CanGoBack(JNIEnv* env, jobject obj) { - return web_contents_->GetController().CanGoBack(); -} - -jboolean ContentViewCoreImpl::CanGoForward(JNIEnv* env, jobject obj) { - return web_contents_->GetController().CanGoForward(); -} - -jboolean ContentViewCoreImpl::CanGoToOffset(JNIEnv* env, jobject obj, - jint offset) { - return web_contents_->GetController().CanGoToOffset(offset); -} - -void ContentViewCoreImpl::GoBack(JNIEnv* env, jobject obj) { - web_contents_->GetController().GoBack(); - UpdateTabCrashedFlag(); -} - -void ContentViewCoreImpl::GoForward(JNIEnv* env, jobject obj) { - web_contents_->GetController().GoForward(); - UpdateTabCrashedFlag(); -} - -void ContentViewCoreImpl::GoToOffset(JNIEnv* env, jobject obj, jint offset) { - web_contents_->GetController().GoToOffset(offset); - UpdateTabCrashedFlag(); -} - -void ContentViewCoreImpl::GoToNavigationIndex(JNIEnv* env, - jobject obj, - jint index) { - web_contents_->GetController().GoToIndex(index); - UpdateTabCrashedFlag(); -} - void ContentViewCoreImpl::LoadIfNecessary(JNIEnv* env, jobject obj) { web_contents_->GetController().LoadIfNecessary(); - UpdateTabCrashedFlag(); } void ContentViewCoreImpl::RequestRestoreLoad(JNIEnv* env, jobject obj) { @@ -1179,14 +1171,19 @@ void ContentViewCoreImpl::StopLoading(JNIEnv* env, jobject obj) { web_contents_->Stop(); } -void ContentViewCoreImpl::Reload(JNIEnv* env, jobject obj) { - // Set check_for_repost parameter to false as we have no repost confirmation - // dialog ("confirm form resubmission" screen will still appear, however). +void ContentViewCoreImpl::Reload(JNIEnv* env, + jobject obj, + jboolean check_for_repost) { if (web_contents_->GetController().NeedsReload()) web_contents_->GetController().LoadIfNecessary(); else - web_contents_->GetController().Reload(true); - UpdateTabCrashedFlag(); + web_contents_->GetController().Reload(check_for_repost); +} + +void ContentViewCoreImpl::ReloadIgnoringCache(JNIEnv* env, + jobject obj, + jboolean check_for_repost) { + web_contents_->GetController().ReloadIgnoringCache(check_for_repost); } void ContentViewCoreImpl::CancelPendingReload(JNIEnv* env, jobject obj) { @@ -1199,8 +1196,8 @@ void ContentViewCoreImpl::ContinuePendingReload(JNIEnv* env, jobject obj) { void ContentViewCoreImpl::ClearHistory(JNIEnv* env, jobject obj) { // TODO(creis): Do callers of this need to know if it fails? - if (web_contents_->GetController().CanPruneAllButVisible()) - web_contents_->GetController().PruneAllButVisible(); + if (web_contents_->GetController().CanPruneAllButLastCommitted()) + web_contents_->GetController().PruneAllButLastCommitted(); } void ContentViewCoreImpl::AddJavascriptInterface( @@ -1223,7 +1220,7 @@ void ContentViewCoreImpl::AddJavascriptInterface( java_bridge->AsWeakPtr()); java_bridge->AddNamedObject(ConvertJavaStringToUTF16(env, name), bound_object); - WebKit::WebBindings::releaseObject(bound_object); + blink::WebBindings::releaseObject(bound_object); } void ContentViewCoreImpl::RemoveJavascriptInterface(JNIEnv* env, @@ -1317,27 +1314,27 @@ void ContentViewCoreImpl::AttachExternalVideoSurface(JNIEnv* env, jobject obj, jint player_id, jobject jsurface) { -#if defined(GOOGLE_TV) +#if defined(VIDEO_HOLE) RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( web_contents_->GetRenderViewHost()); if (rvhi && rvhi->media_player_manager()) { rvhi->media_player_manager()->AttachExternalVideoSurface( static_cast<int>(player_id), jsurface); } -#endif +#endif // defined(VIDEO_HOLE) } void ContentViewCoreImpl::DetachExternalVideoSurface(JNIEnv* env, jobject obj, jint player_id) { -#if defined(GOOGLE_TV) +#if defined(VIDEO_HOLE) RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( web_contents_->GetRenderViewHost()); if (rvhi && rvhi->media_player_manager()) { rvhi->media_player_manager()->DetachExternalVideoSurface( static_cast<int>(player_id)); } -#endif +#endif // defined(VIDEO_HOLE) } jboolean ContentViewCoreImpl::IsRenderWidgetHostViewReady(JNIEnv* env, @@ -1459,10 +1456,6 @@ int ContentViewCoreImpl::GetNativeImeAdapter(JNIEnv* env, jobject obj) { return rwhva->GetNativeImeAdapter(); } -jboolean ContentViewCoreImpl::NeedsReload(JNIEnv* env, jobject obj) { - return web_contents_->GetController().NeedsReload(); -} - void ContentViewCoreImpl::UndoScrollFocusedEditableNodeIntoView( JNIEnv* env, jobject obj) { @@ -1501,7 +1494,7 @@ void ContentViewCoreImpl::EvaluateJavaScript(JNIEnv* env, if (!callback) { // No callback requested. - rvh->ExecuteJavascriptInWebFrame(string16(), // frame_xpath + rvh->ExecuteJavascriptInWebFrame(base::string16(), // frame_xpath ConvertJavaStringToUTF16(env, script)); return; } @@ -1514,7 +1507,7 @@ void ContentViewCoreImpl::EvaluateJavaScript(JNIEnv* env, base::Bind(&JavaScriptResultCallback, j_callback); rvh->ExecuteJavascriptInWebFrameCallbackResult( - string16(), // frame_xpath + base::string16(), // frame_xpath ConvertJavaStringToUTF16(env, script), c_callback); } @@ -1532,7 +1525,8 @@ void ContentViewCoreImpl::UpdateImeAdapter(int native_ime_adapter, int selection_end, int composition_start, int composition_end, - bool show_ime_if_needed) { + bool show_ime_if_needed, + bool require_ack) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) @@ -1544,15 +1538,7 @@ void ContentViewCoreImpl::UpdateImeAdapter(int native_ime_adapter, jstring_text.obj(), selection_start, selection_end, composition_start, composition_end, - show_ime_if_needed); -} - -void ContentViewCoreImpl::ProcessImeBatchStateAck(bool is_begin) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); - if (obj.is_null()) - return; - Java_ContentViewCore_processImeBatchStateAck(env, obj.obj(), is_begin); + show_ime_if_needed, require_ack); } void ContentViewCoreImpl::ClearSslPreferences(JNIEnv* env, jobject obj) { @@ -1594,29 +1580,103 @@ void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv* env, jobject obj, return; RenderWidgetHostImpl* host_impl = RenderWidgetHostImpl::From( host_view->GetRenderWidgetHost()); + BrowserAccessibilityState* accessibility_state = + BrowserAccessibilityState::GetInstance(); if (enabled) { - BrowserAccessibilityState::GetInstance()->EnableAccessibility(); - if (host_impl) + // This enables accessibility globally unless it was explicitly disallowed + // by a command-line flag. + accessibility_state->OnScreenReaderDetected(); + // If it was actually enabled globally, enable it for this RenderWidget now. + if (accessibility_state->IsAccessibleBrowser() && host_impl) host_impl->SetAccessibilityMode(AccessibilityModeComplete); } else { - BrowserAccessibilityState::GetInstance()->DisableAccessibility(); + accessibility_state->DisableAccessibility(); if (host_impl) host_impl->SetAccessibilityMode(AccessibilityModeOff); } } +void ContentViewCoreImpl::SendSingleTapUma(JNIEnv* env, + jobject obj, + jint type, + jint count) { + UMA_HISTOGRAM_ENUMERATION("Event.SingleTapType", type, count); +} + +void ContentViewCoreImpl::SendActionAfterDoubleTapUma(JNIEnv* env, + jobject obj, + jint type, + jboolean has_delay, + jint count) { + // This UMA stat tracks a user's action after a double tap within + // k seconds (where k == 5 currently). This UMA will tell us if + // removing the tap gesture delay will lead to significantly more + // accidental navigations after a double tap. + if (has_delay) { + UMA_HISTOGRAM_ENUMERATION("Event.ActionAfterDoubleTapWithDelay", type, + count); + } else { + UMA_HISTOGRAM_ENUMERATION("Event.ActionAfterDoubleTapNoDelay", type, + count); + } +} + +void ContentViewCoreImpl::SendOrientationChangeEventInternal() { + RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid(); + if (rwhv) + rwhv->UpdateScreenInfo(rwhv->GetNativeView()); + + RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>( + web_contents_->GetRenderViewHost()); + rvhi->SendOrientationChangeEvent(device_orientation_); +} + +void ContentViewCoreImpl::ExtractSmartClipData(JNIEnv* env, + jobject obj, + jint x, + jint y, + jint width, + jint height) { + gfx::Rect rect( + static_cast<int>(x / GetDpiScale()), + static_cast<int>(y / GetDpiScale()), + static_cast<int>((width > 0 && width < GetDpiScale()) ? + 1 : (int)(width / GetDpiScale())), + static_cast<int>((height > 0 && height < GetDpiScale()) ? + 1 : (int)(height / GetDpiScale()))); + GetWebContents()->Send(new ViewMsg_ExtractSmartClipData( + GetWebContents()->GetRoutingID(), rect)); +} + +void ContentViewCoreImpl::OnSmartClipDataExtracted(const string16& result) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); + if (obj.is_null()) + return; + ScopedJavaLocalRef<jstring> jresult = ConvertUTF16ToJavaString(env, result); + Java_ContentViewCore_onSmartClipDataExtracted( + env, obj.obj(), jresult.obj()); +} + +void ContentViewCoreImpl::WebContentsDestroyed(WebContents* web_contents) { + WebContentsViewAndroid* wcva = + static_cast<WebContentsViewAndroid*>(web_contents->GetView()); + DCHECK(wcva); + wcva->SetContentViewCore(NULL); +} + // This is called for each ContentView. -jint Init(JNIEnv* env, jobject obj, - jboolean hardware_accelerated, - jint native_web_contents, - jint view_android, - jint window_android) { +jlong Init(JNIEnv* env, jobject obj, + jboolean hardware_accelerated, + jlong native_web_contents, + jlong view_android, + jlong window_android) { ContentViewCoreImpl* view = new ContentViewCoreImpl( env, obj, hardware_accelerated, reinterpret_cast<WebContents*>(native_web_contents), reinterpret_cast<ui::ViewAndroid*>(view_android), reinterpret_cast<ui::WindowAndroid*>(window_android)); - return reinterpret_cast<jint>(view); + return reinterpret_cast<intptr_t>(view); } bool RegisterContentViewCore(JNIEnv* env) { diff --git a/chromium/content/browser/android/content_view_core_impl.h b/chromium/content/browser/android/content_view_core_impl.h index 765f63da983..5c61ae60b6d 100644 --- a/chromium/content/browser/android/content_view_core_impl.h +++ b/chromium/content/browser/android/content_view_core_impl.h @@ -19,6 +19,7 @@ #include "content/public/browser/android/content_view_core.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "content/public/browser/web_contents_observer.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/gfx/rect.h" #include "ui/gfx/rect_f.h" @@ -35,7 +36,8 @@ struct MenuItem; // TODO(jrg): this is a shell. Upstream the rest. class ContentViewCoreImpl : public ContentViewCore, - public NotificationObserver { + public NotificationObserver, + public WebContentsObserver { public: static ContentViewCoreImpl* FromWebContents(WebContents* web_contents); ContentViewCoreImpl(JNIEnv* env, @@ -61,11 +63,15 @@ class ContentViewCoreImpl : public ContentViewCore, virtual void RequestContentClipping(const gfx::Rect& clipping, const gfx::Size& content_size) OVERRIDE; virtual void PauseVideo() OVERRIDE; + virtual void PauseOrResumeGeolocation(bool should_pause) OVERRIDE; // -------------------------------------------------------------------------- // Methods called from Java via JNI // -------------------------------------------------------------------------- + base::android::ScopedJavaLocalRef<jobject> GetWebContentsAndroid(JNIEnv* env, + jobject obj); + void OnJavaContentViewCoreDestroyed(JNIEnv* env, jobject obj); // Notifies the ContentViewCore that items were selected in the currently @@ -87,7 +93,6 @@ class ContentViewCoreImpl : public ContentViewCore, base::android::ScopedJavaLocalRef<jstring> GetTitle( JNIEnv* env, jobject obj) const; jboolean IsIncognito(JNIEnv* env, jobject obj); - jboolean Crashed(JNIEnv* env, jobject obj) const { return tab_crashed_; } void SendOrientationChangeEvent(JNIEnv* env, jobject obj, jint orientation); jboolean SendTouchEvent(JNIEnv* env, jobject obj, @@ -119,8 +124,10 @@ class ContentViewCoreImpl : public ContentViewCore, jfloat x, jfloat y); void ShowPressState(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y); - void ShowPressCancel(JNIEnv* env, jobject obj, jlong time_ms, - jfloat x, jfloat y); + void TapCancel(JNIEnv* env, jobject obj, jlong time_ms, + jfloat x, jfloat y); + void TapDown(JNIEnv* env, jobject obj, jlong time_ms, + jfloat x, jfloat y); void DoubleTap(JNIEnv* env, jobject obj, jlong time_ms, jfloat x, jfloat y) ; void LongPress(JNIEnv* env, jobject obj, jlong time_ms, @@ -138,20 +145,13 @@ class ContentViewCoreImpl : public ContentViewCore, jfloat x2, jfloat y2); void MoveCaret(JNIEnv* env, jobject obj, jfloat x, jfloat y); - jboolean CanGoBack(JNIEnv* env, jobject obj); - jboolean CanGoForward(JNIEnv* env, jobject obj); - jboolean CanGoToOffset(JNIEnv* env, jobject obj, jint offset); - void GoBack(JNIEnv* env, jobject obj); - void GoForward(JNIEnv* env, jobject obj); - void GoToOffset(JNIEnv* env, jobject obj, jint offset); - void GoToNavigationIndex(JNIEnv* env, jobject obj, jint index); void LoadIfNecessary(JNIEnv* env, jobject obj); void RequestRestoreLoad(JNIEnv* env, jobject obj); void StopLoading(JNIEnv* env, jobject obj); - void Reload(JNIEnv* env, jobject obj); + void Reload(JNIEnv* env, jobject obj, jboolean check_for_repost); + void ReloadIgnoringCache(JNIEnv* env, jobject obj, jboolean check_for_repost); void CancelPendingReload(JNIEnv* env, jobject obj); void ContinuePendingReload(JNIEnv* env, jobject obj); - jboolean NeedsReload(JNIEnv* env, jobject obj); void ClearHistory(JNIEnv* env, jobject obj); void EvaluateJavaScript(JNIEnv* env, jobject obj, @@ -219,11 +219,25 @@ class ContentViewCoreImpl : public ContentViewCore, jobject jsurface); void DetachExternalVideoSurface(JNIEnv* env, jobject obj, jint player_id); void SetAccessibilityEnabled(JNIEnv* env, jobject obj, bool enabled); - + void SendActionAfterDoubleTapUma(JNIEnv* env, + jobject obj, + jint type, + jboolean has_delay, + jint count); + void SendSingleTapUma(JNIEnv* env, jobject obj, jint type, jint count); + + void ExtractSmartClipData(JNIEnv* env, + jobject obj, + jint x, + jint y, + jint width, + jint height); // -------------------------------------------------------------------------- // Public methods that call to Java via JNI // -------------------------------------------------------------------------- + void OnSmartClipDataExtracted(const string16& result); + // Creates a popup menu with |items|. // |multiple| defines if it should support multi-select. // If not |multiple|, |selected_item| sets the initially selected item. @@ -248,14 +262,14 @@ class ContentViewCoreImpl : public ContentViewCore, const std::string& text, int selection_start, int selection_end, int composition_start, int composition_end, - bool show_ime_if_needed); - void ProcessImeBatchStateAck(bool is_begin); - void SetTitle(const string16& title); + bool show_ime_if_needed, bool require_ack); + void SetTitle(const base::string16& title); void OnBackgroundColorChanged(SkColor color); bool HasFocus(); void ConfirmTouchEvent(InputEventAckState ack_result); void UnhandledFlingStartEvent(); + void OnScrollUpdateGestureConsumed(); void HasTouchEventHandlers(bool need_touch_events); void OnSelectionChanged(const std::string& text); void OnSelectionBoundsChanged( @@ -269,16 +283,9 @@ class ContentViewCoreImpl : public ContentViewCore, void ShowDisambiguationPopup( const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap); - // Creates a java-side touch gesture, e.g. used by - // chrome.gpuBenchmarking.smoothScrollBy. - base::android::ScopedJavaLocalRef<jobject> CreateOnePointTouchGesture( - int start_x, int start_y, int delta_x, int delta_y); - - // Creates a java-side touch gesture with two pointers, e.g. used by - // chrome.gpuBenchmarking.pinchBy. - base::android::ScopedJavaLocalRef<jobject> CreateTwoPointTouchGesture( - int start_x0, int start_y0, int delta_x0, int delta_y0, - int start_x1, int start_y1, int delta_x1, int delta_y1); + // Creates a java-side touch event, used for injecting touch event for + // testing/benchmarking purposes + base::android::ScopedJavaLocalRef<jobject> CreateTouchEventSynthesizer(); // Notifies the java object about the external surface, requesting for one if // necessary. @@ -291,6 +298,9 @@ class ContentViewCoreImpl : public ContentViewCore, // typically be an Activity context for an on screen view. base::android::ScopedJavaLocalRef<jobject> GetContext(); + // Returns True if the given media should be blocked to load. + bool ShouldBlockMediaRequest(const GURL& url); + // -------------------------------------------------------------------------- // Methods called from native code // -------------------------------------------------------------------------- @@ -302,7 +312,8 @@ class ContentViewCoreImpl : public ContentViewCore, void AttachLayer(scoped_refptr<cc::Layer> layer); void RemoveLayer(scoped_refptr<cc::Layer> layer); - void SetNeedsBeginFrame(bool enabled); + void AddBeginFrameSubscriber(); + void RemoveBeginFrameSubscriber(); void SetNeedsAnimate(); private: @@ -316,6 +327,10 @@ class ContentViewCoreImpl : public ContentViewCore, const NotificationSource& source, const NotificationDetails& details) OVERRIDE; + // WebContentsObserver implementation. + virtual void RenderViewReady() OVERRIDE; + virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; + // -------------------------------------------------------------------------- // Other private methods and data // -------------------------------------------------------------------------- @@ -326,8 +341,8 @@ class ContentViewCoreImpl : public ContentViewCore, float GetTouchPaddingDip(); - WebKit::WebGestureEvent MakeGestureEvent( - WebKit::WebInputEvent::Type type, long time_ms, float x, float y) const; + blink::WebGestureEvent MakeGestureEvent( + blink::WebInputEvent::Type type, int64 time_ms, float x, float y) const; void SendBeginFrame(base::TimeTicks frame_time); @@ -336,15 +351,14 @@ class ContentViewCoreImpl : public ContentViewCore, void DeleteScaledSnapshotTexture(); - void SendGestureEvent(const WebKit::WebGestureEvent& event); - - // Checks if there there is a corresponding renderer process and updates - // |tab_crashed_| accordingly. - void UpdateTabCrashedFlag(); + void SendGestureEvent(const blink::WebGestureEvent& event); // Update focus state of the RenderWidgetHostView. void SetFocusInternal(bool focused); + // Send device_orientation_ to renderer. + void SendOrientationChangeEventInternal(); + // A weak reference to the Java ContentViewCore object. JavaObjectWeakGlobalRef java_ref_; @@ -357,9 +371,6 @@ class ContentViewCoreImpl : public ContentViewCore, // A compositor layer containing any layer that should be shown. scoped_refptr<cc::Layer> root_layer_; - // Whether the renderer backing this ContentViewCore has crashed. - bool tab_crashed_; - // Device scale factor. float dpi_scale_; @@ -374,6 +385,12 @@ class ContentViewCoreImpl : public ContentViewCore, // The owning window that has a hold of main application activity. ui::WindowAndroid* window_android_; + // The cache of device's current orientation set from Java side, this value + // will be sent to Renderer once it is ready. + int device_orientation_; + + bool geolocation_needs_pause_; + DISALLOW_COPY_AND_ASSIGN(ContentViewCoreImpl); }; diff --git a/chromium/content/browser/android/content_view_render_view.cc b/chromium/content/browser/android/content_view_render_view.cc index 4faa4df97aa..639deae5ca6 100644 --- a/chromium/content/browser/android/content_view_render_view.cc +++ b/chromium/content/browser/android/content_view_render_view.cc @@ -16,8 +16,10 @@ #include "content/public/browser/android/compositor.h" #include "content/public/browser/android/content_view_layer_renderer.h" #include "jni/ContentViewRenderView_jni.h" +#include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/size.h" +#include <android/bitmap.h> #include <android/native_window_jni.h> using base::android::ScopedJavaLocalRef; @@ -29,8 +31,11 @@ bool ContentViewRenderView::RegisterContentViewRenderView(JNIEnv* env) { return RegisterNativesImpl(env); } -ContentViewRenderView::ContentViewRenderView(JNIEnv* env, jobject obj) - : buffers_swapped_during_composite_(false) { +ContentViewRenderView::ContentViewRenderView(JNIEnv* env, + jobject obj, + gfx::NativeWindow root_window) + : buffers_swapped_during_composite_(false), + root_window_(root_window) { java_obj_.Reset(env, obj); } @@ -38,10 +43,12 @@ ContentViewRenderView::~ContentViewRenderView() { } // static -static jint Init(JNIEnv* env, jobject obj) { +static jlong Init(JNIEnv* env, jobject obj, jlong native_root_window) { + gfx::NativeWindow root_window = + reinterpret_cast<gfx::NativeWindow>(native_root_window); ContentViewRenderView* content_view_render_view = - new ContentViewRenderView(env, obj); - return reinterpret_cast<jint>(content_view_render_view); + new ContentViewRenderView(env, obj, root_window); + return reinterpret_cast<intptr_t>(content_view_render_view); } void ContentViewRenderView::Destroy(JNIEnv* env, jobject obj) { @@ -83,6 +90,15 @@ jboolean ContentViewRenderView::Composite(JNIEnv* env, jobject obj) { return buffers_swapped_during_composite_; } +jboolean ContentViewRenderView::CompositeToBitmap(JNIEnv* env, jobject obj, + jobject java_bitmap) { + gfx::JavaBitmap bitmap(java_bitmap); + if (!compositor_ || bitmap.format() != ANDROID_BITMAP_FORMAT_RGBA_8888) + return false; + return compositor_->CompositeAndReadback(bitmap.pixels(), + gfx::Rect(bitmap.size())); +} + void ContentViewRenderView::ScheduleComposite() { JNIEnv* env = base::android::AttachCurrentThread(); Java_ContentViewRenderView_requestRender(env, java_obj_.obj()); @@ -99,7 +115,7 @@ void ContentViewRenderView::OnSwapBuffersCompleted() { void ContentViewRenderView::InitCompositor() { if (!compositor_) - compositor_.reset(Compositor::Create(this)); + compositor_.reset(Compositor::Create(this, root_window_)); } } // namespace content diff --git a/chromium/content/browser/android/content_view_render_view.h b/chromium/content/browser/android/content_view_render_view.h index 714f02f7d32..1bd3899ac3c 100644 --- a/chromium/content/browser/android/content_view_render_view.h +++ b/chromium/content/browser/android/content_view_render_view.h @@ -10,6 +10,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "content/public/browser/android/compositor_client.h" +#include "ui/gfx/native_widget_types.h" namespace content { class Compositor; @@ -19,7 +20,9 @@ class ContentViewRenderView : public CompositorClient { // Registers the JNI methods for ContentViewRender. static bool RegisterContentViewRenderView(JNIEnv* env); - ContentViewRenderView(JNIEnv* env, jobject obj); + ContentViewRenderView(JNIEnv* env, + jobject obj, + gfx::NativeWindow root_window); // Methods called from Java via JNI ----------------------------------------- void Destroy(JNIEnv* env, jobject obj); @@ -28,6 +31,7 @@ class ContentViewRenderView : public CompositorClient { void SurfaceDestroyed(JNIEnv* env, jobject obj); void SurfaceSetSize(JNIEnv* env, jobject obj, jint width, jint height); jboolean Composite(JNIEnv* env, jobject obj); + jboolean CompositeToBitmap(JNIEnv* env, jobject obj, jobject java_bitmap); // CompositorClient --------------------------------------------------------- virtual void ScheduleComposite() OVERRIDE; @@ -45,6 +49,8 @@ class ContentViewRenderView : public CompositorClient { scoped_ptr<content::Compositor> compositor_; + gfx::NativeWindow root_window_; + DISALLOW_COPY_AND_ASSIGN(ContentViewRenderView); }; diff --git a/chromium/content/browser/android/content_view_statics.cc b/chromium/content/browser/android/content_view_statics.cc index 66af8652d49..e176564c4a0 100644 --- a/chromium/content/browser/android/content_view_statics.cc +++ b/chromium/content/browser/android/content_view_statics.cc @@ -24,7 +24,7 @@ namespace { // TODO(pliard): http://crbug.com/235909. Move WebKit shared timer toggling // functionality out of ContentViewStatistics and not be build on top of -// WebKit::Platform::SuspendSharedTimer. +// blink::Platform::SuspendSharedTimer. // TODO(pliard): http://crbug.com/235912. Add unit tests for WebKit shared timer // toggling. @@ -62,8 +62,8 @@ void ResumeWebkitSharedTimers(const std::vector<int>& suspended_processes) { // Returns the first substring consisting of the address of a physical location. static jstring FindAddress(JNIEnv* env, jclass clazz, jstring addr) { - string16 content_16 = ConvertJavaStringToUTF16(env, addr); - string16 result_16; + base::string16 content_16 = ConvertJavaStringToUTF16(env, addr); + base::string16 result_16; if (content::address_parser::FindAddress(content_16, &result_16)) return ConvertUTF16ToJavaString(env, result_16).Release(); return NULL; diff --git a/chromium/content/browser/android/date_time_chooser_android.cc b/chromium/content/browser/android/date_time_chooser_android.cc index 7c91ff0977d..f6b50c9da4b 100644 --- a/chromium/content/browser/android/date_time_chooser_android.cc +++ b/chromium/content/browser/android/date_time_chooser_android.cc @@ -4,74 +4,46 @@ #include "content/browser/android/date_time_chooser_android.h" +#include "base/android/jni_android.h" #include "base/android/jni_string.h" +#include "base/i18n/char_iterator.h" +#include "content/common/date_time_suggestion.h" #include "content/common/view_messages.h" #include "content/public/browser/android/content_view_core.h" -#include "content/public/browser/render_view_host_observer.h" +#include "content/public/browser/render_view_host.h" #include "jni/DateTimeChooserAndroid_jni.h" +#include "third_party/icu/source/common/unicode/uchar.h" +#include "third_party/icu/source/common/unicode/unistr.h" using base::android::AttachCurrentThread; using base::android::ConvertJavaStringToUTF16; using base::android::ConvertUTF8ToJavaString; - - -namespace content { - -// Updates date/time via IPC to the RenderView -class DateTimeChooserAndroid::DateTimeIPCSender : - public RenderViewHostObserver { - public: - explicit DateTimeIPCSender(RenderViewHost* sender); - virtual ~DateTimeIPCSender() {} - void ReplaceDateTime(int dialog_type, - int year, - int month, - int day, - int hour, - int minute, - int second, - int milli, - int week); - void CancelDialog(); - - private: - DISALLOW_COPY_AND_ASSIGN(DateTimeIPCSender); -}; - -DateTimeChooserAndroid::DateTimeIPCSender::DateTimeIPCSender( - RenderViewHost* sender) - : RenderViewHostObserver(sender) { +using base::android::ConvertUTF16ToJavaString; + + +namespace { + +string16 SanitizeSuggestionString(const string16& string) { + string16 trimmed = string.substr(0, 255); + icu::UnicodeString sanitized; + base::i18n::UTF16CharIterator sanitized_iterator(&trimmed); + while (!sanitized_iterator.end()) { + UChar c = sanitized_iterator.get(); + if (u_isprint(c)) + sanitized.append(c); + sanitized_iterator.Advance(); + } + return string16(sanitized.getBuffer(), + static_cast<size_t>(sanitized.length())); } -void DateTimeChooserAndroid::DateTimeIPCSender::ReplaceDateTime(int dialog_type, - int year, - int month, - int day, - int hour, - int minute, - int second, - int milli, - int week) { - ViewHostMsg_DateTimeDialogValue_Params value; - value.year = year; - value.month = month; - value.day = day; - value.hour = hour; - value.minute = minute; - value.second = second; - value.milli = milli; - value.week = week; - value.dialog_type = dialog_type; - Send(new ViewMsg_ReplaceDateTime(routing_id(), value)); -} +} // namespace -void DateTimeChooserAndroid::DateTimeIPCSender::CancelDialog() { - Send(new ViewMsg_CancelDateTimeDialog(routing_id())); -} +namespace content { // DateTimeChooserAndroid implementation DateTimeChooserAndroid::DateTimeChooserAndroid() - : sender_(NULL) { + : host_(NULL) { } DateTimeChooserAndroid::~DateTimeChooserAndroid() { @@ -92,58 +64,54 @@ void DateTimeChooserAndroid::InitializeDateInputTypes( void DateTimeChooserAndroid::ReplaceDateTime(JNIEnv* env, jobject, - int dialog_type, - int year, - int month, - int day, - int hour, - int minute, - int second, - int milli, - int week) { - sender_->ReplaceDateTime( - dialog_type, year, month, day, hour, minute, second, milli, week); + jdouble value) { + host_->Send(new ViewMsg_ReplaceDateTime(host_->GetRoutingID(), value)); } void DateTimeChooserAndroid::CancelDialog(JNIEnv* env, jobject) { - sender_->CancelDialog(); + host_->Send(new ViewMsg_CancelDateTimeDialog(host_->GetRoutingID())); } -void DateTimeChooserAndroid::ShowDialog(ContentViewCore* content, - RenderViewHost* sender, - int type, - int year, - int month, - int day, - int hour, - int minute, - int second, - int milli, - int week, - double min, - double max, - double step) { - if (sender_) - delete sender_; - sender_ = new DateTimeIPCSender(sender); +void DateTimeChooserAndroid::ShowDialog( + ContentViewCore* content, + RenderViewHost* host, + ui::TextInputType dialog_type, + double dialog_value, + double min, + double max, + double step, + const std::vector<DateTimeSuggestion>& suggestions) { + host_ = host; JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobjectArray> suggestions_array; + + if (suggestions.size() > 0) { + suggestions_array = + Java_DateTimeChooserAndroid_createSuggestionsArray(env, + suggestions.size()); + for (size_t i = 0; i < suggestions.size(); ++i) { + const content::DateTimeSuggestion& suggestion = suggestions[i]; + ScopedJavaLocalRef<jstring> localized_value = ConvertUTF16ToJavaString( + env, SanitizeSuggestionString(suggestion.localized_value)); + ScopedJavaLocalRef<jstring> label = ConvertUTF16ToJavaString( + env, SanitizeSuggestionString(suggestion.label)); + Java_DateTimeChooserAndroid_setDateTimeSuggestionAt(env, + suggestions_array.obj(), i, + suggestion.value, localized_value.obj(), label.obj()); + } + } + j_date_time_chooser_.Reset(Java_DateTimeChooserAndroid_createDateTimeChooser( env, content->GetJavaObject().obj(), reinterpret_cast<intptr_t>(this), - type, - year, - month, - day, - hour, - minute, - second, - milli, - week, + dialog_type, + dialog_value, min, max, - step)); + step, + suggestions_array.obj())); } // ---------------------------------------------------------------------------- diff --git a/chromium/content/browser/android/date_time_chooser_android.h b/chromium/content/browser/android/date_time_chooser_android.h index 68cb4560172..c02ecf56fe2 100644 --- a/chromium/content/browser/android/date_time_chooser_android.h +++ b/chromium/content/browser/android/date_time_chooser_android.h @@ -6,14 +6,17 @@ #define CONTENT_BROWSER_ANDROID_DATE_TIME_CHOOSER_ANDROID_H_ #include <string> +#include <vector> #include "base/android/jni_helper.h" #include "base/memory/scoped_ptr.h" +#include "ui/base/ime/text_input_type.h" namespace content { class ContentViewCore; class RenderViewHost; +struct DateTimeSuggestion; // Android implementation for DateTimeChooser dialogs. class DateTimeChooserAndroid { @@ -22,33 +25,19 @@ class DateTimeChooserAndroid { ~DateTimeChooserAndroid(); // DateTimeChooser implementation: + // Shows the dialog. |dialog_value| is the date/time value converted to a + // number as defined in HTML. (See blink::InputType::parseToNumber()) void ShowDialog(ContentViewCore* content, - RenderViewHost* sender, - int type, - int year, - int month, - int day, - int hour, - int minute, - int second, - int milli, - int week, + RenderViewHost* host, + ui::TextInputType dialog_type, + double dialog_value, double min, double max, - double step); - - // Replaces the current value with the one passed the different fields - void ReplaceDateTime(JNIEnv* env, - jobject, - jint dialog_type, - jint year, - jint month, - jint day, - jint hour, - jint minute, - jint second, - jint milli, - jint week); + double step, + const std::vector<DateTimeSuggestion>& suggestions); + + // Replaces the current value + void ReplaceDateTime(JNIEnv* env, jobject, jdouble value); // Closes the dialog without propagating any changes. void CancelDialog(JNIEnv* env, jobject); @@ -61,11 +50,7 @@ class DateTimeChooserAndroid { int text_input_type_time, int text_input_type_week); private: - class DateTimeIPCSender; - - // The DateTimeIPCSender class is a render view observer, so it will take care - // of its own deletion. - DateTimeIPCSender* sender_; + RenderViewHost* host_; base::android::ScopedJavaGlobalRef<jobject> j_date_time_chooser_; diff --git a/chromium/content/browser/android/download_controller_android_impl.cc b/chromium/content/browser/android/download_controller_android_impl.cc index 7d27e64a193..f3a274a3ef4 100644 --- a/chromium/content/browser/android/download_controller_android_impl.cc +++ b/chromium/content/browser/android/download_controller_android_impl.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/time/time.h" #include "content/browser/android/content_view_core_impl.h" #include "content/browser/download/download_item_impl.h" #include "content/browser/download/download_manager_impl.h" @@ -254,18 +255,9 @@ void DownloadControllerAndroidImpl::OnDownloadStarted( void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (item->IsDangerous() && - (item->GetState() != DownloadItem::CANCELLED)) + if (item->IsDangerous() && (item->GetState() != DownloadItem::CANCELLED)) OnDangerousDownload(item); - if (item->GetState() != DownloadItem::COMPLETE) - return; - - // Multiple OnDownloadUpdated() notifications may be issued while the download - // is in the COMPLETE state. Only handle one. - item->RemoveObserver(this); - - // Call onDownloadCompleted JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jstring> jurl = ConvertUTF8ToJavaString(env, item->GetURL().spec()); @@ -276,10 +268,44 @@ void DownloadControllerAndroidImpl::OnDownloadUpdated(DownloadItem* item) { ScopedJavaLocalRef<jstring> jfilename = ConvertUTF8ToJavaString( env, item->GetTargetFilePath().BaseName().value()); - Java_DownloadController_onDownloadCompleted( - env, GetJavaObject()->Controller(env).obj(), - base::android::GetApplicationContext(), jurl.obj(), jmime_type.obj(), - jfilename.obj(), jpath.obj(), item->GetReceivedBytes(), true); + switch (item->GetState()) { + case DownloadItem::IN_PROGRESS: { + base::TimeDelta time_delta; + item->TimeRemaining(&time_delta); + Java_DownloadController_onDownloadUpdated( + env, GetJavaObject()->Controller(env).obj(), + base::android::GetApplicationContext(), jurl.obj(), jmime_type.obj(), + jfilename.obj(), jpath.obj(), item->GetReceivedBytes(), true, + item->GetId(), item->PercentComplete(), time_delta.InMilliseconds()); + break; + } + case DownloadItem::COMPLETE: + // Multiple OnDownloadUpdated() notifications may be issued while the + // download is in the COMPLETE state. Only handle one. + item->RemoveObserver(this); + + // Call onDownloadCompleted + Java_DownloadController_onDownloadCompleted( + env, GetJavaObject()->Controller(env).obj(), + base::android::GetApplicationContext(), jurl.obj(), jmime_type.obj(), + jfilename.obj(), jpath.obj(), item->GetReceivedBytes(), true, + item->GetId()); + break; + case DownloadItem::CANCELLED: + // TODO(shashishekhar): An interrupted download can be resumed. Android + // currently does not support resumable downloads. Add handling for + // interrupted case based on item->CanResume(). + case DownloadItem::INTERRUPTED: + // Call onDownloadCompleted with success = false. + Java_DownloadController_onDownloadCompleted( + env, GetJavaObject()->Controller(env).obj(), + base::android::GetApplicationContext(), jurl.obj(), jmime_type.obj(), + jfilename.obj(), jpath.obj(), item->GetReceivedBytes(), false, + item->GetId()); + break; + case DownloadItem::MAX_DOWNLOAD_STATE: + NOTREACHED(); + } } void DownloadControllerAndroidImpl::OnDangerousDownload(DownloadItem* item) { diff --git a/chromium/content/browser/android/edge_effect.cc b/chromium/content/browser/android/edge_effect.cc index d8411bc1f89..41fa1a171e1 100644 --- a/chromium/content/browser/android/edge_effect.cc +++ b/chromium/content/browser/android/edge_effect.cc @@ -36,8 +36,9 @@ const float kMaxGlowHeight = 4.f; const float kPullGlowBegin = 1.f; const float kPullEdgeBegin = 0.6f; -// Minimum velocity that will be absorbed +// Min/max velocity that will be absorbed const float kMinVelocity = 100.f; +const float kMaxVelocity = 10000.f; const float kEpsilon = 0.001f; @@ -51,7 +52,7 @@ const int kPullDistanceGlowFactor = 7; const float kPullDistanceAlphaGlowFactor = 1.1f; const int kVelocityEdgeFactor = 8; -const int kVelocityGlowFactor = 16; +const int kVelocityGlowFactor = 12; template <typename T> T Lerp(T a, T b, T t) { @@ -220,11 +221,11 @@ void EdgeEffect::Release(base::TimeTicks current_time) { void EdgeEffect::Absorb(base::TimeTicks current_time, float velocity) { state_ = STATE_ABSORB; float scaled_velocity = - dpi_scale_ * std::max(kMinVelocity, std::abs(velocity)); + dpi_scale_ * Clamp(std::abs(velocity), kMinVelocity, kMaxVelocity); start_time_ = current_time; // This should never be less than 1 millisecond. - duration_ = base::TimeDelta::FromMilliseconds(0.1f + (velocity * 0.03f)); + duration_ = base::TimeDelta::FromMilliseconds(0.15f + (velocity * 0.02f)); // The edge should always be at least partially visible, regardless // of velocity. @@ -232,7 +233,7 @@ void EdgeEffect::Absorb(base::TimeTicks current_time, float velocity) { edge_scale_y_ = edge_scale_y_start_ = 0.f; // The glow depends more on the velocity, and therefore starts out // nearly invisible. - glow_alpha_start_ = 0.5f; + glow_alpha_start_ = 0.3f; glow_scale_y_start_ = 0.f; // Factor the velocity by 8. Testing on device shows this works best to diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc b/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc index b04e85456f1..230b1e92dc6 100644 --- a/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc +++ b/chromium/content/browser/android/in_process/synchronous_compositor_impl.cc @@ -59,7 +59,7 @@ class VideoContextProvider return gl_in_process_context_->GetSurfaceTexture(stream_id); } - virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { + virtual blink::WebGraphicsContext3D* Context3d() OVERRIDE { return context_provider_->Context3d(); } @@ -109,7 +109,7 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; - WebKit::WebGraphicsContext3D::Attributes attributes; + blink::WebGraphicsContext3D::Attributes attributes; attributes.antialias = false; attributes.shareResources = true; attributes.noAutomaticFlushes = true; @@ -178,15 +178,13 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory( int view_id) OVERRIDE { - scoped_refptr<VideoContextProvider> context_provider; - if (CanCreateMainThreadContext()) { - context_provider = - new VideoContextProvider(offscreen_context_for_main_thread_, - wrapped_gl_context_for_main_thread_); - } - return make_scoped_ptr(new StreamTextureFactorySynchronousImpl( - context_provider.get(), view_id)) - .PassAs<StreamTextureFactory>(); + scoped_ptr<StreamTextureFactorySynchronousImpl> factory( + new StreamTextureFactorySynchronousImpl( + base::Bind(&SynchronousCompositorFactoryImpl:: + TryCreateStreamTextureFactory, + base::Unretained(this)), + view_id)); + return factory.PassAs<StreamTextureFactory>(); } void CompositorInitializedHardwareDraw(SynchronousCompositorImpl* compositor); @@ -195,6 +193,8 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory { private: void ReleaseGlobalHardwareResources(); bool CanCreateMainThreadContext(); + scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> + TryCreateStreamTextureFactory(); SynchronousInputEventFilter synchronous_input_event_filter_; @@ -247,6 +247,21 @@ bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() { return num_hardware_compositors_ > 0; } +scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> +SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory() { + scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> + context_provider; + if (CanCreateMainThreadContext() && + GetOffscreenContextProviderForMainThread()) { + DCHECK(offscreen_context_for_main_thread_); + DCHECK(wrapped_gl_context_for_main_thread_); + context_provider = + new VideoContextProvider(offscreen_context_for_main_thread_, + wrapped_gl_context_for_main_thread_); + } + return context_provider; +} + base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = LAZY_INSTANCE_INITIALIZER; @@ -396,7 +411,7 @@ void SynchronousCompositorImpl::SetContinuousInvalidate(bool enable) { } InputEventAckState SynchronousCompositorImpl::HandleInputEvent( - const WebKit::WebInputEvent& input_event) { + const blink::WebInputEvent& input_event) { DCHECK(CalledOnValidThread()); return g_factory.Get().synchronous_input_event_filter()->HandleInputEvent( contents_->GetRoutingID(), input_event); @@ -415,6 +430,13 @@ void SynchronousCompositorImpl::DidActivatePendingTree() { compositor_client_->DidUpdateContent(); } +void SynchronousCompositorImpl::SetMaxScrollOffset( + gfx::Vector2dF max_scroll_offset) { + DCHECK(CalledOnValidThread()); + if (compositor_client_) + compositor_client_->SetMaxRootLayerScrollOffset(max_scroll_offset); +} + void SynchronousCompositorImpl::SetTotalScrollOffset(gfx::Vector2dF new_value) { DCHECK(CalledOnValidThread()); if (compositor_client_) @@ -428,6 +450,26 @@ gfx::Vector2dF SynchronousCompositorImpl::GetTotalScrollOffset() { return gfx::Vector2dF(); } +bool SynchronousCompositorImpl::IsExternalFlingActive() const { + DCHECK(CalledOnValidThread()); + if (compositor_client_) + return compositor_client_->IsExternalFlingActive(); + return false; +} + +void SynchronousCompositorImpl::SetTotalPageScaleFactor( + float page_scale_factor) { + DCHECK(CalledOnValidThread()); + if (compositor_client_) + compositor_client_->SetRootLayerPageScaleFactor(page_scale_factor); +} + +void SynchronousCompositorImpl::SetScrollableSize(gfx::SizeF scrollable_size) { + DCHECK(CalledOnValidThread()); + if (compositor_client_) + compositor_client_->SetRootLayerScrollableSize(scrollable_size); +} + // Not using base::NonThreadSafe as we want to enforce a more exacting threading // requirement: SynchronousCompositorImpl() must only be used on the UI thread. bool SynchronousCompositorImpl::CalledOnValidThread() const { diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_impl.h b/chromium/content/browser/android/in_process/synchronous_compositor_impl.h index 3189dcc983a..f23d920a555 100644 --- a/chromium/content/browser/android/in_process/synchronous_compositor_impl.h +++ b/chromium/content/browser/android/in_process/synchronous_compositor_impl.h @@ -19,7 +19,7 @@ class InputHandler; struct DidOverscrollParams; } -namespace WebKit { +namespace blink { class WebInputEvent; } @@ -43,7 +43,7 @@ class SynchronousCompositorImpl // is implicitly that of the in-process renderer. static SynchronousCompositorImpl* FromRoutingID(int routing_id); - InputEventAckState HandleInputEvent(const WebKit::WebInputEvent& input_event); + InputEventAckState HandleInputEvent(const blink::WebInputEvent& input_event); // SynchronousCompositor virtual void SetClient(SynchronousCompositorClient* compositor_client) @@ -73,8 +73,12 @@ class SynchronousCompositorImpl virtual void DidActivatePendingTree() OVERRIDE; // LayerScrollOffsetDelegate + virtual void SetMaxScrollOffset(gfx::Vector2dF max_scroll_offset) OVERRIDE; virtual void SetTotalScrollOffset(gfx::Vector2dF new_value) OVERRIDE; virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE; + virtual bool IsExternalFlingActive() const OVERRIDE; + virtual void SetTotalPageScaleFactor(float page_scale_factor) OVERRIDE; + virtual void SetScrollableSize(gfx::SizeF scrollable_size) OVERRIDE; void SetInputHandler(cc::InputHandler* input_handler); void DidOverscroll(const cc::DidOverscrollParams& params); diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc index 28119a20329..2d37659723c 100644 --- a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc +++ b/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.cc @@ -14,6 +14,7 @@ #include "content/browser/android/in_process/synchronous_compositor_impl.h" #include "content/public/browser/browser_thread.h" #include "gpu/command_buffer/client/gl_in_process_context.h" +#include "gpu/command_buffer/common/gpu_memory_allocation.h" #include "third_party/skia/include/core/SkBitmapDevice.h" #include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/rect_conversions.h" @@ -35,7 +36,7 @@ CreateWebGraphicsContext3D(scoped_refptr<gfx::GLSurface> surface) { const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; - WebKit::WebGraphicsContext3D::Attributes attributes; + blink::WebGraphicsContext3D::Attributes attributes; attributes.antialias = false; attributes.shareResources = true; attributes.noAutomaticFlushes = true; @@ -104,7 +105,7 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( : cc::OutputSurface( scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareDevice(this))), routing_id_(routing_id), - needs_begin_frame_(false), + needs_begin_impl_frame_(false), invoking_composite_(false), did_swap_buffer_(false), current_sw_canvas_(NULL), @@ -115,6 +116,9 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface( capabilities_.adjust_deadline_for_parent = false; // Cannot call out to GetDelegate() here as the output surface is not // constructed on the correct thread. + + memory_policy_.priority_cutoff_when_visible = + gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; } SynchronousCompositorOutputSurface::~SynchronousCompositorOutputSurface() { @@ -155,14 +159,14 @@ void SynchronousCompositorOutputSurface::Reshape( // Intentional no-op: surface size is controlled by the embedder. } -void SynchronousCompositorOutputSurface::SetNeedsBeginFrame( +void SynchronousCompositorOutputSurface::SetNeedsBeginImplFrame( bool enable) { DCHECK(CalledOnValidThread()); - cc::OutputSurface::SetNeedsBeginFrame(enable); - needs_begin_frame_ = enable; + cc::OutputSurface::SetNeedsBeginImplFrame(enable); + needs_begin_impl_frame_ = enable; SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate(); if (delegate) - delegate->SetContinuousInvalidate(needs_begin_frame_); + delegate->SetContinuousInvalidate(needs_begin_impl_frame_); } void SynchronousCompositorOutputSurface::SwapBuffers( @@ -261,8 +265,8 @@ void SynchronousCompositorOutputSurface::InvokeComposite( adjusted_transform, viewport, clip, valid_for_tile_management); SetNeedsRedrawRect(gfx::Rect(viewport.size())); - if (needs_begin_frame_) - BeginFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor()); + if (needs_begin_impl_frame_) + BeginImplFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor()); // After software draws (which might move the viewport arbitrarily), restore // the previous hardware viewport to allow CC's tile manager to prioritize @@ -280,8 +284,9 @@ void SynchronousCompositorOutputSurface::InvokeComposite( OnSwapBuffersComplete(); } -void SynchronousCompositorOutputSurface::PostCheckForRetroactiveBeginFrame() { - // Synchronous compositor cannot perform retroactive begin frames, so +void +SynchronousCompositorOutputSurface::PostCheckForRetroactiveBeginImplFrame() { + // Synchronous compositor cannot perform retroactive BeginImplFrames, so // intentionally no-op here. } diff --git a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h b/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h index b9b4d678c09..2879de00c04 100644 --- a/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h +++ b/chromium/content/browser/android/in_process/synchronous_compositor_output_surface.h @@ -59,7 +59,7 @@ class SynchronousCompositorOutputSurface virtual bool ForcedDrawToSoftwareDevice() const OVERRIDE; virtual bool BindToClient(cc::OutputSurfaceClient* surface_client) OVERRIDE; virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE; - virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; + virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE; virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE; // Partial SynchronousCompositor API implementation. @@ -80,7 +80,7 @@ class SynchronousCompositorOutputSurface friend class SoftwareDevice; // Private OutputSurface overrides. - virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE; + virtual void PostCheckForRetroactiveBeginImplFrame() OVERRIDE; void InvokeComposite(const gfx::Transform& transform, gfx::Rect viewport, @@ -90,7 +90,7 @@ class SynchronousCompositorOutputSurface SynchronousCompositorOutputSurfaceDelegate* GetDelegate(); int routing_id_; - bool needs_begin_frame_; + bool needs_begin_impl_frame_; bool invoking_composite_; bool did_swap_buffer_; diff --git a/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc b/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc index 34144dac579..b8ba0ea3352 100644 --- a/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc +++ b/chromium/content/browser/android/in_process/synchronous_input_event_filter.cc @@ -10,7 +10,7 @@ #include "content/public/browser/browser_thread.h" #include "ui/events/latency_info.h" -using WebKit::WebInputEvent; +using blink::WebInputEvent; namespace content { @@ -22,14 +22,14 @@ SynchronousInputEventFilter::~SynchronousInputEventFilter() { InputEventAckState SynchronousInputEventFilter::HandleInputEvent( int routing_id, - const WebKit::WebInputEvent& input_event) { + const blink::WebInputEvent& input_event) { // The handler will be empty both before renderer initialization and after // renderer destruction. It's possible that this will be reached in such a // state. While not good, it should also not be fatal. if (handler_.is_null()) return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; - - return handler_.Run(routing_id, &input_event, ui::LatencyInfo()); + ui::LatencyInfo latency; + return handler_.Run(routing_id, &input_event, &latency); } void SynchronousInputEventFilter::SetBoundHandler(const Handler& handler) { diff --git a/chromium/content/browser/android/in_process/synchronous_input_event_filter.h b/chromium/content/browser/android/in_process/synchronous_input_event_filter.h index 18601c222ae..a6fa68fcfda 100644 --- a/chromium/content/browser/android/in_process/synchronous_input_event_filter.h +++ b/chromium/content/browser/android/in_process/synchronous_input_event_filter.h @@ -9,10 +9,10 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "content/port/common/input_event_ack_state.h" -#include "content/renderer/gpu/input_handler_manager_client.h" +#include "content/renderer/input/input_handler_manager_client.h" #include "ui/gfx/vector2d_f.h" -namespace WebKit { +namespace blink { class WebInputEvent; } @@ -29,7 +29,7 @@ class SynchronousInputEventFilter : public InputHandlerManagerClient { virtual ~SynchronousInputEventFilter(); InputEventAckState HandleInputEvent(int routing_id, - const WebKit::WebInputEvent& input_event); + const blink::WebInputEvent& input_event); // InputHandlerManagerClient implementation. virtual void SetBoundHandler(const Handler& handler) OVERRIDE; diff --git a/chromium/content/browser/android/interstitial_page_delegate_android.cc b/chromium/content/browser/android/interstitial_page_delegate_android.cc index 4ed48907bed..f598cd36a5c 100644 --- a/chromium/content/browser/android/interstitial_page_delegate_android.cc +++ b/chromium/content/browser/android/interstitial_page_delegate_android.cc @@ -84,11 +84,11 @@ bool InterstitialPageDelegateAndroid return RegisterNativesImpl(env); } -static jint Init(JNIEnv* env, jobject obj, jstring html_content) { +static jlong Init(JNIEnv* env, jobject obj, jstring html_content) { InterstitialPageDelegateAndroid* delegate = new InterstitialPageDelegateAndroid( env, obj, base::android::ConvertJavaStringToUTF8(env, html_content)); - return reinterpret_cast<jint>(delegate); + return reinterpret_cast<intptr_t>(delegate); } } // namespace content diff --git a/chromium/content/browser/android/overscroll_glow.cc b/chromium/content/browser/android/overscroll_glow.cc index 6adf7dbec48..8e08de45eca 100644 --- a/chromium/content/browser/android/overscroll_glow.cc +++ b/chromium/content/browser/android/overscroll_glow.cc @@ -6,6 +6,7 @@ #include "base/debug/trace_event.h" #include "base/lazy_instance.h" +#include "base/threading/worker_pool.h" #include "cc/layers/image_layer.h" #include "content/browser/android/edge_effect.h" #include "ui/gfx/android/java_bitmap.h" @@ -63,54 +64,61 @@ gfx::Vector2dF ZeroSmallComponents(gfx::Vector2dF vector) { return vector; } +// Force loading of any necessary resources. This function is thread-safe. +void EnsureResources() { + g_overscroll_resources.Get(); +} + } // namespace -scoped_ptr<OverscrollGlow> OverscrollGlow::Create(bool enabled, - gfx::SizeF size) { - const SkBitmap& edge = g_overscroll_resources.Get().edge_bitmap(); - const SkBitmap& glow = g_overscroll_resources.Get().glow_bitmap(); - if (edge.isNull() || glow.isNull()) - return scoped_ptr<OverscrollGlow>(); +scoped_ptr<OverscrollGlow> OverscrollGlow::Create(bool enabled) { + // Don't block the main thread with effect resource loading during creation. + // Effect instantiation is deferred until the effect overscrolls, in which + // case the main thread may block until the resource has loaded. + if (enabled && g_overscroll_resources == NULL) + base::WorkerPool::PostTask(FROM_HERE, base::Bind(EnsureResources), true); - return make_scoped_ptr(new OverscrollGlow(enabled, size, edge, glow)); + return make_scoped_ptr(new OverscrollGlow(enabled)); } -void OverscrollGlow::EnsureResources() { - g_overscroll_resources.Get(); -} - -OverscrollGlow::OverscrollGlow(bool enabled, - gfx::SizeF size, - const SkBitmap& edge, - const SkBitmap& glow) +OverscrollGlow::OverscrollGlow(bool enabled) : enabled_(enabled), - size_(size), + initialized_(false), horizontal_overscroll_enabled_(true), - vertical_overscroll_enabled_(true), - root_layer_(cc::Layer::Create()) { - for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { - scoped_refptr<cc::Layer> edge_layer = CreateImageLayer(edge); - scoped_refptr<cc::Layer> glow_layer = CreateImageLayer(glow); - root_layer_->AddChild(edge_layer); - root_layer_->AddChild(glow_layer); - edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer)); - } -} + vertical_overscroll_enabled_(true) {} OverscrollGlow::~OverscrollGlow() { - root_layer_->RemoveFromParent(); + Detach(); +} + +void OverscrollGlow::Enable() { + enabled_ = true; +} + +void OverscrollGlow::Disable() { + if (!enabled_) + return; + enabled_ = false; + if (!enabled_ && initialized_) { + Detach(); + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) + edge_effects_[i]->Finish(); + } } -void OverscrollGlow::OnOverscrolled(base::TimeTicks current_time, +bool OverscrollGlow::OnOverscrolled(cc::Layer* overscrolling_layer, + base::TimeTicks current_time, gfx::Vector2dF overscroll, gfx::Vector2dF velocity) { + DCHECK(overscrolling_layer); + if (!enabled_) - return; + return false; // The size of the glow determines the relative effect of the inputs; an // empty-sized effect is effectively disabled. if (size_.IsEmpty()) - return; + return false; if (!horizontal_overscroll_enabled_) { overscroll.set_x(0); @@ -126,10 +134,16 @@ void OverscrollGlow::OnOverscrolled(base::TimeTicks current_time, velocity = ZeroSmallComponents(velocity); if (overscroll.IsZero()) { - Release(current_time); - return; + if (initialized_) { + Release(current_time); + UpdateLayerAttachment(overscrolling_layer); + } + return NeedsAnimate(); } + if (!InitializeIfNecessary()) + return false; + if (!velocity.IsZero()) { // Release effects if scrolling has changed directions. if (velocity.x() * old_velocity_.x() < 0) @@ -152,18 +166,16 @@ void OverscrollGlow::OnOverscrolled(base::TimeTicks current_time, old_velocity_ = velocity; old_overscroll_ = overscroll; -} -void OverscrollGlow::Release(base::TimeTicks current_time) { - for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { - edge_effects_[i]->Release(current_time); - } - old_overscroll_ = old_velocity_ = gfx::Vector2dF(); + UpdateLayerAttachment(overscrolling_layer); + return NeedsAnimate(); } bool OverscrollGlow::Animate(base::TimeTicks current_time) { - if (!NeedsAnimate()) + if (!NeedsAnimate()) { + Detach(); return false; + } const gfx::SizeF sizes[EdgeEffect::EDGE_COUNT] = { size_, gfx::SizeF(size_.height(), size_.width()), @@ -177,21 +189,16 @@ bool OverscrollGlow::Animate(base::TimeTicks current_time) { } } - return NeedsAnimate(); -} - -void OverscrollGlow::SetEnabled(bool enabled) { - if (enabled_ == enabled) - return; - enabled_ = enabled; - if (!enabled_) { - for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) - edge_effects_[i]->Finish(); + if (!NeedsAnimate()) { + Detach(); + return false; } + + return true; } bool OverscrollGlow::NeedsAnimate() const { - if (!enabled_) + if (!enabled_ || !initialized_) return false; for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { if (!edge_effects_[i]->IsFinished()) @@ -200,8 +207,54 @@ bool OverscrollGlow::NeedsAnimate() const { return false; } +void OverscrollGlow::UpdateLayerAttachment(cc::Layer* parent) { + DCHECK(parent); + if (!root_layer_) + return; + + if (!NeedsAnimate()) { + Detach(); + return; + } + + if (root_layer_->parent() != parent) + parent->AddChild(root_layer_); +} + +void OverscrollGlow::Detach() { + if (root_layer_) + root_layer_->RemoveFromParent(); +} + +bool OverscrollGlow::InitializeIfNecessary() { + DCHECK(enabled_); + if (initialized_) + return true; + + const SkBitmap& edge = g_overscroll_resources.Get().edge_bitmap(); + const SkBitmap& glow = g_overscroll_resources.Get().glow_bitmap(); + if (edge.isNull() || glow.isNull()) { + Disable(); + return false; + } + + DCHECK(!root_layer_); + root_layer_ = cc::Layer::Create(); + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + scoped_refptr<cc::Layer> edge_layer = CreateImageLayer(edge); + scoped_refptr<cc::Layer> glow_layer = CreateImageLayer(glow); + root_layer_->AddChild(edge_layer); + root_layer_->AddChild(glow_layer); + edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer)); + } + + initialized_ = true; + return true; +} + void OverscrollGlow::Pull(base::TimeTicks current_time, gfx::Vector2dF overscroll_delta) { + DCHECK(enabled_ && initialized_); overscroll_delta = ZeroSmallComponents(overscroll_delta); if (overscroll_delta.IsZero()) return; @@ -229,6 +282,7 @@ void OverscrollGlow::Absorb(base::TimeTicks current_time, gfx::Vector2dF velocity, gfx::Vector2dF overscroll, gfx::Vector2dF old_overscroll) { + DCHECK(enabled_ && initialized_); if (overscroll.IsZero() || velocity.IsZero()) return; @@ -249,7 +303,16 @@ void OverscrollGlow::Absorb(base::TimeTicks current_time, } } +void OverscrollGlow::Release(base::TimeTicks current_time) { + DCHECK(initialized_); + for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { + edge_effects_[i]->Release(current_time); + } + old_overscroll_ = old_velocity_ = gfx::Vector2dF(); +} + void OverscrollGlow::ReleaseAxis(Axis axis, base::TimeTicks current_time) { + DCHECK(initialized_); switch (axis) { case AXIS_X: edge_effects_[EdgeEffect::EDGE_LEFT]->Release(current_time); @@ -267,6 +330,7 @@ void OverscrollGlow::ReleaseAxis(Axis axis, base::TimeTicks current_time) { } EdgeEffect* OverscrollGlow::GetOppositeEdge(int edge_index) { + DCHECK(initialized_); return edge_effects_[(edge_index + 2) % EdgeEffect::EDGE_COUNT].get(); } diff --git a/chromium/content/browser/android/overscroll_glow.h b/chromium/content/browser/android/overscroll_glow.h index 01156a23f03..3a13fb3c4f1 100644 --- a/chromium/content/browser/android/overscroll_glow.h +++ b/chromium/content/browser/android/overscroll_glow.h @@ -26,43 +26,35 @@ namespace content { */ class OverscrollGlow { public: - // Create and initialize a new effect with the necessary resources. - // If |enabled| is false, the effect will be be deactivated until - // SetEnabled(true) is called. - // The caller should attach |root_layer| to the desired layer tree. - static scoped_ptr<OverscrollGlow> Create(bool enabled, gfx::SizeF size); - - // Force loading of any necessary resources. This function is thread-safe. - static void EnsureResources(); + // Create a new effect. If |enabled| is false, the effect will remain + // deactivated until explicitly enabled. + // Note: No resources will be allocated until the effect is both + // enabled and an overscroll event has occurred. + static scoped_ptr<OverscrollGlow> Create(bool enabled); ~OverscrollGlow(); - // If false, the glow will be deactivated, and subsequent calls to - // OnOverscrolled or Animate will have no effect. - void SetEnabled(bool enabled); + // Enable the effect. If the effect was previously disabled, it will remain + // dormant until subsequent calls to |OnOverscrolled()|. + void Enable(); + + // Deactivate and detach the effect. Subsequent calls to |OnOverscrolled()| or + // |Animate()| will have no effect. + void Disable(); + // Effect layers will be attached to |overscrolling_layer| if necessary. // |overscroll| is the accumulated overscroll for the current gesture. // |velocity| is the instantaneous velocity for the overscroll. - void OnOverscrolled(base::TimeTicks current_time, + // Returns true if the effect still needs animation ticks. + bool OnOverscrolled(cc::Layer* overscrolling_layer, + base::TimeTicks current_time, gfx::Vector2dF overscroll, gfx::Vector2dF velocity); - // Triggers glow recession for any active edges. - // Note: This does not actually release any resources; the name mirrors that - // in Android's OverscrollGlow class. - void Release(base::TimeTicks current_time); - // Returns true if the effect still needs animation ticks. + // Note: The effect will detach itself when no further animation is required. bool Animate(base::TimeTicks current_time); - // Returns true if the effect needs animation ticks. - bool NeedsAnimate() const; - - // The root layer of the effect (not necessarily of the tree). - scoped_refptr<cc::Layer> root_layer() const { - return root_layer_; - } - // Horizontal overscroll will be ignored when false. void set_horizontal_overscroll_enabled(bool enabled) { horizontal_overscroll_enabled_ = enabled; @@ -79,18 +71,20 @@ class OverscrollGlow { private: enum Axis { AXIS_X, AXIS_Y }; - OverscrollGlow(bool enabled, - gfx::SizeF size, - const SkBitmap& edge, - const SkBitmap& glow); + OverscrollGlow(bool enabled); + // Returns whether the effect is initialized. + bool InitializeIfNecessary(); + bool NeedsAnimate() const; + void UpdateLayerAttachment(cc::Layer* parent); + void Detach(); void Pull(base::TimeTicks current_time, gfx::Vector2dF added_overscroll); void Absorb(base::TimeTicks current_time, gfx::Vector2dF velocity, gfx::Vector2dF overscroll, gfx::Vector2dF old_overscroll); - + void Release(base::TimeTicks current_time); void ReleaseAxis(Axis axis, base::TimeTicks current_time); EdgeEffect* GetOppositeEdge(int edge_index); @@ -98,6 +92,7 @@ class OverscrollGlow { scoped_ptr<EdgeEffect> edge_effects_[EdgeEffect::EDGE_COUNT]; bool enabled_; + bool initialized_; gfx::SizeF size_; gfx::Vector2dF old_overscroll_; gfx::Vector2dF old_velocity_; diff --git a/chromium/content/browser/android/popup_item_type_list.h b/chromium/content/browser/android/popup_item_type_list.h new file mode 100644 index 00000000000..3f50490f610 --- /dev/null +++ b/chromium/content/browser/android/popup_item_type_list.h @@ -0,0 +1,23 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file intentionally does not have header guards because this file +// is meant to be included inside a macro to generate enum values. + +// This file contains a list of sync PopupItemTypes which describe the type +// and enabled state of a select popup item. List is used by Android when +// displaying a new select popup menu. + +#ifndef DEFINE_POPUP_ITEM_TYPE +#error "Please define DEFINE_POPUP_ITEM_TYPE before including this file." +#endif + +// Popup item is of type group +DEFINE_POPUP_ITEM_TYPE(GROUP, 0) + +// Popup item is disabled +DEFINE_POPUP_ITEM_TYPE(DISABLED, 1) + +// Popup item is enabled +DEFINE_POPUP_ITEM_TYPE(ENABLED, 2) diff --git a/chromium/content/browser/android/touch_point.cc b/chromium/content/browser/android/touch_point.cc index 1a10e6ecfca..ffe2e50507c 100644 --- a/chromium/content/browser/android/touch_point.cc +++ b/chromium/content/browser/android/touch_point.cc @@ -10,15 +10,15 @@ #include "jni/TouchPoint_jni.h" -using WebKit::WebTouchEvent; -using WebKit::WebTouchPoint; +using blink::WebTouchEvent; +using blink::WebTouchPoint; namespace { void MaybeAddTouchPoint(JNIEnv* env, jobject pt, float dpi_scale, - WebKit::WebTouchEvent& event) { + blink::WebTouchEvent& event) { WebTouchPoint::State state = static_cast<WebTouchPoint::State>( Java_TouchPoint_getState(env, pt)); if (state == WebTouchPoint::StateUndefined) @@ -32,7 +32,7 @@ void MaybeAddTouchPoint(JNIEnv* env, // Record the current number of points in the WebTouchEvent const int idx = event.touchesLength; - DCHECK_LT(idx, WebKit::WebTouchEvent::touchesLengthCap); + DCHECK_LT(idx, blink::WebTouchEvent::touchesLengthCap); WebTouchPoint wtp; wtp.id = Java_TouchPoint_getId(env, pt); @@ -43,20 +43,28 @@ void MaybeAddTouchPoint(JNIEnv* env, wtp.screenPosition = wtp.position; wtp.force = Java_TouchPoint_getPressure(env, pt); - // TODO(djsollen): WebKit stores touch point size as a pair of radii, which - // are integers. We receive touch point size from Android as a float - // between 0 and 1 and interpret 'size' as an elliptical area. We convert - // size to a radius and then scale up to avoid truncating away all of the - // data. W3C spec is for the radii to be in units of screen pixels. Need to - // change. - const static double PI = 3.1415926; - const static double SCALE_FACTOR = 1024.0; - const int radius = static_cast<int>( - (sqrt(Java_TouchPoint_getSize(env, pt)) / PI) * SCALE_FACTOR); - wtp.radiusX = radius / dpi_scale; - wtp.radiusY = radius / dpi_scale; - // Since our radii are equal, a rotation angle doesn't mean anything. - wtp.rotationAngle = 0.0; + const int radiusMajor = static_cast<int>( + Java_TouchPoint_getTouchMajor(env, pt) * 0.5f / dpi_scale); + const int radiusMinor = static_cast<int>( + Java_TouchPoint_getTouchMinor(env, pt) * 0.5f / dpi_scale); + const float majorAngleInRadiansClockwiseFromVertical = + Java_TouchPoint_getOrientation(env, pt); + const float majorAngleInDegreesClockwiseFromVertical = + std::isnan(majorAngleInRadiansClockwiseFromVertical) + ? 0.f : (majorAngleInRadiansClockwiseFromVertical * 180.f) / M_PI; + // Android provides a major axis orientation clockwise with respect to the + // vertical of [-90, 90], while the W3C specifies a range of [0, 90]. + if (majorAngleInDegreesClockwiseFromVertical >= 0) { + wtp.radiusX = radiusMinor; + wtp.radiusY = radiusMajor; + wtp.rotationAngle = majorAngleInDegreesClockwiseFromVertical; + } else { + wtp.radiusX = radiusMajor; + wtp.radiusY = radiusMinor; + wtp.rotationAngle = majorAngleInDegreesClockwiseFromVertical + 90.f; + } + DCHECK_GE(wtp.rotationAngle, 0.f); + DCHECK_LE(wtp.rotationAngle, 90.f); // Add the newly created WebTouchPoint to the event event.touches[idx] = wtp; @@ -72,7 +80,7 @@ void TouchPoint::BuildWebTouchEvent(JNIEnv* env, jlong time_ms, float dpi_scale, jobjectArray pts, - WebKit::WebTouchEvent& event) { + blink::WebTouchEvent& event) { event.type = static_cast<WebTouchEvent::Type>(type); event.timeStampSeconds = static_cast<double>(time_ms) / base::Time::kMillisecondsPerSecond; @@ -91,16 +99,16 @@ void TouchPoint::BuildWebTouchEvent(JNIEnv* env, static void RegisterConstants(JNIEnv* env) { Java_TouchPoint_initializeConstants( env, - WebKit::WebTouchEvent::TouchStart, - WebKit::WebTouchEvent::TouchMove, - WebKit::WebTouchEvent::TouchEnd, - WebKit::WebTouchEvent::TouchCancel, - WebKit::WebTouchPoint::StateUndefined, - WebKit::WebTouchPoint::StateReleased, - WebKit::WebTouchPoint::StatePressed, - WebKit::WebTouchPoint::StateMoved, - WebKit::WebTouchPoint::StateStationary, - WebKit::WebTouchPoint::StateCancelled); + blink::WebTouchEvent::TouchStart, + blink::WebTouchEvent::TouchMove, + blink::WebTouchEvent::TouchEnd, + blink::WebTouchEvent::TouchCancel, + blink::WebTouchPoint::StateUndefined, + blink::WebTouchPoint::StateReleased, + blink::WebTouchPoint::StatePressed, + blink::WebTouchPoint::StateMoved, + blink::WebTouchPoint::StateStationary, + blink::WebTouchPoint::StateCancelled); } bool RegisterTouchPoint(JNIEnv* env) { diff --git a/chromium/content/browser/android/touch_point.h b/chromium/content/browser/android/touch_point.h index 8e9971bad5c..d7caac08764 100644 --- a/chromium/content/browser/android/touch_point.h +++ b/chromium/content/browser/android/touch_point.h @@ -12,7 +12,7 @@ namespace content { // This class provides a helper method to convert a java object array of touch -// events (in physical pixdels) into a WebKit::WebTouchEvent (in dip). +// events (in physical pixdels) into a blink::WebTouchEvent (in dip). class TouchPoint { public: static void BuildWebTouchEvent(JNIEnv* env, @@ -20,7 +20,7 @@ class TouchPoint { jlong time_ms, float dpi_scale, jobjectArray pts, - WebKit::WebTouchEvent& event); + blink::WebTouchEvent& event); }; bool RegisterTouchPoint(JNIEnv* env); diff --git a/chromium/content/browser/android/tracing_controller_android.cc b/chromium/content/browser/android/tracing_controller_android.cc new file mode 100644 index 00000000000..75ac6d7c238 --- /dev/null +++ b/chromium/content/browser/android/tracing_controller_android.cc @@ -0,0 +1,78 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/tracing_controller_android.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/debug/trace_event.h" +#include "base/logging.h" +#include "content/public/browser/tracing_controller.h" +#include "jni/TracingControllerAndroid_jni.h" + +namespace content { + +static jlong Init(JNIEnv* env, jobject obj) { + TracingControllerAndroid* profiler = new TracingControllerAndroid(env, obj); + return reinterpret_cast<intptr_t>(profiler); +} + +TracingControllerAndroid::TracingControllerAndroid(JNIEnv* env, jobject obj) + : weak_java_object_(env, obj), + weak_factory_(this) {} + +TracingControllerAndroid::~TracingControllerAndroid() {} + +void TracingControllerAndroid::Destroy(JNIEnv* env, jobject obj) { + delete this; +} + +bool TracingControllerAndroid::StartTracing(JNIEnv* env, + jobject obj, + jstring jfilename, + jstring jcategories, + jboolean record_continuously) { + file_path_ = base::FilePath( + base::android::ConvertJavaStringToUTF8(env, jfilename)); + std::string categories = + base::android::ConvertJavaStringToUTF8(env, jcategories); + + // This log is required by adb_profile_chrome.py. + LOG(WARNING) << "Logging performance trace to file: " << file_path_.value(); + + return TracingController::GetInstance()->EnableRecording( + categories, + record_continuously ? TracingController::RECORD_CONTINUOUSLY + : TracingController::DEFAULT_OPTIONS, + TracingController::EnableRecordingDoneCallback()); +} + +void TracingControllerAndroid::StopTracing(JNIEnv* env, jobject obj) { + if (!TracingController::GetInstance()->DisableRecording( + file_path_, + base::Bind(&TracingControllerAndroid::OnTracingStopped, + weak_factory_.GetWeakPtr()))) { + LOG(ERROR) << "EndTracingAsync failed, forcing an immediate stop"; + OnTracingStopped(file_path_); + } +} + +void TracingControllerAndroid::OnTracingStopped( + const base::FilePath& file_path) { + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jobject> obj = weak_java_object_.get(env); + if (obj.obj()) + Java_TracingControllerAndroid_onTracingStopped(env, obj.obj()); +} + +static jstring GetDefaultCategories(JNIEnv* env, jobject obj) { + return base::android::ConvertUTF8ToJavaString(env, + base::debug::CategoryFilter::kDefaultCategoryFilterString).Release(); +} + +bool RegisterTracingControllerAndroid(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +} // namespace content diff --git a/chromium/content/browser/android/tracing_controller_android.h b/chromium/content/browser/android/tracing_controller_android.h new file mode 100644 index 00000000000..4d70e7b75ef --- /dev/null +++ b/chromium/content/browser/android/tracing_controller_android.h @@ -0,0 +1,43 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_ANDROID_TRACING_CONTROLLER_ANDROID_H_ +#define CONTENT_BROWSER_ANDROID_TRACING_CONTROLLER_ANDROID_H_ + +#include "base/android/jni_helper.h" +#include "base/files/file_path.h" +#include "base/memory/weak_ptr.h" + +namespace content { + +// This class implements the native methods of TracingControllerAndroid.java +class TracingControllerAndroid { + public: + TracingControllerAndroid(JNIEnv* env, jobject obj); + void Destroy(JNIEnv* env, jobject obj); + + bool StartTracing(JNIEnv* env, + jobject obj, + jstring filename, + jstring categories, + jboolean record_continuously); + void StopTracing(JNIEnv* env, jobject obj); + + private: + ~TracingControllerAndroid(); + void OnTracingStopped(const base::FilePath& file_path); + + JavaObjectWeakGlobalRef weak_java_object_; + base::FilePath file_path_; + base::WeakPtrFactory<TracingControllerAndroid> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(TracingControllerAndroid); +}; + +// Register this class's native methods through jni. +bool RegisterTracingControllerAndroid(JNIEnv* env); + +} // namespace content + +#endif // CONTENT_BROWSER_ANDROID_TRACING_CONTROLLER_ANDROID_H_ diff --git a/chromium/content/browser/android/tracing_intent_handler.cc b/chromium/content/browser/android/tracing_intent_handler.cc deleted file mode 100644 index 324f8055cc1..00000000000 --- a/chromium/content/browser/android/tracing_intent_handler.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/android/tracing_intent_handler.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_string.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "content/public/browser/trace_controller.h" -#include "jni/TracingIntentHandler_jni.h" - -namespace content { - -TracingIntentHandler* g_trace_intent_handler = NULL; - -TracingIntentHandler::TracingIntentHandler(const base::FilePath& path) - : TraceSubscriberStdio(path, FILE_TYPE_ARRAY, false) { - TraceController::GetInstance()->BeginTracing( - this, - std::string("-test*"), - base::debug::TraceLog::RECORD_UNTIL_FULL); -} - -TracingIntentHandler::~TracingIntentHandler() { -} - -void TracingIntentHandler::OnEndTracingComplete() { - TraceSubscriberStdio::OnEndTracingComplete(); - delete this; -} - -void TracingIntentHandler::OnEndTracing() { - if (!TraceController::GetInstance()->EndTracingAsync(this)) { - delete this; - } -} - -static void BeginTracing(JNIEnv* env, jclass clazz, jstring jspath) { - std::string path(base::android::ConvertJavaStringToUTF8(env, jspath)); - if (g_trace_intent_handler != NULL) - return; - g_trace_intent_handler = new TracingIntentHandler(base::FilePath(path)); -} - -static void EndTracing(JNIEnv* env, jclass clazz) { - DCHECK(!g_trace_intent_handler); - g_trace_intent_handler->OnEndTracing(); - g_trace_intent_handler = NULL; -} - -bool RegisterTracingIntentHandler(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace content diff --git a/chromium/content/browser/android/tracing_intent_handler.h b/chromium/content/browser/android/tracing_intent_handler.h deleted file mode 100644 index 787f854e628..00000000000 --- a/chromium/content/browser/android/tracing_intent_handler.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_ANDROID_TRACING_INTENT_HANDLER_H_ -#define CONTENT_BROWSER_ANDROID_TRACING_INTENT_HANDLER_H_ - -#include <jni.h> -#include <string> - -#include "content/browser/tracing/trace_subscriber_stdio.h" - -namespace content { - -// Registers the TracingIntentHandler native methods. -bool RegisterTracingIntentHandler(JNIEnv* env); - -class TracingIntentHandler : public TraceSubscriberStdio { - public: - explicit TracingIntentHandler(const base::FilePath& path); - virtual ~TracingIntentHandler(); - - // TraceSubscriber implementation - virtual void OnEndTracingComplete() OVERRIDE; - - // IntentHandler - void OnEndTracing(); -}; - -} // namespace content -#endif // CONTENT_BROWSER_ANDROID_TRACING_INTENT_HANDLER_H_ diff --git a/chromium/content/browser/android/vibration_message_filter.cc b/chromium/content/browser/android/vibration_message_filter.cc deleted file mode 100644 index 578fbfdf6e9..00000000000 --- a/chromium/content/browser/android/vibration_message_filter.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/android/vibration_message_filter.h" - -#include <algorithm> - -#include "base/safe_numerics.h" -#include "content/common/view_messages.h" -#include "jni/VibrationMessageFilter_jni.h" -#include "third_party/WebKit/public/platform/WebVibration.h" - -using base::android::AttachCurrentThread; - -namespace content { - -// Minimum duration of a vibration is 1 millisecond. -const int64 kMinimumVibrationDurationMs = 1; - -VibrationMessageFilter::VibrationMessageFilter() { -} - -VibrationMessageFilter::~VibrationMessageFilter() { -} - -// static -bool VibrationMessageFilter::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -bool VibrationMessageFilter::OnMessageReceived( - const IPC::Message& message, - bool* message_was_ok) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_EX(VibrationMessageFilter, - message, - *message_was_ok) - IPC_MESSAGE_HANDLER(ViewHostMsg_Vibrate, OnVibrate) - IPC_MESSAGE_HANDLER(ViewHostMsg_CancelVibration, OnCancelVibration) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP_EX() - return handled; -} - -void VibrationMessageFilter::OnVibrate(int64 milliseconds) { - // Though the Blink implementation already sanitizes vibration times, don't - // trust any values passed from the renderer. - milliseconds = std::max(kMinimumVibrationDurationMs, - std::min(milliseconds, - base::checked_numeric_cast<int64>(WebKit::kVibrationDurationMax))); - - if (j_vibration_message_filter_.is_null()) { - j_vibration_message_filter_.Reset( - Java_VibrationMessageFilter_create( - AttachCurrentThread(), - base::android::GetApplicationContext())); - } - Java_VibrationMessageFilter_vibrate(AttachCurrentThread(), - j_vibration_message_filter_.obj(), - milliseconds); -} - -void VibrationMessageFilter::OnCancelVibration() { - Java_VibrationMessageFilter_cancelVibration(AttachCurrentThread(), - j_vibration_message_filter_.obj()); -} - -} // namespace content diff --git a/chromium/content/browser/android/vibration_message_filter.h b/chromium/content/browser/android/vibration_message_filter.h deleted file mode 100644 index 935b6106625..00000000000 --- a/chromium/content/browser/android/vibration_message_filter.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_ANDROID_VIBRATION_MESSAGE_FILTER_H_ -#define CONTENT_BROWSER_ANDROID_VIBRATION_MESSAGE_FILTER_H_ - -#include "base/android/jni_android.h" -#include "content/public/browser/browser_message_filter.h" - -namespace content { - -class VibrationMessageFilter : public BrowserMessageFilter { - public: - VibrationMessageFilter(); - - static bool Register(JNIEnv* env); - - private: - virtual ~VibrationMessageFilter(); - - // BrowserMessageFilter implementation. - virtual bool OnMessageReceived(const IPC::Message& message, - bool* message_was_ok) OVERRIDE; - - void OnVibrate(int64 milliseconds); - void OnCancelVibration(); - - base::android::ScopedJavaGlobalRef<jobject> j_vibration_message_filter_; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_ANDROID_VIBRATION_MESSAGE_FILTER_H_ diff --git a/chromium/content/browser/android/web_contents_observer_android.cc b/chromium/content/browser/android/web_contents_observer_android.cc index e30bf953304..797ea3b1af9 100644 --- a/chromium/content/browser/android/web_contents_observer_android.cc +++ b/chromium/content/browser/android/web_contents_observer_android.cc @@ -22,7 +22,6 @@ using base::android::AttachCurrentThread; using base::android::ScopedJavaLocalRef; using base::android::ConvertUTF8ToJavaString; using base::android::ConvertUTF16ToJavaString; -using base::android::HasClass; namespace content { @@ -37,12 +36,12 @@ WebContentsObserverAndroid::WebContentsObserverAndroid( WebContentsObserverAndroid::~WebContentsObserverAndroid() { } -jint Init(JNIEnv* env, jobject obj, jint native_content_view_core) { +jlong Init(JNIEnv* env, jobject obj, jlong native_content_view_core) { ContentViewCore* content_view_core = reinterpret_cast<ContentViewCore*>(native_content_view_core); WebContentsObserverAndroid* native_observer = new WebContentsObserverAndroid( env, obj, content_view_core->GetWebContents()); - return reinterpret_cast<jint>(native_observer); + return reinterpret_cast<intptr_t>(native_observer); } void WebContentsObserverAndroid::Destroy(JNIEnv* env, jobject obj) { @@ -61,6 +60,18 @@ void WebContentsObserverAndroid::WebContentsDestroyed( } } +void WebContentsObserverAndroid::RenderProcessGone( + base::TerminationStatus termination_status) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); + if (obj.is_null()) + return; + jboolean was_oom_protected = + termination_status == base::TERMINATION_STATUS_OOM_PROTECTED; + Java_WebContentsObserverAndroid_renderProcessGone( + env, obj.obj(), was_oom_protected); +} + void WebContentsObserverAndroid::DidStartLoading( RenderViewHost* render_view_host) { JNIEnv* env = AttachCurrentThread(); @@ -79,29 +90,19 @@ void WebContentsObserverAndroid::DidStopLoading( ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); if (obj.is_null()) return; - - std::string url_string; - NavigationEntry* entry = - web_contents()->GetController().GetLastCommittedEntry(); - // Not that GetBaseURLForDataURL is only used by the Android WebView - if (entry && !entry->GetBaseURLForDataURL().is_empty()) { - url_string = entry->GetBaseURLForDataURL().possibly_invalid_spec(); - } else { - url_string = web_contents()->GetLastCommittedURL().spec(); - } - - ScopedJavaLocalRef<jstring> jstring_url( - ConvertUTF8ToJavaString(env, url_string)); + ScopedJavaLocalRef<jstring> jstring_url(ConvertUTF8ToJavaString( + env, web_contents()->GetLastCommittedURL().spec())); Java_WebContentsObserverAndroid_didStopLoading( env, obj.obj(), jstring_url.obj()); } void WebContentsObserverAndroid::DidFailProvisionalLoad( int64 frame_id, + const base::string16& frame_unique_name, bool is_main_frame, const GURL& validated_url, int error_code, - const string16& error_description, + const base::string16& error_description, RenderViewHost* render_view_host) { DidFailLoadInternal( true, is_main_frame, error_code, error_description, validated_url); @@ -112,7 +113,7 @@ void WebContentsObserverAndroid::DidFailLoad( const GURL& validated_url, bool is_main_frame, int error_code, - const string16& error_description, + const base::string16& error_description, RenderViewHost* render_view_host) { DidFailLoadInternal( false, is_main_frame, error_code, error_description, validated_url); @@ -129,9 +130,16 @@ void WebContentsObserverAndroid::DidNavigateMainFrame( ConvertUTF8ToJavaString(env, params.url.spec())); ScopedJavaLocalRef<jstring> jstring_base_url( ConvertUTF8ToJavaString(env, params.base_url.spec())); - Java_WebContentsObserverAndroid_didNavigateMainFrame( + // See http://crbug.com/251330 for why it's determined this way. + bool in_page_navigation = + details.type == NAVIGATION_TYPE_IN_PAGE || details.is_in_page; + // TODO(mkosiba): delete once downstream rolls. + Java_WebContentsObserverAndroid_didNavigateMainFrameV_JLS_JLS_Z( env, obj.obj(), jstring_url.obj(), jstring_base_url.obj(), details.is_navigation_to_different_page()); + Java_WebContentsObserverAndroid_didNavigateMainFrameV_JLS_JLS_Z_Z( + env, obj.obj(), jstring_url.obj(), jstring_base_url.obj(), + details.is_navigation_to_different_page(), in_page_navigation); } void WebContentsObserverAndroid::DidNavigateAnyFrame( @@ -174,6 +182,7 @@ void WebContentsObserverAndroid::DidStartProvisionalLoadForFrame( void WebContentsObserverAndroid::DidCommitProvisionalLoadForFrame( int64 frame_id, + const base::string16& frame_unique_name, bool is_main_frame, const GURL& url, PageTransition transition_type, @@ -198,12 +207,29 @@ void WebContentsObserverAndroid::DidFinishLoad( ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); if (obj.is_null()) return; + + std::string url_string = validated_url.spec(); + NavigationEntry* entry = + web_contents()->GetController().GetLastCommittedEntry(); + // Note that GetBaseURLForDataURL is only used by the Android WebView. + if (entry && !entry->GetBaseURLForDataURL().is_empty()) + url_string = entry->GetBaseURLForDataURL().possibly_invalid_spec(); + ScopedJavaLocalRef<jstring> jstring_url( - ConvertUTF8ToJavaString(env, validated_url.spec())); + ConvertUTF8ToJavaString(env, url_string)); Java_WebContentsObserverAndroid_didFinishLoad( env, obj.obj(), frame_id, jstring_url.obj(), is_main_frame); } +void WebContentsObserverAndroid::NavigationEntryCommitted( + const LoadCommittedDetails& load_details) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); + if (obj.is_null()) + return; + Java_WebContentsObserverAndroid_navigationEntryCommitted(env, obj.obj()); +} + void WebContentsObserverAndroid::DidChangeVisibleSSLState() { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); @@ -232,7 +258,7 @@ void WebContentsObserverAndroid::DidFailLoadInternal( bool is_provisional_load, bool is_main_frame, int error_code, - const string16& description, + const base::string16& description, const GURL& url) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env)); @@ -252,10 +278,6 @@ void WebContentsObserverAndroid::DidFailLoadInternal( } bool RegisterWebContentsObserverAndroid(JNIEnv* env) { - if (!HasClass(env, kWebContentsObserverAndroidClassPath)) { - DLOG(ERROR) << "Unable to find class WebContentsObserverAndroid!"; - return false; - } return RegisterNativesImpl(env); } } // namespace content diff --git a/chromium/content/browser/android/web_contents_observer_android.h b/chromium/content/browser/android/web_contents_observer_android.h index e975d795260..15a136390f8 100644 --- a/chromium/content/browser/android/web_contents_observer_android.h +++ b/chromium/content/browser/android/web_contents_observer_android.h @@ -9,6 +9,7 @@ #include "base/android/jni_helper.h" #include "base/basictypes.h" +#include "base/process/kill.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/frame_navigate_params.h" @@ -31,20 +32,23 @@ class WebContentsObserverAndroid : public WebContentsObserver { void Destroy(JNIEnv* env, jobject obj); private: + virtual void RenderProcessGone( + base::TerminationStatus termination_status) OVERRIDE; virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE; virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE; virtual void DidFailProvisionalLoad( int64 frame_id, + const base::string16& frame_unique_name, bool is_main_frame, const GURL& validated_url, int error_code, - const string16& error_description, + const base::string16& error_description, RenderViewHost* render_view_host) OVERRIDE; virtual void DidFailLoad(int64 frame_id, const GURL& validated_url, bool is_main_frame, int error_code, - const string16& error_description, + const base::string16& error_description, RenderViewHost* render_view_host) OVERRIDE; virtual void DidNavigateMainFrame(const LoadCommittedDetails& details, const FrameNavigateParams& params) OVERRIDE; @@ -60,6 +64,7 @@ class WebContentsObserverAndroid : public WebContentsObserver { RenderViewHost* render_view_host) OVERRIDE; virtual void DidCommitProvisionalLoadForFrame( int64 frame_id, + const base::string16& frame_unique_name, bool is_main_frame, const GURL& url, PageTransition transition_type, @@ -68,6 +73,8 @@ class WebContentsObserverAndroid : public WebContentsObserver { const GURL& validated_url, bool is_main_frame, RenderViewHost* render_view_host) OVERRIDE; + virtual void NavigationEntryCommitted( + const LoadCommittedDetails& load_details) OVERRIDE; virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE; virtual void DidChangeVisibleSSLState() OVERRIDE; virtual void DidAttachInterstitialPage() OVERRIDE; @@ -76,7 +83,7 @@ class WebContentsObserverAndroid : public WebContentsObserver { void DidFailLoadInternal(bool is_provisional_load, bool is_main_frame, int error_code, - const string16& description, + const base::string16& description, const GURL& url); JavaObjectWeakGlobalRef weak_java_observer_; |