提交 0bc96076 编写于 作者: A Adam Barth

Add MineDigger.apk that works offline

This CL builds an APK for MineDigger that works offline. We use |sky_packager|
to snapshot the Dart code, which we then extract from the APK during startup.
If we succeed in extracting a snapshot, we load it by default.

TBR=eseidel@chromium.org

Review URL: https://codereview.chromium.org/1211253004.
上级 06adbc9a
......@@ -2,9 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/ui.gni")
import("//tools/grit/grit_rule.gni")
group("sky") {
testonly = true
......@@ -13,6 +10,7 @@ group("sky") {
"//sky/engine/platform:platform_unittests",
"//sky/engine/web:sky_unittests",
"//sky/engine/wtf:unittests",
"//sky/sdk/example",
"//sky/tools/imagediff",
"//sky/tools/packager($host_toolchain)",
"//sky/tools/tester",
......@@ -33,11 +31,7 @@ group("sky_apk") {
testonly = true
deps = [
"//mojo/dart/mojo_services",
"//mojo/dart/mojom",
"//mojo/public/dart:mojo",
"//sky/sdk",
"//third_party/dart-pkg",
]
if (is_android) {
......
......@@ -21,3 +21,79 @@ template("sky_apk") {
] + invoker.deps
}
}
template("sky_app") {
action("gen_snapshot") {
main_dart = invoker.main_dart
package_root = "$root_gen_dir/dart-pkg/packages"
# Note: org.chromium.base.ResourceExtractor knows about 'snapshot_blob.bin'.
snapshot = "$target_gen_dir/snapshot_blob.bin"
inputs = [
main_dart,
]
outputs = [
snapshot,
]
sky_packager_dir =
get_label_info("//sky/tools/packager($host_toolchain)", "root_out_dir")
script = "//sky/tools/sky_packager.py"
src_dir = "//"
cwd = rebase_path(src_dir, root_build_dir)
args = [
rebase_path("$sky_packager_dir/sky_packager", src_dir),
rebase_path(main_dart, src_dir),
"--package-root",
rebase_path(package_root, src_dir),
"--snapshot",
rebase_path(snapshot, src_dir),
"-C",
cwd,
]
deps = [
"//sky/tools/packager($host_toolchain)",
"//sky/sdk",
]
}
copy_ex("assets") {
clear_dir = true
dest = "$target_gen_dir/assets"
sources = [
"$root_build_dir/icudtl.dat",
"$target_gen_dir/snapshot_blob.bin",
]
deps = [
"//third_party/icu",
]
}
android_apk(target_name) {
apk_name = invoker.apk_name
android_manifest = "apk/AndroidManifest.xml"
native_libs = [ "libsky_shell.so" ]
asset_location = "$target_gen_dir/assets"
deps = [
"//base:base_java",
"//sky/shell:assets",
"//sky/shell:java",
"//sky/shell:sky_shell",
":assets",
":gen_snapshot",
]
if (defined(invoker.deps)) {
deps += invoker.deps
}
}
}
......@@ -133,8 +133,12 @@ dart_pkg("sdk") {
]
datadeps = [
"//sky/services/testing:bindings",
"//mojo/dart/mojo_services",
"//mojo/dart/mojom",
"//mojo/public/dart:mojo",
"//sky/engine/bindings",
"//sky/services/testing:bindings",
"//third_party/dart-pkg",
]
sdk_ext_directory = "$root_gen_dir/sky/bindings"
......
# Copyright 2015 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.
group("example") {
testonly = true
deps = []
if (is_android) {
deps += [ "//sky/sdk/example/mine_digger" ]
}
}
# Copyright 2015 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.
assert(is_android)
import("//sky/apk/rules.gni")
sky_app("mine_digger") {
apk_name = "MineDigger"
main_dart = "lib/main.dart"
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2015 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.domokit.mine_digger">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:name="org.domokit.sky.shell.SkyApplication" android:label="Mine Digger">
<activity android:name="org.domokit.sky.shell.SkyActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
android:hardwareAccelerated="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
name: mine_digger
author: Chromium Authors <sky-dev@googlegroups.com>
description: Classic minesweeper-inspired game
homepage: https://github.com/domokit/sky_sdk/tree/master/packages/sky/example/mine_digger
version: 0.0.1
dependencies:
sky: '>=0.0.10 <1.0.0'
......@@ -56,7 +56,7 @@ class SkyHome extends App {
new SkyDemo('Interactive Flex', 'example/rendering/interactive_flex.dart'),
new SkyDemo('Sector Layout', 'example/widgets/sector.dart'),
new SkyDemo('Touch Demo', 'example/rendering/touch_demo.dart'),
new SkyDemo('Minedigger Game', 'example/mine_digger/mine_digger.dart'),
new SkyDemo('Minedigger Game', 'example/mine_digger/lib/main.dart'),
// TODO(eseidel): We could use to separate these groups?
new SkyDemo('Old Stocks App', 'example/stocks/main.sky'),
......
......@@ -13,5 +13,5 @@ interface ViewportObserver {
RunFromNetwork(string url);
RunFromFile(string main, string package_root);
RunFromSnapshot(string url, handle<data_pipe_consumer> snapshot);
RunFromSnapshot(string path);
};
......@@ -182,6 +182,10 @@ public class PlatformViewAndroid extends SurfaceView
mViewportObserver.onInputEvent(event);
}
public void loadSnapshot(String path) {
mViewportObserver.runFromSnapshot(path);
}
public void loadUrl(String url) {
mViewportObserver.runFromNetwork(url);
}
......
......@@ -10,6 +10,10 @@ import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import org.chromium.base.PathUtils;
import java.io.File;
/**
* Base class for activities that use Sky.
*/
......@@ -36,6 +40,8 @@ public class SkyActivity extends Activity {
mView = new PlatformViewAndroid(this);
setContentView(mView);
mTracingController = new TracingController(this);
loadSnapshotIfAvailable();
}
/**
......@@ -59,6 +65,13 @@ public class SkyActivity extends Activity {
super.onBackPressed();
}
private void loadSnapshotIfAvailable() {
File snapshot = new File(PathUtils.getDataDirectory(this), SkyApplication.SNAPSHOT);
if (snapshot.exists()) {
mView.loadSnapshot(snapshot.getPath());
}
}
public void loadUrl(String url) {
mView.loadUrl(url);
}
......
......@@ -23,10 +23,12 @@ import org.domokit.oknet.NetworkServiceImpl;
* state and initializations.
*/
public class SkyApplication extends BaseChromiumApplication {
static final String SNAPSHOT = "snapshot_blob.bin";
private static final String TAG = "SkyApplication";
private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "sky_shell";
private static final String[] SKY_MANDATORY_PAKS = {
"icudtl.dat",
"icudtl.dat", SNAPSHOT
};
@Override
......@@ -39,7 +41,8 @@ public class SkyApplication extends BaseChromiumApplication {
}
private void initializeJavaUtils() {
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, getApplicationContext());
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
getApplicationContext());
}
private void initializeNative() {
......
......@@ -8,12 +8,9 @@
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/worker_pool.h"
#include "mojo/common/data_pipe_utils.h"
#include "sky/shell/platform_view.h"
#include "sky/shell/service_provider.h"
#include "sky/shell/shell.h"
......@@ -24,14 +21,10 @@ namespace sky {
namespace shell {
namespace {
void Ignored(bool) {
}
void Usage() {
std::cerr << "Usage: sky_shell"
<< " [--" << switches::kPackageRoot << "]"
<< " [--" << switches::kSnapshot << "]"
<< " <sky-app>" << std::endl;
<< " [MAIN_DART --" << switches::kPackageRoot << "=PACKAGE_ROOT]"
<< " [--" << switches::kSnapshot << "=SNAPSHOT]" << std::endl;
}
void Init() {
......@@ -46,20 +39,15 @@ void Init() {
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
std::string main = command_line.GetArgs()[0];
if (command_line.HasSwitch(switches::kSnapshot)) {
base::FilePath snapshot =
command_line.GetSwitchValuePath(switches::kSnapshot);
mojo::DataPipe pipe;
viewport_observer->RunFromSnapshot(main, pipe.consumer_handle.Pass());
scoped_refptr<base::TaskRunner> runner =
base::WorkerPool::GetTaskRunner(true);
mojo::common::CopyFromFile(snapshot, pipe.producer_handle.Pass(), 0,
runner.get(), base::Bind(&Ignored));
std::string snapshot =
command_line.GetSwitchValueASCII(switches::kSnapshot);
viewport_observer->RunFromSnapshot(snapshot);
return;
}
if (command_line.HasSwitch(switches::kPackageRoot)) {
std::string main = command_line.GetArgs()[0];
std::string package_root =
command_line.GetSwitchValueASCII(switches::kPackageRoot);
viewport_observer->RunFromFile(main, package_root);
......@@ -80,8 +68,7 @@ int main(int argc, const char* argv[]) {
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(sky::shell::switches::kHelp) ||
command_line.GetArgs().empty()) {
if (command_line.HasSwitch(sky::shell::switches::kHelp)) {
sky::shell::Usage();
return 0;
}
......
......@@ -5,7 +5,10 @@
#include "sky/shell/ui/engine.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/threading/worker_pool.h"
#include "base/trace_event/trace_event.h"
#include "mojo/common/data_pipe_utils.h"
#include "mojo/public/cpp/application/connect.h"
#include "sky/engine/public/platform/WebInputEvent.h"
#include "sky/engine/public/platform/sky_display_metrics.h"
......@@ -29,6 +32,17 @@ namespace shell {
namespace {
void Ignored(bool) {
}
mojo::ScopedDataPipeConsumerHandle Fetch(const base::FilePath& path) {
mojo::DataPipe pipe;
auto runner = base::WorkerPool::GetTaskRunner(true);
mojo::common::CopyFromFile(base::FilePath(path), pipe.producer_handle.Pass(),
0, runner.get(), base::Bind(&Ignored));
return pipe.consumer_handle.Pass();
}
void ConfigureSettings(blink::WebSettings* settings) {
settings->setDefaultFixedFontSize(13);
settings->setDefaultFontSize(16);
......@@ -218,11 +232,11 @@ void Engine::RunFromFile(const mojo::String& main,
RunFromLibrary(main);
}
void Engine::RunFromSnapshot(const mojo::String& url,
mojo::ScopedDataPipeConsumerHandle snapshot) {
void Engine::RunFromSnapshot(const mojo::String& path) {
CloseWebViewIfNeeded();
sky_view_ = blink::SkyView::Create(this);
sky_view_->RunFromSnapshot(blink::WebString::fromUTF8(url), snapshot.Pass());
sky_view_->RunFromSnapshot(blink::WebString::fromUTF8(path),
Fetch(base::FilePath(path)));
UpdateSkyViewSize();
}
......
......@@ -73,8 +73,7 @@ class Engine : public UIDelegate,
void RunFromNetwork(const mojo::String& url) override;
void RunFromFile(const mojo::String& main,
const mojo::String& package_root) override;
void RunFromSnapshot(const mojo::String& url,
mojo::ScopedDataPipeConsumerHandle snapshot) override;
void RunFromSnapshot(const mojo::String& path) override;
// WebViewClient methods:
void frameDetached(blink::WebFrame*) override;
......
......@@ -31,9 +31,6 @@ void WriteSnapshot(base::FilePath path) {
CHECK_EQ(base::WriteFile(path, reinterpret_cast<const char*>(buffer), size),
size);
std::cout << "Successfully wrote snapshot to " << path.LossyDisplayName()
<< " (" << size << " bytes)." << std::endl;
}
int main(int argc, const char* argv[]) {
......
#!/usr/bin/env python
# Copyright 2015 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.
import argparse
import subprocess
import sys
import os
def main():
parser = argparse.ArgumentParser(description='Sky Packager')
parser.add_argument('executable', type=str)
parser.add_argument('main', type=str)
parser.add_argument('--package-root', type=str)
parser.add_argument('--snapshot', type=str)
parser.add_argument('-C', type=str,
help='Switch to this directory before running executable')
args = parser.parse_args()
return subprocess.check_call([
args.executable,
args.main,
'--package-root=%s' % args.package_root,
'--snapshot=%s' % args.snapshot,
], cwd=args.C)
if __name__ == '__main__':
sys.exit(main())
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册