Upstream version 7.35.136.0 60/20860/1
authorEurogiciel-BOT <eurogiciel.tizen@gmail.com>
Tue, 13 May 2014 08:48:39 +0000 (08:48 +0000)
committerEurogiciel-BOT <eurogiciel.tizen@gmail.com>
Tue, 13 May 2014 08:48:39 +0000 (08:48 +0000)
Upstream commit-id 253eb01190ffaacffaf0d55dfbf40ff4ee65390d

Change-Id: I37d25bc838e3371a01c80779f8f00bd7d62e5ddf
Signed-off-by: Eurogiciel-BOT <eurogiciel.tizen@gmail.com>
103 files changed:
packaging/crosswalk.spec
src/ozone/wayland/wayland.gyp
src/xwalk/DEPS.xwalk
src/xwalk/VERSION
src/xwalk/app/android/app_hello_world/AndroidManifest.xml
src/xwalk/app/android/app_template/AndroidManifest.xml
src/xwalk/app/android/runtime_activity/src/org/xwalk/app/XWalkMixedResources.java [deleted file]
src/xwalk/app/android/runtime_activity/src/org/xwalk/app/XWalkRuntimeActivityBase.java
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/CrossPackageWrapper.java
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkMixedResources.java [new file with mode: 0644]
src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeApplication.java [new file with mode: 0644]
src/xwalk/app/android/runtime_client_shell/AndroidManifest.xml
src/xwalk/app/tools/android/compress_js_and_css.py
src/xwalk/app/tools/android/customize.py
src/xwalk/app/tools/android/make_apk.py
src/xwalk/app/tools/android/make_apk_test.py
src/xwalk/app/tools/android/manifest_json_parser.py
src/xwalk/app/tools/android/test_data/compressor/css/test.css [new file with mode: 0644]
src/xwalk/app/tools/android/test_data/compressor/js/test.js [new file with mode: 0644]
src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_parse_error.json [new file with mode: 0644]
src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_chinese_name.json [new file with mode: 0644]
src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_invalid_name.json [new file with mode: 0644]
src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_space_name.json [new file with mode: 0644]
src/xwalk/application/browser/application.cc
src/xwalk/application/browser/application.h
src/xwalk/application/browser/application_service.cc
src/xwalk/application/browser/application_service.h
src/xwalk/application/browser/application_tizen.cc [new file with mode: 0644]
src/xwalk/application/browser/application_tizen.h [new file with mode: 0644]
src/xwalk/application/browser/linux/running_application_object.cc
src/xwalk/application/common/application_data.cc
src/xwalk/application/common/constants.cc
src/xwalk/application/common/constants.h
src/xwalk/application/common/manifest_handlers/widget_handler.cc
src/xwalk/application/common/manifest_handlers/widget_handler.h
src/xwalk/application/tools/linux/xwalk_application_tools.gyp
src/xwalk/application/tools/tizen/xwalk_tizen_helper.gyp
src/xwalk/application/xwalk_application.gypi
src/xwalk/build/android/generate_xwalk_core_library.py
src/xwalk/build/system.gyp
src/xwalk/build/xwalk_filename_rules.gypi
src/xwalk/dbus/xwalk_dbus.gyp
src/xwalk/packaging/crosswalk.spec
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkContent.java
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkLaunchScreenManager.java
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkNavigationHandlerImpl.java
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkNavigationHistory.java
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkPreferences.java
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkUIClient.java
src/xwalk/runtime/android/core/src/org/xwalk/core/XWalkView.java
src/xwalk/runtime/android/core/src/org/xwalk/core/extension/api/presentation/PresentationExtension.java
src/xwalk/runtime/android/sample/AndroidManifest.xml
src/xwalk/runtime/android/sample/assets/index.html
src/xwalk/runtime/android/sample/res/layout/navigation_layout.xml
src/xwalk/runtime/android/sample/res/layout/version_layout.xml [new file with mode: 0644]
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/LoadAppFromManifestActivity.java
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/MultiXWalkViewActivity.java
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/OnHideOnShowActivity.java
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/PauseTimersActivity.java
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/ResourceAndUIClientsActivity.java
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkBaseActivity.java [new file with mode: 0644]
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkNavigationActivity.java
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkPreferencesActivity.java
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkVersionAndAPIVersion.java [new file with mode: 0644]
src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkViewWithLayoutActivity.java
src/xwalk/runtime/app/xwalk_main_delegate.cc
src/xwalk/runtime/app/xwalk_main_delegate.h
src/xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.cc [new file with mode: 0644]
src/xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.h [new file with mode: 0644]
src/xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.cc [new file with mode: 0644]
src/xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h [new file with mode: 0644]
src/xwalk/runtime/browser/runtime.cc
src/xwalk/runtime/browser/runtime.h
src/xwalk/runtime/browser/runtime_url_request_context_getter.cc
src/xwalk/runtime/browser/xwalk_browser_main_parts.cc
src/xwalk/runtime/browser/xwalk_content_browser_client.cc
src/xwalk/runtime/browser/xwalk_content_browser_client.h
src/xwalk/runtime/browser/xwalk_render_message_filter.h
src/xwalk/runtime/common/xwalk_content_client.cc
src/xwalk/runtime/common/xwalk_content_client.h
src/xwalk/runtime/common/xwalk_paths.cc
src/xwalk/runtime/common/xwalk_paths.h
src/xwalk/runtime/common/xwalk_switches.cc
src/xwalk/runtime/common/xwalk_switches.h
src/xwalk/runtime/renderer/pepper/pepper_helper.cc [new file with mode: 0644]
src/xwalk/runtime/renderer/pepper/pepper_helper.h [new file with mode: 0644]
src/xwalk/runtime/renderer/pepper/pepper_uma_host.cc [new file with mode: 0644]
src/xwalk/runtime/renderer/pepper/pepper_uma_host.h [new file with mode: 0644]
src/xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.cc [new file with mode: 0644]
src/xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.h [new file with mode: 0644]
src/xwalk/runtime/renderer/xwalk_content_renderer_client.cc
src/xwalk/runtime/renderer/xwalk_content_renderer_client.h
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/AddJavascriptInterfaceTest.java [new file with mode: 0644]
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/EvaluateJavascriptTest.java [new file with mode: 0644]
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/LoadTest.java [new file with mode: 0644]
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/LoadUrlTest.java [deleted file]
src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/XWalkViewTestBase.java
src/xwalk/test/android/data/add_js_interface.html [new file with mode: 0644]
src/xwalk/tools/build/linux/FILES.cfg
src/xwalk/tools/build/win/FILES.cfg
src/xwalk/xwalk.gyp
src/xwalk/xwalk_android_tests.gypi
src/xwalk/xwalk_tests.gypi

index 6cedf75..113af1c 100644 (file)
@@ -2,7 +2,7 @@
 %bcond_with wayland
 
 Name:           crosswalk
-Version:        6.35.132.0
+Version:        7.35.136.0
 Release:        0
 Summary:        Crosswalk is an app runtime based on Chromium
 License:        (BSD-3-Clause and LGPL-2.1+)
index b46fc33..9e4014c 100644 (file)
@@ -13,7 +13,7 @@
     'enable_xdg_shell%': '<(enable_xdg_shell)',
     'conditions': [
       ['sysroot!=""', {
-        'pkg-config': './pkg-config-wrapper "<(sysroot)" "<(target_arch)"',
+        'pkg-config': '../../build/linux/pkg-config-wrapper "<(sysroot)" "<(target_arch)"',
       }, {
         'pkg-config': 'pkg-config'
       }],
index 877a87b..b562bdc 100644 (file)
@@ -10,7 +10,7 @@ chromium_version = '35.0.1916.17'
 chromium_crosswalk_point = 'e62582858402995e841741a28af1c418d815897f'
 blink_crosswalk_point = '2c4e1889f37db55c77215de4f113748f071cb7aa'
 v8_crosswalk_point = 'd27abf42d305c5ee30cabed4926783bb105953c0'
-ozone_wayland_point = 'f4faec532d7d2f482b3ffe1e52be6fa3e6fc8629'
+ozone_wayland_point = '55f39c62b461b92d3b0b912c7c80ae98d866b5a6'
 
 deps_xwalk = {
   'src': 'https://github.com/crosswalk-project/chromium-crosswalk.git@%s' % chromium_crosswalk_point,
index efaa7da..cde4ae0 100644 (file)
@@ -1,4 +1,4 @@
-MAJOR=6
+MAJOR=7
 MINOR=35
-BUILD=132
+BUILD=136
 PATCH=0
index ef07c24..8b7384f 100644 (file)
@@ -9,7 +9,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.xwalk.app.hello.world">
 
-    <application android:name="android.app.Application"
+    <application android:name="org.xwalk.app.runtime.XWalkRuntimeApplication"
         android:label="XWalkAppHelloWorld" android:hardwareAccelerated="true"
         android:icon="@drawable/crosswalk">
         <activity android:name="org.xwalk.app.hello.world.HelloWorldActivity"
index f07ac77..81b4710 100644 (file)
@@ -10,7 +10,7 @@
     package="org.xwalk.app.template"
     android:installLocation="auto">
 
-    <application android:name="android.app.Application"
+    <application android:name="org.xwalk.app.runtime.XWalkRuntimeApplication"
         android:label="XWalkAppTemplate" android:hardwareAccelerated="true"
         android:icon="@drawable/crosswalk">
         <activity android:name="org.xwalk.app.template.AppTemplateActivity"
diff --git a/src/xwalk/app/android/runtime_activity/src/org/xwalk/app/XWalkMixedResources.java b/src/xwalk/app/android/runtime_activity/src/org/xwalk/app/XWalkMixedResources.java
deleted file mode 100644 (file)
index 8f2a5d2..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.xwalk.app;
-
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-
-/**
- * XWalkMixedResources is used to combine the resources
- * from two different packages.
- * 
- * TODO(wang16): Add more override functions (e.g. getColor/Boolean).
- */
-public class XWalkMixedResources extends Resources {
-
-    private Resources mExtend;
-
-    XWalkMixedResources(Resources base, Resources extend) {
-        super(base.getAssets(), base.getDisplayMetrics(),
-                base.getConfiguration());
-        mExtend = extend;
-    }
-
-    @Override
-    public CharSequence getText(int id) throws NotFoundException {
-        try {
-            return mExtend.getText(id);
-        } catch (NotFoundException e) {
-            return super.getText(id);
-        }
-    }
-
-    @Override
-    public Drawable getDrawable(int id) throws NotFoundException {
-        try {
-            return mExtend.getDrawable(id);
-        } catch (NotFoundException e) {
-            return super.getDrawable(id);
-        }
-    }
-}
index 18ca87a..f16ede1 100644 (file)
@@ -11,7 +11,6 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Bundle;
 import android.view.View;
@@ -36,8 +35,6 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
 
     private AlertDialog mLibraryNotFoundDialog = null;
 
-    private XWalkMixedResources mMixedResources = null;
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         IntentFilter intentFilter = new IntentFilter("org.xwalk.intent");
@@ -103,12 +100,6 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
         mRuntimeView.onActivityResult(requestCode, resultCode, data);
     }
 
-    @Override
-    public Resources getResources() {
-        if (mMixedResources == null) return super.getResources();
-        return mMixedResources;
-    }
-
     private String getLibraryApkDownloadUrl() {
         int resId = getResources().getIdentifier("xwalk_library_apk_download_url", "string", getPackageName());
         if (resId == 0) return DEFAULT_LIBRARY_APK_URL;
@@ -125,8 +116,6 @@ public abstract class XWalkRuntimeActivityBase extends Activity implements Cross
         if (mRuntimeView == null || mRuntimeView.get() == null) {
             mRuntimeView = new XWalkRuntimeClient(this, null, this);
             if (mRuntimeView.get() != null) {
-                mMixedResources = new XWalkMixedResources(super.getResources(),
-                        mRuntimeView.getLibraryContext().getResources());
                 mShownNotFoundDialog = false;
                 if (mLibraryNotFoundDialog != null) mLibraryNotFoundDialog.cancel();
             }
index 64f4c9f..27307d4 100644 (file)
@@ -35,6 +35,11 @@ public abstract class CrossPackageWrapper {
                 mLibCtx = ctx.createPackageContext(
                         LIBRARY_APK_PACKAGE_NAME,
                         Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+                Context app = ctx.getApplicationContext();
+                assert(app instanceof XWalkRuntimeApplication);
+                XWalkRuntimeApplication xwalkApp = (XWalkRuntimeApplication) app;
+                xwalkApp.addResource(mLibCtx.getResources());
+
                 mTargetClass =
                         mLibCtx.getClassLoader().loadClass(className);
             }
diff --git a/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkMixedResources.java b/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkMixedResources.java
new file mode 100644 (file)
index 0000000..8ee6cbd
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.xwalk.app.runtime;
+
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.TypedValue;
+
+/**
+ * XWalkMixedResources is used to combine the resources
+ * from two different packages.
+ *
+ * Chromium uses resources through:
+ *   R.layout; R.id; R.string; R.dimen; R.drawable;
+ *   R.attr; R.style; R.menu ; R.color
+ * R.layout and R.menu is covered by Resources.getLayout()
+ * R.string is covered by Resources.getText()
+ * R.dimen, R.drawable and R.color is covered by getValue()
+ *
+ * For R.id, if it's used like findViewById(R.id.xxx), R.id.xxx
+ * is const at compile time within library context. It works
+ * if the view in hierachy has the same id, which needs inflate
+ * with layout resource from library context. Layout is covered
+ * by getLayout(), so R.id is OK.
+ *
+ * TODO(wang16):
+ * For R.attr and R.style, I have no confidence that it's covered.
+ * But the only place use this R.attr and R.style is "select" tag
+ * which is verified working well with this MixedResources.
+ */
+public class XWalkMixedResources extends Resources {
+
+    private Resources mExtend;
+
+    XWalkMixedResources(Resources base, Resources extend) {
+        super(base.getAssets(), base.getDisplayMetrics(),
+                base.getConfiguration());
+        mExtend = extend;
+    }
+
+    @Override
+    public CharSequence getText(int id) throws NotFoundException {
+        try {
+            return mExtend.getText(id);
+        } catch (NotFoundException e) {
+            return super.getText(id);
+        }
+    }
+
+    @Override
+    public XmlResourceParser getLayout(int id) throws NotFoundException {
+        try {
+            return mExtend.getLayout(id);
+        } catch (NotFoundException e) {
+            return super.getLayout(id);
+        }
+    }
+
+    @Override
+    public void getValue(int id, TypedValue outValue, boolean resolveRefs) {
+        try {
+            mExtend.getValue(id, outValue, resolveRefs);
+        } catch (NotFoundException e) {
+            super.getValue(id, outValue, resolveRefs);
+        }
+    }
+
+    @Override
+    public void getValueForDensity(int id, int density, TypedValue outValue, boolean resolveRefs) {
+        try {
+            mExtend.getValueForDensity(id, density, outValue, resolveRefs);
+        } catch (NotFoundException e) {
+            super.getValueForDensity(id, density, outValue, resolveRefs);
+        }
+    }
+
+    @Override
+    public int getIdentifier(String name, String defType, String defPackage) {
+        int id = mExtend.getIdentifier(name, defType, defPackage);
+        return id != 0 ? id : super.getIdentifier(name, defType, defPackage);
+    }
+}
diff --git a/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeApplication.java b/src/xwalk/app/android/runtime_client/src/org/xwalk/app/runtime/XWalkRuntimeApplication.java
new file mode 100644 (file)
index 0000000..e4aae1a
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.xwalk.app.runtime;
+
+import android.app.Application;
+import android.content.res.Resources;
+
+/**
+ * XWalkRuntimeApplication is to support cross package resource loading.
+ * It provides method to allow overriding getResources() behavior.
+ */
+public class XWalkRuntimeApplication extends Application {
+    private Resources mRes = null;
+
+    @Override
+    public Resources getResources() {
+        return mRes == null ? super.getResources() : mRes;
+    }
+
+    void addResource(Resources res) {
+        if (mRes != null) return;
+        mRes = new XWalkMixedResources(super.getResources(), res);
+    }
+}
index dd98c68..6ff673a 100644 (file)
@@ -9,7 +9,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.xwalk.runtime.client.shell">
 
-    <application android:name="android.app.Application"
+    <application android:name="org.xwalk.app.runtime.XWalkRuntimeApplication"
         android:label="XWalkRuntimeClientShell" android:hardwareAccelerated="true">
         <activity android:name="org.xwalk.runtime.client.shell.XWalkRuntimeClientShellActivity"
             android:theme="@android:style/Theme.Holo.Light.NoActionBar"
index 8b879bb..f46a9ec 100755 (executable)
@@ -4,9 +4,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import fnmatch
 import os
-import stat
 import subprocess
 
 def GetJARFilename():
@@ -17,35 +15,18 @@ def GetJARFilename():
   cur_dir = os.path.realpath(os.path.dirname(__file__))
   return os.path.join(cur_dir, "libs", file_name)
 
-def GetFileList(path, ext, sub_dir = True):
-  if os.path.exists(path):
-    file_list = []
-    for name in os.listdir(path):
-      full_name = os.path.join(path, name)
-      st = os.lstat(full_name)
-      if stat.S_ISDIR(st.st_mode) and sub_dir:
-        file_list += GetFileList(full_name, ext)
-      elif os.path.isfile(full_name):
-        if fnmatch.fnmatch(full_name, ext):
-          file_list.append(full_name)
-    return file_list
-  else:
-    return []
-
-def ExecuteCmd(path, ext):
-  file_list = GetFileList(path, "*." + ext)
+
+def ExecuteCmd(file_list, ext):
   for file_full_path in file_list:
     if os.path.exists(file_full_path):
       cmd_args = ["java", "-jar", GetJARFilename(), "--type=" + ext,
           file_full_path, "-o", file_full_path]
       subprocess.call(cmd_args)
 
-class CompressJsAndCss(object):
-  def __init__(self, input_path):
-    self.input_path = input_path
 
-  def CompressJavaScript(self):
-    ExecuteCmd(self.input_path, "js")
+def CompressJavaScript(file_list):
+  ExecuteCmd(file_list, "js")
+
 
-  def CompressCss(self):
-    ExecuteCmd(self.input_path, "css")
+def CompressCss(file_list):
+  ExecuteCmd(file_list, "css")
index 27123df..c11ad04 100755 (executable)
@@ -4,11 +4,14 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import compress_js_and_css
+import fnmatch
 import json
 import optparse
 import os
 import re
 import shutil
+import stat
 import sys
 
 from customize_launch_screen import CustomizeLaunchScreen
@@ -19,6 +22,28 @@ from handle_xml import EditElementValueByNodeName
 from handle_permissions import HandlePermissions
 from xml.dom import minidom
 
+def VerifyAppName(value, mode='default'):
+  descrpt = 'The app'
+  sample = 'helloworld, hello_world, hello_world1'
+  regex = r'^([a-zA-Z](\w)*)+$'
+
+  if len(value) >= 128 :
+    print('To be safe, the length of package name or app name '
+          'should be less than 128.')
+    sys.exit(6)
+  if mode == 'packagename':
+    regex = r'^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$'
+    descrpt = 'Each part of package'
+    sample = 'org.xwalk.example, org.xwalk.example_'
+
+  if not re.match(regex, value):
+    print('Error: %s name should be started with letters and should not '
+          'conatin invalid characters.\n'
+          'It may conatin letters, numbers and underscores\n'
+          'Sample: %s' % (descrpt, sample))
+    sys.exit(6)
+
+
 def ReplaceInvalidChars(value, mode='default'):
   """ Replace the invalid chars with '_' for input string.
   Args:
@@ -36,33 +61,76 @@ def ReplaceInvalidChars(value, mode='default'):
   return value
 
 
-def Prepare(sanitized_name, package, app_root):
-  if os.path.exists(sanitized_name):
-    shutil.rmtree(sanitized_name)
-  shutil.copytree('app_src', sanitized_name)
-  shutil.rmtree(os.path.join(sanitized_name, 'src'))
+def GetFilesByExt(path, ext, sub_dir = True):
+  if os.path.exists(path):
+    file_list = []
+    for name in os.listdir(path):
+      full_name = os.path.join(path, name)
+      st = os.lstat(full_name)
+      if stat.S_ISDIR(st.st_mode) and sub_dir:
+        file_list += GetFilesByExt(full_name, ext)
+      elif os.path.isfile(full_name):
+        if fnmatch.fnmatch(full_name, ext):
+          file_list.append(full_name)
+    return file_list
+  else:
+    return []
+
+
+def ParseParameterForCompressor(option, value, values, parser):
+  if ((not values or values.startswith('-'))
+      and value.find('--compressor') != -1):
+    values = 'all'
+  val = values
+  if parser.rargs and not parser.rargs[0].startswith('-'):
+    val = parser.rargs[0]
+    parser.rargs.pop(0)
+  setattr(parser.values, option.dest, val)
+
+
+def CompressSourceFiles(app_root, compressor):
+  js_list = []
+  css_list = []
+  js_ext = '*.js'
+  css_ext = '*.css'
+
+  if compressor == 'all' or compressor == 'js':
+    js_list = GetFilesByExt(app_root, js_ext)
+    compress_js_and_css.CompressJavaScript(js_list)
+
+  if compressor == 'all' or compressor == 'css':
+    css_list = GetFilesByExt(app_root, css_ext)
+    compress_js_and_css.CompressCss(css_list)
+
+
+def Prepare(name, package, app_root, compressor):
+  if os.path.exists(name):
+    shutil.rmtree(name)
+  shutil.copytree('app_src', name)
+  shutil.rmtree(os.path.join(name, 'src'))
   src_root = os.path.join('app_src', 'src', 'org', 'xwalk', 'app', 'template')
   src_activity = os.path.join(src_root, 'AppTemplateActivity.java')
   if not os.path.isfile(src_activity):
     print ('Please make sure that the java file'
            ' of activity does exist.')
     sys.exit(7)
-  root_path =  os.path.join(sanitized_name, 'src',
-                            package.replace('.', os.path.sep))
+  root_path =  os.path.join(name, 'src', package.replace('.', os.path.sep))
   if not os.path.exists(root_path):
     os.makedirs(root_path)
-  dest_activity = sanitized_name + 'Activity.java'
+  dest_activity = name + 'Activity.java'
   shutil.copyfile(src_activity, os.path.join(root_path, dest_activity))
   if app_root:
-    assets_path = os.path.join(sanitized_name, 'assets')
+    assets_path = os.path.join(name, 'assets')
     shutil.rmtree(assets_path)
     os.makedirs(assets_path)
     app_src_path = os.path.join(assets_path, 'www')
     shutil.copytree(app_root, app_src_path)
+    if compressor:
+      CompressSourceFiles(app_src_path, compressor)
 
 
-def CustomizeStringXML(sanitized_name, description):
-  strings_path = os.path.join(sanitized_name, 'res', 'values', 'strings.xml')
+def CustomizeStringXML(name, description):
+  strings_path = os.path.join(name, 'res', 'values', 'strings.xml')
   if not os.path.isfile(strings_path):
     print ('Please make sure strings_xml'
            ' exists under app_src folder.')
@@ -77,8 +145,8 @@ def CustomizeStringXML(sanitized_name, description):
     strings_file.close()
 
 
-def CustomizeThemeXML(sanitized_name, fullscreen, app_manifest):
-  theme_path = os.path.join(sanitized_name, 'res', 'values', 'theme.xml')
+def CustomizeThemeXML(name, fullscreen, app_manifest):
+  theme_path = os.path.join(name, 'res', 'values', 'theme.xml')
   if not os.path.isfile(theme_path):
     print('Error: theme.xml is missing in the build tool.')
     sys.exit(6)
@@ -87,7 +155,7 @@ def CustomizeThemeXML(sanitized_name, fullscreen, app_manifest):
   if fullscreen:
     EditElementValueByNodeName(theme_xmldoc, 'item',
                                'android:windowFullscreen', 'true')
-  has_background = CustomizeLaunchScreen(app_manifest, sanitized_name)
+  has_background = CustomizeLaunchScreen(app_manifest, name)
   if has_background:
     EditElementValueByNodeName(theme_xmldoc, 'item',
                                'android:windowBackground',
@@ -97,17 +165,17 @@ def CustomizeThemeXML(sanitized_name, fullscreen, app_manifest):
   theme_file.close()
 
 
-def CustomizeXML(sanitized_name, package, app_versionCode, app_version,
-                 description, name, orientation, icon_dict, fullscreen,
-                 icon, app_manifest, permissions, app_root):
-  manifest_path = os.path.join(sanitized_name, 'AndroidManifest.xml')
+def CustomizeXML(package, app_versionCode, app_version, description, name,
+                 orientation, icon_dict, fullscreen, icon, app_manifest,
+                 permissions, app_root):
+  manifest_path = os.path.join(name, 'AndroidManifest.xml')
   if not os.path.isfile(manifest_path):
     print ('Please make sure AndroidManifest.xml'
            ' exists under app_src folder.')
     sys.exit(6)
 
-  CustomizeStringXML(sanitized_name, description)
-  CustomizeThemeXML(sanitized_name, fullscreen, app_manifest)
+  CustomizeStringXML(name, description)
+  CustomizeThemeXML(name, fullscreen, app_manifest)
   xmldoc = minidom.parse(manifest_path)
   EditElementAttribute(xmldoc, 'manifest', 'package', package)
   if app_versionCode:
@@ -121,18 +189,18 @@ def CustomizeXML(sanitized_name, package, app_versionCode, app_version,
                          "@string/description")
   HandlePermissions(permissions, xmldoc)
   EditElementAttribute(xmldoc, 'application', 'android:label', name)
-  activity_name = package + '.' + sanitized_name + 'Activity'
+  activity_name = package + '.' + name + 'Activity'
   EditElementAttribute(xmldoc, 'activity', 'android:name', activity_name)
   EditElementAttribute(xmldoc, 'activity', 'android:label', name)
   if orientation:
     EditElementAttribute(xmldoc, 'activity', 'android:screenOrientation',
                          orientation)
-  icon_name = CustomizeIcon(sanitized_name, app_root, icon, icon_dict)
+  icon_name = CustomizeIcon(name, app_root, icon, icon_dict)
   if icon_name:
     EditElementAttribute(xmldoc, 'application', 'android:icon',
                          '@drawable/%s' % icon_name)
 
-  file_handle = open(os.path.join(sanitized_name, 'AndroidManifest.xml'), 'w')
+  file_handle = open(os.path.join(name, 'AndroidManifest.xml'), 'w')
   xmldoc.writexml(file_handle, encoding='utf-8')
   file_handle.close()
 
@@ -160,15 +228,14 @@ def SetVariable(file_path, string_line, variable, value):
   shutil.move(temp_file_path, file_path)
 
 
-def CustomizeJava(sanitized_name, package, app_url, app_local_path,
+def CustomizeJava(name, package, app_url, app_local_path,
                   enable_remote_debugging, display_as_fullscreen,
                   keep_screen_on):
-  root_path =  os.path.join(sanitized_name, 'src',
-                            package.replace('.', os.path.sep))
-  dest_activity = os.path.join(root_path, sanitized_name + 'Activity.java')
+  root_path =  os.path.join(name, 'src', package.replace('.', os.path.sep))
+  dest_activity = os.path.join(root_path, name + 'Activity.java')
   ReplaceString(dest_activity, 'org.xwalk.app.template', package)
-  ReplaceString(dest_activity, 'AppTemplate', sanitized_name)
-  manifest_file = os.path.join(sanitized_name, 'assets/www', 'manifest.json')
+  ReplaceString(dest_activity, 'AppTemplate', name)
+  manifest_file = os.path.join(name, 'assets/www', 'manifest.json')
   if os.path.isfile(manifest_file):
     ReplaceString(
         dest_activity,
@@ -180,8 +247,7 @@ def CustomizeJava(sanitized_name, package, app_url, app_local_path,
         ReplaceString(dest_activity, 'file:///android_asset/www/index.html',
                       app_url)
     elif app_local_path:
-      if os.path.isfile(os.path.join(sanitized_name, 'assets/www',
-                                     app_local_path)):
+      if os.path.isfile(os.path.join(name, 'assets/www', app_local_path)):
         ReplaceString(dest_activity, 'file:///android_asset/www/index.html',
                       'app://' + package + '/' + app_local_path)
       else:
@@ -226,7 +292,7 @@ def CopyExtensionFile(extension_name, suffix, src_path, dest_path):
     shutil.copyfile(src_file, dest_file)
 
 
-def CustomizeExtensions(sanitized_name, name, extensions):
+def CustomizeExtensions(name, extensions):
   """Copy the files from external extensions and merge them into APK.
 
   The directory of one external extension should be like:
@@ -295,7 +361,7 @@ def CustomizeExtensions(sanitized_name, name, extensions):
       json_output['jsapi'] = js_path_prefix + json_output['jsapi']
       extension_json_list.append(json_output)
       # Merge the permissions of extensions into AndroidManifest.xml.
-      manifest_path = os.path.join(sanitized_name, 'AndroidManifest.xml')
+      manifest_path = os.path.join(name, 'AndroidManifest.xml')
       xmldoc = minidom.parse(manifest_path)
       if ('permissions' in json_output):
         # Get used permission list to avoid repetition as "--permissions"
@@ -325,16 +391,16 @@ def CustomizeExtensions(sanitized_name, name, extensions):
     extension_json_file.close()
 
 
-def GenerateCommandLineFile(sanitized_name, xwalk_command_line):
+def GenerateCommandLineFile(name, xwalk_command_line):
   if xwalk_command_line == '':
     return
-  assets_path = os.path.join(sanitized_name, 'assets')
+  assets_path = os.path.join(name, 'assets')
   file_path = os.path.join(assets_path, 'xwalk-command-line')
   command_line_file = open(file_path, 'w')
   command_line_file.write('xwalk ' + xwalk_command_line)
 
 
-def CustomizeIconByDict(sanitized_name, app_root, icon_dict):
+def CustomizeIconByDict(name, app_root, icon_dict):
   icon_name = None
   drawable_dict = {'ldpi':[1, 37], 'mdpi':[37, 72], 'hdpi':[72, 96],
                    'xhdpi':[96, 120], 'xxhdpi':[120, 144], 'xxxhdpi':[144, 168]}
@@ -351,7 +417,7 @@ def CustomizeIconByDict(sanitized_name, app_root, icon_dict):
     for kd, vd in drawable_dict.iteritems():
       for item in icon_list:
         if item[0] >= vd[0] and item[0] < vd[1]:
-          drawable_path = os.path.join(sanitized_name, 'res', 'drawable-' + kd)
+          drawable_path = os.path.join(name, 'res', 'drawable-' + kd)
           if not os.path.exists(drawable_path):
             os.makedirs(drawable_path)
           icon = os.path.join(app_root, item[1])
@@ -368,9 +434,9 @@ def CustomizeIconByDict(sanitized_name, app_root, icon_dict):
   return icon_name
 
 
-def CustomizeIconByOption(sanitized_name, icon):
+def CustomizeIconByOption(name, icon):
   if os.path.isfile(icon):
-    drawable_path = os.path.join(sanitized_name, 'res', 'drawable')
+    drawable_path = os.path.join(name, 'res', 'drawable')
     if not os.path.exists(drawable_path):
       os.makedirs(drawable_path)
     icon_file = os.path.basename(icon)
@@ -383,12 +449,12 @@ def CustomizeIconByOption(sanitized_name, icon):
     sys.exit(6)
 
 
-def CustomizeIcon(sanitized_name, app_root, icon, icon_dict):
+def CustomizeIcon(name, app_root, icon, icon_dict):
   icon_name = None
   if icon:
-    icon_name = CustomizeIconByOption(sanitized_name, icon)
+    icon_name = CustomizeIconByOption(name, icon)
   else:
-    icon_name = CustomizeIconByDict(sanitized_name, app_root, icon_dict)
+    icon_name = CustomizeIconByDict(name, app_root, icon_dict)
   return icon_name
 
 
@@ -397,19 +463,18 @@ def CustomizeAll(app_versionCode, description, icon_dict, permissions, app_url,
                  display_as_fullscreen, keep_screen_on, extensions,
                  app_manifest, icon, package='org.xwalk.app.template',
                  name='AppTemplate', app_version='1.0.0',
-                 orientation='unspecified', xwalk_command_line=''):
-  sanitized_name = ReplaceInvalidChars(name, 'apkname')
+                 orientation='unspecified', xwalk_command_line='',
+                 compressor=None):
   try:
-    Prepare(sanitized_name, package, app_root)
-    CustomizeXML(sanitized_name, package, app_versionCode, app_version,
-                 description, name, orientation, icon_dict,
-                 display_as_fullscreen, icon, app_manifest, permissions,
-                 app_root)
-    CustomizeJava(sanitized_name, package, app_url, app_local_path,
+    Prepare(name, package, app_root, compressor)
+    CustomizeXML(package, app_versionCode, app_version, description, name,
+                 orientation, icon_dict, display_as_fullscreen, icon,
+                 app_manifest, permissions, app_root)
+    CustomizeJava(name, package, app_url, app_local_path,
                   enable_remote_debugging, display_as_fullscreen,
                   keep_screen_on)
-    CustomizeExtensions(sanitized_name, name, extensions)
-    GenerateCommandLineFile(sanitized_name, xwalk_command_line)
+    CustomizeExtensions(name, extensions)
+    GenerateCommandLineFile(name, xwalk_command_line)
   except SystemExit as ec:
     print('Exiting with error code: %d' % ec.code)
     sys.exit(ec.code)
@@ -469,7 +534,13 @@ def main():
           'For example, '
           '--xwalk-command-line=\'--chromium-command-1 --xwalk-command-2\'')
   parser.add_option('--xwalk-command-line', default='', help=info)
-
+  info = ('Minify and obfuscate javascript and css.'
+          '--compressor: compress javascript and css.'
+          '--compressor=js: compress javascript.'
+          '--compressor=css: compress css.')
+  parser.add_option('--compressor', dest='compressor', action='callback',
+                    callback=ParseParameterForCompressor,
+                    type='string', nargs=0, help=info)
   options, _ = parser.parse_args()
   try:
     icon_dict = {144: 'icons/icon_144.png',
@@ -493,8 +564,7 @@ def main():
                  options.fullscreen, options.keep_screen_on, options.extensions,
                  options.manifest, icon, options.package, options.name,
                  options.app_version, options.orientation,
-                 options.xwalk_command_line)
-
+                 options.xwalk_command_line, options.compressor)
   except SystemExit as ec:
     print('Exiting with error code: %d' % ec.code)
     return ec.code
index 563681e..e56533f 100755 (executable)
@@ -5,7 +5,6 @@
 # found in the LICENSE file.
 # pylint: disable=F0401
 
-import compress_js_and_css
 import operator
 import optparse
 import os
@@ -15,7 +14,9 @@ import subprocess
 import sys
 
 sys.path.append('scripts/gyp')
-from customize import ReplaceInvalidChars, CustomizeAll
+
+from customize import VerifyAppName, CustomizeAll, \
+                      ParseParameterForCompressor
 from dex import AddExeExtensions
 from handle_permissions import permission_mapping_table
 from manifest_json_parser import HandlePermissionList
@@ -90,10 +91,17 @@ def GetVersion(path):
 
 def ParseManifest(options):
   parser = ManifestJsonParser(os.path.expanduser(options.manifest))
-  if not options.package:
-    options.package = 'org.xwalk.' + parser.GetAppName().lower()
-  if not options.name:
-    options.name = parser.GetAppName()
+  app_name = parser.GetAppName()
+  if options.package:
+    VerifyAppName(options.package, 'packagename')
+  else:
+    VerifyAppName(app_name)
+    options.package = 'org.xwalk.' + app_name.lower()
+  if options.name:
+    VerifyAppName(options.name)
+  else:
+    VerifyAppName(app_name)
+    options.name = app_name
   if not options.app_version:
     options.app_version = parser.GetVersion()
   if not options.app_versionCode and not options.app_versionCodeBase:
@@ -208,10 +216,10 @@ def Customize(options):
                options.app_local_path, remote_debugging,
                fullscreen_flag, options.keep_screen_on, options.extensions,
                options.manifest, icon, package, name, app_version,
-               orientation, options.xwalk_command_line)
+               orientation, options.xwalk_command_line, options.compressor)
 
 
-def Execution(options, sanitized_name):
+def Execution(options, name):
   android_path_array = Which('android')
   if not android_path_array:
     print('Please install Android SDK first.')
