// 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 "base/android/jni_android.h" #include "base/logging.h" #include "content/browser/android/content_view_core_impl.h" #include "content/browser/power_save_blocker_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/android/content_view_core.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents_observer.h" #include "jni/PowerSaveBlocker_jni.h" #include "ui/android/view_android.h" namespace content { using base::android::AttachCurrentThread; class PowerSaveBlockerImpl::Delegate : public base::RefCountedThreadSafe, public WebContentsObserver { public: explicit Delegate(WebContents* web_contents); // Does the actual work to apply or remove the desired power save block. void ApplyBlock(); void RemoveBlock(); private: friend class base::RefCountedThreadSafe; ~Delegate() override; base::android::ScopedJavaLocalRef GetContentViewCore(); base::android::ScopedJavaGlobalRef java_power_save_blocker_; DISALLOW_COPY_AND_ASSIGN(Delegate); }; PowerSaveBlockerImpl::Delegate::Delegate(WebContents* web_contents) : WebContentsObserver(web_contents) { JNIEnv* env = AttachCurrentThread(); java_power_save_blocker_.Reset(Java_PowerSaveBlocker_create(env)); } PowerSaveBlockerImpl::Delegate::~Delegate() { } void PowerSaveBlockerImpl::Delegate::ApplyBlock() { DCHECK_CURRENTLY_ON(BrowserThread::UI); base::android::ScopedJavaLocalRef java_content_view_core = GetContentViewCore(); if (java_content_view_core.is_null()) return; ScopedJavaLocalRef obj(java_power_save_blocker_); JNIEnv* env = AttachCurrentThread(); Java_PowerSaveBlocker_applyBlock(env, obj.obj(), java_content_view_core.obj()); } void PowerSaveBlockerImpl::Delegate::RemoveBlock() { DCHECK_CURRENTLY_ON(BrowserThread::UI); base::android::ScopedJavaLocalRef java_content_view_core = GetContentViewCore(); if (java_content_view_core.is_null()) return; ScopedJavaLocalRef obj(java_power_save_blocker_); JNIEnv* env = AttachCurrentThread(); Java_PowerSaveBlocker_removeBlock(env, obj.obj(), java_content_view_core.obj()); } base::android::ScopedJavaLocalRef PowerSaveBlockerImpl::Delegate::GetContentViewCore() { if (!web_contents()) return base::android::ScopedJavaLocalRef(); ContentViewCoreImpl* content_view_core_impl = ContentViewCoreImpl::FromWebContents(web_contents()); if (!content_view_core_impl) return base::android::ScopedJavaLocalRef(); return content_view_core_impl->GetJavaObject(); } PowerSaveBlockerImpl::PowerSaveBlockerImpl(PowerSaveBlockerType type, Reason reason, const std::string& description) { // Don't support kPowerSaveBlockPreventAppSuspension } PowerSaveBlockerImpl::~PowerSaveBlockerImpl() { if (delegate_.get()) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&Delegate::RemoveBlock, delegate_)); } } void PowerSaveBlockerImpl::InitDisplaySleepBlocker(WebContents* web_contents) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!web_contents) return; delegate_ = new Delegate(web_contents); delegate_->ApplyBlock(); } bool RegisterPowerSaveBlocker(JNIEnv* env) { return RegisterNativesImpl(env); } } // namespace content