Teach SkyShell.apk to stop posting frames when not visible
This listens to both surface destruction as well as activity pause/unpause. R=abarth@chromium.org, abarth@google.com Review URL: https://codereview.chromium.org/1230073002 .
This commit is contained in:
@@ -97,6 +97,10 @@ public class PlatformViewAndroid extends SurfaceView
|
||||
KeyboardServiceImpl.setActiveView(this);
|
||||
}
|
||||
|
||||
SkyEngine getEngine() {
|
||||
return mSkyEngine;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
getHolder().removeCallback(mSurfaceCallback);
|
||||
@@ -199,24 +203,6 @@ public class PlatformViewAndroid extends SurfaceView
|
||||
mSkyEngine.onInputEvent(event);
|
||||
}
|
||||
|
||||
public void onBackPressed() {
|
||||
InputEvent event = new InputEvent();
|
||||
event.type = EventType.BACK;
|
||||
mSkyEngine.onInputEvent(event);
|
||||
}
|
||||
|
||||
public void loadSnapshot(String path) {
|
||||
mSkyEngine.runFromSnapshot(path);
|
||||
}
|
||||
|
||||
public void loadBundle(String path) {
|
||||
mSkyEngine.runFromBundle(path);
|
||||
}
|
||||
|
||||
public void loadUrl(String url) {
|
||||
mSkyEngine.runFromNetwork(url);
|
||||
}
|
||||
|
||||
private void attach() {
|
||||
Core core = CoreImpl.getInstance();
|
||||
Pair<SkyEngine.Proxy, InterfaceRequest<SkyEngine>> result =
|
||||
|
||||
@@ -11,6 +11,8 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import org.chromium.base.PathUtils;
|
||||
import org.chromium.mojom.sky.EventType;
|
||||
import org.chromium.mojom.sky.InputEvent;
|
||||
|
||||
import org.domokit.activity.ActivityImpl;
|
||||
|
||||
@@ -64,14 +66,30 @@ public class SkyActivity extends Activity {
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mView != null) {
|
||||
mView.onBackPressed();
|
||||
// TODO(abarth): We should have some way to trigger the default
|
||||
// back behavior.
|
||||
InputEvent event = new InputEvent();
|
||||
event.type = EventType.BACK;
|
||||
mView.getEngine().onInputEvent(event);
|
||||
return;
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (mView != null) {
|
||||
mView.getEngine().onActivityPaused();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostResume() {
|
||||
super.onPostResume();
|
||||
if (mView != null) {
|
||||
mView.getEngine().onActivityResumed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this function to customize startup behavior.
|
||||
*/
|
||||
@@ -79,18 +97,18 @@ public class SkyActivity extends Activity {
|
||||
File dataDir = new File(PathUtils.getDataDirectory(this));
|
||||
File snapshot = new File(dataDir, SkyApplication.SNAPSHOT);
|
||||
if (snapshot.exists()) {
|
||||
mView.loadSnapshot(snapshot.getPath());
|
||||
mView.getEngine().runFromSnapshot(snapshot.getPath());
|
||||
return;
|
||||
}
|
||||
File appBundle = new File(dataDir, SkyApplication.APP_BUNDLE);
|
||||
if (appBundle.exists()) {
|
||||
mView.loadBundle(appBundle.getPath());
|
||||
mView.getEngine().runFromBundle(appBundle.getPath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void loadUrl(String url) {
|
||||
mView.loadUrl(url);
|
||||
mView.getEngine().runFromNetwork(url);
|
||||
}
|
||||
|
||||
public boolean loadBundleByName(String name) {
|
||||
@@ -99,7 +117,7 @@ public class SkyActivity extends Activity {
|
||||
if (!bundle.exists()) {
|
||||
return false;
|
||||
}
|
||||
mView.loadBundle(bundle.getPath());
|
||||
mView.getEngine().runFromBundle(bundle.getPath());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ Animator::Animator(const Engine::Config& config, Engine* engine)
|
||||
engine_(engine),
|
||||
engine_requested_frame_(false),
|
||||
frame_in_progress_(false),
|
||||
paused_(false),
|
||||
weak_factory_(this) {
|
||||
}
|
||||
|
||||
@@ -37,10 +38,16 @@ void Animator::RequestFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::CancelFrameRequest() {
|
||||
void Animator::Stop() {
|
||||
paused_ = true;
|
||||
engine_requested_frame_ = false;
|
||||
}
|
||||
|
||||
void Animator::Start() {
|
||||
paused_ = false;
|
||||
RequestFrame();
|
||||
}
|
||||
|
||||
void Animator::BeginFrame() {
|
||||
DCHECK(frame_in_progress_);
|
||||
// There could be a request in the message loop at time of cancel.
|
||||
@@ -62,6 +69,9 @@ void Animator::BeginFrame() {
|
||||
void Animator::OnFrameComplete() {
|
||||
DCHECK(frame_in_progress_);
|
||||
frame_in_progress_ = false;
|
||||
if (paused_)
|
||||
return;
|
||||
|
||||
if (engine_requested_frame_) {
|
||||
frame_in_progress_ = true;
|
||||
BeginFrame();
|
||||
|
||||
@@ -17,7 +17,9 @@ class Animator {
|
||||
~Animator();
|
||||
|
||||
void RequestFrame();
|
||||
void CancelFrameRequest();
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
void BeginFrame();
|
||||
@@ -27,6 +29,7 @@ class Animator {
|
||||
Engine* engine_;
|
||||
bool engine_requested_frame_;
|
||||
bool frame_in_progress_;
|
||||
bool paused_;
|
||||
|
||||
base::WeakPtrFactory<Animator> weak_factory_;
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ Engine::Engine(const Config& config)
|
||||
: config_(config),
|
||||
animator_(new Animator(config, this)),
|
||||
binding_(this),
|
||||
activity_running_(false),
|
||||
have_surface_(false),
|
||||
weak_factory_(this) {
|
||||
}
|
||||
|
||||
@@ -118,11 +120,15 @@ void Engine::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
|
||||
config_.gpu_task_runner->PostTask(
|
||||
FROM_HERE, base::Bind(&GPUDelegate::OnAcceleratedWidgetAvailable,
|
||||
config_.gpu_delegate, widget));
|
||||
have_surface_ = true;
|
||||
StartAnimatorIfPossible();
|
||||
if (sky_view_)
|
||||
ScheduleFrame();
|
||||
}
|
||||
|
||||
void Engine::OnOutputSurfaceDestroyed() {
|
||||
have_surface_ = false;
|
||||
StopAnimator();
|
||||
config_.gpu_task_runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&GPUDelegate::OnOutputSurfaceDestroyed, config_.gpu_delegate));
|
||||
@@ -195,12 +201,31 @@ void Engine::RunFromBundle(const mojo::String& path) {
|
||||
weak_factory_.GetWeakPtr(), path_str));
|
||||
}
|
||||
|
||||
void Engine::OnActivityPaused() {
|
||||
activity_running_ = false;
|
||||
StopAnimator();
|
||||
}
|
||||
|
||||
void Engine::OnActivityResumed() {
|
||||
activity_running_ = true;
|
||||
StartAnimatorIfPossible();
|
||||
}
|
||||
|
||||
void Engine::DidCreateIsolate(Dart_Isolate isolate) {
|
||||
Internals::Create(isolate,
|
||||
CreateServiceProvider(config_.service_provider_context),
|
||||
root_bundle_.Pass());
|
||||
}
|
||||
|
||||
void Engine::StopAnimator() {
|
||||
animator_->Stop();
|
||||
}
|
||||
|
||||
void Engine::StartAnimatorIfPossible() {
|
||||
if (activity_running_ && have_surface_)
|
||||
animator_->Start();
|
||||
}
|
||||
|
||||
void Engine::ScheduleFrame() {
|
||||
animator_->RequestFrame();
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ class Engine : public UIDelegate,
|
||||
void RunFromSnapshot(const mojo::String& path) override;
|
||||
void RunFromBundle(const mojo::String& path) override;
|
||||
|
||||
void OnActivityPaused() override;
|
||||
void OnActivityResumed() override;
|
||||
|
||||
// SkyViewClient methods:
|
||||
void ScheduleFrame() override;
|
||||
void DidCreateIsolate(Dart_Isolate isolate) override;
|
||||
@@ -88,6 +91,9 @@ class Engine : public UIDelegate,
|
||||
void RunFromSnapshotStream(const std::string& name,
|
||||
mojo::ScopedDataPipeConsumerHandle snapshot);
|
||||
|
||||
void StopAnimator();
|
||||
void StartAnimatorIfPossible();
|
||||
|
||||
Config config_;
|
||||
scoped_ptr<Animator> animator_;
|
||||
|
||||
@@ -99,6 +105,10 @@ class Engine : public UIDelegate,
|
||||
blink::SkyDisplayMetrics display_metrics_;
|
||||
mojo::Binding<SkyEngine> binding_;
|
||||
|
||||
// TODO(eseidel): This should move into an AnimatorStateMachine.
|
||||
bool activity_running_;
|
||||
bool have_surface_;
|
||||
|
||||
base::WeakPtrFactory<Engine> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Engine);
|
||||
|
||||
Reference in New Issue
Block a user