@@ -288,16 +296,16 @@ def Execution(options, sanitized_name):
   if options.mode == 'embedded':
     # Prepare the .pak file for embedded mode.
     pak_src_path = os.path.join('native_libs_res', 'xwalk.pak')
-    pak_des_path = os.path.join(sanitized_name, 'assets', 'xwalk.pak')
+    pak_des_path = os.path.join(name, 'assets', 'xwalk.pak')
     shutil.copy(pak_src_path, pak_des_path)
 
     # Prepare the icudtl.dat for embedded mode.
     icudtl_src_path = os.path.join('native_libs_res', 'icudtl.dat')
-    icudtl_des_path = os.path.join(sanitized_name, 'assets', 'icudtl.dat')
+    icudtl_des_path = os.path.join(name, 'assets', 'icudtl.dat')
     shutil.copy(icudtl_src_path, icudtl_des_path)
 
     js_src_dir = os.path.join('native_libs_res', 'jsapi')
-    js_des_dir = os.path.join(sanitized_name, 'assets', 'jsapi')
+    js_des_dir = os.path.join(name, 'assets', 'jsapi')
     if os.path.exists(js_des_dir):
       shutil.rmtree(js_des_dir)
     shutil.copytree(js_src_dir, js_des_dir)
@@ -325,8 +333,8 @@ def Execution(options, sanitized_name):
                         + os.path.join(res_xwalk_java, 'java_R', 'R.txt') + ' '
                         + os.path.join(res_content_java, 'java_R', 'R.txt'))
 
