Chromium全屏播放视频电源管理

介绍

Android为了达到节约电源的目的,在屏幕没有操作时便会自动息屏,那么比如我们在播放视频时,尽管对屏幕没有操作,但是我们此时是不希望它息屏的,如果视频处于暂停状态,此时是希望它自动息屏的。
下面来看一下如何在Chromium全屏播放视频时是如何控制屏幕的。

实现

因为全屏播放是和ContentVideoView.java相关的,那么就在这个类中来实现。
首先在content_switches.h中声明一个PowerSaveBlocker 开关:

CONTENT_EXPORT extern const char kEnableContentVideoViewPowerSaveBlocker[];

在content_switches.cc中初始化:

// Enable the PowerSaveBlocker in ContentVideoView. Android only.
const char kEnableContentVideoViewPowerSaveBlocker[] = "enable-content-video-view-power-save-blocker";

然后在aw_main_delegate.cc中把开关打开:
在AwMainDelegate::BasicStartupComplete中加上

cl->AppendSwitch(switches::kEnableContentVideoViewPowerSaveBlocker)

接下来就要在ContentVideoView.java中来实现了:
首先ContentVideoView要实现一下ViewAndroidDelegate接口:
实现它的三个方法:

    @Override
    public View acquireAnchorView() {
        View anchorView = new View(getContext());
        addView(anchorView);
        return anchorView;
    }

    @Override
    public void setAnchorViewPosition(View view, float x, float y, float width, float height) {
        Log.e(TAG, "setAnchorViewPosition isn't implemented");
    }

    @Override
    public void releaseAnchorView(View anchorView) {
        removeView(anchorView);
    }

添加一个成员变量:

// The ViewAndroid is used to keep screen on during video playback.
private ViewAndroid mViewAndroid;

在构造函数中实现:

mViewAndroid = new ViewAndroid(new WindowAndroid(context.getApplicationContext()), this);

实现一个函数供jni层调用:

    @CalledByNative
    private long getNativeViewAndroid() {
        return mViewAndroid.getNativePointer();
    }

ContentVideoView类对应的jni层类在content_video_view.cc中实现,那么电源管理也主要在这个类中进行:
首先看content_video_view.h,要在content的命名空间中申明PowerSaveBlocker类和添加成员变量和方法:

#include "base/timer/timer.h"

class PowerSaveBlocker;

  // Returns the associated NativeView
  gfx::NativeView GetNativeView();

  void CreatePowerSaveBlocker();

  // 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_;

在content_video_view.cc中实现:

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 (base::CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableContentVideoViewPowerSaveBlocker)) {
    // In fullscreen Clank reuses the power save blocker attached to the
    // container view that was created for embedded video. The WebView cannot
    // reuse that so we create a new blocker instead.
    if (power_save_blocker_) return;
    power_save_blocker_ = PowerSaveBlocker::Create(
        PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
        "Playing video").Pass();
    static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())->
        InitDisplaySleepBlocker(GetNativeView());
  }
}

在构造函数中调用CreatePowerSaveBlocker

ContentVideoView::ContentVideoView(
    BrowserMediaPlayerManager* manager)
    : manager_(manager),
      weak_factory_(this) {
  ……
  CreatePowerSaveBlocker();
}

ContentVideoView::OpenVideo()ContentVideoView::Play时调用CreatePowerSaveBlocker()来保持不息屏:
ContentVideoView::OnMediaPlayerErrorContentVideoView::OnPlaybackComplete()ContentVideoView::PauseContentVideoView::ExitFullscreen时调用power_save_blocker_.reset()来让系统重新控制屏幕。
这样就达到了我们对播放视频是屏幕控制的目的。

你可能感兴趣的:(android,视频,chromium,电源管理)