diff --git a/engine/src/flutter/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java b/engine/src/flutter/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java index aa807efee0..be7dbf41d6 100644 --- a/engine/src/flutter/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java +++ b/engine/src/flutter/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java @@ -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> result = diff --git a/engine/src/flutter/shell/android/org/domokit/sky/shell/SkyActivity.java b/engine/src/flutter/shell/android/org/domokit/sky/shell/SkyActivity.java index c29e4647e7..9b30b73178 100644 --- a/engine/src/flutter/shell/android/org/domokit/sky/shell/SkyActivity.java +++ b/engine/src/flutter/shell/android/org/domokit/sky/shell/SkyActivity.java @@ -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; } } diff --git a/engine/src/flutter/shell/ui/animator.cc b/engine/src/flutter/shell/ui/animator.cc index 7b7fe3caca..ceca49942c 100644 --- a/engine/src/flutter/shell/ui/animator.cc +++ b/engine/src/flutter/shell/ui/animator.cc @@ -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(); diff --git a/engine/src/flutter/shell/ui/animator.h b/engine/src/flutter/shell/ui/animator.h index 15dd2f43f2..cef6624cc6 100644 --- a/engine/src/flutter/shell/ui/animator.h +++ b/engine/src/flutter/shell/ui/animator.h @@ -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 weak_factory_; diff --git a/engine/src/flutter/shell/ui/engine.cc b/engine/src/flutter/shell/ui/engine.cc index 7893ec51f4..75991d0a79 100644 --- a/engine/src/flutter/shell/ui/engine.cc +++ b/engine/src/flutter/shell/ui/engine.cc @@ -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(); } diff --git a/engine/src/flutter/shell/ui/engine.h b/engine/src/flutter/shell/ui/engine.h index f4c51ffac3..3db3f85bb1 100644 --- a/engine/src/flutter/shell/ui/engine.h +++ b/engine/src/flutter/shell/ui/engine.h @@ -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_; @@ -99,6 +105,10 @@ class Engine : public UIDelegate, blink::SkyDisplayMetrics display_metrics_; mojo::Binding binding_; + // TODO(eseidel): This should move into an AnimatorStateMachine. + bool activity_running_; + bool have_surface_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(Engine);