-  resource_dir = '-DRESOURCE_DIR=' + os.path.join(sanitized_name, 'res')
-  manifest_path = os.path.join(sanitized_name, 'AndroidManifest.xml')
+  resource_dir = '-DRESOURCE_DIR=' + os.path.join(name, 'res')
+  manifest_path = os.path.join(name, 'AndroidManifest.xml')
   cmd = ['python', os.path.join('scripts', 'gyp', 'ant.py'),
          '-DAAPT_PATH=%s' % aapt_path,
          res_dirs,
@@ -359,7 +367,7 @@ def Execution(options, sanitized_name):
   classpath += os.path.join(os.getcwd(), 'libs',
                             'xwalk_app_runtime_java.jar')
   classpath += ' ' + sdk_jar_path
-  src_dirs = '--src-dirs=' + os.path.join(os.getcwd(), sanitized_name, 'src') +\
+  src_dirs = '--src-dirs=' + os.path.join(os.getcwd(), name, 'src') +\
              ' ' + os.path.join(os.getcwd(), 'out', 'gen')
   cmd = ['python', os.path.join('scripts', 'gyp', 'javac.py'),
          '--output-dir=%s' % os.path.join('out', 'classes'),
@@ -368,10 +376,10 @@ def Execution(options, sanitized_name):
          '--javac-includes=',
          '--chromium-code=0',
          '--stamp=compile.stam']
-  RunCommand(cmd)
+  RunCommand(cmd, options.verbose)
 
   # Package resources.
-  asset_dir = '-DASSET_DIR=%s' % os.path.join(sanitized_name, 'assets')
+  asset_dir = '-DASSET_DIR=%s' % os.path.join(name, 'assets')
   xml_path = os.path.join('scripts', 'ant', 'apk-package-resources.xml')
   cmd = ['python', os.path.join('scripts', 'gyp', 'ant.py'),
          '-DAAPT_PATH=%s' % aapt_path,
@@ -381,7 +389,7 @@ def Execution(options, sanitized_name):
          '-DANDROID_SDK_JAR=%s' % sdk_jar_path,
          '-DANDROID_SDK_ROOT=%s' % sdk_root_path,
          '-DANT_TASKS_JAR=%s' % ant_tasks_jar_path,
-         '-DAPK_NAME=%s' % sanitized_name,
+         '-DAPK_NAME=%s' % name,
          '-DAPP_MANIFEST_VERSION_CODE=0',
          '-DAPP_MANIFEST_VERSION_NAME=Developer Build',
          asset_dir,
@@ -400,7 +408,7 @@ def Execution(options, sanitized_name):
 
   # Check whether external extensions are included.
   extensions_string = 'xwalk-extensions'
-  extensions_dir = os.path.join(os.getcwd(), sanitized_name, extensions_string)
+  extensions_dir = os.path.join(os.getcwd(), name, extensions_string)
   external_extension_jars = FindExtensionJars(extensions_dir)
   input_jars = []
   if options.mode == 'embedded':
@@ -415,7 +423,7 @@ def Execution(options, sanitized_name):
   dex_command_list.extend(input_jars)
   RunCommand(dex_command_list)
 
-  src_dir = '-DSOURCE_DIR=' + os.path.join(sanitized_name, 'src')
+  src_dir = '-DSOURCE_DIR=' + os.path.join(name, 'src')
   apk_path = '-DUNSIGNED_APK_PATH=' + os.path.join('out', 'app-unsigned.apk')
   native_lib_path = '-DNATIVE_LIBS_DIR='
   if options.mode == 'embedded':
@@ -440,7 +448,7 @@ def Execution(options, sanitized_name):
   cmd = ['python', 'scripts/gyp/ant.py',
          '-DANDROID_SDK_ROOT=%s' % sdk_root_path,
          '-DANT_TASKS_JAR=%s' % ant_tasks_jar_path,
-         '-DAPK_NAME=%s' % sanitized_name,
+         '-DAPK_NAME=%s' % name,
          '-DCONFIGURATION_NAME=Release',
          native_lib_path,
          '-DOUT_DIR=out',
@@ -453,7 +461,7 @@ def Execution(options, sanitized_name):
 
   apk_path = '--unsigned-apk-path=' + os.path.join('out', 'app-unsigned.apk')
   final_apk_path = '--final-apk-path=' + \
-                   os.path.join('out', sanitized_name + '.apk')
+                   os.path.join('out', name + '.apk')
   cmd = ['python', 'scripts/gyp/finalize_apk.py',
          '--android-sdk-root=%s' % sdk_root_path,
          apk_path,
@@ -463,7 +471,7 @@ def Execution(options, sanitized_name):
          '--keystore-passcode=%s' % key_code]
   RunCommand(cmd)
 
-  src_file = os.path.join('out', sanitized_name + '.apk')
+  src_file = os.path.join('out', name + '.apk')
   package_name = options.name
   if options.app_version:
     package_name += ('_' + options.app_version)
@@ -502,19 +510,19 @@ def PrintPackageInfo(target_dir, app_name, app_version,
                'Consider building for x86 as well.')
 
 
-def MakeApk(options, sanitized_name):
+def MakeApk(options):
   Customize(options)
   app_version = ''
+  name = options.name
   if options.app_version:
     app_version = options.app_version
   if options.mode == 'shared':
-    Execution(options, sanitized_name)
-    PrintPackageInfo(options.target_dir, sanitized_name, app_version)
+    Execution(options, name)
+    PrintPackageInfo(options.target_dir, name, app_version)
   elif options.mode == 'embedded':
     if options.arch:
-      Execution(options, sanitized_name)
-      PrintPackageInfo(options.target_dir, sanitized_name,
-                       app_version, options.arch)
+      Execution(options, name)
+      PrintPackageInfo(options.target_dir, name, app_version, options.arch)
     else:
       # If the arch option is unspecified, all of available platform APKs
       # will be generated.
@@ -528,7 +536,7 @@ def MakeApk(options, sanitized_name):
             options.arch = 'x86'
           elif arch.find('arm') != -1:
             options.arch = 'arm'
-          Execution(options, sanitized_name)
+          Execution(options, name)
           packaged_archs.append(options.arch)
         else:
           print('Warning: failed to create package for arch "%s" '
@@ -543,26 +551,13 @@ def MakeApk(options, sanitized_name):
       if len(packaged_archs) >=2:
         multi_arch = True
       for arch in packaged_archs:
-        PrintPackageInfo(options.target_dir, sanitized_name,
-                         app_version, arch, multi_arch)
+        PrintPackageInfo(options.target_dir, name, app_version, arch,
+                         multi_arch)
   else:
     print('Unknown mode for packaging the application. Abort!')
     sys.exit(11)
 
 
-def parse_optional_arg(default_value):
-  def func(option, value, values, parser):
-    del value
-    del values
-    if parser.rargs and not parser.rargs[0].startswith('-'):
-      val = parser.rargs[0]
-      parser.rargs.pop(0)
-    else:
-      val = default_value
-    setattr(parser.values, option.dest, val)
-  return func
-
-
 def main(argv):
   parser = optparse.OptionParser()
   parser.add_option('-v', '--version', action='store_true',
@@ -678,7 +673,8 @@ def main(argv):
           '--compressor=js: compress javascript.'
           '--compressor=css: compress css.')
   group.add_option('--compressor', dest='compressor', action='callback',
-                   callback=parse_optional_arg('all'), help=info)
+                   callback=ParseParameterForCompressor, type='string', nargs=0,
+                   help=info)
   parser.add_option_group(group)
   options, _ = parser.parse_args()
   if len(argv) == 1:
@@ -705,14 +701,14 @@ def main(argv):
       options.manifest = manifest_path
 
   if not options.manifest:
-    if not options.package:
+    if options.package:
+      VerifyAppName(options.package, 'packagename')
+    else:
       parser.error('The package name is required! '
                    'Please use "--package" option.')
-    elif len(options.package) >= 128 :
-      parser.error('To be safe, the length of package name '
-                   'should be less than 128.')
-
-    if not options.name:
+    if options.name:
+      VerifyAppName(options.name)
+    else:
       parser.error('The APK name is required! Please use "--name" option.')
     if not ((options.app_url and not options.app_root
         and not options.app_local_path) or ((not options.app_url)
@@ -742,10 +738,6 @@ def main(argv):
           'does exist.')
     sys.exit(7)
 
-  options.name = ReplaceInvalidChars(options.name, 'apkname')
-  options.package = ReplaceInvalidChars(options.package)
-  sanitized_name = ReplaceInvalidChars(options.name, 'apkname')
-
   if options.target_dir:
     target_dir = os.path.abspath(os.path.expanduser(options.target_dir))
     options.target_dir = target_dir
@@ -753,20 +745,11 @@ def main(argv):
       os.makedirs(target_dir)
 
   try:
-    compress = compress_js_and_css.CompressJsAndCss(options.app_root)
-    if options.compressor == 'all':
-      compress.CompressJavaScript()
-      compress.CompressCss()
-    elif options.compressor == 'js':
-      compress.CompressJavaScript()
-    elif options.compressor == 'css':
-      compress.CompressCss()
-    MakeApk(options, sanitized_name)
+    MakeApk(options)
   except SystemExit as ec:
-    CleanDir(sanitized_name)
+    CleanDir(options.name)
     CleanDir('out')
-    if os.path.exists(xpk_temp_dir):
-      CleanDir(xpk_temp_dir)
+    CleanDir(xpk_temp_dir)
     return ec.code
   return 0
 
index 6560542..0b2c62d 100755 (executable)
@@ -25,6 +25,32 @@ def Clean(name, app_version):
       os.remove(name + '_' + app_version + '_arm.apk')
 
 
+def CompareSizeForCompressor(mode, original, ext, name, fun):
+  size = 0
+  compressed_size = 0
+  mode_list = ['all', 'js', 'css']
+
+  www_dir = os.path.join(name, 'assets', 'www')
+  if os.path.exists(www_dir):
+    size = GetFileSize(original)
+    compressed_file = os.path.join(www_dir, ext, 'test.' + ext)
+    compressed_size = GetFileSize(compressed_file)
+
+    if mode in mode_list:
+      fun(compressed_size < size)
+    else:
+      fun(size == compressed_size)
+  else:
+    print('Error: %s is not exist.' % www_dir)
+
+
+def GetFileSize(file_path):
+  size = 0
+  if os.path.exists(file_path):
+    size = os.path.getsize(file_path)
+  return size
+
+
 def RunCommand(command):
   """Runs the command list, return the output."""
   proc = subprocess.Popen(command, stdout=subprocess.PIPE,
@@ -32,6 +58,26 @@ def RunCommand(command):
   return proc.communicate()[0]
 
 
+def GetResultWithOption(mode, manifest=None, name=None, package=None):
+  app_url = None
+  if manifest != None:
+    manifest = '--manifest=' + manifest
+  else:
+    app_url = '--app-url=http://www.intel.com'
+  if name != None:
+    name = '--name=' + name
+  if package != None:
+    package = '--package=' + package
+  cmd = ['python', 'make_apk.py',
+         '--app-version=1.0.0',
+         '%s' % manifest,
+         '%s' % name,
+         '%s' % package,
+         '%s' % app_url,
+         mode]
+  return RunCommand(cmd)
+
+
 class TestMakeApk(unittest.TestCase):
   @classmethod
   def setUpClass(cls):
@@ -157,25 +203,22 @@ class TestMakeApk(unittest.TestCase):
     out = RunCommand(cmd)
     Clean('Example', '1.0.0')
     self.assertTrue(out.find('The APK name is required!') != -1)
-    cmd = ['python', 'make_apk.py', '--name="Test Example"',
-           '--app-version=1.0.0',
+
+    cmd = ['python', 'make_apk.py', '--name=Test_Example',
+           '--app-version=1.0.0', '--app-url=http://www.intel.com',
            '--package=org.xwalk.example', self._mode]
     out = RunCommand(cmd)
-    Clean('Test Example', '1.0.0')
     self.assertTrue(out.find('The APK name is required!') == -1)
-    # The following invalid chars verification is too heavy for embedded mode,
-    # and the result of verification should be the same between shared mode
-    # and embedded mode. So only do the verification in the shared mode.
-    if self._mode.find('shared') != -1:
-      invalid_chars = '\/:.*?"<>|-'
-      for c in invalid_chars:
-        invalid_name = '--name=Example' + c
-        cmd = ['python', 'make_apk.py', invalid_name,
-               '--app-version=1.0.0', '--package=org.xwalk.example',
-               '--app-url=http://www.intel.com', self._mode]
-        out = RunCommand(cmd)
-        Clean('Example_', '1.0.0')
-        self.assertTrue(out.find('Illegal character') != -1)
+    Clean('Test_Example', '1.0.0')
+
+    invalid_chars = '\/:.*?"<>|-'
+    for c in invalid_chars:
+      invalid_name = '--name=Example' + c
+      cmd = ['python', 'make_apk.py', invalid_name,
+             '--app-version=1.0.0', '--package=org.xwalk.example',
+             '--app-url=http://www.intel.com', self._mode]
+      out = RunCommand(cmd)
+      self.assertTrue(out.find('invalid characters') != -1)
 
   def testToolVersion(self):
     cmd = ['python', 'make_apk.py', '--version']
@@ -716,7 +759,6 @@ class TestMakeApk(unittest.TestCase):
 
     self.executeCommandAndVerifyResult('customize.py')
 
-
   def testTargetDir(self):
     test_option = ['./', '../', '~/']
     for option in test_option:
@@ -736,6 +778,114 @@ class TestMakeApk(unittest.TestCase):
           self.assertTrue(os.path.exists(apk_path))
           self.checkApk(apk_path, arch)
 
+  def testCompressor(self):
+    app_root = os.path.join('test_data', 'compressor')
+    css_folder = os.path.join('test_data', 'compressor', 'css')
+    css_file = os.path.join(css_folder, 'test.css')
+    js_folder = os.path.join('test_data', 'compressor', 'js')
+    js_file = os.path.join(js_folder, 'test.js')
+    fun = self.assertTrue
+    name = 'Example'
+
+    cmd = ['python', 'customize.py',
+           '--name=%s' % name,
+           '--compressor',
+           '--app-root=%s' % app_root]
+    RunCommand(cmd)
+    CompareSizeForCompressor('all', css_file, 'css', name, fun)
+    CompareSizeForCompressor('all', js_file, 'js', name, fun)
+
+    cmd = ['python', 'customize.py',
+           '--name=%s' % name,
+           '--app-root=%s' % app_root,
+           '--compressor']
+    RunCommand(cmd)
+    CompareSizeForCompressor('all', css_file, 'css', name, fun)
+    CompareSizeForCompressor('all', js_file, 'js', name, fun)
+
+    cmd = ['python', 'customize.py',
+           '--name=%s' % name,
+           '--compressor=js',
+           '--app-root=%s' % app_root]
+    RunCommand(cmd)
+    CompareSizeForCompressor('js', js_file, 'js', name, fun)
+
+    cmd = ['python', 'customize.py',
+           '--name=%s' % name,
+           '--compressor=css',
+           '--app-root=%s' % app_root]
+    RunCommand(cmd)
+    CompareSizeForCompressor('css', css_file, 'css', name, fun)
+
+    cmd = ['python', 'customize.py',
+           '--name=%s' % name,
+           '--app-root=%s' % app_root]
+    RunCommand(cmd)
+    CompareSizeForCompressor(None, css_file, 'css', name, fun)
+    CompareSizeForCompressor(None, js_file, 'js', name, fun)
+
+    cmd = ['python', 'customize.py',
+           '--name=%s' % name,
+           '--app-root=%s' % app_root,
+           '--compressor=other']
+    RunCommand(cmd)
+    CompareSizeForCompressor(None, css_file, 'css', name, fun)
+    CompareSizeForCompressor(None, js_file, 'js', name, fun)
+
+    Clean(name, '1.0.0')
+
+  def testInvalidCharacter(self):
+    version = '1.0.0'
+    start_with_letters = ' should be started with letters'
+    app_name_error = 'app name' + start_with_letters
+    package_name_error = 'package name' + start_with_letters
+    parse_error = 'parser error in manifest.json file'
+    directory = os.path.join('test_data', 'manifest', 'invalidchars')
+
+    manifest_path = os.path.join(directory, 'manifest_with_space_name.json')
+    result = GetResultWithOption(self._mode, manifest_path)
+    self.assertTrue(result.find(app_name_error) != -1)
+
+    manifest_path = os.path.join(directory, 'manifest_with_chinese_name.json')
+    result = GetResultWithOption(self._mode, manifest_path)
+    self.assertTrue(result.find(app_name_error) != -1)
+
+    manifest_path = os.path.join(directory, 'manifest_parse_error.json')
+    result = GetResultWithOption(self._mode, manifest_path)
+    self.assertTrue(result.find(parse_error) != -1)
+
+    manifest_path = os.path.join(directory, 'manifest_with_invalid_name.json')
+    result = GetResultWithOption(self._mode, manifest_path)
+    self.assertTrue(result.find(app_name_error) != -1)
+
+    package = 'org.xwalk.example'
+    name = '_hello'
+    result = GetResultWithOption(self._mode, name=name, package=package)
+    self.assertTrue(result.find(app_name_error) != -1)
+
+    name = '123hello'
+    result = GetResultWithOption(self._mode, name=name, package=package)
+    self.assertTrue(result.find(app_name_error) != -1)
+
+    name = 'hello_'
+    result = GetResultWithOption(self._mode, name=name, package=package)
+    self.assertTrue(result.find(app_name_error) == -1)
+    Clean(name, version)
+
+    name = 'xwalk'
+    package = 'org.xwalk._example'
+    result = GetResultWithOption(self._mode, name=name, package=package)
+    self.assertTrue(result.find(package_name_error) != -1)
+
+    package = 'org.xwalk.123example'
+    result = GetResultWithOption(self._mode, name=name, package=package)
+    self.assertTrue(result.find(package_name_error) != -1)
+
+    package = 'org.xwalk.example_'
+    result = GetResultWithOption(self._mode, name=name, package=package)
+    self.assertTrue(result.find(package_name_error) == -1)
+    Clean(name, version)
+
 
 def SuiteWithModeOption():
   # Gather all the tests for the specified mode option.
@@ -754,6 +904,7 @@ def SuiteWithModeOption():
   test_suite.addTest(TestMakeApk('testFullscreen'))
   test_suite.addTest(TestMakeApk('testIconByOption'))
   test_suite.addTest(TestMakeApk('testIconByManifest'))
+  test_suite.addTest(TestMakeApk('testInvalidCharacter'))
   test_suite.addTest(TestMakeApk('testKeystore'))
   test_suite.addTest(TestMakeApk('testManifest'))
   test_suite.addTest(TestMakeApk('testManifestWithError'))
@@ -771,6 +922,7 @@ def SuiteWithModeOption():
 def SuiteWithEmptyModeOption():
   # Gather all the tests for empty mode option.
   test_suite = unittest.TestSuite()
+  test_suite.addTest(TestMakeApk('testCompressor'))
   test_suite.addTest(TestMakeApk('testCustomizeFile'))
   test_suite.addTest(TestMakeApk('testEmptyMode'))
   test_suite.addTest(TestMakeApk('testToolVersion'))
index f3ac84c..4f073ad 100755 (executable)
@@ -54,11 +54,11 @@ class ManifestJsonParser(object):
       input_src = input_file.read()
       self.data_src = json.JSONDecoder().decode(input_src)
       self.ret_dict = self._output_items()
-    except (TypeError, ValueError, IOError):
-      print('There is a parser error in manifest.json file.')
+    except (TypeError, ValueError, IOError) as error:
+      print('There is a parser error in manifest.json file: %s' % error)
       sys.exit(1)
-    except KeyError:
-      print('There is a field error in manifest.json file.')
+    except KeyError as error:
+      print('There is a field error in manifest.json file: %s' % error)
       sys.exit(1)
     finally:
       input_file.close()
diff --git a/src/xwalk/app/tools/android/test_data/compressor/css/test.css b/src/xwalk/app/tools/android/test_data/compressor/css/test.css
new file mode 100644 (file)
index 0000000..5bbdecf
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+
+#body {
+    background-color: blue;
+}
+
+#div {
+    position: absolute;
+    width: 20px;
+    height: 20px;
+    text-align: center;
+}
+
+h1 {
+    color:orange;
+    text-align:center;
+}
+
+p {
+    font-family:"Times New Roman";
+    font-size:50px;
+}
diff --git a/src/xwalk/app/tools/android/test_data/compressor/js/test.js b/src/xwalk/app/tools/android/test_data/compressor/js/test.js
new file mode 100644 (file)
index 0000000..358ef05
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0.  The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+
+function multiplication(p1, p2) {
+  return p1 * p2; // return the product of p1 and p2.
+}
+
+function testAlert() {
+  alert("hello, world");
+}
diff --git a/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_parse_error.json b/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_parse_error.json
new file mode 100644 (file)
index 0000000..f16dbf2
--- /dev/null
@@ -0,0 +1,14 @@
+{
+  "name": "\Example",
+  "version": "1.0.0",
+  "launch_path": "http://www.intel.com",
+  "app": {
+      "launch": {
+          "local_path": "index.html"
+      }
+  },
+  "description": "a sample description",
+  "origin": "app://app.id",
+  "default_locale": "en",
+  "fullscreen":"true"
+}
diff --git a/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_chinese_name.json b/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_chinese_name.json
new file mode 100644 (file)
index 0000000..910c31b
--- /dev/null
@@ -0,0 +1,14 @@
+{
+  "name": "你好",
+  "version": "1.0.0",
+  "launch_path": "http://www.intel.com",
+  "app": {
+      "launch": {
+          "local_path": "index.html"
+      }
+  },
+  "description": "a sample description",
+  "origin": "app://app.id",
+  "default_locale": "en",
+  "fullscreen":"true"
+}
diff --git a/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_invalid_name.json b/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_invalid_name.json
new file mode 100644 (file)
index 0000000..413b4f0
--- /dev/null
@@ -0,0 +1,14 @@
+{
+  "name": "@*&^Example",
+  "version": "1.0.0",
+  "launch_path": "http://www.intel.com",
+  "app": {
+      "launch": {
+          "local_path": "index.html"
+      }
+  },
+  "description": "a sample description",
+  "origin": "app://app.id",
+  "default_locale": "en",
+  "fullscreen":"true"
+}
diff --git a/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_space_name.json b/src/xwalk/app/tools/android/test_data/manifest/invalidchars/manifest_with_space_name.json
new file mode 100644 (file)
index 0000000..cdbb6dc
--- /dev/null
@@ -0,0 +1,14 @@
+{
+  "name": " ",
+  "version": "1.0.0",
+  "launch_path": "http://www.intel.com",
+  "app": {
+      "launch": {
+          "local_path": "index.html"
+      }
+  },
+  "description": "a sample description",
+  "origin": "app://app.id",
+  "default_locale": "en",
+  "fullscreen":"true"
+}
index 8bd625c..002f58d 100644 (file)
 #include "xwalk/runtime/browser/xwalk_runner.h"
 #include "xwalk/runtime/common/xwalk_common_messages.h"
 
-#if defined(OS_TIZEN)
-#include "xwalk/runtime/browser/ui/native_app_window.h"
-#endif
-
-#if defined(USE_OZONE) && defined(OS_TIZEN)
-#include "base/message_loop/message_pump_ozone.h"
-#include "content/public/browser/render_view_host.h"
-#include "ui/events/event.h"
-#include "ui/events/event_constants.h"
-#include "ui/events/keycodes/keyboard_codes_posix.h"
-#include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h"
-#endif
-
-#if defined(OS_TIZEN)
-#include "xwalk/application/common/manifest_handlers/navigation_handler.h"
-#endif
-
 namespace xwalk {
 
 namespace keys = application_manifest_keys;
@@ -59,10 +42,6 @@ const char* kDefaultWidgetEntryPage[] = {
 "index.xhtml",
 "index.xht"};
 
-content::RenderProcessHost* GetHost(Runtime* runtime) {
-  DCHECK(runtime);
-  return runtime->web_contents()->GetRenderProcessHost();
-}
 }  // namespace
 
 namespace application {
@@ -93,26 +72,20 @@ Application::Application(
     scoped_refptr<ApplicationData> data,
     RuntimeContext* runtime_context,
     Observer* observer)
-    : runtime_context_(runtime_context),
+    : main_runtime_(NULL),
       application_data_(data),
-      main_runtime_(NULL),
+      is_security_mode_(false),
+      runtime_context_(runtime_context),
       observer_(observer),
       entry_point_used_(Default),
       termination_mode_used_(Normal),
-      weak_factory_(this),
-      is_security_mode_(false) {
+      weak_factory_(this) {
   DCHECK(runtime_context_);
   DCHECK(application_data_);
   DCHECK(observer_);
-#if defined(USE_OZONE) && defined(OS_TIZEN)
-  base::MessagePumpOzone::Current()->AddObserver(this);
-#endif
 }
 
 Application::~Application() {
-#if defined(USE_OZONE) && defined(OS_TIZEN)
-  base::MessagePumpOzone::Current()->RemoveObserver(this);
-#endif
   Terminate(Immediate);
 }
 
@@ -261,17 +234,6 @@ void Application::Terminate(TerminationMode mode) {
                 std::mem_fun(&Runtime::Close));
 }
 
-#if defined(OS_TIZEN)
-void Application::Hide() {
-  DCHECK(runtimes_.size());
-  std::set<Runtime*>::iterator it = runtimes_.begin();
-  for (; it != runtimes_.end(); ++it) {
-    if ((*it)->window())
-      (*it)->window()->Hide();
-  }
-}
-#endif
-
 Runtime* Application::GetMainDocumentRuntime() const {
   return HasMainDocument() ? main_runtime_ : NULL;
 }
@@ -446,35 +408,6 @@ void Application::InitSecurityPolicy() {
   if (application_data_->GetPackageType() != Manifest::TYPE_WGT)
     return;
 
-#if defined(OS_TIZEN)
-  // On Tizen, CSP mode has higher priority, and WARP will be disabled
-  // if the application is under CSP mode.
-  if (application_data_->HasCSPDefined()) {
-    // Always enable security mode when under CSP mode.
-    is_security_mode_ = true;
-    NavigationInfo* info = static_cast<NavigationInfo*>(
-        application_data_->GetManifestData(widget_keys::kAllowNavigationKey));
-    if (info) {
-      const std::vector<std::string>& allowed_list = info->GetAllowedDomains();
-      for (std::vector<std::string>::const_iterator it = allowed_list.begin();
-           it != allowed_list.end(); ++it) {
-        // If the policy start with "*.", like this: *.domain,
-        // means that can access to all subdomains for 'domain',
-        // otherwise, the host of request url should exactly the same
-        // as policy.
-        bool subdomains = ((*it).find("*.") == 0);
-        std::string host = subdomains ? (*it).substr(2) : (*it);
-        AddSecurityPolicy(GURL("http://" + host), subdomains);
-        AddSecurityPolicy(GURL("https://" + host), subdomains);
-      }
-    }
-    GetHost(main_runtime_)->Send(
-        new ViewMsg_EnableSecurityMode(
-            ApplicationData::GetBaseURLFromApplicationId(id()),
-            SecurityPolicy::CSP));
-    return;
-  }
-#endif
   const WARPInfo* info = static_cast<WARPInfo*>(
       application_data_->GetManifestData(widget_keys::kAccessKey));
   // FIXME(xinchao): Need to enable WARP mode by default.
@@ -503,7 +436,7 @@ void Application::InitSecurityPolicy() {
     is_security_mode_ = true;
   }
   if (is_security_mode_)
-    GetHost(main_runtime_)->Send(
+    main_runtime_->GetRenderProcessHost()->Send(
         new ViewMsg_EnableSecurityMode(
             ApplicationData::GetBaseURLFromApplicationId(id()),
             SecurityPolicy::WARP));
@@ -511,7 +444,7 @@ void Application::InitSecurityPolicy() {
 
 void Application::AddSecurityPolicy(const GURL& url, bool subdomains) {
   GURL app_url = application_data_->URL();
-  GetHost(main_runtime_)->Send(
+  main_runtime_->GetRenderProcessHost()->Send(
       new ViewMsg_SetAccessWhiteList(
           app_url, url, subdomains));
   security_policy_.push_back(new SecurityPolicy(url, subdomains));
@@ -530,7 +463,7 @@ bool Application::CanRequestURL(const GURL& url) const {
       url.host() == id())
     return true;
 
-  for (int i = 0; i < security_policy_.size(); ++i) {
+  for (unsigned i = 0; i < security_policy_.size(); ++i) {
     const GURL& policy = security_policy_[i]->url();
     bool subdomains = security_policy_[i]->subdomains();
     bool is_host_matched = subdomains ?
@@ -541,41 +474,5 @@ bool Application::CanRequestURL(const GURL& url) const {
   return false;
 }
 
-#if defined(USE_OZONE) && defined(OS_TIZEN)
-base::EventStatus Application::WillProcessEvent(
-    const base::NativeEvent& event) {
-  return base::EVENT_CONTINUE;
-}
-
-void Application::DidProcessEvent(
-    const base::NativeEvent& event) {
-  ui::Event* eve = static_cast<ui::Event*>(event);
-  if (!eve->IsKeyEvent() || eve->type() != ui::ET_KEY_PRESSED)
-    return;
-
-  ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(eve);
-
-  // FIXME: Most Wayland devices don't have similar hardware button for 'back'
-  // and 'memu' as Tizen Mobile, even that hardare buttons could be different
-  // across different kinds of Wayland platforms.
-  // Here use external keyboard button 'Backspace' & 'HOME' to emulate 'back'
-  // and 'menu' key. Should change this if there is customized key binding.
-  if (key_event->key_code() != ui::VKEY_BACK &&
-      key_event->key_code() != ui::VKEY_HOME)
-    return;
-
-  TizenSettingInfo* info = static_cast<TizenSettingInfo*>(
-      data()->GetManifestData(widget_keys::kTizenSettingKey));
-  if (info && !info->hwkey_enabled())
-    return;
-
-  for (std::set<xwalk::Runtime*>::iterator it = runtimes_.begin();
-      it != runtimes_.end(); ++it) {
-    (*it)->web_contents()->GetRenderViewHost()->Send(new ViewMsg_HWKeyPressed(
-        (*it)->web_contents()->GetRoutingID(), key_event->key_code()));
-  }
-}
-#endif
-
 }  // namespace application
 }  // namespace xwalk
index 4de28db..fc0fb98 100644 (file)
 #include "xwalk/application/common/security_policy.h"
 #include "xwalk/runtime/browser/runtime.h"
 
-#if defined(USE_OZONE) && defined(OS_TIZEN)
-#include "base/message_loop/message_pump_observer.h"
-#endif
-
 namespace xwalk {
 
 class RuntimeContext;
@@ -41,12 +37,7 @@ class SecurityPolicy;
 // terminated.
 // There's one-to-one correspondence between Application and Render Process
 // Host, obtained from its "runtimes" (pages).
-class Application
-  :
-#if defined(USE_OZONE) && defined(OS_TIZEN)
-  public base::MessagePumpObserver,
-#endif
-  public Runtime::Observer {
+class Application : public Runtime::Observer {
  public:
   virtual ~Application();
 
@@ -97,10 +88,6 @@ class Application
   };
   void Terminate(TerminationMode = Normal);
 
-#if defined(OS_TIZEN)
-  void Hide();
-#endif
-
   // Returns Runtime (application page) containing the application's
   // 'main document'. The main document is the main entry point of
   // the application to the system. This method will return 'NULL'
@@ -140,17 +127,27 @@ class Application
                      StoredPermission perm);
   bool CanRequestURL(const GURL& url) const;
 
+ protected:
+  // We enforce ApplicationService ownership.
+  friend class ApplicationService;
+  Application(scoped_refptr<ApplicationData> data,
+              RuntimeContext* context,
+              Observer* observer);
+
+  virtual void InitSecurityPolicy();
+  void AddSecurityPolicy(const GURL& url, bool subdomains);
+
+  Runtime* main_runtime_;
+  std::set<Runtime*> runtimes_;
+  scoped_refptr<ApplicationData> const application_data_;
+  bool is_security_mode_;
+
  private:
   bool HasMainDocument() const;
   // Runtime::Observer implementation.
   virtual void OnRuntimeAdded(Runtime* runtime) OVERRIDE;
   virtual void OnRuntimeRemoved(Runtime* runtime) OVERRIDE;
 
-  // We enforce ApplicationService ownership.
-  friend class ApplicationService;
-  Application(scoped_refptr<ApplicationData> data,
-              RuntimeContext* context,
-              Observer* observer);
   bool Launch(const LaunchParams& launch_params);
 
   // Try to extract the URL from different possible keys for entry points in the
@@ -168,32 +165,19 @@ class Application
   bool IsOnSuspendHandlerRegistered() const;
   bool IsTerminating() const { return finish_observer_; }
 
-  void InitSecurityPolicy();
-  void AddSecurityPolicy(const GURL& url, bool subdomains);
-
-#if defined(USE_OZONE) && defined(OS_TIZEN)
-  virtual base::EventStatus WillProcessEvent(
-      const base::NativeEvent& event) OVERRIDE;
-  virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
-#endif
-
   RuntimeContext* runtime_context_;
-  const scoped_refptr<ApplicationData> application_data_;
-  Runtime* main_runtime_;
-  std::set<Runtime*> runtimes_;
   scoped_ptr<EventObserver> finish_observer_;
   Observer* observer_;
   // The entry point used as part of Launch().
   LaunchEntryPoint entry_point_used_;
   TerminationMode termination_mode_used_;
-  base::WeakPtrFactory<Application> weak_factory_;
   std::map<std::string, std::string> name_perm_map_;
   // Application's session permissions.
   StoredPermissionMap permission_map_;
   // Security policy set.
   ScopedVector<SecurityPolicy> security_policy_;
-  bool is_security_mode_;
-
+  // WeakPtrFactory should be always declared the last.
+  base::WeakPtrFactory<Application> weak_factory_;
   DISALLOW_COPY_AND_ASSIGN(Application);
 };
 
index b9a8411..a99d8a3 100644 (file)
@@ -30,6 +30,7 @@
 #include "xwalk/runtime/common/xwalk_paths.h"
 
 #if defined(OS_TIZEN)
+#include "xwalk/application/browser/application_tizen.h"
 #include "xwalk/application/browser/installer/tizen/service_package_installer.h"
 #endif
 
@@ -492,7 +493,7 @@ bool ApplicationService::Uninstall(const std::string& id) {
   return result;
 }
 
-bool ApplicationService::ChangeLocale(const std::string& locale) {
+void ApplicationService::ChangeLocale(const std::string& locale) {
   const ApplicationData::ApplicationDataMap& apps =
       application_storage_->GetInstalledApplications();
   ApplicationData::ApplicationDataMap::const_iterator it;
@@ -526,9 +527,15 @@ Application* ApplicationService::Launch(
   }
 
   event_manager_->AddEventRouterForApp(application_data);
+
+#if defined(OS_TIZEN)
+  Application* application(new ApplicationTizen(application_data,
+    runtime_context_, this));
+#else
   Application* application(new Application(application_data,
-                                           runtime_context_,
-                                           this));
+    runtime_context_, this));
+#endif
+
   ScopedVector<Application>::iterator app_iter =
       applications_.insert(applications_.end(), application);
 
index 23e30a1..7a18dc2 100644 (file)
@@ -54,7 +54,7 @@ class ApplicationService : public Application::Observer {
   bool Install(const base::FilePath& path, std::string* id);
   bool Uninstall(const std::string& id);
   bool Update(const std::string& id, const base::FilePath& path);
-  bool ChangeLocale(const std::string& locale);
+  void ChangeLocale(const std::string& locale);
 
   Application* Launch(scoped_refptr<ApplicationData> application_data,
                       const Application::LaunchParams& launch_params);
diff --git a/src/xwalk/application/browser/application_tizen.cc b/src/xwalk/application/browser/application_tizen.cc
new file mode 100644 (file)
index 0000000..942c702
--- /dev/null
@@ -0,0 +1,144 @@
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xwalk/application/browser/application_tizen.h"
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/render_process_host.h"
+
+#include "xwalk/runtime/browser/ui/native_app_window.h"
+#include "xwalk/runtime/common/xwalk_common_messages.h"
+
+#if defined(USE_OZONE)
+#include "base/message_loop/message_pump_ozone.h"
+#include "content/public/browser/render_view_host.h"
+#include "ui/events/event.h"
+#include "ui/events/event_constants.h"
+#include "ui/events/keycodes/keyboard_codes_posix.h"
+#include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h"
+#endif
+
+#include "xwalk/application/common/application_manifest_constants.h"
+#include "xwalk/application/common/manifest_handlers/navigation_handler.h"
+
+namespace xwalk {
+
+namespace widget_keys = application_widget_keys;
+
+namespace application {
+
+namespace {
+const char kAsterisk[] = "*";
+}  // namespace
+
+
+ApplicationTizen::ApplicationTizen(
+    scoped_refptr<ApplicationData> data,
+    RuntimeContext* runtime_context,
+    Application::Observer* observer)
+    : Application(data, runtime_context, observer) {
+#if defined(USE_OZONE)
+  base::MessagePumpOzone::Current()->AddObserver(this);
+#endif
+}
+
+ApplicationTizen::~ApplicationTizen() {
+#if defined(USE_OZONE)
+  base::MessagePumpOzone::Current()->RemoveObserver(this);
+#endif
+}
+
+void ApplicationTizen::Hide() {
+  DCHECK(runtimes_.size());
+  std::set<Runtime*>::iterator it = runtimes_.begin();
+  for (; it != runtimes_.end(); ++it) {
+    if ((*it)->window())
+      (*it)->window()->Hide();
+  }
+}
+
+void ApplicationTizen::InitSecurityPolicy() {
+  // On Tizen, CSP mode has higher priority, and WARP will be disabled
+  // if the application is under CSP mode.
+  if (!application_data_->HasCSPDefined()) {
+    Application::InitSecurityPolicy();
+    return;
+  }
+
+  if (application_data_->GetPackageType() != Manifest::TYPE_WGT)
+    return;
+
+  // Always enable security mode when under CSP mode.
+  is_security_mode_ = true;
+  NavigationInfo* info = static_cast<NavigationInfo*>(
+      application_data_->GetManifestData(widget_keys::kAllowNavigationKey));
+  if (info) {
+    const std::vector<std::string>& allowed_list = info->GetAllowedDomains();
+    for (std::vector<std::string>::const_iterator it = allowed_list.begin();
+         it != allowed_list.end(); ++it) {
+      // If the policy is "*", it represents that any external link is allowed
+      // to navigate to.
+      if ((*it) == kAsterisk) {
+        is_security_mode_ = false;
+        return;
+      }
+
+      // If the policy start with "*.", like this: *.domain,
+      // means that can access to all subdomains for 'domain',
+      // otherwise, the host of request url should exactly the same
+      // as policy.
+      bool subdomains = ((*it).find("*.") == 0);
+      std::string host = subdomains ? (*it).substr(2) : (*it);
+      AddSecurityPolicy(GURL("http://" + host), subdomains);
+      AddSecurityPolicy(GURL("https://" + host), subdomains);
+    }
+  }
+  main_runtime_->GetRenderProcessHost()->Send(
+      new ViewMsg_EnableSecurityMode(
+          ApplicationData::GetBaseURLFromApplicationId(id()),
+          SecurityPolicy::CSP));
+}
+
+#if defined(USE_OZONE)
+base::EventStatus ApplicationTizen::WillProcessEvent(
+    const base::NativeEvent& event) {
+  return base::EVENT_CONTINUE;
+}
+
+void ApplicationTizen::DidProcessEvent(
+    const base::NativeEvent& event) {
+  ui::Event* ui_event = static_cast<ui::Event*>(event);
+  if (!ui_event->IsKeyEvent() || ui_event->type() != ui::ET_KEY_PRESSED)
+    return;
+
+  ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(ui_event);
+
+  // FIXME: Most Wayland devices don't have similar hardware button for 'back'
+  // and 'memu' as Tizen Mobile, even that hardare buttons could be different
+  // across different kinds of Wayland platforms.
+  // Here use external keyboard button 'Backspace' & 'HOME' to emulate 'back'
+  // and 'menu' key. Should change this if there is customized key binding.
+  if (key_event->key_code() != ui::VKEY_BACK &&
+      key_event->key_code() != ui::VKEY_HOME)
+    return;
+
+  TizenSettingInfo* info = static_cast<TizenSettingInfo*>(
+      data()->GetManifestData(widget_keys::kTizenSettingKey));
+  if (info && !info->hwkey_enabled())
+    return;
+
+  for (std::set<xwalk::Runtime*>::iterator it = runtimes_.begin();
+      it != runtimes_.end(); ++it) {
+    (*it)->web_contents()->GetRenderViewHost()->Send(new ViewMsg_HWKeyPressed(
+        (*it)->web_contents()->GetRoutingID(), key_event->key_code()));
+  }
+}
+#endif
+
+}  // namespace application
+}  // namespace xwalk
diff --git a/src/xwalk/application/browser/application_tizen.h b/src/xwalk/application/browser/application_tizen.h
new file mode 100644 (file)
index 0000000..a1d424f
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef XWALK_APPLICATION_BROWSER_APPLICATION_TIZEN_H_
+#define XWALK_APPLICATION_BROWSER_APPLICATION_TIZEN_H_
+
+#include "xwalk/application/browser/application.h"
+
+#if defined(USE_OZONE)
+#include "base/message_loop/message_pump_observer.h"
+#endif
+
+namespace xwalk {
+namespace application {
+
+class ApplicationTizen : //  NOLINT
+#if defined(USE_OZONE)
+  public base::MessagePumpObserver,
+#endif
+  public Application {
+ public:
+  virtual ~ApplicationTizen();
+  void Hide();
+
+ private:
+  // We enforce ApplicationService ownership.
+  friend class ApplicationService;
+  ApplicationTizen(scoped_refptr<ApplicationData> data,
+                   RuntimeContext* context,
+                   Application::Observer* observer);
+
+  virtual void InitSecurityPolicy() OVERRIDE;
+
+#if defined(USE_OZONE)
+  virtual base::EventStatus WillProcessEvent(
+      const base::NativeEvent& event) OVERRIDE;
+  virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
+#endif
+};
+
+inline ApplicationTizen* ToApplicationTizen(Application* app) {
+  return static_cast<ApplicationTizen*>(app);
+}
+
+}  // namespace application
+}  // namespace xwalk
+
+#endif  // XWALK_APPLICATION_BROWSER_APPLICATION_TIZEN_H_
index 19b8cd5..efba653 100644 (file)
@@ -11,9 +11,9 @@
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/exported_object.h"
+#include "xwalk/application/browser/application_tizen.h"
 #include "xwalk/application/browser/linux/running_applications_manager.h"
 
-
 namespace {
 
 // D-Bus Interface implemented by objects that represent running
@@ -158,7 +158,7 @@ void RunningApplicationObject::OnHide(
     return;
   }
 
-  application_->Hide();
+  ToApplicationTizen(application_)->Hide();
 
   scoped_ptr<dbus::Response> response =
       dbus::Response::FromMethodCall(method_call);
index 54a6762..7bf8ade 100644 (file)
@@ -28,6 +28,7 @@
 #include "xwalk/application/common/manifest_handler.h"
 #include "xwalk/application/common/manifest_handlers/main_document_handler.h"
 #include "xwalk/application/common/manifest_handlers/permissions_handler.h"
+#include "xwalk/application/common/manifest_handlers/widget_handler.h"
 #include "xwalk/application/common/permission_policy_manager.h"
 #include "content/public/common/url_constants.h"
 #include "url/url_util.h"
@@ -373,11 +374,25 @@ bool ApplicationData::HasCSPDefined() const {
 
 bool ApplicationData::SetApplicationLocale(const std::string& locale,
                                            base::string16* error) {
+  DCHECK(thread_checker_.CalledOnValidThread());
   manifest_->SetSystemLocale(locale);
   if (!LoadName(error))
     return false;
   if (!LoadDescription(error))
     return false;
+
+  // Only update when the package is wgt and we have parsed the widget handler,
+  // otherwise we can not get widget_info.
+  if (WidgetInfo* widget_info = static_cast<WidgetInfo*>(
+          GetManifestData(widget_keys::kWidgetKey))) {
+    std::string string_value;
+    if (manifest_->GetString(widget_keys::kNameKey, &string_value))
+      widget_info->SetName(string_value);
+    if (manifest_->GetString(widget_keys::kShortNameKey, &string_value))
+      widget_info->SetShortName(string_value);
+    if (manifest_->GetString(widget_keys::kDescriptionKey, &string_value))
+      widget_info->SetDescription(string_value);
+  }
   return true;
 }
 
index 94c3089..8a84774 100644 (file)
@@ -17,6 +17,8 @@ const base::FilePath::CharType kMessagesFilename[] =
     FILE_PATH_LITERAL("messages.json");
 const char kGeneratedMainDocumentFilename[] =
     "_generated_main_document.html";
+const base::FilePath::CharType kCookieDatabaseFilename[] =
+    FILE_PATH_LITERAL("ApplicationCookies");
 
 }  // namespace application
 }  // namespace xwalk
index 9b86ae2..3878fe0 100644 (file)
@@ -25,6 +25,9 @@ extern const base::FilePath::CharType kMessagesFilename[];
 // The filename to use for main document generated from app.main.scripts.
 extern const char kGeneratedMainDocumentFilename[];
 
+// The name of cookies database file.
+extern const base::FilePath::CharType kCookieDatabaseFilename[];
+
 }  // namespace application
 }  // namespace xwalk
 
index ee49846..ec29744 100644 (file)
@@ -93,6 +93,18 @@ void WidgetInfo::Set(const std::string& key, base::Value* value) {
   value_->Set(key, value);
 }
 
+void WidgetInfo::SetName(const std::string& name) {
+  value_->SetString(kName, name);
+}
+
+void WidgetInfo::SetShortName(const std::string& short_name) {
+  value_->SetString(kShortName, short_name);
+}
+
+void WidgetInfo::SetDescription(const std::string& description) {
+  value_->SetString(kDecription, description);
+}
+
 WidgetHandler::WidgetHandler() {}
 
 WidgetHandler::~WidgetHandler() {}
index c97a671..2e2ebb3 100644 (file)
@@ -22,6 +22,12 @@ class WidgetInfo : public ApplicationData::ManifestData {
   void SetString(const std::string& key, const std::string& value);
   void Set(const std::string& key, base::Value* value);
 
+  // Name, shrot name and description are i18n items, they will be set
+  // if their value were changed after loacle was changed.
+  void SetName(const std::string& name);
+  void SetShortName(const std::string& short_name);
+  void SetDescription(const std::string& description);
+
   base::DictionaryValue* GetWidgetInfo() {
     return value_.get();
   }
index f3b06af..bafe531 100644 (file)
@@ -63,7 +63,7 @@
             'gio',
           ],
         }],
-        ['tizen==1 or tizen_mobile==1', {
+        ['tizen==1', {
           'dependencies': [
             'gio',
             '../../../build/system.gyp:tizen_appcore_common'
index 7d5f60d..415ef01 100644 (file)
@@ -5,7 +5,7 @@
       'type': 'executable',
       'product_name': 'xwalk-pkg-helper',
       'conditions': [
-        ['tizen==1 or tizen_mobile==1', {
+        ['tizen==1', {
           'dependencies': [
             '../../../build/system.gyp:tizen',
             '../../../../base/base.gyp:base',
index 905e4cc..d114e2d 100644 (file)
             'browser/linux/running_applications_manager.h',
           ],
         }],
-        [ 'tizen == 1 or tizen_mobile == 1', {
+        ['tizen==1', {
           'dependencies': [
             'build/system.gyp:tizen',
             'tizen/xwalk_tizen.gypi:xwalk_tizen_lib',
             '../third_party/re2/re2.gyp:re2',
           ],
           'sources': [
+            'browser/application_tizen.cc',
+            'browser/application_tizen.h',
             'browser/installer/tizen/packageinfo_constants.cc',
             'browser/installer/tizen/packageinfo_constants.h',
             'browser/installer/tizen/service_package_installer.cc',
index c64965a..d71c067 100755 (executable)
@@ -245,6 +245,14 @@ def main(argv):
   src_dir = os.path.join(out_project_dir, 'src')
   if not os.path.isdir(src_dir):
     os.mkdir(src_dir)
+  readme = os.path.join(src_dir, 'README.md')
+  open(readme, 'w').write(
+      "# Source folder for xwalk_core_library\n"
+      "## Why it's empty\n"
+      "xwalk_core_library doesn't contain java sources.\n"
+      "## Why put me here\n"
+      "To make archives keep the folder, "
+      "the src directory is needed to build an apk by ant.")
   print 'Your Android library project has been created at %s' % (
       out_project_dir)
 
index 6bf7a55..8035093 100644 (file)
@@ -4,7 +4,7 @@
 
 {
   'conditions': [
-    [ 'tizen == 1 or tizen_mobile == 1', {
+    ['tizen==1', {
       'targets': [
         {
           'target_name': 'tizen_geolocation',
index 3b50c54..ced9511 100644 (file)
@@ -11,7 +11,7 @@
 # every .gyp file, including Chromium's).
 {
   'target_conditions': [
-    ['tizen_mobile!=1 and tizen!=1', {
+    ['tizen!=1', {
       'sources/': [
         ['exclude', '_tizen(_unittest)?\\.(h|cc)$'],
         ['exclude', '(^|/)tizen/'],
index e5a030e..f07411d 100644 (file)
@@ -18,7 +18,7 @@
         'xwalk_service_name.h',
       ],
       'conditions': [
-        [ 'tizen == 1 or tizen_mobile == 1', {
+        ['tizen==1', {
           'sources': [
             'dbus_manager_tizen.cc',
           ],
index 6cedf75..113af1c 100644 (file)
@@ -2,7 +2,7 @@
 %bcond_with wayland
 
 Name:           crosswalk
-Version:        6.35.132.0
+Version:        7.35.136.0
 Release:        0
 Summary:        Crosswalk is an app runtime based on Chromium
 License:        (BSD-3-Clause and LGPL-2.1+)
index 21bdf9b..0aa44df 100644 (file)
@@ -438,6 +438,7 @@ class XWalkContent extends FrameLayout implements XWalkPreferences.KeyValueChang
     public void destroy() {
         if (mXWalkContent == 0) return;
 
+        XWalkPreferences.unload(this);
         // Reset existing notification service in order to destruct it.
         setNotificationService(null);
         // Remove its children used for page rendering from view hierarchy.
index bb0d099..1f57e2c 100644 (file)
@@ -128,8 +128,9 @@ public class XWalkLaunchScreenManager
                 mLaunchScreenDialog.getWindow().setBackgroundDrawable(bgDrawable);
                 // Set foreground image
                 RelativeLayout root = getLaunchScreenLayout(imageBorderList);
-                if (root == null) return;
-                mLaunchScreenDialog.setContentView(root);
+                // The root layout can be null when there is no 'image' provided in the manifest.
+                // We can just display the background instead of no launch screen dialog displayed.
+                if (root != null) mLaunchScreenDialog.setContentView(root);
                 mLaunchScreenDialog.show();
 
                 // Change the layout depends on the orientation change.
index 0d793dc..6258d74 100644 (file)
@@ -10,6 +10,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
 import android.util.Log;
+import android.webkit.MimeTypeMap;
 
 import org.chromium.components.navigation_interception.NavigationParams;
 
@@ -47,7 +48,9 @@ public class XWalkNavigationHandlerImpl implements XWalkNavigationHandler {
         } else {
             intent = createIntentForActionUri(url);
         }
-        return intent != null && startActivity(intent);
+        if (intent != null && startActivity(intent)) return true;
+
+        return handleUrlByMimeType(url);
     }
 
     protected boolean startActivity(Intent intent) {
@@ -120,4 +123,32 @@ public class XWalkNavigationHandlerImpl implements XWalkNavigationHandler {
         }
         return intent;
     }
+
+    private boolean handleUrlByMimeType(String url) {
+        MimeTypeMap map = MimeTypeMap.getSingleton();
+        String extenstion = MimeTypeMap.getFileExtensionFromUrl(url);
+        String mimeType = map.getMimeTypeFromExtension(extenstion);
+
+        if (shouldHandleMimeType(mimeType)) {
+            Intent sendIntent = new Intent();
+            sendIntent.setAction(Intent.ACTION_VIEW);
+            sendIntent.setDataAndType(Uri.parse(url), mimeType);
+
+            if (sendIntent.resolveActivity(mContext.getPackageManager()) != null) {
+                startActivity(sendIntent);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean shouldHandleMimeType(String mimeType) {
+        // Currently only "application/*" MIME type should be handled.
+        // Other types (text/*, video/*, image/*, audio/*) are not handled
+        // by intent actions.
+        if (mimeType != null && mimeType.startsWith("application/")) {
+            return true;
+        }
+        return false;
+    }
 }
index 6547772..8802288 100644 (file)
@@ -80,9 +80,9 @@ public final class XWalkNavigationHistory implements Cloneable, Serializable {
      * The direction for web page navigation.
      */
     public enum Direction {
-        /** the backward direction for web page navigation. */
+        /** The backward direction for web page navigation. */
         BACKWARD,
-        /** the forward direction for web page navigation. */
+        /** The forward direction for web page navigation. */
         FORWARD
     }
 
index 3423876..08a0b78 100644 (file)
@@ -4,6 +4,8 @@
 
 package org.xwalk.core;
 
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
@@ -16,8 +18,12 @@ import java.util.Map;
  */
 public final class XWalkPreferences {
     private static HashMap<String, Boolean> sPrefMap = new HashMap<String, Boolean>();
-    private static ArrayList<KeyValueChangeListener> sListeners =
-            new ArrayList<KeyValueChangeListener>();
+    // Here we use WeakReference to make sure the KeyValueChangeListener instance
+    // can be GC-ed to avoid memory leaking issue.
+    private static ArrayList<WeakReference<KeyValueChangeListener> > sListeners =
+            new ArrayList<WeakReference<KeyValueChangeListener> >();
+    private static ReferenceQueue<KeyValueChangeListener> sRefQueue =
+            new ReferenceQueue<KeyValueChangeListener>();
 
     /**
      * The key string to enable/disable remote debugging.
@@ -66,26 +72,56 @@ public final class XWalkPreferences {
         registerListener(listener);
     }
 
+    static synchronized void unload(KeyValueChangeListener listener) {
+        unregisterListener(listener);
+    }
+
     // Listen to value changes.
     interface KeyValueChangeListener {
         public void onKeyValueChanged(String key, boolean value);
     }
 
     private static synchronized void registerListener(KeyValueChangeListener listener) {
-        sListeners.add(listener);
+        removeEnqueuedReference();
+        WeakReference<KeyValueChangeListener> weakListener =
+                new WeakReference<KeyValueChangeListener>(listener, sRefQueue);
+        sListeners.add(weakListener);
+    }
+
+    private static synchronized void unregisterListener(KeyValueChangeListener listener) {
+        removeEnqueuedReference();
+        for (WeakReference<KeyValueChangeListener> weakListener : sListeners) {
+            if (weakListener.get() == listener) {
+                sListeners.remove(weakListener);
+                break;
+            }
+        }
     }
 
     private static void onKeyValueChanged(String key, boolean enabled) {
-        for (KeyValueChangeListener listener : sListeners) {
-            listener.onKeyValueChanged(key, enabled);
+        for (WeakReference<KeyValueChangeListener> weakListener : sListeners) {
+            KeyValueChangeListener listener = weakListener.get();
+            if (listener != null) listener.onKeyValueChanged(key, enabled);
         }
     }
 
     private static void checkKey(String key) throws RuntimeException {
+        removeEnqueuedReference();
         if (!sPrefMap.containsKey(key)) {
             throw new RuntimeException("Warning: the preference key " + key +
                     " is not supported by Crosswalk.");
         }
     }
 
+    /**
+     * Internal method to keep track of weak references and remove the enqueued
+     * references from listener list by polling the reference queue.
+     */
+    @SuppressWarnings("unchecked")
+    private static void removeEnqueuedReference() {
+        WeakReference<KeyValueChangeListener> toRemove;
+        while ((toRemove = (WeakReference<KeyValueChangeListener>) sRefQueue.poll()) != null) {
+            sListeners.remove(toRemove);
+        }
+    }
 }
index af86daf..58d4453 100644 (file)
@@ -201,15 +201,11 @@ public class XWalkUIClient {
                         fResult.confirm();
                         dialog.dismiss();
                     }
-                }).setOnKeyListener(new DialogInterface.OnKeyListener() {
+                })
+                .setOnCancelListener(new DialogInterface.OnCancelListener() {
                     @Override
-                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-                        if (keyCode == KeyEvent.KEYCODE_BACK) {
-                            fResult.confirm();
-                            return false;
-                        } else {
-                            return true;
-                        }
+                    public void onCancel(DialogInterface dialog) {
+                        fResult.cancel();
                     }
                 });
         mDialog = dialogBuilder.create();
@@ -231,22 +227,20 @@ public class XWalkUIClient {
                         dialog.dismiss();
                     }
                 })
-                .setNegativeButton(mCancelButton, null)
+                // Need to implement 'onClick' and call the dialog.cancel. Otherwise, the
+                // UI will be locked.
+                .setNegativeButton(mCancelButton, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        // This will call OnCancelLisitener.onCancel().
+                        dialog.cancel();
+                    }
+                })
                 .setOnCancelListener(new DialogInterface.OnCancelListener() {
                     @Override
                     public void onCancel(DialogInterface dialog) {
                         fResult.cancel();
                     }
-                }).setOnKeyListener(new DialogInterface.OnKeyListener() {
-                    @Override
-                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-                        if (keyCode == KeyEvent.KEYCODE_BACK) {
-                            fResult.confirm();
-                            return false;
-                        } else {
-                            return true;
-                        }
-                    }
                 });
         mDialog = dialogBuilder.create();
         mDialog.show();
@@ -266,7 +260,15 @@ public class XWalkUIClient {
                         dialog.dismiss();
                     }
                 })
-                .setNegativeButton(mCancelButton, null)
+                // Need to implement 'onClick' and call the dialog.cancel. Otherwise, the
+                // UI will be locked.
+                .setNegativeButton(mCancelButton, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        // This will call OnCancelLisitener.onCancel().
+                        dialog.cancel();
+                    }
+                })
                 .setOnCancelListener(new DialogInterface.OnCancelListener() {
                     @Override
                     public void onCancel(DialogInterface dialog) {
index 49771f4..c7e0288 100644 (file)
@@ -29,31 +29,123 @@ import org.chromium.base.ApplicationStatus;
 import org.xwalk.core.extension.XWalkExtensionManager;
 
 /**
- * XWalkView represents an Android view for web apps/pages. Thus most of attributes
- * for Android view are true for this class. It includes an instance of
- * android.view.SurfaceView for rendering. Currently limitations for android.view.SurfaceView
- * also are applied for this class as well, like resizing, retation, transformation and
- * animation.
+ * <p>XWalkView represents an Android view for web apps/pages. Thus most of attributes
+ * for Android view are valid for this class. Since it internally uses
+ * <a href="http://developer.android.com/reference/android/view/SurfaceView.html">
+ * android.view.SurfaceView</a> for rendering web pages, it can't be resized, rotated,
+ * transformed and animated due to the limitations of SurfaceView. Besides, XWalkView won't
+ * be rendered if it's invisible.</p>
  *
- * It provides 2 major callback classes, namely XWalkResourceClient and XWalkUIClient for
- * listening to the events related resource loading and UI. By default, Crosswalk has an inner
- * implementation. Callers can override them if like.
+ * <p>XWalkView needs hardware acceleration to render web pages. As a result, the
+ * AndroidManifest.xml of the caller's app must be appended with the attribute
+ * "android:hardwareAccelerated" and its value must be set as "true".</p>
+ * <pre>
+ * &lt;application android:name="android.app.Application" android:label="XWalkUsers"
+ *     android:hardwareAccelerated="true"&gt;
+ * </pre>
  *
- * Unlike other Android views, this class has to listen to system events like application life
- * cycle, intents, and activity result. The web engine inside this view need to handle them.
+ * <p>Crosswalk provides 2 major callback classes, namely {@link XWalkResourceClient} and
+ * {@link XWalkUIClient} for listening to the events related to resource loading and UI.
+ * By default, Crosswalk has a default implementation. Callers can override them if needed.</p>
  *
- * It already includes all newly created Web APIs from Crosswalk like Presentation,
- * DeviceCapabilities, etc..
+ * <p>Unlike other Android views, this class has to listen to system events like application life
+ * cycle, intents, and activity result. The web engine inside this view need to get and handle
+ * them. For example:</p>
+ *
+ * <pre>
+ *   import android.app.Activity;
+ *   import android.os.Bundle;
+ *
+ *   import org.xwalk.core.XWalkResourceClient;
+ *   import org.xwalk.core.XWalkUIClient;
+ *   import org.xwalk.core.XWalkView;
+ *
+ *   public class MyActivity extends Activity {
+ *       XWalkView mXwalkView;
+ *
+ *       class MyResourceClient extends XWalkResourceClient {
+ *           MyResourceClient(XWalkView view) {
+ *               super(view);
+ *           }
+ *
+ *           &#64;Override
+ *           WebResourceResponse shouldInterceptLoadRequest(XWalkView view, String url) {
+ *               // Handle it here.
+ *               ...
+ *           }
+ *       }
+ *
+ *       class MyUIClient extends XWalkUIClient {
+ *           MyUIClient(XWalkView view) {
+ *               super(view);
+ *           }
+ *
+ *           &#64;Override
+ *           void onFullscreenToggled(XWalkView view, String url) {
+ *               // Handle it here.
+ *               ...
+ *           }
+ *       }
+ *
+ *       &#64;Override
+ *       protected void onCreate(Bundle savedInstanceState) {
+ *           mXwalkView = new XWalkView(this, null);
+ *           setContentView(mXwalkView);
+ *           mXwalkView.setResourceClient(new MyResourceClient(mXwalkView));
+ *           mXwalkView.setUIClient(new MyUIClient(mXwalkView));
+ *           mXwalkView.load("http://www.crosswalk-project.org", null);
+ *       }
+ *
+ *       &#64;Override
+ *       protected void onPause() {
+ *           super.onPause();
+ *           if (mXwalkView != null) {
+ *               mXwalkView.pauseTimers();
+ *               mXwalkView.onHide();
+ *           }
+ *       }
+ *
+ *       &#64;Override
+ *       protected void onResume() {
+ *           super.onResume();
+ *           if (mXwalkView != null) {
+ *               mXwalkView.resumeTimers();
+ *               mXwalkView.onShow();
+ *           }
+ *       }
+ *
+ *       &#64;Override
+ *       protected void onDestroy() {
+ *           super.onDestroy();
+ *           if (mXwalkView != null) {
+ *               mXwalkView.onDestroy();
+ *           }
+ *       }
+ *
+ *       &#64;Override
+ *       protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ *           if (mXwalkView != null) {
+ *               mXwalkView.onActivityResult(requestCode, resultCode, data);
+ *           }
+ *       }
+ *
+ *       &#64;Override
+ *       protected void onNewIntent(Intent intent) {
+ *           if (mXwalkView != null) {
+ *               mXwalkView.onNewIntent(intent);
+ *           }
+ *       }
+ *   }
+ * </pre>
  */
 public class XWalkView extends android.widget.FrameLayout {
 
-    protected static final String PLAYSTORE_DETAIL_URI = "market://details?id=";
+    static final String PLAYSTORE_DETAIL_URI = "market://details?id=";
 
     private XWalkContent mContent;
     private Activity mActivity;
     private Context mContext;
     private XWalkExtensionManager mExtensionManager;
-    private boolean mIsTimerPaused;
     private boolean mIsHidden;
 
     /** Normal reload mode as default. */
@@ -188,7 +280,6 @@ public class XWalkView extends android.widget.FrameLayout {
     }
 
     private void initXWalkContent(Context context, AttributeSet attrs) {
-        mIsTimerPaused = false;
         mIsHidden = false;
         mContent = new XWalkContent(context, attrs, this);
         addView(mContent,
@@ -382,10 +473,9 @@ public class XWalkView extends android.widget.FrameLayout {
      * just this XWalkView.
      */
     public void pauseTimers() {
-        if (mContent == null || mIsTimerPaused) return;
+        if (mContent == null) return;
         checkThreadSafety();
         mContent.pauseTimers();
-        mIsTimerPaused = true;
     }
 
     /**
@@ -396,10 +486,9 @@ public class XWalkView extends android.widget.FrameLayout {
      * just this XWalkView.
      */
     public void resumeTimers() {
-        if (mContent == null || !mIsTimerPaused) return;
+        if (mContent == null) return;
         checkThreadSafety();
         mContent.resumeTimers();
-        mIsTimerPaused = false;
     }
 
     /**
@@ -437,7 +526,8 @@ public class XWalkView extends android.widget.FrameLayout {
     /**
      * Pass through activity result to XWalkView. Many internal facilities need this
      * to handle activity result like JavaScript dialog, Crosswalk extensions, etc.
-     * See android.app.Activity.onActivityResult().
+     * See <a href="http://developer.android.com/reference/android/app/Activity.html">
+     * android.app.Activity.onActivityResult()</a>.
      * @param requestCode passed from android.app.Activity.onActivityResult().
      * @param resultCode passed from android.app.Activity.onActivityResult().
      * @param data passed from android.app.Activity.onActivityResult().
@@ -451,7 +541,8 @@ public class XWalkView extends android.widget.FrameLayout {
     /**
      * Pass through intents to XWalkView. Many internal facilities need this
      * to receive the intents like web notification. See
-     * android.app.Activity.onNewIntent().
+     * <a href="http://developer.android.com/reference/android/app/Activity.html">
+     * android.app.Activity.onNewIntent()</a>.
      * @param intent passed from android.app.Activity.onNewIntent().
      */
     public boolean onNewIntent(Intent intent) {
@@ -523,7 +614,8 @@ public class XWalkView extends android.widget.FrameLayout {
     }
 
     /**
-     * Inherit from android.view.View. This class needs to handle some keys like
+     * Inherit from <a href="http://developer.android.com/reference/android/view/View.html">
+     * android.view.View</a>. This class needs to handle some keys like
      * 'BACK'.
      * @param keyCode passed from android.view.View.onKeyUp().
      * @param event passed from android.view.View.onKeyUp().
index 65dc66e..9e21600 100644 (file)
@@ -98,10 +98,7 @@ public class PresentationExtension extends XWalkExtension {
                 notifyAvailabilityChanged(false);
                 // Destroy the presentation content if there is no available secondary display
                 // any more.
-                if (mPresentationContent != null) {
-                    mPresentationContent.close();
-                    mPresentationContent = null;
-                }
+                closePresentationContent();
             }
         }
 
@@ -276,8 +273,7 @@ public class PresentationExtension extends XWalkExtension {
                     @Override
                     public void onContentClosed(XWalkPresentationContent content) {
                         if (content == mPresentationContent) {
-                            mPresentationContent.close();
-                            mPresentationContent = null;
+                            closePresentationContent();
                             if (mPresentationView != null) mPresentationView.cancel();
                         }
                     }
@@ -312,10 +308,7 @@ public class PresentationExtension extends XWalkExtension {
         if (displays.length == 0 && mAvailableDisplayCount > 0) {
             notifyAvailabilityChanged(false);
             mAvailableDisplayCount = 0;
-            if (mPresentationContent != null) {
-                mPresentationContent.close();
-                mPresentationContent = null;
-            }
+            closePresentationContent();
         }
 
         // If there was no available display but right now there is at least one available
@@ -356,8 +349,7 @@ public class PresentationExtension extends XWalkExtension {
         // If the presentation view is showed on another display, we need to dismiss it
         // and re-create a new one.
         if (mPresentationView != null && mPresentationView.getDisplay() != preferredDisplay) {
-            mPresentationView.dismiss();
-            mPresentationView = null;
+            dismissPresentationView();
         }
 
         // If the presentation view is not NULL and its associated display is not changed,
@@ -398,10 +390,7 @@ public class PresentationExtension extends XWalkExtension {
 
     @Override
     public void onPause() {
-        if (mPresentationView != null) {
-            mPresentationView.dismiss();
-            mPresentationView = null;
-        }
+        dismissPresentationView();
 
         if (mPresentationContent != null) mPresentationContent.onPause();
 
@@ -411,5 +400,21 @@ public class PresentationExtension extends XWalkExtension {
 
     @Override
     public void onDestroy() {
+        // close the presentation content if have.
+        closePresentationContent();
+    }
+
+    private void dismissPresentationView() {
+        if (mPresentationView == null) return;
+
+        mPresentationView.dismiss();
+        mPresentationView = null;
+    }
+
+    private void closePresentationContent() {
+        if (mPresentationContent == null) return;
+
+        mPresentationContent.close();
+        mPresentationContent = null;
     }
 }
index afd955b..04c620c 100644 (file)
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
+        <activity
+            android:name=".XWalkVersionAndAPIVersion"
+            android:label="Versions"
+            android:parentActivityName=".XWalkEmbeddedAPISample" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
     </application>
 
-</manifest>
\ No newline at end of file
+</manifest>
index 5c49c6b..2fb163a 100644 (file)
@@ -1,6 +1,5 @@
 <html>
     <body>
         Hello World.
-        <script>alert('Hello World!')</script>
     </body>
 </html>
index 27c55f0..e80db7c 100644 (file)
             android:src="@android:drawable/ic_media_next" />
     </LinearLayout>
 
+    <LinearLayout
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <TextView
+            android:id="@+id/text1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="#FDF5E6" />
+
+        <TextView
+            android:id="@+id/text2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="#FDF5E6" />
+
+        <TextView
+            android:id="@+id/text3"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="#FDF5E6" />
+    </LinearLayout>
+
     <org.xwalk.core.XWalkView
         android:id="@+id/xwalkview"
         android:layout_width="match_parent"
diff --git a/src/xwalk/runtime/android/sample/res/layout/version_layout.xml b/src/xwalk/runtime/android/sample/res/layout/version_layout.xml
new file mode 100644 (file)
index 0000000..8051d09
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (c) 2014 Intel Corporation. All rights reserved.
+
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <LinearLayout
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <TextView
+            android:id="@+id/text1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="#FDF5E6" />
+    </LinearLayout>
+
+    <org.xwalk.core.XWalkView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/xwalkview"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" >
+    </org.xwalk.core.XWalkView>
+
+</LinearLayout>
index 8effcd9..b2746ea 100644 (file)
@@ -6,19 +6,18 @@ package org.xwalk.core.sample;
 
 import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.os.Bundle;
 
-public class LoadAppFromManifestActivity extends Activity {
+public class LoadAppFromManifestActivity extends XWalkBaseActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.xwview_layout);
-        XWalkView xwalkView = (XWalkView) findViewById(R.id.xwalkview);
+        mXWalkView = (XWalkView) findViewById(R.id.xwalkview);
 
         // The manifest definition, please refer to the link:
         // https://crosswalk-project.org/#wiki/Crosswalk-manifest 
-        xwalkView.loadAppFromManifest("file:///android_asset/manifest.json", null);
+        mXWalkView.loadAppFromManifest("file:///android_asset/manifest.json", null);
     }
 }
index 09b4545..3b0e12e 100644 (file)
@@ -6,11 +6,12 @@ package org.xwalk.core.sample;
 
 import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.os.Bundle;
 import android.widget.LinearLayout;
 
-public class MultiXWalkViewActivity extends Activity {
+public class MultiXWalkViewActivity extends XWalkBaseActivity {
+
+    private XWalkView mXWalkView2;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -24,13 +25,39 @@ public class MultiXWalkViewActivity extends Activity {
                 LinearLayout.LayoutParams.MATCH_PARENT);
         params.weight = 1;
 
-        XWalkView view1 = new XWalkView(this, this);
-        parent.addView(view1, params);
+        mXWalkView = new XWalkView(this, this);
+        parent.addView(mXWalkView, params);
+
+        mXWalkView2 = new XWalkView(this, this);
+        parent.addView(mXWalkView2, params);
+
+        mXWalkView.load("http://www.intel.com", null);
+        mXWalkView2.load("http://www.baidu.com", null);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        if (mXWalkView2 != null) {
+            mXWalkView2.onHide();
+            mXWalkView2.pauseTimers();
+        }
+    }
 
-        XWalkView view2 = new XWalkView(this, this);
-        parent.addView(view2, params);
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (mXWalkView2 != null) {
+            mXWalkView2.onShow();
+            mXWalkView2.resumeTimers();
+        }
+    }
 
-        view1.load("http://www.intel.com", null);
-        view2.load("http://www.baidu.com", null);
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mXWalkView2 != null) {
+            mXWalkView2.onDestroy();
+        }
     }
 }
index 99f503f..fb7667b 100644 (file)
@@ -6,12 +6,9 @@ package org.xwalk.core.sample;
 
 import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.os.Bundle;
 
-public class OnHideOnShowActivity extends Activity {
-
-    private XWalkView mXWalkView;
+public class OnHideOnShowActivity extends XWalkBaseActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -19,20 +16,8 @@ public class OnHideOnShowActivity extends Activity {
         setContentView(R.layout.xwview_layout);
         mXWalkView = (XWalkView) findViewById(R.id.xwalkview);
 
+        // The web page below will display a video.
+        // When home button is pressed, the activity will be in background, and the video will be paused.
         mXWalkView.load("http://www.w3.org/2010/05/video/mediaevents.html", null);
     }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        // It will pause the video, when the app in background.
-        mXWalkView.onHide();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        // Need to call onShow() when onHide() was called.
-        mXWalkView.onShow();
-    }
 }
index d93bb41..e639eb9 100644 (file)
@@ -6,17 +6,15 @@ package org.xwalk.core.sample;
 
 import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.os.Bundle;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.ImageButton;
 
-public class PauseTimersActivity extends Activity {
+public class PauseTimersActivity extends XWalkBaseActivity {
 
     private ImageButton mButton;
     private boolean isPaused;
-    XWalkView mXWalkView;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
index 3a443c0..52f9a41 100644 (file)
@@ -9,20 +9,19 @@ import org.xwalk.core.XWalkResourceClient;
 import org.xwalk.core.XWalkUIClient;
 import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
 import android.webkit.ValueCallback;
 import android.webkit.WebResourceResponse;
 
-public class ResourceAndUIClientsActivity extends Activity {
+public class ResourceAndUIClientsActivity extends XWalkBaseActivity {
 
     private static final String TAG = ResourceAndUIClientsActivity.class.getName();
 
-    class ResourceCLient extends XWalkResourceClient {
+    class ResourceClient extends XWalkResourceClient {
 
-        public ResourceCLient(XWalkView xwalkView) {
+        public ResourceClient(XWalkView xwalkView) {
             super(xwalkView);
         }
 
@@ -96,9 +95,9 @@ public class ResourceAndUIClientsActivity extends Activity {
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.xwview_layout);
-        XWalkView xwalkView = (XWalkView) findViewById(R.id.xwalkview);
-        xwalkView.setResourceClient(new ResourceCLient(xwalkView));
-        xwalkView.setUIClient(new UIClient(xwalkView));
-        xwalkView.load("http://www.baidu.com", null);
+        mXWalkView = (XWalkView) findViewById(R.id.xwalkview);
+        mXWalkView.setResourceClient(new ResourceClient(mXWalkView));
+        mXWalkView.setUIClient(new UIClient(mXWalkView));
+        mXWalkView.load("http://www.baidu.com", null);
     }
 }
diff --git a/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkBaseActivity.java b/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkBaseActivity.java
new file mode 100644 (file)
index 0000000..6803f6b
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.xwalk.core.sample;
+
+import org.xwalk.core.XWalkView;
+
+import android.app.Activity;
+
+public class XWalkBaseActivity extends Activity {
+    protected XWalkView mXWalkView;
+
+    /*
+     * When the activity is paused, XWalkView.onHide() and XWalkView.pauseTimers() need to be called.
+     */
+    @Override
+    public void onPause() {
+        super.onPause();
+        if (mXWalkView != null) {
+            mXWalkView.onHide();
+            mXWalkView.pauseTimers();
+        }
+    }
+
+    /*
+     * When the activity is resumed, XWalkView.onShow() and XWalkView.resumeTimers() need to be called.
+     */
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (mXWalkView != null) {
+            mXWalkView.onShow();
+            mXWalkView.resumeTimers();
+        }
+    }
+
+    /*
+     * Call onDestroy on XWalkView to release native resources when the activity is destroyed.
+     */
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mXWalkView != null) {
+            mXWalkView.onDestroy();
+        }
+    }
+}
index a4d37dc..ec3b50c 100644 (file)
@@ -4,20 +4,23 @@
 
 package org.xwalk.core.sample;
 
-import org.xwalk.core.XWalkView;
 import org.xwalk.core.XWalkNavigationHistory;
+import org.xwalk.core.XWalkNavigationItem;
+import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.os.Bundle;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.ImageButton;
+import android.widget.TextView;
 
-public class XWalkNavigationActivity extends Activity {
+public class XWalkNavigationActivity extends XWalkBaseActivity {
 
     private ImageButton mNextButton;
     private ImageButton mPrevButton;
-    private XWalkView mXWalkView;
+
+    String url, originalUrl, title;
+    TextView text1, text2, text3;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -27,6 +30,10 @@ public class XWalkNavigationActivity extends Activity {
         mNextButton = (ImageButton) findViewById(R.id.next);
         mXWalkView = (XWalkView) findViewById(R.id.xwalkview);
 
+        text1 = (TextView) super.findViewById(R.id.text1);
+        text2 = (TextView) super.findViewById(R.id.text2);
+        text3 = (TextView) super.findViewById(R.id.text3);
+
         mPrevButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -36,6 +43,8 @@ public class XWalkNavigationActivity extends Activity {
                     mXWalkView.getNavigationHistory().navigate(
                             XWalkNavigationHistory.Direction.BACKWARD, 1);
                 }
+                XWalkNavigationItem navigationItem = mXWalkView.getNavigationHistory().getCurrentItem();
+                showNavigationItemInfo(navigationItem);
             }
         });
 
@@ -48,9 +57,21 @@ public class XWalkNavigationActivity extends Activity {
                     mXWalkView.getNavigationHistory().navigate(
                             XWalkNavigationHistory.Direction.FORWARD, 1);
                 }
+                XWalkNavigationItem navigationItem = mXWalkView.getNavigationHistory().getCurrentItem();
+                showNavigationItemInfo(navigationItem);
             }
         });
 
         mXWalkView.load("http://www.baidu.com/", null);
     }
+
+    private void showNavigationItemInfo(XWalkNavigationItem navigationItem){
+        url = navigationItem.getUrl();
+        originalUrl = navigationItem.getOriginalUrl();
+        title = navigationItem.getTitle();
+
+        text1.setText(title);
+        text2.setText(url);
+        text3.setText(originalUrl);
+    }
 }
index 96da1dd..67c197a 100644 (file)
@@ -7,21 +7,20 @@ package org.xwalk.core.sample;
 import org.xwalk.core.XWalkPreferences;
 import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.os.Bundle;
 
-public class XWalkPreferencesActivity extends Activity {
+public class XWalkPreferencesActivity extends XWalkBaseActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.xwview_layout);
-        XWalkView xwalkView = (XWalkView) findViewById(R.id.xwalkview);
+        mXWalkView = (XWalkView) findViewById(R.id.xwalkview);
 
         // Enable remote debugging.
         // You can debug the web content via PC chrome.
         XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
 
-        xwalkView.load("http://www.baidu.com/", null);
+        mXWalkView.load("http://www.baidu.com/", null);
     }
 }
diff --git a/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkVersionAndAPIVersion.java b/src/xwalk/runtime/android/sample/src/org/xwalk/core/sample/XWalkVersionAndAPIVersion.java
new file mode 100644 (file)
index 0000000..1993403
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.xwalk.core.sample;
+
+import org.xwalk.core.XWalkView;
+
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class XWalkVersionAndAPIVersion extends XWalkBaseActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.version_layout);
+        mXWalkView = (XWalkView) findViewById(R.id.xwalkview);
+        String apiVersion = mXWalkView.getAPIVersion();
+        String xwalkVersion = mXWalkView.getXWalkVersion();
+        TextView text1 = (TextView) super.findViewById(R.id.text1);
+        text1.setText("API Version: " + apiVersion + "; XWalk Version: " + xwalkVersion);
+        mXWalkView.load("", "");
+    }
+}
index e9739d8..b575391 100644 (file)
@@ -6,16 +6,15 @@ package org.xwalk.core.sample;
 
 import org.xwalk.core.XWalkView;
 
-import android.app.Activity;
 import android.os.Bundle;
 
-public class XWalkViewWithLayoutActivity extends Activity {
+public class XWalkViewWithLayoutActivity extends XWalkBaseActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.xwview_layout);
-        XWalkView xwalkView = (XWalkView) findViewById(R.id.xwalkview);
-        xwalkView.load("http://www.baidu.com/", null);
+        mXWalkView = (XWalkView) findViewById(R.id.xwalkview);
+        mXWalkView.load("http://www.baidu.com/", null);
     }
 }
index 13f266f..d59189b 100644 (file)
 #include "xwalk/runtime/common/xwalk_paths.h"
 #include "xwalk/runtime/renderer/xwalk_content_renderer_client.h"
 
+#if !defined(DISABLE_NACL) && defined(OS_LINUX)
+#include "components/nacl/common/nacl_paths.h"
+#include "components/nacl/zygote/nacl_fork_delegate_linux.h"
+#endif
+
 #if defined(OS_TIZEN)
 #include "xwalk/runtime/renderer/tizen/xwalk_content_renderer_client_tizen.h"
 #endif
@@ -47,6 +52,11 @@ bool XWalkMainDelegate::BasicStartupComplete(int* exit_code) {
   if (process_type.empty())
     SetTaskbarGroupIdForProcess();
 #endif
+
+#if !defined(DISABLE_NACL) && defined(OS_LINUX)
+  nacl::RegisterPathProvider();
+#endif
+
   return false;
 }
 
@@ -63,6 +73,17 @@ int XWalkMainDelegate::RunProcess(const std::string& process_type,
   return -1;
 }
 
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+content::ZygoteForkDelegate* XWalkMainDelegate::ZygoteStarting() {
+#if defined(DISABLE_NACL)
+  return NULL;
+#else
+  return new NaClForkDelegate();
+#endif
+}
+
+#endif  // defined(OS_POSIX) && !defined(OS_ANDROID)
+
 // static
 void XWalkMainDelegate::InitializeResourceBundle() {
   base::FilePath pak_file;
index 948489b..cec8a1b 100644 (file)
@@ -26,6 +26,9 @@ class XWalkMainDelegate : public content::ContentMainDelegate {
   virtual void PreSandboxStartup() OVERRIDE;
   virtual int RunProcess(const std::string& process_type,
       const content::MainFunctionParams& main_function_params) OVERRIDE;
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+  virtual content::ZygoteForkDelegate* ZygoteStarting();
+#endif
   virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE;
   virtual content::ContentRendererClient*
       CreateContentRendererClient() OVERRIDE;
diff --git a/src/xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.cc b/src/xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.cc
new file mode 100644 (file)
index 0000000..d87d508
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.h"
+
+#include "base/path_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
+#include "xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h"
+#include "xwalk/runtime/common/xwalk_paths.h"
+
+namespace {
+
+// Calls OnKeepaliveOnUIThread on UI thread.
+void OnKeepalive(
+    const content::BrowserPpapiHost::OnKeepaliveInstanceData& instance_data,
+    const base::FilePath& profile_data_directory) {
+  DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+}
+
+}  // namespace
+
+NaClBrowserDelegateImpl::NaClBrowserDelegateImpl() {
+}
+
+NaClBrowserDelegateImpl::~NaClBrowserDelegateImpl() {
+}
+
+void NaClBrowserDelegateImpl::ShowMissingArchInfobar(int render_process_id,
+                                                     int render_view_id) {
+}
+
+bool NaClBrowserDelegateImpl::DialogsAreSuppressed() {
+  return true;
+}
+
+bool NaClBrowserDelegateImpl::GetCacheDirectory(base::FilePath* cache_dir) {
+  return PathService::Get(xwalk::DIR_DATA_PATH, cache_dir);
+}
+
+bool NaClBrowserDelegateImpl::GetPluginDirectory(base::FilePath* plugin_dir) {
+  return PathService::Get(xwalk::DIR_INTERNAL_PLUGINS, plugin_dir);
+}
+
+bool NaClBrowserDelegateImpl::GetPnaclDirectory(base::FilePath* pnacl_dir) {
+  return PathService::Get(xwalk::DIR_PNACL_COMPONENT, pnacl_dir);
+}
+
+bool NaClBrowserDelegateImpl::GetUserDirectory(base::FilePath* user_dir) {
+  return PathService::Get(xwalk::DIR_DATA_PATH, user_dir);
+}
+
+std::string NaClBrowserDelegateImpl::GetVersionString() const {
+  return "Chrome/" CHROME_VERSION " Crosswalk/" XWALK_VERSION;
+}
+
+ppapi::host::HostFactory* NaClBrowserDelegateImpl::CreatePpapiHostFactory(
+    content::BrowserPpapiHost* ppapi_host) {
+  return new xwalk::XWalkBrowserPepperHostFactory(ppapi_host);
+}
+
+void NaClBrowserDelegateImpl::SetDebugPatterns(std::string debug_patterns) {
+}
+
+bool NaClBrowserDelegateImpl::URLMatchesDebugPatterns(
+    const GURL& manifest_url) {
+  return false;
+}
+
+// This function is security sensitive.  Be sure to check with a security
+// person before you modify it.
+bool NaClBrowserDelegateImpl::MapUrlToLocalFilePath(
+    const GURL& file_url, bool use_blocking_api, base::FilePath* file_path) {
+  return false;
+}
+
+content::BrowserPpapiHost::OnKeepaliveCallback
+NaClBrowserDelegateImpl::GetOnKeepaliveCallback() {
+  return base::Bind(&OnKeepalive);
+}
diff --git a/src/xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.h b/src/xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.h
new file mode 100644 (file)
index 0000000..c19af32
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_RUNTIME_BROWSER_NACL_HOST_NACL_BROWSER_DELEGATE_IMPL_H_
+#define XWALK_RUNTIME_BROWSER_NACL_HOST_NACL_BROWSER_DELEGATE_IMPL_H_
+
+#include <string>
+
+#include "components/nacl/browser/nacl_browser_delegate.h"
+
+class NaClBrowserDelegateImpl : public NaClBrowserDelegate {
+ public:
+  NaClBrowserDelegateImpl();
+  virtual ~NaClBrowserDelegateImpl();
+
+  virtual void ShowMissingArchInfobar(int render_process_id,
+                                      int render_view_id) OVERRIDE;
+  virtual bool DialogsAreSuppressed() OVERRIDE;
+  virtual bool GetCacheDirectory(base::FilePath* cache_dir) OVERRIDE;
+  virtual bool GetPluginDirectory(base::FilePath* plugin_dir) OVERRIDE;
+  virtual bool GetPnaclDirectory(base::FilePath* pnacl_dir) OVERRIDE;
+  virtual bool GetUserDirectory(base::FilePath* user_dir) OVERRIDE;
+  virtual std::string GetVersionString() const OVERRIDE;
+  virtual ppapi::host::HostFactory* CreatePpapiHostFactory(
+      content::BrowserPpapiHost* ppapi_host) OVERRIDE;
+  virtual bool MapUrlToLocalFilePath(const GURL& url,
+                                     bool is_blocking,
+                                     base::FilePath* file_path) OVERRIDE;
+  virtual void SetDebugPatterns(std::string debug_patterns) OVERRIDE;
+  virtual bool URLMatchesDebugPatterns(const GURL& manifest_url) OVERRIDE;
+  virtual content::BrowserPpapiHost::OnKeepaliveCallback
+      GetOnKeepaliveCallback() OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NaClBrowserDelegateImpl);
+};
+
+#endif  // XWALK_RUNTIME_BROWSER_NACL_HOST_NACL_BROWSER_DELEGATE_IMPL_H_
diff --git a/src/xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.cc b/src/xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.cc
new file mode 100644 (file)
index 0000000..456caee
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h"
+
+#include "content/public/browser/browser_ppapi_host.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/host/resource_host.h"
+
+using ppapi::host::ResourceHost;
+
+namespace xwalk {
+
+XWalkBrowserPepperHostFactory::XWalkBrowserPepperHostFactory(
+    content::BrowserPpapiHost* host)
+    : host_(host) {
+}
+
+XWalkBrowserPepperHostFactory::~XWalkBrowserPepperHostFactory() {
+}
+
+scoped_ptr<ResourceHost> XWalkBrowserPepperHostFactory::CreateResourceHost(
+    ppapi::host::PpapiHost* host,
+    const ppapi::proxy::ResourceMessageCallParams& params,
+    PP_Instance instance,
+    const IPC::Message& message) {
+  DCHECK(host == host_->GetPpapiHost());
+
+  return scoped_ptr<ResourceHost>();
+}
+
+}  // namespace xwalk
diff --git a/src/xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h b/src/xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h
new file mode 100644 (file)
index 0000000..282c670
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_RUNTIME_BROWSER_RENDERER_HOST_PEPPER_XWALK_BROWSER_PEPPER_HOST_FACTORY_H_
+#define XWALK_RUNTIME_BROWSER_RENDERER_HOST_PEPPER_XWALK_BROWSER_PEPPER_HOST_FACTORY_H_
+
+#include "ppapi/host/host_factory.h"
+
+namespace content {
+class BrowserPpapiHost;
+}  // namespace content
+
+namespace xwalk {
+
+class XWalkBrowserPepperHostFactory : public ppapi::host::HostFactory {
+ public:
+  // Non-owning pointer to the filter must outlive this class.
+  explicit XWalkBrowserPepperHostFactory(content::BrowserPpapiHost* host);
+  virtual ~XWalkBrowserPepperHostFactory();
+
+  virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost(
+      ppapi::host::PpapiHost* host,
+      const ppapi::proxy::ResourceMessageCallParams& params,
+      PP_Instance instance,
+      const IPC::Message& message) OVERRIDE;
+
+ private:
+  // Non-owning pointer.
+  content::BrowserPpapiHost* host_;
+
+  DISALLOW_COPY_AND_ASSIGN(XWalkBrowserPepperHostFactory);
+};
+
+}  // namespace xwalk
+
+#endif  // XWALK_RUNTIME_BROWSER_RENDERER_HOST_PEPPER_XWALK_BROWSER_PEPPER_HOST_FACTORY_H_
index 01cdfdb..718dd0e 100644 (file)
@@ -156,8 +156,8 @@ void Runtime::Close() {
   delete this;
 }
 
-NativeAppWindow* Runtime::window() const {
-  return window_;
+content::RenderProcessHost* Runtime::GetRenderProcessHost() {
+  return web_contents_->GetRenderProcessHost();
 }
 
 //////////////////////////////////////////////////////
index f1d31f0..5a7ae93 100644 (file)
@@ -23,6 +23,7 @@ namespace content {
 class ColorChooser;
 struct FileChooserParams;
 class WebContents;
+class RenderProcessHost;
 }
 
 namespace xwalk {
@@ -70,10 +71,12 @@ class Runtime : public content::WebContentsDelegate,
   void Close();
 
   content::WebContents* web_contents() const { return web_contents_.get(); }
-  NativeAppWindow* window() const;
+  NativeAppWindow* window() const { return window_; }
   RuntimeContext* runtime_context() const { return runtime_context_; }
   gfx::Image app_icon() const { return app_icon_; }
 
+  content::RenderProcessHost* GetRenderProcessHost();
+
 #if defined(OS_TIZEN_MOBILE)
   void CloseRootWindow();
 #endif
index f73f794..7509218 100644 (file)
@@ -15,6 +15,7 @@
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/threading/worker_pool.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/cookie_store_factory.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
 #include "net/cert/cert_verifier.h"
@@ -36,6 +37,7 @@
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_storage.h"
 #include "net/url_request/url_request_job_factory_impl.h"
+#include "xwalk/application/common/constants.h"
 #include "xwalk/runtime/browser/runtime_network_delegate.h"
 
 #if defined(OS_ANDROID)
@@ -90,7 +92,15 @@ net::URLRequestContext* RuntimeURLRequestContextGetter::GetURLRequestContext() {
 #if defined(OS_ANDROID)
     storage_->set_cookie_store(xwalk::GetCookieMonster());
 #else
-    storage_->set_cookie_store(new net::CookieMonster(NULL, NULL));
+    content::CookieStoreConfig cookie_config(base_path_.Append(
+        application::kCookieDatabaseFilename),
+        content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
+        NULL, NULL);
+    net::CookieStore* cookie_store = content::CreateCookieStore(cookie_config);
+    const char* schemes[] = {application::kApplicationScheme,
+                             content::kChromeDevToolsScheme};
+    cookie_store->GetCookieMonster()->SetCookieableSchemes(schemes, 2);
+    storage_->set_cookie_store(cookie_store);
 #endif
     storage_->set_server_bound_cert_service(new net::ServerBoundCertService(
         new net::DefaultServerBoundCertStore(NULL),
index b43b1b1..62ffc55 100644 (file)
 #include "base/files/file_path.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_number_conversions.h"
+#include "cc/base/switches.h"
+#include "components/nacl/browser/nacl_browser.h"
+#include "components/nacl/browser/nacl_process_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/main_function_params.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/common/result_codes.h"
+#include "extensions/browser/extension_system.h"
+#include "net/base/net_util.h"
+#include "ui/gl/gl_switches.h"
 #include "xwalk/application/browser/application.h"
 #include "xwalk/application/browser/application_system.h"
 #include "xwalk/extensions/browser/xwalk_extension_service.h"
 #include "xwalk/extensions/common/xwalk_extension_switches.h"
 #include "xwalk/runtime/browser/devtools/remote_debugging_server.h"
+#include "xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.h"
 #include "xwalk/runtime/browser/runtime.h"
 #include "xwalk/runtime/browser/runtime_context.h"
 #include "xwalk/runtime/browser/xwalk_runner.h"
 #include "xwalk/runtime/common/xwalk_runtime_features.h"
 #include "xwalk/runtime/common/xwalk_switches.h"
-#include "cc/base/switches.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/main_function_params.h"
-#include "content/public/common/url_constants.h"
-#include "content/public/common/result_codes.h"
-#include "net/base/net_util.h"
-#include "ui/gl/gl_switches.h"
 
 #if defined(USE_AURA) && defined(USE_X11)
 #include "ui/base/ime/input_method_initializer.h"
@@ -179,6 +184,16 @@ void XWalkBrowserMainParts::PreMainMessageLoopRun() {
   if (extension_service_)
     RegisterExternalExtensions();
 
+#if !defined(DISABLE_NACL)
+  NaClBrowserDelegateImpl* delegate = new NaClBrowserDelegateImpl();
+  nacl::NaClBrowser::SetDelegate(delegate);
+
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(nacl::NaClProcessHost::EarlyStartup));
+#endif
+
   CommandLine* command_line = CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kRemoteDebuggingPort)) {
     std::string port_str =
index 31da805..6da9b67 100644 (file)
 #include "base/command_line.h"
 #include "base/path_service.h"
 #include "base/platform_file.h"
+#include "content/public/browser/browser_child_process_host.h"
 #include "content/public/browser/browser_main_parts.h"
+#include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/child_process_data.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/resource_context.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/main_function_params.h"
 #include "content/public/common/show_desktop_notification_params.h"
+#include "components/nacl/browser/nacl_browser.h"
+#include "components/nacl/browser/nacl_host_message_filter.h"
+#include "components/nacl/browser/nacl_process_host.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "net/ssl/ssl_info.h"
 #include "net/url_request/url_request_context_getter.h"
+#include "ppapi/host/ppapi_host.h"
 #include "xwalk/extensions/common/xwalk_extension_switches.h"
 #include "xwalk/runtime/browser/xwalk_browser_main_parts.h"
 #include "xwalk/runtime/browser/geolocation/xwalk_access_token_store.h"
 #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h"
+#include "xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h"
 #include "xwalk/runtime/browser/runtime_context.h"
 #include "xwalk/runtime/browser/runtime_quota_permission_context.h"
 #include "xwalk/runtime/browser/speech/speech_recognition_manager_delegate.h"
 #include "xwalk/runtime/browser/xwalk_render_message_filter.h"
 #include "xwalk/runtime/browser/xwalk_runner.h"
+#include "xwalk/runtime/common/xwalk_paths.h"
 
 #if defined(OS_ANDROID)
 #include "base/android/path_utils.h"
@@ -55,6 +66,8 @@
 #include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"
 #endif
 
+using content::BrowserChildProcessHostIterator;
+
 namespace xwalk {
 
 namespace {
@@ -157,6 +170,18 @@ XWalkContentBrowserClient::GetWebContentsViewDelegate(
 
 void XWalkContentBrowserClient::RenderProcessWillLaunch(
     content::RenderProcessHost* host) {
+#if !defined(DISABLE_NACL)
+  int id = host->GetID();
+  net::URLRequestContextGetter* context =
+      host->GetStoragePartition()->GetURLRequestContext();
+
+  host->AddFilter(new nacl::NaClHostMessageFilter(
+      id,
+      // TODO(Halton): IsOffTheRecord?
+      false,
+      host->GetBrowserContext()->GetPath(),
+      context));
+#endif
   xwalk_runner_->OnRenderProcessWillLaunch(host);
   host->AddFilter(new XWalkRenderMessageFilter);
 }
@@ -281,6 +306,34 @@ void XWalkContentBrowserClient::CancelDesktopNotification(
 #endif
 }
 
+void XWalkContentBrowserClient::DidCreatePpapiPlugin(
+    content::BrowserPpapiHost* browser_host) {
+#if defined(ENABLE_PLUGINS)
+  browser_host->GetPpapiHost()->AddHostFactoryFilter(
+      scoped_ptr<ppapi::host::HostFactory>(
+          new XWalkBrowserPepperHostFactory(browser_host)));
+#endif
+}
+
+content::BrowserPpapiHost*
+    XWalkContentBrowserClient::GetExternalBrowserPpapiHost(
+        int plugin_process_id) {
+#if !defined(DISABLE_NACL)
+  BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_LOADER);
+  while (!iter.Done()) {
+    nacl::NaClProcessHost* host = static_cast<nacl::NaClProcessHost*>(
+        iter.GetDelegate());
+    if (host->process() &&
+        host->process()->GetData().id == plugin_process_id) {
+      // Found the plugin.
+      return host->browser_ppapi_host();
+    }
+    ++iter;
+  }
+#endif
+  return NULL;
+}
+
 #if defined(OS_ANDROID)
 void XWalkContentBrowserClient::ResourceDispatcherHostCreated() {
   RuntimeResourceDispatcherHostDelegateAndroid::
index 5618aee..033074b 100644 (file)
@@ -128,6 +128,11 @@ class XWalkContentBrowserClient : public content::ContentBrowserClient {
                                bool* no_javascript_access) OVERRIDE;
 #endif
 
+  virtual void DidCreatePpapiPlugin(
+      content::BrowserPpapiHost* browser_host) OVERRIDE;
+  virtual content::BrowserPpapiHost* GetExternalBrowserPpapiHost(
+      int plugin_process_id) OVERRIDE;
+
 #if defined(OS_ANDROID)
   virtual void ResourceDispatcherHostCreated();
 #endif
index 0756933..af0da03 100644 (file)
@@ -20,6 +20,7 @@ class XWalkRenderMessageFilter : public content::BrowserMessageFilter {
 #if defined(OS_TIZEN)
   void OnOpenLinkExternal(const GURL& url);
 #endif
+  virtual ~XWalkRenderMessageFilter() {}
 
   DISALLOW_COPY_AND_ASSIGN(XWalkRenderMessageFilter);
 };
index c2f000c..b196833 100644 (file)
@@ -5,13 +5,37 @@
 #include "xwalk/runtime/common/xwalk_content_client.h"
 
 #include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/nacl/common/nacl_process_type.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/user_agent.h"
+#include "content/public/common/pepper_plugin_info.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "xwalk/application/common/constants.h"
+#include "xwalk/runtime/common/xwalk_switches.h"
+#include "xwalk/runtime/common/xwalk_paths.h"
+
+const char* const xwalk::XWalkContentClient::kNaClPluginName = "Native Client";
+
+namespace {
+
+const char kNaClPluginMimeType[] = "application/x-nacl";
+const char kNaClPluginExtension[] = "";
+const char kNaClPluginDescription[] = "Native Client Executable";
+const uint32 kNaClPluginPermissions = ppapi::PERMISSION_PRIVATE |
+                                      ppapi::PERMISSION_DEV;
+
+const char kPnaclPluginMimeType[] = "application/x-pnacl";
+const char kPnaclPluginExtension[] = "";
+const char kPnaclPluginDescription[] = "Portable Native Client Executable";
+
+}  // namespace
 
 namespace xwalk {
 
@@ -35,6 +59,40 @@ XWalkContentClient::~XWalkContentClient() {
   xwalk::GetUserAgent();
 }
 
+void XWalkContentClient::AddPepperPlugins(
+    std::vector<content::PepperPluginInfo>* plugins) {
+  // Handle Native Client just like the PDF plugin. This means that it is
+  // enabled by default for the non-portable case.  This allows apps installed
+  // from the Chrome Web Store to use NaCl even if the command line switch
+  // isn't set.  For other uses of NaCl we check for the command line switch.
+  // Specifically, Portable Native Client is only enabled by the command line
+  // switch.
+  static bool skip_nacl_file_check = false;
+  base::FilePath path;
+  if (PathService::Get(xwalk::FILE_NACL_PLUGIN, &path)) {
+    if (skip_nacl_file_check || base::PathExists(path)) {
+      content::PepperPluginInfo nacl;
+      nacl.path = path;
+      nacl.name = XWalkContentClient::kNaClPluginName;
+      content::WebPluginMimeType nacl_mime_type(kNaClPluginMimeType,
+                                                kNaClPluginExtension,
+                                                kNaClPluginDescription);
+      nacl.mime_types.push_back(nacl_mime_type);
+      if (!CommandLine::ForCurrentProcess()->HasSwitch(
+              switches::kDisablePnacl)) {
+        content::WebPluginMimeType pnacl_mime_type(kPnaclPluginMimeType,
+                                                   kPnaclPluginExtension,
+                                                   kPnaclPluginDescription);
+        nacl.mime_types.push_back(pnacl_mime_type);
+      }
+      nacl.permissions = kNaClPluginPermissions;
+      plugins->push_back(nacl);
+
+      skip_nacl_file_check = true;
+    }
+  }
+}
+
 std::string XWalkContentClient::GetProduct() const {
   return std::string("Version/4.0");
 }
@@ -70,4 +128,16 @@ void XWalkContentClient::AddAdditionalSchemes(
   savable_schemes->push_back(application::kApplicationScheme);
 }
 
+std::string XWalkContentClient::GetProcessTypeNameInEnglish(int type) {
+  switch (type) {
+    case PROCESS_TYPE_NACL_LOADER:
+      return "Native Client module";
+    case PROCESS_TYPE_NACL_BROKER:
+      return "Native Client broker";
+  }
+
+  DCHECK(false) << "Unknown child process type!";
+  return "Unknown";
+}
+
 }  // namespace xwalk
index dc014b5..a522625 100644 (file)
@@ -20,6 +20,10 @@ class XWalkContentClient : public content::ContentClient {
   XWalkContentClient();
   virtual ~XWalkContentClient();
 
+  static const char* const kNaClPluginName;
+
+  virtual void AddPepperPlugins(
+      std::vector<content::PepperPluginInfo>* plugins) OVERRIDE;
   virtual std::string GetProduct() const OVERRIDE;
   virtual std::string GetUserAgent() const OVERRIDE;
   virtual base::string16 GetLocalizedString(int message_id) const OVERRIDE;
@@ -32,6 +36,7 @@ class XWalkContentClient : public content::ContentClient {
   virtual void AddAdditionalSchemes(
       std::vector<std::string>* standard_schemes,
       std::vector<std::string>* saveable_shemes) OVERRIDE;
+  virtual std::string GetProcessTypeNameInEnglish(int type) OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(XWalkContentClient);
index 0727328..5a6147a 100644 (file)
 #elif defined(OS_LINUX)
 #include "base/environment.h"
 #include "base/nix/xdg_util.h"
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+#import "base/mac/mac_util.h"
 #endif
 
 namespace xwalk {
 
 namespace {
 
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+
+base::FilePath GetVersionedDirectory() {
+  // Start out with the path to the running executable.
+  base::FilePath path;
+  PathService::Get(base::FILE_EXE, &path);
+
+  // One step up to MacOS, another to Contents.
+  path = path.DirName().DirName();
+  DCHECK_EQ(path.BaseName().value(), "Contents");
+
+  if (base::mac::IsBackgroundOnlyProcess()) {
+    // path identifies the helper .app's Contents directory in the browser
+    // .app's versioned directory.  Go up two steps to get to the browser
+    // .app's versioned directory.
+    path = path.DirName().DirName();
+  }
+
+  return path;
+}
+
+base::FilePath GetFrameworkBundlePath() {
+  // It's tempting to use +[NSBundle bundleWithIdentifier:], but it's really
+  // slow (about 30ms on 10.5 and 10.6), despite Apple's documentation stating
+  // that it may be more efficient than +bundleForClass:.  +bundleForClass:
+  // itself takes 1-2ms.  Getting an NSBundle from a path, on the other hand,
+  // essentially takes no time at all, at least when the bundle has already
+  // been loaded as it will have been in this case.  The FilePath operations
+  // needed to compute the framework's path are also effectively free, so that
+  // is the approach that is used here.  NSBundle is also documented as being
+  // not thread-safe, and thread safety may be a concern here.
+
+  // The framework bundle is at a known path and name from the browser .app's
+  // versioned directory.
+  return GetVersionedDirectory().Append("XWalk");
+}
+#endif
+
+// File name of the internal NaCl plugin on different platforms.
+const base::FilePath::CharType kInternalNaClPluginFileName[] =
+#if defined(OS_WIN)
+    FILE_PATH_LITERAL("ppGoogleNaClPluginChrome.dll");
+#elif defined(OS_MACOSX)
+    // TODO(noelallen) Please verify this extention name is correct.
+    FILE_PATH_LITERAL("ppGoogleNaClPluginChrome.plugin");
+#else  // Linux and Chrome OS
+    FILE_PATH_LITERAL("libppGoogleNaClPluginChrome.so");
+#endif
+
 #if defined(OS_LINUX)
 base::FilePath GetConfigPath() {
   scoped_ptr<base::Environment> env(base::Environment::Create());
@@ -64,6 +115,23 @@ bool GetXWalkDataPath(base::FilePath* path) {
   return true;
 }
 
+bool GetInternalPluginsDirectory(base::FilePath* result) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  // If called from Chrome, get internal plugins from a subdirectory of the
+  // framework.
+  if (base::mac::AmIBundled()) {
+    *result = xwalk::GetFrameworkBundlePath();
+    DCHECK(!result->empty());
+    *result = result->Append("Internet Plug-Ins");
+    return true;
+  }
+  // In tests, just look in the module directory (below).
+#endif
+
+  // The rest of the world expects plugins in the module directory.
+  return PathService::Get(base::DIR_MODULE, result);
+}
+
 }  // namespace
 
 bool PathProvider(int key, base::FilePath* path) {
@@ -71,6 +139,43 @@ bool PathProvider(int key, base::FilePath* path) {
   switch (key) {
     case xwalk::DIR_DATA_PATH:
       return GetXWalkDataPath(path);
+      break;
+    case xwalk::DIR_INTERNAL_PLUGINS:
+      if (!GetInternalPluginsDirectory(&cur))
+        return false;
+      break;
+    case xwalk::FILE_NACL_PLUGIN:
+      if (!GetInternalPluginsDirectory(&cur))
+        return false;
+      cur = cur.Append(kInternalNaClPluginFileName);
+      break;
+    // Where PNaCl files are ultimately located.  The default finds the files
+    // inside the InternalPluginsDirectory / build directory, as if it
+    // was shipped along with xwalk.  The value can be overridden
+    // if it is installed via component updater.
+    case xwalk::DIR_PNACL_COMPONENT:
+#if defined(OS_MACOSX)
+      // PNaCl really belongs in the InternalPluginsDirectory but actually
+      // copying it there would result in the files also being shipped, which
+      // we don't want yet. So for now, just find them in the directory where
+      // they get built.
+      if (!PathService::Get(base::DIR_EXE, &cur))
+        return false;
+      if (base::mac::AmIBundled()) {
+        // If we're called from xwalk, it's beside the app (outside the
+        // app bundle), if we're called from a unittest, we'll already be
+        // outside the bundle so use the exe dir.
+        // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
+        cur = cur.DirName();
+        cur = cur.DirName();
+        cur = cur.DirName();
+      }
+#else
+      if (!GetInternalPluginsDirectory(&cur))
+        return false;
+#endif
+      cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
+      break;
     case xwalk::DIR_TEST_DATA:
       if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
         return false;
@@ -95,4 +200,3 @@ void RegisterPathProvider() {
 }
 
 }  // namespace xwalk
-
index 88520cc..8f66a84 100644 (file)
@@ -14,6 +14,11 @@ enum {
   PATH_START = 1000,
   DIR_DATA_PATH = PATH_START,  // Directory where the cache and local storage
                                // data resides.
+  DIR_INTERNAL_PLUGINS,        // Directory where internal plugins reside.
+
+  FILE_NACL_PLUGIN,            // Full path to the internal NaCl plugin file.
+  DIR_PNACL_COMPONENT,         // Full path to the latest PNaCl version
+                               // (subdir of DIR_PNACL_BASE).
   DIR_TEST_DATA,               // Directory where unit test data resides.
   DIR_WGT_STORAGE_PATH,        // Directory where widget storage data resides.
   PATH_END
index f3e2ed8..5e9e8ea 100644 (file)
@@ -6,21 +6,26 @@
 
 namespace switches {
 
-// Specifies the data path directory, which XWalk runtime will look for its
-// state, e.g. cache, localStorage etc.
-const char kXWalkDataPath[] = "data-path";
-
 // Specifies the icon file for the app window.
 const char kAppIcon[] = "app-icon";
 
+// Disables the usage of Portable Native Client.
+const char kDisablePnacl[] = "disable-pnacl";
+
+// Enable all the experimental features in XWalk.
+const char kExperimentalFeatures[] = "enable-xwalk-experimental-features";
+
 // Specifies the window whether launched with fullscreen mode.
 const char kFullscreen[] = "fullscreen";
 
+// Specifies install an application.
+const char kInstall[] = "install";
+
 // Specifies list all installed applications.
 const char kListApplications[] = "list-apps";
 
-// Specifies install an application.
-const char kInstall[] = "install";
+// List the command lines feature flags.
+const char kListFeaturesFlags[] = "list-features-flags";
 
 // Specifies uninstall an application from runtime.
 const char kUninstall[] = "uninstall";
@@ -33,10 +38,8 @@ const char kXWalkAllowExternalExtensionsForRemoteSources[] =
 // issue these requests is platform-specific.
 const char kXWalkRunAsService[] = "run-as-service";
 
-// List the command lines feature flags.
-const char kListFeaturesFlags[] = "list-features-flags";
-
-// Enable all the experimental features in XWalk.
-const char kExperimentalFeatures[] = "enable-xwalk-experimental-features";
+// Specifies the data path directory, which XWalk runtime will look for its
+// state, e.g. cache, localStorage etc.
+const char kXWalkDataPath[] = "data-path";
 
 }  // namespace switches
index 1cc6777..98c8f23 100644 (file)
@@ -8,26 +8,18 @@
 // Defines all command line switches for XWalk.
 namespace switches {
 
-extern const char kXWalkDataPath[];
-
 extern const char kAppIcon[];
-
+extern const char kDisablePnacl[];
+extern const char kExperimentalFeatures[];
 extern const char kFullscreen[];
-
 extern const char kInstall[];
-
 extern const char kListApplications[];
-
+extern const char kListFeaturesFlags[];
 extern const char kUninstall[];
-
 extern const char kXWalkAllowExternalExtensionsForRemoteSources[];
-
+extern const char kXWalkDataPath[];
 extern const char kXWalkRunAsService[];
 
-extern const char kListFeaturesFlags[];
-
-extern const char kExperimentalFeatures[];
-
 }  // namespace switches
 
 #endif  // XWALK_RUNTIME_COMMON_XWALK_SWITCHES_H_
diff --git a/src/xwalk/runtime/renderer/pepper/pepper_helper.cc b/src/xwalk/runtime/renderer/pepper/pepper_helper.cc
new file mode 100644 (file)
index 0000000..451cfe8
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xwalk/runtime/renderer/pepper/pepper_helper.h"
+
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/host/ppapi_host.h"
+#include "xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.h"
+
+PepperHelper::PepperHelper(content::RenderFrame* render_frame)
+    : RenderFrameObserver(render_frame) {
+}
+
+PepperHelper::~PepperHelper() {
+}
+
+void PepperHelper::DidCreatePepperPlugin(content::RendererPpapiHost* host) {
+  host->GetPpapiHost()->AddHostFactoryFilter(
+      scoped_ptr<ppapi::host::HostFactory>(
+          new XWalkRendererPepperHostFactory(host)));
+}
diff --git a/src/xwalk/runtime/renderer/pepper/pepper_helper.h b/src/xwalk/runtime/renderer/pepper/pepper_helper.h
new file mode 100644 (file)
index 0000000..a422ae6
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_RUNTIME_RENDERER_PEPPER_PEPPER_HELPER_H_
+#define XWALK_RUNTIME_RENDERER_PEPPER_PEPPER_HELPER_H_
+
+#include "base/compiler_specific.h"
+#include "content/public/renderer/render_frame_observer.h"
+
+// This class listens for Pepper creation events from the RenderFrame and
+// attaches the parts required for Chrome-specific plugin support.
+class PepperHelper : public content::RenderFrameObserver {
+ public:
+  explicit PepperHelper(content::RenderFrame* render_frame);
+  virtual ~PepperHelper();
+
+  // RenderFrameObserver.
+  virtual void DidCreatePepperPlugin(content::RendererPpapiHost* host) OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PepperHelper);
+};
+
+#endif  // XWALK_RUNTIME_RENDERER_PEPPER_PEPPER_HELPER_H_
diff --git a/src/xwalk/runtime/renderer/pepper/pepper_uma_host.cc b/src/xwalk/runtime/renderer/pepper/pepper_uma_host.cc
new file mode 100644 (file)
index 0000000..b1aadf3
--- /dev/null
@@ -0,0 +1,115 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xwalk/runtime/renderer/pepper/pepper_uma_host.h"
+
+#include "base/metrics/histogram.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+PepperUMAHost::PepperUMAHost(
+    content::RendererPpapiHost* host,
+    PP_Instance instance,
+    PP_Resource resource)
+    : ResourceHost(host->GetPpapiHost(), instance, resource),
+      document_url_(host->GetDocumentURL(instance)),
+      is_plugin_in_process_(host->IsRunningInProcess()) {
+}
+
+PepperUMAHost::~PepperUMAHost() {
+}
+
+int32_t PepperUMAHost::OnResourceMessageReceived(
+    const IPC::Message& msg,
+    ppapi::host::HostMessageContext* context) {
+  IPC_BEGIN_MESSAGE_MAP(PepperUMAHost, msg)
+    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomTimes,
+        OnHistogramCustomTimes);
+    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomCounts,
+        OnHistogramCustomCounts);
+    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramEnumeration,
+        OnHistogramEnumeration);
+  IPC_END_MESSAGE_MAP()
+  return PP_ERROR_FAILED;
+}
+
+bool PepperUMAHost::IsHistogramAllowed(const std::string& histogram) {
+  return (is_plugin_in_process_ && histogram.find("NaCl.") == 0);
+}
+
+#define RETURN_IF_BAD_ARGS(_min, _max, _buckets) \
+  do { \
+    if (_min >= _max || _buckets <= 1) \
+      return PP_ERROR_BADARGUMENT; \
+  } while (0)
+
+int32_t PepperUMAHost::OnHistogramCustomTimes(
+    ppapi::host::HostMessageContext* context,
+    const std::string& name,
+    int64_t sample,
+    int64_t min,
+    int64_t max,
+    uint32_t bucket_count) {
+  if (!IsHistogramAllowed(name)) {
+    return PP_ERROR_NOACCESS;
+  }
+  RETURN_IF_BAD_ARGS(min, max, bucket_count);
+
+  base::HistogramBase* counter =
+      base::Histogram::FactoryTimeGet(
+          name,
+          base::TimeDelta::FromMilliseconds(min),
+          base::TimeDelta::FromMilliseconds(max),
+          bucket_count,
+          base::HistogramBase::kUmaTargetedHistogramFlag);
+  counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
+  return PP_OK;
+}
+
+int32_t PepperUMAHost::OnHistogramCustomCounts(
+    ppapi::host::HostMessageContext* context,
+    const std::string& name,
+    int32_t sample,
+    int32_t min,
+    int32_t max,
+    uint32_t bucket_count) {
+  if (!IsHistogramAllowed(name)) {
+    return PP_ERROR_NOACCESS;
+  }
+  RETURN_IF_BAD_ARGS(min, max, bucket_count);
+
+  base::HistogramBase* counter =
+      base::Histogram::FactoryGet(
+          name,
+          min,
+          max,
+          bucket_count,
+          base::HistogramBase::kUmaTargetedHistogramFlag);
+  counter->Add(sample);
+  return PP_OK;
+}
+
+int32_t PepperUMAHost::OnHistogramEnumeration(
+    ppapi::host::HostMessageContext* context,
+    const std::string& name,
+    int32_t sample,
+    int32_t boundary_value) {
+  if (!IsHistogramAllowed(name)) {
+    return PP_ERROR_NOACCESS;
+  }
+  RETURN_IF_BAD_ARGS(0, boundary_value, boundary_value + 1);
+
+  base::HistogramBase* counter =
+      base::LinearHistogram::FactoryGet(
+          name,
+          1,
+          boundary_value,
+          boundary_value + 1,
+          base::HistogramBase::kUmaTargetedHistogramFlag);
+  counter->Add(sample);
+  return PP_OK;
+}
diff --git a/src/xwalk/runtime/renderer/pepper/pepper_uma_host.h b/src/xwalk/runtime/renderer/pepper/pepper_uma_host.h
new file mode 100644 (file)
index 0000000..faa5c3e
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_RUNTIME_RENDERER_PEPPER_PEPPER_UMA_HOST_H_
+#define XWALK_RUNTIME_RENDERER_PEPPER_PEPPER_UMA_HOST_H_
+
+#include <set>
+#include <string>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/host/resource_host.h"
+#include "url/gurl.h"
+
+namespace content {
+class RendererPpapiHost;
+}
+
+namespace ppapi {
+namespace host {
+struct HostMessageContext;
+}  // namespace host
+}  // namespace ppapi
+
+class PepperUMAHost : public ppapi::host::ResourceHost {
+ public:
+  PepperUMAHost(content::RendererPpapiHost* host,
+                PP_Instance instance,
+                PP_Resource resource);
+
+  virtual ~PepperUMAHost();
+
+  // ppapi::host::ResourceMessageHandler implementation.
+  virtual int32_t OnResourceMessageReceived(
+      const IPC::Message& msg,
+      ppapi::host::HostMessageContext* context) OVERRIDE;
+
+ private:
+  bool IsHistogramAllowed(const std::string& histogram);
+
+  int32_t OnHistogramCustomTimes(
+      ppapi::host::HostMessageContext* context,
+      const std::string& name,
+      int64_t sample,
+      int64_t min,
+      int64_t max,
+      uint32_t bucket_count);
+
+  int32_t OnHistogramCustomCounts(
+      ppapi::host::HostMessageContext* context,
+      const std::string& name,
+      int32_t sample,
+      int32_t min,
+      int32_t max,
+      uint32_t bucket_count);
+
+  int32_t OnHistogramEnumeration(
+      ppapi::host::HostMessageContext* context,
+      const std::string& name,
+      int32_t sample,
+      int32_t boundary_value);
+
+  const GURL document_url_;
+  bool is_plugin_in_process_;
+
+  // Set of origins that can use UMA private APIs from NaCl.
+  std::set<std::string> allowed_origins_;
+  // Set of histograms that can be used from this interface.
+  std::set<std::string> allowed_histograms_;
+
+  DISALLOW_COPY_AND_ASSIGN(PepperUMAHost);
+};
+
+#endif  // XWALK_RUNTIME_RENDERER_PEPPER_PEPPER_UMA_HOST_H_
diff --git a/src/xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.cc b/src/xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.cc
new file mode 100644 (file)
index 0000000..2dcba87
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.h"
+
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "xwalk/runtime/renderer/pepper/pepper_uma_host.h"
+
+using ppapi::host::ResourceHost;
+
+XWalkRendererPepperHostFactory::XWalkRendererPepperHostFactory(
+    content::RendererPpapiHost* host)
+    : host_(host) {
+}
+
+XWalkRendererPepperHostFactory::~XWalkRendererPepperHostFactory() {
+}
+
+scoped_ptr<ResourceHost>
+XWalkRendererPepperHostFactory::CreateResourceHost(
+    ppapi::host::PpapiHost* host,
+    const ppapi::proxy::ResourceMessageCallParams& params,
+    PP_Instance instance,
+    const IPC::Message& message) {
+  DCHECK(host == host_->GetPpapiHost());
+
+  // Make sure the plugin is giving us a valid instance for this resource.
+  if (!host_->IsValidInstance(instance))
+    return scoped_ptr<ResourceHost>();
+
+  // Permissions for the following interfaces will be checked at the
+  // time of the corresponding instance's method calls.  Currently these
+  // interfaces are available only for whitelisted apps which may not have
+  // access to the other private interfaces.
+  if (message.type() == PpapiHostMsg_UMA_Create::ID) {
+    return scoped_ptr<ResourceHost>(new PepperUMAHost(
+        host_, instance, params.pp_resource()));
+  }
+
+  return scoped_ptr<ResourceHost>();
+}
diff --git a/src/xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.h b/src/xwalk/runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.h
new file mode 100644 (file)
index 0000000..2054394
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef XWALK_RUNTIME_RENDERER_PEPPER_XWALK_RENDERER_PEPPER_HOST_FACTORY_H_
+#define XWALK_RUNTIME_RENDERER_PEPPER_XWALK_RENDERER_PEPPER_HOST_FACTORY_H_
+
+#include "ppapi/host/host_factory.h"
+
+namespace content {
+class RendererPpapiHost;
+}
+
+class XWalkRendererPepperHostFactory : public ppapi::host::HostFactory {
+ public:
+  explicit XWalkRendererPepperHostFactory(content::RendererPpapiHost* host);
+  virtual ~XWalkRendererPepperHostFactory();
+
+  // HostFactory.
+  virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost(
+      ppapi::host::PpapiHost* host,
+      const ppapi::proxy::ResourceMessageCallParams& params,
+      PP_Instance instance,
+      const IPC::Message& message) OVERRIDE;
+
+ private:
+  // Not owned by this object.
+  content::RendererPpapiHost* host_;
+
+  DISALLOW_COPY_AND_ASSIGN(XWalkRendererPepperHostFactory);
+};
+
+#endif  // XWALK_RUNTIME_RENDERER_PEPPER_XWALK_RENDERER_PEPPER_HOST_FACTORY_H_
index 0f28aa3..158dfb1 100644 (file)
@@ -5,6 +5,7 @@
 #include "xwalk/runtime/renderer/xwalk_content_renderer_client.h"
 
 #include "base/strings/utf_string_conversions.h"
+#include "components/nacl/renderer/ppb_nacl_private_impl.h"
 #include "components/visitedlink/renderer/visitedlink_slave.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_frame_observer.h"
@@ -20,6 +21,7 @@
 #include "xwalk/application/renderer/application_native_module.h"
 #include "xwalk/extensions/renderer/xwalk_js_module.h"
 #include "xwalk/runtime/common/xwalk_localized_error.h"
+#include "xwalk/runtime/renderer/pepper/pepper_helper.h"
 
 #if defined(OS_ANDROID)
 #include "xwalk/runtime/renderer/android/xwalk_permission_client.h"
@@ -111,6 +113,10 @@ void XWalkContentRendererClient::RenderFrameCreated(
 #if defined(OS_ANDROID)
   new XWalkPermissionClient(render_frame);
 #endif
+
+#if defined(ENABLE_PLUGINS)
+  new PepperHelper(render_frame);
+#endif
 }
 
 void XWalkContentRendererClient::RenderViewCreated(
@@ -147,6 +153,23 @@ void XWalkContentRendererClient::DidCreateModuleSystem(
           IDR_XWALK_APPLICATION_WIDGET_COMMON_API));
 }
 
+const void* XWalkContentRendererClient::CreatePPAPIInterface(
+    const std::string& interface_name) {
+#if defined(ENABLE_PLUGINS) && !defined(DISABLE_NACL)
+  if (interface_name == PPB_NACL_PRIVATE_INTERFACE)
+    return nacl::GetNaClPrivateInterface();
+#endif
+  return NULL;
+}
+
+bool XWalkContentRendererClient::IsExternalPepperPlugin(
+    const std::string& module_name) {
+  // TODO(bbudge) remove this when the trusted NaCl plugin has been removed.
+  // We must defer certain plugin events for NaCl instances since we switch
+  // from the in-process to the out-of-process proxy after instantiating them.
+  return module_name == "Native Client";
+}
+
 #if defined(OS_ANDROID)
 unsigned long long XWalkContentRendererClient::VisitedLinkHash( // NOLINT
     const char* canonical_url, size_t length) {
@@ -180,8 +203,9 @@ bool XWalkContentRendererClient::WillSendRequest(blink::WebFrame* frame,
   if (xwalk_render_process_observer_->IsCSPMode()) {
     if (url.GetOrigin() != app_url.GetOrigin() &&
         origin_url != first_party_for_cookies &&
+        !first_party_for_cookies.is_empty() &&
         first_party_for_cookies.GetOrigin() != app_url.GetOrigin() &&
-        !frame->document().securityOrigin().canRequest(url)) {
+        !blink::WebSecurityOrigin::create(app_url).canRequest(url)) {
       LOG(INFO) << "[BLOCK] allow-navigation: " << url.spec();
       content::RenderThread::Get()->Send(new ViewMsg_OpenLinkExternal(url));
       *new_url = GURL();
index 609ff18..fc45966 100644 (file)
@@ -46,6 +46,9 @@ class XWalkContentRendererClient
   virtual void DidCreateScriptContext(
       blink::WebFrame* frame, v8::Handle<v8::Context> context,
       int extension_group, int world_id) OVERRIDE;
+  virtual bool IsExternalPepperPlugin(const std::string& module_name) OVERRIDE;
+  virtual const void* CreatePPAPIInterface(
+      const std::string& interface_name) OVERRIDE;
 #if defined(OS_ANDROID)
   virtual unsigned long long VisitedLinkHash(const char* canonical_url, // NOLINT
                                              size_t length) OVERRIDE;
@@ -71,7 +74,7 @@ class XWalkContentRendererClient
   scoped_ptr<visitedlink::VisitedLinkSlave> visited_link_slave_;
 #endif
 
-  void GetNavigationErrorStrings(
+  virtual void GetNavigationErrorStrings(
       content::RenderView* render_view,
       blink::WebFrame* frame,
       const blink::WebURLRequest& failed_request,
diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/AddJavascriptInterfaceTest.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/AddJavascriptInterfaceTest.java
new file mode 100644 (file)
index 0000000..40d5c23
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.xwalk.core.xwview.test;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.test.util.Feature;
+
+import org.xwalk.core.JavascriptInterface;
+
+/**
+ * Test suite for addJavascriptInterface().
+ */
+public class AddJavascriptInterfaceTest extends XWalkViewTestBase {
+    final String mExpectedStr = "xwalk";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setXWalkClient(new XWalkViewTestBase.TestXWalkClient());
+    }
+
+    class TestJavascriptInterface {
+        public String getTextWithoutAnnotation() {
+            return mExpectedStr;
+        }
+
+        @JavascriptInterface
+        public String getText() {
+            return mExpectedStr;
+        }
+    }
+
+    private void addJavascriptInterface() {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                getXWalkView().addJavascriptInterface(new TestJavascriptInterface(),
+                        "testInterface");
+            }
+        });
+    }
+
+    private void raisesExceptionAndSetTitle(String script) throws Throwable {
+        executeJavaScriptAndWaitForResult("try { var title = " +
+                                          script + ";" +
+                                          "  document.title = title;" +
+                                          "} catch (exception) {" +
+                                          "  document.title = \"xwalk\";" +
+                                          "}");
+    }
+
+    @SmallTest
+    @Feature({"AddJavascriptInterface"})
+    public void testAddJavascriptInterface() throws Throwable {
+        final String name = "add_js_interface.html";
+
+        addJavascriptInterface();
+        loadAssetFile(name);
+        assertEquals(mExpectedStr, getTitleOnUiThread());
+    }
+
+    @SmallTest
+    @Feature({"AddJavascriptInterface"})
+    public void testAddJavascriptInterfaceWithAnnotation() throws Throwable {
+        final String name = "index.html";
+        final String xwalkStr = "\"xwalk\"";
+        String result;
+
+        addJavascriptInterface();
+        loadAssetFile(name);
+
+        result = executeJavaScriptAndWaitForResult("testInterface.getText()");
+        assertEquals(xwalkStr, result);
+
+        raisesExceptionAndSetTitle("testInterface.getTextWithoutAnnotation()");
+
+        String title = getTitleOnUiThread();
+        assertEquals(mExpectedStr, title);
+    }
+}
diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/EvaluateJavascriptTest.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/EvaluateJavascriptTest.java
new file mode 100644 (file)
index 0000000..bd6abf0
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.xwalk.core.xwview.test;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.test.util.Feature;
+
+/**
+ * Test suite for evaluateJavascript().
+ */
+public class EvaluateJavascriptTest extends XWalkViewTestBase {
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setXWalkClient(new XWalkViewTestBase.TestXWalkClient());
+    }
+
+    @SmallTest
+    @Feature({"EvaluateJavascript"})
+    public void testEvaluateJavascript() throws Throwable {
+        final String expectedTitle = "xwalk";
+        final String name = "index.html";
+        final String code = "document.title=\"xwalk\"";
+
+        loadAssetFile(name);
+        executeJavaScriptAndWaitForResult(code);
+        assertEquals(expectedTitle, getTitleOnUiThread());
+    }
+}
diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/LoadTest.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/LoadTest.java
new file mode 100644 (file)
index 0000000..c3e32d8
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.xwalk.core.xwview.test;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.test.util.DisabledTest;
+import org.chromium.base.test.util.Feature;
+
+/**
+ * Test suite for load().
+ */
+public class LoadTest extends XWalkViewTestBase {
+    final String expectedTitle = "The WebKit Open Source Project";
+    final String expectedLocalTitle = "Crosswalk Sample Application";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setXWalkClient(new XWalkViewTestBase.TestXWalkClient());
+    }
+
+    // TODO(hengzhi): Since the device issue, it can not access the network,
+    // so disabled this test temporarily. It will be enabled later.
+    // @SmallTest
+    // @Feature({"Load"})
+    @DisabledTest
+    public void testHttpUrl() throws Throwable {
+        final String url = "http://www.webkit.org/";
+
+        loadUrlSync(url);
+        assertEquals(expectedTitle, getTitleOnUiThread());
+    }
+
+    // TODO(hengzhi): Since the device issue, it can not access the network,
+    // so disabled this test temporarily. It will be enabled later.
+    // @SmallTest
+    // @Feature({"Load"})
+    @DisabledTest
+    public void testHttpsUrl() throws Throwable {
+        final String url = "https://www.webkit.org/";
+
+        loadUrlSync(url);
+        assertEquals(expectedTitle, getTitleOnUiThread());
+    }
+
+    @SmallTest
+    @Feature({"Load"})
+    public void testAndroidAssetUrl() throws Throwable {
+        final String url = "file:///android_asset/www/index.html";
+
+        loadUrlSync(url);
+        assertEquals(expectedLocalTitle, getTitleOnUiThread());
+    }
+
+    @SmallTest
+    @Feature({"LoadWithData"})
+    public void testWithData() throws Throwable {
+        final String name = "index.html";
+        String fileContent = getFileContent(name);
+
+        loadDataSync(null, fileContent, "text/html", false);
+        assertEquals(expectedLocalTitle, getTitleOnUiThread());
+
+        loadDataSync(name, fileContent, "text/html", false);
+        assertEquals(expectedLocalTitle, getTitleOnUiThread());
+    }
+
+    @SmallTest
+    @Feature({"ContentScheme"})
+    public void testContentUrl() throws Throwable {
+        final String resource = "content_test";
+        final String contentUrl = TestContentProvider.createContentUrl(resource);
+
+        int count =
+                TestContentProvider.getResourceRequestCount(getActivity(), resource);
+        loadUrlSync(contentUrl);
+        assertEquals(count + 1,
+                TestContentProvider.getResourceRequestCount(getActivity(), resource));
+    }
+
+    @SmallTest
+    @Feature({"Load"})
+    public void testEmpytUrlAndContent() throws Throwable {
+        loadDataAsync(null, null, "text/html", false);
+        Thread.sleep(1000);
+        assertNotNull(getTitleOnUiThread());
+    }
+}
diff --git a/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/LoadUrlTest.java b/src/xwalk/test/android/core/javatests/src/org/xwalk/core/xwview/test/LoadUrlTest.java
deleted file mode 100644 (file)
index d26e82f..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.xwalk.core.xwview.test;
-
-import android.graphics.Bitmap;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-
-/**
- * Test suite for loadUrl().
- */
-public class LoadUrlTest extends XWalkViewTestBase {
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        setXWalkClient(new XWalkViewTestBase.TestXWalkClient());
-    }
-
-    // @SmallTest
-    // @Feature({"LoadUrl"})
-    // TODO(hengzhi): Since the device issue, it can not access the network,
-    // so disabled this test temporarily. It will be enabled later.
-    @DisabledTest
-    public void testNormalUrl() throws Throwable {
-        final String url = "http://www.webkit.org/";
-        final String expected_title = "The WebKit Open Source Project";
-        loadUrlSync(url);
-        assertEquals(expected_title, getTitleOnUiThread());
-    }
-
-    @SmallTest
-    @Feature({"LoadUrl"})
-    public void testLocalUrl() throws Throwable {
-        final String name = "index.html";
-        final String expected_title = "Crosswalk Sample Application";
-
-        loadAssetFile(name);
-        assertEquals(expected_title, getTitleOnUiThread());
-    }
-
-    @SmallTest
-    @Feature({"ContentScheme"})
-    public void testContentUrl() throws Throwable {
-        final String resource = "content_test";
-        final String content_url = TestContentProvider.createContentUrl(resource);
-
-        int count_before_load =
-                TestContentProvider.getResourceRequestCount(getActivity(), resource);
-        loadUrlSync(content_url);
-        assertEquals(count_before_load + 1,
-                TestContentProvider.getResourceRequestCount(getActivity(), resource));
-    } 
-}
index 8e1cfd6..5555902 100644 (file)
@@ -24,6 +24,7 @@ import org.chromium.content.browser.LoadUrlParams;
 import org.chromium.content.browser.test.util.CallbackHelper;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
+
 import org.xwalk.core.XWalkClient;
 import org.xwalk.core.XWalkNavigationHistory;
 import org.xwalk.core.XWalkResourceClient;
diff --git a/src/xwalk/test/android/data/add_js_interface.html b/src/xwalk/test/android/data/add_js_interface.html
new file mode 100644 (file)
index 0000000..5c34716
--- /dev/null
@@ -0,0 +1,14 @@
+<html>
+<head>
+<script type="text/javascript">
+    function setTitle()
+    {
+        document.title = testInterface.getText();
+    }
+</script>
+<title></title>
+</head>
+
+<body onload="setTitle()">
+</body>
+</html>
index cc78d93..eb26985 100644 (file)
@@ -52,9 +52,4 @@ FILES = [
     'filename': 'Makefile.templ',
     'buildtype': ['dev', 'official'],
   },
-# XPK package generator
-  {
-    'filename': 'tools/make_xpk.py',
-    'buildtype': ['dev', 'official'],
-  },
 ]
index 4466759..3d07eaf 100644 (file)
@@ -91,9 +91,4 @@ FILES = [
     'buildtype': ['dev', 'official'],
     'archive': 'xwalk-win32-syms.zip',
   },
-# XPK package generator
-  {
-    'filename': 'tools/make_xpk.py',
-    'buildtype': ['dev', 'official'],
-  },
 ]
index 8402285..e5c01b1 100644 (file)
@@ -9,6 +9,9 @@
       }, {
        'use_custom_freetype%': 0,
       }],
+      ['OS=="win" or OS=="mac"', {
+        'disable_nacl': 1,
+      }],
     ], # conditions
   },
   'includes' : [
         'runtime/browser/image_util.h',
         'runtime/browser/media/media_capture_devices_dispatcher.cc',
         'runtime/browser/media/media_capture_devices_dispatcher.h',
+        'runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.cc',
+        'runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h',
         'runtime/browser/runtime.cc',
         'runtime/browser/runtime.h',
         'runtime/browser/runtime_context.cc',
         'runtime/renderer/android/xwalk_permission_client.h',
         'runtime/renderer/android/xwalk_render_view_ext.cc',
         'runtime/renderer/android/xwalk_render_view_ext.h',
+        'runtime/renderer/pepper/pepper_helper.cc',
+        'runtime/renderer/pepper/pepper_helper.h',
+        'runtime/renderer/pepper/pepper_uma_host.cc',
+        'runtime/renderer/pepper/pepper_uma_host.h',
+        'runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.cc',
+        'runtime/renderer/pepper/xwalk_renderer_pepper_host_factory.h',
         'runtime/renderer/tizen/xwalk_content_renderer_client_tizen.cc',
         'runtime/renderer/tizen/xwalk_content_renderer_client_tizen.h',
         'runtime/renderer/tizen/xwalk_render_view_ext_tizen.cc',
         },
       },
       'conditions': [
-        [ 'tizen == 1 or tizen_mobile == 1', {
+        ['tizen==1', {
           'dependencies': [
             'build/system.gyp:tizen_geolocation',
             'sysapps/sysapps_resources.gyp:xwalk_sysapps_resources',
             ['exclude', '_aura\\.cc$'],
           ],
         }],
+        ['disable_nacl==0', {
+            'conditions': [
+                ['OS=="linux"', {
+                  'sources': [
+                    'runtime/browser/nacl_host/nacl_browser_delegate_impl.cc',
+                    'runtime/browser/nacl_host/nacl_browser_delegate_impl.h',
+                  ],
+                  'dependencies': [
+                    '../components/nacl.gyp:nacl',
+                    '../components/nacl.gyp:nacl_browser',
+                    '../components/nacl.gyp:nacl_common',
+                    '../components/nacl.gyp:nacl_renderer',
+                    '../components/nacl.gyp:nacl_helper',
+                    '../native_client/src/trusted/service_runtime/linux/nacl_bootstrap.gyp:nacl_helper_bootstrap',
+                  ],
+                }],
+            ],
+        }],
+        ['enable_plugins==1', {
+          'dependencies': [
+            '../ppapi/ppapi_internal.gyp:ppapi_host',
+            '../ppapi/ppapi_internal.gyp:ppapi_proxy',
+            '../ppapi/ppapi_internal.gyp:ppapi_ipc',
+            '../ppapi/ppapi_internal.gyp:ppapi_shared',
+          ],
+        }, {  # enable_plugins==0
+          'sources/': [
+            ['exclude', '^runtime/browser/renderer_host/pepper/'],
+            ['exclude', '^runtime/renderer/pepper/'],
+          ],
+        }],
       ],
     },
     {
           'dependencies': [
             'xwalk',
             'xwalk_all_tests',
-            'xwalk_xpk_generator',
           ],
         },
         {
             'xwalk_runtime_lib_apk',
             'xwalk_app_hello_world_apk',
             'xwalk_app_template',
+            'xwalk_core_sample_apk'
           ],
         }],
       ],
     },
-    {
-      'target_name': 'xwalk_xpk_generator',
-      'type': 'none',
-      'copies': [
-        {
-          'destination': '<(PRODUCT_DIR)/tools',
-          'files': [
-            'tools/make_xpk.py',
-          ],
-        },
-      ],
-    },
   ], # targets
   'conditions': [
     ['OS=="linux"', {
index aab897a..5963b15 100644 (file)
         'java_in_dir': 'test/android/core/javatests',
         'is_test_apk': 1,
         'additional_input_paths': [
+          '<(PRODUCT_DIR)/xwalk_xwview_test/assets/add_js_interface.html',
           '<(PRODUCT_DIR)/xwalk_xwview_test/assets/broadcast.html',
           '<(PRODUCT_DIR)/xwalk_xwview_test/assets/echo.html',
           '<(PRODUCT_DIR)/xwalk_xwview_test/assets/echoSync.html',
         {
           'destination': '<(PRODUCT_DIR)/xwalk_xwview_test/assets',
           'files': [
+            'test/android/data/add_js_interface.html',
             'test/android/data/broadcast.html',
             'test/android/data/echo.html',
             'test/android/data/echoSync.html',
         'apk_name': 'XWalkRuntimeClientShell',
         'java_in_dir': 'app/android/runtime_client_shell',
         'resource_dir': 'app/android/runtime_client_shell/res',
+        'is_test_apk': 1,
         'additional_input_paths': [
           '<(PRODUCT_DIR)/runtime_client_shell/assets/extensions-config.json',
           '<(PRODUCT_DIR)/runtime_client_shell/assets/index.html',
index b3fb91c..fa4f9e1 100644 (file)
@@ -58,7 +58,7 @@
             '../skia/skia.gyp:skia',
           ],
         }],
-        ['tizen == 1 or tizen_mobile == 1', {
+        ['tizen==1', {
           'sources': [
             'application/common/manifest_handlers/navigation_handler_unittest.cc',
           ],