diff --git a/.gitignore b/.gitignore index 0c609ce036f23..bfdf7a537b590 100644 --- a/.gitignore +++ b/.gitignore @@ -476,3 +476,5 @@ vs-chromium-project.txt /win8/metro_driver/metro_driver_version_resources.xml /x86-generic_out/ /xcodebuild +/content/nw + diff --git a/DEPS b/DEPS index c3a36c4de4070..fabe449353062 100644 --- a/DEPS +++ b/DEPS @@ -17,6 +17,8 @@ vars = { 'https://android.googlesource.com/platform/external/deqp', 'freetype_android_revision': 'a512b0fe7a8d9db0e5aa9c0a4db1e92cb861722d', + 'nwjs_git': + 'https://github.com/nwjs', 'google_toolbox_for_mac_revision': '401878398253074c515c03cb3a3f8bb0cc8da6e9', 'googlecode_url': @@ -167,8 +169,13 @@ deps = { (Var("chromium_git")) + '/chromium/deps/acid3.git@6be0a66a1ebd7ebc5abc1b2f405a945f6d871521', 'src/tools/swarming_client': (Var("chromium_git")) + '/external/swarming.client.git@df6e95e7669883c8fe9ef956c69a544154701a49', - 'src/v8': - (Var("chromium_git")) + '/v8/v8.git@d95aababa8f08bc018f72fe621fbf53427de5d17' + #'src/v8': + # (Var("chromium_git")) + '/v8/v8.git@d95aababa8f08bc018f72fe621fbf53427de5d17' + # (Var("nwjs_git")) + '/v8.git@origin/nw16', + #'src/content/nw': + # (Var("nwjs_git")) + '/nw.js.git@origin/nw16', + #'src/third_party/node': + # (Var("nwjs_git")) + '/node.git@origin/nw16', } deps_os = { @@ -718,6 +725,17 @@ hooks = [ 'name': 'doclava' }, + { + 'action': [ + 'python', + 'src/content/nw/tools/patcher.py', + '--patch-config', 'src/content/nw/patch/patch.cfg' + ], + 'pattern': + '.', + 'name': + 'nw_patch' + }, { 'action': [ 'python', diff --git a/apps/app_lifetime_monitor.cc b/apps/app_lifetime_monitor.cc index 6051f0c1c222f..6ec52fb7c45e4 100644 --- a/apps/app_lifetime_monitor.cc +++ b/apps/app_lifetime_monitor.cc @@ -86,8 +86,10 @@ void AppLifetimeMonitor::OnAppWindowRemoved(AppWindow* app_window) { } void AppLifetimeMonitor::OnAppWindowHidden(AppWindow* app_window) { +#if 0 if (!HasOtherVisibleAppWindows(app_window)) NotifyAppDeactivated(app_window->extension_id()); +#endif } void AppLifetimeMonitor::OnAppWindowShown(AppWindow* app_window, diff --git a/apps/app_load_service.cc b/apps/app_load_service.cc index eb4b5c6b1c5e7..c1236c6d516bf 100644 --- a/apps/app_load_service.cc +++ b/apps/app_load_service.cc @@ -4,6 +4,8 @@ #include "apps/app_load_service.h" +#include "content/nw/src/nw_content.h" + #include "apps/app_load_service_factory.h" #include "apps/app_restore_service.h" #include "apps/launcher.h" @@ -69,6 +71,8 @@ bool AppLoadService::LoadAndLaunch(const base::FilePath& extension_path, return false; } + nw::SetMainExtensionId(extension_id); + // Schedule the app to be launched once loaded. PostReloadAction& action = post_reload_actions_[extension_id]; action.action_type = LAUNCH_FOR_LOAD_AND_LAUNCH; diff --git a/apps/launcher.cc b/apps/launcher.cc index 02c630279efef..7cad00e6ed16b 100644 --- a/apps/launcher.cc +++ b/apps/launcher.cc @@ -101,7 +101,10 @@ class PlatformAppPathLauncher extension_id(extension->id()), entry_paths_(entry_paths), mime_type_collector_(profile), - is_directory_collector_(profile) {} + is_directory_collector_(profile) { + if (extension->is_nwjs_app()) //NWJS#5097 + entry_paths_.clear(); + } PlatformAppPathLauncher(Profile* profile, const Extension* extension, @@ -110,7 +113,7 @@ class PlatformAppPathLauncher extension_id(extension->id()), mime_type_collector_(profile), is_directory_collector_(profile) { - if (!file_path.empty()) + if (!file_path.empty() && !extension->is_nwjs_app()) //NWJS#5097 entry_paths_.push_back(file_path); } diff --git a/base/base.gyp b/base/base.gyp index 7c9417d013c77..31ff30abef5f4 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -250,6 +250,8 @@ 'message_loop/message_pump_libevent.h', 'message_loop/message_pump_mac.h', 'message_loop/message_pump_mac.mm', + #'message_loop/message_pump_uv.cc', + #'message_loop/message_pump_uv.h', 'metrics/field_trial.cc', 'metrics/field_trial.h', 'posix/file_descriptor_shuffle.cc', diff --git a/base/base_switches.cc b/base/base_switches.cc index fa0bc3337189b..36783eb75eeec 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc @@ -101,4 +101,5 @@ const char kEnableCrashReporterForTesting[] = "enable-crash-reporter-for-testing"; #endif +const char kNWJS[] = "nwjs"; } // namespace switches diff --git a/base/base_switches.h b/base/base_switches.h index b80077b6bbe15..75e3bf12b249d 100644 --- a/base/base_switches.h +++ b/base/base_switches.h @@ -38,6 +38,7 @@ extern const char kDisableUsbKeyboardDetect[]; extern const char kEnableCrashReporterForTesting[]; #endif +extern const char kNWJS[]; } // namespace switches #endif // BASE_BASE_SWITCHES_H_ diff --git a/base/command_line.cc b/base/command_line.cc index c991959d6911b..bba438c00333f 100644 --- a/base/command_line.cc +++ b/base/command_line.cc @@ -151,43 +151,83 @@ string16 QuoteForCommandLineToArgvW(const string16& arg, CommandLine::CommandLine(NoProgram no_program) : argv_(1), - begin_args_(1) { + begin_args_(1), + argc0_(0), argv0_(NULL) { } CommandLine::CommandLine(const FilePath& program) : argv_(1), - begin_args_(1) { + begin_args_(1), + argc0_(0), argv0_(NULL) { SetProgram(program); } CommandLine::CommandLine(int argc, const CommandLine::CharType* const* argv) : argv_(1), - begin_args_(1) { + begin_args_(1), + argc0_(0), argv0_(NULL) { InitFromArgv(argc, argv); } CommandLine::CommandLine(const StringVector& argv) : argv_(1), - begin_args_(1) { + begin_args_(1), + argc0_(0), argv0_(NULL) { InitFromArgv(argv); } CommandLine::CommandLine(const CommandLine& other) : argv_(other.argv_), + original_argv_(other.original_argv_), switches_(other.switches_), - begin_args_(other.begin_args_) { + begin_args_(other.begin_args_), + argc0_(other.argc0_), argv0_(NULL) { + +#if defined(OS_WIN) + if (other.argv0_) { + argv0_ = new char*[argc0_ + 1]; + for (int i = 0; i < argc0_; ++i) { + argv0_[i] = new char[strlen(other.argv0_[i]) + 1]; + strcpy(argv0_[i], other.argv0_[i]); + } + argv0_[argc0_] = NULL; + } +#else + argv0_ = other.argv0_; +#endif ResetStringPieces(); } CommandLine& CommandLine::operator=(const CommandLine& other) { argv_ = other.argv_; + original_argv_ = other.original_argv_; switches_ = other.switches_; begin_args_ = other.begin_args_; +#if defined(OS_WIN) + if (other.argv0_) { + argv0_ = new char*[argc0_ + 1]; + for (int i = 0; i < argc0_; ++i) { + argv0_[i] = new char[strlen(other.argv0_[i]) + 1]; + strcpy(argv0_[i], other.argv0_[i]); + } + argv0_[argc0_] = NULL; + } +#else + argv0_ = other.argv0_; +#endif ResetStringPieces(); return *this; } CommandLine::~CommandLine() { +#if defined(OS_WIN) + if (!argv0_) + return; + for (int i = 0; i < argc0_; i++) { + delete[] argv0_[i]; + } + delete[] argv0_; +#endif } #if defined(OS_WIN) @@ -248,12 +288,34 @@ CommandLine CommandLine::FromString(const string16& command_line) { void CommandLine::InitFromArgv(int argc, const CommandLine::CharType* const* argv) { StringVector new_argv; + argc0_ = argc; +#if !defined(OS_WIN) + argv0_ = (char**)argv; +#else + argv0_ = new char*[argc + 1]; + for (int i = 0; i < argc; ++i) { + std::string str(base::WideToUTF8(argv[i])); + argv0_[i] = new char[str.length() + 1]; + strcpy(argv0_[i], str.c_str()); + } + argv0_[argc] = NULL; +#endif for (int i = 0; i < argc; ++i) new_argv.push_back(argv[i]); InitFromArgv(new_argv); } void CommandLine::InitFromArgv(const StringVector& argv) { +#if !defined(OS_MACOSX) + original_argv_ = argv; +#else + for (size_t index = 0; index < argv.size(); ++index) { + if (argv[index].compare(0, strlen("--psn_"), "--psn_") != 0 && + argv[index].compare(0, strlen("-psn_"), "-psn_") != 0) { + original_argv_.push_back(argv[index]); + } + } +#endif argv_ = StringVector(1); switches_.clear(); switches_by_stringpiece_.clear(); @@ -390,6 +452,12 @@ void CommandLine::AppendArgNative(const CommandLine::StringType& value) { argv_.push_back(value); } +#if defined(OS_MACOSX) +void CommandLine::FixOrigArgv4Finder(const CommandLine::StringType& value) { + original_argv_.push_back(value); +} +#endif + void CommandLine::AppendArguments(const CommandLine& other, bool include_program) { if (include_program) diff --git a/base/command_line.h b/base/command_line.h index 3de8873e26aa6..cd10c38099233 100644 --- a/base/command_line.h +++ b/base/command_line.h @@ -142,6 +142,11 @@ class BASE_EXPORT CommandLine { // Returns the original command line string as a vector of strings. const StringVector& argv() const { return argv_; } + int argc0() { return argc0_; } + char** argv0() { return argv0_; } + + // Returns the original command line string as a vector of strings (keeps precedence). + const StringVector& original_argv() const { return original_argv_; } // Get and Set the program part of the command line string (the first item). FilePath GetProgram() const; @@ -192,6 +197,10 @@ class BASE_EXPORT CommandLine { void AppendArgPath(const FilePath& value); void AppendArgNative(const StringType& value); +#if defined(OS_MACOSX) + void FixOrigArgv4Finder(const StringType& value); +#endif + // Append the switches and arguments from another command line to this one. // If |include_program| is true, include |other|'s program as well. void AppendArguments(const CommandLine& other, bool include_program); @@ -233,6 +242,9 @@ class BASE_EXPORT CommandLine { // The argv array: { program, [(--|-|/)switch[=value]]*, [--], [argument]* } StringVector argv_; + // The argv array (precedence not messed). + StringVector original_argv_; + // Parsed-out switch keys and values. SwitchMap switches_; @@ -244,6 +256,9 @@ class BASE_EXPORT CommandLine { // The index after the program and switches, any arguments start here. size_t begin_args_; + + int argc0_; + char** argv0_; }; } // namespace base diff --git a/base/files/file_util.h b/base/files/file_util.h index 8fd9fffeb36d0..54b00da9f6819 100644 --- a/base/files/file_util.h +++ b/base/files/file_util.h @@ -291,7 +291,7 @@ BASE_EXPORT bool NormalizeToNativeFilePath(const FilePath& path, // Given an existing file in |path|, returns whether this file is on a network // drive or not. If |path| does not exist, this function returns false. -BASE_EXPORT bool IsOnNetworkDrive(const base::FilePath& path); +//BASE_EXPORT bool IsOnNetworkDrive(const base::FilePath& path); #endif // This function will return if the given file is a symlink or not. diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index ca1c5250b920d..742b216b61942 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc @@ -137,7 +137,7 @@ std::string TempFileName() { #if defined(GOOGLE_CHROME_BUILD) return std::string(".com.google.Chrome.XXXXXX"); #else - return std::string(".org.chromium.Chromium.XXXXXX"); + return std::string(".io.nwjs.XXXXXX"); #endif } diff --git a/base/files/file_util_win.cc b/base/files/file_util_win.cc index ddb9c2806a75b..9baa4da86bf91 100644 --- a/base/files/file_util_win.cc +++ b/base/files/file_util_win.cc @@ -559,6 +559,7 @@ bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) { return success; } +#if 0 bool IsOnNetworkDrive(const base::FilePath& path) { win::ScopedHandle handle( ::CreateFileW(path.value().c_str(), @@ -578,6 +579,7 @@ bool IsOnNetworkDrive(const base::FilePath& path) { &remote_proto_info, sizeof(remote_proto_info)); } +#endif // TODO(rkc): Work out if we want to handle NTFS junctions here or not, handle // them if we do decide to. diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index b9517c450ee80..6eff020e28765 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h @@ -37,6 +37,10 @@ #include "base/message_loop/message_pump_libevent.h" #endif +#if !defined(OS_MACOSX) +#include "base/message_loop/message_pump_uv.h" +#endif + namespace base { class HistogramBase; @@ -100,6 +104,9 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate { // TYPE_CUSTOM // MessagePump was supplied to constructor. // + // TYPE_NODE + // For integration with NodeJS/libuv in the renderer thread + enum Type { TYPE_DEFAULT, TYPE_UI, @@ -107,7 +114,8 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate { TYPE_IO, #if defined(OS_ANDROID) TYPE_JAVA, -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) + TYPE_NODE }; // Normally, it is not necessary to instantiate a MessageLoop. Instead, it @@ -701,6 +709,43 @@ class BASE_EXPORT MessageLoopForIO : public MessageLoop { static_assert(sizeof(MessageLoop) == sizeof(MessageLoopForIO), "MessageLoopForIO should not have extra member variables"); +#if !defined(OS_MACOSX) + +//----------------------------------------------------------------------------- +// MessageLoopForUV extends MessageLoop with methods that are particular to a +// MessageLoop instantiated with TYPE_NODE. +// +// This class is typically used like so: +// MessageLoopForUV::current()->...call some method... +// + +class BASE_EXPORT MessageLoopForUV : public MessageLoop { + public: + + MessageLoopForUV() : MessageLoop(TYPE_NODE) { + } + + // Returns the MessageLoopForUV of the current thread. + static MessageLoopForUV* current() { + MessageLoop* loop = MessageLoop::current(); + //DCHECK_EQ(MessageLoop::TYPE_NODE, loop->type()); + return static_cast(loop); + } + + base::MessagePumpUV* pump_uv() { + return static_cast(pump_.get()); + } + +}; + +// Do not add any member variables to MessageLoopForUV! This is important b/c +// MessageLoopForUV is often allocated via MessageLoop(TYPE_IO). Any extra +// data that you need should be stored on the MessageLoop's pump_ instance. +static_assert(sizeof(MessageLoop) == sizeof(MessageLoopForUV), + "MessageLoopForUV should not have extra member variables"); + +#endif + } // namespace base #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ diff --git a/base/message_loop/message_pump_mac.h b/base/message_loop/message_pump_mac.h index 14b8377b9086b..80eff3c72a089 100644 --- a/base/message_loop/message_pump_mac.h +++ b/base/message_loop/message_pump_mac.h @@ -123,7 +123,8 @@ class MessagePumpCFRunLoopBase : public MessagePump { // the instance method; the instance method returns true if it resignalled // work_source_ to be called again from the loop. static void RunWorkSource(void* info); - bool RunWork(); + protected: + virtual bool RunWork(); // Perform idle-priority work. This is normally called by PreWaitObserver, // but is also associated with idle_work_source_. When this function @@ -131,7 +132,8 @@ class MessagePumpCFRunLoopBase : public MessagePump { // static method calls the instance method; the instance method returns // true if idle work was done. static void RunIdleWorkSource(void* info); - bool RunIdleWork(); + virtual bool RunIdleWork(); + virtual void PreWaitObserverHook(); // Perform work that may have been deferred because it was not runnable // within a nested run loop. This is associated with diff --git a/base/message_loop/message_pump_mac.mm b/base/message_loop/message_pump_mac.mm index b50ea6878813b..9e83a77580339 100644 --- a/base/message_loop/message_pump_mac.mm +++ b/base/message_loop/message_pump_mac.mm @@ -458,9 +458,13 @@ explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) : // nesting-deferred work may have accumulated. Schedule it for processing // if appropriate. self->MaybeScheduleNestingDeferredWork(); + self->PreWaitObserverHook(); }); } +void MessagePumpCFRunLoopBase::PreWaitObserverHook() { +} + // Called from the run loop. // static void MessagePumpCFRunLoopBase::PreSourceObserver(CFRunLoopObserverRef observer, diff --git a/base/message_loop/message_pump_uv.cc b/base/message_loop/message_pump_uv.cc new file mode 100644 index 0000000000000..d9b1f643be628 --- /dev/null +++ b/base/message_loop/message_pump_uv.cc @@ -0,0 +1,179 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/message_loop/message_pump_uv.h" + +#include "base/logging.h" +#include "base/command_line.h" +#include "content/public/common/content_switches.h" +#include "v8/include/v8.h" +#include "third_party/node/src/node.h" +#undef CHECK +#undef CHECK_EQ +#undef CHECK_GE +#undef CHECK_GT +#undef CHECK_NE +#undef CHECK_LT +#undef CHECK_LE +#undef CHECK_OP +#undef DISALLOW_COPY_AND_ASSIGN +#include "third_party/node/src/node_webkit.h" + +VoidHookFn g_msg_pump_ctor_fn = nullptr; +VoidHookFn g_msg_pump_dtor_fn = nullptr; +VoidHookFn g_msg_pump_sched_work_fn = nullptr, g_msg_pump_nest_leave_fn = nullptr, g_msg_pump_need_work_fn = nullptr; +VoidHookFn g_msg_pump_did_work_fn = nullptr, g_msg_pump_pre_loop_fn = nullptr, g_msg_pump_nest_enter_fn = nullptr; +VoidIntHookFn g_msg_pump_delay_work_fn = nullptr; +VoidHookFn g_msg_pump_clean_ctx_fn = nullptr; +GetPointerFn g_uv_default_loop_fn = nullptr; + +namespace base { + +MessagePumpUV::MessagePumpUV() + : keep_running_(true), + nesting_level_(0) { + // wakeup_event_ = new uv_async_t; + // uv_async_init(uv_default_loop(), wakeup_event_, wakeup_callback); + // node::g_nw_uv_run = uv_run; + g_msg_pump_ctor_fn(&wakeup_event_); +} + +MessagePumpUV::~MessagePumpUV() { + // delete wakeup_event_; + // wakeup_event_ = NULL; + g_msg_pump_dtor_fn(&wakeup_event_); +} + +void MessagePumpUV::Run(Delegate* delegate) { + + ++nesting_level_; + DCHECK(keep_running_) << "Quit must have been called outside of Run!"; + + msg_pump_context_t ctx; + memset(&ctx, 0, sizeof(msg_pump_context_t)); + + // Poll external loop in nested message loop, so node.js's events will be + // paused in nested loop. + // uv_loop_t* loop = uv_default_loop(); + ctx.loop = g_uv_default_loop_fn(); + ctx.wakeup_event = wakeup_event_; + ctx.wakeup_events = &wakeup_events_; + + if (nesting_level_ > 1) { + g_msg_pump_nest_enter_fn(&ctx); + wakeup_event_ = ctx.wakeup_event; + // loop = uv_loop_new(); + + // wakeup_events_.push_back(wakeup_event_); + // wakeup_event_ = new uv_async_t; + // uv_async_init(loop, wakeup_event_, wakeup_callback); + } + + // // Create handles for the loop. + // uv_idle_t idle_handle; + // uv_idle_init(loop, &idle_handle); + + // uv_timer_t delay_timer; + // delay_timer.data = &idle_handle; + // uv_timer_init(loop, &delay_timer); + + g_msg_pump_pre_loop_fn(&ctx); + // Enter Loop + for (;;) { + bool did_work = delegate->DoWork(); + if (!keep_running_) + break; + + did_work |= delegate->DoDelayedWork(&delayed_work_time_); + if (!keep_running_) + break; + + if (did_work) { + // // call tick callback after done work in V8, + // // in the same way node upstream handle this in MakeCallBack, + // // or the tick callback is blocked in some cases + // if (node::g_env) { + // v8::Isolate* isolate = node::g_env->isolate(); + // v8::HandleScope handleScope(isolate); + // (*node::g_nw_uv_run)(loop, UV_RUN_NOWAIT); + // node::CallNWTickCallback(node::g_env, v8::Undefined(isolate)); + // } + g_msg_pump_did_work_fn(&ctx); + continue; + } + + did_work = delegate->DoIdleWork(); + if (!keep_running_) + break; + + if (did_work) { + g_msg_pump_did_work_fn(&ctx); + continue; + } + + if (delayed_work_time_.is_null()) { + // (*node::g_nw_uv_run)(loop, UV_RUN_ONCE); + g_msg_pump_need_work_fn(&ctx); + } else { + TimeDelta delay = delayed_work_time_ - TimeTicks::Now(); + if (delay > TimeDelta()) { + // uv_timer_start(&delay_timer, timer_callback, + // delay.InMilliseconds(), 0); + // (*node::g_nw_uv_run)(loop, UV_RUN_ONCE); + // uv_idle_stop(&idle_handle); + // uv_timer_stop(&delay_timer); + g_msg_pump_delay_work_fn(&ctx, delay.InMilliseconds()); + } else { + // It looks like delayed_work_time_ indicates a time in the past, so we + // need to call DoDelayedWork now. + delayed_work_time_ = TimeTicks(); + } + } + // Since event_ is auto-reset, we don't need to do anything special here + // other than service each delegate method. + } + + if (nesting_level_ > 1) { + // uv_close((uv_handle_t*)wakeup_event_, NULL); + // // Delete external loop. + // uv_loop_close(loop); + // free(loop); + + // // Restore previous async handle. + // delete wakeup_event_; + // wakeup_event_ = wakeup_events_.back(); + // wakeup_events_.pop_back(); + g_msg_pump_nest_leave_fn(&ctx); + wakeup_event_ = ctx.wakeup_event; + } + + keep_running_ = true; + --nesting_level_; + g_msg_pump_clean_ctx_fn(&ctx); +} + +void MessagePumpUV::Quit() { + keep_running_ = false; +} + +void MessagePumpUV::ScheduleWork() { +// // Since this can be called on any thread, we need to ensure that our Run +// // loop wakes up. +// #if defined(OS_WIN) +// uv_async_send_nw(wakeup_event_); +// #else +// uv_async_send(wakeup_event_); +// #endif + g_msg_pump_sched_work_fn(wakeup_event_); +} + +void MessagePumpUV::ScheduleDelayedWork( + const TimeTicks& delayed_work_time) { + // We know that we can't be blocked on Wait right now since this method can + // only be called on the same thread as Run, so we only need to update our + // record of how long to sleep when we do sleep. + delayed_work_time_ = delayed_work_time; +} + +} // namespace base diff --git a/base/message_loop/message_pump_uv.h b/base/message_loop/message_pump_uv.h new file mode 100644 index 0000000000000..04480dd0d9986 --- /dev/null +++ b/base/message_loop/message_pump_uv.h @@ -0,0 +1,50 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_MESSAGE_PUMP_UV_H_ +#define BASE_MESSAGE_PUMP_UV_H_ +#pragma once + +#include "base/message_loop/message_pump.h" +#include "base/time/time.h" +#include "content/common/content_export.h" + +#include + +//#include "third_party/node/deps/uv/include/uv.h" + +typedef struct uv_async_s uv_async_t; +namespace base { + +class CONTENT_EXPORT MessagePumpUV : public MessagePump { + public: + MessagePumpUV(); + + // MessagePump methods: + void Run(Delegate* delegate) override; + void Quit() override; + void ScheduleWork() override; + void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override; + + private: + ~MessagePumpUV() override; + + // This flag is set to false when Run should return. + bool keep_running_; + + // Nested loop level. + int nesting_level_; + + // Handle to wake up loop. + std::vector wakeup_events_; + void* wakeup_event_; + + TimeTicks delayed_work_time_; + + DISALLOW_COPY_AND_ASSIGN(MessagePumpUV); +}; + +} // namespace base + +#endif // BASE_MESSAGE_PUMP_UV_H_ diff --git a/base/message_loop/message_pumpuv_mac.h b/base/message_loop/message_pumpuv_mac.h new file mode 100644 index 0000000000000..1d52d4a2b72b0 --- /dev/null +++ b/base/message_loop/message_pumpuv_mac.h @@ -0,0 +1,94 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The basis for all native run loops on the Mac is the CFRunLoop. It can be +// used directly, it can be used as the driving force behind the similar +// Foundation NSRunLoop, and it can be used to implement higher-level event +// loops such as the NSApplication event loop. +// +// This file introduces a basic CFRunLoop-based implementation of the +// MessagePump interface called CFRunLoopBase. CFRunLoopBase contains all +// of the machinery necessary to dispatch events to a delegate, but does not +// implement the specific run loop. Concrete subclasses must provide their +// own DoRun and Quit implementations. +// +// A concrete subclass that just runs a CFRunLoop loop is provided in +// MessagePumpCFRunLoop. For an NSRunLoop, the similar MessagePumpNSRunLoop +// is provided. +// +// For the application's event loop, an implementation based on AppKit's +// NSApplication event system is provided in MessagePumpNSApplication. +// +// Typically, MessagePumpNSApplication only makes sense on a Cocoa +// application's main thread. If a CFRunLoop-based message pump is needed on +// any other thread, one of the other concrete subclasses is preferrable. +// MessagePumpMac::Create is defined, which returns a new NSApplication-based +// or NSRunLoop-based MessagePump subclass depending on which thread it is +// called on. + +#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMPUV_MAC_H_ +#define BASE_MESSAGE_LOOP_MESSAGE_PUMPUV_MAC_H_ + +#include "base/message_loop/message_pump.h" + +#include +#include "v8.h" +#include "third_party/node/src/node_webkit.h" + +#include "base/memory/weak_ptr.h" +#include "base/message_loop/timer_slack.h" + +#include "base/message_loop/message_pump_mac.h" + +#if defined(__OBJC__) +#if defined(OS_IOS) +#import +#else +#import + +#endif // !defined(OS_IOS) +#endif // defined(__OBJC__) + +namespace base { + +class RunLoop; +class TimeTicks; + +class BASE_EXPORT MessagePumpUVNSRunLoop : public MessagePumpCFRunLoopBase { + public: + MessagePumpUVNSRunLoop(); + ~MessagePumpUVNSRunLoop() override; + + void DoRun(Delegate* delegate) override; + void Quit() override; + + protected: + bool RunWork() override; + bool RunIdleWork() override; + void PreWaitObserverHook() override; + + private: + // A source that doesn't do anything but provide something signalable + // attached to the run loop. This source will be signalled when Quit + // is called, to cause the loop to wake up so that it can stop. + CFRunLoopSourceRef quit_source_; + + // Thread to poll uv events. + static void EmbedThreadRunner(void *arg); + + // False after Quit is called. + bool keep_running_; + // Flag to pause the libuv loop. + bool pause_uv_; + + msg_pump_context_t ctx_; + // Whether we're done. + int embed_closed_; + + DISALLOW_COPY_AND_ASSIGN(MessagePumpUVNSRunLoop); +}; + +} // namespace base + +#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMPUV_MAC_H_ diff --git a/base/message_loop/message_pumpuv_mac.mm b/base/message_loop/message_pumpuv_mac.mm new file mode 100644 index 0000000000000..f198617d0221a --- /dev/null +++ b/base/message_loop/message_pumpuv_mac.mm @@ -0,0 +1,380 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Copyright Plask, (c) Dean McNamee , 2011. BSD license + + +#import "base/message_loop/message_pump_mac.h" +#import "base/message_loop/message_pumpuv_mac.h" + +#include +#import + +#include + +#include + +#include "base/logging.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/message_loop/timer_slack.h" +#include "base/command_line.h" +#include "base/run_loop.h" +#include "base/time/time.h" +#include "v8/include/v8.h" + +#if !defined(OS_IOS) +#import +#endif // !defined(OS_IOS) + +#include +#include +#include + +#include +#include "third_party/node/src/node_webkit.h" +#include "content/nw/src/nw_content.h" + +#define EVENTLOOP_DEBUG 0 + +#if EVENTLOOP_DEBUG +#define EVENTLOOP_DEBUG_C(x) x +#else +#define EVENTLOOP_DEBUG_C(x) do { } while(0) +#endif + + +//static bool g_should_quit = false; +static int g_kqueue_fd = 0; +static int g_main_thread_pipe_fd = 0; +static int g_kqueue_thread_pipe_fd = 0; + +VoidHookFn g_msg_pump_dtor_osx_fn = nullptr, g_uv_sem_post_fn = nullptr, g_uv_sem_wait_fn = nullptr; +VoidPtr4Fn g_msg_pump_ctor_osx_fn = nullptr; +IntVoidFn g_nw_uvrun_nowait_fn = nullptr; +IntVoidFn g_uv_runloop_once_fn = nullptr; +IntVoidFn g_uv_backend_timeout_fn = nullptr; +IntVoidFn g_uv_backend_fd_fn = nullptr; + +extern GetNodeEnvFn g_get_node_env_fn; + + +VoidHookFn g_msg_pump_ctor_fn = nullptr; +VoidHookFn g_msg_pump_dtor_fn = nullptr; +VoidHookFn g_msg_pump_sched_work_fn = nullptr, g_msg_pump_nest_leave_fn = nullptr, g_msg_pump_need_work_fn = nullptr; +VoidHookFn g_msg_pump_did_work_fn = nullptr, g_msg_pump_pre_loop_fn = nullptr, g_msg_pump_nest_enter_fn = nullptr; +VoidIntHookFn g_msg_pump_delay_work_fn = nullptr; +VoidHookFn g_msg_pump_clean_ctx_fn = nullptr; +GetPointerFn g_uv_default_loop_fn = nullptr; + +int +kevent_hook(int kq, const struct kevent *changelist, int nchanges, + struct kevent *eventlist, int nevents, + const struct timespec *timeout) { + int res; + + EVENTLOOP_DEBUG_C((printf("KQUEUE--- fd: %d changes: %d\n", kq, nchanges))); + +#if 0 //EVENTLOOP_DEBUG + for (int i = 0; i < nchanges; ++i) { + dump_kevent(&changelist[i]); + } +#endif + +#if EVENTLOOP_BYPASS_CUSTOM + int res = kevent(kq, changelist, nchanges, eventlist, nevents, timeout); + printf("---> results: %d\n", res); + for (int i = 0; i < res; ++i) { + dump_kevent(&eventlist[i]); + } + return res; +#endif + + if (eventlist == NULL) // Just updating the state. + return kevent(kq, changelist, nchanges, eventlist, nevents, timeout); + + struct timespec zerotimeout; + memset(&zerotimeout, 0, sizeof(zerotimeout)); + + // Going for a poll. A bit less optimial but we break it into two system + // calls to make sure that the kqueue state is up to date. We might as well + // also peek since we basically get it for free w/ the same call. + EVENTLOOP_DEBUG_C((printf("-- Updating kqueue state and peek\n"))); + res = kevent(kq, changelist, nchanges, eventlist, nevents, &zerotimeout); + if (res != 0) return res; + + /* + printf("kevent() blocking\n"); + res = kevent(kq, NULL, 0, eventlist, nevents, timeout); + if (res != 0) return res; + return res; + */ + + /* + printf("Going for it...\n"); + res = kevent(kq, changelist, nchanges, eventlist, nevents, timeout); + printf("<- %d\n", res); + return res; + */ + + double ts = 9999; // Timeout in seconds. Default to some "future". + if (timeout != NULL) + ts = timeout->tv_sec + (timeout->tv_nsec / 1000000000.0); + + // NOTE(deanm): We only ever make a single pass, because we need to make + // sure that any user code (which could update timers, etc) is reflected + // and we have a proper timeout value. Since user code can run in response + // to [NSApp sendEvent] (mouse movement, keypress, etc, etc), we wind down + // and go back through the uv loop again to make sure to update everything. + + EVENTLOOP_DEBUG_C((printf("-> Running NSApp iteration: timeout %f\n", ts))); + + // Have the helper thread start select()ing on the kqueue. + write(g_main_thread_pipe_fd, "~", 1); + + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate dateWithTimeIntervalSinceNow:ts]]; + + // Stop the helper thread if it hasn't already woken up (in which case it + // would have already stopped itself). + write(g_main_thread_pipe_fd, "!", 1); + + EVENTLOOP_DEBUG_C((printf("<- Finished NSApp iteration\n"))); + + // Do the actual kqueue call now (ignore the timeout, don't block). + return kevent(kq, NULL, 0, eventlist, nevents, &zerotimeout); +} + +namespace base { + +namespace { + +// static +const CFStringRef kMessageLoopExclusiveRunLoopMode = + CFSTR("kMessageLoopExclusiveRunLoopMode"); + +void CFRunLoopAddSourceToAllModes(CFRunLoopRef rl, CFRunLoopSourceRef source) { + CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes); + CFRunLoopAddSource(rl, source, kMessageLoopExclusiveRunLoopMode); +} + +void CFRunLoopRemoveSourceFromAllModes(CFRunLoopRef rl, + CFRunLoopSourceRef source) { + CFRunLoopRemoveSource(rl, source, kCFRunLoopCommonModes); + CFRunLoopRemoveSource(rl, source, kMessageLoopExclusiveRunLoopMode); +} + +void NoOp(void* info) { +} + +#if 0 +void UvNoOp(void* handle) { +} +#endif + +} // namespace + +// A scoper for autorelease pools created from message pump run loops. +// Avoids dirtying up the ScopedNSAutoreleasePool interface for the rare +// case where an autorelease pool needs to be passed in. +class MessagePumpScopedAutoreleasePool { + public: + explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) : + pool_(pump->CreateAutoreleasePool()) { + } + ~MessagePumpScopedAutoreleasePool() { + [pool_ drain]; + } + + private: + NSAutoreleasePool* pool_; + DISALLOW_COPY_AND_ASSIGN(MessagePumpScopedAutoreleasePool); +}; + +bool MessagePumpUVNSRunLoop::RunWork() { + if (!delegate_) { + // This point can be reached with a NULL delegate_ if Run is not on the + // stack but foreign code is spinning the CFRunLoop. Arrange to come back + // here when a delegate is available. + delegateless_work_ = true; + return false; + } + + // The NSApplication-based run loop only drains the autorelease pool at each + // UI event (NSEvent). The autorelease pool is not drained for each + // CFRunLoopSource target that's run. Use a local pool for any autoreleased + // objects if the app is not currently handling a UI event to ensure they're + // released promptly even in the absence of UI events. + MessagePumpScopedAutoreleasePool autorelease_pool(this); + + // Call DoWork and DoDelayedWork once, and if something was done, arrange to + // come back here again as long as the loop is still running. + bool did_work = delegate_->DoWork(); + bool resignal_work_source = did_work; + + TimeTicks next_time; + delegate_->DoDelayedWork(&next_time); + if (!did_work) { + // Determine whether there's more delayed work, and if so, if it needs to + // be done at some point in the future or if it's already time to do it. + // Only do these checks if did_work is false. If did_work is true, this + // function, and therefore any additional delayed work, will get another + // chance to run before the loop goes to sleep. + bool more_delayed_work = !next_time.is_null(); + if (more_delayed_work) { + TimeDelta delay = next_time - TimeTicks::Now(); + if (delay > TimeDelta()) { + // There's more delayed work to be done in the future. + ScheduleDelayedWork(next_time); + } else { + // There's more delayed work to be done, and its time is in the past. + // Arrange to come back here directly as long as the loop is still + // running. + resignal_work_source = true; + } + } + } + + if (resignal_work_source) { + CFRunLoopSourceSignal(work_source_); + } + + return resignal_work_source; +} + +bool MessagePumpUVNSRunLoop::RunIdleWork() { + if (!delegate_) { + // This point can be reached with a NULL delegate_ if Run is not on the + // stack but foreign code is spinning the CFRunLoop. Arrange to come back + // here when a delegate is available. + delegateless_idle_work_ = true; + return false; + } + + // The NSApplication-based run loop only drains the autorelease pool at each + // UI event (NSEvent). The autorelease pool is not drained for each + // CFRunLoopSource target that's run. Use a local pool for any autoreleased + // objects if the app is not currently handling a UI event to ensure they're + // released promptly even in the absence of UI events. + MessagePumpScopedAutoreleasePool autorelease_pool(this); + + // Call DoIdleWork once, and if something was done, arrange to come back here + // again as long as the loop is still running. + bool did_work = delegate_->DoIdleWork(); + if (did_work) { + CFRunLoopSourceSignal(idle_work_source_); + } + + return did_work; +} + +void MessagePumpUVNSRunLoop::PreWaitObserverHook() { + // call tick callback before sleep in mach port + // in the same way node upstream handle this in MakeCallBack, + // or the tick callback is blocked in some cases + nw::KickNextTick(); +} + +MessagePumpUVNSRunLoop::MessagePumpUVNSRunLoop() + : keep_running_(true) { + CFRunLoopSourceContext source_context = CFRunLoopSourceContext(); + source_context.perform = NoOp; + quit_source_ = CFRunLoopSourceCreate(NULL, // allocator + 0, // priority + &source_context); + CFRunLoopAddSourceToAllModes(run_loop(), quit_source_); + + embed_closed_ = 0; + int pipefds[2]; + if (pipe(pipefds) != 0) abort(); + + g_uv_default_loop_fn(); + + g_kqueue_thread_pipe_fd = pipefds[0]; + g_main_thread_pipe_fd = pipefds[1]; + g_kqueue_fd = g_uv_backend_fd_fn(); + + g_msg_pump_ctor_osx_fn(&ctx_, (void*)EmbedThreadRunner, (void*)kevent_hook, this); +} + +MessagePumpUVNSRunLoop::~MessagePumpUVNSRunLoop() { + CFRunLoopRemoveSourceFromAllModes(run_loop(), quit_source_); + CFRelease(quit_source_); + // Clear uv. + embed_closed_ = 1; + g_msg_pump_dtor_osx_fn(&ctx_); +} + +void MessagePumpUVNSRunLoop::DoRun(Delegate* delegate) { + + // Pause uv in nested loop. + if (nesting_level() > 0) { + pause_uv_ = true; + while (keep_running_) { + // NSRunLoop manages autorelease pools itself. + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate distantFuture]]; + } + } else { + while (keep_running_) { + g_uv_runloop_once_fn(); + } + } + + keep_running_ = true; + // Resume uv. + if (nesting_level() > 0) { + pause_uv_ = false; + } +} + +void MessagePumpUVNSRunLoop::Quit() { + keep_running_ = false; + CFRunLoopSourceSignal(quit_source_); + CFRunLoopWakeUp(run_loop()); + write(g_main_thread_pipe_fd, "q", 1); +} + +void MessagePumpUVNSRunLoop::EmbedThreadRunner(void *arg) { + bool check_kqueue = false; + + base::MessagePumpUVNSRunLoop* message_pump = static_cast(arg); + + NSAutoreleasePool* pool = [NSAutoreleasePool new]; // To avoid the warning. + + while (true) { + int nfds = g_kqueue_thread_pipe_fd + 1; + fd_set fds; + FD_ZERO(&fds); + FD_SET(g_kqueue_thread_pipe_fd, &fds); + if (check_kqueue) { + FD_SET(g_kqueue_fd, &fds); + if (g_kqueue_fd + 1 > nfds) nfds = g_kqueue_fd + 1; + } + + EVENTLOOP_DEBUG_C((printf("Calling select: %d\n", check_kqueue))); + int res = select(nfds, &fds, NULL, NULL, NULL); + if (res <= 0) abort(); // TODO(deanm): Handle signals, etc. + + if (FD_ISSET(g_kqueue_fd, &fds)) { + EVENTLOOP_DEBUG_C((printf("postEvent\n"))); + message_pump->ScheduleWork(); + check_kqueue = false; + } + + if (FD_ISSET(g_kqueue_thread_pipe_fd, &fds)) { + char msg; + ssize_t amt = read(g_kqueue_thread_pipe_fd, &msg, 1); + if (amt != 1) abort(); // TODO(deanm): Handle errors. + if (msg == 'q') { // quit. + EVENTLOOP_DEBUG_C((printf("quitting kqueue helper\n"))); + break; + } + check_kqueue = msg == '~'; // ~ - start, ! - stop. + } + } + + [pool drain]; + +} + +} // namespace base diff --git a/base/native_library_posix.cc b/base/native_library_posix.cc index 3179a93833c0a..e1016bbfc9f2a 100644 --- a/base/native_library_posix.cc +++ b/base/native_library_posix.cc @@ -27,7 +27,7 @@ NativeLibrary LoadNativeLibrary(const FilePath& library_path, // refer to the bug tracker. Some useful bug reports to read include: // http://crbug.com/17943, http://crbug.com/17557, http://crbug.com/36892, // and http://crbug.com/40794. - void* dl = dlopen(library_path.value().c_str(), RTLD_LAZY); + void* dl = dlopen(library_path.value().c_str(), RTLD_LAZY | RTLD_GLOBAL); if (!dl && error) error->message = dlerror(); diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc index 99582f59cfcfa..ae632f05e85fd 100644 --- a/base/process/launch_posix.cc +++ b/base/process/launch_posix.cc @@ -464,6 +464,7 @@ Process LaunchProcess(const std::vector& argv, #ifndef PR_SET_NO_NEW_PRIVS #define PR_SET_NO_NEW_PRIVS 38 #endif +#if 0 if (!options.allow_new_privs) { if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) { // Only log if the error is not EINVAL (i.e. not supported). @@ -477,6 +478,7 @@ Process LaunchProcess(const std::vector& argv, _exit(127); } } +#endif #endif if (current_directory != nullptr) { diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 92b7bd5b2f6d4..40179a4ecb4e4 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h @@ -20,6 +20,11 @@ class HistogramSynchronizer; class NativeBackendKWallet; class ScopedAllowWaitForLegacyWebViewApi; +namespace extensions { +class NwAppSetProxyConfigFunction; +class ContentVerifier; +} + namespace cc { class CompletionEvent; class SingleThreadTaskGraphRunner; @@ -216,6 +221,9 @@ class BASE_EXPORT ThreadRestrictions { friend class mus::CommandBufferLocal; friend class mus::GpuState; + friend class extensions::NwAppSetProxyConfigFunction; + friend class extensions::ContentVerifier; + // END ALLOWED USAGE. // BEGIN USAGE THAT NEEDS TO BE FIXED. friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc index 52eccbe1a0cfd..a43f5e4f8f3f4 100644 --- a/base/trace_event/process_memory_dump.cc +++ b/base/trace_event/process_memory_dump.cc @@ -24,10 +24,6 @@ #include #endif -#if defined(OS_WIN) -#include -#endif - namespace base { namespace trace_event { @@ -106,7 +102,7 @@ size_t ProcessMemoryDump::CountResidentBytes(void* start_address, !!mincore(reinterpret_cast(chunk_start), chunk_size, vec.get()); for (size_t i = 0; i < page_count; i++) resident_page_count += vec[i] & MINCORE_INCORE ? 1 : 0; -#elif defined(OS_WIN) +#elif defined(OS_WIN_DISABLE) for (size_t i = 0; i < page_count; i++) { vec[i].VirtualAddress = reinterpret_cast(chunk_start + i * page_size); diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h index 51e4b5f5150a0..611e1ebfbebbe 100644 --- a/base/trace_event/process_memory_dump.h +++ b/base/trace_event/process_memory_dump.h @@ -23,7 +23,7 @@ // Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the // resident memory. -#if (defined(OS_POSIX) && !defined(OS_NACL)) || defined(OS_WIN) +#if (defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_IOS)) #define COUNT_RESIDENT_BYTES_SUPPORTED #endif diff --git a/base/win/win_util.cc b/base/win/win_util.cc index 75f1e53c1416c..a060d650a19c6 100644 --- a/base/win/win_util.cc +++ b/base/win/win_util.cc @@ -696,10 +696,14 @@ bool GetLoadedModulesSnapshot(HANDLE process, std::vector* snapshot) { } void EnableFlicks(HWND hwnd) { + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return; ::RemoveProp(hwnd, MICROSOFT_TABLETPENSERVICE_PROPERTY); } void DisableFlicks(HWND hwnd) { + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return; ::SetProp(hwnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast(TABLET_DISABLE_FLICKS | TABLET_DISABLE_FLICKFALLBACKKEYS)); diff --git a/breakpad/breakpad.gyp b/breakpad/breakpad.gyp index 507d32edfb908..d91ab3bfa05a2 100644 --- a/breakpad/breakpad.gyp +++ b/breakpad/breakpad.gyp @@ -451,7 +451,7 @@ # GN version: //breakpad:dump_syms 'target_name': 'dump_syms', 'type': 'executable', - 'toolsets': ['host'], + 'toolsets': ['host', 'target'], # dwarf2reader.cc uses dynamic_cast. Because we don't typically # don't support RTTI, we enable it for this single target. Since diff --git a/build/chrome_settings.gypi b/build/chrome_settings.gypi index 646b2098b6344..ce06b2d3b5ede 100644 --- a/build/chrome_settings.gypi +++ b/build/chrome_settings.gypi @@ -20,10 +20,10 @@ # The policy .grd file also needs the bundle id. 'grit_defines': ['-D', 'mac_bundle_id=com.google.Chrome'], }, { # else: branding!="Chrome" - 'mac_bundle_id': 'org.chromium.Chromium', + 'mac_bundle_id': 'io.nwjs.nw', 'mac_creator': 'Cr24', # The policy .grd file also needs the bundle id. - 'grit_defines': ['-D', 'mac_bundle_id=org.chromium.Chromium'], + 'grit_defines': ['-D', 'mac_bundle_id=io.nwjs.nw'], }], # branding ], # conditions }], # OS=="mac" diff --git a/build/common.gypi b/build/common.gypi index 2850490e6ae35..5983e9b97df1b 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -101,6 +101,7 @@ # based on 'buildtype' (i.e. we don't care about saving symbols for # non-Official # builds). 'buildtype%': 'Dev', + 'nwjs_sdk%': 0, # Override branding to select the desired branding flavor. 'branding%': 'Chromium', @@ -169,6 +170,7 @@ 'enable_wayland_server%': '<(enable_wayland_server)', 'enable_wifi_display%': '<(enable_wifi_display)', 'buildtype%': '<(buildtype)', + 'nwjs_sdk%': '<(nwjs_sdk)', 'branding%': '<(branding)', 'branding_path_component%': '<(branding)', 'host_arch%': '<(host_arch)', @@ -360,6 +362,7 @@ 'enable_app_list%': '<(enable_app_list)', 'use_default_render_theme%': '<(use_default_render_theme)', 'buildtype%': '<(buildtype)', + 'nwjs_sdk%': '<(nwjs_sdk)', 'branding%': '<(branding)', 'branding_path_component%': '<(branding_path_component)', 'arm_version%': '<(arm_version)', @@ -430,7 +433,7 @@ 'use_titlecase_in_grd%': 0, # Remoting compilation is enabled by default. Set to 0 to disable. - 'remoting%': 1, + 'remoting%': 0, # Configuration policy is enabled by default. Overridden on some # platforms. This can't be disabled manually since code in src/chrome @@ -441,7 +444,7 @@ # for safe browsing feature. Safe browsing can be compiled in 3 different # levels: 0 disables it, 1 enables it fully, and 2 enables mobile # protection via an external API. - 'safe_browsing%': 1, + 'safe_browsing%': 0, # Web speech is enabled by default. Set to 0 to disable. 'enable_web_speech%': 1, @@ -619,13 +622,13 @@ # See https://chromium.googlesource.com/chromium/src/+/master/docs/clang.md for details. # If this is set, clang is used as both host and target compiler in # cross-compile builds. - 'clang%': 0, + 'clang%': 1, # Use experimental lld linker instead of the platform's default linker. 'use_lld%': 0, # Enable plugin installation by default. - 'enable_plugin_installation%': 1, + 'enable_plugin_installation%': 0, # Specifies whether to use canvas_skia.cc in place of platform # specific implementations of gfx::Canvas. Affects text drawing in the @@ -831,7 +834,8 @@ ['branding=="Chrome" or chromecast==1', { 'proprietary_codecs%': 1, }, { - 'proprietary_codecs%': 0, + # This enables only the interface to proprietary codecs, not the codecs themselves + 'proprietary_codecs%': 1, }], ['buildtype=="Official"', { @@ -896,7 +900,7 @@ ['chromeos==1 or OS=="android" or OS=="ios" or desktop_linux==1', { 'enable_plugin_installation%': 0, }, { - 'enable_plugin_installation%': 1, + 'enable_plugin_installation%': 0, }], # Whether PPAPI is enabled. @@ -1112,7 +1116,7 @@ 'google_default_client_id%': '', 'google_default_client_secret%': '', # Native Client is enabled by default. - 'disable_nacl%': '0', + 'disable_nacl%': '1', # Native Client toolchains, enabled by default. 'disable_pnacl%': 0, @@ -1128,6 +1132,7 @@ }, # Copy conditionally-set variables out one scope. + 'nwjs_sdk%': '<(nwjs_sdk)', 'branding%': '<(branding)', 'branding_path_component%': '<(branding_path_component)', 'buildtype%': '<(buildtype)', @@ -1320,7 +1325,7 @@ # The default value for mac_strip in target_defaults. This cannot be # set there, per the comment about variable% in a target_defaults. - 'mac_strip_release%': 0, + 'mac_strip_release%': 1, # Set to 1 to enable java code coverage. Instruments classes during build # to produce .ec files during runtime. @@ -1417,12 +1422,12 @@ 'profiling_full_stack_frames%': '0', # And if we want to dump symbols for Breakpad-enabled builds. - 'linux_dump_symbols%': 0, + 'linux_dump_symbols%': 1, # And if we want to strip the binary after dumping symbols. 'linux_strip_binary%': 0, # If we want stack unwind support for backtrace(). 'debug_unwind_tables%': 1, - 'release_unwind_tables%': 1, + 'release_unwind_tables%': 0, # Override where to find binutils 'binutils_version%': 0, @@ -1595,6 +1600,9 @@ 'libjpeg_turbo_gyp_path': '<(DEPTH)/third_party/libjpeg_turbo/libjpeg.gyp', 'conditions': [ + ['nwjs_sdk!=1', { + 'locales==': [ 'en-US', ], + }], # Enable the Syzygy optimization step for the official builds. ['OS=="win" and buildtype=="Official" and syzyasan!=1 and clang!=1', { 'syzygy_optimize%': 1, @@ -1953,7 +1961,7 @@ ['branding=="Chrome"', { 'mac_product_name%': 'Google Chrome', }, { # else: branding!="Chrome" - 'mac_product_name%': 'Chromium', + 'mac_product_name%': 'nwjs', }], # Official mac builds require a specific OS X SDK, but iOS and # non-official mac builds do not. @@ -1989,7 +1997,7 @@ }], ['component=="static_library"', { # Turn on multiple dll by default on Windows when in static_library. - 'chrome_multiple_dll%': 1, + 'chrome_multiple_dll%': 0, }], ['asan==1 or syzyasan==1', { 'win_use_allocator_shim%': 0, @@ -2084,6 +2092,9 @@ }], # Set up -D and -E flags passed into grit. + ['nwjs_sdk==1', { + 'grit_defines': ['-D', 'nwjs_sdk'], + }], ['branding=="Chrome"', { # TODO(mmoss) The .grd files look for _google_chrome, but for # consistency they should look for google_chrome_build like C++. @@ -2676,6 +2687,9 @@ '<(DEPTH)/build/win/asan.gyp:asan_dynamic_runtime', ], }], + ['nwjs_sdk==1', { + 'defines': ['NWJS_SDK'], + }], ['branding=="Chrome"', { 'defines': ['GOOGLE_CHROME_BUILD'], }, { # else: branding!="Chrome" @@ -3099,8 +3113,7 @@ '_SCL_SECURE_NO_DEPRECATE', ], 'msvs_disabled_warnings': [ - # forcing value to bool 'true' or 'false' (performance warning) - 4800, + 4800, 4275, 4267, 4090, 4146, 4334, 4068 ], 'msvs_settings': { 'VCCLCompilerTool': { @@ -3115,7 +3128,7 @@ 'VCCLCompilerTool': { 'WarnAsError': 'false' }, } }], - [ 'component=="shared_library"', { + [ '1 == 1', { # TODO(darin): Unfortunately, some third_party code depends on base. 'msvs_disabled_warnings': [ 4251, # class 'std::xx' needs to have dll-interface. @@ -3165,7 +3178,7 @@ }, }, }], - ['OS=="win" and component=="shared_library"', { + ['1 == 1', { 'msvs_disabled_warnings': [ 4251, # class 'std::xx' needs to have dll-interface. ], @@ -5194,7 +5207,7 @@ 'configurations': { 'Release_Base': { 'conditions': [ - ['branding=="Chrome" and buildtype=="Official"', { + ['mac_breakpad == 1', { 'xcode_settings': { 'OTHER_CFLAGS': [ # The Google Chrome Framework dSYM generated by dsymutil has diff --git a/build/compiler_version.py b/build/compiler_version.py index 8db0108110963..8d80f0cbcbb02 100755 --- a/build/compiler_version.py +++ b/build/compiler_version.py @@ -54,7 +54,7 @@ def GetVersion(compiler, tool): try: # Note that compiler could be something tricky like "distcc g++". if tool == "assembler": - compiler = compiler + " -Xassembler --version -x assembler -c /dev/null" + compiler = compiler + " --version -Xassembler -x assembler -c /dev/null" # Unmodified: GNU assembler (GNU Binutils) 2.24 # Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22 # Fedora: GNU assembler version 2.23.2 diff --git a/build/win/dbghelp_xp/x64/dbghelp.dll b/build/win/dbghelp_xp/x64/dbghelp.dll new file mode 100644 index 0000000000000..446f1fafc77b4 Binary files /dev/null and b/build/win/dbghelp_xp/x64/dbghelp.dll differ diff --git a/build/win/reorder-imports.py b/build/win/reorder-imports.py index 00a69d75de373..822354dab6ad5 100755 --- a/build/win/reorder-imports.py +++ b/build/win/reorder-imports.py @@ -16,8 +16,8 @@ def reorder_imports(input_dir, output_dir, architecture): (pdbs, manifests etc.). """ - input_image = os.path.join(input_dir, 'chrome.exe') - output_image = os.path.join(output_dir, 'chrome.exe') + input_image = os.path.join(input_dir, 'nw.exe') + output_image = os.path.join(output_dir, 'nw.exe') swap_exe = os.path.join( __file__, @@ -29,11 +29,11 @@ def reorder_imports(input_dir, output_dir, architecture): if architecture == 'x64': args.append('--x64'); - args.append('chrome_elf.dll'); + args.append('nw_elf.dll'); subprocess.check_call(args) - for fname in glob.iglob(os.path.join(input_dir, 'chrome.exe.*')): + for fname in glob.iglob(os.path.join(input_dir, 'nw.exe.*')): shutil.copy(fname, os.path.join(output_dir, os.path.basename(fname))) return 0 @@ -41,9 +41,9 @@ def reorder_imports(input_dir, output_dir, architecture): def main(argv): usage = 'reorder_imports.py -i -o -a ' parser = optparse.OptionParser(usage=usage) - parser.add_option('-i', '--input', help='reorder chrome.exe in DIR', + parser.add_option('-i', '--input', help='reorder nw.exe in DIR', metavar='DIR') - parser.add_option('-o', '--output', help='write new chrome.exe to DIR', + parser.add_option('-o', '--output', help='write new nw.exe to DIR', metavar='DIR') parser.add_option('-a', '--arch', help='architecture of build (optional)', default='ia32') diff --git a/chrome/app/app-Info.plist b/chrome/app/app-Info.plist index c5939d4d093fb..03ac630d3e501 100644 --- a/chrome/app/app-Info.plist +++ b/chrome/app/app-Info.plist @@ -336,7 +336,7 @@ public.data UTTypeDescription - Chromium Extra + NWJS Extra UTTypeIdentifier org.chromium.extension UTTypeTagSpecification diff --git a/chrome/app/chrome_crash_reporter_client.cc b/chrome/app/chrome_crash_reporter_client.cc index b113ba1b7d631..deea8700c13f1 100644 --- a/chrome/app/chrome_crash_reporter_client.cc +++ b/chrome/app/chrome_crash_reporter_client.cc @@ -62,7 +62,7 @@ void ChromeCrashReporterClient::GetProductNameAndVersion( *product_name = "Chrome_ChromeOS"; #else // OS_LINUX #if !defined(ADDRESS_SANITIZER) - *product_name = "Chrome_Linux"; + *product_name = "NWJS"; #else *product_name = "Chrome_Linux_ASan"; #endif @@ -95,8 +95,9 @@ size_t ChromeCrashReporterClient::RegisterCrashKeys() { } bool ChromeCrashReporterClient::IsRunningUnattended() { - std::unique_ptr env(base::Environment::Create()); - return env->HasVar(env_vars::kHeadless); + // std::unique_ptr env(base::Environment::Create()); + // return env->HasVar(env_vars::kHeadless); + return true; } bool ChromeCrashReporterClient::GetCollectStatsConsent() { diff --git a/chrome/app/chrome_dll.ver b/chrome/app/chrome_dll.ver index 910fca21d178a..fccabec864571 100644 --- a/chrome/app/chrome_dll.ver +++ b/chrome/app/chrome_dll.ver @@ -1,2 +1,2 @@ -INTERNAL_NAME=chrome_dll -ORIGINAL_FILENAME=chrome.dll +INTERNAL_NAME=nw_dll +ORIGINAL_FILENAME=nw.dll diff --git a/chrome/app/chrome_exe.ver b/chrome/app/chrome_exe.ver index a2d39013f5a5d..17bb91f1806de 100644 --- a/chrome/app/chrome_exe.ver +++ b/chrome/app/chrome_exe.ver @@ -1,2 +1,2 @@ -INTERNAL_NAME=chrome_exe -ORIGINAL_FILENAME=chrome.exe +INTERNAL_NAME=nw_exe +ORIGINAL_FILENAME=nw.exe diff --git a/chrome/app/chrome_exe_main_mac.c b/chrome/app/chrome_exe_main_mac.c index 5c9be39ba3f3d..d122e3797310d 100644 --- a/chrome/app/chrome_exe_main_mac.c +++ b/chrome/app/chrome_exe_main_mac.c @@ -72,7 +72,7 @@ __attribute__((visibility("default"))) int main(int argc, char* argv[]) { } snprintf(framework_path, framework_path_size, "%s/%s", parent_dir, rel_path); - void* library = dlopen(framework_path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST); + void* library = dlopen(framework_path, RTLD_LAZY | RTLD_FIRST); if (!library) { fprintf(stderr, "dlopen %s: %s\n", framework_path, dlerror()); abort(); diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index 6eeb475d7c8fa..085a70f779d20 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc @@ -234,6 +234,12 @@ int main() { HasValidWindowsPrefetchArgument(*command_line)); if (process_type == crash_reporter::switches::kCrashpadHandler) { + // HACK: Let Windows know that we have started. This is needed to suppress + // the IDC_APPSTARTING cursor from being displayed for a prolonged period + // while a subprocess is starting. NWJS#4685 + PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0); + MSG msg; + PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); return crash_reporter::RunAsCrashpadHandler( *base::CommandLine::ForCurrentProcess()); } @@ -252,8 +258,10 @@ int main() { EnableHighDPISupport(); +#if 0 //FIXME(nwjs) if (AttemptFastNotify(*command_line)) return 0; +#endif RemoveAppCompatFlagsEntry(); diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc index 0ad602abf0cfc..b2806f15c82ff 100644 --- a/chrome/app/chrome_main.cc +++ b/chrome/app/chrome_main.cc @@ -52,7 +52,7 @@ int ChromeMain(int argc, const char** argv) { #if defined(OS_WIN) // The process should crash when going through abnormal termination. - base::win::SetShouldCrashOnProcessDetach(true); + base::win::SetShouldCrashOnProcessDetach(false); base::win::SetAbortBehaviorForCrashReporting(); params.instance = instance; params.sandbox_info = sandbox_info; diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 75286cc2d3c90..5288652331908 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc @@ -55,6 +55,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_switches.h" +#include "content/nw/src/nw_base.h" #if defined(OS_WIN) #include #include @@ -145,6 +146,16 @@ base::LazyInstance g_chrome_content_gpu_client = LAZY_INSTANCE_INITIALIZER; + +#include "third_party/node/src/node_webkit.h" +#include "third_party/zlib/google/zip_reader.h" +#include "base/native_library.h" +#include "base/strings/utf_string_conversions.h" +#if defined(OS_MACOSX) +#include "base/mac/bundle_locations.h" +#include "base/strings/sys_string_conversions.h" +#endif + base::LazyInstance g_chrome_content_renderer_client = LAZY_INSTANCE_INITIALIZER; base::LazyInstance @@ -164,6 +175,9 @@ base::LazyInstance::Leaky g_chrome_crash_client = extern int NaClMain(const content::MainFunctionParams&); extern int ServiceProcessMain(const content::MainFunctionParams&); +NodeStartFn g_node_start_fn = nullptr; +SetBlobPathFn g_set_blob_path_fn = nullptr; + namespace { #if defined(OS_WIN) @@ -410,7 +424,7 @@ void InitializeUserDataDir() { // Append the fallback user data directory to the commandline. Otherwise, // child or service processes will attempt to use the invalid directory. - if (specified_directory_was_invalid) + //if (specified_directory_was_invalid) command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir); } @@ -466,7 +480,7 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) { chromeos::BootTimesRecorder::Get()->SaveChromeMainStats(); #endif - const base::CommandLine& command_line = + base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); #if defined(OS_WIN) @@ -488,6 +502,35 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) { chrome::common::mac::EnableCFBundleBlocker(); #endif + const base::CommandLine::StringVector& args = command_line.GetArgs(); + if (args.size() > 0) { + zip::ZipReader reader; + base::FilePath fp(args[0]); + if (!command_line.HasSwitch(switches::kProcessType) && + base::PathExists(fp) && !base::DirectoryExists(fp) && !reader.Open(fp)) { + base::NativeLibraryLoadError error; +#if defined(OS_MACOSX) + base::FilePath node_dll_path = base::mac::FrameworkBundlePath().Append(base::FilePath::FromUTF16Unsafe(base::GetNativeLibraryName(base::UTF8ToUTF16("libnode")))); + base::ScopedCFTypeRef natives_file_name(base::SysUTF8ToCFStringRef("natives_blob.bin")); + std::string blob_path = base::mac::PathForFrameworkBundleResource(natives_file_name).AsUTF8Unsafe(); +#else + base::FilePath node_dll_path = base::FilePath::FromUTF16Unsafe(base::GetNativeLibraryName(base::UTF8ToUTF16("node"))); +#endif + base::NativeLibrary node_dll = base::LoadNativeLibrary(node_dll_path, &error); + if(!node_dll) + LOG(FATAL) << "Failed to load node library (error: " << error.ToString() << ")"; + else { +#if defined(OS_MACOSX) + g_set_blob_path_fn = (SetBlobPathFn)base::GetFunctionPointerFromNativeLibrary(node_dll, "g_set_blob_path"); + g_set_blob_path_fn(blob_path.c_str()); +#endif + g_node_start_fn = (NodeStartFn)base::GetFunctionPointerFromNativeLibrary(node_dll, "g_node_start"); + *exit_code = g_node_start_fn(command_line.argc0(), command_line.argv0()); + } + return true; + } + } + Profiling::ProcessStarted(); base::trace_event::TraceLog::GetInstance()->SetArgumentFilterPredicate( @@ -699,6 +742,8 @@ void ChromeMainDelegate::PreSandboxStartup() { crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer()); #endif + if (process_type.empty()) + nw::InitNWPackage(); #if defined(OS_MACOSX) // On the Mac, the child executable lives at a predefined location within // the app bundle's versioned directory. @@ -721,12 +766,12 @@ void ChromeMainDelegate::PreSandboxStartup() { // Initialize the user data dir for any process type that needs it. if (chrome::ProcessNeedsProfileDir(process_type)) InitializeUserDataDir(); - +#if 0 // Register component_updater PathProvider after DIR_USER_DATA overidden by // command line flags. Maybe move the chrome PathProvider down here also? component_updater::RegisterPathProvider(chrome::DIR_COMPONENTS, chrome::DIR_USER_DATA); - +#endif // Enable Message Loop related state asap. if (command_line.HasSwitch(switches::kMessageLoopHistogrammer)) base::MessageLoop::EnableHistogrammer(true); diff --git a/chrome/app/chrome_version.rc.version b/chrome/app/chrome_version.rc.version index 0ec74bdd42dd5..588068457adbf 100644 --- a/chrome/app/chrome_version.rc.version +++ b/chrome/app/chrome_version.rc.version @@ -10,8 +10,6 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION @MAJOR@,@MINOR@,@BUILD@,@PATCH@ - PRODUCTVERSION @MAJOR@,@MINOR@,@BUILD@,@PATCH@ FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -28,16 +26,13 @@ BEGIN BEGIN VALUE "CompanyName", "@COMPANY_FULLNAME@" VALUE "FileDescription", "@PRODUCT_FULLNAME@" - VALUE "FileVersion", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@" VALUE "InternalName", "@INTERNAL_NAME@" VALUE "LegalCopyright", "@COPYRIGHT@" VALUE "OriginalFilename", "@ORIGINAL_FILENAME@" VALUE "ProductName", "@PRODUCT_FULLNAME@" - VALUE "ProductVersion", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@" VALUE "CompanyShortName", "@COMPANY_SHORTNAME@" VALUE "ProductShortName", "@PRODUCT_SHORTNAME@" VALUE "LastChange", "@LASTCHANGE@" - VALUE "Official Build", "@OFFICIAL_BUILD@" END END BLOCK "VarFileInfo" diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 1477ef05ac7ff..9676e76a04447 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd @@ -137,17 +137,17 @@ If you update this file, be sure also to update google_chrome_strings.grd. --> Disconnecting $1someone@example.com will clear your history, bookmarks, settings, and other Chromium data stored on this device. Data stored in your Google Account will not be cleared and can be managed on <a target="_blank" href="$2">Google Dashboard</a>. - Chromium + nwjs - Chromium + nwjs - Chromium + nwjs - Chromium is a web browser that runs webpages and applications with lightning speed. It's fast, stable, and easy to use. Browse the web more safely with malware and phishing protection built into Chromium. + nwjs runtime enables writing native application with Web technologies. @@ -160,10 +160,10 @@ If you update this file, be sure also to update google_chrome_strings.grd. --> - Chromium App Launcher + nwjs App Launcher - Chromium Binaries + nwjs Binaries https://support.google.com/chrome/?p=ib_chromeframe @@ -205,7 +205,7 @@ If you update this file, be sure also to update google_chrome_strings.grd. --> The Chromium Authors - Copyright $1 The Chromium Authors. All rights reserved. + Copyright $1 NW.js contributors, Chromium Authors, IO.js. All rights reserved. @@ -696,13 +696,13 @@ Chromium is unable to recover your settings. - Chromium + nwjs - Chromium Helper + nwjs Helper - Chromium Helper + nwjs Helper diff --git a/chrome/app/framework.order b/chrome/app/framework.order index 062dba88fdf21..e8e9ea97e0071 100644 --- a/chrome/app/framework.order +++ b/chrome/app/framework.order @@ -24,6 +24,267 @@ __ZdlPvS_ # Provided by build/sanitizers/sanitizer_options.cc in ASan builds. ___asan_default_options +__ZN4node14ErrnoExceptionEPN2v87IsolateEiPKcS4_S4_ +__ZN4node11UVExceptionEPN2v87IsolateEiPKcS4_S4_ +__ZN4node11UVExceptionEPN2v87IsolateEiPKcS4_S4_S4_ +__ZN4node16CallTickCallbackEPNS_11EnvironmentEN2v86HandleINS2_5ValueEEE +__ZN4node12MakeCallbackEPN2v87IsolateENS0_6HandleINS0_6ObjectEEEPKciPNS3_INS0_5ValueEEE +__ZN4node12MakeCallbackEPN2v87IsolateENS0_6HandleINS0_6ObjectEEENS3_INS0_6StringEEEiPNS3_INS0_5ValueEEE +__ZN4node12MakeCallbackEPN2v87IsolateENS0_6HandleINS0_6ObjectEEENS3_INS0_8FunctionEEEiPNS3_INS0_5ValueEEE +__ZN4node6EncodeEPN2v87IsolateEPKcmNS_8encodingE +__ZN4node6EncodeEPN2v87IsolateEPKtm +__ZN4node11DecodeBytesEPN2v87IsolateENS0_6HandleINS0_5ValueEEENS_8encodingE +__ZN4node11DecodeWriteEPN2v87IsolateEPcmNS0_6HandleINS0_5ValueEEENS_8encodingE +_node_module_register +__ZN4node14FatalExceptionEPN2v87IsolateERKNS0_8TryCatchE +__ZN4node9OnMessageEN2v86HandleINS0_7MessageEEENS1_INS0_5ValueEEE +__ZN4node15LoadEnvironmentEPNS_11EnvironmentE +__ZN4node4InitEPiPPKcS0_PS3_ +__ZN4node9RunAtExitEPNS_11EnvironmentE +__ZN4node6AtExitEPFvPvES0_ +__ZN4node14EmitBeforeExitEPNS_11EnvironmentE +__ZN4node8EmitExitEPNS_11EnvironmentE +__ZN4node17CreateEnvironmentEPN2v87IsolateENS0_6HandleINS0_7ContextEEEiPKPKciS9_ +__ZN4node17CreateEnvironmentEPN2v87IsolateEP9uv_loop_sNS0_6HandleINS0_7ContextEEEiPKPKciSB_ +__ZN4node5StartEiPPc +__ZN4node11SetupNWNodeEiPPc +__ZN4node15StartNWInstanceEiPPcN2v86HandleINS2_7ContextEEE +__ZN4node17SetNWTickCallbackEPFN2v86HandleINS0_5ValueEEEPNS_11EnvironmentES3_E +__ZN4node18CallNWTickCallbackEPNS_11EnvironmentEN2v86HandleINS2_5ValueEEE +__ZN4node6Buffer11HasInstanceEN2v86HandleINS1_5ValueEEE +__ZN4node6Buffer11HasInstanceEN2v86HandleINS1_6ObjectEEE +__ZN4node6Buffer4DataEN2v86HandleINS1_5ValueEEE +__ZN4node6Buffer4DataEN2v86HandleINS1_6ObjectEEE +__ZN4node6Buffer6LengthEN2v86HandleINS1_5ValueEEE +__ZN4node6Buffer6LengthEN2v86HandleINS1_6ObjectEEE +__ZN4node6Buffer3NewEPN2v87IsolateENS1_6HandleINS1_6StringEEENS_8encodingE +__ZN4node6Buffer3NewEPN2v87IsolateEm +__ZN4node6Buffer3NewEPN2v87IsolateEPKcm +__ZN4node6Buffer3NewEPN2v87IsolateEPcmPFvS4_PvES5_ +__ZN4node6Buffer3UseEPN2v87IsolateEPcj +__ZN4node4i18n22InitializeICUDirectoryEPKc +__ZN4node7smalloc17ExternalArraySizeEN2v817ExternalArrayTypeE +__ZN4node7smalloc5AllocEPN2v87IsolateENS1_6HandleINS1_6ObjectEEEmNS1_17ExternalArrayTypeE +__ZN4node7smalloc5AllocEPN2v87IsolateENS1_6HandleINS1_6ObjectEEEPcmNS1_17ExternalArrayTypeE +__ZN4node7smalloc5AllocEPN2v87IsolateENS1_6HandleINS1_6ObjectEEEmPFvPcPvES8_NS1_17ExternalArrayTypeE +__ZN4node7smalloc5AllocEPN2v87IsolateENS1_6HandleINS1_6ObjectEEEPcmPFvS7_PvES8_NS1_17ExternalArrayTypeE +__ZN4node7smalloc12AllocDisposeEPN2v87IsolateENS1_6HandleINS1_6ObjectEEE +__ZN4node7smalloc15HasExternalDataEPN2v87IsolateENS1_5LocalINS1_6ObjectEEE +_uv_fs_poll_init +_uv_fs_poll_start +_uv_fs_poll_stop +_uv_fs_poll_getpath +_uv_inet_ntop +_uv_inet_pton +_uv_queue_work +_uv_cancel +_uv_handle_size +_uv_req_size +_uv_loop_size +_uv_buf_init +_uv_err_name +_uv_strerror +_uv_ip4_addr +_uv_ip6_addr +_uv_ip4_name +_uv_ip6_name +_uv_tcp_bind +_uv_udp_bind +_uv_tcp_connect +_uv_udp_send +_uv_udp_try_send +_uv_udp_recv_start +_uv_udp_recv_stop +_uv_walk +_uv_ref +_uv_unref +_uv_has_ref +_uv_stop +_uv_now +_uv_recv_buffer_size +_uv_send_buffer_size +_uv_fs_event_getpath +_uv_fs_scandir_next +_uv_loop_configure +_uv_default_loop +_uv_loop_new +_uv_loop_close +_uv_loop_delete +_uv_version +_uv_version_string +_uv_async_init +_uv_async_send +_uv_hrtime +_uv_close +_uv_is_closing +_uv_backend_fd +_uv_backend_timeout +_uv_loop_alive +_uv_run +_uv_update_time +_uv_is_active +_uv_cwd +_uv_chdir +_uv_disable_stdio_inheritance +_uv_fileno +_uv_getrusage +_uv_dlopen +_uv_dlclose +_uv_dlsym +_uv_dlerror +_uv_fs_access +_uv_fs_chmod +_uv_fs_chown +_uv_fs_close +_uv_fs_fchmod +_uv_fs_fchown +_uv_fs_fdatasync +_uv_fs_fstat +_uv_fs_fsync +_uv_fs_ftruncate +_uv_fs_futime +_uv_fs_lstat +_uv_fs_link +_uv_fs_mkdir +_uv_fs_mkdtemp +_uv_fs_open +_uv_fs_read +_uv_fs_scandir +_uv_fs_readlink +_uv_fs_rename +_uv_fs_rmdir +_uv_fs_sendfile +_uv_fs_stat +_uv_fs_symlink +_uv_fs_unlink +_uv_fs_utime +_uv_fs_write +_uv_fs_req_cleanup +_uv_getaddrinfo +_uv_freeaddrinfo +_uv_getnameinfo +_uv_loop_init +_uv_prepare_init +_uv_prepare_start +_uv_prepare_stop +_uv_check_init +_uv_check_start +_uv_check_stop +_uv_idle_init +_uv_idle_start +_uv_idle_stop +_uv_pipe_init +_uv_pipe_bind +_uv_pipe_open +_uv_pipe_connect +_uv_pipe_getsockname +_uv_pipe_getpeername +_uv_pipe_pending_instances +_uv_pipe_pending_count +_uv_pipe_pending_type +_uv_poll_init +_uv_poll_init_socket +_uv_poll_stop +_uv_poll_start +_uv_spawn +_uv_process_kill +_uv_kill +_uv_signal_init +_uv_signal_start +_uv_signal_stop +_uv_accept +_uv_listen +_uv_shutdown +_uv_write2 +_uv_write +_uv_try_write +_uv_read_start +_uv_read_stop +_uv_is_readable +_uv_is_writable +_uv_stream_set_blocking +_uv_tcp_init +_uv_tcp_open +_uv_tcp_getsockname +_uv_tcp_getpeername +_uv_tcp_nodelay +_uv_tcp_keepalive +_uv_tcp_simultaneous_accepts +_uv_thread_create +_uv_thread_self +_uv_thread_join +_uv_thread_equal +_uv_mutex_init +_uv_mutex_destroy +_uv_mutex_lock +_uv_mutex_trylock +_uv_mutex_unlock +_uv_rwlock_init +_uv_rwlock_destroy +_uv_rwlock_rdlock +_uv_rwlock_tryrdlock +_uv_rwlock_rdunlock +_uv_rwlock_wrlock +_uv_rwlock_trywrlock +_uv_rwlock_wrunlock +_uv_once +_uv_sem_init +_uv_sem_destroy +_uv_sem_post +_uv_sem_wait +_uv_sem_trywait +_uv_cond_init +_uv_cond_destroy +_uv_cond_signal +_uv_cond_broadcast +_uv_cond_wait +_uv_cond_timedwait +_uv_barrier_init +_uv_barrier_destroy +_uv_barrier_wait +_uv_key_create +_uv_key_delete +_uv_key_get +_uv_key_set +_uv_timer_init +_uv_timer_start +_uv_timer_stop +_uv_timer_again +_uv_timer_set_repeat +_uv_timer_get_repeat +_uv_tty_init +_uv_tty_set_mode +_uv_tty_get_winsize +_uv_guess_handle +_uv_tty_reset_mode +_uv_udp_init +_uv_udp_open +_uv_udp_set_membership +_uv_udp_set_broadcast +_uv_udp_set_ttl +_uv_udp_set_multicast_ttl +_uv_udp_set_multicast_loop +_uv_udp_set_multicast_interface +_uv_udp_getsockname +_uv_setup_args +_uv_set_process_title +_uv_get_process_title +_uv_exepath +_uv_get_free_memory +_uv_get_total_memory +_uv_loadavg +_uv_resident_set_memory +_uv_uptime +_uv_cpu_info +_uv_free_cpu_info +_uv_interface_addresses +_uv_free_interface_addresses +_uv_fs_event_init +_uv_fs_event_start +_uv_fs_event_stop + + + # Entry point from the app mode loader. _ChromeAppModeStart_v4 diff --git a/chrome/app/main_dll_loader_win.cc b/chrome/app/main_dll_loader_win.cc index a0245d86567b1..75c1e081c3fc0 100644 --- a/chrome/app/main_dll_loader_win.cc +++ b/chrome/app/main_dll_loader_win.cc @@ -56,9 +56,16 @@ typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*); typedef void (*RelaunchChromeBrowserWithNewCommandLineIfNeededFunc)(); +#define BUFSIZE MAX_PATH + // Loads |module| after setting the CWD to |module|'s directory. Returns a // reference to the loaded module on success, or null on error. HMODULE LoadModuleWithDirectory(const base::FilePath& module) { + bool restore_directory = false; + TCHAR Buffer[BUFSIZE]; + if (::GetCurrentDirectoryW(BUFSIZE, Buffer)) { + restore_directory = true; + } ::SetCurrentDirectoryW(module.DirName().value().c_str()); const startup_metric_utils::PreReadOptions pre_read_options = @@ -74,8 +81,12 @@ HMODULE LoadModuleWithDirectory(const base::FilePath& module) { PreReadFile(module, pre_read_options); } - return ::LoadLibraryExW(module.value().c_str(), nullptr, + HMODULE ret = ::LoadLibraryExW(module.value().c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); + if (restore_directory) + ::SetCurrentDirectory(Buffer); + + return ret; } void RecordDidRun(const base::FilePath& dll_path) { @@ -122,7 +133,7 @@ HMODULE MainDllLoader::Load(base::FilePath* module) { } HMODULE dll = LoadModuleWithDirectory(*module); if (!dll) { - PLOG(ERROR) << "Failed to load Chrome DLL from " << module->value(); + PLOG(ERROR) << "Failed to load NW DLL from " << module->value(); return nullptr; } diff --git a/chrome/app/nibs/MainMenu.xib b/chrome/app/nibs/MainMenu.xib index 5fff8c69e61ab..7de16d66f511f 100644 --- a/chrome/app/nibs/MainMenu.xib +++ b/chrome/app/nibs/MainMenu.xib @@ -1,560 +1,792 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 1050 + 14B25 + 7702 + 1343.16 + 755.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 7702 + + + NSCustomObject + NSMenu + NSMenuItem + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + BrowserCrApplication + + + FirstResponder + + + BrowserCrApplication + + + NSFontManager + + + AMainMenu + + + + ^IDS_APP_MENU_PRODUCT_NAME + + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + 44002 + + + ^IDS_APP_MENU_PRODUCT_NAME + + + + ^IDS_ABOUT_MAC$IDS_PRODUCT_NAME + + 2147483647 + + + 40018 + + + + ^IDS_HIDE_APP_MAC$IDS_PRODUCT_NAME + h + 1048576 + 2147483647 + + + 44003 + + + + ^IDS_HIDE_OTHERS_MAC + h + 1572864 + 2147483647 + + + + + + ^IDS_SHOW_ALL_MAC + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + ^IDS_CONFIRM_TO_QUIT_OPTION + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + ^IDS_EXIT_MAC$IDS_PRODUCT_NAME + q + 1048576 + 2147483647 + + + 34031 + + + _NSAppleMenu + + + + + ^IDS_EDIT_MENU_MAC + + 2147483647 + + + submenuAction: + 36004 + + + ^IDS_EDIT_MENU_MAC + + + + ^IDS_EDIT_UNDO_MAC + z + 1048576 + 2147483647 + + + 50144 + + + + ^IDS_EDIT_REDO_MAC + Z + 1179648 + 2147483647 + + + 50145 + + + + YES + YES + + + 2147483647 + + + + + + ^IDS_CUT_MAC + x + 1048576 + 2147483647 + + + 50141 + + + + ^IDS_COPY_MAC + c + 1048576 + 2147483647 + + + 50140 + + + + ^IDS_PASTE_MAC + v + 1048576 + 2147483647 + + + 50142 + + + + ^IDS_PASTE_MATCH_STYLE_MAC + V + 1048576 + 2147483647 + + + 50147 + + + + YES + ^IDS_PASTE_MATCH_STYLE_MAC + V + 1572864 + 2147483647 + + + + + + ^IDS_EDIT_DELETE_MAC + + 2147483647 + + + 50143 + + + + ^IDS_EDIT_SELECT_ALL_MAC + a + 1048576 + 2147483647 + + + 50146 + + + + + + + ^IDS_WINDOW_MENU_MAC + + 2147483647 + + + submenuAction: + 34045 + + + ^IDS_WINDOW_MENU_MAC + + + + ^IDS_MINIMIZE_WINDOW_MAC + m + 1048576 + 2147483647 + + + 34046 + + + + ^IDS_ZOOM_WINDOW_MAC + + 2147483647 + + + 34047 + + + + ^IDS_ALL_WINDOWS_FRONT_MAC + + 2147483647 + + + 34048 + + + _NSWindowsMenu + + + + _NSMainMenu + + + ChromeUILocalizer + + + AppController + + + + NO + + + + delegate + + + + 485 + + + + terminate: + + + + 647 + + + + hide: + + + + 369 + + + + hideOtherApplications: + + + + 370 + + + + unhideAllApplications: + + + + 372 + + + + undo: + + + + 223 + + + + redo: + + + + 231 + + + + cut: + + + + 228 + + + + copy: + + + + 224 + + + + paste: + + + + 226 + + + + pasteAndMatchStyle: + + + + 696 + + + + pasteAndMatchStyle: + + + + 697 + + + + delete: + + + + 235 + + + + selectAll: + + + + 232 + + + + performMiniaturize: + + + + 37 + + + + performZoom: + + + + 240 + + + + arrangeInFront: + + + + 39 + + + + orderFrontStandardAboutPanel: + + + + 644 + + + + toggleConfirmToQuit: + + + + 688 + + + + owner_ + + + + 642 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 373 + + + + + 29 + + + + + + + + Main Menu + + + 56 + + + + + + + + 57 + + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 145 + + + + + 150 + + + + + 149 + + + + + 687 + + + + + 686 + + + + + 136 + + + + + 217 + + + + + + + + 205 + + + + + + + + + + + + + + + + + 207 + + + + + 215 + + + + + 206 + + + + + 199 + + + + + 197 + + + + + 203 + + + + + 658 + + + + + 689 + + + + + 202 + + + + + 198 + + + + + 19 + + + + + + + + 24 + + + + + + + + + + 23 + + + + + 239 + + + + + 5 + + + + + 641 + + + + + 483 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + + + + 0 + IBCocoaFramework + NO + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + + com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 + + + YES + 3 + + {12, 12} + {10, 2} + + + + diff --git a/chrome/app/nw.dll.manifest b/chrome/app/nw.dll.manifest new file mode 100644 index 0000000000000..d068c1366cec5 --- /dev/null +++ b/chrome/app/nw.dll.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/chrome/app/nw.exe.manifest b/chrome/app/nw.exe.manifest new file mode 100644 index 0000000000000..d36f084b65946 --- /dev/null +++ b/chrome/app/nw.exe.manifest @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/chrome/app/theme/chromium/BRANDING b/chrome/app/theme/chromium/BRANDING index 6a6bc265f7eeb..0b950e39cb0be 100644 --- a/chrome/app/theme/chromium/BRANDING +++ b/chrome/app/theme/chromium/BRANDING @@ -1,9 +1,9 @@ -COMPANY_FULLNAME=The Chromium Authors -COMPANY_SHORTNAME=The Chromium Authors -PRODUCT_FULLNAME=Chromium -PRODUCT_SHORTNAME=Chromium -PRODUCT_INSTALLER_FULLNAME=Chromium Installer -PRODUCT_INSTALLER_SHORTNAME=Chromium Installer +COMPANY_FULLNAME=The NWJS Community +COMPANY_SHORTNAME=nwjs.io +PRODUCT_FULLNAME=nwjs +PRODUCT_SHORTNAME=nwjs +PRODUCT_INSTALLER_FULLNAME=NWJS Installer +PRODUCT_INSTALLER_SHORTNAME=NWJS Installer COPYRIGHT=Copyright 2016 The Chromium Authors. All rights reserved. -MAC_BUNDLE_ID=org.chromium.Chromium -MAC_CREATOR_CODE=Cr24 +MAC_BUNDLE_ID=io.nwjs.nwjs +MAC_CREATOR_CODE=NWJS \ No newline at end of file diff --git a/chrome/app/theme/chromium/mac/app.icns b/chrome/app/theme/chromium/mac/app.icns index 54ee532d7934d..1a03ae29c16fa 100644 Binary files a/chrome/app/theme/chromium/mac/app.icns and b/chrome/app/theme/chromium/mac/app.icns differ diff --git a/chrome/app/theme/chromium/mac/document.icns b/chrome/app/theme/chromium/mac/document.icns index 73fd43dfb87b0..1a03ae29c16fa 100644 Binary files a/chrome/app/theme/chromium/mac/document.icns and b/chrome/app/theme/chromium/mac/document.icns differ diff --git a/chrome/app/theme/chromium/product_logo_128.png b/chrome/app/theme/chromium/product_logo_128.png index 9f88fb10a2b4a..7e63ba7f8c2b1 100644 Binary files a/chrome/app/theme/chromium/product_logo_128.png and b/chrome/app/theme/chromium/product_logo_128.png differ diff --git a/chrome/app/theme/chromium/product_logo_22.png b/chrome/app/theme/chromium/product_logo_22.png index 33c2256e6d042..1207110f2c59a 100644 Binary files a/chrome/app/theme/chromium/product_logo_22.png and b/chrome/app/theme/chromium/product_logo_22.png differ diff --git a/chrome/app/theme/chromium/product_logo_22_mono.png b/chrome/app/theme/chromium/product_logo_22_mono.png index dc970053fa029..1207110f2c59a 100644 Binary files a/chrome/app/theme/chromium/product_logo_22_mono.png and b/chrome/app/theme/chromium/product_logo_22_mono.png differ diff --git a/chrome/app/theme/chromium/product_logo_24.png b/chrome/app/theme/chromium/product_logo_24.png index e6d9e56fe8bb3..543bff73b3ed1 100644 Binary files a/chrome/app/theme/chromium/product_logo_24.png and b/chrome/app/theme/chromium/product_logo_24.png differ diff --git a/chrome/app/theme/chromium/product_logo_256.png b/chrome/app/theme/chromium/product_logo_256.png index 96ee2307fc7d3..00664f9ecac42 100644 Binary files a/chrome/app/theme/chromium/product_logo_256.png and b/chrome/app/theme/chromium/product_logo_256.png differ diff --git a/chrome/app/theme/chromium/product_logo_32.xpm b/chrome/app/theme/chromium/product_logo_32.xpm new file mode 100644 index 0000000000000..71ab1b52f1637 --- /dev/null +++ b/chrome/app/theme/chromium/product_logo_32.xpm @@ -0,0 +1,563 @@ +/* XPM */ +static char * nwjs_logo_32_xpm[] = { +"32 32 528 2", +" c None", +". c #C2C2C7", +"+ c #B0B0B4", +"@ c #B8B8BC", +"# c #5F5F69", +"$ c #5E5E67", +"% c #B7B7BA", +"& c #B1B1B5", +"* c #B2B2B8", +"= c #C2C2C6", +"- c #5E5E66", +"; c #1A1D2A", +"> c #222634", +", c #222835", +"' c #1A1D29", +") c #5C5C64", +"! c #C1C1C3", +"~ c #B2B3B7", +"{ c #B1B2B9", +"] c #BEBFC2", +"^ c #909094", +"/ c #1B1C28", +"( c #2A303D", +"_ c #3A4050", +": c #444B5B", +"< c #444B5A", +"[ c #3A4151", +"} c #1A1B28", +"| c #8A8A90", +"1 c #BFBFC2", +"2 c #B1B1B9", +"3 c #BEBEC1", +"4 c #AEAEB3", +"5 c #32323B", +"6 c #1F2431", +"7 c #343A49", +"8 c #474D5E", +"9 c #515869", +"0 c #545B6C", +"a c #545C6D", +"b c #525869", +"c c #484F60", +"d c #343B4B", +"e c #1F2430", +"f c #2E2F38", +"g c #A9A9AF", +"h c #BDBDC0", +"i c #BABAC0", +"j c #BCBCC0", +"k c #57575E", +"l c #10141E", +"m c #282E3B", +"n c #3D4352", +"o c #4C5364", +"p c #565D6E", +"q c #5C6376", +"r c #61687B", +"s c #60677B", +"t c #5D6477", +"u c #585E6F", +"v c #4E5566", +"w c #3F4655", +"x c #292F3D", +"y c #525259", +"z c #BCBDC2", +"A c #A7A7AF", +"B c #C2C2C4", +"C c #85858C", +"D c #161820", +"E c #1C222D", +"F c #2F3542", +"G c #3E4553", +"H c #49505F", +"I c #555B6D", +"J c #5F6579", +"K c #686F83", +"L c #6D748A", +"M c #6C7287", +"N c #697085", +"O c #61677B", +"P c #565D6F", +"Q c #4B5262", +"R c #3F4654", +"S c #303643", +"T c #1D232F", +"U c #16171F", +"V c #7B7B81", +"W c #BEBEC2", +"X c #A6A7AE", +"Y c #9B9BA0", +"Z c #A8A8AE", +"` c #2F2F36", +" . c #11161F", +".. c #222934", +"+. c #303641", +"@. c #373D4A", +"#. c #414755", +"$. c #4E5565", +"%. c #5D6475", +"&. c #697084", +"*. c #747B90", +"=. c #757C92", +"-. c #777E94", +";. c #747C91", +">. c #6B7287", +",. c #5F6578", +"'. c #515868", +"). c #424957", +"!. c #383E4A", +"~. c #313642", +"{. c #232934", +"]. c #111520", +"^. c #2B2C33", +"/. c #A2A2A7", +"(. c #75757D", +"_. c #ABABB0", +":. c #14151D", +"<. c #1D232D", +"[. c #2B303B", +"}. c #313742", +"|. c #323844", +"1. c #353B48", +"2. c #404654", +"3. c #4E5464", +"4. c #6E768A", +"5. c #7D859A", +"6. c #7C849A", +"7. c #7E869C", +"8. c #7E879C", +"9. c #70778B", +"0. c #5F6779", +"a. c #505667", +"b. c #424856", +"c. c #383D4A", +"d. c #2C323F", +"e. c #11141C", +"f. c #A8A9AD", +"g. c #696970", +"h. c #84858B", +"i. c #5A5A61", +"j. c #1C212C", +"k. c #30343F", +"l. c #333844", +"m. c #333945", +"n. c #353B47", +"o. c #393F4B", +"p. c #404553", +"q. c #484F5D", +"r. c #5B6275", +"s. c #6E778B", +"t. c #80879D", +"u. c #80889E", +"v. c #71798E", +"w. c #5D6577", +"x. c #535A6C", +"y. c #4A515F", +"z. c #3A404C", +"A. c #363B47", +"B. c #343741", +"C. c #313A4A", +"D. c #2E3847", +"E. c #212530", +"F. c #62636A", +"G. c #87888E", +"H. c #8E8E95", +"I. c #3E3F47", +"J. c #2A2F3A", +"K. c #313640", +"L. c #333843", +"M. c #3A3F4A", +"N. c #3E4551", +"O. c #464B59", +"P. c #4C5161", +"Q. c #52596A", +"R. c #53596B", +"S. c #565F70", +"T. c #4D5363", +"U. c #474D5B", +"V. c #3E4756", +"W. c #3B3E49", +"X. c #393A46", +"Y. c #1E63B5", +"Z. c #1D4C87", +"`. c #2E3644", +" + c #2B313C", +".+ c #505158", +"++ c #919197", +"@+ c #939398", +"#+ c #393A41", +"$+ c #2A2F39", +"%+ c #2F343E", +"&+ c #303440", +"*+ c #333742", +"=+ c #393E4A", +"-+ c #3D4350", +";+ c #3B414E", +">+ c #424857", +",+ c #414654", +"'+ c #454C5A", +")+ c #434B5B", +"!+ c #41454F", +"~+ c #3E3F48", +"{+ c #33557F", +"]+ c #1F70C2", +"^+ c #0B88FF", +"/+ c #1A4373", +"(+ c #2B2A2F", +"_+ c #2E333D", +":+ c #2B303A", +"<+ c #4C4D54", +"[+ c #94959C", +"}+ c #95959B", +"|+ c #393A42", +"1+ c #292E38", +"2+ c #2F333D", +"3+ c #30353F", +"4+ c #323742", +"5+ c #353A45", +"6+ c #373C48", +"7+ c #3A404D", +"8+ c #3C4250", +"9+ c #3D4250", +"0+ c #3C414E", +"a+ c #3D424F", +"b+ c #363D4D", +"c+ c #275A96", +"d+ c #0F81F7", +"e+ c #0B85FB", +"f+ c #0B71E9", +"g+ c #1A2536", +"h+ c #282E3A", +"i+ c #2F343D", +"j+ c #2F333E", +"k+ c #2A2E39", +"l+ c #4D4E54", +"m+ c #96969D", +"n+ c #96969C", +"o+ c #393B42", +"p+ c #292D37", +"q+ c #2D323C", +"r+ c #333944", +"s+ c #353945", +"t+ c #353A46", +"u+ c #353A48", +"v+ c #3A3536", +"w+ c #30476C", +"x+ c #1860C3", +"y+ c #0D76F3", +"z+ c #0981FF", +"A+ c #0A6FF1", +"B+ c #0B49AA", +"C+ c #1B1F29", +"D+ c #2C313E", +"E+ c #30353D", +"F+ c #2E323D", +"G+ c #2A2F38", +"H+ c #98989E", +"I+ c #96969B", +"J+ c #3B3C43", +"K+ c #282D36", +"L+ c #2D313B", +"M+ c #2E333C", +"N+ c #30343D", +"O+ c #2F353F", +"P+ c #2C313C", +"Q+ c #313641", +"R+ c #2D333F", +"S+ c #545358", +"T+ c #2F7BC6", +"U+ c #1A6CDE", +"V+ c #0A78FA", +"W+ c #0A67EA", +"X+ c #0951DF", +"Y+ c #082D79", +"Z+ c #1C1E23", +"`+ c #2E3441", +" @ c #30343E", +".@ c #2E313B", +"+@ c #4E4F56", +"@@ c #3C3D44", +"#@ c #282D37", +"$@ c #2B313B", +"%@ c #252A33", +"&@ c #272C35", +"*@ c #292F39", +"=@ c #2F333F", +"-@ c #55575E", +";@ c #818183", +">@ c #9297A1", +",@ c #898988", +"'@ c #0540C3", +")@ c #0840CF", +"!@ c #0C1E46", +"~@ c #1A1F2A", +"{@ c #262B34", +"]@ c #272B35", +"^@ c #292E37", +"/@ c #2C313A", +"(@ c #4F5156", +"_@ c #97979E", +":@ c #292D36", +"<@ c #2B3038", +"[@ c #2B3039", +"}@ c #2B313A", +"|@ c #2A3039", +"1@ c #252B35", +"2@ c #67696D", +"3@ c #A2A2A2", +"4@ c #A3A3A5", +"5@ c #868B92", +"6@ c #818793", +"7@ c #0433BC", +"8@ c #0F1934", +"9@ c #272D37", +"0@ c #2C3039", +"a@ c #2C3038", +"b@ c #2A2E37", +"c@ c #4F5056", +"d@ c #96979D", +"e@ c #939399", +"f@ c #3B3D43", +"g@ c #282C36", +"h@ c #2B2F38", +"i@ c #2C2F39", +"j@ c #2B2F3A", +"k@ c #7E7F82", +"l@ c #A9A9AA", +"m@ c #A7A7A8", +"n@ c #8A8A8B", +"o@ c #5B5B5D", +"p@ c #232C48", +"q@ c #11161E", +"r@ c #2A313D", +"s@ c #292E3A", +"t@ c #2D323D", +"u@ c #282E36", +"v@ c #4D4E55", +"w@ c #95959C", +"x@ c #909096", +"y@ c #2B2F37", +"z@ c #373B44", +"A@ c #969696", +"B@ c #A5A5A6", +"C@ c #8E8E8F", +"D@ c #69696D", +"E@ c #1F222C", +"F@ c #0F1421", +"G@ c #1E232F", +"H@ c #2D323E", +"I@ c #272D38", +"J@ c #2C303A", +"K@ c #2A2F37", +"L@ c #4E4F55", +"M@ c #93939A", +"N@ c #8E8E93", +"O@ c #3B3D44", +"P@ c #232831", +"Q@ c #53565B", +"R@ c #9F9E9D", +"S@ c #8B8B8B", +"T@ c #45474C", +"U@ c #161822", +"V@ c #060C18", +"W@ c #1F2531", +"X@ c #2C313F", +"Y@ c #272D39", +"Z@ c #262C36", +"`@ c #29303B", +" # c #2A2E38", +".# c #8E8F96", +"+# c #3D3E46", +"@# c #262A33", +"## c #696A6D", +"$# c #757678", +"%# c #33373E", +"&# c #060B18", +"*# c #161C29", +"=# c #29303D", +"-# c #272F3B", +";# c #212833", +"># c #242A36", +",# c #2A303E", +"'# c #2B303E", +")# c #2B323F", +"!# c #282F3B", +"~# c #282E38", +"{# c #4C4E55", +"]# c #88888F", +"^# c #7E7E85", +"/# c #43444C", +"(# c #262B35", +"_# c #2F333B", +":# c #4C4E51", +"<# c #21272F", +"[# c #141924", +"}# c #1D222D", +"|# c #292E39", +"1# c #2B313F", +"2# c #262D38", +"3# c #2B313E", +"4# c #2B303C", +"5# c #292F38", +"6# c #52535A", +"7# c #808087", +"8# c #6F7076", +"9# c #5D5D66", +"0# c #252B34", +"a# c #1E222D", +"b# c #242832", +"c# c #272E37", +"d# c #2A303C", +"e# c #2B313D", +"f# c #2C3340", +"g# c #272E3B", +"h# c #2B3340", +"i# c #68696F", +"j# c #707178", +"k# c #9F9FA4", +"l# c #2A2D37", +"m# c #2B323B", +"n# c #2D333E", +"o# c #2F3440", +"p# c #2C323D", +"q# c #2B323D", +"r# c #2C313D", +"s# c #2B303D", +"t# c #282D3A", +"u# c #282D3B", +"v# c #2C323C", +"w# c #2E343E", +"x# c #2F3441", +"y# c #2F3540", +"z# c #2A303A", +"A# c #9B9CA1", +"B# c #4E4E56", +"C# c #72737B", +"D# c #A2A3A7", +"E# c #4C4E57", +"F# c #262C35", +"G# c #303642", +"H# c #313743", +"I# c #2F3642", +"J# c #2F3644", +"K# c #2F3643", +"L# c #2F3543", +"M# c #2D3341", +"N# c #2D3340", +"O# c #303743", +"P# c #2F3640", +"Q# c #50525A", +"R# c #9F9FA5", +"S# c #6A6A73", +"T# c #62626C", +"U# c #9F9FA7", +"V# c #8A8A92", +"W# c #363942", +"X# c #232932", +"Y# c #2F343F", +"Z# c #313744", +"`# c #343C4A", +" $ c #363F52", +".$ c #394258", +"+$ c #3A455D", +"@$ c #39435B", +"#$ c #394358", +"$$ c #373F52", +"%$ c #343B4A", +"&$ c #323744", +"*$ c #222730", +"=$ c #3C3F47", +"-$ c #909198", +";$ c #9D9DA6", +">$ c #61616C", +",$ c #7D7E88", +"'$ c #ACACB5", +")$ c #717179", +"!$ c #2A2E36", +"~$ c #29303A", +"{$ c #323949", +"]$ c #353D4F", +"^$ c #3A4256", +"/$ c #394256", +"($ c #373F53", +"_$ c #353D4E", +":$ c #333A49", +"<$ c #272B33", +"[$ c #75767D", +"}$ c #A8A8B0", +"|$ c #787984", +"1$ c #8B8B95", +"2$ c #A1A1A9", +"3$ c #575861", +"4$ c #1F252E", +"5$ c #303847", +"6$ c #313948", +"7$ c #313846", +"8$ c #303742", +"9$ c #1F252F", +"0$ c #5B5C64", +"a$ c #A6A6AD", +"b$ c #8A8A94", +"c$ c #6A6A75", +"d$ c #93949D", +"e$ c #8F8F98", +"f$ c #3E414A", +"g$ c #242932", +"h$ c #2E333E", +"i$ c #2E323E", +"j$ c #2D333D", +"k$ c #3C3E47", +"l$ c #8F8F97", +"m$ c #90909A", +"n$ c #666672", +"o$ c #6A6B76", +"p$ c #73747D", +"q$ c #292D35", +"r$ c #75767E", +"s$ c #92929B", +"t$ c #696A75", +"u$ c #686974", +"v$ c #82828D", +"w$ c #6B6C76", +"x$ c #6A6C75", +"y$ c #81808B", +"z$ c #666773", +"A$ c #474855", +"B$ c #5E5F6A", +"C$ c #5F606C", +" . . ", +" + @ # $ % & ", +" * = - ; > , ' ) ! ~ ", +" { ] ^ / ( _ : < [ ( } | 1 2 ", +" 3 4 5 6 7 8 9 0 a b c d e f g h ", +" i j k l m n o p q r s t u v w x l y @ z ", +" A B C D E F G H I J K L M N O P Q R S T U V W X ", +" Y Z ` ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.Y ", +" (._.:.<.[.}.|.1.2.3.q 4.5.6.7.8.9.0.a.b.c.|.}.d.<.e.f.g. ", +" h.i.j.k.l.m.n.o.p.q.9 r.s.t.u.v.w.x.y.#.z.A.B.C.D.E.F.G. ", +" H.I.J.K.+.L.A.M.N.O.P.Q.P R.b S.R.T.U.V.W.X.Y.Z.`. +.+++ ", +" @+#+$+%+&+*+A.=+-+;+2.>+,+'+'+b.)+!+~+{+]+^+/+(+_+:+<+[+ ", +" }+|+1+2+3+4+5+6+M.7+n.c.8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+ ", +" n+o+p+q+i+K.4+r+s+l.~.t+u+v+w+x+y+z+A+B+C+D+K.E+F+G+l+H+ ", +" I+J+K+L+M+N+O+k.%+P+Q+R+S+T+U+V+W+X+Y+Z+`+k. @2+.@1++@H+ ", +" }+@@#@$@:+p+%@&@#@*@=@-@;@>@,@'@)@!@~@{@]@%@^@:+/@G+(@_@ ", +" }+@@:@<@[@[@}@$+|@1@2@3@4@5@6@7@8@K+{@9@$+[.:+0@a@b@c@d@ ", +" e@f@g@h@h@i@j@ +&+k@l@m@n@o@p@q@r@s@:+t@ +j@[@h@h@u@v@w@ ", +" x@@@]@h@y@<@[@z@A@B@C@D@E@F@G@t@H@I@D+ +J@$+h@K@h@:@L@M@ ", +" N@O@{@p+h@P@Q@R@S@T@U@V@W@X@X@h+Y@Z@`@[.j@G+h@ #^@&@+@.# ", +" G.+#@##@}@##$#%#&#*#=#X@-#;#>#,#'#)#!# +J.:+$+^@~#]@{#]# ", +" ^#/#(#_#:#<#[#}#|#D+D+1#( 2#2#3#1#D+D+4#$@J.5# #^@]@6#7# ", +" 8#9#0#|#a#b#c#d#e#e#d.d.f#m g#h#d.3#e#e#[.|@:+[.P+$+i#j# ", +" 6#k#l#m#n#o#n#p#q#r#e#s#3#t#u#e#s#r#v#e#p#w#x#y#z#h@A#B# ", +" C#D#E#F#}.G#S H#I#J#K#L#M#N#F L#J#S O#H#G#P#b#Q#R#S# ", +" T#U#V#W#X#%+Y#Z#`# $.$+$@$#$$$%$&$Y#%+*$=$-$;$>$ ", +" ,$'$)$!$~$I#{$]$$$^$/$($_$:$L#*@<$[$}$|$ ", +" 1$2$3$4$+.K#5$6$6$7$K#8$9$0$a$b$ ", +" c$d$e$f$g$h$i$H@j$P@k$l$m$n$ ", +" o$e$p$q$/@/@!$r$s$t$ ", +" u$v$w$x$y$z$ ", +" A$B$C$ "}; diff --git a/chrome/app/theme/chromium/product_logo_64.png b/chrome/app/theme/chromium/product_logo_64.png index c8f9c190c8e97..8358e5d2e0a32 100644 Binary files a/chrome/app/theme/chromium/product_logo_64.png and b/chrome/app/theme/chromium/product_logo_64.png differ diff --git a/chrome/app/theme/chromium/win/chromium.ico b/chrome/app/theme/chromium/win/chromium.ico index c2e434a028b53..173a8f4e8f8aa 100644 Binary files a/chrome/app/theme/chromium/win/chromium.ico and b/chrome/app/theme/chromium/win/chromium.ico differ diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 6f35be98a682b..17fd220eb7ccc 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -554,7 +554,6 @@ - diff --git a/chrome/app/version_assembly/version_assembly_manifest.template b/chrome/app/version_assembly/version_assembly_manifest.template index 4ed10ad82c995..1b2f3685b1a0d 100644 --- a/chrome/app/version_assembly/version_assembly_manifest.template +++ b/chrome/app/version_assembly/version_assembly_manifest.template @@ -4,6 +4,6 @@ name='@MAJOR@.@MINOR@.@BUILD@.@PATCH@' version='@MAJOR@.@MINOR@.@BUILD@.@PATCH@' type='win32'/> - + - \ No newline at end of file + diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index f482d56c7a8eb..2a6174f43b232 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -104,6 +104,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" +#include "content/nw/src/nw_content.h" + using apps::AppShimHandler; using apps::ExtensionAppShimHandler; using base::UserMetricsAction; @@ -145,7 +147,7 @@ } Browser* browser = chrome::GetLastActiveBrowser(); - CHECK(browser); + //CHECK(browser); return browser; } @@ -389,7 +391,7 @@ - (void)awakeFromNib { [self initMenuState]; // Initialize the Profile menu. - [self initProfileMenu]; + //[self initProfileMenu]; } - (void)unregisterEventHandlers { @@ -495,6 +497,9 @@ - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)app { return NSTerminateNow; } + if (!AppWindowRegistryUtil::CloseAllAppWindows(true)) + return NSTerminateCancel; + // Check if the preference is turned on. const PrefService* prefs = g_browser_process->local_state(); if (!prefs->GetBoolean(prefs::kConfirmToQuitEnabled)) { @@ -677,7 +682,11 @@ - (void)setUpdateCheckInterval { - (void)openStartupUrls { DCHECK(startupComplete_); - [self openUrlsReplacingNTP:startupUrls_]; + if (startupUrls_.size()) { + base::CommandLine::ForCurrentProcess()->AppendArg(startupUrls_[0].spec()); + base::CommandLine::ForCurrentProcess()->FixOrigArgv4Finder(startupUrls_[0].spec()); + } + //[self openUrlsReplacingNTP:startupUrls_]; startupUrls_.clear(); } @@ -740,7 +749,7 @@ - (void)applicationDidFinishLaunching:(NSNotification*)notify { // If enabled, keep Chrome alive when apps are open instead of quitting all // apps. - quitWithAppsController_ = new QuitWithAppsController(); + // quitWithAppsController_ = new QuitWithAppsController(); // Dynamically update shortcuts for "Close Window" and "Close Tab" menu items. [[closeTabMenuItem_ menu] setDelegate:self]; @@ -1169,6 +1178,8 @@ - (void)commandDispatchUsingKeyModifiers:(id)sender { // browser windows. - (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication hasVisibleWindows:(BOOL)hasVisibleWindows { + return nw::ApplicationShouldHandleReopenHook(hasVisibleWindows) ? YES : NO; +#if 0 // If the browser is currently trying to quit, don't do anything and return NO // to prevent AppKit from doing anything. // TODO(rohitrao): Remove this code when http://crbug.com/40861 is resolved. @@ -1258,6 +1269,7 @@ - (BOOL)applicationShouldHandleReopen:(NSApplication*)theApplication // We've handled the reopen event, so return NO to tell AppKit not // to do anything. return NO; +#endif } - (void)initMenuState { @@ -1367,6 +1379,9 @@ - (void)openUrls:(const std::vector&)urls { return; } + nw::OSXOpenURLsHook(urls); + +#if 0 Browser* browser = chrome::GetLastActiveBrowser(); // if no browser window exists then create one with no tabs to be filled in if (!browser) { @@ -1379,6 +1394,7 @@ - (void)openUrls:(const std::vector&)urls { chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; StartupBrowserCreatorImpl launch(base::FilePath(), dummy, first_run); launch.OpenURLsInBrowser(browser, false, urls); +#endif } - (void)getUrl:(NSAppleEventDescriptor*)event @@ -1462,6 +1478,7 @@ - (NSMenu*)applicationDockMenu:(NSApplication*)sender { if (profilesAdded) [dockMenu addItem:[NSMenuItem separatorItem]]; +#if 0 NSString* titleStr = l10n_util::GetNSStringWithFixup(IDS_NEW_WINDOW_MAC); base::scoped_nsobject item( [[NSMenuItem alloc] initWithTitle:titleStr @@ -1486,6 +1503,7 @@ - (NSMenu*)applicationDockMenu:(NSApplication*)sender { [item setEnabled:[self validateUserInterfaceItem:item]]; [dockMenu addItem:item]; } +#endif // TODO(rickcam): Mock out BackgroundApplicationListModel, then add unit // tests which use the mock in place of the profile-initialized model. diff --git a/chrome/browser/app_icon_win.cc b/chrome/browser/app_icon_win.cc index 9c3e7d69dca68..b50bb4368b341 100644 --- a/chrome/browser/app_icon_win.cc +++ b/chrome/browser/app_icon_win.cc @@ -4,6 +4,8 @@ #include "chrome/browser/app_icon_win.h" +#include "content/nw/src/nw_content.h" + #include "chrome/app/chrome_dll_resource.h" #include "chrome/common/chrome_constants.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -30,6 +32,9 @@ int GetAppIconResourceId() { } // namespace HICON GetAppIcon() { + HICON ret = nw::GetWindowHIcon(); + if (ret) + return ret; // TODO(mgiuca): Use GetAppIconImageFamily/CreateExact instead of LoadIcon, to // get correct scaling. (See http://crbug.com/551256) const int icon_id = GetAppIconResourceId(); @@ -39,6 +44,9 @@ HICON GetAppIcon() { } HICON GetSmallAppIcon() { + HICON ret = nw::GetAppHIcon(); + if (ret) + return ret; // TODO(mgiuca): Use GetAppIconImageFamily/CreateExact instead of LoadIcon, to // get correct scaling. (See http://crbug.com/551256) const int icon_id = GetAppIconResourceId(); diff --git a/chrome/browser/apps/app_shim/app_shim_handler_mac.cc b/chrome/browser/apps/app_shim/app_shim_handler_mac.cc index 25bb125592742..4cb155d919cca 100644 --- a/chrome/browser/apps/app_shim/app_shim_handler_mac.cc +++ b/chrome/browser/apps/app_shim/app_shim_handler_mac.cc @@ -19,13 +19,15 @@ #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" +#include "content/nw/src/nw_content.h" + namespace apps { namespace { void TerminateIfNoAppWindows() { bool app_windows_left = - AppWindowRegistryUtil::IsAppWindowVisibleInAnyProfile(0); + AppWindowRegistryUtil::IsAppWindowVisibleInAnyProfile(0, false); if (!app_windows_left && !AppListService::Get()->IsAppListVisible()) { chrome::AttemptExit(); } @@ -61,7 +63,8 @@ class AppShimHandlerRegistry : public content::NotificationObserver { } void MaybeTerminate() { - if (!browser_session_running_) { + if (!nw::IsReloadingApp()) { + //NW: #4164. browser_session_running_ never set to false // Post this to give AppWindows a chance to remove themselves from the // registry. base::MessageLoop::current()->PostTask( diff --git a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc index 61269fe242fb0..82624a4e7f700 100644 --- a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc +++ b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.cc @@ -322,7 +322,7 @@ const Extension* ExtensionAppShimHandler::MaybeGetAppForBrowser( } // static -void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window) { +void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window, bool user_force) { ExtensionAppShimHandler* handler = GetInstance(); Host* host = handler->FindHost( Profile::FromBrowserContext(app_window->browser_context()), @@ -333,7 +333,7 @@ void ExtensionAppShimHandler::QuitAppForWindow(AppWindow* app_window) { // App shims might be disabled or the shim is still starting up. AppWindowRegistry::Get( Profile::FromBrowserContext(app_window->browser_context())) - ->CloseAllAppWindowsForApp(app_window->extension_id()); + ->CloseAllAppWindowsForApp(app_window->extension_id(), user_force); } } @@ -638,7 +638,8 @@ void ExtensionAppShimHandler::OnShimQuit(Host* host) { const AppWindowList windows = delegate_->GetWindows(profile, app_id); for (AppWindowRegistry::const_iterator it = windows.begin(); it != windows.end(); ++it) { - (*it)->GetBaseWindow()->Close(); + if ((*it)->NWCanClose()) + (*it)->GetBaseWindow()->Close(); } } // Once the last window closes, flow will end up in OnAppDeactivated via diff --git a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h index 2f4362893e381..eb42371b8dc45 100644 --- a/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h +++ b/chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h @@ -93,7 +93,7 @@ class ExtensionAppShimHandler : public AppShimHandler, static const extensions::Extension* MaybeGetAppForBrowser(Browser* browser); - static void QuitAppForWindow(extensions::AppWindow* app_window); + static void QuitAppForWindow(extensions::AppWindow* app_window, bool user_force = false); static void QuitHostedAppForWindow(Profile* profile, const std::string& app_id); diff --git a/chrome/browser/apps/app_window_registry_util.cc b/chrome/browser/apps/app_window_registry_util.cc index adce2d235e526..a8b9e513126d4 100644 --- a/chrome/browser/apps/app_window_registry_util.cc +++ b/chrome/browser/apps/app_window_registry_util.cc @@ -43,7 +43,7 @@ AppWindow* AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( // static bool AppWindowRegistryUtil::IsAppWindowVisibleInAnyProfile( - int window_type_mask) { + int window_type_mask, bool check_visible) { std::vector profiles = g_browser_process->profile_manager()->GetLoadedProfiles(); for (std::vector::const_iterator i = profiles.begin(); @@ -59,7 +59,7 @@ bool AppWindowRegistryUtil::IsAppWindowVisibleInAnyProfile( continue; for (const AppWindow* window : app_windows) { - if (!window->is_hidden() && + if ((!window->is_hidden() || !check_visible )&& (window_type_mask == 0 || (window->window_type() & window_type_mask))) return true; @@ -70,7 +70,7 @@ bool AppWindowRegistryUtil::IsAppWindowVisibleInAnyProfile( } // static -void AppWindowRegistryUtil::CloseAllAppWindows() { +bool AppWindowRegistryUtil::CloseAllAppWindows(bool user_force) { std::vector profiles = g_browser_process->profile_manager()->GetLoadedProfiles(); for (std::vector::const_iterator i = profiles.begin(); @@ -86,8 +86,13 @@ void AppWindowRegistryUtil::CloseAllAppWindows() { AppWindowList window_list_copy(registry->app_windows()); for (const auto& window : window_list_copy) { // Ensure window is still valid. - if (ContainsValue(registry->app_windows(), window)) - window->GetBaseWindow()->Close(); + if (ContainsValue(registry->app_windows(), window)) { + if (window->NWCanClose(user_force)) + window->GetBaseWindow()->Close(); + else + return false; + } } } + return true; } diff --git a/chrome/browser/apps/app_window_registry_util.h b/chrome/browser/apps/app_window_registry_util.h index 8fd6b358cc8ca..5dcf02ecd612d 100644 --- a/chrome/browser/apps/app_window_registry_util.h +++ b/chrome/browser/apps/app_window_registry_util.h @@ -21,10 +21,10 @@ class AppWindowRegistryUtil { // Returns true if the number of visible app windows registered across all // browser contexts is non-zero. |window_type_mask| is a bitwise OR filter of // AppWindow::WindowType, or 0 for any window type. - static bool IsAppWindowVisibleInAnyProfile(int window_type_mask); + static bool IsAppWindowVisibleInAnyProfile(int window_type_mask, bool check_visible = true); // Close all app windows in all profiles. - static void CloseAllAppWindows(); + static bool CloseAllAppWindows(bool user_force = false); }; #endif // CHROME_BROWSER_APPS_APP_WINDOW_REGISTRY_UTIL_H_ diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 5d345cbe9b781..73d7defbc86e1 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc @@ -2269,6 +2269,14 @@ IN_PROC_BROWSER_TEST_P(WebViewTest, ClearData) { << message_; } +// Regression test for https://crbug.com/615429. +IN_PROC_BROWSER_TEST_P(WebViewTest, ClearDataTwice) { + ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. + ASSERT_TRUE(RunPlatformAppTestWithArg("platform_apps/web_view/common", + "cleardata_twice")) + << message_; +} + #if defined(OS_WIN) // Test is disabled on Windows because it fails often (~9% time) // http://crbug.com/489088 diff --git a/chrome/browser/background/background_application_list_model.cc b/chrome/browser/background/background_application_list_model.cc index 60cd674584768..5576682ff8a8c 100644 --- a/chrome/browser/background/background_application_list_model.cc +++ b/chrome/browser/background/background_application_list_model.cc @@ -264,8 +264,10 @@ bool BackgroundApplicationListModel::IsBackgroundApp( // manifest. // Not a background app if we don't have the background permission. + // NWJS: nwjs_default_app is listed as background app and prevents + // quit so we need to disable it here if (!extension.permissions_data()->HasAPIPermission( - APIPermission::kBackground)) { + APIPermission::kBackground, true)) { return false; } diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index dc5e290d644f5..5f7cdff525b42 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -235,6 +235,7 @@ class BrowserProcess { virtual net_log::ChromeNetLog* net_log() = 0; +#if 0 virtual component_updater::ComponentUpdateService* component_updater() = 0; virtual CRLSetFetcher* crl_set_fetcher() = 0; @@ -244,7 +245,7 @@ class BrowserProcess { virtual component_updater::SupervisedUserWhitelistInstaller* supervised_user_whitelist_installer() = 0; - +#endif virtual MediaFileSystemRegistry* media_file_system_registry() = 0; virtual bool created_local_state() const = 0; diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 5c74de660fb31..7c6ee8cc2675f 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -274,8 +274,10 @@ void BrowserProcessImpl::StartTearDown() { // that URLFetcher operation before going away.) metrics_services_manager_.reset(); intranet_redirect_detector_.reset(); +#if 0 if (safe_browsing_service_.get()) safe_browsing_service()->ShutDown(); +#endif network_time_tracker_.reset(); #if defined(ENABLE_PLUGIN_INSTALLATION) plugins_resource_service_.reset(); @@ -865,6 +867,7 @@ net_log::ChromeNetLog* BrowserProcessImpl::net_log() { return net_log_.get(); } +#if 0 component_updater::ComponentUpdateService* BrowserProcessImpl::component_updater() { if (!component_updater_.get()) { @@ -881,13 +884,16 @@ BrowserProcessImpl::component_updater() { } return component_updater_.get(); } +#endif +#if 0 CRLSetFetcher* BrowserProcessImpl::crl_set_fetcher() { if (!crl_set_fetcher_) crl_set_fetcher_ = new CRLSetFetcher(); return crl_set_fetcher_.get(); } + component_updater::PnaclComponentInstaller* BrowserProcessImpl::pnacl_component_installer() { #if !defined(DISABLE_NACL) @@ -912,6 +918,7 @@ BrowserProcessImpl::supervised_user_whitelist_installer() { } return supervised_user_whitelist_installer_.get(); } +#endif void BrowserProcessImpl::ResourceDispatcherHostCreated() { resource_dispatcher_host_delegate_.reset( @@ -1118,9 +1125,11 @@ void BrowserProcessImpl::CreateSafeBrowsingService() { // Set this flag to true so that we don't retry indefinitely to // create the service class if there was an error. created_safe_browsing_service_ = true; +#if 0 safe_browsing_service_ = safe_browsing::SafeBrowsingService::CreateSafeBrowsingService(); safe_browsing_service_->Initialize(); +#endif } void BrowserProcessImpl::CreateGCMDriver() { @@ -1185,11 +1194,13 @@ void BrowserProcessImpl::ApplyMetricsReportingPolicy() { } void BrowserProcessImpl::CacheDefaultWebClientState() { +#if 0 #if defined(OS_CHROMEOS) cached_default_web_client_state_ = shell_integration::IS_DEFAULT; #elif !defined(OS_ANDROID) cached_default_web_client_state_ = shell_integration::GetDefaultBrowser(); #endif +#endif } void BrowserProcessImpl::Pin() { diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index d0c8b09404a1f..c2ed6bcb69c34 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -135,12 +135,14 @@ class BrowserProcessImpl : public BrowserProcess, #endif net_log::ChromeNetLog* net_log() override; +#if 0 component_updater::ComponentUpdateService* component_updater() override; CRLSetFetcher* crl_set_fetcher() override; component_updater::PnaclComponentInstaller* pnacl_component_installer() override; component_updater::SupervisedUserWhitelistInstaller* supervised_user_whitelist_installer() override; +#endif MediaFileSystemRegistry* media_file_system_registry() override; bool created_local_state() const override; #if defined(ENABLE_WEBRTC) diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index f0635182af039..aa16dd12791f3 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -72,6 +72,7 @@ + diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc index 6d9a6b4407211..3f73eb4763aac 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.cc +++ b/chrome/browser/browsing_data/browsing_data_remover.cc @@ -134,6 +134,7 @@ CallbackList* GetOnBrowsingDataRemovedCallbacks() { return g_on_browsing_data_removed_callbacks; } +#if !defined(DISABLE_NACL) void UIThreadTrampolineHelper(const base::Closure& callback) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); } @@ -146,6 +147,7 @@ base::Closure UIThreadTrampoline(const base::Closure& callback) { // task is actually posted. return base::Bind(&UIThreadTrampolineHelper, callback); } +#endif template void IgnoreArgumentHelper(const base::Closure& callback, T unused_argument) { @@ -208,6 +210,7 @@ void ClearPnaclCacheOnIOThread(base::Time begin, } #endif +#if 0 void ClearCookiesOnIOThread(base::Time delete_begin, base::Time delete_end, net::URLRequestContextGetter* rq_context, @@ -231,6 +234,7 @@ void ClearCookiesWithPredicateOnIOThread( cookie_store->DeleteAllCreatedBetweenWithPredicateAsync( delete_begin, delete_end, predicate, IgnoreArgument(callback)); } +#endif void OnClearedChannelIDsOnIOThread(net::URLRequestContextGetter* rq_context, const base::Closure& callback) { @@ -645,6 +649,7 @@ void BrowsingDataRemover::RemoveImpl( // doesn't make sense to apply the time period of deleting in the last X // hours/days to the safebrowsing cookies since they aren't the result of // any user action. +#if 0 if (delete_begin_ == base::Time()) { safe_browsing::SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); @@ -672,7 +677,7 @@ void BrowsingDataRemover::RemoveImpl( } } } - +#endif MediaDeviceIDSalt::Reset(profile_->GetPrefs()); } diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 766755517f674..0073b6e561306 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -7,6 +7,8 @@ #include #include +#include "content/nw/src/nw_content.h" + #include #include #include @@ -444,6 +446,7 @@ OSStatus KeychainCallback(SecKeychainEvent keychain_event, } #endif // defined(OS_MACOSX) +#if 0 void RegisterComponentsForUpdate() { component_updater::ComponentUpdateService* cus = g_browser_process->component_updater(); @@ -509,6 +512,7 @@ void RegisterComponentsForUpdate() { RegisterCAPSComponent(cus); #endif // defined(OS_WIN) } +#endif // disable component updater #if !defined(OS_ANDROID) bool ProcessSingletonNotificationCallback( @@ -518,6 +522,9 @@ bool ProcessSingletonNotificationCallback( if (!g_browser_process || g_browser_process->IsShuttingDown()) return false; + if (!nw::ProcessSingletonNotificationCallbackHook(command_line, current_directory)) + return false; + if (command_line.HasSwitch(switches::kOriginalProcessStartTime)) { std::string start_time_string = command_line.GetSwitchValueASCII(switches::kOriginalProcessStartTime); @@ -877,9 +884,13 @@ void ChromeBrowserMainParts::PostMainMessageLoopStart() { int ChromeBrowserMainParts::PreCreateThreads() { TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreCreateThreads"); + result_code_ = PreCreateThreadsImpl(); if (result_code_ == content::RESULT_CODE_NORMAL_EXIT) { + result_code_ = nw::MainPartsPreCreateThreadsHook(); + if (result_code_ != content::RESULT_CODE_NORMAL_EXIT) + return result_code_; #if !defined(OS_ANDROID) // These members must be initialized before exiting this function normally. DCHECK(master_prefs_.get()); @@ -1173,6 +1184,8 @@ void ChromeBrowserMainParts::PreMainMessageLoopRun() { result_code_ = PreMainMessageLoopRunImpl(); + nw::MainPartsPreMainMessageLoopRunHook(); + for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) chrome_extra_parts_[i]->PreMainMessageLoopRun(); } @@ -1574,7 +1587,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { #endif // BUILDFLAG(ENABLE_BACKGROUND) // Post-profile init --------------------------------------------------------- - TranslateService::Initialize(); + //TranslateService::Initialize(); // Needs to be done before PostProfileInit, since login manager on CrOS is // called inside PostProfileInit. @@ -1755,11 +1768,11 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { // This must be called prior to RegisterComponentsForUpdate, in case the CLD // data source is based on the Component Updater. - translate::BrowserCldUtils::ConfigureDefaultDataProvider(); - + //translate::BrowserCldUtils::ConfigureDefaultDataProvider(); +#if 0 if (!parsed_command_line().HasSwitch(switches::kDisableComponentUpdate)) RegisterComponentsForUpdate(); - +#endif #if defined(OS_ANDROID) variations::VariationsService* variations_service = browser_process_->variations_service(); @@ -1939,7 +1952,7 @@ void ChromeBrowserMainParts::PostMainMessageLoopRun() { // Some tests don't set parameters.ui_task, so they started translate // language fetch that was never completed so we need to cleanup here // otherwise it will be done by the destructor in a wrong thread. - TranslateService::Shutdown(parameters().ui_task == NULL); + //TranslateService::Shutdown(parameters().ui_task == NULL); if (notify_result_ == ProcessSingleton::PROCESS_NONE) process_singleton_->Cleanup(); @@ -1986,6 +1999,7 @@ void ChromeBrowserMainParts::PostDestroyThreads() { process_singleton_.reset(); device_event_log::Shutdown(); + nw::MainPartsPostDestroyThreadsHook(); // We need to do this check as late as possible, but due to modularity, this // may be the last point in Chrome. This would be more effective if done at // a higher level on the stack, so that it is impossible for an early return diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm index 11d7ff43ffe2e..5c282ccff7921 100644 --- a/chrome/browser/chrome_browser_main_mac.mm +++ b/chrome/browser/chrome_browser_main_mac.mm @@ -143,6 +143,7 @@ void EnsureMetadataNeverIndexFile(const base::FilePath& user_data_dir) { } } +#if 1 // Now load the nib (from the right bundle). base::scoped_nsobject nib( [[NSNib alloc] initWithNibNamed:@"MainMenu" @@ -150,6 +151,11 @@ void EnsureMetadataNeverIndexFile(const base::FilePath& user_data_dir) { // TODO(viettrungluu): crbug.com/20504 - This currently leaks, so if you // change this, you'll probably need to change the Valgrind suppression. [nib instantiateNibWithOwner:NSApp topLevelObjects:nil]; +#else + AppController* delegate = [AppController alloc]; + [NSApp setDelegate:delegate]; +#endif + // Make sure the app controller has been created. DCHECK([NSApp delegate]); diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9af79ac139c2a..60aef6a44f970 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -9,6 +9,9 @@ #include #include +#include "content/nw/src/common/shell_switches.h" +#include "content/nw/src/nw_content.h" + #include "base/base_switches.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -519,7 +522,7 @@ breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost( PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path); { ANNOTATE_SCOPED_MEMORY_LEAK; - bool upload = (getenv(env_vars::kHeadless) == NULL); + bool upload = false; breakpad::CrashHandlerHostLinux* crash_handler = new breakpad::CrashHandlerHostLinux(process_type, dumps_path, upload); crash_handler->StartUploaderThread(); @@ -611,10 +614,12 @@ class SafeBrowsingSSLCertReporter : public SSLCertReporter { // SSLCertReporter implementation void ReportInvalidCertificateChain( const std::string& serialized_report) override { +#if 0 if (safe_browsing_ui_manager_) { safe_browsing_ui_manager_->ReportInvalidCertificateChain( serialized_report, base::Bind(&base::DoNothing)); } +#endif } private: @@ -1210,6 +1215,18 @@ bool ChromeContentBrowserClient::MayReuseHost( bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( content::BrowserContext* browser_context, const GURL& url) { + // PDF extension should use new process, or there is a loop of IPC + // message BrowserPluginHostMsg_SetFocus and InputMsg_SetFocus + // #4335 + + if (url.SchemeIs(extensions::kExtensionScheme) && url.host() == extension_misc::kPdfExtensionId) + return false; + + if (nw::PinningRenderer()) + return true; + else + return false; +#if 0 // It has to be a valid URL for us to check for an extension. if (!url.is_valid()) return false; @@ -1222,6 +1239,7 @@ bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( #else return false; #endif +#endif } void ChromeContentBrowserClient::SiteInstanceGotProcess( @@ -1485,6 +1503,8 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches( #endif if (process_type == switches::kRendererProcess) { + command_line->AppendSwitch(switches::kNWJS); + content::RenderProcessHost* process = content::RenderProcessHost::FromID(child_process_id); Profile* profile = @@ -1606,6 +1626,7 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches( autofill::switches::kDisableAccessorySuggestionView, autofill::switches::kEnableAccessorySuggestionView, #endif + switches::kEnableSpellChecking, autofill::switches::kDisableFillOnAccountSelect, autofill::switches::kDisablePasswordGeneration, autofill::switches::kEnableFillOnAccountSelect, @@ -2078,12 +2099,8 @@ void ChromeContentBrowserClient::AllowCertificateError( if (expired_previous_decision) options_mask |= SSLErrorUI::EXPIRED_BUT_PREVIOUSLY_ALLOWED; - safe_browsing::SafeBrowsingService* safe_browsing_service = - g_browser_process->safe_browsing_service(); std::unique_ptr cert_reporter( - new SafeBrowsingSSLCertReporter(safe_browsing_service - ? safe_browsing_service->ui_manager() - : nullptr)); + new SafeBrowsingSSLCertReporter(nullptr)); SSLErrorHandler::HandleSSLError(web_contents, cert_error, ssl_info, request_url, options_mask, std::move(cert_reporter), callback); @@ -2439,6 +2456,8 @@ void ChromeContentBrowserClient::OverrideWebkitPrefs( for (size_t i = 0; i < extra_parts_.size(); ++i) extra_parts_[i]->OverrideWebkitPrefs(rvh, web_prefs); + + nw::OverrideWebkitPrefsHook(rvh, web_prefs); } void ChromeContentBrowserClient::BrowserURLHandlerCreated( diff --git a/chrome/browser/component_updater/file_type_policies_component_installer.cc b/chrome/browser/component_updater/file_type_policies_component_installer.cc index 8f261bc6914f5..7bbe4958416e7 100644 --- a/chrome/browser/component_updater/file_type_policies_component_installer.cc +++ b/chrome/browser/component_updater/file_type_policies_component_installer.cc @@ -35,6 +35,7 @@ const uint8_t kPublicKeySHA256[32] = { const char kFileTypePoliciesManifestName[] = "File Type Policies"; void LoadFileTypesFromDisk(const base::FilePath& pb_path) { +#if 0 if (pb_path.empty()) return; @@ -49,6 +50,7 @@ void LoadFileTypesFromDisk(const base::FilePath& pb_path) { safe_browsing::FileTypePolicies::GetInstance()->PopulateFromDynamicUpdate( binary_pb); +#endif } } // namespace diff --git a/chrome/browser/component_updater/pepper_flash_component_installer.cc b/chrome/browser/component_updater/pepper_flash_component_installer.cc index cae975d5861e0..9d75aa9d8a458 100644 --- a/chrome/browser/component_updater/pepper_flash_component_installer.cc +++ b/chrome/browser/component_updater/pepper_flash_component_installer.cc @@ -185,7 +185,7 @@ void RegisterPepperFlashWithChrome(const base::FilePath& path, #if defined(OS_WIN) // On Windows, component updated DLLs can't load off network drives. // See crbug.com/572131 for details. - is_on_network = base::IsOnNetworkDrive(path); + is_on_network = false; //base::IsOnNetworkDrive(path); #endif // If equal version, register iff component is not on a network drive, // and the version of flash is not bundled, and not debug system. diff --git a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc index 239039fcb3651..bcf86dc5d2ba1 100644 --- a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc +++ b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc @@ -89,7 +89,7 @@ void InternalExtensionProvider::Observe( DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_CREATED, type); const extensions::ExtensionHost* host = content::Details(details).ptr(); - if (host->extension()->is_platform_app()) { + if (host->extension()->is_platform_app() && !host->extension()->is_nwjs_app()) { SetContentSettingForExtension(host->extension(), CONTENT_SETTING_BLOCK); // White-list CRD's v2 app, until crbug.com/134216 is complete. diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index d8636d9106033..ec2f12d55d01a 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc @@ -585,7 +585,7 @@ void DevToolsUIBindings::AppendToFile(const std::string& url, } void DevToolsUIBindings::RequestFileSystems() { - CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); + //CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); std::vector file_systems = file_helper_->GetFileSystems(); base::ListValue file_systems_value; @@ -596,7 +596,7 @@ void DevToolsUIBindings::RequestFileSystems() { } void DevToolsUIBindings::AddFileSystem(const std::string& file_system_path) { - CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); + //CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); file_helper_->AddFileSystem( file_system_path, base::Bind(&DevToolsUIBindings::ShowDevToolsConfirmInfoBar, @@ -604,13 +604,13 @@ void DevToolsUIBindings::AddFileSystem(const std::string& file_system_path) { } void DevToolsUIBindings::RemoveFileSystem(const std::string& file_system_path) { - CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); + //CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); file_helper_->RemoveFileSystem(file_system_path); } void DevToolsUIBindings::UpgradeDraggedFileSystemPermissions( const std::string& file_system_url) { - CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); + //CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); file_helper_->UpgradeDraggedFileSystemPermissions( file_system_url, base::Bind(&DevToolsUIBindings::ShowDevToolsConfirmInfoBar, @@ -620,7 +620,7 @@ void DevToolsUIBindings::UpgradeDraggedFileSystemPermissions( void DevToolsUIBindings::IndexPath(int index_request_id, const std::string& file_system_path) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); + //CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); if (!file_helper_->IsFileSystemAdded(file_system_path)) { IndexingDone(index_request_id, file_system_path); return; @@ -658,7 +658,7 @@ void DevToolsUIBindings::SearchInPath(int search_request_id, const std::string& file_system_path, const std::string& query) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); + //CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)); if (!file_helper_->IsFileSystemAdded(file_system_path)) { SearchCompleted(search_request_id, file_system_path, @@ -986,6 +986,9 @@ void DevToolsUIBindings::SearchCompleted( void DevToolsUIBindings::ShowDevToolsConfirmInfoBar( const base::string16& message, const InfoBarCallback& callback) { +#if 1 + callback.Run(true); // #4602 +#else if (!delegate_->GetInfoBarService()) { callback.Run(false); return; @@ -993,6 +996,7 @@ void DevToolsUIBindings::ShowDevToolsConfirmInfoBar( std::unique_ptr delegate( new DevToolsConfirmInfoBarDelegate(callback, message)); GlobalConfirmInfoBar::Show(std::move(delegate)); +#endif } void DevToolsUIBindings::AddDevToolsExtensionsToClient() { diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index 82de54ee8f0fe..22b7be2bfb309 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc @@ -617,6 +617,8 @@ void DevToolsWindow::Show(const DevToolsToggleAction& action) { bool should_show_window = !browser_ || (action.type() != DevToolsToggleAction::kInspect); + should_show_window = should_show_window && !headless_; + if (!browser_) CreateDevToolsBrowser(); @@ -703,7 +705,8 @@ DevToolsWindow::DevToolsWindow(Profile* profile, WebContents* main_web_contents, DevToolsUIBindings* bindings, WebContents* inspected_web_contents, - bool can_dock) + bool can_dock, + bool headless) : profile_(profile), main_web_contents_(main_web_contents), toolbox_web_contents_(nullptr), @@ -711,6 +714,7 @@ DevToolsWindow::DevToolsWindow(Profile* profile, browser_(nullptr), is_docked_(true), can_dock_(can_dock), + headless_(headless), // This initialization allows external front-end to work without changes. // We don't wait for docking call, but instead immediately show undocked. // Passing "dockSide=undocked" parameter ensures proper UI. @@ -767,7 +771,8 @@ DevToolsWindow* DevToolsWindow::Create( bool shared_worker_frontend, const std::string& remote_frontend, bool can_dock, - const std::string& settings) { + const std::string& settings, + content::WebContents* cdt_web_contents) { if (profile->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled) || base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) return nullptr; @@ -788,6 +793,19 @@ DevToolsWindow* DevToolsWindow::Create( shared_worker_frontend, remote_frontend, can_dock, settings)); + + if (cdt_web_contents) { + cdt_web_contents->GetController().LoadURL( + DecorateFrontendURL(url), content::Referrer(), + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string()); + DevToolsUIBindings* bindings = + DevToolsUIBindings::ForWebContents(cdt_web_contents); + if (!bindings) + return nullptr; + + return new DevToolsWindow(profile, cdt_web_contents, bindings, + inspected_web_contents, can_dock, true); + } std::unique_ptr main_web_contents( WebContents::Create(WebContents::CreateParams(profile))); main_web_contents->GetController().LoadURL( @@ -933,7 +951,8 @@ void DevToolsWindow::WebContentsCreated(WebContents* source_contents, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, - WebContents* new_contents) { + WebContents* new_contents, + const base::string16& nw_window_manifest) { if (target_url.SchemeIs(content::kChromeDevToolsScheme) && target_url.path().rfind("toolbox.html") != std::string::npos) { CHECK(can_dock_); @@ -1042,7 +1061,7 @@ bool DevToolsWindow::PreHandleGestureEvent( } void DevToolsWindow::ActivateWindow() { - if (life_stage_ != kLoadCompleted) + if (life_stage_ != kLoadCompleted || headless_) return; if (is_docked_ && GetInspectedBrowserWindow()) main_web_contents_->Focus(); @@ -1149,6 +1168,10 @@ void DevToolsWindow::RenderProcessGone(bool crashed) { } } +void DevToolsWindow::Close() { + browser_->window()->Close(); +} + void DevToolsWindow::OnLoadCompleted() { // First seed inspected tab id for extension APIs. WebContents* inspected_web_contents = GetInspectedWebContents(); diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h index 1aeab130590f0..118e7506b4e99 100644 --- a/chrome/browser/devtools/devtools_window.h +++ b/chrome/browser/devtools/devtools_window.h @@ -208,7 +208,10 @@ class DevToolsWindow : public DevToolsUIBindings::Delegate, content::WebContents* GetInspectedWebContents(); - private: + void Close(); + + public: + friend class DevToolsWindowTesting; friend class DevToolsWindowCreationObserver; @@ -241,7 +244,8 @@ class DevToolsWindow : public DevToolsUIBindings::Delegate, content::WebContents* main_web_contents, DevToolsUIBindings* bindings, content::WebContents* inspected_web_contents, - bool can_dock); + bool can_dock, + bool headless = false); static DevToolsWindow* Create(Profile* profile, const GURL& frontend_url, @@ -249,7 +253,9 @@ class DevToolsWindow : public DevToolsUIBindings::Delegate, bool shared_worker_frontend, const std::string& remote_frontend, bool can_dock, - const std::string& settings); + const std::string& settings, + content::WebContents* cdt_web_contents = nullptr); + static GURL GetDevToolsURL(Profile* profile, const GURL& base_url, bool shared_worker_frontend, @@ -276,7 +282,8 @@ class DevToolsWindow : public DevToolsUIBindings::Delegate, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, - content::WebContents* new_contents) override; + content::WebContents* new_contents, + const base::string16& nw_window_manifest) override; void CloseContents(content::WebContents* source) override; void ContentsZoomChange(bool zoom_in) override; void BeforeUnloadFired(content::WebContents* tab, @@ -307,6 +314,7 @@ class DevToolsWindow : public DevToolsUIBindings::Delegate, void SetIsDocked(bool is_docked) override; void OpenInNewTab(const std::string& url) override; void SetWhitelistedShortcuts(const std::string& message) override; + public: void InspectedContentsClosing() override; void OnLoadCompleted() override; void ReadyForTest() override; @@ -331,6 +339,7 @@ class DevToolsWindow : public DevToolsUIBindings::Delegate, Browser* browser_; bool is_docked_; const bool can_dock_; + const bool headless_; LifeStage life_stage_; DevToolsToggleAction action_on_load_; DevToolsContentsResizingStrategy contents_resizing_strategy_; diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index 4f934e28075ed..b7401c08119ec 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc @@ -206,12 +206,14 @@ ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) { download_manager_ = dm; +#if 0 safe_browsing::SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); if (sb_service && !profile_->IsOffTheRecord()) { // Include this download manager in the set monitored by safe browsing. sb_service->AddDownloadManager(dm); } +#endif } void ChromeDownloadManagerDelegate::Shutdown() { diff --git a/chrome/browser/download/download_commands.cc b/chrome/browser/download/download_commands.cc index eeb3767e5d937..08ec0b2f79dff 100644 --- a/chrome/browser/download/download_commands.cc +++ b/chrome/browser/download/download_commands.cc @@ -180,9 +180,11 @@ bool DownloadCommands::IsCommandEnabled(Command command) const { // filename. Don't base an "Always open" decision based on it. Also // exclude extensions. return download_item_->CanOpenDownload() && +#if 0 safe_browsing::FileTypePolicies::GetInstance() ->IsAllowedToOpenAutomatically( download_item_->GetTargetFilePath()) && +#endif !download_crx_util::IsExtensionDownload(*download_item_); case CANCEL: return !download_item_->IsDone(); diff --git a/chrome/browser/download/download_danger_prompt.cc b/chrome/browser/download/download_danger_prompt.cc index 8ed6be4ec6107..095b28b9d08ee 100644 --- a/chrome/browser/download/download_danger_prompt.cc +++ b/chrome/browser/download/download_danger_prompt.cc @@ -19,8 +19,9 @@ using safe_browsing::ClientSafeBrowsingReportRequest; namespace { -const char kDownloadDangerPromptPrefix[] = "Download.DownloadDangerPrompt"; +//const char kDownloadDangerPromptPrefix[] = "Download.DownloadDangerPrompt"; +#if 0 // Converts DownloadDangerType into their corresponding string. const char* GetDangerTypeString( const content::DownloadDangerType& danger_type) { @@ -46,6 +47,7 @@ const char* GetDangerTypeString( NOTREACHED(); return nullptr; } +#endif } // namespace @@ -86,6 +88,7 @@ void DownloadDangerPrompt::SendSafeBrowsingDownloadRecoveryReport( void DownloadDangerPrompt::RecordDownloadDangerPrompt( bool did_proceed, const content::DownloadItem& download) { +#if 0 int64_t file_type_uma_value = safe_browsing::FileTypePolicies::GetInstance()->UmaValueForFile( download.GetTargetFilePath()); @@ -101,4 +104,5 @@ void DownloadDangerPrompt::RecordDownloadDangerPrompt( GetDangerTypeString(danger_type)), file_type_uma_value); } +#endif } diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc index 05039fe5c5eb1..c3467f9fd1860 100644 --- a/chrome/browser/download/download_prefs.cc +++ b/chrome/browser/download/download_prefs.cc @@ -188,8 +188,10 @@ DownloadPrefs::DownloadPrefs(Profile* profile) : profile_(profile) { // automatically can change in the future. When the list is tightened, it is // expected that some entries in the users' auto open list will get dropped // permanently as a result. +#if 0 if (FileTypePolicies::GetInstance()->IsAllowedToOpenAutomatically( filename_with_extension)) +#endif auto_open_.insert(extension); } } @@ -201,7 +203,7 @@ void DownloadPrefs::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref( prefs::kPromptForDownload, - false, + true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterStringPref(prefs::kDownloadExtensionsToOpen, std::string()); registry->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false); @@ -315,10 +317,11 @@ bool DownloadPrefs::IsAutoOpenEnabledBasedOnExtension( bool DownloadPrefs::EnableAutoOpenBasedOnExtension( const base::FilePath& file_name) { base::FilePath::StringType extension = file_name.Extension(); +#if 0 if (!FileTypePolicies::GetInstance()->IsAllowedToOpenAutomatically( file_name)) return false; - +#endif DCHECK(extension[0] == base::FilePath::kExtensionSeparator); extension.erase(0, 1); diff --git a/chrome/browser/download/download_target_determiner.cc b/chrome/browser/download/download_target_determiner.cc index 32a2e5f6c489c..6ef46f2b0ced6 100644 --- a/chrome/browser/download/download_target_determiner.cc +++ b/chrome/browser/download/download_target_determiner.cc @@ -879,7 +879,7 @@ DownloadFileType::DangerLevel DownloadTargetDeterminer::GetDangerLevel( if (download_prefs_->IsAutoOpenEnabledBasedOnExtension(virtual_path_) && download_->HasUserGesture()) return DownloadFileType::NOT_DANGEROUS; - +#if 0 DownloadFileType::DangerLevel danger_level = safe_browsing::FileTypePolicies::GetInstance()->GetFileDangerLevel( virtual_path_.BaseName()); @@ -893,7 +893,8 @@ DownloadFileType::DangerLevel DownloadTargetDeterminer::GetDangerLevel( (download_->GetTransitionType() == ui::PAGE_TRANSITION_FROM_ADDRESS_BAR || (download_->HasUserGesture() && visits == VISITED_REFERRER))) return DownloadFileType::NOT_DANGEROUS; - return danger_level; +#endif + return DownloadFileType::NOT_DANGEROUS; } void DownloadTargetDeterminer::OnDownloadDestroyed( diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc index 0a5e843193f83..fa9a774f241d8 100644 --- a/chrome/browser/extensions/activity_log/activity_log.cc +++ b/chrome/browser/extensions/activity_log/activity_log.cc @@ -211,7 +211,7 @@ bool GetUrlForTabId(int tab_id, if (found) { *url = contents->GetURL(); - *is_incognito = browser->profile()->IsOffTheRecord(); + *is_incognito = false; //browser->profile()->IsOffTheRecord(); return true; } else { return false; diff --git a/chrome/browser/extensions/api/content_settings/content_settings_store.cc b/chrome/browser/extensions/api/content_settings/content_settings_store.cc index 765636dbf9ec3..c7ca9336b74cb 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_store.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_store.cc @@ -103,6 +103,13 @@ void ContentSettingsStore::SetExtensionContentSetting( { base::AutoLock lock(lock_); OriginIdentifierValueMap* map = GetValueMap(ext_id, scope); + if (!map) { + ExtensionEntry* entry = new ExtensionEntry; + entries_.insert(std::make_pair(base::Time::Now(), entry)); + entry->id = ext_id; + entry->enabled = true; + map = GetValueMap(ext_id, scope); + } if (setting == CONTENT_SETTING_DEFAULT) { map->DeleteValue(primary_pattern, secondary_pattern, type, identifier); } else { diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc index a7df881df9f10..b4b3c7edb2cc1 100644 --- a/chrome/browser/extensions/api/cookies/cookies_api.cc +++ b/chrome/browser/extensions/api/cookies/cookies_api.cc @@ -86,13 +86,16 @@ bool ParseStoreContext(ChromeAsyncExtensionFunction* function, } else { // The store ID was not specified; use the current execution context's // cookie store by default. - // GetCurrentBrowser() already takes into account incognito settings. + // GetCurrentBrowser() already takes into account incognito + // settings. +#if 0 Browser* current_browser = function->GetCurrentBrowser(); if (!current_browser) { function->SetError(keys::kNoCookieStoreFoundError); return false; } - store_profile = current_browser->profile(); +#endif + store_profile = function->GetProfile(); *store_id = cookies_helpers::GetStoreIdFromProfile(store_profile); } diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc index 3326d47532a7c..8b5508788a91f 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc @@ -87,9 +87,13 @@ bool DesktopCaptureChooseDesktopMediaFunction::RunAsync() { } DCHECK(web_contents); } else { - origin = extension()->url(); target_name = base::UTF8ToUTF16(extension()->name()); web_contents = GetSenderWebContents(); + // NWJS fix for nwjs/nw.js#4579 + // NWJS app allows running on origins other than `chrome-extension://*/*`. + // The origin should then be from the senders URL, in order not to fail + // the origin checking in `DesktopStreamsRegistry::RequestMediaForStreamId`. + origin = extension()->is_nwjs_app() ? web_contents->GetURL().GetOrigin() : extension()->url(); DCHECK(web_contents); } diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc index b7fefdcca05fa..4070e299701ae 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc @@ -259,12 +259,13 @@ LanguageSettingsPrivateSetLanguageListFunction::Run() { parameters = language_settings_private::SetLanguageList::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(parameters.get()); +#if 0 std::unique_ptr translate_prefs = ChromeTranslateClient::CreateTranslatePrefs( chrome_details_.GetProfile()->GetPrefs()); translate_prefs->UpdateLanguageList(parameters->language_codes); - +#endif return RespondNow(NoArguments()); } @@ -395,9 +396,11 @@ LanguageSettingsPrivateGetTranslateTargetLanguageFunction:: ExtensionFunction::ResponseAction LanguageSettingsPrivateGetTranslateTargetLanguageFunction::Run() { - return RespondNow(OneArgument(new base::StringValue( + return RespondNow(OneArgument(new base::StringValue(""))); +#if 0 TranslateService::GetTargetLanguage( chrome_details_.GetProfile()->GetPrefs())))); +#endif } #if defined(OS_CHROMEOS) diff --git a/chrome/browser/extensions/api/preference/preference_api.cc b/chrome/browser/extensions/api/preference/preference_api.cc index 3d24d983cd5bd..06bd88e481cc5 100644 --- a/chrome/browser/extensions/api/preference/preference_api.cc +++ b/chrome/browser/extensions/api/preference/preference_api.cc @@ -641,7 +641,11 @@ bool GetPreferenceFunction::RunSync() { std::unique_ptr result(new base::DictionaryValue); // Retrieve level of control. - std::string level_of_control = helpers::GetLevelOfControl( + std::string level_of_control; + if (extension()->is_nwjs_app()) + level_of_control = "controllable_by_this_extension"; + else + level_of_control = helpers::GetLevelOfControl( GetProfile(), extension_id(), browser_pref, incognito); result->SetString(keys::kLevelOfControl, level_of_control); diff --git a/chrome/browser/extensions/api/preference/preference_helpers.cc b/chrome/browser/extensions/api/preference/preference_helpers.cc index e2b3577cbe592..353052f71d6d6 100644 --- a/chrome/browser/extensions/api/preference/preference_helpers.cc +++ b/chrome/browser/extensions/api/preference/preference_helpers.cc @@ -106,8 +106,11 @@ void DispatchEventToExtensions(Profile* profile, base::DictionaryValue* dict; bool rv = args->GetDictionary(0, &dict); DCHECK(rv); - std::string level_of_control = - GetLevelOfControl(profile, extension->id(), browser_pref, incognito); + std::string level_of_control; + if (extension->is_nwjs_app()) + level_of_control = kControlledByThisExtension; + else + level_of_control = GetLevelOfControl(profile, extension->id(), browser_pref, incognito); dict->SetString(kLevelOfControlKey, level_of_control); // If the extension is in incognito split mode, diff --git a/chrome/browser/extensions/api/tabs/ash_panel_contents.cc b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc index 4279baa95359a..5161d852dcae9 100644 --- a/chrome/browser/extensions/api/tabs/ash_panel_contents.cc +++ b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc @@ -36,7 +36,8 @@ AshPanelContents::~AshPanelContents() { void AshPanelContents::Initialize(content::BrowserContext* context, content::RenderFrameHost* creator_frame, - const GURL& url) { + const GURL& url, + const extensions::Extension* extension) { url_ = url; content::WebContents::CreateParams create_params( diff --git a/chrome/browser/extensions/api/tabs/ash_panel_contents.h b/chrome/browser/extensions/api/tabs/ash_panel_contents.h index 442051dc7847a..d7c84f1d6faa5 100644 --- a/chrome/browser/extensions/api/tabs/ash_panel_contents.h +++ b/chrome/browser/extensions/api/tabs/ash_panel_contents.h @@ -22,6 +22,7 @@ class RenderViewHost; namespace extensions { struct DraggableRegion; +class Extension; } // extensions::AppWindowContents class specific to panel windows created by v1 @@ -39,7 +40,8 @@ class AshPanelContents // extensions::AppWindowContents void Initialize(content::BrowserContext* context, content::RenderFrameHost* creator_frame, - const GURL& url) override; + const GURL& url, + const extensions::Extension* extension) override; void LoadContents(int32_t creator_process_id) override; void NativeWindowChanged( extensions::NativeAppWindow* native_app_window) override; diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 885d1a7bc6e83..995388e5e20ec 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc @@ -1048,6 +1048,7 @@ bool TabsCreateFunction::RunSync() { AssignOptionalValue(params->create_properties.index, options.index); AssignOptionalValue(params->create_properties.url, options.url); + options.create_browser_if_needed = true; std::string error; std::unique_ptr result( ExtensionTabUtil::OpenTab(this, options, &error)); @@ -1766,6 +1767,8 @@ bool TabsDetectLanguageFunction::RunAsync() { tabs::DetectLanguage::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); + return false; +#if 0 int tab_id = 0; Browser* browser = NULL; WebContents* contents = NULL; @@ -1828,6 +1831,7 @@ bool TabsDetectLanguageFunction::RunAsync() { this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::Source(&(contents->GetController()))); return true; +#endif } void TabsDetectLanguageFunction::Observe( @@ -1981,7 +1985,7 @@ ScriptExecutor* ExecuteCodeInTabFunction::GetScriptExecutor() { &contents, NULL, &error_) && - contents && browser; + contents; if (!success) return NULL; diff --git a/chrome/browser/extensions/browser_context_keyed_service_factories.cc b/chrome/browser/extensions/browser_context_keyed_service_factories.cc index 9b397736815e9..fc2358618b462 100644 --- a/chrome/browser/extensions/browser_context_keyed_service_factories.cc +++ b/chrome/browser/extensions/browser_context_keyed_service_factories.cc @@ -70,6 +70,8 @@ #include "chrome/browser/extensions/api/spellcheck/spellcheck_api.h" #endif +#include "content/nw/src/api/object_manager_factory.h" + namespace chrome_extensions { void EnsureBrowserContextKeyedServiceFactoriesBuilt() { @@ -115,6 +117,7 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() { extensions::MediaPlayerAPI::GetFactoryInstance(); #endif extensions::MenuManagerFactory::GetInstance(); + nw::ObjectManagerFactory::GetInstance(); extensions::OmniboxAPI::GetFactoryInstance(); extensions::PasswordsPrivateEventRouterFactory::GetInstance(); #if defined(ENABLE_PLUGINS) diff --git a/chrome/browser/extensions/chrome_component_extension_resource_manager.cc b/chrome/browser/extensions/chrome_component_extension_resource_manager.cc index cb1b96259c4d3..b48c74c3562bf 100644 --- a/chrome/browser/extensions/chrome_component_extension_resource_manager.cc +++ b/chrome/browser/extensions/chrome_component_extension_resource_manager.cc @@ -9,6 +9,7 @@ #include "base/path_service.h" #include "build/build_config.h" #include "chrome/common/chrome_paths.h" +#include "extensions/common/constants.h" #include "grit/chrome_unscaled_resources.h" #include "grit/component_extension_resources_map.h" #include "grit/theme_resources.h" @@ -86,7 +87,8 @@ bool ChromeComponentExtensionResourceManager::IsComponentExtensionResource( base::FilePath relative_path; if (!PathService::Get(chrome::DIR_RESOURCES, &resources_dir) || !resources_dir.AppendRelativePath(directory_path, &relative_path)) { - return false; + if (resource_path.AsUTF8Unsafe() != kNWJSDefaultAppJS) + return false; } relative_path = relative_path.Append(resource_path); relative_path = relative_path.NormalizePathSeparators(); diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc index db7849125222f..4e812613dca7c 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc @@ -72,6 +72,7 @@ enum RenderProcessHostPrivilege { PRIV_EXTENSION, }; +#if 0 RenderProcessHostPrivilege GetPrivilegeRequiredByUrl( const GURL& url, ExtensionRegistry* registry) { @@ -116,6 +117,7 @@ RenderProcessHostPrivilege GetProcessPrivilege( return PRIV_EXTENSION; } +#endif } // namespace @@ -307,6 +309,8 @@ bool ChromeContentBrowserClientExtensionsPart::IsSuitableHost( Profile* profile, content::RenderProcessHost* process_host, const GURL& site_url) { + return true; +#if 0 DCHECK(profile); ExtensionRegistry* registry = ExtensionRegistry::Get(profile); @@ -323,6 +327,7 @@ bool ChromeContentBrowserClientExtensionsPart::IsSuitableHost( GetPrivilegeRequiredByUrl(site_url, registry); return GetProcessPrivilege(process_host, process_map, registry) == privilege_required; +#endif } // static diff --git a/chrome/browser/extensions/chrome_content_verifier_delegate.cc b/chrome/browser/extensions/chrome_content_verifier_delegate.cc index 7d8b74ed2631e..e98599d26a80c 100644 --- a/chrome/browser/extensions/chrome_content_verifier_delegate.cc +++ b/chrome/browser/extensions/chrome_content_verifier_delegate.cc @@ -110,6 +110,8 @@ ContentVerifierDelegate::Mode ChromeContentVerifierDelegate::ShouldBeVerified( return ContentVerifierDelegate::ENFORCE_STRICT; #endif + if (extension.is_nwjs_app() && !Manifest::IsComponentLocation(extension.location())) + return default_mode_; if (!extension.is_extension() && !extension.is_legacy_packaged_app()) return ContentVerifierDelegate::NONE; if (!Manifest::IsAutoUpdateableLocation(extension.location())) @@ -159,6 +161,7 @@ std::set ChromeContentVerifierDelegate::GetBrowserImagePaths( void ChromeContentVerifierDelegate::VerifyFailed( const std::string& extension_id, + const base::FilePath& relative_path, ContentVerifyJob::FailureReason reason) { ExtensionRegistry* registry = ExtensionRegistry::Get(context_); const Extension* extension = diff --git a/chrome/browser/extensions/chrome_content_verifier_delegate.h b/chrome/browser/extensions/chrome_content_verifier_delegate.h index 6c815bb1fc556..bdd2000ca2cba 100644 --- a/chrome/browser/extensions/chrome_content_verifier_delegate.h +++ b/chrome/browser/extensions/chrome_content_verifier_delegate.h @@ -30,6 +30,7 @@ class ChromeContentVerifierDelegate : public ContentVerifierDelegate { std::set GetBrowserImagePaths( const extensions::Extension* extension) override; void VerifyFailed(const std::string& extension_id, + const base::FilePath& relative_path, ContentVerifyJob::FailureReason reason) override; private: diff --git a/chrome/browser/extensions/chrome_extension_web_contents_observer.cc b/chrome/browser/extensions/chrome_extension_web_contents_observer.cc index 466ac326d35ee..d7e35afafaadd 100644 --- a/chrome/browser/extensions/chrome_extension_web_contents_observer.cc +++ b/chrome/browser/extensions/chrome_extension_web_contents_observer.cc @@ -28,6 +28,9 @@ #include "extensions/common/extension_urls.h" #include "extensions/common/switches.h" +#include "components/ui/zoom/zoom_controller.h" +#include "content/public/browser/web_contents.h" + using content::BrowserContext; DEFINE_WEB_CONTENTS_USER_DATA_KEY( @@ -37,7 +40,35 @@ namespace extensions { ChromeExtensionWebContentsObserver::ChromeExtensionWebContentsObserver( content::WebContents* web_contents) - : ExtensionWebContentsObserver(web_contents) {} + : ExtensionWebContentsObserver(web_contents) { + // Since ZoomController is also a WebContentsObserver, we need to be careful + // about disconnecting from it since the relative order of destruction of + // WebContentsObservers is not guaranteed. ZoomController silently clears + // its ZoomObserver list during WebContentsDestroyed() so there's no need + // to explicitly remove ourselves on destruction. + ui_zoom::ZoomController* zoom_controller = + ui_zoom::ZoomController::FromWebContents(web_contents); + // There may not always be a ZoomController, e.g. in tests. + if (zoom_controller) + zoom_controller->AddObserver(this); +} + +void ChromeExtensionWebContentsObserver::OnZoomChanged( + const ui_zoom::ZoomController::ZoomChangedEventData& data) { + ProcessManager* const process_manager = ProcessManager::Get(browser_context()); + const Extension* const extension = + process_manager->GetExtensionForWebContents(web_contents()); + if (extension) { + base::ListValue args; + args.AppendDouble(data.old_zoom_level); + args.AppendDouble(data.new_zoom_level); + + content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); + rfh->Send(new ExtensionMsg_MessageInvoke( + rfh->GetRoutingID(), extension->id(), "nw.Window", + "updateAppWindowZoom", args, false)); + } +} ChromeExtensionWebContentsObserver::~ChromeExtensionWebContentsObserver() {} @@ -56,7 +87,8 @@ void ChromeExtensionWebContentsObserver::RenderViewCreated( // Components of chrome that are implemented as extensions or platform apps // are allowed to use chrome://resources/ and chrome://theme/ URLs. if ((extension->is_extension() || extension->is_platform_app()) && - Manifest::IsComponentLocation(extension->location())) { + (Manifest::IsComponentLocation(extension->location()) || + extension->is_nwjs_app())) { policy->GrantOrigin(process_id, url::Origin(GURL(content::kChromeUIResourcesURL))); policy->GrantOrigin(process_id, @@ -69,6 +101,7 @@ void ChromeExtensionWebContentsObserver::RenderViewCreated( // never given access to Chrome APIs). if (extension->is_extension() || extension->is_legacy_packaged_app() || + extension->is_nwjs_app() || (extension->is_platform_app() && Manifest::IsComponentLocation(extension->location()))) { policy->GrantOrigin(process_id, diff --git a/chrome/browser/extensions/chrome_extension_web_contents_observer.h b/chrome/browser/extensions/chrome_extension_web_contents_observer.h index f827b3a6f60f1..8fd0685516e22 100644 --- a/chrome/browser/extensions/chrome_extension_web_contents_observer.h +++ b/chrome/browser/extensions/chrome_extension_web_contents_observer.h @@ -14,6 +14,8 @@ #include "extensions/browser/extension_web_contents_observer.h" #include "extensions/common/stack_frame.h" +#include "components/ui/zoom/zoom_observer.h" + namespace content { class RenderFrameHost; } @@ -25,7 +27,13 @@ namespace extensions { // renderers. class ChromeExtensionWebContentsObserver : public ExtensionWebContentsObserver, + public ui_zoom::ZoomObserver, public content::WebContentsUserData { + public: + // ZoomObserver implementation. + void OnZoomChanged( + const ui_zoom::ZoomController::ZoomChangedEventData& data) override; + private: friend class content::WebContentsUserData; diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index b08507dbaaca9..4ae9e89bf543a 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc @@ -64,6 +64,8 @@ #include "extensions/browser/updater/null_extension_cache.h" #endif +#include "content/nw/src/api/generated_api_registration.h" + namespace extensions { ChromeExtensionsBrowserClient::ChromeExtensionsBrowserClient() { @@ -272,6 +274,7 @@ void ChromeExtensionsBrowserClient::RegisterExtensionFunctions( // Generated APIs from lower-level modules. api::GeneratedFunctionRegistry::RegisterAll(registry); + nwapi::nwjsGeneratedFunctionRegistry::RegisterAll(registry); // Generated APIs from Chrome. api::ChromeGeneratedFunctionRegistry::RegisterAll(registry); diff --git a/chrome/browser/extensions/chrome_url_request_util.cc b/chrome/browser/extensions/chrome_url_request_util.cc index 2ffd99d3d1466..af1c3cc18f266 100644 --- a/chrome/browser/extensions/chrome_url_request_util.cc +++ b/chrome/browser/extensions/chrome_url_request_util.cc @@ -22,6 +22,7 @@ #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/info_map.h" #include "extensions/browser/url_request_util.h" +#include "extensions/common/constants.h" #include "extensions/common/file_util.h" #include "net/base/mime_util.h" #include "net/base/net_errors.h" @@ -154,6 +155,29 @@ net::URLRequestJob* MaybeCreateURLRequestResourceBundleJob( const base::FilePath& directory_path, const std::string& content_security_policy, bool send_cors_header) { + + std::string path = request->url().path(); + if (path.size() > 1 && + path.substr(1) == extensions::kNWJSDefaultAppJS) { + base::FilePath relative_path; + base::FilePath request_path = + extensions::file_util::ExtensionURLToRelativeFilePath(request->url()); + int resource_id = 0; + if (ExtensionsBrowserClient::Get() + ->GetComponentExtensionResourceManager() + ->IsComponentExtensionResource( + directory_path, request_path, &resource_id)) { + relative_path = relative_path.Append(request_path); + relative_path = relative_path.NormalizePathSeparators(); + return new URLRequestResourceBundleJob(request, + network_delegate, + relative_path, + resource_id, + content_security_policy, + send_cors_header); + } + } + base::FilePath resources_path; base::FilePath relative_path; // Try to load extension resources from chrome resource file if diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index 932ebbddc569f..c2c1a6617bc3e 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc @@ -526,6 +526,7 @@ void ComponentLoader::EnableBackgroundExtensionsForTesting() { void ComponentLoader::AddDefaultComponentExtensions( bool skip_session_components) { +#if 0 // Do not add component extensions that have background pages here -- add them // to AddDefaultComponentExtensionsWithBackgroundPages. #if defined(OS_CHROMEOS) @@ -565,6 +566,7 @@ void ComponentLoader::AddDefaultComponentExtensions( } AddKeyboardApp(); +#endif AddDefaultComponentExtensionsWithBackgroundPages(skip_session_components); @@ -572,6 +574,27 @@ void ComponentLoader::AddDefaultComponentExtensions( Add(pdf_extension_util::GetManifest(), base::FilePath(FILE_PATH_LITERAL("pdf"))); #endif + + base::CommandLine& command_line(*base::CommandLine::ForCurrentProcess()); + + //match the condition in startup_browser_creator.cc + if (command_line.HasSwitch("nwapp") || command_line.GetArgs().size() > 0) + return; + + std::string url; + if (command_line.HasSwitch("url")) { + url = command_line.GetSwitchValueASCII("url"); + } + std::string manifest_contents = + ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_NWJS_DEFAPP_MANIFEST).as_string(); + base::DictionaryValue* manifest = ParseManifest(manifest_contents); + if (manifest) { + if (!url.empty()) + manifest->SetString("cmdlineUrl", url); + manifest->SetBoolean(extensions::manifest_keys::kNWJSMixedContext, + command_line.HasSwitch("mixed-context")); + Add(manifest, base::FilePath(FILE_PATH_LITERAL("nwjs_default_app")), true); + } } void ComponentLoader::AddDefaultComponentExtensionsForKioskMode( @@ -611,6 +634,7 @@ void ComponentLoader::AddDefaultComponentExtensionsWithBackgroundPages( return; } +#if 0 //nwjs #if defined(OS_CHROMEOS) && defined(GOOGLE_CHROME_BUILD) // Since this is a v2 app it has a background page. AddWithNameAndDescription( @@ -692,8 +716,12 @@ void ComponentLoader::AddDefaultComponentExtensionsWithBackgroundPages( #endif // defined(GOOGLE_CHROME_BUILD) +#endif //nwjs + +#if 0 Add(IDR_CRYPTOTOKEN_MANIFEST, base::FilePath(FILE_PATH_LITERAL("cryptotoken"))); +#endif } void ComponentLoader:: diff --git a/chrome/browser/extensions/extension_install_checker.cc b/chrome/browser/extensions/extension_install_checker.cc index 313225df59060..d8d1447de1b63 100644 --- a/chrome/browser/extensions/extension_install_checker.cc +++ b/chrome/browser/extensions/extension_install_checker.cc @@ -113,13 +113,14 @@ void ExtensionInstallChecker::OnRequirementsCheckDone( void ExtensionInstallChecker::CheckBlacklistState() { DCHECK(extension_.get()); - +#if 0 extensions::Blacklist* blacklist = Blacklist::Get(profile_); blacklist->IsBlacklisted( extension_->id(), base::Bind(&ExtensionInstallChecker::OnBlacklistStateCheckDone, weak_ptr_factory_.GetWeakPtr(), current_sequence_number_)); +#endif } void ExtensionInstallChecker::OnBlacklistStateCheckDone(int sequence_number, diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index bb8fda7313f83..bd16113d8b7cc 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -4,6 +4,8 @@ #include "chrome/browser/extensions/extension_service.h" +#include "content/nw/src/nw_content.h" + #include #include @@ -103,6 +105,8 @@ #include "storage/browser/fileapi/file_system_context.h" #endif +#include "content/nw/src/nw_content.h" + using content::BrowserContext; using content::BrowserThread; using content::DevToolsAgentHost; @@ -299,7 +303,7 @@ ExtensionService::ExtensionService(Profile* profile, bool autoupdate_enabled, bool extensions_enabled, extensions::OneShotEvent* ready) - : extensions::Blacklist::Observer(blacklist), + : profile_(profile), system_(extensions::ExtensionSystem::Get(profile)), extension_prefs_(extension_prefs), @@ -324,6 +328,8 @@ ExtensionService::ExtensionService(Profile* profile, registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, content::NotificationService::AllBrowserContextsAndSources()); + registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, + content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, @@ -334,8 +340,8 @@ ExtensionService::ExtensionService(Profile* profile, extensions::ExtensionManagementFactory::GetForBrowserContext(profile_) ->AddObserver(this); - - // Set up the ExtensionUpdater. +#if 0 + // Set up the ExtensionUpdater if (autoupdate_enabled) { int update_frequency = extensions::kDefaultUpdateFrequencySeconds; if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { @@ -353,17 +359,18 @@ ExtensionService::ExtensionService(Profile* profile, base::Bind(ChromeExtensionDownloaderFactory::CreateForProfile, profile))); } - +#endif component_loader_.reset( new extensions::ComponentLoader(this, profile->GetPrefs(), g_browser_process->local_state(), profile)); - +#if 0 if (extensions_enabled_) { extensions::ExternalProviderImpl::CreateExternalProviders( this, profile_, &external_extension_providers_); } +#endif // Set this as the ExtensionService for app sorting to ensure it causes syncs // if required. @@ -647,6 +654,7 @@ void ExtensionService::ReloadExtensionImpl( // BeingUpgraded is set back to false when the extension is added. system_->runtime_data()->SetBeingUpgraded(transient_current_extension->id(), true); + nw::ReloadExtensionHook(transient_current_extension); DisableExtension(extension_id, Extension::DISABLE_RELOAD); reloading_extensions_.insert(extension_id); } else { @@ -1422,7 +1430,6 @@ void ExtensionService::OnLoadedInstalledExtensions() { if (updater_) updater_->Start(); - OnBlacklistUpdated(); } void ExtensionService::AddExtension(const Extension* extension) { @@ -1744,6 +1751,8 @@ void ExtensionService::OnExtensionInstalled( } } + disable_reasons &= ~Extension::DISABLE_CORRUPTED; + // Unsupported requirements overrides the management policy. if (install_flags & extensions::kInstallFlagHasRequirementErrors) { disable_reasons |= Extension::DISABLE_UNSUPPORTED_REQUIREMENT; @@ -1786,9 +1795,13 @@ void ExtensionService::OnExtensionInstalled( extension->location(), Manifest::NUM_LOCATIONS); } - const Extension::State initial_state = - disable_reasons == Extension::DISABLE_NONE ? Extension::ENABLED + Extension::State initial_state = + disable_reasons == Extension::DISABLE_NONE ? Extension::ENABLED : Extension::DISABLED; + + if (id == nw::GetMainExtensionId()) + initial_state = Extension::ENABLED; + if (initial_state == Extension::ENABLED) extension_prefs_->SetExtensionEnabled(id); else @@ -1970,16 +1983,23 @@ void ExtensionService::RegisterContentSettings( void ExtensionService::TrackTerminatedExtension( const std::string& extension_id) { + bool to_quit = false; extensions_being_terminated_.erase(extension_id); const Extension* extension = GetInstalledExtension(extension_id); if (!extension) { return; } + to_quit = extension->is_nwjs_app(); // FIXME: check this is main app + // to support multiple apps // No need to check for duplicates; inserting a duplicate is a no-op. registry_->AddTerminated(make_scoped_refptr(extension)); UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_TERMINATE); + if (to_quit) + base::MessageLoop::current()->PostTask( + FROM_HERE, + Bind(&base::MessageLoop::QuitWhenIdle, Unretained(base::MessageLoop::current()))); } void ExtensionService::TerminateExtension(const std::string& extension_id) { @@ -2125,6 +2145,12 @@ void ExtensionService::Observe(int type, AsWeakPtr(), host->extension()->id())); break; } + case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { + content::RenderProcessHost* process = + content::Source(source).ptr(); + nw::RendererProcessTerminatedHook(process, details); + break; + } case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { content::RenderProcessHost* process = content::Source(source).ptr(); @@ -2273,11 +2299,13 @@ void ExtensionService::MaybeFinishDelayedInstallations() { } } +#if 0 void ExtensionService::OnBlacklistUpdated() { blacklist_->GetBlacklistedIDs( registry_->GenerateInstalledExtensionsSet()->GetIDs(), base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr())); } +#endif void ExtensionService::ManageBlacklist( const extensions::Blacklist::BlacklistStateMap& state_map) { diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 556cc4f388d1c..10ea27ccd0ab8 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -181,7 +181,6 @@ class ExtensionService : public ExtensionServiceInterface, public extensions::ExternalProviderInterface::VisitorInterface, public content::NotificationObserver, - public extensions::Blacklist::Observer, public extensions::ExtensionManagement::Observer { public: // Attempts to uninstall an extension from a given ExtensionService. Returns @@ -468,7 +467,7 @@ class ExtensionService const content::NotificationDetails& details) override; // extensions::Blacklist::Observer implementation. - void OnBlacklistUpdated() override; + // void OnBlacklistUpdated() override; // Similar to FinishInstallation, but first checks if there still is an update // pending for the extension, and makes sure the extension is still idle. diff --git a/chrome/browser/extensions/extension_system_factory.cc b/chrome/browser/extensions/extension_system_factory.cc index 18266ffe2e512..ac6510226a4fe 100644 --- a/chrome/browser/extensions/extension_system_factory.cc +++ b/chrome/browser/extensions/extension_system_factory.cc @@ -51,7 +51,7 @@ ExtensionSystemSharedFactory::ExtensionSystemSharedFactory() DependsOn(policy::ProfilePolicyConnectorFactory::GetInstance()); DependsOn(ProcessManagerFactory::GetInstance()); DependsOn(RendererStartupHelperFactory::GetInstance()); - DependsOn(BlacklistFactory::GetInstance()); + //DependsOn(BlacklistFactory::GetInstance()); DependsOn(DeclarativeUserScriptManagerFactory::GetInstance()); DependsOn(EventRouterFactory::GetInstance()); // This depends on ExtensionDownloader which depends on diff --git a/chrome/browser/extensions/extension_system_impl.cc b/chrome/browser/extensions/extension_system_impl.cc index 365ef9139ff34..15a1f81e0f5aa 100644 --- a/chrome/browser/extensions/extension_system_impl.cc +++ b/chrome/browser/extensions/extension_system_impl.cc @@ -73,6 +73,8 @@ #include "components/user_manager/user_manager.h" #endif +#include "content/nw/src/nw_content_verifier_delegate.h" + using content::BrowserThread; namespace extensions { @@ -177,7 +179,7 @@ void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { ExtensionErrorReporter::Init(allow_noisy_errors); content_verifier_ = new ContentVerifier( - profile_, new ChromeContentVerifierDelegate(profile_)); + profile_, new NWContentVerifierDelegate(profile_)); service_worker_manager_.reset(new ServiceWorkerManager(profile_)); @@ -195,7 +197,7 @@ void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { extension_service_.reset(new ExtensionService( profile_, base::CommandLine::ForCurrentProcess(), profile_->GetPath().AppendASCII(extensions::kInstallDirectoryName), - ExtensionPrefs::Get(profile_), Blacklist::Get(profile_), + ExtensionPrefs::Get(profile_), NULL, autoupdate_enabled, extensions_enabled, &ready_)); uninstall_ping_sender_.reset(new UninstallPingSender( @@ -206,7 +208,7 @@ void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { { InstallVerifier::Get(profile_)->Init(); ContentVerifierDelegate::Mode mode = - ChromeContentVerifierDelegate::GetDefaultMode(); + NWContentVerifierDelegate::GetDefaultMode(); #if defined(OS_CHROMEOS) mode = std::max(mode, ContentVerifierDelegate::BOOTSTRAP); #endif // defined(OS_CHROMEOS) diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 68a27d537c296..33e16c9972bc5 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc @@ -141,7 +141,7 @@ base::DictionaryValue* ExtensionTabUtil::OpenTab( if (!browser) return NULL; } - +#if 0 // Ensure the selected browser is tabbed. if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser()) browser = chrome::FindTabbedBrowser(function->GetProfile(), @@ -151,7 +151,7 @@ base::DictionaryValue* ExtensionTabUtil::OpenTab( *error = keys::kNoCurrentWindowError; return NULL; } - +#endif // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that // represents the active tab. WebContents* opener = NULL; @@ -513,6 +513,15 @@ bool ExtensionTabUtil::GetTabById(int tab_id, Profile* incognito_profile = include_incognito && profile->HasOffTheRecordProfile() ? profile->GetOffTheRecordProfile() : NULL; + AppWindowRegistry* registry = AppWindowRegistry::Get(profile); + for (AppWindow* app_window : registry->app_windows()) { + WebContents* target_contents = app_window->web_contents(); + if (SessionTabHelper::IdForTab(target_contents) == tab_id) { + if (contents) + *contents = target_contents; + return true; + } + } for (auto* target_browser : *BrowserList::GetInstance()) { if (target_browser->profile() == profile || target_browser->profile() == incognito_profile) { diff --git a/chrome/browser/extensions/extension_webkit_preferences.cc b/chrome/browser/extensions/extension_webkit_preferences.cc index 73ce8c33e0536..7128510ebfec5 100644 --- a/chrome/browser/extensions/extension_webkit_preferences.cc +++ b/chrome/browser/extensions/extension_webkit_preferences.cc @@ -30,10 +30,17 @@ void SetPreferences(const extensions::Extension* extension, } if (extension->is_platform_app()) { - webkit_prefs->databases_enabled = false; - webkit_prefs->local_storage_enabled = false; - webkit_prefs->sync_xhr_in_documents_enabled = false; - webkit_prefs->cookie_enabled = false; + if (extension->is_nwjs_app()) { + webkit_prefs->databases_enabled = true; + webkit_prefs->local_storage_enabled = true; + webkit_prefs->sync_xhr_in_documents_enabled = true; + webkit_prefs->cookie_enabled = true; + }else{ + webkit_prefs->databases_enabled = false; + webkit_prefs->local_storage_enabled = false; + webkit_prefs->sync_xhr_in_documents_enabled = false; + webkit_prefs->cookie_enabled = false; + } } // Enable WebGL features that regular pages can't access, since they add diff --git a/chrome/browser/extensions/global_shortcut_listener_win.cc b/chrome/browser/extensions/global_shortcut_listener_win.cc index 65b244d55441b..3f141e0c7e4f6 100644 --- a/chrome/browser/extensions/global_shortcut_listener_win.cc +++ b/chrome/browser/extensions/global_shortcut_listener_win.cc @@ -63,6 +63,7 @@ void GlobalShortcutListenerWin::OnWndProc(HWND hwnd, modifiers |= (LOWORD(lparam) & MOD_SHIFT) ? ui::EF_SHIFT_DOWN : 0; modifiers |= (LOWORD(lparam) & MOD_ALT) ? ui::EF_ALT_DOWN : 0; modifiers |= (LOWORD(lparam) & MOD_CONTROL) ? ui::EF_CONTROL_DOWN : 0; + modifiers |= (LOWORD(lparam) & MOD_WIN) ? ui::EF_COMMAND_DOWN : 0; ui::Accelerator accelerator( ui::KeyboardCodeForWindowsKeyCode(key_code), modifiers); @@ -77,6 +78,7 @@ bool GlobalShortcutListenerWin::RegisterAcceleratorImpl( modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0; modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0; modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0; + modifiers |= accelerator.IsCmdDown() ? MOD_WIN : 0; static int hotkey_id = 0; bool success = !!RegisterHotKey( gfx::SingletonHwnd::GetInstance()->hwnd(), diff --git a/chrome/browser/extensions/global_shortcut_listener_x11.cc b/chrome/browser/extensions/global_shortcut_listener_x11.cc index dfd31bfb687be..916315805d2ff 100644 --- a/chrome/browser/extensions/global_shortcut_listener_x11.cc +++ b/chrome/browser/extensions/global_shortcut_listener_x11.cc @@ -38,6 +38,7 @@ int GetNativeModifiers(const ui::Accelerator& accelerator) { modifiers |= accelerator.IsShiftDown() ? ShiftMask : 0; modifiers |= accelerator.IsCtrlDown() ? ControlMask : 0; modifiers |= accelerator.IsAltDown() ? Mod1Mask : 0; + modifiers |= accelerator.IsCmdDown() ? Mod4Mask : 0; return modifiers; } @@ -151,6 +152,7 @@ void GlobalShortcutListenerX11::OnXKeyPressEvent(::XEvent* x_event) { modifiers |= (x_event->xkey.state & ShiftMask) ? ui::EF_SHIFT_DOWN : 0; modifiers |= (x_event->xkey.state & ControlMask) ? ui::EF_CONTROL_DOWN : 0; modifiers |= (x_event->xkey.state & Mod1Mask) ? ui::EF_ALT_DOWN : 0; + modifiers |= (x_event->xkey.state & Mod4Mask) ? ui::EF_COMMAND_DOWN : 0; ui::Accelerator accelerator( ui::KeyboardCodeFromXKeyEvent(x_event), modifiers); diff --git a/chrome/browser/extensions/standard_management_policy_provider.cc b/chrome/browser/extensions/standard_management_policy_provider.cc index 1a0542f4ddab8..a40d105c27ba3 100644 --- a/chrome/browser/extensions/standard_management_policy_provider.cc +++ b/chrome/browser/extensions/standard_management_policy_provider.cc @@ -106,6 +106,7 @@ bool StandardManagementPolicyProvider::UserMayLoad( case Manifest::TYPE_HOSTED_APP: case Manifest::TYPE_LEGACY_PACKAGED_APP: case Manifest::TYPE_PLATFORM_APP: + case Manifest::TYPE_NWJS_APP: case Manifest::TYPE_SHARED_MODULE: { if (!settings_->IsAllowedManifestType(extension->GetType())) return ReturnLoadError(extension, error); diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc index 7be912fcdd60c..5583528e6262f 100644 --- a/chrome/browser/file_select_helper.cc +++ b/chrome/browser/file_select_helper.cc @@ -182,7 +182,7 @@ void FileSelectHelper::FileSelectedWithExtraInfo( } const base::FilePath& path = file.local_path; - if (dialog_type_ == ui::SelectFileDialog::SELECT_UPLOAD_FOLDER) { + if (dialog_type_ == ui::SelectFileDialog::SELECT_UPLOAD_FOLDER && extract_directory_) { StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_); return; } @@ -426,6 +426,7 @@ void FileSelectHelper::RunFileChooser(content::WebContents* tab, // FileSelectHelper will keep itself alive until it sends the result message. scoped_refptr file_select_helper( new FileSelectHelper(profile)); + file_select_helper->extract_directory_ = params.extract_directory; file_select_helper->RunFileChooser( tab->GetRenderViewHost(), tab, base::WrapUnique(new content::FileChooserParams(params))); @@ -494,6 +495,11 @@ void FileSelectHelper::GetSanitizedFilenameOnUIThread( std::unique_ptr params) { base::FilePath default_file_path = profile_->last_selected_directory().Append( GetSanitizedFileName(params->default_file_name)); + + if (!params->initial_path.empty()) + default_file_path = params->initial_path.Append( + GetSanitizedFileName(params->default_file_name)); + #if defined(FULL_SAFE_BROWSING) CheckDownloadRequestWithSafeBrowsing(default_file_path, std::move(params)); #else diff --git a/chrome/browser/file_select_helper.h b/chrome/browser/file_select_helper.h index 503acf7bd959e..2a0f459a5738b 100644 --- a/chrome/browser/file_select_helper.h +++ b/chrome/browser/file_select_helper.h @@ -221,6 +221,8 @@ class FileSelectHelper : public base::RefCountedThreadSafe< // Profile used to set/retrieve the last used directory. Profile* profile_; + bool extract_directory_; + // The RenderViewHost and WebContents for the page showing a file dialog // (may only be one such dialog). content::RenderViewHost* render_view_host_; diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 5e2080252100f..87b20047fc678 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -133,6 +133,8 @@ #include "crypto/openssl_util.h" #endif +#include "content/nw/src/policy_cert_verifier.h" + using content::BrowserThread; class SafeBrowsingURLRequestContext; @@ -624,8 +626,8 @@ void IOThread::Init() { globals_->cert_verifier.reset(new net::MultiThreadedCertVerifier( new chromeos::CertVerifyProcChromeOS())); #else - globals_->cert_verifier.reset(new net::MultiThreadedCertVerifier( - net::CertVerifyProc::CreateDefault())); + globals_->cert_verifier.reset(new nw::PolicyCertVerifier()); + #endif globals_->transport_security_state.reset(new net::TransportSecurityState()); diff --git a/chrome/browser/lifetime/keep_alive_registry.h b/chrome/browser/lifetime/keep_alive_registry.h index 0028ce3c12668..75acf956b8707 100644 --- a/chrome/browser/lifetime/keep_alive_registry.h +++ b/chrome/browser/lifetime/keep_alive_registry.h @@ -46,10 +46,12 @@ class KeepAliveRegistry { KeepAliveRegistry(); ~KeepAliveRegistry(); + public: // Add/Remove entries. Do not use directly, use ScopedKeepAlive instead. void Register(KeepAliveOrigin origin, KeepAliveRestartOption restart); void Unregister(KeepAliveOrigin origin, KeepAliveRestartOption restart); + private: // Methods called when a specific aspect of the state of the registry changes. void OnKeepAliveStateChanged(bool new_keeping_alive); void OnRestartAllowedChanged(bool new_restart_allowed); diff --git a/chrome/browser/mac/master_prefs.mm b/chrome/browser/mac/master_prefs.mm index 1ee7c6b74cff4..79a1923d56015 100644 --- a/chrome/browser/mac/master_prefs.mm +++ b/chrome/browser/mac/master_prefs.mm @@ -20,8 +20,8 @@ const char kMasterPreferencesFileName[] = "Google Chrome Master Preferences"; #else const NSSearchPathDirectory kSearchPath = NSApplicationSupportDirectory; -const char kMasterPreferencesDirectory[] = "Chromium"; -const char kMasterPreferencesFileName[] = "Chromium Master Preferences"; +const char kMasterPreferencesDirectory[] = "NWJS"; +const char kMasterPreferencesFileName[] = "NWJS Master Preferences"; #endif // GOOGLE_CHROME_BUILD } // namespace diff --git a/chrome/browser/media/desktop_capture_access_handler.cc b/chrome/browser/media/desktop_capture_access_handler.cc index 6aa8d20f31606..4e67d80482c02 100644 --- a/chrome/browser/media/desktop_capture_access_handler.cc +++ b/chrome/browser/media/desktop_capture_access_handler.cc @@ -62,6 +62,7 @@ base::string16 GetApplicationTitle(content::WebContents* web_contents, return base::UTF8ToUTF16(title); } +#if 0 base::string16 GetStopSharingUIString( const base::string16& application_title, const base::string16& registered_extension_name, @@ -133,6 +134,7 @@ base::string16 GetStopSharingUIString( } return base::string16(); } +#endif // Helper to get list of media stream devices for desktop capture in |devices|. // Registers to display notification if |display_notification| is true. // Returns an instance of MediaStreamUI to be passed to content layer. @@ -163,6 +165,7 @@ std::unique_ptr GetDevicesForDesktopCapture( } } +#if 0 // If required, register to display the notification for stream capture. if (!display_notification) { return ui; @@ -171,6 +174,7 @@ std::unique_ptr GetDevicesForDesktopCapture( ui = ScreenCaptureNotificationUI::Create(GetStopSharingUIString( application_title, registered_extension_name, capture_audio, media_id.type)); +#endif return ui; } diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc index 883de4833d8e3..36f49778ac6e5 100644 --- a/chrome/browser/media/media_stream_capture_indicator.cc +++ b/chrome/browser/media/media_stream_capture_indicator.cc @@ -408,8 +408,10 @@ void MediaStreamCaptureIndicator::UpdateNotificationUserInterface() { return; } +#if 0 //NWJS fix issue #4852 // The icon will take the ownership of the passed context menu. MaybeCreateStatusTrayIcon(audio, video); +#endif if (status_icon_) { status_icon_->SetContextMenu(std::move(menu)); } diff --git a/chrome/browser/media/router/media_router.gyp b/chrome/browser/media/router/media_router.gyp index 2785f49ab039d..7eb607c864bef 100644 --- a/chrome/browser/media/router/media_router.gyp +++ b/chrome/browser/media/router/media_router.gyp @@ -37,6 +37,11 @@ '<@(media_router_non_android_sources)', ] }], + [ 'OS!="win"', { + 'sources/': [ ['exclude', '_win(_browsertest|_unittest|_test)?\\.(h|cc)$'], + ['exclude', '(^|/)win/'], + ['exclude', '(^|/)win_[^/]*\\.(h|cc)$'] ], + }], ] }, { diff --git a/chrome/browser/media/router/media_router_dialog_controller.cc b/chrome/browser/media/router/media_router_dialog_controller.cc index 1c89200c7b37e..68b1e97e5c09b 100644 --- a/chrome/browser/media/router/media_router_dialog_controller.cc +++ b/chrome/browser/media/router/media_router_dialog_controller.cc @@ -27,8 +27,10 @@ MediaRouterDialogController::GetOrCreateForWebContents( #if BUILDFLAG(ANDROID_JAVA_UI) return MediaRouterDialogControllerAndroid::GetOrCreateForWebContents( contents); -#else +#elif defined(NWJS_SDK) return MediaRouterDialogControllerImpl::GetOrCreateForWebContents(contents); +#else + return nullptr; #endif } diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation_service_delegate_impl.cc index e29a9057d8c2e..8da5f599a2116 100644 --- a/chrome/browser/media/router/presentation_service_delegate_impl.cc +++ b/chrome/browser/media/router/presentation_service_delegate_impl.cc @@ -732,9 +732,13 @@ void PresentationServiceDelegateImpl::StartSession( weak_factory_.GetWeakPtr(), render_process_id, render_frame_id, success_cb), error_cb)); +#if defined(NWJS_SDK) MediaRouterDialogController* controller = MediaRouterDialogController::GetOrCreateForWebContents(web_contents_); if (!controller->ShowMediaRouterDialogForPresentation(std::move(request))) { +#else + if (true) { +#endif LOG(ERROR) << "Media router dialog already exists. Ignoring StartSession."; error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN, "Unable to create dialog.")); diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc index d7ef150b474e5..39b07c68d51b2 100644 --- a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc +++ b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc @@ -88,6 +88,8 @@ ChromeMetricsServicesManagerClient::GetURLRequestContext() { bool ChromeMetricsServicesManagerClient::IsSafeBrowsingEnabled( const base::Closure& on_update_callback) { + return false; +#if 0 // Start listening for updates to SB service state. This is done here instead // of in the constructor to avoid errors from trying to instantiate SB // service before the IO thread exists. @@ -103,6 +105,7 @@ bool ChromeMetricsServicesManagerClient::IsSafeBrowsingEnabled( } return sb_service && sb_service->enabled_by_prefs(); +#endif } bool ChromeMetricsServicesManagerClient::IsMetricsReportingEnabled() { diff --git a/chrome/browser/notifications/notification_conversion_helper.cc b/chrome/browser/notifications/notification_conversion_helper.cc index c2f8e920c9665..cd7372a73e52b 100644 --- a/chrome/browser/notifications/notification_conversion_helper.cc +++ b/chrome/browser/notifications/notification_conversion_helper.cc @@ -205,7 +205,7 @@ std::string NotificationConversionHelper::MapTypeToString( case message_center::NOTIFICATION_TYPE_CUSTOM: return "custom"; default: - NOTREACHED(); + //NOTREACHED(); return ""; } } diff --git a/chrome/browser/notifications/notification_object_proxy.cc b/chrome/browser/notifications/notification_object_proxy.cc index 15a57b3d0deee..8f5fc8f080f7c 100644 --- a/chrome/browser/notifications/notification_object_proxy.cc +++ b/chrome/browser/notifications/notification_object_proxy.cc @@ -53,7 +53,7 @@ void NotificationObjectProxy::SettingsClick() { } bool NotificationObjectProxy::ShouldDisplaySettingsButton() { - return true; + return false; } std::string NotificationObjectProxy::id() const { diff --git a/chrome/browser/nwjs_resources.grd b/chrome/browser/nwjs_resources.grd new file mode 100644 index 0000000000000..d19c92978ab5f --- /dev/null +++ b/chrome/browser/nwjs_resources.grd @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 103fda4b2c9f0..73c647cb778df 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc @@ -162,9 +162,13 @@ ChromePasswordManagerClient::ChromePasswordManagerClient( ChromePasswordManagerClient::~ChromePasswordManagerClient() {} bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const { +#if 1 + return true; +#else return base::FeatureList::IsEnabled( password_manager::features::kEnableAutomaticPasswordSaving) && chrome::GetChannel() == version_info::Channel::UNKNOWN; +#endif } bool ChromePasswordManagerClient::IsPasswordManagementEnabledForCurrentPage() diff --git a/chrome/browser/password_manager/native_backend_gnome_x.cc b/chrome/browser/password_manager/native_backend_gnome_x.cc index ded031e6053e3..ea9f7f2c939a9 100644 --- a/chrome/browser/password_manager/native_backend_gnome_x.cc +++ b/chrome/browser/password_manager/native_backend_gnome_x.cc @@ -105,7 +105,7 @@ bool GnomeKeyringLoader::LoadGnomeKeyring() { namespace { -const char kGnomeKeyringAppString[] = "chrome"; +const char kGnomeKeyringAppString[] = "nwjs"; // Convert the attributes of a given keyring entry into a new PasswordForm. // Note: does *not* get the actual password, as that is not a key attribute! diff --git a/chrome/browser/password_manager/native_backend_libsecret.cc b/chrome/browser/password_manager/native_backend_libsecret.cc index 7d5b258c12381..495e721b3411d 100644 --- a/chrome/browser/password_manager/native_backend_libsecret.cc +++ b/chrome/browser/password_manager/native_backend_libsecret.cc @@ -35,7 +35,7 @@ const int kMaxPossibleTimeTValue = std::numeric_limits::max(); namespace { -const char kLibsecretAppString[] = "chrome"; +const char kLibsecretAppString[] = "nwjs"; // Schema is analagous to the fields in PasswordForm. const SecretSchema kLibsecretSchema = { diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index b3a8bf944365a..c6b267da1da3e 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -425,7 +425,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { DownloadPrefs::RegisterProfilePrefs(registry); HostContentSettingsMap::RegisterProfilePrefs(registry); IncognitoModePrefs::RegisterProfilePrefs(registry); - InstantUI::RegisterProfilePrefs(registry); + //InstantUI::RegisterProfilePrefs(registry); NavigationCorrectionTabObserver::RegisterProfilePrefs(registry); MediaCaptureDevicesDispatcher::RegisterProfilePrefs(registry); MediaDeviceIDSalt::RegisterProfilePrefs(registry); diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc index d5394b857a367..5c8c8ba754f48 100644 --- a/chrome/browser/process_singleton_posix.cc +++ b/chrome/browser/process_singleton_posix.cc @@ -99,12 +99,43 @@ using content::BrowserThread; namespace { +// XXX: +class SanitizedSocketPath { + public: + explicit SanitizedSocketPath(const base::FilePath& socket_path) + : socket_path_(socket_path) { + if (socket_path.value().length() >= arraysize(sockaddr_un::sun_path)) { + bool found_current_dir = GetCurrentDirectory(&old_path_); + CHECK(found_current_dir) << "Failed to determine the current directory."; + changed_directory_ = SetCurrentDirectory(socket_path.DirName()); + CHECK(changed_directory_) << "Failed to change directory: " << + socket_path.DirName().value(); + } + } + + ~SanitizedSocketPath() { + if (changed_directory_) + SetCurrentDirectory(old_path_); + } + + base::FilePath SocketPath() const { + return changed_directory_ ? socket_path_.BaseName() : socket_path_; + } + + private: + bool changed_directory_ = false; + base::FilePath socket_path_; + base::FilePath old_path_; + + DISALLOW_COPY_AND_ASSIGN(SanitizedSocketPath); +}; + // Timeout for the current browser process to respond. 20 seconds should be // enough. -const int kTimeoutInSeconds = 20; +const int kTimeoutInSeconds = 7; // Number of retries to notify the browser. 20 retries over 20 seconds = 1 try // per second. -const int kRetryAttempts = 20; +const int kRetryAttempts = 7; static bool g_disable_prompt; const char kStartToken[] = "START"; const char kACKToken[] = "ACK"; @@ -379,13 +410,16 @@ bool ConnectSocket(ScopedSocket* socket, return false; // Now we know the directory was (at that point) created by the profile // owner. Try to connect. - sockaddr_un addr; - SetupSockAddr(socket_target.value(), &addr); - int ret = HANDLE_EINTR(connect(socket->fd(), - reinterpret_cast(&addr), - sizeof(addr))); - if (ret != 0) - return false; + { + SanitizedSocketPath sanitized_socket_target(socket_target); + sockaddr_un addr; + SetupSockAddr(sanitized_socket_target.SocketPath().value(), &addr); + int ret = HANDLE_EINTR(connect(socket->fd(), + reinterpret_cast(&addr), + sizeof(addr))); + if (ret != 0) + return false; + } // Check the cookie again. We only link in /tmp, which is sticky, so, if the // directory is still correct, it must have been correct in-between when we // connected. POSIX, sadly, lacks a connectat(). @@ -398,8 +432,9 @@ bool ConnectSocket(ScopedSocket* socket, } else if (errno == EINVAL) { // It exists, but is not a symlink (or some other error we detect // later). Just connect to it directly; this is an older version of Chrome. + SanitizedSocketPath sanitized_socket_path(socket_path); sockaddr_un addr; - SetupSockAddr(socket_path.value(), &addr); + SetupSockAddr(sanitized_socket_path.SocketPath().value(), &addr); int ret = HANDLE_EINTR(connect(socket->fd(), reinterpret_cast(&addr), sizeof(addr))); @@ -992,12 +1027,15 @@ bool ProcessSingleton::Create() { return false; } - SetupSocket(socket_target_path.value(), &sock, &addr); + { + SanitizedSocketPath sanitized_socket_target(socket_target_path); + SetupSocket(sanitized_socket_target.SocketPath().value(), &sock, &addr); - if (bind(sock, reinterpret_cast(&addr), sizeof(addr)) < 0) { - PLOG(ERROR) << "Failed to bind() " << socket_target_path.value(); - CloseSocket(sock); - return false; + if (bind(sock, reinterpret_cast(&addr), sizeof(addr)) < 0) { + PLOG(ERROR) << "Failed to bind() " << socket_target_path.value(); + CloseSocket(sock); + return false; + } } if (listen(sock, 5) < 0) diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 1d9a295ea87c1..214cd8d0ec5e6 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc @@ -168,7 +168,7 @@ EnsureBrowserContextKeyedServiceFactoriesBuilt() { extensions::EnsureBrowserContextKeyedServiceFactoriesBuilt(); extensions::ExtensionManagementFactory::GetInstance(); chrome_extensions::EnsureBrowserContextKeyedServiceFactoriesBuilt(); - AppShortcutManagerFactory::GetInstance(); + //AppShortcutManagerFactory::GetInstance(); #endif #if defined(ENABLE_APP_LIST) diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index ff1acb838d9ff..a722264fd9d6b 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -449,12 +449,14 @@ ProfileImpl::ProfileImpl( path_, sequenced_task_runner, create_mode == CREATE_MODE_SYNCHRONOUS); #endif +#if 0 scoped_refptr safe_browsing_service( g_browser_process->safe_browsing_service()); if (safe_browsing_service.get()) { pref_validation_delegate_ = safe_browsing_service->CreatePreferenceValidationDelegate(this); } +#endif content::BrowserContext::Initialize(this, path_); diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 29806d4694791..80342d9e5b3c2 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc @@ -5,6 +5,10 @@ #include "chrome/browser/profiles/profile_impl_io_data.h" #include + +#include "content/nw/src/nw_base.h" +#include "extensions/common/manifest_constants.h" + #include #include #include @@ -582,6 +586,10 @@ void ProfileImplIOData:: extensions_context->set_net_log(io_thread->net_log()); + std::string domain; + if (nw::package()->root()->GetString(extensions::manifest_keys::kNWJSDomain, &domain)) { + extensions_context->set_cookie_store(main_request_context()->cookie_store()); + } else { content::CookieStoreConfig cookie_config( lazy_params_->extensions_cookie_path, lazy_params_->session_cookie_mode, @@ -591,6 +599,7 @@ void ProfileImplIOData:: cookie_config.cookieable_schemes.push_back(extensions::kExtensionScheme); extensions_cookie_store_ = content::CreateCookieStore(cookie_config); extensions_context->set_cookie_store(extensions_cookie_store_.get()); + } std::unique_ptr extensions_job_factory( new net::URLRequestJobFactoryImpl()); diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc index 20aed8a16d413..cfddcc75d7299 100644 --- a/chrome/browser/profiles/profile_info_cache.cc +++ b/chrome/browser/profiles/profile_info_cache.cc @@ -911,7 +911,7 @@ void ProfileInfoCache::DownloadHighResAvatarIfNeeded( size_t icon_index, const base::FilePath& profile_path) { // Downloading is only supported on desktop. -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) +#if 1 return; #endif DCHECK(!disable_avatar_download_for_testing_); diff --git a/chrome/browser/renderer_context_menu/context_menu_content_type_platform_app.cc b/chrome/browser/renderer_context_menu/context_menu_content_type_platform_app.cc index 3df598de7e9f4..5c8b7353eb885 100644 --- a/chrome/browser/renderer_context_menu/context_menu_content_type_platform_app.cc +++ b/chrome/browser/renderer_context_menu/context_menu_content_type_platform_app.cc @@ -11,6 +11,8 @@ #include "extensions/common/extension.h" #include "extensions/common/manifest.h" +#include "content/nw/src/common/shell_switches.h" + using extensions::Extension; using extensions::ProcessManager; @@ -39,6 +41,14 @@ bool ContextMenuContentTypePlatformApp::SupportsGroup(int group) { DCHECK(platform_app->is_platform_app()); +#if defined(NWJS_SDK) + bool enable_devtools = true; + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kDisableDevTools)) + enable_devtools = false; +#endif + switch (group) { // Add undo/redo, cut/copy/paste etc for text fields. case ITEM_GROUP_EDITABLE: @@ -46,12 +56,10 @@ bool ContextMenuContentTypePlatformApp::SupportsGroup(int group) { return ContextMenuContentType::SupportsGroup(group); case ITEM_GROUP_CURRENT_EXTENSION: return true; +#if defined(NWJS_SDK) case ITEM_GROUP_DEVTOOLS_UNPACKED_EXT: - // Add dev tools for unpacked extensions. - return extensions::Manifest::IsUnpackedLocation( - platform_app->location()) || - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDebugPackedApps); + return enable_devtools; +#endif default: return false; } diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 66bf27abe8276..c6b357aadfff3 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc @@ -6,6 +6,8 @@ #include +#include "content/nw/src/common/shell_switches.h" + #include #include #include @@ -818,15 +820,25 @@ void RenderViewContextMenu::InitMenu() { AppendCurrentExtensionItems(); } +#if defined(NWJS_SDK) + bool enable_devtools = true; + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kDisableDevTools)) + enable_devtools = false; + if (content_type_->SupportsGroup( ContextMenuContentType::ITEM_GROUP_DEVELOPER)) { + if (enable_devtools) AppendDeveloperItems(); } if (content_type_->SupportsGroup( ContextMenuContentType::ITEM_GROUP_DEVTOOLS_UNPACKED_EXT)) { + if (enable_devtools) AppendDevtoolsForUnpackedExtensions(); } +#endif if (content_type_->SupportsGroup( ContextMenuContentType::ITEM_GROUP_PRINT_PREVIEW)) { @@ -1181,6 +1193,7 @@ void RenderViewContextMenu::AppendPageItems() { menu_model_.AddItemWithStringId(IDC_PRINT, IDS_CONTENT_CONTEXT_PRINT); AppendMediaRouterItem(); +#if 0 if (TranslateService::IsTranslatableURL(params_.page_url)) { std::string locale = g_browser_process->GetApplicationLocale(); locale = translate::TranslateDownloadManager::GetLanguageCode(locale); @@ -1191,6 +1204,7 @@ void RenderViewContextMenu::AppendPageItems() { l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_TRANSLATE, language)); AddGoogleIconToLastMenuItem(&menu_model_); } +#endif } void RenderViewContextMenu::AppendCopyItem() { @@ -1281,7 +1295,11 @@ void RenderViewContextMenu::AppendSearchProvider() { } void RenderViewContextMenu::AppendEditableItems() { - const bool use_spelling = !chrome::IsRunningInForcedAppMode(); + bool use_spelling = !chrome::IsRunningInForcedAppMode(); + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(switches::kEnableSpellChecking)) + use_spelling = false; if (use_spelling) AppendSpellingSuggestionItems(); @@ -1320,6 +1338,7 @@ void RenderViewContextMenu::AppendEditableItems() { } void RenderViewContextMenu::AppendLanguageSettings() { +#if 0 const bool use_spelling = !chrome::IsRunningInForcedAppMode(); if (!use_spelling) return; @@ -1337,6 +1356,7 @@ void RenderViewContextMenu::AppendLanguageSettings() { spelling_options_submenu_observer_->InitMenu(params_); observers_.AddObserver(spelling_options_submenu_observer_.get()); #endif +#endif } void RenderViewContextMenu::AppendSpellingSuggestionItems() { @@ -1465,6 +1485,8 @@ bool RenderViewContextMenu::IsCommandIdEnabled(int id) const { return IsDevCommandEnabled(id); case IDC_CONTENT_CONTEXT_TRANSLATE: { + return false; +#if 0 ChromeTranslateClient* chrome_translate_client = ChromeTranslateClient::FromWebContents(embedder_web_contents_); // If no |chrome_translate_client| attached with this WebContents or we're @@ -1493,6 +1515,7 @@ bool RenderViewContextMenu::IsCommandIdEnabled(int id) const { target_lang) && // Disable on the Instant Extended NTP. !search::IsInstantNTP(embedder_web_contents_); +#endif } case IDC_CONTENT_CONTEXT_OPENLINKNEWTAB: @@ -2059,6 +2082,7 @@ void RenderViewContextMenu::ExecuteCommand(int id, int event_flags) { } case IDC_CONTENT_CONTEXT_TRANSLATE: { +#if 0 // A translation might have been triggered by the time the menu got // selected, do nothing in that case. ChromeTranslateClient* chrome_translate_client = @@ -2084,9 +2108,9 @@ void RenderViewContextMenu::ExecuteCommand(int id, int event_flags) { chrome_translate_client->GetTranslateManager(); DCHECK(manager); manager->TranslatePage(original_lang, target_lang, true); +#endif break; } - case IDC_CONTENT_CONTEXT_RELOADFRAME: // We always obey the cache here. // TODO(evanm): Perhaps we could allow shift-clicking the menu item to do diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index 774cef9b4bb3a..3883dd9e8c93e 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc @@ -246,6 +246,7 @@ void AppendComponentUpdaterThrottles( content::ResourceContext* resource_context, ResourceType resource_type, ScopedVector* throttles) { +#if 0 const char* crx_id = NULL; component_updater::ComponentUpdateService* cus = g_browser_process->component_updater(); @@ -268,6 +269,7 @@ void AppendComponentUpdaterThrottles( throttles->push_back( component_updater::GetOnDemandResourceThrottle(cus, crx_id)); } +#endif } #endif // !defined(DISABLE_NACL) @@ -386,8 +388,10 @@ void ChromeResourceDispatcherHostDelegate::RequestBeginning( content::AppCacheService* appcache_service, ResourceType resource_type, ScopedVector* throttles) { +#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING) if (safe_browsing_.get()) safe_browsing_->OnResourceRequest(request); +#endif const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); bool is_prerendering = diff --git a/chrome/browser/renderer_preferences_util.cc b/chrome/browser/renderer_preferences_util.cc index 1a1a910a0b300..d3584506dd5e6 100644 --- a/chrome/browser/renderer_preferences_util.cc +++ b/chrome/browser/renderer_preferences_util.cc @@ -28,6 +28,8 @@ #include "ui/views/linux_ui/linux_ui.h" #endif +#include "content/nw/src/nw_content.h" + namespace renderer_preferences_util { void UpdateFromSystemSettings(content::RendererPreferences* prefs, @@ -109,6 +111,9 @@ void UpdateFromSystemSettings(content::RendererPreferences* prefs, prefs->plugin_fullscreen_allowed = pref_service->GetBoolean(prefs::kFullscreenAllowed); #endif + std::string user_agent; + if (nw::GetUserAgentFromManifest(&user_agent)) + prefs->user_agent_override = user_agent; } } // namespace renderer_preferences_util diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd index 84d0f8a162370..184394417254e 100644 --- a/chrome/browser/resources/component_extension_resources.grd +++ b/chrome/browser/resources/component_extension_resources.grd @@ -25,6 +25,7 @@ + @@ -32,6 +33,7 @@ + @@ -155,6 +157,9 @@ + + + @@ -201,6 +206,8 @@ + + @@ -257,6 +264,7 @@ to be the only viable option at the moment. --> + diff --git a/chrome/browser/resources/empty.css b/chrome/browser/resources/empty.css new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/chrome/browser/resources/empty.html b/chrome/browser/resources/empty.html new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/chrome/browser/resources/empty.js b/chrome/browser/resources/empty.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/chrome/browser/resources/empty.json b/chrome/browser/resources/empty.json new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/chrome/browser/resources/empty.png b/chrome/browser/resources/empty.png new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/chrome/browser/resources/nwjs/default.js b/chrome/browser/resources/nwjs/default.js new file mode 100644 index 0000000000000..a5e1ce27fb418 --- /dev/null +++ b/chrome/browser/resources/nwjs/default.js @@ -0,0 +1,46 @@ +//console.log("NWJS/DEFAULT.JS"); +var manifest = chrome.runtime.getManifest(); +var options = {}; +var title = null; +if (manifest.window) { + if (manifest.window.id) + options.id = manifest.window.id; + options.innerBounds = {}; + if (manifest.window.frame === false) + options.frame = 'none'; + if (manifest.window.resizable === false) + options.resizable = false; + if (manifest.window.height) + options.innerBounds.height = manifest.window.height; + if (manifest.window.width) + options.innerBounds.width = manifest.window.width; + if (manifest.window.min_width) + options.innerBounds.minWidth = manifest.window.min_width; + if (manifest.window.max_width) + options.innerBounds.maxWidth = manifest.window.max_width; + if (manifest.window.min_height) + options.innerBounds.minHeight = manifest.window.min_height; + if (manifest.window.max_height) + options.innerBounds.maxHeight = manifest.window.max_height; + if (manifest.window.fullscreen === true) + options.state = 'fullscreen'; + if (manifest.window.show === false) + options.hidden = true; + if (manifest.window.show_in_taskbar === false) + options.show_in_taskbar = false; + if (manifest.window['always_on_top'] === true) + options.alwaysOnTop = true; + if (manifest.window['visible_on_all_workspaces'] === true) + options.visibleOnAllWorkspaces = true; + if (manifest.window.transparent) + options.alphaEnabled = true; + if (manifest.window.kiosk === true) + options.kiosk = true; + if (manifest.window.position) + options.position = manifest.window.position; + if (manifest.window.title) + options.title = manifest.window.title; +} + +chrome.app.window.create(manifest.main, options, function(win) { +}); diff --git a/chrome/browser/resources/nwjs_default_app/main.js b/chrome/browser/resources/nwjs_default_app/main.js new file mode 100644 index 0000000000000..4ee5538332f0b --- /dev/null +++ b/chrome/browser/resources/nwjs_default_app/main.js @@ -0,0 +1,7 @@ +var manifest = chrome.runtime.getManifest(); +var url = manifest.cmdlineUrl || 'nw_blank.html'; +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create( + url, + {'id': 'nwjs_default_app', 'height': 550, 'width': 750}); +}); diff --git a/chrome/browser/resources/nwjs_default_app/manifest.json b/chrome/browser/resources/nwjs_default_app/manifest.json new file mode 100644 index 0000000000000..1e9c9e219ebcd --- /dev/null +++ b/chrome/browser/resources/nwjs_default_app/manifest.json @@ -0,0 +1,17 @@ +{ + //id: aafddpmiffkameplnjkglahmbnbgidce + "key":"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgmO8NbDyu8AB/Cudz33l3kkgPbIeYaitcYgn4RBJdNRPjJ2sRy0icbVMyZjXhNV81vuH60ZO5PiBmVIp6v49Aq2RSkFVbwPw0y1Yo6UgATlaaEKEJV2VGrlQJaN12bGM/Dz8KGuHVGTbtqHS+B0QyQJMAbXLJ8HkmvJPlUQZf3QIDAQAB", + "name": "NWJS Default", + "version": "0.1", + "manifest_version": 2, + "description": "NWJS default app", + "app": { + "background": { + "scripts": [ "main.js" ] + } + }, + "permissions": [ + "node", "proxy", "" + ], + "display_in_launcher": false +} diff --git a/chrome/browser/resources/nwjs_default_app/nw_blank.html b/chrome/browser/resources/nwjs_default_app/nw_blank.html new file mode 100644 index 0000000000000..cda95d6c72fe9 --- /dev/null +++ b/chrome/browser/resources/nwjs_default_app/nw_blank.html @@ -0,0 +1,74 @@ + + + +nw.js + + + +
+

NW.js

+
+
+ nw.js v
+ Node v
+ Chromium
+ commit hash:
+
+ + diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js index dab584d9d0bdc..7c5250fee0896 100644 --- a/chrome/browser/resources/pdf/pdf.js +++ b/chrome/browser/resources/pdf/pdf.js @@ -629,7 +629,7 @@ PDFViewer.prototype = { if (this.isPrintPreview_) this.navigator_.navigate(message.data.url, true); else - this.navigator_.navigate(message.data.url, message.data.newTab); + this.navigator_.navigate(message.data.url, true); //message.data.newTab); break; case 'setScrollPosition': var position = this.viewport_.position; diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js index acbfae038781a..4461a72739db1 100644 --- a/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chrome/browser/resources/print_preview/data/destination_store.js @@ -429,8 +429,10 @@ cr.define('print_preview', function() { init: function( isInAppKioskMode, systemDefaultDestinationId, - serializedDefaultDestinationSelectionRulesStr) { + serializedDefaultDestinationSelectionRulesStr, + isInNWPrintMode) { this.pdfPrinterEnabled_ = !isInAppKioskMode; + this.isInNWPrintMode_ = isInNWPrintMode; this.systemDefaultDestinationId_ = systemDefaultDestinationId; this.createLocalPdfPrintDestination_(); @@ -458,7 +460,7 @@ cr.define('print_preview', function() { var capabilities = null; var extensionId = ''; var extensionName = ''; - if (this.appState_.selectedDestinationId && + if (this.appState_.selectedDestinationId && !this.isInNWPrintMode_ && this.appState_.selectedDestinationOrigin) { origin = this.appState_.selectedDestinationOrigin; id = this.appState_.selectedDestinationId; @@ -672,7 +674,7 @@ cr.define('print_preview', function() { * @private */ convertPreselectedToDestinationMatch_: function() { - if (this.appState_.selectedDestinationId && + if (this.appState_.selectedDestinationId && !this.isInNWPrintMode_ && this.appState_.selectedDestinationOrigin) { return this.createExactDestinationMatch_( this.appState_.selectedDestinationOrigin, diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js index 2cf0eaf6ea198..055bdd5b61867 100644 --- a/chrome/browser/resources/print_preview/native_layer.js +++ b/chrome/browser/resources/print_preview/native_layer.js @@ -490,7 +490,8 @@ cr.define('print_preview', function() { initialSettings['shouldPrintSelectionOnly'] || false, initialSettings['printerName'] || null, initialSettings['appState'] || null, - initialSettings['defaultDestinationSelectionRules'] || null); + initialSettings['defaultDestinationSelectionRules'] || null, + initialSettings['nwPrintMode'] || false); var initialSettingsSetEvent = new Event( NativeLayer.EventType.INITIAL_SETTINGS_SET); @@ -946,8 +947,10 @@ cr.define('print_preview', function() { selectionOnly, systemDefaultDestinationId, serializedAppStateStr, - serializedDefaultDestinationSelectionRulesStr) { + serializedDefaultDestinationSelectionRulesStr, + nwPrintMode) { + this.isNWPrintMode_ = nwPrintMode; /** * Whether the print preview should be in auto-print mode. * @type {boolean} @@ -1035,6 +1038,9 @@ cr.define('print_preview', function() { }; NativeInitialSettings.prototype = { + get isInNWPrintMode() { + return this.isNWPrintMode_; + }, /** * @return {boolean} Whether the print preview should be in auto-print mode. */ diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js index 56899206b3973..4efc3a29ef923 100644 --- a/chrome/browser/resources/print_preview/print_preview.js +++ b/chrome/browser/resources/print_preview/print_preview.js @@ -647,7 +647,8 @@ cr.define('print_preview', function() { this.destinationStore_.init( settings.isInAppKioskMode, settings.systemDefaultDestinationId, - settings.serializedDefaultDestinationSelectionRulesStr); + settings.serializedDefaultDestinationSelectionRulesStr, + settings.isInNWPrintMode); this.appState_.setInitialized(); $('document-title').innerText = settings.documentTitle; diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc index d6f5c6509ba51..32fae6588f201 100644 --- a/chrome/browser/shell_integration_linux.cc +++ b/chrome/browser/shell_integration_linux.cc @@ -49,6 +49,8 @@ #include "chrome/common/chrome_switches.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" +#include "content/nw/src/nw_base.h" +#include "content/nw/src/nw_package.h" #include "grit/chrome_unscaled_resources.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image_family.h" @@ -571,12 +573,15 @@ std::vector GetDataSearchLocations(base::Environment* env) { } std::string GetProgramClassName() { + return nw::package()->GetName(); +#if 0 std::unique_ptr env(base::Environment::Create()); std::string desktop_file(GetDesktopName(env.get())); std::size_t last = desktop_file.find(".desktop"); if (last != std::string::npos) return desktop_file.substr(0, last); return desktop_file; +#endif } std::string GetDesktopName(base::Environment* env) { diff --git a/chrome/browser/spellchecker/feedback.cc b/chrome/browser/spellchecker/feedback.cc index cfc4a711b3c9c..62cc5a9423e5b 100644 --- a/chrome/browser/spellchecker/feedback.cc +++ b/chrome/browser/spellchecker/feedback.cc @@ -26,7 +26,7 @@ namespace spellcheck { Feedback::Feedback(size_t max_total_text_size) - : max_total_text_size_(max_total_text_size), total_text_size_(0) { + : empty_hash_collection_(), max_total_text_size_(max_total_text_size), total_text_size_(0) { DCHECK_GE(max_total_text_size, 1024U); } diff --git a/chrome/browser/spellchecker/spellcheck_factory.cc b/chrome/browser/spellchecker/spellcheck_factory.cc index 3fd085b9fc1b7..207a53dcba906 100644 --- a/chrome/browser/spellchecker/spellcheck_factory.cc +++ b/chrome/browser/spellchecker/spellcheck_factory.cc @@ -75,7 +75,7 @@ void SpellcheckServiceFactory::RegisterProfilePrefs( user_prefs->RegisterStringPref( prefs::kSpellCheckDictionary, l10n_util::GetStringUTF8(IDS_SPELLCHECK_DICTIONARY)); - user_prefs->RegisterBooleanPref(prefs::kSpellCheckUseSpellingService, false); + user_prefs->RegisterBooleanPref(prefs::kSpellCheckUseSpellingService, true); user_prefs->RegisterBooleanPref( prefs::kEnableContinuousSpellcheck, true, diff --git a/chrome/browser/status_icons/status_icon.h b/chrome/browser/status_icons/status_icon.h index 0eaaf247f9733..291ca770fd60e 100644 --- a/chrome/browser/status_icons/status_icon.h +++ b/chrome/browser/status_icons/status_icon.h @@ -72,11 +72,11 @@ class StatusIcon { // thread to do it. Use sparingly. virtual void ForceVisible(); - protected: + public: // Invoked after a call to SetContextMenu() to let the platform-specific // subclass update the native context menu based on the new model. If NULL is // passed, subclass should destroy the native context menu. - virtual void UpdatePlatformContextMenu(StatusIconMenuModel* model) = 0; + virtual void UpdatePlatformContextMenu(ui::MenuModel* model) = 0; private: base::ObserverList observers_; diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index 0f71827875aea..7c1f5f364560c 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc @@ -205,6 +205,7 @@ void SupervisedUserService::Init() { if (sync_service) sync_service->AddPreferenceProvider(this); +#if 0 std::string client_id = component_updater::SupervisedUserWhitelistInstaller:: ClientIdForProfilePath(profile_->GetPath()); whitelist_service_.reset(new SupervisedUserWhitelistService( @@ -213,6 +214,7 @@ void SupervisedUserService::Init() { whitelist_service_->AddSiteListsChangedCallback( base::Bind(&SupervisedUserService::OnSiteListsChanged, weak_ptr_factory_.GetWeakPtr())); +#endif SetActive(ProfileIsSupervised()); } diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc index c658357ac0b44..ffd3e918a07f0 100644 --- a/chrome/browser/ui/apps/chrome_app_delegate.cc +++ b/chrome/browser/ui/apps/chrome_app_delegate.cc @@ -8,6 +8,12 @@ #include #include "base/macros.h" + +#include "chrome/browser/sessions/session_tab_helper.h" +#include "chrome/browser/extensions/tab_helper.h" +#include "chrome/browser/password_manager/chrome_password_manager_client.h" +#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" + #include "base/strings/stringprintf.h" #include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/chrome_notification_types.h" @@ -51,10 +57,16 @@ #endif // defined(ENABLE_PRINT_PREVIEW) #endif // defined(ENABLE_PRINTING) +#include "chrome/browser/browser_process.h" +#include "chrome/browser/ui/autofill/chrome_autofill_client.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include "components/autofill/core/browser/autofill_manager.h" +#include "chrome/browser/ui/prefs/prefs_tab_helper.h" + namespace { // Time to wait for an app window to show before allowing Chrome to quit. -int kAppWindowFirstShowTimeoutSeconds = 10; +//int kAppWindowFirstShowTimeoutSeconds = 10; bool disable_external_open_for_testing_ = false; @@ -69,7 +81,7 @@ content::WebContents* OpenURLFromTabInternal( if (params.disposition == NEW_BACKGROUND_TAB) { new_tab_params.disposition = NEW_BACKGROUND_TAB; } else { - new_tab_params.disposition = NEW_FOREGROUND_TAB; + new_tab_params.disposition = NEW_POPUP; new_tab_params.window_action = chrome::NavigateParams::SHOW_WINDOW; } @@ -160,6 +172,7 @@ ChromeAppDelegate::ChromeAppDelegate(bool keep_alive) : has_been_shown_(false), is_hidden_(true), new_window_contents_delegate_(new NewWindowContentsDelegate()), + web_contents_(nullptr), weak_factory_(this) { if (keep_alive) { keep_alive_.reset(new ScopedKeepAlive(KeepAliveOrigin::CHROME_APP_DELEGATE, @@ -180,6 +193,8 @@ void ChromeAppDelegate::DisableExternalOpenForTesting() { } void ChromeAppDelegate::InitWebContents(content::WebContents* web_contents) { + web_contents_ = web_contents; + favicon::CreateContentFaviconDriverForWebContents(web_contents); #if defined(ENABLE_PRINTING) @@ -190,12 +205,31 @@ void ChromeAppDelegate::InitWebContents(content::WebContents* web_contents) { printing::PrintViewManagerBasic::CreateForWebContents(web_contents); #endif // defined(ENABLE_PRINT_PREVIEW) #endif // defined(ENABLE_PRINTING) + // Kiosk app supports zooming. + //if (chrome::IsRunningInForcedAppMode()) + // ZoomController comes before common tab helpers since ChromeExtensionWebContentsObserver + // may want to register as a ZoomObserver with it. + ui_zoom::ZoomController::CreateForWebContents(web_contents); + +#if 1 + extensions::TabHelper::CreateForWebContents(web_contents); +#else + SessionTabHelper::CreateForWebContents(web_contents); + extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( web_contents); - - // Kiosk app supports zooming. - if (chrome::IsRunningInForcedAppMode()) - ui_zoom::ZoomController::CreateForWebContents(web_contents); +#endif + autofill::ChromeAutofillClient::CreateForWebContents(web_contents); + autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate( + web_contents, + autofill::ChromeAutofillClient::FromWebContents(web_contents), + g_browser_process->GetApplicationLocale(), + autofill::AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER); + ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( + web_contents, + autofill::ChromeAutofillClient::FromWebContents(web_contents)); + ManagePasswordsUIController::CreateForWebContents(web_contents); + PrefsTabHelper::CreateForWebContents(web_contents); } void ChromeAppDelegate::RenderViewCreated( @@ -235,11 +269,13 @@ void ChromeAppDelegate::AddNewContents(content::BrowserContext* context, bool user_gesture, bool* was_blocked) { if (!disable_external_open_for_testing_) { +#if 0 // We don't really want to open a window for |new_contents|, but we need to // capture its intended navigation. Here we give ownership to the // NewWindowContentsDelegate, which will dispose of the contents once // a navigation is captured. new_contents->SetDelegate(new_window_contents_delegate_.get()); +#endif return; } chrome::ScopedTabbedBrowserDisplayer displayer( @@ -320,6 +356,7 @@ void ChromeAppDelegate::SetTerminatingCallback(const base::Closure& callback) { void ChromeAppDelegate::OnHide() { is_hidden_ = true; +#if 0 if (has_been_shown_) { keep_alive_.reset(); return; @@ -332,13 +369,16 @@ void ChromeAppDelegate::OnHide() { base::Bind(&ChromeAppDelegate::RelinquishKeepAliveAfterTimeout, weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(kAppWindowFirstShowTimeoutSeconds)); +#endif } void ChromeAppDelegate::OnShow() { has_been_shown_ = true; is_hidden_ = false; +#if 0 keep_alive_.reset(new ScopedKeepAlive(KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::DISABLED)); +#endif } void ChromeAppDelegate::Observe(int type, diff --git a/chrome/browser/ui/apps/chrome_app_delegate.h b/chrome/browser/ui/apps/chrome_app_delegate.h index 568c8a47aa33d..0401e36b518cb 100644 --- a/chrome/browser/ui/apps/chrome_app_delegate.h +++ b/chrome/browser/ui/apps/chrome_app_delegate.h @@ -70,7 +70,6 @@ class ChromeAppDelegate : public extensions::AppDelegate, void SetTerminatingCallback(const base::Closure& callback) override; void OnHide() override; void OnShow() override; - // content::NotificationObserver: void Observe(int type, const content::NotificationSource& source, @@ -82,6 +81,7 @@ class ChromeAppDelegate : public extensions::AppDelegate, std::unique_ptr new_window_contents_delegate_; base::Closure terminating_callback_; content::NotificationRegistrar registrar_; + content::WebContents* web_contents_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(ChromeAppDelegate); diff --git a/chrome/browser/ui/apps/chrome_app_window_client.cc b/chrome/browser/ui/apps/chrome_app_window_client.cc index 1fa807fcd059e..4253b77bfd126 100644 --- a/chrome/browser/ui/apps/chrome_app_window_client.cc +++ b/chrome/browser/ui/apps/chrome_app_window_client.cc @@ -13,6 +13,8 @@ #include "extensions/browser/app_window/app_window.h" #include "extensions/common/extension.h" +#include "content/nw/src/nw_content.h" + // TODO(jamescook): We probably shouldn't compile this class at all on Android. // See http://crbug.com/343612 #if !defined(OS_ANDROID) @@ -38,8 +40,10 @@ extensions::AppWindow* ChromeAppWindowClient::CreateAppWindow( #if defined(OS_ANDROID) return NULL; #else - return new extensions::AppWindow(context, new ChromeAppDelegate(true), + extensions::AppWindow* ret = new extensions::AppWindow(context, new ChromeAppDelegate(true), extension); + nw::CreateAppWindowHook(ret); + return ret; #endif } diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index e551474c1f4a0..95a05eec2baea 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -297,7 +297,7 @@ content::SecurityStyle SecurityLevelToSecurityStyle( // Browser, CreateParams: Browser::CreateParams::CreateParams(Profile* profile) - : type(TYPE_TABBED), + : type(TYPE_POPUP), profile(profile), trusted_source(false), initial_show_state(ui::SHOW_STATE_DEFAULT), @@ -305,7 +305,7 @@ Browser::CreateParams::CreateParams(Profile* profile) window(NULL) {} Browser::CreateParams::CreateParams(Type type, Profile* profile) - : type(type), + : type(TYPE_POPUP), profile(profile), trusted_source(false), initial_show_state(ui::SHOW_STATE_DEFAULT), @@ -1746,7 +1746,8 @@ void Browser::WebContentsCreated(WebContents* source_contents, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, - WebContents* new_contents) { + WebContents* new_contents, + const base::string16& nw_window_manifest) { // Adopt the WebContents now, so all observers are in place, as the network // requests for its initial navigation will start immediately. The WebContents // will later be inserted into this browser using Browser::Navigate via @@ -2214,11 +2215,13 @@ void Browser::OnExtensionUnloaded( void Browser::OnIsPageTranslatedChanged(content::WebContents* source) { DCHECK(source); +#if 0 if (tab_strip_model_->GetActiveWebContents() == source) { window_->SetTranslateIconToggled( ChromeTranslateClient::FromWebContents( source)->GetLanguageState().IsPageTranslated()); } +#endif } void Browser::OnTranslateEnabledChanged(content::WebContents* source) { @@ -2483,15 +2486,15 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) { SetDelegate(delegate); CoreTabHelper::FromWebContents(web_contents)->set_delegate(delegate); SearchTabHelper::FromWebContents(web_contents)->set_delegate(delegate); - translate::ContentTranslateDriver& content_translate_driver = - ChromeTranslateClient::FromWebContents(web_contents)->translate_driver(); + // translate::ContentTranslateDriver& content_translate_driver = + // ChromeTranslateClient::FromWebContents(web_contents)->translate_driver(); if (delegate) { ui_zoom::ZoomController::FromWebContents(web_contents)->AddObserver(this); - content_translate_driver.AddObserver(this); + //content_translate_driver.AddObserver(this); } else { ui_zoom::ZoomController::FromWebContents(web_contents)->RemoveObserver( this); - content_translate_driver.RemoveObserver(this); + //content_translate_driver.RemoveObserver(this); } } diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 2196898ed2b21..f4f072dd36168 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -621,7 +621,8 @@ class Browser : public TabStripModelObserver, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, - content::WebContents* new_contents) override; + content::WebContents* new_contents, + const base::string16& nw_window_manifest) override; void RendererUnresponsive(content::WebContents* source) override; void RendererResponsive(content::WebContents* source) override; void DidNavigateMainFramePostCommit( diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index c599839c5d205..dd939e2633635 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc @@ -328,6 +328,7 @@ int GetContentRestrictions(const Browser* browser) { } void NewEmptyWindow(Profile* profile) { +#if 0 bool incognito = profile->IsOffTheRecord(); PrefService* prefs = profile->GetPrefs(); if (incognito) { @@ -355,6 +356,7 @@ void NewEmptyWindow(Profile* profile) { OpenEmptyWindow(profile->GetOriginalProfile()); } } +#endif } Browser* OpenEmptyWindow(Profile* profile) { @@ -809,6 +811,7 @@ void SaveCreditCard(Browser* browser) { } void Translate(Browser* browser) { +#if 0 if (!browser->window()->IsActive()) return; @@ -826,6 +829,7 @@ void Translate(Browser* browser) { } browser->window()->ShowTranslateBubble( web_contents, step, translate::TranslateErrors::NONE, true); +#endif } void ManagePasswordsForPage(Browser* browser) { diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index 179c0bb9bc2c8..6e262a5e61aa5 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc @@ -55,7 +55,7 @@ using base::UserMetricsAction; namespace chrome { namespace { -const char kHashMark[] = "#"; +//const char kHashMark[] = "#"; void OpenBookmarkManagerWithHash(Browser* browser, const std::string& action, @@ -127,10 +127,12 @@ void ShowHelpImpl(Browser* browser, Profile* profile, HelpSource source) { #endif } +#if 0 std::string GenerateContentSettingsExceptionsSubPage(ContentSettingsType type) { return kContentSettingsExceptionsSubPage + std::string(kHashMark) + options::ContentSettingsHandler::ContentSettingsTypeToGroupName(type); } +#endif } // namespace @@ -288,25 +290,31 @@ void ShowSettingsSubPageInTabbedBrowser(Browser* browser, void ShowContentSettingsExceptions(Browser* browser, ContentSettingsType content_settings_type) { +#if 0 ShowSettingsSubPage( browser, GenerateContentSettingsExceptionsSubPage(content_settings_type)); +#endif } void ShowContentSettingsExceptionsInWindow( Profile* profile, ContentSettingsType content_settings_type) { +#if 0 DCHECK(switches::SettingsWindowEnabled()); ShowSettingsSubPageForProfile( profile, GenerateContentSettingsExceptionsSubPage(content_settings_type)); +#endif } void ShowContentSettings(Browser* browser, ContentSettingsType content_settings_type) { +#if 0 ShowSettingsSubPage( browser, kContentSettingsSubPage + std::string(kHashMark) + options::ContentSettingsHandler::ContentSettingsTypeToGroupName( content_settings_type)); +#endif } void ShowClearBrowsingDataDialog(Browser* browser) { diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm index efb348592403b..1c47d75f6002f 100644 --- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm +++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm @@ -24,6 +24,11 @@ using extensions::Extension; +#include "chrome/browser/devtools/devtools_window.h" + +#include "content/nw/src/api/menu/menu.h" +#include "content/nw/src/common/shell_switches.h" + namespace { // When an app window loses main status, AppKit may make another app window main @@ -75,6 +80,7 @@ void AddDuplicateItem(NSMenuItem* top_level_item, [[top_level_item submenu] addItem:item]; } +#if 0 // Finds an item with |item_tag| and removes it from the submenu of // |top_level_item|. void RemoveMenuItemWithTag(NSMenuItem* top_level_item, @@ -132,6 +138,7 @@ void SetItemWithTagVisible(NSMenuItem* top_level_item, [alternate_item setHidden:!visible]; [menu_item setHidden:!visible]; } +#endif // Return the Extension (if any) associated with the given window. If it is not // a platform app nor hosted app, but it is a browser, |is_browser| will be set @@ -211,6 +218,7 @@ void SetAppCyclesWindows(const std::string& app_id, int sequence_number) { [[NSApp keyWindow] makeKeyAndOrderFront:nil]; } +#if 0 // Sets the window cycle list to Chrome browser windows only. void SetChromeCyclesWindows(int sequence_number) { if (g_window_cycle_sequence_number != sequence_number) @@ -226,6 +234,7 @@ void SetChromeCyclesWindows(int sequence_number) { if (any_change) [[NSApp keyWindow] makeKeyAndOrderFront:nil]; } +#endif } // namespace @@ -354,6 +363,7 @@ - (void)quitCurrentPlatformApp; - (void)hideCurrentPlatformApp; // If the currently focused window belongs to a platform app, focus the app. - (void)focusCurrentPlatformApp; +- (void)showDevtools; @end @implementation AppShimMenuController @@ -393,6 +403,7 @@ - (void)buildAppMenuItems { resourceId:IDS_EXIT_MAC action:@selector(quitCurrentPlatformApp) keyEquivalent:@"q"]); +#if 0 newDoppelganger_.reset([[DoppelgangerMenuItem alloc] initWithController:self menuTag:IDC_FILE_MENU @@ -417,6 +428,7 @@ - (void)buildAppMenuItems { resourceId:0 action:nil keyEquivalent:@"o"]); +#endif allToFrontDoppelganger_.reset([[DoppelgangerMenuItem alloc] initWithController:self menuTag:IDC_WINDOW_MENU @@ -440,18 +452,21 @@ - (void)buildAppMenuItems { [appMenu addItem:[NSMenuItem separatorItem]]; [appMenu addItem:[quitDoppelganger_ menuItem]]; +#if 0 // File menu. fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]); [[fileMenuItem_ submenu] addItem:[newDoppelganger_ menuItem]]; [[fileMenuItem_ submenu] addItem:[openDoppelganger_ menuItem]]; [[fileMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; [[fileMenuItem_ submenu] addItem:[closeWindowDoppelganger_ menuItem]]; +#endif // Edit menu. We copy the menu because the last two items, "Start Dictation" // and "Special Characters" are added by OSX, so we can't copy them // explicitly. editMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_EDIT_MENU] copy]); +#if 0 // View menu. Remove "Always Show Bookmark Bar" and separator. viewMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_VIEW_MENU] copy]); RemoveMenuItemWithTag(viewMenuItem_, IDC_SHOW_BOOKMARK_BAR, YES); @@ -461,12 +476,34 @@ - (void)buildAppMenuItems { AddDuplicateItem(historyMenuItem_, IDC_HISTORY_MENU, IDC_BACK); AddDuplicateItem(historyMenuItem_, IDC_HISTORY_MENU, IDC_FORWARD); +#endif // Window menu. windowMenuItem_.reset([NewTopLevelItemFrom(IDC_WINDOW_MENU) retain]); AddDuplicateItem(windowMenuItem_, IDC_WINDOW_MENU, IDC_MINIMIZE_WINDOW); AddDuplicateItem(windowMenuItem_, IDC_WINDOW_MENU, IDC_MAXIMIZE_WINDOW); [[windowMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; [[windowMenuItem_ submenu] addItem:[allToFrontDoppelganger_ menuItem]]; + +#if defined(NWJS_SDK) + bool enable_devtools = true; + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kDisableDevTools)) + enable_devtools = false; + + if (enable_devtools) { + [[windowMenuItem_ submenu] setAutoenablesItems:NO]; + NSMenuItem* item = [[NSMenuItem alloc] + initWithTitle:@"Devtools" + action:@selector(showDevtools) + keyEquivalent:@"i"]; + [item setTag:IDC_DEV_TOOLS_CONSOLE]; + [item setTarget:self]; + [item setEnabled:YES]; + [item setKeyEquivalentModifierMask:NSCommandKeyMask | NSAlternateKeyMask]; + [[windowMenuItem_ submenu] addItem:item]; + } +#endif } - (void)registerEventHandlers { @@ -498,8 +535,17 @@ - (void)windowMainStatusChanged:(NSNotification*)notification { const Extension* extension = GetExtensionForNSWindow(window, &is_browser); // Ignore is_browser: if a window becomes main that does not belong to an // extension or browser, treat it the same as switching to a browser. - if (extension) + + extensions::AppWindow* appWindow = + AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( + window); + if (extension) { + if (appWindow->menu_) { + [NSApp setMainMenu:appWindow->menu_->menu_]; + return; + } [self appBecameMain:extension]; + } else [self chromeBecameMain]; } else if ([name isEqualToString:NSWindowDidResignMainNotification]) { @@ -530,7 +576,12 @@ - (void)appBecameMain:(const Extension*)app { return; if (!appId_.empty()) - [self removeMenuItems]; + return; + // #4591: when app sets menubar and launch another chrome app, + // removeMenuItems will try to remove appmenuitem which isn't + // in the main menu; then app will crash. + // so after this function runs once, we just do nothing and return here + //[self removeMenuItems]; appId_ = app->id(); [self addMenuItems:app]; @@ -542,6 +593,7 @@ - (void)appBecameMain:(const Extension*)app { } - (void)chromeBecameMain { +#if 0 if (appId_.empty()) return; @@ -552,6 +604,7 @@ - (void)chromeBecameMain { FROM_HERE, base::Bind(&SetChromeCyclesWindows, ++g_window_cycle_sequence_number)); } +#endif } - (void)addMenuItems:(const Extension*)app { @@ -566,14 +619,15 @@ - (void)addMenuItems:(const Extension*)app { [aboutDoppelganger_ enableForApp:app]; [hideDoppelganger_ enableForApp:app]; [quitDoppelganger_ enableForApp:app]; - [newDoppelganger_ enableForApp:app]; - [openDoppelganger_ enableForApp:app]; - [closeWindowDoppelganger_ enableForApp:app]; + //[newDoppelganger_ enableForApp:app]; + //[openDoppelganger_ enableForApp:app]; + //[closeWindowDoppelganger_ enableForApp:app]; [appMenuItem_ setTitle:base::SysUTF8ToNSString(appId_)]; [[appMenuItem_ submenu] setTitle:title]; [mainMenu addItem:appMenuItem_]; +#if 0 [mainMenu addItem:fileMenuItem_]; SetItemWithTagVisible(editMenuItem_, @@ -581,23 +635,28 @@ - (void)addMenuItems:(const Extension*)app { app->is_hosted_app(), true); SetItemWithTagVisible(editMenuItem_, IDC_FIND_MENU, app->is_hosted_app(), false); +#endif [mainMenu addItem:editMenuItem_]; +#if 0 if (app->is_hosted_app()) { [mainMenu addItem:viewMenuItem_]; [mainMenu addItem:historyMenuItem_]; } +#endif [mainMenu addItem:windowMenuItem_]; } - (void)removeMenuItems { NSMenu* mainMenu = [NSApp mainMenu]; [mainMenu removeItem:appMenuItem_]; - [mainMenu removeItem:fileMenuItem_]; + //[mainMenu removeItem:fileMenuItem_]; +#if 0 if ([mainMenu indexOfItem:viewMenuItem_] >= 0) [mainMenu removeItem:viewMenuItem_]; if ([mainMenu indexOfItem:historyMenuItem_] >= 0) [mainMenu removeItem:historyMenuItem_]; +#endif [mainMenu removeItem:editMenuItem_]; [mainMenu removeItem:windowMenuItem_]; @@ -608,9 +667,9 @@ - (void)removeMenuItems { [aboutDoppelganger_ disable]; [hideDoppelganger_ disable]; [quitDoppelganger_ disable]; - [newDoppelganger_ disable]; - [openDoppelganger_ disable]; - [closeWindowDoppelganger_ disable]; + //[newDoppelganger_ disable]; + //[openDoppelganger_ disable]; + //[closeWindowDoppelganger_ disable]; } - (void)quitCurrentPlatformApp { @@ -618,7 +677,7 @@ - (void)quitCurrentPlatformApp { AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( [NSApp keyWindow]); if (appWindow) { - apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow); + apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow, true); } else { Browser* browser = chrome::FindBrowserWithWindow([NSApp keyWindow]); const Extension* extension = @@ -653,4 +712,12 @@ - (void)focusCurrentPlatformApp { apps::ExtensionAppShimHandler::FocusAppForWindow(appWindow); } +- (void)showDevtools { + extensions::AppWindow* appWindow = + AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( + [NSApp keyWindow]); + if (appWindow) + DevToolsWindow::OpenDevToolsWindow(appWindow->web_contents()); +} + @end diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h index e0d91ad45e1fb..bc48685b01b03 100644 --- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h +++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h @@ -46,6 +46,7 @@ class SkRegion; - (BOOL)handledByExtensionCommand:(NSEvent*)event priority:(ui::AcceleratorManager::HandlerPriority)priority; +- (void)closeAllWindowsQuit:(id)sender; @end // Cocoa bridge to AppWindow. @@ -76,10 +77,13 @@ class NativeAppWindowCocoa : public extensions::NativeAppWindow, void SetBounds(const gfx::Rect& bounds) override; void FlashFrame(bool flash) override; bool IsAlwaysOnTop() const override; + void SetShowInTaskbar(bool show) override; // Called when the window is about to be closed. void WindowWillClose(); + bool NWCanClose(bool user_force = false); + // Called when the window is focused. void WindowDidBecomeKey(); @@ -126,6 +130,8 @@ class NativeAppWindowCocoa : public extensions::NativeAppWindow, protected: // NativeAppWindow implementation. void SetFullscreen(int fullscreen_types) override; + void SetResizable(bool flag) override; + bool IsResizable() const override; bool IsFullscreenOrPending() const override; void UpdateWindowIcon() override; void UpdateWindowTitle() override; @@ -185,7 +191,9 @@ class NativeAppWindowCocoa : public extensions::NativeAppWindow, // Hides the window unconditionally. Used by Hide and HideWithApp. void HideWithoutMarkingHidden(); +public: extensions::AppWindow* app_window_; // weak - AppWindow owns NativeAppWindow. +private: bool has_frame_; diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm index c3cfb679918a7..42078a8885286 100644 --- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm @@ -18,6 +18,9 @@ #include "chrome/browser/ui/cocoa/extensions/extension_view_mac.h" #include "chrome/common/chrome_switches.h" #include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "extensions/common/extension.h" #include "skia/ext/skia_utils_mac.h" @@ -25,6 +28,9 @@ #import "ui/gfx/mac/nswindow_frame_controls.h" #include "ui/gfx/skia_util.h" +#include "ui/display/screen.h" +#include "content/nw/src/nw_content_mac.h" + // NOTE: State Before Update. // // Internal state, such as |is_maximized_|, must be set before the window @@ -43,12 +49,18 @@ // desired size. using extensions::AppWindow; +using extensions::AppWindowRegistry; @interface NSWindow (NSPrivateApis) - (void)setBottomCornerRounded:(BOOL)rounded; - (BOOL)_isTitleHidden; @end +namespace content { + extern bool g_support_transparency; + extern bool g_force_cpu_draw; +} + namespace { const int kActivateThrottlePeriodSeconds = 2; @@ -102,6 +114,12 @@ - (void)setTitlebarBackgroundView:(NSView*)view { titlebar_background_view_.reset([view retain]); } +- (BOOL)windowShouldClose:(id)sender { + if (appWindow_ && !appWindow_->NWCanClose()) + return NO; + return YES; +} + - (void)windowWillClose:(NSNotification*)notification { if (appWindow_) appWindow_->WindowWillClose(); @@ -181,6 +199,24 @@ - (BOOL)handledByExtensionCommand:(NSEvent*)event return NO; } +// this function is for createMacBuiltin only +- (void)closeAllWindowsQuit:(id)sender { + if (!appWindow_) + return; + AppWindowRegistry* registry = AppWindowRegistry::Get(appWindow_->app_window_->browser_context()); + if (!registry) + return; + + AppWindowRegistry::AppWindowList windows = + registry->GetAppWindowsForApp(appWindow_->app_window_->GetExtension()->id()); + + for (AppWindow* window : windows) { + // passing true for createMacBuiltin: https://github.com/nwjs/nw.js/issues/4580#issuecomment-199236153 + if (window->NWCanClose(true)) + window->GetBaseWindow()->Close(); + } +} + @end @interface AppNSWindow : ChromeEventProcessingWindow @@ -191,7 +227,7 @@ @implementation AppNSWindow // Similar to ChromeBrowserWindow, don't draw the title, but allow it to be seen // in menus, Expose, etc. - (BOOL)_isTitleHidden { - return YES; + return NO; } @end @@ -219,6 +255,10 @@ - (NSRect)contentRectForFrameRect:(NSRect)frameRect { return frameRect; } +- (BOOL)_isTitleHidden { + return YES; +} + @end @interface ControlRegionView : NSView @@ -274,7 +314,7 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; if (extension) name = extension->name(); [window setTitle:base::SysUTF8ToNSString(name)]; - [[window contentView] setWantsLayer:YES]; + [[window contentView] setWantsLayer:!content::g_force_cpu_draw]; if (params.always_on_top) gfx::SetNSWindowAlwaysOnTop(window, true); @@ -284,6 +324,12 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; window_controller_.reset( [[NativeAppWindowController alloc] initWithWindow:window]); + + if (content::g_support_transparency && params.alpha_enabled) { + [window setHasShadow: NO]; + [window setOpaque: NO]; + [window setBackgroundColor: [NSColor clearColor]]; + } if (has_frame_ && has_frame_color_) { TitlebarBackgroundView* view = @@ -303,7 +349,12 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; // We can now compute the precise window bounds and constraints. gfx::Insets insets = GetFrameInsets(); - SetBounds(params.GetInitialWindowBounds(insets)); + gfx::Rect bounds = params.GetInitialWindowBounds(insets); + if (params.position == AppWindow::POS_MOUSE) { + gfx::Point cursor_pos(display::Screen::GetScreen()->GetCursorScreenPoint()); + bounds.set_origin(cursor_pos); + } + SetBounds(bounds); SetContentSizeConstraints(params.GetContentMinimumSize(insets), params.GetContentMaximumSize(insets)); @@ -380,6 +431,10 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; return is_fullscreen_; } +void NativeAppWindowCocoa::SetShowInTaskbar(bool show) { + NWSetNSWindowShowInTaskbar(this, show); +} + void NativeAppWindowCocoa::SetFullscreen(int fullscreen_types) { bool fullscreen = (fullscreen_types != AppWindow::FULLSCREEN_TYPE_NONE); if (fullscreen == is_fullscreen_) @@ -563,6 +618,16 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; event.type == content::NativeWebKeyboardEvent::Char) { return; } + + // NW fix + // Simple key press events without modifiers should be sent to the menu. + // See https://github.com/nwjs/nw.js/issues/4837 + NSEvent* nsEvent = event.os_event; + if ([nsEvent type] == NSKeyDown) { + if ([[NSApp mainMenu] performKeyEquivalent:nsEvent]) + return; + } + [window() redispatchKeyEvent:event.os_event]; } @@ -622,6 +687,12 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; void NativeAppWindowCocoa::RenderViewCreated(content::RenderViewHost* rvh) { if (IsActive()) WebContents()->RestoreFocus(); + if (content::g_support_transparency && + app_window_->requested_alpha_enabled() && CanHaveAlphaEnabled()) { + content::RenderWidgetHostView* view = rvh->GetWidget()->GetView(); + DCHECK(view); + view->SetBackgroundColor(SK_ColorTRANSPARENT); + } } bool NativeAppWindowCocoa::IsFrameless() const { @@ -660,7 +731,7 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; } bool NativeAppWindowCocoa::CanHaveAlphaEnabled() const { - return false; + return content::g_support_transparency ? [window() isOpaque] == NO : false; } gfx::NativeView NativeAppWindowCocoa::GetHostView() const { @@ -693,6 +764,10 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; app_window_->OnNativeClose(); } +bool NativeAppWindowCocoa::NWCanClose(bool user_force) { + return app_window_->NWCanClose(user_force); +} + void NativeAppWindowCocoa::WindowDidBecomeKey() { app_window_->OnNativeWindowActivated(); @@ -782,7 +857,8 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; void NativeAppWindowCocoa::HideWithApp() { is_hidden_with_app_ = true; - HideWithoutMarkingHidden(); + [NSApp hide:nil]; +// HideWithoutMarkingHidden(); } gfx::Size NativeAppWindowCocoa::GetContentMinimumSize() const { @@ -793,6 +869,25 @@ - (void)setMouseDownCanMoveWindow:(BOOL)can_move; return size_constraints_.GetMaximumSize(); } +void NativeAppWindowCocoa::SetResizable(bool flag) { + is_resizable_ = flag; + gfx::Size min_size = size_constraints_.GetMinimumSize(); + gfx::Size max_size = size_constraints_.GetMaximumSize(); + + shows_resize_controls_ = + is_resizable_ && !size_constraints_.HasFixedSize(); + shows_fullscreen_controls_ = + is_resizable_ && !size_constraints_.HasMaximumSize() && has_frame_; + + gfx::ApplyNSWindowSizeConstraints(window(), min_size, max_size, + shows_resize_controls_, + shows_fullscreen_controls_); +} + +bool NativeAppWindowCocoa::IsResizable() const { + return is_resizable_; +} + void NativeAppWindowCocoa::SetContentSizeConstraints( const gfx::Size& min_size, const gfx::Size& max_size) { // Update the size constraints. diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index 8a730be6db888..1fec438e39aa5 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm @@ -137,6 +137,8 @@ - (void)validateText:(NSString*)text { initial_show_state_(ui::SHOW_STATE_DEFAULT), attention_request_id_(0) { + CHECK(browser->is_type_popup()) << "opening browser window."; + gfx::Rect bounds; chrome::GetSavedWindowBoundsAndShowState(browser_, &bounds, @@ -627,6 +629,7 @@ - (void)validateText:(NSString*)text { translate::TranslateStep step, translate::TranslateErrors::Type error_type, bool is_user_gesture) { +#if 0 ChromeTranslateClient* chrome_translate_client = ChromeTranslateClient::FromWebContents(contents); translate::LanguageState& language_state = @@ -636,6 +639,7 @@ - (void)validateText:(NSString*)text { [controller_ showTranslateBubbleForWebContents:contents step:step errorType:error_type]; +#endif } #if BUILDFLAG(ENABLE_ONE_CLICK_SIGNIN) diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index f416135563c6b..419efcf963b2a 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm @@ -1572,6 +1572,7 @@ - (void)showTranslateBubbleForWebContents:(content::WebContents*)contents step:(translate::TranslateStep)step errorType:(translate::TranslateErrors::Type) errorType { +#if 0 // TODO(hajimehoshi): The similar logic exists at TranslateBubbleView:: // ShowBubble. This should be unified. if (translateBubbleController_) { @@ -1615,6 +1616,7 @@ - (void)showTranslateBubbleForWebContents:(content::WebContents*)contents selector:@selector(translateBubbleWindowWillClose:) name:NSWindowWillCloseNotification object:[translateBubbleController_ window]]; +#endif } - (void)dismissPermissionBubble { diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm index ca5dc796bce7c..de3bfeb41cf8c 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm @@ -978,6 +978,7 @@ new ManagePasswordsDecoration(command_updater, this)), } void LocationBarViewMac::UpdateTranslateDecoration() { +#if 0 if (!TranslateService::IsTranslateBubbleEnabled()) return; @@ -991,6 +992,7 @@ new ManagePasswordsDecoration(command_updater, this)), translate_decoration_->SetVisible(enabled); translate_decoration_->SetLit(language_state.IsPageTranslated(), IsLocationBarDark()); +#endif } bool LocationBarViewMac::UpdateZoomDecoration(bool default_zoom_changed) { diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h index 19be82175c060..995061e7b6001 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h @@ -36,7 +36,7 @@ class StatusIconMac : public StatusIcon { protected: // Overridden from StatusIcon. - void UpdatePlatformContextMenu(StatusIconMenuModel* model) override; + void UpdatePlatformContextMenu(ui::MenuModel* model) override; private: FRIEND_TEST_ALL_PREFIXES(StatusIconMacTest, CreateMenu); diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm index f0566febac48f..cd98fc7ecba6c 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm @@ -96,7 +96,7 @@ - (void)handleClick:(id)sender { return menu_.get() != nil; } -void StatusIconMac::UpdatePlatformContextMenu(StatusIconMenuModel* model) { +void StatusIconMac::UpdatePlatformContextMenu(ui::MenuModel* model) { if (!model) { menu_.reset(); } else { diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm index dba85d4f98f88..2d28b298d92e1 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm @@ -90,7 +90,10 @@ - (id)initTabWindowControllerWithTabStrip:(BOOL)hasTabStrip kBrowserFrameViewPaintHeight)]); [tabStripBackgroundView_ setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; - [self insertTabStripBackgroundViewIntoWindow:window titleBar:hasTitleBar]; + + //fix warning when opening devtools: #4312 + if (hasTabStrip) + [self insertTabStripBackgroundViewIntoWindow:window titleBar:hasTitleBar]; tabStripView_.reset([[TabStripView alloc] initWithFrame:NSMakeRect( diff --git a/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc b/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc index f0e9cec873a4a..7179514343d81 100644 --- a/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc +++ b/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc @@ -237,7 +237,6 @@ void AppIndicatorIcon::SetImage(const gfx::ImageSkia& image) { } void AppIndicatorIcon::SetToolTip(const base::string16& tool_tip) { - DCHECK(!tool_tip_.empty()); tool_tip_ = base::UTF16ToUTF8(tool_tip); UpdateClickActionReplacementMenuItem(); } @@ -382,8 +381,8 @@ void AppIndicatorIcon::UpdateClickActionReplacementMenuItem() { if (!delegate()->HasClickAction() && menu_model_) return; - DCHECK(!tool_tip_.empty()); - menu_->UpdateClickActionReplacementMenuItem( + if(!tool_tip_.empty()) + menu_->UpdateClickActionReplacementMenuItem( tool_tip_.c_str(), base::Bind(&AppIndicatorIcon::OnClickActionReplacementMenuItemActivated, base::Unretained(this))); diff --git a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc index 65ea0ee5120b8..1a4cb77abbb0c 100644 --- a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc +++ b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc @@ -304,11 +304,11 @@ GtkWidget* SelectFileDialogImplGTK::CreateSelectFolderDialog( gfx::NativeWindow parent) { std::string title_string = title; if (title_string.empty()) { - title_string = (type == SELECT_UPLOAD_FOLDER) ? + title_string = 0 ? l10n_util::GetStringUTF8(IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE) : l10n_util::GetStringUTF8(IDS_SELECT_FOLDER_DIALOG_TITLE); } - std::string accept_button_label = (type == SELECT_UPLOAD_FOLDER) ? + std::string accept_button_label = 0 ? l10n_util::GetStringUTF8(IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON) : "_Open"; diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index 2f79b8736960f..29a8be47f85e8 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc @@ -407,7 +407,8 @@ void ManagePasswordsUIController::DidNavigateMainFrame( } void ManagePasswordsUIController::WasHidden() { - TabDialogs::FromWebContents(web_contents())->HideManagePasswordsBubble(); + if (TabDialogs::FromWebContents(web_contents())) + TabDialogs::FromWebContents(web_contents())->HideManagePasswordsBubble(); } void ManagePasswordsUIController::ShowBubbleWithoutUserInteraction() { diff --git a/chrome/browser/ui/scoped_tabbed_browser_displayer.cc b/chrome/browser/ui/scoped_tabbed_browser_displayer.cc index 6f09f0b8ed68b..6b7916fb37914 100644 --- a/chrome/browser/ui/scoped_tabbed_browser_displayer.cc +++ b/chrome/browser/ui/scoped_tabbed_browser_displayer.cc @@ -13,7 +13,7 @@ namespace chrome { ScopedTabbedBrowserDisplayer::ScopedTabbedBrowserDisplayer(Profile* profile) { browser_ = FindTabbedBrowser(profile, false); if (!browser_) - browser_ = new Browser(Browser::CreateParams(profile)); + browser_ = new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile)); } ScopedTabbedBrowserDisplayer::~ScopedTabbedBrowserDisplayer() { diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index ae452e2147b43..65cb0e4700707 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc @@ -76,6 +76,15 @@ #include "extensions/common/switches.h" #include "net/base/port_util.h" +#include "extensions/browser/extension_system.h" +#include "chrome/browser/extensions/component_loader.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/common/extensions/extension_constants.h" +#include "grit/browser_resources.h" +#include "extensions/common/constants.h" +#include "chrome/browser/ui/extensions/app_launch_params.h" +#include "chrome/browser/ui/extensions/application_launch.h" + #if defined(USE_ASH) #include "ash/shell.h" #endif @@ -707,10 +716,46 @@ bool StartupBrowserCreator::ProcessCmdLineImpl( // chrome to shut down. // TODO(jackhou): Do this properly once keep-alive is handled by the // background page of apps. Tracked at http://crbug.com/175381 - if (chrome::GetBrowserCount(last_used_profile) != 0) + // if (chrome::GetBrowserCount(last_used_profile) != 0) return true; } + if (!process_startup) + return true; + + const base::CommandLine::StringVector& params = command_line.GetArgs(); + if (command_line.HasSwitch("nwapp")) { + if (!apps::AppLoadService::Get(last_used_profile)->LoadAndLaunch( + base::FilePath(command_line.GetSwitchValueNative("nwapp")), command_line, cur_dir)) { + return false; + } + return true; + } + if (params.size() > 0) { + if (!apps::AppLoadService::Get(last_used_profile)->LoadAndLaunch( + base::FilePath(params[0]), command_line, cur_dir)) { + return false; + } + return true; + } else { + ExtensionService* extension_service = + extensions::ExtensionSystem::Get(last_used_profile)->extension_service(); + extensions::ComponentLoader* component_loader = extension_service->component_loader(); + std::string id = component_loader->GetExtensionID(IDR_NWJS_DEFAPP_MANIFEST, + base::FilePath(FILE_PATH_LITERAL("nwjs_default_app"))); + + LOG(INFO) << "loading default app: " << id; + const extensions::Extension* extension = extension_service->GetExtensionById(id, true); + if (!extension) { + LOG(FATAL) << "Failed to load default app"; + return false; + } + OpenApplication( + AppLaunchParams(last_used_profile, extension, extensions::LAUNCH_CONTAINER_WINDOW, + NEW_WINDOW, extensions::SOURCE_CHROME_INTERNAL)); + return true; + } + #if defined(OS_WIN) // Log whether this process was a result of an action in the Windows Jumplist. if (command_line.HasSwitch(switches::kWinJumplistAction)) { diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 6398c772a5fea..d83e961fa0fe2 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc @@ -152,7 +152,7 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) { ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( web_contents, autofill::ChromeAutofillClient::FromWebContents(web_contents)); - ChromeTranslateClient::CreateForWebContents(web_contents); + //ChromeTranslateClient::CreateForWebContents(web_contents); CoreTabHelper::CreateForWebContents(web_contents); ExternalProtocolObserver::CreateForWebContents(web_contents); favicon::CreateContentFaviconDriverForWebContents(web_contents); diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc index 487a59a88d9ba..ff6373e28a7d7 100644 --- a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc +++ b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc @@ -63,9 +63,11 @@ ComponentToolbarActionsFactory::GetComponentToolbarActionForId( // should be okay. If this changes, we should rethink this design to have, // e.g., RegisterChromeAction(). #if defined(ENABLE_MEDIA_ROUTER) +#if defined(NWJS_SDK) if (id == kMediaRouterActionId) return std::unique_ptr( new MediaRouterAction(browser, bar)); +#endif #endif // defined(ENABLE_MEDIA_ROUTER) NOTREACHED(); diff --git a/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc b/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc index 1306401674413..42b0d0f821a29 100644 --- a/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc +++ b/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc @@ -26,6 +26,9 @@ AppWindowDesktopWindowTreeHostWin::~AppWindowDesktopWindowTreeHostWin() { bool AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets( gfx::Insets* insets) const { +#if 1 + return false; +#else // The inset added below is only necessary for the native glass frame, i.e. // not for colored frames drawn by Chrome, or when DWM is disabled. // In fullscreen the frame is not visible. @@ -36,6 +39,7 @@ bool AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets( *insets = app_window_->glass_frame_view()->GetClientAreaInsets(); return true; +#endif } void AppWindowDesktopWindowTreeHostWin::HandleFrameChanged() { @@ -58,6 +62,9 @@ void AppWindowDesktopWindowTreeHostWin::PostHandleMSG(UINT message, } void AppWindowDesktopWindowTreeHostWin::UpdateDWMFrame() { +#if 1 + return; +#else if (!GetWidget()->client_view() || !app_window_->glass_frame_view()) return; @@ -77,4 +84,5 @@ void AppWindowDesktopWindowTreeHostWin::UpdateDWMFrame() { } DwmExtendFrameIntoClientArea(GetHWND(), &margins); +#endif } diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc index 67e01345555fb..711fb03d8fa62 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc @@ -21,6 +21,14 @@ #include "ui/views/controls/webview/webview.h" #include "ui/views/widget/widget.h" +#if defined(NWJS_SDK) +#include "base/command_line.h" +#include "chrome/browser/devtools/devtools_window.h" +#include "content/nw/src/common/shell_switches.h" +#endif + +#include "ui/display/screen.h" + using extensions::AppWindow; namespace { @@ -37,9 +45,12 @@ struct AcceleratorMapping { }; const AcceleratorMapping kAppWindowAcceleratorMap[] = { - { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, - { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, + // { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, + // { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW }, +#if defined(NWJS_SDK) + { ui::VKEY_F12, ui::EF_NONE, IDC_DEV_TOOLS_TOGGLE }, +#endif }; // These accelerators will only be available in kiosk mode. These allow the @@ -110,6 +121,10 @@ void ChromeNativeAppWindowViews::OnBeforeWidgetInit( views::Widget* widget) { } +bool ChromeNativeAppWindowViews::NWCanClose(bool user_force) const { + return app_window()->NWCanClose(user_force); +} + void ChromeNativeAppWindowViews::OnBeforePanelWidgetInit( bool use_default_bounds, views::Widget::InitParams* init_params, @@ -150,10 +165,23 @@ void ChromeNativeAppWindowViews::InitializeDefaultWindow( bool position_specified = window_bounds.x() != BoundsSpecification::kUnspecifiedPosition && window_bounds.y() != BoundsSpecification::kUnspecifiedPosition; + position_specified |= create_params.position == AppWindow::POS_MOUSE; if (!position_specified) widget()->CenterWindow(window_bounds.size()); - else + else if (create_params.position == AppWindow::POS_MOUSE) { + gfx::Point cursor_pos(display::Screen::GetScreen()->GetCursorScreenPoint()); + window_bounds.set_origin(cursor_pos); + widget()->SetBounds(window_bounds); + }else widget()->SetBounds(window_bounds); + } else { + if (create_params.position == AppWindow::POS_CENTER) + widget()->CenterWindow(gfx::Size(640, 480)); + else if (create_params.position == extensions::AppWindow::POS_MOUSE) { + gfx::Point cursor_pos(display::Screen::GetScreen()->GetCursorScreenPoint()); + gfx::Rect bounds(cursor_pos, gfx::Size(640, 480)); + widget()->SetBounds(bounds); + } } #if defined(OS_CHROMEOS) @@ -307,6 +335,14 @@ bool ChromeNativeAppWindowViews::AcceleratorPressed( accelerator_table.find(accelerator); DCHECK(iter != accelerator_table.end()); int command_id = iter->second; +#if defined(NWJS_SDK) + content::WebContents* web_contents; + bool enable_devtools = true; + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kDisableDevTools)) + enable_devtools = false; +#endif switch (command_id) { case IDC_CLOSE_WINDOW: Close(); @@ -323,7 +359,25 @@ bool ChromeNativeAppWindowViews::AcceleratorPressed( ui_zoom::PageZoom::Zoom(web_view()->GetWebContents(), content::PAGE_ZOOM_IN); return true; - default: +#if defined(NWJS_SDK) + case IDC_DEV_TOOLS: + if (!enable_devtools) + return true; + web_contents = app_window()->web_contents(); + if (web_contents) { + DevToolsWindow::OpenDevToolsWindow(web_contents); + } + return true; + case IDC_DEV_TOOLS_TOGGLE: + if (!enable_devtools) + return true; + web_contents = app_window()->web_contents(); + if (web_contents) { + DevToolsWindow::OpenDevToolsWindow(web_contents, DevToolsToggleAction::Toggle()); + } + return true; +#endif + default: NOTREACHED() << "Unknown accelerator sent to app window."; } return NativeAppWindowViews::AcceleratorPressed(accelerator); diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.h b/chrome/browser/ui/views/apps/chrome_native_app_window_views.h index 10e74450cd208..d40981199f68a 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.h +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.h @@ -56,6 +56,7 @@ class ChromeNativeAppWindowViews views::Widget* widget) override; bool WidgetHasHitTestMask() const override; void GetWidgetHitTestMask(gfx::Path* mask) const override; + bool NWCanClose(bool user_force = false) const override; // views::View implementation. gfx::Size GetPreferredSize() const override; diff --git a/chrome/browser/ui/views/apps/glass_app_window_frame_view_win.cc b/chrome/browser/ui/views/apps/glass_app_window_frame_view_win.cc index ee35b185be5e3..384ac21cfe255 100644 --- a/chrome/browser/ui/views/apps/glass_app_window_frame_view_win.cc +++ b/chrome/browser/ui/views/apps/glass_app_window_frame_view_win.cc @@ -59,6 +59,9 @@ gfx::Insets GlassAppWindowFrameViewWin::GetClientAreaInsets() const { } gfx::Rect GlassAppWindowFrameViewWin::GetBoundsForClientView() const { +#if 1 + return bounds(); +#else if (widget_->IsFullscreen()) return bounds(); @@ -67,6 +70,7 @@ gfx::Rect GlassAppWindowFrameViewWin::GetBoundsForClientView() const { insets.top(), std::max(0, width() - insets.left() - insets.right()), std::max(0, height() - insets.top() - insets.bottom())); +#endif } gfx::Rect GlassAppWindowFrameViewWin::GetWindowBoundsForClientBounds( @@ -93,6 +97,11 @@ int GlassAppWindowFrameViewWin::NonClientHitTest(const gfx::Point& point) { if (!bounds().Contains(point)) return HTNOWHERE; + int client_component = widget_->client_view()->NonClientHitTest(point); + if (client_component != HTNOWHERE) + return client_component; + + // Check the frame first, as we allow a small area overlapping the contents // to be used for resize handles. bool can_ever_resize = widget_->widget_delegate() @@ -111,10 +120,6 @@ int GlassAppWindowFrameViewWin::NonClientHitTest(const gfx::Point& point) { if (frame_component != HTNOWHERE) return frame_component; - int client_component = widget_->client_view()->NonClientHitTest(point); - if (client_component != HTNOWHERE) - return client_component; - // Caption is a safe default. return HTCAPTION; } diff --git a/chrome/browser/ui/views/chrome_views_delegate.cc b/chrome/browser/ui/views/chrome_views_delegate.cc index e0c9f334689b7..be85378ae0788 100644 --- a/chrome/browser/ui/views/chrome_views_delegate.cc +++ b/chrome/browser/ui/views/chrome_views_delegate.cc @@ -6,6 +6,8 @@ #include +#include "content/nw/src/nw_content.h" + #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -299,6 +301,9 @@ HICON ChromeViewsDelegate::GetSmallWindowIcon() const { #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) gfx::ImageSkia* ChromeViewsDelegate::GetDefaultWindowIcon() const { + gfx::ImageSkia* ret = nw::GetAppIcon(); + if (ret) + return ret; ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); return rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_64); } diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 5fe85c7765440..12a39f83e46fe 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -155,6 +155,10 @@ #include "ui/views/widget/widget.h" #include "ui/views/window/dialog_delegate.h" + +#include "extensions/browser/app_window/app_window.h" +#include "extensions/browser/app_window/app_window_registry.h" + #if defined(USE_ASH) #include "chrome/browser/ui/ash/ash_util.h" #endif @@ -517,6 +521,8 @@ BrowserView::~BrowserView() { } void BrowserView::Init(Browser* browser) { + // type popup is for devtools window. that's what we want + CHECK(browser->is_type_popup()) << "opening browser window."; browser_.reset(browser); browser_->tab_strip_model()->AddObserver(this); immersive_mode_controller_.reset(chrome::CreateImmersiveModeController()); @@ -1314,13 +1320,13 @@ void BrowserView::ShowTranslateBubble( if (rvh->IsFocusedElementEditable()) return; } - +#if 0 ChromeTranslateClient* chrome_translate_client = ChromeTranslateClient::FromWebContents(web_contents); translate::LanguageState& language_state = chrome_translate_client->GetLanguageState(); language_state.SetTranslateEnabled(true); - +#endif if (IsMinimized()) return; @@ -1714,6 +1720,22 @@ bool BrowserView::ShouldShowWindowTitle() const { } gfx::ImageSkia BrowserView::GetWindowAppIcon() { +#if 0 + if (browser_->is_devtools()) { + WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents(); + DevToolsWindow* devtools_window = DevToolsWindow::AsDevToolsWindow(contents); + if (devtools_window) { + WebContents* inspected_contents = devtools_window->GetInspectedWebContents(); + Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); + extensions::AppWindowRegistry* registry = extensions::AppWindowRegistry::Get(profile); + if (registry) { + extensions::AppWindow* app_window = registry->GetAppWindowForWebContents(inspected_contents); + if (app_window) + return app_window->app_icon().AsImageSkia(); + } + } + } +#endif if (browser_->is_app()) { WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents(); extensions::TabHelper* extensions_tab_helper = diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 6b4235d1f1b8b..fa3b351ea923c 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc @@ -1005,6 +1005,7 @@ bool LocationBarView::RefreshSaveCreditCardIconView() { } void LocationBarView::RefreshTranslateIcon() { +#if 0 WebContents* web_contents = GetWebContents(); if (!web_contents) return; @@ -1015,6 +1016,7 @@ void LocationBarView::RefreshTranslateIcon() { translate_icon_view_->SetVisible(enabled); if (!enabled) TranslateBubbleView::CloseCurrentBubble(); +#endif } bool LocationBarView::RefreshManagePasswordsIconView() { diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc index b8889690fde6f..e116680e02ccf 100644 --- a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc +++ b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc @@ -8,15 +8,12 @@ #include "ui/views/linux_ui/linux_ui.h" StatusIconLinuxWrapper::StatusIconLinuxWrapper( - views::StatusIconLinux* status_icon) - : menu_model_(NULL) { + views::StatusIconLinux* status_icon) { status_icon_.reset(status_icon); status_icon_->set_delegate(this); } StatusIconLinuxWrapper::~StatusIconLinuxWrapper() { - if (menu_model_) - menu_model_->RemoveObserver(this); } void StatusIconLinuxWrapper::SetImage(const gfx::ImageSkia& image) { @@ -61,14 +58,6 @@ StatusIconLinuxWrapper* StatusIconLinuxWrapper::CreateWrappedStatusIcon( } void StatusIconLinuxWrapper::UpdatePlatformContextMenu( - StatusIconMenuModel* model) { - // If a menu already exists, remove ourself from its oberver list. - if (menu_model_) - menu_model_->RemoveObserver(this); - + ui::MenuModel* model) { status_icon_->UpdatePlatformContextMenu(model); - menu_model_ = model; - - if (model) - model->AddObserver(this); } diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h index 7c5791af3dfb4..3cbb0c73f8ae6 100644 --- a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h +++ b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h @@ -44,7 +44,7 @@ class StatusIconLinuxWrapper : public StatusIcon, // Invoked after a call to SetContextMenu() to let the platform-specific // subclass update the native context menu based on the new model. If NULL is // passed, subclass should destroy the native context menu. - void UpdatePlatformContextMenu(StatusIconMenuModel* model) override; + void UpdatePlatformContextMenu(ui::MenuModel* model) override; private: // A status icon wrapper should only be created by calling @@ -56,8 +56,6 @@ class StatusIconLinuxWrapper : public StatusIcon, std::unique_ptr status_icon_; - StatusIconMenuModel* menu_model_; - DISALLOW_COPY_AND_ASSIGN(StatusIconLinuxWrapper); }; diff --git a/chrome/browser/ui/views/status_icons/status_icon_win.cc b/chrome/browser/ui/views/status_icons/status_icon_win.cc index e153be212c5e6..70049cab18089 100644 --- a/chrome/browser/ui/views/status_icons/status_icon_win.cc +++ b/chrome/browser/ui/views/status_icons/status_icon_win.cc @@ -156,7 +156,7 @@ void StatusIconWin::ForceVisible() { //////////////////////////////////////////////////////////////////////////////// // StatusIconWin, private: -void StatusIconWin::UpdatePlatformContextMenu(StatusIconMenuModel* menu) { +void StatusIconWin::UpdatePlatformContextMenu(ui::MenuModel* menu) { // |menu_model_| is about to be destroyed. Destroy the menu (which closes it) // so that it doesn't attempt to continue using |menu_model_|. menu_runner_.reset(); diff --git a/chrome/browser/ui/views/status_icons/status_icon_win.h b/chrome/browser/ui/views/status_icons/status_icon_win.h index 05e45bc14723e..f4e8778f4ace4 100644 --- a/chrome/browser/ui/views/status_icons/status_icon_win.h +++ b/chrome/browser/ui/views/status_icons/status_icon_win.h @@ -57,7 +57,7 @@ class StatusIconWin : public StatusIcon { protected: // Overridden from StatusIcon: - void UpdatePlatformContextMenu(StatusIconMenuModel* menu) override; + void UpdatePlatformContextMenu(ui::MenuModel* menu) override; private: void InitIconData(NOTIFYICONDATA* icon_data); diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index a864fc18c69d7..3e6ba146d7785 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc @@ -116,6 +116,7 @@ views::Widget* TranslateBubbleView::ShowBubble( translate::TranslateStep step, translate::TranslateErrors::Type error_type, DisplayReason reason) { +#if 0 if (translate_bubble_view_) { // When the user reads the advanced setting panel, the bubble should not be // changed because they are focusing on the bubble. @@ -158,6 +159,8 @@ views::Widget* TranslateBubbleView::ShowBubble( view->ShowForReason(reason); translate::ReportUiAction(translate::BUBBLE_SHOWN); return bubble_widget; +#endif + return nullptr; } // static diff --git a/chrome/browser/ui/webui/chrome_web_contents_handler.cc b/chrome/browser/ui/webui/chrome_web_contents_handler.cc index beaf9f3e67a4a..27626857372ed 100644 --- a/chrome/browser/ui/webui/chrome_web_contents_handler.cc +++ b/chrome/browser/ui/webui/chrome_web_contents_handler.cc @@ -82,7 +82,7 @@ void ChromeWebContentsHandler::AddNewContents( Browser* browser = chrome::FindTabbedBrowser(profile, false); const bool browser_created = !browser; if (!browser) - browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED, profile)); + browser = new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile)); chrome::NavigateParams params(browser, new_contents); params.source_contents = source; params.disposition = disposition; diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index c3a77a9cc41c2..c7cfa2e230556 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc @@ -208,11 +208,13 @@ WebUIController* NewWebUI(WebUI* web_ui, } #endif // defined(ENABLE_EXTENSIONS) +#if defined(NWJS_SDK) // Special case for older about: handlers. template<> WebUIController* NewWebUI(WebUI* web_ui, const GURL& url) { return new AboutUI(web_ui, url.host()); } +#endif #if defined(OS_CHROMEOS) template<> @@ -264,6 +266,7 @@ bool NeedsExtensionWebUI(Profile* profile, const GURL& url) { } #endif +#if defined(NWJS_SDK) bool IsAboutUI(const GURL& url) { return (url.host() == chrome::kChromeUIChromeURLsHost || url.host() == chrome::kChromeUICreditsHost || @@ -283,6 +286,7 @@ bool IsAboutUI(const GURL& url) { #endif ); // NOLINT } +#endif // Returns a function that can be used to create the right type of WebUI for a // tab, based on its URL. Returns NULL if the URL doesn't have WebUI associated @@ -311,8 +315,10 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, // All platform builds of Chrome will need to have a cloud printing // dialog as backup. It's just that on Chrome OS, it's the only // print dialog. +#if 0 if (url.host() == chrome::kChromeUIComponentsHost) return &NewWebUI; +#endif if (url.spec() == chrome::kChromeUIConstrainedHTMLTestURL) return &NewWebUI; if (url.host() == chrome::kChromeUICrashesHost) @@ -327,6 +333,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, return &NewWebUI; if (url.host() == chrome::kChromeUIHistoryFrameHost) return &NewWebUI; +#if 0 if (url.host() == chrome::kChromeUIInstantHost) return &NewWebUI; if (url.host() == chrome::kChromeUIInterstitialHost) @@ -359,6 +366,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, return &NewWebUI; if (url.host() == chrome::kChromeUITranslateInternalsHost) return &NewWebUI; +#endif if (url.host() == chrome::kChromeUIUserActionsHost) return &NewWebUI; if (url.host() == chrome::kChromeUIVersionHost) @@ -381,8 +389,10 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, if (url.host() == chrome::kChromeUIBookmarksHost) return &NewWebUI; // Downloads list on Android uses the built-in download manager. +#if 0 if (url.host() == chrome::kChromeUIDownloadsHost) return &NewWebUI; +#endif // Help is implemented with native UI elements on Android. if (url.host() == chrome::kChromeUIHelpFrameHost) return &NewWebUI; @@ -395,6 +405,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, return &NewWebUI; // If the material design extensions page is enabled, it gets its own host. // Otherwise, it's handled by the uber settings page. +#if 0 if (url.host() == chrome::kChromeUIExtensionsHost && ::switches::MdExtensionsEnabled()) { return &NewWebUI; @@ -404,16 +415,19 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, url.host() == chrome::kChromeUIHistoryHost) { return &NewWebUI; } +#endif if (url.host() == chrome::kChromeUIQuotaInternalsHost) return &NewWebUI; // Settings are implemented with native UI elements on Android. // Handle chrome://settings if settings in a window and about in settings // are enabled. +#if 0 if (url.host() == chrome::kChromeUISettingsFrameHost || (url.host() == chrome::kChromeUISettingsHost && ::switches::AboutInSettingsEnabled())) { return &NewWebUI; } +#endif if (url.host() == chrome::kChromeUISyncFileSystemInternalsHost) return &NewWebUI; if (url.host() == chrome::kChromeUISystemInfoHost) @@ -497,7 +511,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, if (url.host() == chrome::kChromeUIInspectHost) return &NewWebUI; #endif -#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) +#if 0 if (url.host() == chrome::kChromeUIChromeSigninHost) return &NewWebUI; if (url.host() == chrome::kChromeUIUserManagerHost) @@ -542,7 +556,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, if (url.host() == chrome::kChromeUIAppListStartPageHost) return &NewWebUI; #endif -#if defined(ENABLE_EXTENSIONS) +#if 0 if (url.host() == chrome::kChromeUIExtensionsFrameHost) return &NewWebUI; #endif @@ -568,24 +582,30 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, return &NewWebUI; #endif #if defined(ENABLE_MEDIA_ROUTER) && !defined(OS_ANDROID) +#if defined(NWJS_SDK) if (url.host() == chrome::kChromeUIMediaRouterHost && media_router::MediaRouterEnabled(profile)) { return &NewWebUI; } #endif +#endif + +#if defined(NWJS_SDK) if (IsAboutUI(url)) return &NewWebUI; +#endif if (dom_distiller::IsEnableDomDistillerSet() && url.host() == dom_distiller::kChromeUIDomDistillerHost) { return &NewWebUI; } +#if 0 if (SiteEngagementService::IsEnabled() && url.host() == chrome::kChromeUISiteEngagementHost) { return &NewWebUI; } - +#endif return NULL; } @@ -730,8 +750,10 @@ base::RefCountedMemory* ChromeWebUIControllerFactory::GetFaviconResourceBytes( if (!content::HasWebUIScheme(page_url)) return NULL; +#if 0 if (page_url.host() == chrome::kChromeUIComponentsHost) return ComponentsUI::GetFaviconResourceBytes(scale_factor); +#endif #if defined(OS_WIN) if (page_url.host() == chrome::kChromeUIConflictsHost) @@ -758,6 +780,7 @@ base::RefCountedMemory* ChromeWebUIControllerFactory::GetFaviconResourceBytes( if (page_url.host() == chrome::kChromeUIFlashHost) return FlashUI::GetFaviconResourceBytes(scale_factor); +#if 0 // Android uses the native download manager. if (page_url.host() == chrome::kChromeUIDownloadsHost) return MdDownloadsUI::GetFaviconResourceBytes(scale_factor); @@ -766,8 +789,6 @@ base::RefCountedMemory* ChromeWebUIControllerFactory::GetFaviconResourceBytes( if (page_url.host() == chrome::kChromeUISettingsHost || page_url.host() == chrome::kChromeUISettingsFrameHost) return options::OptionsUI::GetFaviconResourceBytes(scale_factor); - -#if defined(ENABLE_EXTENSIONS) if (page_url.host() == chrome::kChromeUIExtensionsHost || page_url.host() == chrome::kChromeUIExtensionsFrameHost) return extensions::ExtensionsUI::GetFaviconResourceBytes(scale_factor); diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index 69eb887358621..76a4e76c8af1f 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc @@ -104,6 +104,12 @@ using content::WebContents; namespace { +CR_DEFINE_STATIC_LOCAL(std::string, g_nw_printer_name, ()); +CR_DEFINE_STATIC_LOCAL(base::FilePath, g_nw_print_to_pdf_path, ()); +CR_DEFINE_STATIC_LOCAL(std::unique_ptr, g_nw_print_options, ()); + +bool g_nw_custom_printing = false; + enum UserActionBuckets { PRINT_TO_PRINTER, PRINT_TO_PDF, @@ -409,6 +415,25 @@ std::pair GetPrinterNameAndDescription( #endif } +} //namespace + +namespace chrome { +void NWPrintSetCustomPrinting(bool value) { + g_nw_custom_printing = value; +} + +void NWPrintSetOptions(const base::DictionaryValue* dict) { + g_nw_print_options = dict->CreateDeepCopy(); +} + +void NWPrintSetPDFPath(const base::FilePath& path) { + g_nw_print_to_pdf_path = path; +} + +void NWPrintSetDefaultPrinter(const std::string& printer_name) { + g_nw_printer_name = printer_name; +} + void EnumeratePrintersOnFileThread(base::ListValue* printers) { DCHECK_CURRENTLY_ON(BrowserThread::FILE); @@ -443,6 +468,9 @@ void EnumeratePrintersOnFileThread(base::ListValue* printers) { << " printers"; } +} // namespace chrome + +namespace { std::unique_ptr GetPrinterCapabilitiesOnFileThread( const std::string& device_name) { DCHECK_CURRENTLY_ON(BrowserThread::FILE); @@ -699,7 +727,7 @@ void PrintPreviewHandler::HandleGetPrinters(const base::ListValue* /*args*/) { base::ListValue* results = new base::ListValue; BrowserThread::PostTaskAndReply( BrowserThread::FILE, FROM_HERE, - base::Bind(&EnumeratePrintersOnFileThread, + base::Bind(&chrome::EnumeratePrintersOnFileThread, base::Unretained(results)), base::Bind(&PrintPreviewHandler::SetupPrinterList, weak_factory_.GetWeakPtr(), @@ -808,6 +836,26 @@ void PrintPreviewHandler::HandleGetPreview(const base::ListValue* args) { &display_header_footer)) { NOTREACHED(); } + if (g_nw_print_options) { + bool landscape, backgrounds; + int margins_type; + base::DictionaryValue* media_size_value = nullptr; + base::DictionaryValue* custom_margins = nullptr; + + if (g_nw_print_options->GetDictionary(printing::kSettingMediaSize, &media_size_value) && !media_size_value->empty()) + settings->Set(printing::kSettingMediaSize, media_size_value->CreateDeepCopy()); + if (g_nw_print_options->GetBoolean(printing::kSettingHeaderFooterEnabled, &display_header_footer)) + settings->SetBoolean(printing::kSettingHeaderFooterEnabled, display_header_footer); + if (g_nw_print_options->GetBoolean(printing::kSettingLandscape, &landscape)) + settings->SetBoolean(printing::kSettingLandscape, landscape); + if (g_nw_print_options->GetBoolean(printing::kSettingShouldPrintBackgrounds, &backgrounds)) + settings->SetBoolean(printing::kSettingShouldPrintBackgrounds, backgrounds); + if (g_nw_print_options->GetInteger(printing::kSettingMarginsType, &margins_type)) + settings->SetInteger(printing::kSettingMarginsType, margins_type); + if (g_nw_print_options->GetDictionary(printing::kSettingMarginsCustom, &custom_margins) && !custom_margins->empty()) + settings->Set(printing::kSettingMarginsCustom, custom_margins->CreateDeepCopy()); + } + if (display_header_footer) { settings->SetString(printing::kSettingHeaderFooterTitle, initiator->GetTitle()); @@ -878,6 +926,12 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { return; ReportPrintSettingsStats(*settings); + if (g_nw_print_options) { + base::ListValue* page_range_array = nullptr; + + if (g_nw_print_options->GetList(printing::kSettingPageRange, &page_range_array) && !page_range_array->empty()) + settings->Set(printing::kSettingPageRange, page_range_array->CreateDeepCopy()); + } // Never try to add headers/footers here. It's already in the generated PDF. settings->SetBoolean(printing::kSettingHeaderFooterEnabled, false); @@ -907,9 +961,12 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { UMA_HISTOGRAM_COUNTS("PrintPreview.PageCount.PrintToPDF", page_count); ReportUserActionHistogram(PRINT_TO_PDF); PrintToPdf(); + chrome::NWPrintSetCustomPrinting(false); return; } + chrome::NWPrintSetCustomPrinting(false); + #if defined(ENABLE_SERVICE_DISCOVERY) if (print_with_privet && PrivetPrintingEnabled()) { std::string printer_name; @@ -1047,6 +1104,8 @@ void PrintPreviewHandler::HandlePrint(const base::ListValue* args) { } void PrintPreviewHandler::PrintToPdf() { + if (!g_nw_print_to_pdf_path.empty() && g_nw_custom_printing) + print_to_pdf_path_ = g_nw_print_to_pdf_path; if (!print_to_pdf_path_.empty()) { // User has already selected a path, no need to show the dialog again. PostPrintToPdfTask(); @@ -1261,7 +1320,7 @@ void PrintPreviewHandler::SendInitialSettings( print_preview_ui()->initiator_title()); initial_settings.SetBoolean(printing::kSettingPreviewModifiable, print_preview_ui()->source_is_modifiable()); - initial_settings.SetString(printing::kSettingPrinterName, default_printer); + initial_settings.SetString(printing::kSettingPrinterName, g_nw_printer_name.empty() ? default_printer : g_nw_printer_name); initial_settings.SetBoolean(kDocumentHasSelection, print_preview_ui()->source_has_selection()); initial_settings.SetBoolean(printing::kSettingShouldPrintSelectionOnly, @@ -1277,9 +1336,12 @@ void PrintPreviewHandler::SendInitialSettings( base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); initial_settings.SetBoolean(kPrintAutomaticallyInKioskMode, - cmdline->HasSwitch(switches::kKioskModePrinting)); + cmdline->HasSwitch(switches::kKioskModePrinting) || g_nw_custom_printing); initial_settings.SetBoolean(kAppKioskMode, chrome::IsRunningInForcedAppMode()); + if (g_nw_custom_printing) + initial_settings.SetBoolean("nwPrintMode", true); + if (prefs) { const std::string rules_str = prefs->GetString(prefs::kPrintPreviewDefaultDestinationSelectionRules); diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h index 60d4278b7c0ec..093df230129d7 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h @@ -30,6 +30,15 @@ class PrintSystemTaskProxy; namespace base { class DictionaryValue; class RefCountedBytes; +class ListValue; +} + +namespace chrome { + void EnumeratePrintersOnFileThread(base::ListValue* printers); + void NWPrintSetCustomPrinting(bool value); + void NWPrintSetDefaultPrinter(const std::string& printer_name); + void NWPrintSetPDFPath(const base::FilePath& path); + void NWPrintSetOptions(const base::DictionaryValue* dict); } namespace content { diff --git a/chrome/browser/ui/webui/settings/font_handler.cc b/chrome/browser/ui/webui/settings/font_handler.cc index 2c10ff2aa7f04..f23d8d739fa0b 100644 --- a/chrome/browser/ui/webui/settings/font_handler.cc +++ b/chrome/browser/ui/webui/settings/font_handler.cc @@ -40,7 +40,9 @@ FontHandler::FontHandler(content::WebUI* webui) profile_(Profile::FromWebUI(webui)), weak_ptr_factory_(this) { // Perform validation for saved fonts. +#if 0 options::FontSettingsUtilities::ValidateSavedFonts(profile_->GetPrefs()); +#endif } FontHandler::~FontHandler() {} diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index b2ddfdec737bb..5294bee995358 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc @@ -52,6 +52,7 @@ namespace settings { MdSettingsUI::MdSettingsUI(content::WebUI* web_ui) : content::WebUIController(web_ui), WebContentsObserver(web_ui->GetWebContents()) { +#if 0 Profile* profile = Profile::FromWebUI(web_ui); AddSettingsPageUIHandler(new AppearanceHandler(web_ui)); @@ -105,6 +106,7 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui) content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), html_source); +#endif } MdSettingsUI::~MdSettingsUI() { diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index a32d344dea3a5..0bf7d8d5a89bd 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc @@ -535,6 +535,7 @@ void PeopleHandler::HandleStopSyncing(const base::ListValue* args) { if (GetSyncService()) ProfileSyncService::SyncEvent(ProfileSyncService::STOP_FROM_OPTIONS); +#if 0 bool delete_profile = false; args->GetBoolean(0, &delete_profile); signin_metrics::SignoutDelete delete_metric = @@ -549,6 +550,7 @@ void PeopleHandler::HandleStopSyncing(const base::ListValue* args) { web_ui(), ProfileMetrics::DELETE_PROFILE_SETTINGS); } +#endif } #endif diff --git a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc index ccf799c23b100..013fe31cd806a 100644 --- a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc +++ b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc @@ -129,6 +129,7 @@ void TranslateInternalsHandler::OnTranslateEvent( } void TranslateInternalsHandler::OnRemovePrefItem(const base::ListValue* args) { +#if 0 content::WebContents* web_contents = web_ui()->GetWebContents(); Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); @@ -164,6 +165,7 @@ void TranslateInternalsHandler::OnRemovePrefItem(const base::ListValue* args) { } SendPrefsToJs(); +#endif } void TranslateInternalsHandler::OnOverrideCountry(const base::ListValue* args) { diff --git a/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc b/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc index d4653b698fe31..991c915dd9f17 100644 --- a/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc +++ b/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc @@ -65,7 +65,7 @@ content::WebUIDataSource* CreateTranslateInternalsHTMLSource() { // The version string is hardcoded here to avoid linking with the CLD // library, see http://crbug.com/297777. cld_version = "2"; - cld_data_source = translate::CldDataSource::Get()->GetName(); + //cld_data_source = translate::CldDataSource::Get()->GetName(); source->AddString("cld-version", cld_version); source->AddString("cld-data-source", cld_data_source); diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 2607d8b2fc667..385ada5a75e49 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -21,6 +21,8 @@ 'chromium_child_dependencies': [ 'common', '../sync/sync.gyp:sync', + #'../v8/tools/gyp/v8.gyp:v8_libplatform', + #'../third_party/node/node.gyp:node', ], 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/chrome', 'protoc_out_dir': '<(SHARED_INTERMEDIATE_DIR)/protoc_out', @@ -37,7 +39,7 @@ 'utility', '../content/content.gyp:content_gpu', '../content/content.gyp:content_ppapi_plugin', - '../third_party/cld_2/cld_2.gyp:cld2_platform_impl', + #'../third_party/cld_2/cld_2.gyp:cld2_platform_impl', '../third_party/WebKit/public/blink_devtools.gyp:blink_devtools_frontend_resources', ], 'conditions': [ @@ -85,6 +87,7 @@ ], # conditions }, # variables 'includes': [ + '../content/nw/nw.gypi', # Place some targets in gypi files to reduce contention on this file. # By using an include, we keep everything in a single xcodeproj file. # Note on Win64 targets: targets that end with win64 be used @@ -347,7 +350,7 @@ 'inputs': [ '<(DEPTH)/build/linux/dump_app_syms.py', '<(PRODUCT_DIR)/dump_syms', - '<(PRODUCT_DIR)/chrome', + '<(PRODUCT_DIR)/nw', ], 'outputs': [ '<(PRODUCT_DIR)/chrome.breakpad.<(target_arch)', @@ -356,7 +359,7 @@ '<(DEPTH)/build/linux/dump_app_syms.py', '<(PRODUCT_DIR)/dump_syms', '<(linux_strip_binary)', - '<(PRODUCT_DIR)/chrome', + '<(PRODUCT_DIR)/nw', '<@(_outputs)'], 'message': 'Dumping breakpad symbols to <(_outputs)', 'process_outputs_as_sources': 1, diff --git a/chrome/chrome.isolate b/chrome/chrome.isolate index 86ca3cc25f8c6..6d67c1327cb98 100644 --- a/chrome/chrome.isolate +++ b/chrome/chrome.isolate @@ -28,11 +28,11 @@ ['OS=="linux" or OS=="win"', { 'variables': { 'command': [ - '<(PRODUCT_DIR)/chrome<(EXECUTABLE_SUFFIX)', + '<(PRODUCT_DIR)/nw<(EXECUTABLE_SUFFIX)', ], 'files': [ - '<(PRODUCT_DIR)/chrome<(EXECUTABLE_SUFFIX)', - '<(PRODUCT_DIR)/chrome_100_percent.pak', + '<(PRODUCT_DIR)/nw<(EXECUTABLE_SUFFIX)', + '<(PRODUCT_DIR)/nw_100_percent.pak', '<(PRODUCT_DIR)/locales/en-US.pak', '<(PRODUCT_DIR)/locales/fr.pak', '<(PRODUCT_DIR)/resources/extension/', @@ -86,9 +86,9 @@ 'variables': { 'files': [ '<(PRODUCT_DIR)/<(version_full).manifest', - '<(PRODUCT_DIR)/chrome_200_percent.pak', - '<(PRODUCT_DIR)/chrome.dll', - '<(PRODUCT_DIR)/chrome_elf.dll', + '<(PRODUCT_DIR)/nw_200_percent.pak', + '<(PRODUCT_DIR)/nw.dll', + '<(PRODUCT_DIR)/nw_elf.dll', '<(PRODUCT_DIR)/osmesa.dll', ], }, @@ -111,7 +111,7 @@ ['OS=="win" and component=="static_library"', { 'variables': { 'files': [ - '<(PRODUCT_DIR)/chrome_child.dll', + '<(PRODUCT_DIR)/nw_child.dll', ], }, }], diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index c8a76abdd76b1..d1cb8efaefbf3 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -157,8 +157,8 @@ 'browser/component_updater/caps_installer_win.h', 'browser/component_updater/chrome_component_updater_configurator.cc', 'browser/component_updater/chrome_component_updater_configurator.h', - 'browser/component_updater/cld_component_installer.cc', - 'browser/component_updater/cld_component_installer.h', + #'browser/component_updater/cld_component_installer.cc', + #'browser/component_updater/cld_component_installer.h', 'browser/component_updater/component_patcher_operation_out_of_process.cc', 'browser/component_updater/component_patcher_operation_out_of_process.h', 'browser/component_updater/component_updater_resource_throttle.cc', @@ -652,12 +652,12 @@ 'browser/tracing/crash_service_uploader.h', 'browser/tracing/navigation_tracing.cc', 'browser/tracing/navigation_tracing.h', - 'browser/translate/chrome_translate_client.cc', - 'browser/translate/chrome_translate_client.h', - 'browser/translate/translate_accept_languages_factory.cc', - 'browser/translate/translate_accept_languages_factory.h', - 'browser/translate/translate_service.cc', - 'browser/translate/translate_service.h', +# 'browser/translate/chrome_translate_client.cc', +# 'browser/translate/chrome_translate_client.h', +# 'browser/translate/translate_accept_languages_factory.cc', +# 'browser/translate/translate_accept_languages_factory.h', +# 'browser/translate/translate_service.cc', +# 'browser/translate/translate_service.h', 'browser/update_client/chrome_update_query_params_delegate.cc', 'browser/update_client/chrome_update_query_params_delegate.h', 'browser/usb/usb_chooser_context.cc', @@ -3176,6 +3176,7 @@ 'dependencies': [ # NOTE: New dependencies should generally be added in the OS!="ios" # dependencies block below, rather than here. + 'nw_base', 'browser_ui', 'chrome_features.gyp:chrome_common_features', 'chrome_resources.gyp:chrome_extra_resources', @@ -3196,7 +3197,7 @@ '../components/components.gyp:cloud_devices_common', '../components/components.gyp:cloud_policy_proto', '../components/components.gyp:component_metrics_proto', - '../components/components.gyp:component_updater', + #'../components/components.gyp:component_updater', '../components/components.gyp:content_settings_content_common', '../components/components.gyp:content_settings_core_browser', '../components/components.gyp:content_settings_core_common', @@ -3229,7 +3230,7 @@ '../components/components.gyp:policy_component', '../components/components.gyp:proxy_config', '../components/components.gyp:query_parser', - '../components/components.gyp:rappor', + #'../components/components.gyp:rappor', '../components/components.gyp:search', '../components/components.gyp:search_engines', '../components/components.gyp:search_provider_logos', @@ -3266,6 +3267,7 @@ '../components/url_formatter/url_formatter.gyp:url_formatter', '../content/content.gyp:content_browser', '../content/content.gyp:content_common', + 'nw_content', '../courgette/courgette.gyp:courgette_lib', '../crypto/crypto.gyp:crypto', '../google_apis/google_apis.gyp:google_apis', @@ -3364,7 +3366,7 @@ '../components/components.gyp:ssl_config', '../components/components.gyp:storage_monitor', '../components/components.gyp:syncable_prefs', - '../components/components.gyp:translate_content_browser', + #'../components/components.gyp:translate_content_browser', '../components/components.gyp:upload_list', '../components/components.gyp:url_matcher', '../components/components.gyp:user_prefs_tracked', diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index f46547b462b6f..2063b50e1e5b5 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -539,12 +539,12 @@ 'browser/extensions/api/webstore_private/webstore_private_api.h', 'browser/extensions/app_data_migrator.cc', 'browser/extensions/app_data_migrator.h', - 'browser/extensions/blacklist.cc', - 'browser/extensions/blacklist.h', - 'browser/extensions/blacklist_factory.cc', - 'browser/extensions/blacklist_factory.h', - 'browser/extensions/blacklist_state_fetcher.cc', - 'browser/extensions/blacklist_state_fetcher.h', +# 'browser/extensions/blacklist.cc', +# 'browser/extensions/blacklist.h', +# 'browser/extensions/blacklist_factory.cc', +# 'browser/extensions/blacklist_factory.h', +# 'browser/extensions/blacklist_state_fetcher.cc', +# 'browser/extensions/blacklist_state_fetcher.h', 'browser/extensions/blob_reader.cc', 'browser/extensions/blob_reader.h', 'browser/extensions/bookmark_app_helper.cc', diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 594846dbe0c20..5752ff7807ef4 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -302,8 +302,8 @@ 'browser/ui/webui/chromeos/touch_view_controller_delegate.h', 'browser/ui/webui/chromeos/ui_account_tweaks.cc', 'browser/ui/webui/chromeos/ui_account_tweaks.h', - 'browser/ui/webui/components_ui.cc', - 'browser/ui/webui/components_ui.h', +# 'browser/ui/webui/components_ui.cc', +# 'browser/ui/webui/components_ui.h', 'browser/ui/webui/constrained_web_dialog_ui.cc', 'browser/ui/webui/constrained_web_dialog_ui.h', 'browser/ui/webui/cookies_tree_model_util.cc', @@ -314,8 +314,8 @@ 'browser/ui/webui/device_log_ui.h', 'browser/ui/webui/domain_reliability_internals_ui.cc', 'browser/ui/webui/domain_reliability_internals_ui.h', - 'browser/ui/webui/engagement/site_engagement_ui.cc', - 'browser/ui/webui/engagement/site_engagement_ui.h', + #'browser/ui/webui/engagement/site_engagement_ui.cc', + #'browser/ui/webui/engagement/site_engagement_ui.h', 'browser/ui/webui/fallback_icon_source.cc', 'browser/ui/webui/fallback_icon_source.h', 'browser/ui/webui/favicon_source.cc', @@ -328,10 +328,10 @@ 'browser/ui/webui/gcm_internals_ui.h', 'browser/ui/webui/history_ui.cc', 'browser/ui/webui/history_ui.h', - 'browser/ui/webui/instant_ui.cc', - 'browser/ui/webui/instant_ui.h', - 'browser/ui/webui/interstitials/interstitial_ui.cc', - 'browser/ui/webui/interstitials/interstitial_ui.h', +# 'browser/ui/webui/instant_ui.cc', +# 'browser/ui/webui/instant_ui.h', +# 'browser/ui/webui/interstitials/interstitial_ui.cc', +# 'browser/ui/webui/interstitials/interstitial_ui.h', 'browser/ui/webui/invalidations_message_handler.cc', 'browser/ui/webui/invalidations_message_handler.h', 'browser/ui/webui/invalidations_ui.cc', @@ -385,10 +385,10 @@ 'browser/ui/webui/test_files_request_filter.h', 'browser/ui/webui/theme_source.cc', 'browser/ui/webui/theme_source.h', - 'browser/ui/webui/translate_internals/translate_internals_handler.cc', - 'browser/ui/webui/translate_internals/translate_internals_handler.h', - 'browser/ui/webui/translate_internals/translate_internals_ui.cc', - 'browser/ui/webui/translate_internals/translate_internals_ui.h', +# 'browser/ui/webui/translate_internals/translate_internals_handler.cc', +# 'browser/ui/webui/translate_internals/translate_internals_handler.h', +# 'browser/ui/webui/translate_internals/translate_internals_ui.cc', +# 'browser/ui/webui/translate_internals/translate_internals_ui.h', 'browser/ui/webui/user_actions/user_actions_ui.cc', 'browser/ui/webui/user_actions/user_actions_ui.h', 'browser/ui/webui/user_actions/user_actions_ui_handler.cc', @@ -1348,26 +1348,26 @@ 'browser/ui/webui/settings/settings_default_browser_handler.h', 'browser/ui/webui/settings/system_handler.cc', 'browser/ui/webui/settings/system_handler.h', - 'browser/ui/webui/signin/inline_login_handler.cc', - 'browser/ui/webui/signin/inline_login_handler.h', - 'browser/ui/webui/signin/inline_login_handler_impl.cc', - 'browser/ui/webui/signin/inline_login_handler_impl.h', - 'browser/ui/webui/signin/inline_login_ui.cc', - 'browser/ui/webui/signin/inline_login_ui.h', - 'browser/ui/webui/signin/md_user_manager_ui.cc', - 'browser/ui/webui/signin/md_user_manager_ui.h', - 'browser/ui/webui/signin/signin_create_profile_handler.cc', - 'browser/ui/webui/signin/signin_create_profile_handler.h', - 'browser/ui/webui/signin/signin_supervised_user_import_handler.cc', - 'browser/ui/webui/signin/signin_supervised_user_import_handler.h', - 'browser/ui/webui/signin/sync_confirmation_handler.cc', - 'browser/ui/webui/signin/sync_confirmation_handler.h', - 'browser/ui/webui/signin/sync_confirmation_ui.cc', - 'browser/ui/webui/signin/sync_confirmation_ui.h', - 'browser/ui/webui/signin/user_manager_screen_handler.cc', - 'browser/ui/webui/signin/user_manager_screen_handler.h', - 'browser/ui/webui/signin/user_manager_ui.cc', - 'browser/ui/webui/signin/user_manager_ui.h', + #'browser/ui/webui/signin/inline_login_handler.cc', + #'browser/ui/webui/signin/inline_login_handler.h', + #'browser/ui/webui/signin/inline_login_handler_impl.cc', + #'browser/ui/webui/signin/inline_login_handler_impl.h', + #'browser/ui/webui/signin/inline_login_ui.cc', + #'browser/ui/webui/signin/inline_login_ui.h', + #'browser/ui/webui/signin/md_user_manager_ui.cc', + #'browser/ui/webui/signin/md_user_manager_ui.h', + #'browser/ui/webui/signin/signin_create_profile_handler.cc', + #'browser/ui/webui/signin/signin_create_profile_handler.h', + #'browser/ui/webui/signin/signin_supervised_user_import_handler.cc', + #'browser/ui/webui/signin/signin_supervised_user_import_handler.h', + #'browser/ui/webui/signin/sync_confirmation_handler.cc', + #'browser/ui/webui/signin/sync_confirmation_handler.h', + #'browser/ui/webui/signin/sync_confirmation_ui.cc', + #'browser/ui/webui/signin/sync_confirmation_ui.h', + #'browser/ui/webui/signin/user_manager_screen_handler.cc', + #'browser/ui/webui/signin/user_manager_screen_handler.h', + #'browser/ui/webui/signin/user_manager_ui.cc', + #'browser/ui/webui/signin/user_manager_ui.h', ], # Desktop Linux. Assume aura/ash/views/x11. 'chrome_browser_ui_desktop_linux_sources': [ @@ -1842,8 +1842,8 @@ 'browser/ui/webui/extensions/extension_loader_handler.h', 'browser/ui/webui/extensions/extension_settings_handler.cc', 'browser/ui/webui/extensions/extension_settings_handler.h', - 'browser/ui/webui/extensions/extensions_ui.cc', - 'browser/ui/webui/extensions/extensions_ui.h', + #'browser/ui/webui/extensions/extensions_ui.cc', + #'browser/ui/webui/extensions/extensions_ui.h', 'browser/ui/webui/extensions/install_extension_handler.cc', 'browser/ui/webui/extensions/install_extension_handler.h', 'browser/ui/webui/foreign_session_handler.cc', @@ -1866,14 +1866,14 @@ 'browser/ui/webui/identity_internals_ui.h', 'browser/ui/webui/inspect_ui.cc', 'browser/ui/webui/inspect_ui.h', - 'browser/ui/webui/md_downloads/downloads_list_tracker.cc', - 'browser/ui/webui/md_downloads/downloads_list_tracker.h', - 'browser/ui/webui/md_downloads/md_downloads_dom_handler.cc', - 'browser/ui/webui/md_downloads/md_downloads_dom_handler.h', - 'browser/ui/webui/md_downloads/md_downloads_ui.cc', - 'browser/ui/webui/md_downloads/md_downloads_ui.h', - 'browser/ui/webui/md_history_ui.cc', - 'browser/ui/webui/md_history_ui.h', + #'browser/ui/webui/md_downloads/downloads_list_tracker.cc', + #'browser/ui/webui/md_downloads/downloads_list_tracker.h', + #'browser/ui/webui/md_downloads/md_downloads_dom_handler.cc', + #'browser/ui/webui/md_downloads/md_downloads_dom_handler.h', + #'browser/ui/webui/md_downloads/md_downloads_ui.cc', + #'browser/ui/webui/md_downloads/md_downloads_ui.h', + #'browser/ui/webui/md_history_ui.cc', + #'browser/ui/webui/md_history_ui.h', 'browser/ui/webui/ntp/app_launcher_handler.cc', 'browser/ui/webui/ntp/app_launcher_handler.h', 'browser/ui/webui/ntp/app_resource_cache_factory.cc', @@ -1888,102 +1888,102 @@ 'browser/ui/webui/ntp/ntp_resource_cache.h', 'browser/ui/webui/ntp/ntp_resource_cache_factory.cc', 'browser/ui/webui/ntp/ntp_resource_cache_factory.h', - 'browser/ui/webui/options/autofill_options_handler.cc', - 'browser/ui/webui/options/autofill_options_handler.h', - 'browser/ui/webui/options/automatic_settings_reset_handler.cc', - 'browser/ui/webui/options/automatic_settings_reset_handler.h', - 'browser/ui/webui/options/browser_options_handler.cc', - 'browser/ui/webui/options/browser_options_handler.h', - 'browser/ui/webui/options/chromeos/accounts_options_handler.cc', - 'browser/ui/webui/options/chromeos/accounts_options_handler.h', - 'browser/ui/webui/options/chromeos/bluetooth_options_handler.cc', - 'browser/ui/webui/options/chromeos/bluetooth_options_handler.h', - 'browser/ui/webui/options/chromeos/change_picture_options_handler.cc', - 'browser/ui/webui/options/chromeos/change_picture_options_handler.h', - 'browser/ui/webui/options/chromeos/consumer_management_handler.cc', - 'browser/ui/webui/options/chromeos/consumer_management_handler.h', - 'browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc', - 'browser/ui/webui/options/chromeos/core_chromeos_options_handler.h', - 'browser/ui/webui/options/chromeos/cros_language_options_handler.cc', - 'browser/ui/webui/options/chromeos/cros_language_options_handler.h', - 'browser/ui/webui/options/chromeos/date_time_options_handler.cc', - 'browser/ui/webui/options/chromeos/date_time_options_handler.h', - 'browser/ui/webui/options/chromeos/display_options_handler.cc', - 'browser/ui/webui/options/chromeos/display_options_handler.h', - 'browser/ui/webui/options/chromeos/display_overscan_handler.cc', - 'browser/ui/webui/options/chromeos/display_overscan_handler.h', - 'browser/ui/webui/options/chromeos/internet_options_handler.cc', - 'browser/ui/webui/options/chromeos/internet_options_handler.h', - 'browser/ui/webui/options/chromeos/internet_options_handler_strings.cc', - 'browser/ui/webui/options/chromeos/internet_options_handler_strings.h', - 'browser/ui/webui/options/chromeos/keyboard_handler.cc', - 'browser/ui/webui/options/chromeos/keyboard_handler.h', - 'browser/ui/webui/options/chromeos/pointer_handler.cc', - 'browser/ui/webui/options/chromeos/pointer_handler.h', - 'browser/ui/webui/options/chromeos/power_handler.cc', - 'browser/ui/webui/options/chromeos/power_handler.h', - 'browser/ui/webui/options/chromeos/proxy_handler.cc', - 'browser/ui/webui/options/chromeos/proxy_handler.h', - 'browser/ui/webui/options/chromeos/stats_options_handler.cc', - 'browser/ui/webui/options/chromeos/stats_options_handler.h', - 'browser/ui/webui/options/chromeos/user_image_source.cc', - 'browser/ui/webui/options/chromeos/user_image_source.h', - 'browser/ui/webui/options/clear_browser_data_handler.cc', - 'browser/ui/webui/options/clear_browser_data_handler.h', - 'browser/ui/webui/options/content_settings_handler.cc', - 'browser/ui/webui/options/content_settings_handler.h', - 'browser/ui/webui/options/cookies_view_handler.cc', - 'browser/ui/webui/options/cookies_view_handler.h', - 'browser/ui/webui/options/core_options_handler.cc', - 'browser/ui/webui/options/core_options_handler.h', - 'browser/ui/webui/options/create_profile_handler.cc', - 'browser/ui/webui/options/create_profile_handler.h', - 'browser/ui/webui/options/easy_unlock_handler.cc', - 'browser/ui/webui/options/easy_unlock_handler.h', - 'browser/ui/webui/options/font_settings_handler.cc', - 'browser/ui/webui/options/font_settings_handler.h', - 'browser/ui/webui/options/font_settings_utils.h', - 'browser/ui/webui/options/font_settings_utils_linux.cc', - 'browser/ui/webui/options/font_settings_utils_mac.mm', - 'browser/ui/webui/options/font_settings_utils_win.cc', - 'browser/ui/webui/options/handler_options_handler.cc', - 'browser/ui/webui/options/handler_options_handler.h', - 'browser/ui/webui/options/help_overlay_handler.cc', - 'browser/ui/webui/options/help_overlay_handler.h', - 'browser/ui/webui/options/home_page_overlay_handler.cc', - 'browser/ui/webui/options/home_page_overlay_handler.h', - 'browser/ui/webui/options/import_data_handler.cc', - 'browser/ui/webui/options/import_data_handler.h', - 'browser/ui/webui/options/language_dictionary_overlay_handler.cc', - 'browser/ui/webui/options/language_dictionary_overlay_handler.h', - 'browser/ui/webui/options/language_options_handler.cc', - 'browser/ui/webui/options/language_options_handler.h', - 'browser/ui/webui/options/language_options_handler_common.cc', - 'browser/ui/webui/options/language_options_handler_common.h', - 'browser/ui/webui/options/manage_profile_handler.cc', - 'browser/ui/webui/options/manage_profile_handler.h', - 'browser/ui/webui/options/media_devices_selection_handler.cc', - 'browser/ui/webui/options/media_devices_selection_handler.h', - 'browser/ui/webui/options/options_ui.cc', - 'browser/ui/webui/options/options_ui.h', - 'browser/ui/webui/options/password_manager_handler.cc', - 'browser/ui/webui/options/password_manager_handler.h', - 'browser/ui/webui/options/pepper_flash_content_settings_utils.cc', - 'browser/ui/webui/options/pepper_flash_content_settings_utils.h', - 'browser/ui/webui/options/reset_profile_settings_handler.cc', - 'browser/ui/webui/options/reset_profile_settings_handler.h', - 'browser/ui/webui/options/search_engine_manager_handler.cc', - 'browser/ui/webui/options/search_engine_manager_handler.h', - 'browser/ui/webui/options/startup_pages_handler.cc', - 'browser/ui/webui/options/startup_pages_handler.h', - 'browser/ui/webui/options/supervised_user_create_confirm_handler.cc', - 'browser/ui/webui/options/supervised_user_create_confirm_handler.h', - 'browser/ui/webui/options/supervised_user_import_handler.cc', - 'browser/ui/webui/options/supervised_user_import_handler.h', - 'browser/ui/webui/options/supervised_user_learn_more_handler.cc', - 'browser/ui/webui/options/supervised_user_learn_more_handler.h', - 'browser/ui/webui/options/sync_setup_handler.cc', - 'browser/ui/webui/options/sync_setup_handler.h', + #'browser/ui/webui/options/autofill_options_handler.cc', + #'browser/ui/webui/options/autofill_options_handler.h', + #'browser/ui/webui/options/automatic_settings_reset_handler.cc', + #'browser/ui/webui/options/automatic_settings_reset_handler.h', + #'browser/ui/webui/options/browser_options_handler.cc', + #'browser/ui/webui/options/browser_options_handler.h', + #'browser/ui/webui/options/chromeos/accounts_options_handler.cc', + #'browser/ui/webui/options/chromeos/accounts_options_handler.h', + #'browser/ui/webui/options/chromeos/bluetooth_options_handler.cc', + #'browser/ui/webui/options/chromeos/bluetooth_options_handler.h', + #'browser/ui/webui/options/chromeos/change_picture_options_handler.cc', + #'browser/ui/webui/options/chromeos/change_picture_options_handler.h', + #'browser/ui/webui/options/chromeos/consumer_management_handler.cc', + #'browser/ui/webui/options/chromeos/consumer_management_handler.h', + #'browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc', + #'browser/ui/webui/options/chromeos/core_chromeos_options_handler.h', + #'browser/ui/webui/options/chromeos/cros_language_options_handler.cc', + #'browser/ui/webui/options/chromeos/cros_language_options_handler.h', + #'browser/ui/webui/options/chromeos/date_time_options_handler.cc', + #'browser/ui/webui/options/chromeos/date_time_options_handler.h', + #'browser/ui/webui/options/chromeos/display_options_handler.cc', + #'browser/ui/webui/options/chromeos/display_options_handler.h', + #'browser/ui/webui/options/chromeos/display_overscan_handler.cc', + #'browser/ui/webui/options/chromeos/display_overscan_handler.h', + #'browser/ui/webui/options/chromeos/internet_options_handler.cc', + #'browser/ui/webui/options/chromeos/internet_options_handler.h', + #'browser/ui/webui/options/chromeos/internet_options_handler_strings.cc', + #'browser/ui/webui/options/chromeos/internet_options_handler_strings.h', + #'browser/ui/webui/options/chromeos/keyboard_handler.cc', + #'browser/ui/webui/options/chromeos/keyboard_handler.h', + #'browser/ui/webui/options/chromeos/pointer_handler.cc', + #'browser/ui/webui/options/chromeos/pointer_handler.h', + #'browser/ui/webui/options/chromeos/power_handler.cc', + #'browser/ui/webui/options/chromeos/power_handler.h', + #'browser/ui/webui/options/chromeos/proxy_handler.cc', + #'browser/ui/webui/options/chromeos/proxy_handler.h', + #'browser/ui/webui/options/chromeos/stats_options_handler.cc', + #'browser/ui/webui/options/chromeos/stats_options_handler.h', + #'browser/ui/webui/options/chromeos/user_image_source.cc', + #'browser/ui/webui/options/chromeos/user_image_source.h', + #'browser/ui/webui/options/clear_browser_data_handler.cc', + #'browser/ui/webui/options/clear_browser_data_handler.h', + #'browser/ui/webui/options/content_settings_handler.cc', + #'browser/ui/webui/options/content_settings_handler.h', + #'browser/ui/webui/options/cookies_view_handler.cc', + #'browser/ui/webui/options/cookies_view_handler.h', + #'browser/ui/webui/options/core_options_handler.cc', + #'browser/ui/webui/options/core_options_handler.h', + #'browser/ui/webui/options/create_profile_handler.cc', + #'browser/ui/webui/options/create_profile_handler.h', + #'browser/ui/webui/options/easy_unlock_handler.cc', + #'browser/ui/webui/options/easy_unlock_handler.h', + #'browser/ui/webui/options/font_settings_handler.cc', + #'browser/ui/webui/options/font_settings_handler.h', + #'browser/ui/webui/options/font_settings_utils.h', + #'browser/ui/webui/options/font_settings_utils_linux.cc', + #'browser/ui/webui/options/font_settings_utils_mac.mm', + #'browser/ui/webui/options/font_settings_utils_win.cc', + #'browser/ui/webui/options/handler_options_handler.cc', + #'browser/ui/webui/options/handler_options_handler.h', + #'browser/ui/webui/options/help_overlay_handler.cc', + #'browser/ui/webui/options/help_overlay_handler.h', + #'browser/ui/webui/options/home_page_overlay_handler.cc', + #'browser/ui/webui/options/home_page_overlay_handler.h', + #'browser/ui/webui/options/import_data_handler.cc', + #'browser/ui/webui/options/import_data_handler.h', + #'browser/ui/webui/options/language_dictionary_overlay_handler.cc', + #'browser/ui/webui/options/language_dictionary_overlay_handler.h', + #'browser/ui/webui/options/language_options_handler.cc', + #'browser/ui/webui/options/language_options_handler.h', + #'browser/ui/webui/options/language_options_handler_common.cc', + #'browser/ui/webui/options/language_options_handler_common.h', + #'browser/ui/webui/options/manage_profile_handler.cc', + #'browser/ui/webui/options/manage_profile_handler.h', + #'browser/ui/webui/options/media_devices_selection_handler.cc', + #'browser/ui/webui/options/media_devices_selection_handler.h', + #'browser/ui/webui/options/options_ui.cc', + #'browser/ui/webui/options/options_ui.h', + #'browser/ui/webui/options/password_manager_handler.cc', + #'browser/ui/webui/options/password_manager_handler.h', + #'browser/ui/webui/options/pepper_flash_content_settings_utils.cc', + #'browser/ui/webui/options/pepper_flash_content_settings_utils.h', + #'browser/ui/webui/options/reset_profile_settings_handler.cc', + #'browser/ui/webui/options/reset_profile_settings_handler.h', + #'browser/ui/webui/options/search_engine_manager_handler.cc', + #'browser/ui/webui/options/search_engine_manager_handler.h', + #'browser/ui/webui/options/startup_pages_handler.cc', + #'browser/ui/webui/options/startup_pages_handler.h', + #'browser/ui/webui/options/supervised_user_create_confirm_handler.cc', + #'browser/ui/webui/options/supervised_user_create_confirm_handler.h', + #'browser/ui/webui/options/supervised_user_import_handler.cc', + #'browser/ui/webui/options/supervised_user_import_handler.h', + #'browser/ui/webui/options/supervised_user_learn_more_handler.cc', + #'browser/ui/webui/options/supervised_user_learn_more_handler.h', + #'browser/ui/webui/options/sync_setup_handler.cc', + #'browser/ui/webui/options/sync_setup_handler.h', 'browser/ui/webui/policy_indicator_localized_strings_provider.cc', 'browser/ui/webui/policy_indicator_localized_strings_provider.h', 'browser/ui/webui/profile_helper.cc', @@ -2744,8 +2744,8 @@ 'browser/ui/crypto_module_delegate_nss.h', 'browser/ui/crypto_module_password_dialog_nss.cc', 'browser/ui/crypto_module_password_dialog_nss.h', - 'browser/ui/webui/options/certificate_manager_handler.cc', - 'browser/ui/webui/options/certificate_manager_handler.h', + #'browser/ui/webui/options/certificate_manager_handler.cc', + #'browser/ui/webui/options/certificate_manager_handler.h', 'browser/ui/webui/settings/certificates_handler.cc', 'browser/ui/webui/settings/certificates_handler.h', ], @@ -2906,7 +2906,7 @@ '../components/components.gyp:flags_ui', '../components/components.gyp:net_log', '../components/components.gyp:page_load_metrics_browser', - '../components/components.gyp:translate_content_common', + #'../components/components.gyp:translate_content_common', '../components/components_resources.gyp:components_resources', '../content/app/resources/content_resources.gyp:content_resources', '../media/media.gyp:media', @@ -2935,6 +2935,13 @@ '../net/net.gyp:net', ], }], + ['nwjs_sdk==0', { + 'sources!': [ + 'browser/ui/webui/about_ui.cc', + 'browser/ui/webui/about_ui.h', + '<@(chrome_browser_ui_media_router_sources)', + ], + }], ['enable_basic_printing==1 or enable_print_preview==1', { 'dependencies': [ '../printing/printing.gyp:printing', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 3093461f3fd93..de3bca18aaca7 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -378,6 +378,7 @@ 'dependencies': [ '<(DEPTH)/device/usb/usb.gyp:device_usb', '<(DEPTH)/chrome/common/extensions/api/api.gyp:chrome_api', + '<(DEPTH)/content/nw/src/api/api.gyp:nw_api', '<(DEPTH)/extensions/common/api/api.gyp:extensions_api', '<(DEPTH)/extensions/extensions.gyp:extensions_common', '<(DEPTH)/extensions/extensions_resources.gyp:extensions_resources', @@ -419,7 +420,7 @@ '<(DEPTH)/components/components.gyp:password_manager_content_mojo_bindings', '<(DEPTH)/components/components.gyp:password_manager_core_common', '<(DEPTH)/components/components.gyp:signin_core_common', - '<(DEPTH)/components/components.gyp:translate_content_common', + #'<(DEPTH)/components/components.gyp:translate_content_common', '<(DEPTH)/components/components.gyp:visitedlink_common', '<(DEPTH)/extensions/extensions.gyp:extensions_common_constants', '<(DEPTH)/ipc/ipc.gyp:ipc', diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index f5dcc8bd1ad4f..8802b41c90477 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi @@ -32,7 +32,7 @@ ], }, ], - ['OS=="mac" or OS=="win"', { + ['OS=="mac" or OS=="win" or OS=="linux"', { 'targets': [ { # GN version: //chrome:chrome_dll @@ -67,14 +67,14 @@ { 'action_name': 'hardlink_to_output', 'inputs': [ - '$(OutDir)\\initial\\chrome.dll', + '$(OutDir)\\initial\\nw.dll', ], 'outputs': [ - '$(OutDir)\\chrome.dll', + '$(OutDir)\\nw.dll', ], 'action': ['tools\\build\\win\\hardlink_failsafe.bat', - '$(OutDir)\\initial\\chrome.dll', - '$(OutDir)\\chrome.dll'], + '$(OutDir)\\initial\\nw.dll', + '$(OutDir)\\nw.dll'], }, ], 'conditions': [ @@ -85,14 +85,14 @@ 'action_name': 'hardlink_pdb_to_output', 'inputs': [ # Not the pdb, since gyp doesn't know about it - '$(OutDir)\\initial\\chrome.dll', + '$(OutDir)\\initial\\nw.dll', ], 'outputs': [ - '$(OutDir)\\chrome.dll.pdb', + '$(OutDir)\\nw.dll.pdb', ], 'action': ['tools\\build\\win\\hardlink_failsafe.bat', - '$(OutDir)\\initial\\chrome.dll.pdb', - '$(OutDir)\\chrome.dll.pdb'], + '$(OutDir)\\initial\\nw.dll.pdb', + '$(OutDir)\\nw.dll.pdb'], } ] }] @@ -124,7 +124,7 @@ 'chrome_features.gyp:chrome_common_features', 'policy_path_parser', '../content/content.gyp:content_app_browser', - '../third_party/cld_2/cld_2.gyp:cld_2', + #'../third_party/cld_2/cld_2.gyp:cld_2', ], 'conditions': [ ['OS=="win"', { @@ -146,8 +146,11 @@ 'chrome_user32_delay_imports', ], },], + ['OS=="linux"', { + 'product_name': 'nw' + }], ['OS=="win"', { - 'product_name': 'chrome', + 'product_name': 'nw', 'dependencies': [ # On Windows, link the dependencies (libraries) that make # up actual Chromium functionality into this .dll. @@ -188,7 +191,7 @@ 'SubSystem': '2', 'conditions': [ ['incremental_chrome_dll==1', { - 'OutputFile': '$(OutDir)\\initial\\chrome.dll', + 'OutputFile': '$(OutDir)\\initial\\nw.dll', 'UseLibraryDependencyInputs': "true", }], ['target_arch=="ia32"', { @@ -243,7 +246,7 @@ }, 'VCManifestTool': { 'AdditionalManifestFiles': [ - '$(ProjectDir)\\app\\chrome.dll.manifest', + '$(ProjectDir)\\app\\nw.dll.manifest', ], }, }, @@ -300,7 +303,7 @@ ], }], # This step currently fails when using LTO. TODO(pcc): Re-enable. - ['OS=="mac" and use_lto==0 and component=="static_library" and asan==0', { + ['OS=="macdisable" and use_lto==0 and component=="static_library" and asan==0', { 'postbuilds': [ { # This step causes an error to be raised if the .order file @@ -328,7 +331,7 @@ # GN version: //chrome:chrome_child 'target_name': 'chrome_child_dll', 'type': 'shared_library', - 'product_name': 'chrome_child', + 'product_name': 'nw_child', 'variables': { 'enable_wexit_time_destructors': 1, }, diff --git a/chrome/chrome_dll_bundle.gypi b/chrome/chrome_dll_bundle.gypi index 38755ae403cde..65158042bcafe 100644 --- a/chrome/chrome_dll_bundle.gypi +++ b/chrome/chrome_dll_bundle.gypi @@ -57,7 +57,7 @@ 'app/framework-Info.plist', '<@(mac_all_xibs)', 'browser/mac/install.sh', - '<(SHARED_INTERMEDIATE_DIR)/repack/chrome_100_percent.pak', + '<(SHARED_INTERMEDIATE_DIR)/repack/nw_100_percent.pak', '<(SHARED_INTERMEDIATE_DIR)/repack/resources.pak', ' manifest_value( + base::JSONReader::Read(manifest_data, base::JSON_ALLOW_TRAILING_COMMAS)); + if (!manifest_value.get()) + return false; + base::DictionaryValue* manifest = NULL; + if (!manifest_value->GetAsDictionary(&manifest)) return false; - *plugin = CreatePepperFlashInfo(flash_path, FLAPPER_VERSION_STRING, false, + Version version; + if (!chrome::CheckPepperFlashManifest(*manifest, &version)) + return false; + *plugin = CreatePepperFlashInfo(flash_filename, version.GetString(), false, false, true); return true; #else diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index f4e119db21536..27b9559cdae8e 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc @@ -341,7 +341,7 @@ bool PathProvider(int key, base::FilePath* result) { // was shipped along with chrome. The value can be overridden // if it is installed via component updater. case chrome::DIR_PNACL_COMPONENT: -#if defined(OS_MACOSX) +#if 0 // 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 diff --git a/chrome/common/chrome_paths_linux.cc b/chrome/common/chrome_paths_linux.cc index aa26cc9bbb90e..7c37356e62152 100644 --- a/chrome/common/chrome_paths_linux.cc +++ b/chrome/common/chrome_paths_linux.cc @@ -14,6 +14,8 @@ #include "build/build_config.h" #include "chrome/common/chrome_paths_internal.h" +#include "content/nw/src/nw_base.h" + namespace chrome { using base::nix::GetXDGDirectory; @@ -69,7 +71,7 @@ bool GetDefaultUserDataDirectory(base::FilePath* result) { #if defined(GOOGLE_CHROME_BUILD) *result = config_dir.Append("google-chrome"); #else - *result = config_dir.Append("chromium"); + *result = config_dir.Append(nw::package()->GetName()); #endif return true; } diff --git a/chrome/common/chrome_paths_mac.mm b/chrome/common/chrome_paths_mac.mm index d0bbbf72ff0e3..a5fdec7fbc234 100644 --- a/chrome/common/chrome_paths_mac.mm +++ b/chrome/common/chrome_paths_mac.mm @@ -18,6 +18,8 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths_internal.h" +#include "content/nw/src/nw_base.h" + namespace { #if !defined(OS_IOS) @@ -65,7 +67,7 @@ #if defined(GOOGLE_CHROME_BUILD) product_dir_name = "Google/Chrome"; #else - product_dir_name = "Chromium"; + product_dir_name = "nwjs"; #endif } @@ -74,6 +76,7 @@ return strdup(product_dir_name); } +#if 0 // ProductDirName returns the name of the directory inside // ~/Library/Application Support that should hold the product application // data. This can be overridden by setting the CrProductDirName key in the @@ -99,6 +102,7 @@ #endif return std::string(product_dir_name); } +#endif bool GetDefaultUserDataDirectoryForProduct(const std::string& product_dir, base::FilePath* result) { @@ -115,7 +119,7 @@ bool GetDefaultUserDataDirectoryForProduct(const std::string& product_dir, namespace chrome { bool GetDefaultUserDataDirectory(base::FilePath* result) { - return GetDefaultUserDataDirectoryForProduct(ProductDirName(), result); + return GetDefaultUserDataDirectoryForProduct(nw::package()->GetName(), result); } bool GetUserDocumentsDirectory(base::FilePath* result) { diff --git a/chrome/common/chrome_paths_win.cc b/chrome/common/chrome_paths_win.cc index 597448bdf67a2..07ab6795d3164 100644 --- a/chrome/common/chrome_paths_win.cc +++ b/chrome/common/chrome_paths_win.cc @@ -19,6 +19,8 @@ #include "chrome/installer/util/browser_distribution.h" #include "components/nacl/common/nacl_switches.h" +#include "content/nw/src/nw_base.h" + namespace chrome { namespace { @@ -45,8 +47,9 @@ bool GetUserDirectory(int csidl_folder, base::FilePath* result) { bool GetDefaultUserDataDirectory(base::FilePath* result) { if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result)) return false; - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - *result = result->Append(dist->GetInstallSubDir()); + //BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + if (nw::package()) //FIXME: crashpad initialized early in cr49 + *result = result->Append(base::FilePath::FromUTF8Unsafe(nw::package()->GetName())); *result = result->Append(chrome::kUserDataDirname); return true; } diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index f218af12924c9..f05de8e215179 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -573,7 +573,8 @@ }], "launcherPage": { "dependencies": ["manifest:launcher_page"], - "contexts": ["blessed_extension"] + "contexts": ["blessed_extension"], + "platforms": ["chromeos"] }, "launcherSearchProvider": { "dependencies": ["permission:launcherSearchProvider"], @@ -780,6 +781,7 @@ }, { "channel": "trunk", "contexts": ["webui"], + "dependencies": ["permission:usersPrivate"], "matches": [ "chrome://md-settings/*", "chrome://settings/*", diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 158bb33c7391d..34e90ec5c4db9 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -271,16 +271,7 @@ ], "developerPrivate": { "channel": "stable", - "extension_types": ["platform_app"], - "whitelist": [ - "AE27D69DBE571F4B1694F05C89B710C646792231", // Published ADT. - "FA0501B579070BB9CBD4FCAEC8CB0EDF22BA2F04", // Apps Editor published. - "4A4EA121622FCA3D78ED2AB534197F43D7189EE0", // Spark nightly build. - "9FDE6E7F06FCFA11D9A05041C7FF6D8AE662F5D1", // Spark release. - "50B4A905D522C06E27CA6D099E3E54BDA1F152C5", // Spark Beta channel. - "BA0C8BB92084C9741312D90D3EA882526853455F", // Spark dev channel. - "5F57A9AE8DFF5D6BB09DF8606270402612E871E5" // http://crbug.com/422624 - ] + "extension_types": ["platform_app"] }, "devtools": { "channel": "stable", @@ -550,7 +541,7 @@ "launcherSearchProvider": { "channel": "stable", "extension_types": ["extension", "platform_app"], - "platform": ["chromeos"], + "platforms": ["chromeos"], "whitelist": [ "A948368FC53BE437A55FEB414106E207925482F5" // File Manager ] @@ -558,6 +549,7 @@ "logPrivate": { "channel": "stable", "extension_types": ["extension", "platform_app"], + "platforms": ["chromeos"], "whitelist": [ "ddammdhioacbehjngdmkjcjbnfginlla", // Test "1C93BD3CF875F4A73C0B2A163BB8FBDA8B8B3D80", // http://crbug.com/293683 @@ -573,6 +565,7 @@ }, "webcamPrivate": { "channel": "stable", + "platforms": ["chromeos"], "extension_types": ["extension", "platform_app"] }, "management": [ @@ -582,25 +575,7 @@ }, { "channel": "stable", - "extension_types": ["platform_app"], - "whitelist": [ - "AE27D69DBE571F4B1694F05C89B710C646792231", // Published ADT - // TODO(grv): clean up once Apps developer tool is published. - "5107DE9024C329EEA9C9A72D94C16723790C6422", // Apps Developer Tool. - "8C0B1873FFFB65E4D0F4D772879F7304CEF125C2", // Apps Editor old. - "FA0501B579070BB9CBD4FCAEC8CB0EDF22BA2F04", // Apps Editor published. - "EE17C698905F7F2E6DDC87C9C30F11E164C829F4", // Watchdog (Activity Log) - "90113DA9516526D24DAF156C629CC41C049E8882", // Watchdog Test Version - "4A4EA121622FCA3D78ED2AB534197F43D7189EE0", // Spark nightly build. - "9FDE6E7F06FCFA11D9A05041C7FF6D8AE662F5D1", // Spark release. - "50B4A905D522C06E27CA6D099E3E54BDA1F152C5", // Spark Beta channel. - "BA0C8BB92084C9741312D90D3EA882526853455F", // Spark dev channel. - "11B478CEC461C766A2DC1E5BEEB7970AE06DC9C2", // http://crbug.com/408276 - "0EFB879311E9EFBB7C45251F89EC655711B1F6ED", // http://crbug.com/408276 - "9193D3A51E2FE33B496CDA53EA330423166E7F02", // http://crbug.com/408276 - "F9119B8B18C7C82B51E7BC6FF816B694F2EC3E89", // http://crbug.com/408276 - "5F57A9AE8DFF5D6BB09DF8606270402612E871E5" // http://crbug.com/422624 - ] + "extension_types": ["platform_app"] }, { "channel": "stable", @@ -878,6 +853,7 @@ "rtcPrivate": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app"], + "platforms": ["chromeos"], "whitelist": [ "53041A2FA309EECED01FFC751E7399186E860B2C", // Google Talk prod "A74A4D44C7CFCD8844830E6140C8D763E12DD8F3", // Google Talk beta @@ -979,6 +955,7 @@ "usersPrivate": { "channel": "trunk", "extension_types": ["extension", "platform_app"], + "platforms": ["chromeos"], "location": "component" }, "wallpaper": { diff --git a/chrome/common/extensions/api/webview_tag.json b/chrome/common/extensions/api/webview_tag.json index 0263954cd0eb1..6efde3fb3c169 100644 --- a/chrome/common/extensions/api/webview_tag.json +++ b/chrome/common/extensions/api/webview_tag.json @@ -856,6 +856,13 @@ "description": "Returns Chrome's internal process ID for the guest web page's current process, allowing embedders to know how many guests would be affected by terminating the process. Two guests will share a process only if they belong to the same app and have the same storage partition ID. The call is synchronous and returns the embedder's cached notion of the current process ID. The process ID isn't the same as the operating system's process ID.", "parameters": [] }, + { + "name": "getGuestId", + "type": "function", + "returns": { "type": "integer" }, + "description": "", + "parameters": [] + }, { "name": "getUserAgent", "type": "function", @@ -1071,6 +1078,24 @@ } ] }, + { + "name": "showDevTools", + "type": "function", + "description": "Open or close devtools for this webview.", + "parameters": [ + { + "type": "boolean", + "name": "show", + "description" : "show or close." + }, + { + "type": "object", + "name": "container", + "description" : "where to show the devtools, should be a webview", + "optional": true + } + ] + }, { "name": "terminate", "type": "function", diff --git a/chrome/common/extensions/chrome_extensions_client.cc b/chrome/common/extensions/chrome_extensions_client.cc index 14f7f88de594c..a998910db36ed 100644 --- a/chrome/common/extensions/chrome_extensions_client.cc +++ b/chrome/common/extensions/chrome_extensions_client.cc @@ -52,6 +52,8 @@ #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" +#include "content/nw/src/api/generated_schemas.h" + namespace extensions { namespace { @@ -175,6 +177,7 @@ ChromeExtensionsClient::CreateFeatureProviderSource( if (name == "api") { source->LoadJSON(IDR_EXTENSION_API_FEATURES); source->LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES); + source->LoadJSON(IDR_NW_EXTENSION_API_FEATURES); } else if (name == "manifest") { source->LoadJSON(IDR_EXTENSION_MANIFEST_FEATURES); source->LoadJSON(IDR_CHROME_EXTENSION_MANIFEST_FEATURES); @@ -265,6 +268,7 @@ bool ChromeExtensionsClient::IsAPISchemaGenerated( const std::string& name) const { // Test from most common to least common. return api::ChromeGeneratedSchemas::IsGenerated(name) || + nwapi::nwjsGeneratedSchemas::IsGenerated(name) || api::GeneratedSchemas::IsGenerated(name); } @@ -273,6 +277,8 @@ base::StringPiece ChromeExtensionsClient::GetAPISchema( // Test from most common to least common. if (api::ChromeGeneratedSchemas::IsGenerated(name)) return api::ChromeGeneratedSchemas::Get(name); + if (nwapi::nwjsGeneratedSchemas::IsGenerated(name)) + return nwapi::nwjsGeneratedSchemas::Get(name); return api::GeneratedSchemas::Get(name); } diff --git a/chrome/common/extensions/extension_process_policy.cc b/chrome/common/extensions/extension_process_policy.cc index 3208e21d80049..f9fa60a9d9247 100644 --- a/chrome/common/extensions/extension_process_policy.cc +++ b/chrome/common/extensions/extension_process_policy.cc @@ -38,6 +38,9 @@ bool CrossesExtensionProcessBoundary( extensions, new_url); + if (old_url_extension && old_url_extension->is_nwjs_app()) + return false; + // TODO(creis): Temporary workaround for crbug.com/59285: Do not swap process // to navigate from a hosted app to a normal page or another hosted app // (unless either is the web store). This is because some OAuth providers diff --git a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc index d3b89632192d9..91a05fbde5a26 100644 --- a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc +++ b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc @@ -126,6 +126,18 @@ bool LoadUserScriptFromDictionary(const base::DictionaryValue* content_script, result->set_match_about_blank(match_about_blank); } + // in main world + if (content_script->HasKey(keys::kInMainWorld)) { + bool in_main_world = false; + if (!content_script->GetBoolean(keys::kInMainWorld, + &in_main_world)) { + *error = ErrorUtils::FormatErrorMessageUTF16( + errors::kInvalidInMainWorld, base::IntToString(definition_index)); + return false; + } + result->set_in_main_world(in_main_world); + } + // matches (required) const base::ListValue* matches = NULL; if (!content_script->GetList(keys::kMatches, &matches)) { diff --git a/chrome/common/extensions/sync_helper.cc b/chrome/common/extensions/sync_helper.cc index 1a73e4b24d48f..dd5638454b5ed 100644 --- a/chrome/common/extensions/sync_helper.cc +++ b/chrome/common/extensions/sync_helper.cc @@ -59,6 +59,7 @@ bool IsSyncable(const Extension* extension) { case Manifest::TYPE_HOSTED_APP: case Manifest::TYPE_LEGACY_PACKAGED_APP: case Manifest::TYPE_PLATFORM_APP: + case Manifest::TYPE_NWJS_APP: case Manifest::TYPE_THEME: return true; diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc index 1194522f6c0bb..5353ddc4c7b94 100644 --- a/chrome/common/logging_chrome.cc +++ b/chrome/common/logging_chrome.cc @@ -20,6 +20,7 @@ #define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \ content::RegisterIPCLogger(msg_id, logger) #include "chrome/common/all_messages.h" +#include "extensions/common/extension_messages.h" #endif #if defined(OS_WIN) diff --git a/chrome/common/mac/app_mode_chrome_locator.mm b/chrome/common/mac/app_mode_chrome_locator.mm index efd272e706ba5..c1b3b09b58128 100644 --- a/chrome/common/mac/app_mode_chrome_locator.mm +++ b/chrome/common/mac/app_mode_chrome_locator.mm @@ -79,6 +79,7 @@ bool GetChromeBundleInfo(const base::FilePath& chrome_bundle, // However, we want the shims to be agnostic to distribution and operate based // on the data in their plist, so encode the framework names here. NSDictionary* framework_for_exe = @{ + @"nwjs": @"nwjs", @"Chromium": @"Chromium", @"Google Chrome": @"Google Chrome", @"Google Chrome Canary": @"Google Chrome", diff --git a/chrome/common/pepper_flash.cc b/chrome/common/pepper_flash.cc index cad919947ea4b..e6cd550568784 100644 --- a/chrome/common/pepper_flash.cc +++ b/chrome/common/pepper_flash.cc @@ -38,6 +38,7 @@ const char kPepperFlashOperatingSystem[] = "linux"; #endif +#if 0 // Name of the Pepper Flash architecture in the component manifest. const char kPepperFlashArch[] = #if defined(ARCH_CPU_X86) @@ -47,6 +48,7 @@ const char kPepperFlashArch[] = #else // TODO(viettrungluu): Support an ARM check? "???"; #endif +#endif // Returns true if the Pepper |interface_name| is implemented by this browser. // It does not check if the interface is proxied. @@ -124,6 +126,7 @@ bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, if (os != kPepperFlashOperatingSystem) return false; +#if 0 std::string arch; manifest.GetStringASCII("x-ppapi-arch", &arch); if (arch != kPepperFlashArch) { @@ -136,7 +139,7 @@ bool CheckPepperFlashManifest(const base::DictionaryValue& manifest, return false; #endif } - +#endif *version_out = version; return true; } diff --git a/chrome/installer/linux/common/installer.include b/chrome/installer/linux/common/installer.include index ed85858d9fda6..80dbee113bf21 100644 --- a/chrome/installer/linux/common/installer.include +++ b/chrome/installer/linux/common/installer.include @@ -126,11 +126,11 @@ stage_install_common() { # we should flag all installer files in FILES.cfg and get them from there, so # there's only one place people need to keep track of such things (and in # only the public repository). - if [ -r "${BUILDDIR}/chrome_100_percent.pak" ]; then - install -m 644 "${BUILDDIR}/chrome_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" - install -m 644 "${BUILDDIR}/chrome_200_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" - install -m 644 "${BUILDDIR}/chrome_material_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" - install -m 644 "${BUILDDIR}/chrome_material_200_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" + if [ -r "${BUILDDIR}/nw_100_percent.pak" ]; then + install -m 644 "${BUILDDIR}/nw_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" + install -m 644 "${BUILDDIR}/nw_200_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" + install -m 644 "${BUILDDIR}/nw_material_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" + install -m 644 "${BUILDDIR}/nw_material_200_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" else install -m 644 "${BUILDDIR}/theme_resources_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" install -m 644 "${BUILDDIR}/ui_resources_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/" diff --git a/chrome/installer/mini_installer.gyp b/chrome/installer/mini_installer.gyp index 4bf290481ffa8..5b1cc718df665 100644 --- a/chrome/installer/mini_installer.gyp +++ b/chrome/installer/mini_installer.gyp @@ -19,7 +19,7 @@ '../chrome.gyp:chrome_dll', ], 'chrome_dll_path': [ - '<(PRODUCT_DIR)/chrome.dll', + '<(PRODUCT_DIR)/nw.dll', ], 'output_dir': '<(PRODUCT_DIR)', }, diff --git a/chrome/installer/mini_installer.gypi b/chrome/installer/mini_installer.gypi index b0373add0c6fa..29541b4ec7e71 100644 --- a/chrome/installer/mini_installer.gypi +++ b/chrome/installer/mini_installer.gypi @@ -204,7 +204,7 @@ ], 'inputs': [ '<(create_installer_archive_py_path)', - '<(PRODUCT_DIR)/chrome.exe', + '<(PRODUCT_DIR)/nw.exe', '<@(chrome_dll_path)', '<(PRODUCT_DIR)/nacl64.exe', '<(PRODUCT_DIR)/nacl_irt_x86_32.nexe', diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release index 1816869d3cafc..6579fb46eb2c8 100644 --- a/chrome/installer/mini_installer/chrome.release +++ b/chrome/installer/mini_installer/chrome.release @@ -6,7 +6,7 @@ # # Chrome Application dir entries, sorted alphabetically. # -chrome.exe: %(ChromeDir)s\ +nw.exe: %(ChromeDir)s\ wow_helper.exe: %(ChromeDir)s\ # # Chrome version dir assembly manifest. @@ -14,59 +14,61 @@ wow_helper.exe: %(ChromeDir)s\ # hard-code it. # // TODO(caitkp): Find a way to do this without wildcards. # -*.*.*.*.manifest: %(VersionDir)s\ +*.*.*.*.manifest: %(ChromeDir)s\ # # Chrome version dir entries, sorted alphabetically. # -chrome.dll: %(VersionDir)s\ -chrome_100_percent.pak: %(VersionDir)s\ -chrome_material_100_percent.pak: %(VersionDir)s\ -chrome_child.dll: %(VersionDir)s\ -chrome_elf.dll: %(VersionDir)s\ -chrome_watcher.dll: %(VersionDir)s\ -d3dcompiler_47.dll: %(VersionDir)s\ +nw.dll: %(ChromeDir)s\ +nw_100_percent.pak: %(ChromeDir)s\ +nw_child.dll: %(ChromeDir)s\ +nw_elf.dll: %(ChromeDir)s\ +nw_material_100_percent.pak: %(ChromeDir)s\ +nw_watcher.dll: %(ChromeDir)s\ +d3dcompiler_47.dll: %(ChromeDir)s\ ffmpeg.dll: %(VersionDir)s\ -kasko.dll: %(VersionDir)s\ -icudt.dll: %(VersionDir)s\ -icudtl.dat: %(VersionDir)s\ -libEGL.dll: %(VersionDir)s\ -libGLESv2.dll: %(VersionDir)s\ -nacl64.exe: %(VersionDir)s\ -nacl_irt_x86_32.nexe: %(VersionDir)s\ -nacl_irt_x86_64.nexe: %(VersionDir)s\ -natives_blob.bin: %(VersionDir)s\ -resources.pak: %(VersionDir)s\ -snapshot_blob.bin: %(VersionDir)s\ -syzyasan_rtl.dll: %(VersionDir)s\ +kasko.dll: %(ChromeDir)s\ +icudt.dll: %(ChromeDir)s\ +icudtl.dat: %(ChromeDir)s\ +libEGL.dll: %(ChromeDir)s\ +libGLESv2.dll: %(ChromeDir)s\ +nacl64.exe: %(ChromeDir)s\ +nacl_irt_x86_32.nexe: %(ChromeDir)s\ +nacl_irt_x86_64.nexe: %(ChromeDir)s\ +natives_blob.bin: %(ChromeDir)s\ +resources.pak: %(ChromeDir)s\ +snapshot_blob.bin: %(ChromeDir)s\ +syzyasan_rtl.dll: %(ChromeDir)s\ +node.dll: %(ChromeDir)s\ # # Sub directories living in the version dir # -default_apps\*.crx: %(VersionDir)s\default_apps\ -default_apps\external_extensions.json: %(VersionDir)s\default_apps\ -Extensions\*.*: %(VersionDir)s\Extensions\ -locales\*.dll: %(VersionDir)s\Locales -locales\*.pak: %(VersionDir)s\Locales +default_apps\*.crx: %(ChromeDir)s\default_apps\ +default_apps\external_extensions.json: %(ChromeDir)s\default_apps\ +Extensions\*.*: %(ChromeDir)s\Extensions\ +locales\*.dll: %(ChromeDir)s\Locales +locales\*.pak: %(ChromeDir)s\Locales [HIDPI] -chrome_200_percent.pak: %(VersionDir)s\ -chrome_material_200_percent.pak: %(VersionDir)s\ +nw_200_percent.pak: %(ChromeDir)s\ +nw_material_200_percent.pak: %(ChromeDir)s\ [TOUCH] [GOOGLE_CHROME] -SecondaryTile.png: %(VersionDir)s\ -widevinecdmadapter.dll: %(VersionDir)s\ +SecondaryTile.png: %(ChromeDir)s\ +widevinecdmadapter.dll: %(ChromeDir)s\ # # Pepper Flash sub-dir. # -PepperFlash\manifest.json: %(VersionDir)s\PepperFlash\ -PepperFlash\pepflashplayer.dll: %(VersionDir)s\PepperFlash\ +PepperFlash\manifest.json: %(ChromeDir)s\PepperFlash\ +PepperFlash\pepflashplayer.dll: %(ChromeDir)s\PepperFlash\ # # Win8 sub-dir. # # All or none of the following 3 files need to be present as the creation of # VisualElementsManifest.xml is based on the existence of -# %(VersionDir)\VisualElements. On a similar note, no other files should be +# %(ChromeDir)\VisualElements. On a similar note, no other files should be # packaged in this directory. Logo.png: %(VersionDir)s\VisualElements\ SmallLogo.png: %(VersionDir)s\VisualElements\ + diff --git a/chrome/installer/util/browser_distribution.cc b/chrome/installer/util/browser_distribution.cc index 3e1e6a50e7957..4bf5078c8c37d 100644 --- a/chrome/installer/util/browser_distribution.cc +++ b/chrome/installer/util/browser_distribution.cc @@ -153,7 +153,7 @@ base::string16 BrowserDistribution::GetActiveSetupGuid() { } base::string16 BrowserDistribution::GetBaseAppName() { - return L"Chromium"; + return L"nwjs"; } base::string16 BrowserDistribution::GetDisplayName() { @@ -184,7 +184,7 @@ base::string16 BrowserDistribution::GetStartMenuShortcutSubfolder( } base::string16 BrowserDistribution::GetBaseAppId() { - return L"Chromium"; + return L"nwjs"; } base::string16 BrowserDistribution::GetBrowserProgIdPrefix() { @@ -200,11 +200,11 @@ base::string16 BrowserDistribution::GetBrowserProgIdDesc() { base::string16 BrowserDistribution::GetInstallSubDir() { - return L"Chromium"; + return L"nwjs"; } base::string16 BrowserDistribution::GetPublisherName() { - return L"Chromium"; + return L"nwjs"; } base::string16 BrowserDistribution::GetAppDescription() { @@ -218,7 +218,7 @@ base::string16 BrowserDistribution::GetLongAppDescription() { } std::string BrowserDistribution::GetSafeBrowsingName() { - return "chromium"; + return "nwjs"; } base::string16 BrowserDistribution::GetDistributionData(HKEY root_key) { diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc index 5fdc0c1451d60..9407992b0a33e 100644 --- a/chrome/installer/util/google_update_settings.cc +++ b/chrome/installer/util/google_update_settings.cc @@ -231,7 +231,7 @@ bool GoogleUpdateSettings::IsSystemInstall() { } bool GoogleUpdateSettings::GetCollectStatsConsent() { - return GetCollectStatsConsentAtLevel(IsSystemInstall()); + return false; //GetCollectStatsConsentAtLevel(IsSystemInstall()); } // Older versions of Chrome unconditionally read from HKCU\...\ClientState\... diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index 91f2e8473a5ba..6c98ef41f6121 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -206,9 +206,9 @@ const char kGoogleUpdateIsMachineEnvVar[] = "GoogleUpdateIsMachine"; // Active Setup. const wchar_t kActiveSetupExe[] = L"chrmstp.exe"; const wchar_t kAppLauncherGuid[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}"; -const wchar_t kChromeDll[] = L"chrome.dll"; -const wchar_t kChromeChildDll[] = L"chrome_child.dll"; -const wchar_t kChromeExe[] = L"chrome.exe"; +const wchar_t kChromeDll[] = L"nw.dll"; +const wchar_t kChromeChildDll[] = L"nw_child.dll"; +const wchar_t kChromeExe[] = L"nw.exe"; const wchar_t kChromeFrameDll[] = L"npchrome_frame.dll"; const wchar_t kChromeFrameHelperDll[] = L"chrome_frame_helper.dll"; const wchar_t kChromeFrameHelperExe[] = L"chrome_frame_helper.exe"; diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 979878066e070..d46a47151468b 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -156,6 +156,9 @@ #include "chrome/renderer/media/webrtc_logging_message_filter.h" #endif +#include "content/nw/src/nw_content.h" +#include "content/nw/src/common/shell_switches.h" + using autofill::AutofillAgent; using autofill::PasswordAutofillAgent; using autofill::PasswordGenerationAgent; @@ -326,6 +329,15 @@ ChromeContentRendererClient::ChromeContentRendererClient() ChromeContentRendererClient::~ChromeContentRendererClient() { } +void ChromeContentRendererClient::willHandleNavigationPolicy(content::RenderView* rv, + blink::WebFrame* frame, + const blink::WebURLRequest& request, + blink::WebNavigationPolicy* policy, + blink::WebString* manifest, + bool new_win) { + nw::willHandleNavigationPolicy(rv, frame, request, policy, manifest, new_win); +} + void ChromeContentRendererClient::RenderThreadStarted() { RenderThread* thread = RenderThread::Get(); @@ -341,10 +353,11 @@ void ChromeContentRendererClient::RenderThreadStarted() { prescient_networking_dispatcher_.reset( new network_hints::PrescientNetworkingDispatcher()); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); #if defined(ENABLE_SPELLCHECK) // ChromeRenderViewTest::SetUp() creates a Spellcheck and injects it using // SetSpellcheck(). Don't overwrite it. - if (!spellcheck_) { + if (!spellcheck_ && command_line->HasSwitch(switches::kEnableSpellChecking)) { spellcheck_.reset(new SpellCheck()); thread->AddObserver(spellcheck_.get()); } @@ -374,7 +387,6 @@ void ChromeContentRendererClient::RenderThreadStarted() { thread->RegisterExtension(extensions_v8::ExternalExtension::Get()); thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get()); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kEnableBenchmarking)) thread->RegisterExtension(extensions_v8::BenchmarkingExtension::Get()); if (command_line->HasSwitch(switches::kEnableNetBenchmarking)) @@ -528,12 +540,13 @@ void ChromeContentRendererClient::RenderViewCreated( render_view, std::unique_ptr( new ChromePrintWebViewHelperDelegate())); #endif + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); #if defined(ENABLE_SPELLCHECK) - new SpellCheckProvider(render_view, spellcheck_.get()); + if (command_line->HasSwitch(switches::kEnableSpellChecking)) + new SpellCheckProvider(render_view, spellcheck_.get()); #endif new prerender::PrerendererClient(render_view); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kInstantProcess)) new SearchBox(render_view); @@ -1207,7 +1220,7 @@ bool ChromeContentRendererClient::AllowPepperMediaStreamAPI( // Allow only the Hangouts app to use the MediaStream APIs. It's OK to check // the whitelist in the renderer, since we're only preventing access until // these APIs are public and stable. - return (AppCategorizer::IsHangoutsUrl(url)); + return true; #endif // !defined(OS_ANDROID) } diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index 894fdd0a1dcfd..b3e7c928339bc 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h @@ -75,6 +75,12 @@ class ChromeContentRendererClient : public content::ContentRendererClient { ChromeContentRendererClient(); ~ChromeContentRendererClient() override; + void willHandleNavigationPolicy(content::RenderView* rv, + blink::WebFrame* frame, + const blink::WebURLRequest& request, + blink::WebNavigationPolicy* policy, + blink::WebString* manifest, + bool new_win) override; void RenderThreadStarted() override; void RenderFrameCreated(content::RenderFrame* render_frame) override; void RenderViewCreated(content::RenderView* render_view) override; diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc index f38f8161a3c55..79310868349ed 100644 --- a/chrome/renderer/chrome_render_frame_observer.cc +++ b/chrome/renderer/chrome_render_frame_observer.cc @@ -124,9 +124,11 @@ ChromeRenderFrameObserver::ChromeRenderFrameObserver( *base::CommandLine::ForCurrentProcess(); if (!command_line.HasSwitch(switches::kDisableClientSidePhishingDetection)) OnSetClientSidePhishingDetection(true); +#if 0 translate_helper_ = new translate::TranslateHelper( render_frame, chrome::ISOLATED_WORLD_ID_TRANSLATE, 0, extensions::kExtensionScheme); +#endif } ChromeRenderFrameObserver::~ChromeRenderFrameObserver() { @@ -331,12 +333,14 @@ void ChromeRenderFrameObserver::DidFinishLoad() { } void ChromeRenderFrameObserver::DidStartProvisionalLoad() { +#if 0 // Let translate_helper do any preparatory work for loading a URL. if (!translate_helper_) return; translate_helper_->PrepareForUrl( render_frame()->GetWebFrame()->document().url()); +#endif } void ChromeRenderFrameObserver::DidCommitProvisionalLoad( @@ -388,10 +392,12 @@ void ChromeRenderFrameObserver::CapturePageText(TextCaptureType capture_type) { UMA_HISTOGRAM_TIMES(kTranslateCaptureText, base::TimeTicks::Now() - capture_begin_time); +#if 0 // We should run language detection only once. Parsing finishes before // the page loads, so let's pick that timing. if (translate_helper_ && capture_type == PRELIMINARY_CAPTURE) translate_helper_->PageCaptured(contents); +#endif TRACE_EVENT0("renderer", "ChromeRenderFrameObserver::CapturePageText"); diff --git a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc index 49d98dcce3f16..ca2da5ed129d9 100644 --- a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc +++ b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc @@ -7,6 +7,8 @@ #include #include +#include "content/nw/src/nw_content.h" + #include "base/command_line.h" #include "base/lazy_instance.h" #include "chrome/common/chrome_isolated_world_ids.h" @@ -142,6 +144,7 @@ void ChromeExtensionsRendererClient::RenderThreadStarted() { if (!extension_dispatcher_) { extension_dispatcher_.reset( new extensions::Dispatcher(extension_dispatcher_delegate_.get())); + nw::ExtensionDispatcherCreated(extension_dispatcher_.get()); } permissions_policy_delegate_.reset( new extensions::RendererPermissionsPolicyDelegate( diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index ca4786748decd..9685706cd5937 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc @@ -193,6 +193,20 @@ Status ParseSwitches(const base::Value& option, return Status(kOk); } +Status ParseArguments(const base::Value& option, + Capabilities* capabilities) { + const base::ListValue* arg_list = NULL; + if (!option.GetAsList(&arg_list)) + return Status(kUnknownError, "must be a list"); + for (size_t i = 0; i < arg_list->GetSize(); ++i) { + std::string arg_string; + if (!arg_list->GetString(i, &arg_string)) + return Status(kUnknownError, "each argument must be a string"); + capabilities->arguments.push_back(arg_string); + } + return Status(kOk); +} + Status ParseExtensions(const base::Value& option, Capabilities* capabilities) { const base::ListValue* extensions = NULL; if (!option.GetAsList(&extensions)) @@ -434,6 +448,7 @@ Status ParseChromeOptions( parser_map["debuggerAddress"] = base::Bind(&ParseUseRemoteBrowser); } else { parser_map["args"] = base::Bind(&ParseSwitches); + parser_map["nwargs"] = base::Bind(&ParseArguments); parser_map["binary"] = base::Bind(&ParseFilePath, &capabilities->binary); parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach); parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches); diff --git a/chrome/test/chromedriver/capabilities.h b/chrome/test/chromedriver/capabilities.h index 7aa350c6ae2bd..e9812c7a2bf0d 100644 --- a/chrome/test/chromedriver/capabilities.h +++ b/chrome/test/chromedriver/capabilities.h @@ -129,6 +129,8 @@ struct Capabilities { std::vector extensions; + std::vector arguments; + // True if should always use DevTools for taking screenshots. // This is experimental and may be removed at a later point. bool force_devtools_screenshot; diff --git a/chrome/test/chromedriver/chrome/chrome_finder.cc b/chrome/test/chromedriver/chrome/chrome_finder.cc index ecdbbb47ce5f9..ee094aa25fc6e 100644 --- a/chrome/test/chromedriver/chrome/chrome_finder.cc +++ b/chrome/test/chromedriver/chrome/chrome_finder.cc @@ -25,7 +25,7 @@ namespace { -#if defined(OS_WIN) +#if 0 void GetApplicationDirs(std::vector* locations) { std::vector installation_locations; base::FilePath local_app_data, program_files, program_files_x86; @@ -45,7 +45,7 @@ void GetApplicationDirs(std::vector* locations) { installation_locations[i].Append(L"Chromium\\Application")); } } -#elif defined(OS_LINUX) +#elif 0 void GetApplicationDirs(std::vector* locations) { locations->push_back(base::FilePath("/opt/google/chrome")); locations->push_back(base::FilePath("/usr/local/bin")); @@ -84,22 +84,18 @@ bool FindExe( } // namespace internal -#if defined(OS_MACOSX) +#if 0 void GetApplicationDirs(std::vector* locations); #endif bool FindChrome(base::FilePath* browser_exe) { base::FilePath browser_exes_array[] = { #if defined(OS_WIN) - base::FilePath(L"chrome.exe") + base::FilePath(L"nw.exe") #elif defined(OS_MACOSX) - base::FilePath("Google Chrome.app/Contents/MacOS/Google Chrome"), - base::FilePath("Chromium.app/Contents/MacOS/Chromium") + base::FilePath("nwjs.app/Contents/MacOS/nwjs") #elif defined(OS_LINUX) - base::FilePath("google-chrome"), - base::FilePath("chrome"), - base::FilePath("chromium"), - base::FilePath("chromium-browser") + base::FilePath("nw"), #else // it will compile but won't work on other OSes base::FilePath() @@ -120,7 +116,10 @@ bool FindChrome(base::FilePath* browser_exe) { } std::vector locations; - GetApplicationDirs(&locations); + base::FilePath exe_path; + PathService::Get(base::DIR_EXE, &exe_path); + locations.push_back(exe_path); + return internal::FindExe( base::Bind(&base::PathExists), browser_exes, diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.cc b/chrome/test/chromedriver/chrome/devtools_http_client.cc index eb83d76800839..2895ed5233413 100644 --- a/chrome/test/chromedriver/chrome/devtools_http_client.cc +++ b/chrome/test/chromedriver/chrome/devtools_http_client.cc @@ -156,6 +156,8 @@ bool DevToolsHttpClient::IsBrowserWindow(const WebViewInfo& view) const { return window_types_->find(view.type) != window_types_->end() || (view.type == WebViewInfo::kOther && (view.url.find("chrome-extension://") == 0 || + view.url.find("http://") == 0 || + view.url.find("https://") == 0 || view.url == "chrome://print/" || view.url == "chrome://media-router/")); } diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 063b450231afe..6dc439690e330 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc @@ -265,9 +265,15 @@ Status WebViewImpl::CallFunction(const std::string& frame, const base::ListValue& args, std::unique_ptr* result) { std::string json; + bool skip_result = false; base::JSONWriter::Write(args, &json); // TODO(zachconrad): Second null should be array of shadow host ids. - std::string expression = base::StringPrintf( + std::string expression; + if (base::StartsWith(function.c_str(), "rawscript:", base::CompareCase::SENSITIVE)) { + expression = function.substr(10); + skip_result = true; + } else + expression = base::StringPrintf( "(%s).apply(null, [null, %s, %s])", kCallFunctionScript, function.c_str(), @@ -277,6 +283,8 @@ Status WebViewImpl::CallFunction(const std::string& frame, if (status.IsError()) return status; + if (skip_result) + return Status(kOk); return internal::ParseCallFunctionResult(*temp_result, result); } diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc index 50a4cd34bec1b..a6447e0d46e2a 100644 --- a/chrome/test/chromedriver/chrome_launcher.cc +++ b/chrome/test/chromedriver/chrome_launcher.cc @@ -59,6 +59,8 @@ #include "chrome/test/chromedriver/keycode_text_conversion.h" #endif +#include "base/strings/string_number_conversions.h" + namespace { const char* const kCommonSwitches[] = { @@ -67,6 +69,7 @@ const char* const kCommonSwitches[] = { "metrics-recording-only" }; +#if 0 const char* const kDesktopSwitches[] = { "disable-hang-monitor", "disable-prompt-on-repost", @@ -85,6 +88,7 @@ const char* const kDesktopSwitches[] = { "use-mock-keychain", "test-type=webdriver" }; +#endif const char* const kAndroidSwitches[] = { "disable-fre", @@ -136,8 +140,10 @@ Status PrepareCommandLine(uint16_t port, for (const auto& common_switch : kCommonSwitches) switches.SetUnparsedSwitch(common_switch); +#if 0 //FIXME if enabled, chromedriver cannot find chrome on windows for (const auto& desktop_switch : kDesktopSwitches) switches.SetUnparsedSwitch(desktop_switch); +#endif switches.SetSwitch("remote-debugging-port", base::UintToString(port)); for (const auto& excluded_switch : capabilities.exclude_switches) { switches.RemoveSwitch(excluded_switch); @@ -149,7 +155,7 @@ Status PrepareCommandLine(uint16_t port, user_data_dir_path = base::FilePath( switches.GetSwitchValueNative("user-data-dir")); } else { - command.AppendArg("data:,"); + //command.AppendArg("data:,"); if (!user_data_dir->CreateUniqueTempDir()) return Status(kUnknownError, "cannot create temp dir for user data dir"); switches.SetSwitch("user-data-dir", user_data_dir->path().value()); @@ -174,6 +180,10 @@ Status PrepareCommandLine(uint16_t port, if (status.IsError()) return status; switches.AppendToCommandLine(&command); + + for (size_t i = 0; i < capabilities.arguments.size(); i++) + command.AppendArg(capabilities.arguments[i]); + *prepared_command = command; return Status(kOk); } @@ -196,16 +206,21 @@ Status WaitForDevToolsAndCheckVersion( window_types.reset(new std::set()); } + base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); + int timeout = 60; + if (cmd_line->HasSwitch("launch-timeout")) { + std::string s_timeout = cmd_line->GetSwitchValueASCII("launch-timeout"); + base::StringToInt(s_timeout, &timeout); + } std::unique_ptr client(new DevToolsHttpClient( address, context_getter, socket_factory, std::move(device_metrics), std::move(window_types))); base::TimeTicks deadline = - base::TimeTicks::Now() + base::TimeDelta::FromSeconds(60); + base::TimeTicks::Now() + base::TimeDelta::FromSeconds(timeout); Status status = client->Init(deadline - base::TimeTicks::Now()); if (status.IsError()) return status; - base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); if (cmd_line->HasSwitch("disable-build-check")) { LOG(WARNING) << "You are using an unsupported command-line switch: " "--disable-build-check. Please don't report bugs that " @@ -220,7 +235,8 @@ Status WaitForDevToolsAndCheckVersion( WebViewsInfo views_info; client->GetWebViewsInfo(&views_info); for (size_t i = 0; i < views_info.GetSize(); ++i) { - if (views_info.Get(i).type == WebViewInfo::kPage) { + if (views_info.Get(i).type == WebViewInfo::kApp || + views_info.Get(i).type == WebViewInfo::kOther) { //node-remote page *user_client = std::move(client); return Status(kOk); } diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index 0ea9014511de3..5c68995d79195 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc @@ -9,6 +9,8 @@ #include #include +#include "base/strings/string_util.h" + #include "base/callback.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -304,7 +306,9 @@ Status ExecuteExecuteScript(Session* session, const base::ListValue* args; if (!params.GetList("args", &args)) return Status(kUnknownError, "'args' must be a list"); - + if (base::StartsWith(script.c_str(), "rawscript:", base::CompareCase::SENSITIVE)) + return web_view->CallFunction(session->GetCurrentFrameId(), + script, *args, value); return web_view->CallFunction(session->GetCurrentFrameId(), "function(){" + script + "}", *args, value); } diff --git a/chrome/test/data/extensions/platform_apps/web_view/common/cleardata_twice/bootstrap.js b/chrome/test/data/extensions/platform_apps/web_view/common/cleardata_twice/bootstrap.js new file mode 100644 index 0000000000000..289c052a3438c --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/common/cleardata_twice/bootstrap.js @@ -0,0 +1,43 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +config.IS_CHROME_TEST = true; +// Guest served from TestServer. +config.IS_JS_ONLY_GUEST = false; +config.TEST_DIR = 'cleardata_twice'; + +var clearDataTwiceTests = {}; + +var run = function() { + var container = document.createElement('div'); + container.id = 'webview-tag-container'; + document.body.appendChild(container); + + chrome.test.getConfig(function(chromeConfig) { + window.console.log('getConfig: ' + chromeConfig); + utils.setUp(chromeConfig, config); + embedder.loadGuest(function() { + chrome.test.runTests([ + clearDataTwiceTests.clear + ]); + }, function(data) { + // We don't expect guest to send us any postMessage. + chrome.test.fail(); + }); + }); +}; + +// Tests. +// Clears http cache of a webview twice. +clearDataTwiceTests.clear = function testClearDataTwice() { + console.log('clearDataTwiceTests.clear'); + embedder.webview.clearData({}, {cache: true}, function() { + embedder.webview.clearData({}, {cache: true}, function() { + chrome.test.succeed(); + }); + }); +}; + +// Run test(s). +run(); diff --git a/chrome/test/data/extensions/platform_apps/web_view/common/cleardata_twice/guest.html b/chrome/test/data/extensions/platform_apps/web_view/common/cleardata_twice/guest.html new file mode 100644 index 0000000000000..30d2c3278622f --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/common/cleardata_twice/guest.html @@ -0,0 +1,41 @@ + + + + + + + +
Simple guest page.
+ + diff --git a/chrome/tools/build/linux/FILES.cfg b/chrome/tools/build/linux/FILES.cfg index 2b3b3b97ca9fb..90f10002c329a 100644 --- a/chrome/tools/build/linux/FILES.cfg +++ b/chrome/tools/build/linux/FILES.cfg @@ -36,11 +36,11 @@ FILES = [ 'buildtype': ['dev', 'official'], }, { - 'filename': 'chrome_100_percent.pak', + 'filename': 'nw_100_percent.pak', 'buildtype': ['dev', 'official'], }, { - 'filename': 'chrome_200_percent.pak', + 'filename': 'nw_200_percent.pak', 'buildtype': ['dev', 'official'], }, { diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg index 0bbf49f260173..7d42fcc836a79 100644 --- a/chrome/tools/build/win/FILES.cfg +++ b/chrome/tools/build/win/FILES.cfg @@ -80,11 +80,11 @@ FILES = [ 'filegroup': ['default', 'symsrc'], }, { - 'filename': 'chrome_100_percent.pak', + 'filename': 'nw_100_percent.pak', 'buildtype': ['dev', 'official'], }, { - 'filename': 'chrome_200_percent.pak', + 'filename': 'nw_200_percent.pak', 'buildtype': ['dev', 'official'], 'optional': ['dev', 'official'], }, diff --git a/chrome_elf/chrome_elf.def b/chrome_elf/chrome_elf.def index cbf354387f6e2..3f573e695a395 100644 --- a/chrome_elf/chrome_elf.def +++ b/chrome_elf/chrome_elf.def @@ -2,7 +2,7 @@ ; Use of this source code is governed by a BSD-style license that can be ; found in the LICENSE file. -LIBRARY "chrome_elf.dll" +LIBRARY "nw_elf.dll" EXPORTS IsBlacklistInitialized diff --git a/chrome_elf/chrome_elf.gyp b/chrome_elf/chrome_elf.gyp index 034476a6568d8..0b0c6a2f73a0e 100644 --- a/chrome_elf/chrome_elf.gyp +++ b/chrome_elf/chrome_elf.gyp @@ -29,6 +29,7 @@ }, { 'target_name': 'chrome_elf', + 'product_name': 'nw_elf', 'type': 'shared_library', 'include_dirs': [ '..', diff --git a/chrome_elf/chrome_elf.ver b/chrome_elf/chrome_elf.ver index 78f890e7ece7d..92d53efaa487f 100644 --- a/chrome_elf/chrome_elf.ver +++ b/chrome_elf/chrome_elf.ver @@ -1,2 +1,2 @@ -INTERNAL_NAME=chrome_elf_dll -ORIGINAL_FILENAME=chrome_elf.dll +INTERNAL_NAME=nw_elf_dll +ORIGINAL_FILENAME=nw_elf.dll diff --git a/chrome_elf/chrome_elf_constants.cc b/chrome_elf/chrome_elf_constants.cc index 76560228cd6be..1f417e0ec5d43 100644 --- a/chrome_elf/chrome_elf_constants.cc +++ b/chrome_elf/chrome_elf_constants.cc @@ -10,7 +10,7 @@ // depend on BrowserDistribution. http://crbug.com/577820 #define PRODUCT_STRING_PATH L"Google\\Chrome" #elif defined(CHROMIUM_BUILD) -#define PRODUCT_STRING_PATH L"Chromium" +#define PRODUCT_STRING_PATH L"nwjs" #else #error Unknown branding #endif diff --git a/components/about_ui/resources/about_credits.tmpl b/components/about_ui/resources/about_credits.tmpl index e9f119d67775f..3c4d32aa21670 100644 --- a/components/about_ui/resources/about_credits.tmpl +++ b/components/about_ui/resources/about_credits.tmpl @@ -44,7 +44,6 @@ body { background-color: #e8eef7; border-radius: 3px; clear: both; - display: none; padding: 16px; } .licence h3 { diff --git a/components/about_ui/resources/about_credits_entry.tmpl b/components/about_ui/resources/about_credits_entry.tmpl index d1810cd940294..99b354cf89fee 100644 --- a/components/about_ui/resources/about_credits_entry.tmpl +++ b/components/about_ui/resources/about_credits_entry.tmpl @@ -1,6 +1,5 @@
{{name}} -show license homepage
{{license}}
diff --git a/components/app_modal/javascript_dialog_manager.cc b/components/app_modal/javascript_dialog_manager.cc index b6ee3395c99e4..8edefe397f2ba 100644 --- a/components/app_modal/javascript_dialog_manager.cc +++ b/components/app_modal/javascript_dialog_manager.cc @@ -31,7 +31,7 @@ namespace { #if !defined(OS_ANDROID) // Keep in sync with kDefaultMessageWidth, but allow some space for the rest of // the text. -const int kUrlElideWidth = 350; +//const int kUrlElideWidth = 350; #endif class DefaultExtensionsClient : public JavaScriptDialogExtensionsClient { @@ -163,7 +163,7 @@ void JavaScriptDialogManager::RunJavaScriptDialog( message_type, message_text, default_prompt_text, - ShouldDisplaySuppressCheckbox(extra_data), + false, //ShouldDisplaySuppressCheckbox(extra_data), false, // is_before_unload_dialog false, // is_reload base::Bind(&JavaScriptDialogManager::OnDialogClosed, @@ -251,6 +251,8 @@ base::string16 JavaScriptDialogManager::GetTitle( content::WebContents* web_contents, const GURL& origin_url, bool is_alert) { + return base::string16(); +#if 0 // For extensions, show the extension name, but only if the origin of // the alert matches the top-level WebContents. std::string name; @@ -279,6 +281,7 @@ base::string16 JavaScriptDialogManager::GetTitle( is_same_origin_as_main_frame ? IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL : IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL_IFRAME); +#endif } void JavaScriptDialogManager::CancelActiveAndPendingDialogs( diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc index c22c2d5c48053..ce97263811fa2 100644 --- a/components/autofill/core/browser/autofill_download_manager.cc +++ b/components/autofill/core/browser/autofill_download_manager.cc @@ -64,7 +64,7 @@ const net::BackoffEntry::Policy kAutofillBackoffPolicy = { #if defined(GOOGLE_CHROME_BUILD) const char kClientName[] = "Google Chrome"; #else -const char kClientName[] = "Chromium"; +const char kClientName[] = "nwjs"; #endif // defined(GOOGLE_CHROME_BUILD) size_t CountActiveFieldsInForms(const std::vector& forms) { diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc index acefb02f31da3..205dfb90382d3 100644 --- a/components/content_settings/core/browser/content_settings_registry.cc +++ b/components/content_settings/core/browser/content_settings_registry.cc @@ -169,7 +169,7 @@ void ContentSettingsRegistry::Init() { ContentSettingsInfo::INHERIT_IN_INCOGNITO); Register(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications", - CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE, + CONTENT_SETTING_ALLOW, WebsiteSettingsInfo::UNSYNCABLE, WhitelistedSchemes(), ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, CONTENT_SETTING_ASK), diff --git a/components/crash/content/app/breakpad_linux.cc b/components/crash/content/app/breakpad_linux.cc index 47c6b67b76d45..87353c304ed46 100644 --- a/components/crash/content/app/breakpad_linux.cc +++ b/components/crash/content/app/breakpad_linux.cc @@ -654,7 +654,7 @@ bool CrashDone(const MinidumpDescriptor& minidump, info.process_type_length = 7; info.distro = base::g_linux_distro; info.distro_length = my_strlen(base::g_linux_distro); - info.upload = upload; + info.upload = false; info.process_start_time = g_process_start_time; info.oom_size = base::g_oom_size; info.pid = g_pid; @@ -728,7 +728,7 @@ void EnableCrashDumping(bool unattended) { } else { minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); } -#if defined(OS_ANDROID) +#if 1 unattended = true; // Android never uploads directly. #endif if (unattended) { diff --git a/components/crx_file/id_util.cc b/components/crx_file/id_util.cc index 99a245606837e..afa087fef765c 100644 --- a/components/crx_file/id_util.cc +++ b/components/crx_file/id_util.cc @@ -80,6 +80,7 @@ base::FilePath MaybeNormalizePath(const base::FilePath& path) { } bool IdIsValid(const std::string& id) { +#if 0 // Verify that the id is legal. if (id.size() != (crx_file::id_util::kIdSize * 2)) return false; @@ -90,7 +91,7 @@ bool IdIsValid(const std::string& id) { for (size_t i = 0; i < temp.size(); i++) if (temp[i] < 'a' || temp[i] > 'p') return false; - +#endif return true; } diff --git a/components/devtools_http_handler/devtools_http_handler.cc b/components/devtools_http_handler/devtools_http_handler.cc index a5b173afcc4f4..c1c0835c8cd2d 100644 --- a/components/devtools_http_handler/devtools_http_handler.cc +++ b/components/devtools_http_handler/devtools_http_handler.cc @@ -783,6 +783,7 @@ DevToolsHttpHandler::DevToolsHttpHandler( delegate_(delegate), socket_factory_(nullptr), weak_factory_(this) { +#if defined(NWJS_SDK) bool bundles_resources = frontend_url_.empty(); if (frontend_url_.empty()) frontend_url_ = "/devtools/inspector.html"; @@ -795,6 +796,7 @@ DevToolsHttpHandler::DevToolsHttpHandler( output_directory, debug_frontend_dir, bundles_resources)); +#endif } void DevToolsHttpHandler::ServerStarted( diff --git a/components/gcm_driver/gcm_channel_status_syncer.cc b/components/gcm_driver/gcm_channel_status_syncer.cc index cbe1ba2fd4dcb..0ff9e239a4aba 100644 --- a/components/gcm_driver/gcm_channel_status_syncer.cc +++ b/components/gcm_driver/gcm_channel_status_syncer.cc @@ -20,6 +20,8 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "content/nw/src/nw_base.h" + namespace gcm { namespace { @@ -61,7 +63,7 @@ const char kCustomPollIntervalMinutes[] = "gcm-channel-poll-interval"; // static void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kGCMChannelStatus, true); + registry->RegisterBooleanPref(prefs::kGCMChannelStatus, nw::gcm_enabled()); registry->RegisterIntegerPref( prefs::kGCMChannelPollIntervalSeconds, GCMChannelStatusRequest::default_poll_interval_seconds()); @@ -71,7 +73,7 @@ void GCMChannelStatusSyncer::RegisterPrefs(PrefRegistrySimple* registry) { // static void GCMChannelStatusSyncer::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterBooleanPref(prefs::kGCMChannelStatus, true); + registry->RegisterBooleanPref(prefs::kGCMChannelStatus, nw::gcm_enabled()); registry->RegisterIntegerPref( prefs::kGCMChannelPollIntervalSeconds, GCMChannelStatusRequest::default_poll_interval_seconds()); @@ -95,7 +97,7 @@ GCMChannelStatusSyncer::GCMChannelStatusSyncer( user_agent_(user_agent), request_context_(request_context), started_(false), - gcm_enabled_(true), + gcm_enabled_(nw::gcm_enabled()), poll_interval_seconds_( GCMChannelStatusRequest::default_poll_interval_seconds()), custom_poll_interval_use_count_(0), diff --git a/components/gcm_driver/gcm_driver_desktop.cc b/components/gcm_driver/gcm_driver_desktop.cc index d8f7fafba846e..5b18230325514 100644 --- a/components/gcm_driver/gcm_driver_desktop.cc +++ b/components/gcm_driver/gcm_driver_desktop.cc @@ -33,6 +33,8 @@ #include "components/timers/alarm_timer_chromeos.h" #endif +#include "content/nw/src/nw_base.h" + namespace gcm { class GCMDriverDesktop::IOWorker : public GCMClient::Delegate { @@ -1178,7 +1180,8 @@ GCMClient::Result GCMDriverDesktop::EnsureStarted( // Polling for channel status should be invoked when GCM is being requested, // no matter whether GCM is enabled or nor. - gcm_channel_status_syncer_->EnsureStarted(); + if (nw::gcm_enabled()) + gcm_channel_status_syncer_->EnsureStarted(); if (!gcm_enabled_) return GCMClient::GCM_DISABLED; diff --git a/components/metrics_services_manager/metrics_services_manager.cc b/components/metrics_services_manager/metrics_services_manager.cc index e91264c4c2b11..0fa5f618a0d01 100644 --- a/components/metrics_services_manager/metrics_services_manager.cc +++ b/components/metrics_services_manager/metrics_services_manager.cc @@ -30,11 +30,13 @@ metrics::MetricsService* MetricsServicesManager::GetMetricsService() { } rappor::RapporService* MetricsServicesManager::GetRapporService() { +#if 0 DCHECK(thread_checker_.CalledOnValidThread()); if (!rappor_service_) { rappor_service_ = client_->CreateRapporService(); rappor_service_->Initialize(client_->GetURLRequestContext()); } +#endif return rappor_service_.get(); } @@ -80,8 +82,8 @@ void MetricsServicesManager::UpdateRunningServices() { if (client_->OnlyDoMetricsRecording()) { metrics->StartRecordingForTests(); - GetRapporService()->Update( - rappor::UMA_RAPPOR_GROUP | rappor::SAFEBROWSING_RAPPOR_GROUP, false); + // GetRapporService()->Update( + // rappor::UMA_RAPPOR_GROUP | rappor::SAFEBROWSING_RAPPOR_GROUP, false); return; } @@ -97,8 +99,8 @@ void MetricsServicesManager::UpdateRunningServices() { metrics->Stop(); } - int recording_groups = 0; #if defined(GOOGLE_CHROME_BUILD) + int recording_groups = 0; if (may_record_) recording_groups |= rappor::UMA_RAPPOR_GROUP; @@ -112,7 +114,7 @@ void MetricsServicesManager::UpdateRunningServices() { if (client_->IsSafeBrowsingEnabled(on_safe_browsing_update_callback)) recording_groups |= rappor::SAFEBROWSING_RAPPOR_GROUP; #endif // defined(GOOGLE_CHROME_BUILD) - GetRapporService()->Update(recording_groups, may_upload_); + // GetRapporService()->Update(recording_groups, may_upload_); } void MetricsServicesManager::UpdateUploadPermissions(bool may_upload) { diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc index 1952cedf89426..afde01036dfae 100644 --- a/components/nacl/loader/nacl_helper_linux.cc +++ b/components/nacl/loader/nacl_helper_linux.cc @@ -283,7 +283,7 @@ bool HonorRequestAndReply(int reply_fd, } if (!have_to_reply) return false; - const std::vector empty; // We never send file descriptors back. + const std::vector empty = std::vector(); // We never send file descriptors back. if (!base::UnixDomainSocket::SendMsg(reply_fd, write_pickle.data(), write_pickle.size(), empty)) { LOG(ERROR) << "*** send() to zygote failed"; @@ -303,11 +303,13 @@ bool HandleZygoteRequest(int zygote_ipc_fd, &buf, sizeof(buf), &fds); // If the Zygote has started handling requests, we should be sandboxed via // the setuid sandbox. +#if 0 if (!nacl_sandbox->layer_one_enabled()) { LOG(ERROR) << "NaCl helper process running without a sandbox!\n" << "Most likely you need to configure your SUID sandbox " << "correctly"; } +#endif if (msglen == 0 || (msglen == -1 && errno == ECONNRESET)) { // EOF from the browser. Goodbye! _exit(0); @@ -452,7 +454,7 @@ int main(int argc, char* argv[]) { nacl_sandbox->InitializeLayerOneSandbox(); CHECK_EQ(is_init_process, nacl_sandbox->layer_one_enabled()); - const std::vector empty; + const std::vector empty = std::vector(); // Send the zygote a message to let it know we are ready to help if (!base::UnixDomainSocket::SendMsg(kNaClZygoteDescriptor, kNaClHelperStartupAck, diff --git a/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc b/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc index e3878c1cd03b1..f080c4e8a4490 100644 --- a/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc +++ b/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc @@ -179,7 +179,7 @@ void NaClSandbox::InitializeLayerTwoSandbox(bool uses_nonsfi_mode) { // have a single thread running here. DCHECK(!layer_one_sealed_); CHECK(IsSingleThreaded()); - CheckForExpectedNumberOfOpenFds(); + //CheckForExpectedNumberOfOpenFds(); RestrictAddressSpaceUsage(); diff --git a/components/nacl/zygote/nacl_fork_delegate_linux.cc b/components/nacl/zygote/nacl_fork_delegate_linux.cc index b1b39eccd32c2..871f2d91006c0 100644 --- a/components/nacl/zygote/nacl_fork_delegate_linux.cc +++ b/components/nacl/zygote/nacl_fork_delegate_linux.cc @@ -409,7 +409,7 @@ bool NaClForkDelegate::GetTerminationStatus(pid_t pid, bool known_dead, write_pickle.WriteInt(pid); write_pickle.WriteBool(known_dead); - const std::vector empty_fds; + const std::vector empty_fds = std::vector(); char reply_buf[kNaClMaxIPCMessageLength]; ssize_t reply_size = 0; bool got_reply = diff --git a/components/os_crypt/keychain_password_mac.mm b/components/os_crypt/keychain_password_mac.mm index 2ce10cde4437d..27e8886846482 100644 --- a/components/os_crypt/keychain_password_mac.mm +++ b/components/os_crypt/keychain_password_mac.mm @@ -55,8 +55,8 @@ const std::string service_name = "Chrome Safe Storage"; const std::string account_name = "Chrome"; #else - const std::string service_name = "Chromium Safe Storage"; - const std::string account_name = "Chromium"; + const std::string service_name = "NWJS Safe Storage"; + const std::string account_name = "nwjs"; #endif UInt32 password_length = 0; diff --git a/components/os_crypt/os_crypt_mac.mm b/components/os_crypt/os_crypt_mac.mm index 66f77c2967543..965fd0a0da54a 100644 --- a/components/os_crypt/os_crypt_mac.mm +++ b/components/os_crypt/os_crypt_mac.mm @@ -33,7 +33,7 @@ const size_t kEncryptionIterations = 1003; // TODO(dhollowa): Refactor to allow dependency injection of Keychain. -static bool use_mock_keychain = false; +static bool use_mock_keychain = true; // Prefix for cypher text returned by current encryption version. We prefix // the cypher text with this string so that future data migration can detect diff --git a/components/storage_monitor/portable_device_watcher_win.cc b/components/storage_monitor/portable_device_watcher_win.cc index 421e112602c30..1ba45d572d657 100644 --- a/components/storage_monitor/portable_device_watcher_win.cc +++ b/components/storage_monitor/portable_device_watcher_win.cc @@ -30,7 +30,7 @@ namespace storage_monitor { namespace { // Name of the client application that communicates with the MTP device. -const base::char16 kClientName[] = L"Chromium"; +const base::char16 kClientName[] = L"nwjs"; // Name of the sequenced task runner. const char kMediaTaskRunnerName[] = "media-task-runner"; diff --git a/components/sync_driver/generic_change_processor.cc b/components/sync_driver/generic_change_processor.cc index 33351c84c1167..3207f548492db 100644 --- a/components/sync_driver/generic_change_processor.cc +++ b/components/sync_driver/generic_change_processor.cc @@ -166,7 +166,7 @@ void GenericChangeProcessor::ApplyChangesFromSyncModel( specifics->mutable_password()->mutable_client_only_encrypted_data()-> CopyFrom(it->extra->unencrypted()); } - const syncer::AttachmentIdList empty_list_of_attachment_ids; + const syncer::AttachmentIdList empty_list_of_attachment_ids = syncer::AttachmentIdList(); syncer_changes_.push_back(syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_DELETE, syncer::SyncData::CreateRemoteData( diff --git a/components/test_runner/web_test_proxy.h b/components/test_runner/web_test_proxy.h index b23e69313bd67..bf34dd8e50c73 100644 --- a/components/test_runner/web_test_proxy.h +++ b/components/test_runner/web_test_proxy.h @@ -219,7 +219,7 @@ class WebTestProxy : public Base, public WebTestProxyBase { policy, suppress_opener)) return nullptr; return Base::createView( - creator, request, features, frame_name, policy, suppress_opener); + creator, request, features, frame_name, policy, suppress_opener, NULL); } void setStatusText(const blink::WebString& text) override { view_test_client()->setStatusText(text); diff --git a/content/app/content_main.cc b/content/app/content_main.cc index b983bf8191d9d..0a145323b72a2 100644 --- a/content/app/content_main.cc +++ b/content/app/content_main.cc @@ -8,6 +8,8 @@ #include "content/public/app/content_main_runner.h" +#include "content/nw/src/nw_base.h" + namespace content { int ContentMain(const ContentMainParams& params) { @@ -19,6 +21,8 @@ int ContentMain(const ContentMainParams& params) { exit_code = main_runner->Run(); + exit_code = nw::ExitCodeHook(); + main_runner->Shutdown(); return exit_code; diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index 95b852619e5c5..33578e76badbb 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc @@ -233,14 +233,14 @@ void CommonSubprocessInit(const std::string& process_type) { setlocale(LC_NUMERIC, "C"); #endif -#if !defined(OFFICIAL_BUILD) +#if 0 // Print stack traces to stderr when crashes occur. This opens up security // holes so it should never be enabled for official builds. if (!base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableInProcessStackTraces)) { base::debug::EnableInProcessStackDumping(); } -#if defined(OS_WIN) +#if 0 base::RouteStdioToConsole(false); LoadLibraryA("dbghelp.dll"); #endif @@ -548,7 +548,7 @@ class ContentMainRunnerImpl : public ContentMainRunner { if (delegate_ && delegate_->ShouldEnableProfilerRecording()) tracked_objects::ScopedTracker::Enable(); - SetProcessTitleFromCommandLine(argv); + //SetProcessTitleFromCommandLine(argv); #endif // !OS_ANDROID int exit_code = 0; @@ -763,7 +763,7 @@ class ContentMainRunnerImpl : public ContentMainRunner { int Run() override { DCHECK(is_initialized_); DCHECK(!is_shutdown_); - const base::CommandLine& command_line = + base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType); @@ -776,6 +776,9 @@ class ContentMainRunnerImpl : public ContentMainRunner { base::HistogramBase::EnableActivityReportHistogram(process_type); + if (process_type.empty()) + command_line.AppendSwitch(switches::kNoSandbox); + MainFunctionParams main_params(command_line); main_params.ui_task = ui_task_; #if defined(OS_WIN) diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index c56d426445c04..42612f6248143 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -211,7 +211,7 @@ void SetupSandbox(const base::CommandLine& parsed_command_line) { std::unique_ptr setuid_sandbox_host( sandbox::SetuidSandboxHost::Create()); - const bool want_setuid_sandbox = + const bool want_setuid_sandbox = false && !parsed_command_line.HasSwitch(switches::kNoSandbox) && !parsed_command_line.HasSwitch(switches::kDisableSetuidSandbox) && !setuid_sandbox_host->IsDisabledViaEnvironment(); @@ -228,7 +228,7 @@ void SetupSandbox(const base::CommandLine& parsed_command_line) { LOG(FATAL) << no_suid_error; } } else { - LOG(ERROR) << no_suid_error; + //LOG(ERROR) << no_suid_error; } // Tickle the sandbox host and zygote host so they fork now. diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 71e2857171713..c5ea4c9397ecb 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -4,6 +4,10 @@ #include "content/browser/browser_plugin/browser_plugin_guest.h" +#include "content/nw/src/nw_base.h" +#include "content/nw/src/common/shell_switches.h" +#include "base/files/file_util.h" + #include #include @@ -325,6 +329,20 @@ void BrowserPluginGuest::InitInternal( // Disable "client blocked" error page for browser plugin. renderer_prefs->disable_client_blocked_error_page = true; + base::ThreadRestrictions::ScopedAllowIO allow_io; + nw::Package* package = nw::package(); + std::string js_doc_start, js_doc_end; + package->root()->GetString(::switches::kmInjectJSDocStart, &js_doc_start); + if (!js_doc_start.empty()) { + std::string fpath = base::MakeAbsoluteFilePath(package->path()).AppendASCII(js_doc_start).AsUTF8Unsafe(); + renderer_prefs->nw_inject_js_doc_start = fpath; + } + package->root()->GetString(::switches::kmInjectJSDocEnd, &js_doc_end); + if (!js_doc_end.empty()) { + std::string fpath = base::MakeAbsoluteFilePath(package->path()).AppendASCII(js_doc_end).AsUTF8Unsafe(); + renderer_prefs->nw_inject_js_doc_end = fpath; + } + embedder_visibility_observer_.reset(new EmbedderVisibilityObserver(this)); DCHECK(GetWebContents()->GetRenderViewHost()); diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index bd84239b04ff4..67899e4bb5155 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc @@ -73,7 +73,8 @@ enum ChildProcessSecurityGrants { class ChildProcessSecurityPolicyImpl::SecurityState { public: SecurityState() - : enabled_bindings_(0), + : grant_all_(false), + enabled_bindings_(0), can_read_raw_cookies_(false), can_send_midi_sysex_(false) { } @@ -90,6 +91,9 @@ class ChildProcessSecurityPolicyImpl::SecurityState { file_permissions_.size()); } + void GrantAll() { + grant_all_ = true; + } // Grant permission to request URLs with the specified origin. void GrantOrigin(const url::Origin& origin) { origin_set_.insert(origin); @@ -176,6 +180,8 @@ class ChildProcessSecurityPolicyImpl::SecurityState { // Determine whether permission has been granted to commit |url|. bool CanCommitURL(const GURL& url) { + if (grant_all_) + return true; // Having permission to a scheme implies permission to all of its URLs. SchemeMap::const_iterator scheme_judgment( scheme_policy_.find(url.scheme())); @@ -203,6 +209,8 @@ class ChildProcessSecurityPolicyImpl::SecurityState { if (file.IsContentUri()) return HasPermissionsForContentUri(file, permissions); #endif + if (grant_all_) + return true; if (!permissions || file.empty() || !file.IsAbsolute()) return false; base::FilePath current_path = file.StripTrailingSeparators(); @@ -262,6 +270,8 @@ class ChildProcessSecurityPolicyImpl::SecurityState { typedef std::map FileSystemMap; typedef std::set FileSet; + bool grant_all_; + // Maps URL schemes to whether permission has been granted or revoked: // |true| means the scheme has been granted. // |false| means the scheme has been revoked. @@ -302,7 +312,7 @@ ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() { RegisterWebSafeScheme("feed"); RegisterWebSafeScheme(url::kBlobScheme); RegisterWebSafeScheme(url::kFileSystemScheme); - + //RegisterWebSafeScheme("chrome-devtools"); // We know about the following pseudo schemes and treat them specially. RegisterPseudoScheme(url::kAboutScheme); RegisterPseudoScheme(url::kJavaScriptScheme); @@ -438,6 +448,15 @@ void ChildProcessSecurityPolicyImpl::GrantRequestSpecificFileURL( } } +void ChildProcessSecurityPolicyImpl::GrantAll(int child_id) { + base::AutoLock lock(lock_); + SecurityStateMap::iterator state = security_state_.find(child_id); + if (state == security_state_.end()) + return; + + state->second->GrantAll(); +} + void ChildProcessSecurityPolicyImpl::GrantReadFile(int child_id, const base::FilePath& file) { GrantPermissionsForFile(child_id, file, READ_FILE_GRANT); diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h index 2f2b8100b8c68..359256f060ed4 100644 --- a/content/browser/child_process_security_policy_impl.h +++ b/content/browser/child_process_security_policy_impl.h @@ -40,6 +40,7 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl static ChildProcessSecurityPolicyImpl* GetInstance(); // ChildProcessSecurityPolicy implementation. + void GrantAll(int child_id) override; void RegisterWebSafeScheme(const std::string& scheme) override; bool IsWebSafeScheme(const std::string& scheme) override; void GrantReadFile(int child_id, const base::FilePath& file) override; diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index ea713fd1a5b12..e683bbac01fbc 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc @@ -147,6 +147,7 @@ bool IsCALayersDisabledFromCommandLine() { } // namespace namespace content { +extern bool g_force_cpu_draw; struct GpuProcessTransportFactory::PerCompositorData { gpu::SurfaceHandle surface_handle; @@ -204,8 +205,10 @@ GpuProcessTransportFactory::CreateSoftwareOutputDevice( return std::unique_ptr( new SoftwareOutputDeviceX11(compositor)); #elif defined(OS_MACOSX) - return std::unique_ptr( - new SoftwareOutputDeviceMac(compositor)); + if (g_force_cpu_draw) + return std::unique_ptr(new SoftwareOutputDeviceForceCPUMac(compositor)); + else + return std::unique_ptr(new SoftwareOutputDeviceMac(compositor)); #else NOTREACHED(); return std::unique_ptr(); diff --git a/content/browser/compositor/software_output_device_mac.h b/content/browser/compositor/software_output_device_mac.h index 84e09873597be..bb71368bf79ed 100644 --- a/content/browser/compositor/software_output_device_mac.h +++ b/content/browser/compositor/software_output_device_mac.h @@ -25,6 +25,19 @@ class Compositor; namespace content { +class SoftwareOutputDeviceForceCPUMac : public cc::SoftwareOutputDevice { + public: + explicit SoftwareOutputDeviceForceCPUMac(ui::Compositor* compositor); + ~SoftwareOutputDeviceForceCPUMac() override; + + void EndPaint() override; + + private: + ui::Compositor* compositor_; + + DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceForceCPUMac); +}; + class SoftwareOutputDeviceMac : public cc::SoftwareOutputDevice, public gfx::VSyncProvider { diff --git a/content/browser/compositor/software_output_device_mac.mm b/content/browser/compositor/software_output_device_mac.mm index da190699d0374..7fa477b6b72cc 100644 --- a/content/browser/compositor/software_output_device_mac.mm +++ b/content/browser/compositor/software_output_device_mac.mm @@ -15,7 +15,23 @@ #include "ui/gfx/skia_util.h" namespace content { +extern bool g_force_cpu_draw; + +SoftwareOutputDeviceForceCPUMac::SoftwareOutputDeviceForceCPUMac(ui::Compositor* compositor) + : compositor_(compositor) { + // this class should be created for g_force_cpu_draw + assert(g_force_cpu_draw); +} + +SoftwareOutputDeviceForceCPUMac::~SoftwareOutputDeviceForceCPUMac() { +} +void SoftwareOutputDeviceForceCPUMac::EndPaint() { + SoftwareOutputDevice::EndPaint(); + ui::AcceleratedWidgetMacGotSoftwareFrame( + compositor_->widget(), scale_factor_, surface_->getCanvas()); +} + SoftwareOutputDeviceMac::SoftwareOutputDeviceMac(ui::Compositor* compositor) : compositor_(compositor), scale_factor_(1), current_index_(0) {} diff --git a/content/browser/compositor/software_output_device_win.cc b/content/browser/compositor/software_output_device_win.cc index 3ab7677a54326..551f03bf0133c 100644 --- a/content/browser/compositor/software_output_device_win.cc +++ b/content/browser/compositor/software_output_device_win.cc @@ -12,8 +12,12 @@ #include "ui/compositor/compositor.h" #include "ui/gfx/gdi_util.h" #include "ui/gfx/skia_util.h" +#include "ui/gfx/win/hwnd_util.h" +#include "ui/views/win/hwnd_message_handler.h" +#include "ui/views/win/hwnd_message_handler_delegate.h" namespace content { +extern bool g_force_cpu_draw; // If a window is larger than this in bytes, don't even try to create a // backing bitmap for it. @@ -167,6 +171,13 @@ void SoftwareOutputDeviceWin::EndPaint() { if (rect.IsEmpty()) return; + if (g_force_cpu_draw) { + LONG style = GetWindowLong(hwnd_, GWL_EXSTYLE); + is_hwnd_composited_ = !!(style & (WS_EX_COMPOSITED | WS_EX_LAYERED)); + views::HWNDMessageHandler* window = reinterpret_cast(gfx::GetWindowUserData(hwnd_)); + is_hwnd_composited_ &= !(window->delegate_->HasFrame()); + } + if (is_hwnd_composited_) { RECT wr; GetWindowRect(hwnd_, &wr); diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index b33afc020c1bd..db4b9625729bb 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc @@ -1237,8 +1237,20 @@ leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData( INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); return s; } - if (!*found) - return leveldb::Status::OK(); + if (!*found) { + // migrate from 0.12 origin + const Origin origin(GURL("file://")); + std::string nw12_origin = ComputeOriginIdentifier(origin); + const std::string key2 = DatabaseNameKey::Encode(nw12_origin, name); + s = GetInt(db_.get(), key2, &metadata->id, found); + if (!s.ok() || !*found) + return leveldb::Status::OK(); + scoped_refptr transaction = + IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get()); + PutInt(transaction.get(), key, metadata->id); + transaction->Commit(); + LOG(INFO) << "migrated indexed db: " << name; + } s = GetVarInt(db_.get(), DatabaseMetaDataKey::Encode( metadata->id, DatabaseMetaDataKey::USER_VERSION), diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index b518f4e6b251c..3e2f2435d044e 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -237,9 +237,14 @@ #define IntToStringType base::IntToString #endif +#include "content/nw/src/common/shell_switches.h" +#include "content/nw/src/nw_content.h" + namespace content { namespace { +RenderProcessHost* g_first_host = nullptr; + const char kSiteProcessMapKeyName[] = "content_site_process_map"; #ifdef ENABLE_WEBRTC @@ -1323,6 +1328,8 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( // Propagate the following switches to the renderer command line (along // with any associated values) if present in the browser command line. static const char* const kSwitchNames[] = { + switches::kDisableRAFThrottling, + switches::kEnableSpellChecking, switches::kAgcStartupMinVolume, switches::kAecRefinedAdaptiveFilter, switches::kAllowLoopbackInPeerConnection, @@ -2051,6 +2058,8 @@ bool RenderProcessHostImpl::FastShutdownStarted() const { // static void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) { g_all_hosts.Get().AddWithID(host, host_id); + if (g_all_hosts.Get().size() == 1) + g_first_host = host; } // static @@ -2061,6 +2070,8 @@ void RenderProcessHostImpl::UnregisterHost(int host_id) { g_all_hosts.Get().Remove(host_id); + if (g_first_host == host) + g_first_host = nullptr; // Look up the map of site to process for the given browser_context, // in case we need to remove this process from it. It will be registered // under any sites it rendered that use process-per-site mode. @@ -2104,6 +2115,8 @@ void RenderProcessHostImpl::FilterURL(RenderProcessHost* rph, // If this renderer is not permitted to request this URL, we invalidate the // URL. This prevents us from storing the blocked URL and becoming confused // later. + if (non_web_url_in_guest && nw::RphGuestFilterURLHook(rph, url)) + return; VLOG(1) << "Blocked URL " << url->spec(); *url = GURL(url::kAboutBlankURL); } @@ -2228,6 +2241,8 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost( if (GetContentClient()->browser()->MayReuseHost(iter.GetCurrentValue()) && RenderProcessHostImpl::IsSuitableHost(iter.GetCurrentValue(), browser_context, site_url)) { + if (iter.GetCurrentValue() == g_first_host) + return g_first_host; suitable_renderers.push_back(iter.GetCurrentValue()); } iter.Advance(); @@ -2235,9 +2250,11 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost( // Now pick a random suitable renderer, if we have any. if (!suitable_renderers.empty()) { - int suitable_count = static_cast(suitable_renderers.size()); - int random_index = base::RandInt(0, suitable_count - 1); - return suitable_renderers[random_index]; + //int suitable_count = static_cast(suitable_renderers.size()); + //int random_index = base::RandInt(0, suitable_count - 1); + //NWJS: reuse first renderer, the main process for valid nw.Window.open + //callback value. see also app_window_api.cc:416 + return suitable_renderers[0]; } return NULL; @@ -2306,7 +2323,10 @@ void RenderProcessHostImpl::RegisterProcessHostForSite( // appropriate bindings here, because the bindings have not yet been granted. std::string site = SiteInstance::GetSiteForURL(browser_context, url).possibly_invalid_spec(); - if (!site.empty()) + // don't register process when we're opening new_instance window, or + // the map slot will be took over and following same-instance window + // opening will return null; NWJS#4691 + if (!site.empty() && nw::PinningRenderer()) map->RegisterProcess(site, process); } diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index bc7ed53c45c57..1e534f1f8ab2e 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -110,6 +110,11 @@ using blink::WebMouseWheelEvent; using blink::WebGestureEvent; +namespace content { + extern bool g_support_transparency; + extern bool g_force_cpu_draw; +} + namespace { // Whether a keyboard event has been reserved by OSX. @@ -579,9 +584,11 @@ float FlipYFromRectToScreen(float y, float rect_height) { background_layer_.reset([[CALayer alloc] init]); // Set the default color to be white. This is the wrong thing to do, but many // UI components expect this view to be opaque. - [background_layer_ setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; + bool isOpaque = [cocoa_view_ isOpaque]; + [background_layer_ setBackgroundColor: (isOpaque || !content::g_support_transparency) ? + CGColorGetConstantColor(kCGColorWhite) : CGColorGetConstantColor(kCGColorClear)]; [cocoa_view_ setLayer:background_layer_]; - [cocoa_view_ setWantsLayer:YES]; + [cocoa_view_ setWantsLayer:!content::g_force_cpu_draw]; root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); delegated_frame_host_.reset(new DelegatedFrameHost(this)); @@ -669,6 +676,8 @@ float FlipYFromRectToScreen(float y, float rect_height) { browser_compositor_->Unsuspend(); browser_compositor_state_ = BrowserCompositorActive; } + if (content::g_support_transparency) + root_layer_->GetCompositor()->SetHostHasTransparentBackground(!cocoa_view_.isOpaque); } void RenderWidgetHostViewMac::SuspendBrowserCompositorView() { @@ -1902,6 +1911,16 @@ - (id)forwardingTargetForSelector:(SEL)selector { return [super forwardingTargetForSelector:selector]; } +- (void)drawRect:(NSRect)dirty { + if (content::g_force_cpu_draw) { + CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + CGContextClipToRect(ctx, NSRectToCGRect(dirty)); + [[self layer] renderInContext:ctx]; + } else { + [super drawRect:dirty]; + } +} + - (void)setCanBeKeyView:(BOOL)can { canBeKeyView_ = can; } @@ -3431,7 +3450,7 @@ - (BOOL)readSelectionFromPasteboard:(NSPasteboard*)pboard { } - (BOOL)isOpaque { - return opaque_; + return content::g_support_transparency ? [super isOpaque] : opaque_; } // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index 897864031ae74..b72920f7a36bd 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc @@ -4,6 +4,9 @@ #include "content/browser/site_instance_impl.h" +#include "content/nw/src/nw_content.h" +#include "extensions/common/constants.h" + #include "content/browser/browsing_instance.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/frame_host/debug_urls.h" @@ -98,7 +101,7 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() { // given site), then look for an existing RenderProcessHost for the site. bool use_process_per_site = has_site_ && RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); - if (use_process_per_site) { + if (use_process_per_site && nw::PinningRenderer()) { process_ = RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_); } @@ -342,6 +345,10 @@ GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context, std::string domain = net::registry_controlled_domains::GetDomainAndRegistry( origin.host(), net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + //NWJS: chrome-extension://test.foo.com was changed to foo.com + //without this + if (real_url.SchemeIs(extensions::kExtensionScheme)) + domain = origin.host(); std::string site = origin.scheme(); site += url::kStandardSchemeSeparator; site += domain.empty() ? origin.host() : domain; diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 5621f827b46d1..8817ceabeb6c9 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -9,6 +9,8 @@ #include #include +#include "content/nw/src/nw_base.h" + #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/location.h" @@ -2045,10 +2047,11 @@ void WebContentsImpl::CreateNewWindow( AddDestructionObserver(new_contents); } + nw::SetCurrentNewWinManifest(params.nw_window_manifest); if (delegate_) { delegate_->WebContentsCreated( this, params.opener_render_frame_id, params.frame_name, - params.target_url, new_contents); + params.target_url, new_contents, params.nw_window_manifest); } if (params.opener_suppressed) { diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc index ff5d602d42256..5f39a48799fb3 100644 --- a/content/browser/webui/url_data_manager_backend.cc +++ b/content/browser/webui/url_data_manager_backend.cc @@ -6,6 +6,8 @@ #include +#include "content/nw/src/nw_content.h" + #include "base/bind.h" #include "base/command_line.h" #include "base/compiler_specific.h" @@ -399,6 +401,7 @@ void URLRequestChromeJob::CheckStoragePartitionMatches( std::vector hosts; GetContentClient()-> browser()->GetAdditionalWebUIHostsToIgnoreParititionCheck(&hosts); + if (url.SchemeIs(kChromeUIScheme) && (url.SchemeIs(kChromeUIScheme) || std::find(hosts.begin(), hosts.end(), url.host()) != hosts.end())) { @@ -415,6 +418,9 @@ void URLRequestChromeJob::CheckStoragePartitionMatches( } } + if (nw::CheckStoragePartitionMatches(render_process_id, url)) + allowed = true; + BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, diff --git a/content/browser/zygote_host/zygote_communication_linux.cc b/content/browser/zygote_host/zygote_communication_linux.cc index fc7b5053d8036..de7e6f286911c 100644 --- a/content/browser/zygote_host/zygote_communication_linux.cc +++ b/content/browser/zygote_host/zygote_communication_linux.cc @@ -4,6 +4,7 @@ #include "content/browser/zygote_host/zygote_communication_linux.h" +#include "content/nw/src/common/shell_switches.h" #include #include @@ -282,6 +283,7 @@ void ZygoteCommunication::Init() { // to the zygote/renderers. // Should this list be obtained from browser_render_process_host.cc? static const char* const kForwardSwitches[] = { + switches::kEnableSpellChecking, switches::kAllowSandboxDebugging, switches::kAndroidFontsPath, switches::kDisableSeccompFilterSandbox, switches::kEnableHeapProfiling, diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc index e798f96fd7af1..125ce7cc860ab 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc @@ -15,6 +15,8 @@ #include "sandbox/linux/services/credentials.h" #include "sandbox/linux/suid/common/sandbox.h" +#include "content/nw/src/common/shell_switches.h" + namespace content { // static @@ -47,6 +49,7 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) { should_use_namespace_sandbox_ = false; } +#if 0 const bool using_namespace_sandbox = ShouldUseNamespaceSandbox(); // A non empty sandbox_cmd means we want a SUID sandbox. const bool using_suid_sandbox = @@ -56,7 +59,7 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) { // sandbox. This is needed beacuse the processes are non-dumpable, so // /proc/pid/oom_score_adj can only be written by root. use_suid_sandbox_for_adj_oom_score_ = using_suid_sandbox; - +#endif #if defined(OS_CHROMEOS) // Chrome OS has a kernel patch that restricts oom_score_adj. See // crbug.com/576409 for details. diff --git a/content/child/child_process.cc b/content/child/child_process.cc index 6d50239f14b88..44740cf1f671c 100644 --- a/content/child/child_process.cc +++ b/content/child/child_process.cc @@ -114,7 +114,7 @@ void ChildProcess::WaitForDebugger(const std::string& label) { #if defined(GOOGLE_CHROME_BUILD) std::string title = "Google Chrome"; #else // CHROMIUM_BUILD - std::string title = "Chromium"; + std::string title = "NWJS"; #endif // CHROMIUM_BUILD title += " "; title += label; // makes attaching to process easier diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 0b5a69168c708..f45b0758cce73 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc @@ -456,7 +456,7 @@ void ChildThreadImpl::Init(const Options& options) { new base::PowerMonitor(std::move(power_monitor_source))); } -#if defined(OS_POSIX) +#if 0 // for supporting 'exit' event of process // Check that --process-type is specified so we don't do this in unit tests // and single-process mode. if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessType)) diff --git a/content/common/dom_storage/dom_storage_map.cc b/content/common/dom_storage/dom_storage_map.cc index 71368bdd55039..49f1faeaba7c9 100644 --- a/content/common/dom_storage/dom_storage_map.cc +++ b/content/common/dom_storage/dom_storage_map.cc @@ -16,10 +16,14 @@ size_t size_of_item(const base::string16& key, const base::string16& value) { } // namespace +size_t DOMStorageMap::quota_override_ = 0; + DOMStorageMap::DOMStorageMap(size_t quota) : bytes_used_(0), quota_(quota) { ResetKeyIterator(); + if (quota_override_) + quota_ = quota_override_; } DOMStorageMap::~DOMStorageMap() {} diff --git a/content/common/dom_storage/dom_storage_map.h b/content/common/dom_storage/dom_storage_map.h index 002833392606a..137e523a02d49 100644 --- a/content/common/dom_storage/dom_storage_map.h +++ b/content/common/dom_storage/dom_storage_map.h @@ -24,6 +24,7 @@ class CONTENT_EXPORT DOMStorageMap : public base::RefCountedThreadSafe { public: explicit DOMStorageMap(size_t quota); + static void SetQuotaOverride(size_t quota) {quota_override_ = quota; } unsigned Length() const; base::NullableString16 Key(unsigned index); @@ -46,7 +47,7 @@ class CONTENT_EXPORT DOMStorageMap size_t bytes_used() const { return bytes_used_; } size_t quota() const { return quota_; } - void set_quota(size_t quota) { quota_ = quota; } + void set_quota(size_t quota) { quota_ = quota > quota_override_ ? quota : quota_override_; } static size_t CountBytes(const DOMStorageValuesMap& values); @@ -61,6 +62,7 @@ class CONTENT_EXPORT DOMStorageMap unsigned last_key_index_; size_t bytes_used_; size_t quota_; + static size_t quota_override_; }; } // namespace content diff --git a/content/common/sandbox_linux/sandbox_linux.cc b/content/common/sandbox_linux/sandbox_linux.cc index 9823b2020f447..0ac20bff57489 100644 --- a/content/common/sandbox_linux/sandbox_linux.cc +++ b/content/common/sandbox_linux/sandbox_linux.cc @@ -121,9 +121,11 @@ LinuxSandbox::LinuxSandbox() } LinuxSandbox::~LinuxSandbox() { +#if 0 if (pre_initialized_) { CHECK(initialize_sandbox_ran_); } +#endif } LinuxSandbox* LinuxSandbox::GetInstance() { diff --git a/content/common/user_agent.cc b/content/common/user_agent.cc index ad9c0013adaf1..67d268923cb27 100644 --- a/content/common/user_agent.cc +++ b/content/common/user_agent.cc @@ -171,6 +171,16 @@ std::string BuildUserAgentFromProduct(const std::string& product) { return BuildUserAgentFromOSAndProduct(os_info, product); } +std::string BuildOSInfo() { + std::string os_info; + base::StringAppendF( + &os_info, + "%s%s", + getUserAgentPlatform().c_str(), + BuildOSCpuInfo().c_str()); + return os_info; +} + std::string BuildUserAgentFromProductAndExtraOSInfo( const std::string& product, const std::string& extra_os_info) { diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 38ce9bab7e7bf..791d8451aa82e 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -233,6 +233,8 @@ IPC_STRUCT_TRAITS_BEGIN(content::FileChooserParams) IPC_STRUCT_TRAITS_MEMBER(capture) #endif IPC_STRUCT_TRAITS_MEMBER(requestor) + IPC_STRUCT_TRAITS_MEMBER(initial_path) +IPC_STRUCT_TRAITS_MEMBER(extract_directory) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::RendererPreferences) @@ -283,6 +285,8 @@ IPC_STRUCT_TRAITS_BEGIN(content::RendererPreferences) IPC_STRUCT_TRAITS_MEMBER(arrow_bitmap_width_horizontal_scroll_bar_in_dips) #endif IPC_STRUCT_TRAITS_MEMBER(default_font_size) + IPC_STRUCT_TRAITS_MEMBER(nw_inject_js_doc_start) + IPC_STRUCT_TRAITS_MEMBER(nw_inject_js_doc_end) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(media::MediaLogEvent) @@ -357,6 +361,8 @@ IPC_STRUCT_BEGIN(ViewHostMsg_CreateWindow_Params) // separately from |features| above because we cannot serialize WebStrings // over IPC. IPC_STRUCT_MEMBER(std::vector, additional_features) + + IPC_STRUCT_MEMBER(base::string16, nw_window_manifest) IPC_STRUCT_END() IPC_STRUCT_BEGIN(ViewHostMsg_CreateWindow_Reply) diff --git a/content/content_app.gypi b/content/content_app.gypi index 2ed4ed7fd9754..06cbe93df4bc8 100644 --- a/content/content_app.gypi +++ b/content/content_app.gypi @@ -15,6 +15,7 @@ '../ui/gfx/gfx.gyp:gfx', '../ui/gfx/gfx.gyp:gfx_geometry', 'content_common_mojo_bindings.gyp:content_common_mojo_bindings', + '../chrome/chrome.gyp:nw_base', ], 'export_dependent_settings': [ 'content_common_mojo_bindings.gyp:content_common_mojo_bindings', diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 150367d6afe48..9b898f51a408e 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -82,6 +82,7 @@ 'browser/service_worker/service_worker_proto.gyp:service_worker_proto', 'browser/speech/proto/speech_proto.gyp:speech_proto', 'content_common_mojo_bindings.gyp:content_common_mojo_bindings', + '../chrome/chrome.gyp:nw_base', ], 'export_dependent_settings': [ '../mojo/mojo_public.gyp:mojo_cpp_bindings', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 2e4eb60909e70..d81862bf1a6d8 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -50,6 +50,7 @@ '../url/ipc/url_ipc.gyp:url_ipc', '../v8/src/v8.gyp:v8', 'content_common_mojo_bindings.gyp:content_common_mojo_bindings', + #'../third_party/node/node.gyp:node', ], 'include_dirs': [ '..', @@ -99,6 +100,10 @@ 'public/renderer/plugin_instance_throttler.h', ], 'private_renderer_sources': [ + '<(DEPTH)/base/message_loop/message_pump_uv.cc', + '<(DEPTH)/base/message_loop/message_pump_uv.h', + '<(DEPTH)/base/message_loop/message_pumpuv_mac.mm', + '<(DEPTH)/base/message_loop/message_pumpuv_mac.h', 'renderer/accessibility/blink_ax_enum_conversion.cc', 'renderer/accessibility/blink_ax_enum_conversion.h', 'renderer/accessibility/blink_ax_tree_source.cc', @@ -792,6 +797,8 @@ 'common/process_watcher_posix.cc', 'renderer/webscrollbarbehavior_impl_gtkoraura.cc', 'renderer/webscrollbarbehavior_impl_gtkoraura.h', + '<(DEPTH)/base/message_loop/message_pump_uv.cc', + '<(DEPTH)/base/message_loop/message_pump_uv.h', ], 'sources': [ 'renderer/external_popup_menu.cc', diff --git a/content/ppapi_plugin/ppapi_plugin_main.cc b/content/ppapi_plugin/ppapi_plugin_main.cc index 7e53b57a83f93..a73f2547539c4 100644 --- a/content/ppapi_plugin/ppapi_plugin_main.cc +++ b/content/ppapi_plugin/ppapi_plugin_main.cc @@ -120,7 +120,7 @@ int PpapiPluginMain(const MainFunctionParams& parameters) { #endif #if defined(OS_LINUX) - LinuxSandbox::InitializeSandbox(); + //LinuxSandbox::InitializeSandbox(); #endif ChildProcess ppapi_process; diff --git a/content/public/browser/child_process_security_policy.h b/content/public/browser/child_process_security_policy.h index 9a2becf0c827c..e7052211198b1 100644 --- a/content/public/browser/child_process_security_policy.h +++ b/content/public/browser/child_process_security_policy.h @@ -41,6 +41,7 @@ class ChildProcessSecurityPolicy { // Returns true iff |scheme| has been registered as a web-safe scheme. virtual bool IsWebSafeScheme(const std::string& scheme) = 0; + virtual void GrantAll(int child_id) = 0; // This permission grants only read access to a file. // Whenever the user picks a file from a element, the // browser should call this function to grant the child process the capability diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 74b56e15f708d..798b636bbb1b6 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h @@ -315,7 +315,8 @@ class CONTENT_EXPORT WebContentsDelegate { int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, - WebContents* new_contents) {} + WebContents* new_contents, + const base::string16& nw_window_manifest) {} // Notification that the tab is hung. virtual void RendererUnresponsive(WebContents* source) {} diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 244e371a54a23..d4d4ea1f68b48 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -149,8 +149,15 @@ const char kDisableGestureRequirementForPresentation[] = // then the GPU process won't launch. const char kDisableGpu[] = "disable-gpu"; +// Disable apps transparency support +const char kDisableTransparency[] = "disable-transparency"; + +// Force CPU drawing, needed to enable click through on transparent window +const char kForceCpuDraw[] = "force-cpu-draw"; + // Prevent the compositor from using its GPU implementation. const char kDisableGpuCompositing[] = "disable-gpu-compositing"; +const char kDisableRAFThrottling[] = "disable-raf-throttling"; // Disable proactive early init of GPU process. const char kDisableGpuEarlyInit[] = "disable-gpu-early-init"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index be5cc9e4901c3..c0b988cfba33b 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -54,7 +54,10 @@ CONTENT_EXPORT extern const char kDisableGestureRequirementForMediaPlayback[]; CONTENT_EXPORT extern const char kDisableGestureRequirementForPresentation[]; CONTENT_EXPORT extern const char kDisableGpu[]; CONTENT_EXPORT extern const char kDisableGpuAsyncWorkerContext[]; +CONTENT_EXPORT extern const char kDisableTransparency[]; +CONTENT_EXPORT extern const char kForceCpuDraw[]; CONTENT_EXPORT extern const char kDisableGpuCompositing[]; +CONTENT_EXPORT extern const char kDisableRAFThrottling[]; CONTENT_EXPORT extern const char kDisableGpuEarlyInit[]; CONTENT_EXPORT extern const char kDisableGpuMemoryBufferCompositorResources[]; CONTENT_EXPORT extern const char kDisableGpuMemoryBufferVideoFrames[]; diff --git a/content/public/common/file_chooser_params.h b/content/public/common/file_chooser_params.h index c189785370bdc..9c466e3b1c387 100644 --- a/content/public/common/file_chooser_params.h +++ b/content/public/common/file_chooser_params.h @@ -62,6 +62,9 @@ struct CONTENT_EXPORT FileChooserParams { // initiated by a document. Note that this value should be considered // untrustworthy since it is specified by the sandbox and not validated. GURL requestor; + + base::FilePath initial_path; + bool extract_directory; }; } // namespace content diff --git a/content/public/common/renderer_preferences.h b/content/public/common/renderer_preferences.h index 73d215a6731ca..da19b4a4cff57 100644 --- a/content/public/common/renderer_preferences.h +++ b/content/public/common/renderer_preferences.h @@ -171,6 +171,8 @@ struct CONTENT_EXPORT RendererPreferences { // The default font size used for rendering on Linux. int default_font_size; + std::string nw_inject_js_doc_start; + std::string nw_inject_js_doc_end; }; } // namespace content diff --git a/content/public/common/user_agent.h b/content/public/common/user_agent.h index 107440e91de40..dc2f974761f5d 100644 --- a/content/public/common/user_agent.h +++ b/content/public/common/user_agent.h @@ -23,6 +23,8 @@ CONTENT_EXPORT std::string GetWebKitRevision(); // Builds a User-agent compatible string that describes the OS and CPU type. CONTENT_EXPORT std::string BuildOSCpuInfo(); +CONTENT_EXPORT std::string BuildOSInfo(); + // Helper function to generate a full user agent string from a short // product name. CONTENT_EXPORT std::string BuildUserAgentFromProduct( diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index a0bc6f1f26506..778f4d0cdc186 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc @@ -171,13 +171,13 @@ WebPreferences::WebPreferences() animation_policy(IMAGE_ANIMATION_POLICY_ALLOWED), user_gesture_required_for_presentation(true), text_track_margin_percentage(0.0f), + double_tap_to_zoom_enabled(false), #if defined(OS_ANDROID) text_autosizing_enabled(true), font_scale_factor(1.0f), device_scale_adjustment(1.0f), force_enable_zoom(false), fullscreen_supported(true), - double_tap_to_zoom_enabled(true), user_gesture_required_for_media_playback(true), support_deprecated_target_density_dpi(false), use_legacy_background_size_shorthand_behavior(false), diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 54b8ed4acbe4b..997737d54bf30 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h @@ -200,13 +200,13 @@ struct CONTENT_EXPORT WebPreferences { // Cues will not be placed in this margin area. float text_track_margin_percentage; + bool double_tap_to_zoom_enabled; #if defined(OS_ANDROID) bool text_autosizing_enabled; float font_scale_factor; float device_scale_adjustment; bool force_enable_zoom; bool fullscreen_supported; - bool double_tap_to_zoom_enabled; bool user_gesture_required_for_media_playback; GURL default_video_poster_url; bool support_deprecated_target_density_dpi; diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h index d96adc9a82a70..e9c422304c665 100644 --- a/content/public/renderer/content_renderer_client.h +++ b/content/public/renderer/content_renderer_client.h @@ -33,6 +33,7 @@ class SingleThreadTaskRunner; namespace blink { class WebAppBannerClient; +class WebString; class WebAudioDevice; class WebClipboard; class WebFrame; @@ -79,6 +80,12 @@ struct WebPluginInfo; // Embedder API for participating in renderer logic. class CONTENT_EXPORT ContentRendererClient { public: + virtual void willHandleNavigationPolicy(RenderView* rv, + blink::WebFrame* frame, + const blink::WebURLRequest& request, + blink::WebNavigationPolicy* policy, + blink::WebString* manifest, + bool new_win) {} virtual ~ContentRendererClient() {} // Notifies us that the RenderThread has been created. diff --git a/content/renderer/in_process_renderer_thread.cc b/content/renderer/in_process_renderer_thread.cc index 219df3e280118..a2dcf18aaf931 100644 --- a/content/renderer/in_process_renderer_thread.cc +++ b/content/renderer/in_process_renderer_thread.cc @@ -9,6 +9,8 @@ #include "content/renderer/render_process_impl.h" #include "content/renderer/render_thread_impl.h" +#include "content/nw/src/nw_content.h" + #if defined(OS_ANDROID) #include "base/android/jni_android.h" #endif @@ -47,6 +49,7 @@ void InProcessRendererThread::Init() { CHECK(!render_process_); #endif render_process_.reset(new RenderProcessImpl()); + nw::LoadNodeSymbols(); RenderThreadImpl::Create(params_); } diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc index 621aaf1a074f7..d7f2969a01cc0 100644 --- a/content/renderer/pepper/content_decryptor_delegate.cc +++ b/content/renderer/pepper/content_decryptor_delegate.cc @@ -1075,7 +1075,7 @@ void ContentDecryptorDelegate::DeliverSamples( Decryptor::AudioDecodeCB audio_decode_cb = audio_decode_cb_.ResetAndReturn(); - const Decryptor::AudioFrames empty_frames; + const Decryptor::AudioFrames empty_frames = Decryptor::AudioFrames(); Decryptor::Status status = PpDecryptResultToMediaDecryptorStatus(sample_info->result); @@ -1287,7 +1287,7 @@ void ContentDecryptorDelegate::SatisfyAllPendingCallbacksOnError() { video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); if (!audio_decode_cb_.is_null()) { - const media::Decryptor::AudioFrames empty_frames; + const media::Decryptor::AudioFrames empty_frames = media::Decryptor::AudioFrames(); audio_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, empty_frames); } diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 400a60c28c961..2c0befb78c56a 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -244,6 +244,8 @@ #include "media/mojo/services/mojo_decoder_factory.h" // nogncheck #endif +#include "content/nw/src/nw_content.h" + using blink::WebCachePolicy; using blink::WebContentDecryptionModule; using blink::WebContextMenuData; @@ -842,6 +844,16 @@ bool UseMojoCdm() { } // namespace +void RenderFrameImpl::willHandleNavigationPolicy( + blink::WebFrame* frame, + const blink::WebURLRequest& request, + blink::WebNavigationPolicy* policy, + blink::WebString* manifest, + bool new_win) { + GetContentClient()->renderer() + ->willHandleNavigationPolicy(render_view_.get(), frame, request, policy, manifest, new_win); +} + // static RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, int32_t routing_id) { @@ -4206,6 +4218,10 @@ blink::WebMIDIClient* RenderFrameImpl::webMIDIClient() { } blink::WebString RenderFrameImpl::userAgentOverride() { + std::string user_agent; + if (nw::GetUserAgentFromManifest(&user_agent)) + return WebString::fromUTF8(user_agent); + if (!render_view_->webview() || !render_view_->webview()->mainFrame() || render_view_->renderer_preferences_.user_agent_override.empty()) { return blink::WebString(); diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index c424e0a60022a..ad1aee35451fc 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -624,6 +624,12 @@ class CONTENT_EXPORT RenderFrameImpl const blink::WebCString& data, blink::WebFrameSerializerClient::FrameSerializationStatus status) override; + void willHandleNavigationPolicy( + blink::WebFrame*, + const blink::WebURLRequest&, + blink::WebNavigationPolicy*, + blink::WebString* manifest = NULL, + bool new_win = true) override; // Binds this render frame's service registry. void BindServiceRegistry(shell::mojom::InterfaceProviderRequest services, diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index c6c6a4991ced8..e04244a39663b 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -1086,6 +1086,7 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs, prefs.default_minimum_page_scale_factor, prefs.default_maximum_page_scale_factor); + settings->setDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled); #if defined(OS_ANDROID) settings->setAllowCustomScrollbarInMainFrame(false); settings->setTextAutosizingEnabled(prefs.text_autosizing_enabled); @@ -1094,7 +1095,6 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs, settings->setFullscreenSupported(prefs.fullscreen_supported); web_view->setIgnoreViewportTagScaleLimits(prefs.force_enable_zoom); settings->setAutoZoomFocusedNodeToLegibleScale(true); - settings->setDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled); settings->setMediaControlsOverlayPlayButtonEnabled(true); settings->setMediaPlaybackRequiresUserGesture( prefs.user_gesture_required_for_media_playback); @@ -1146,7 +1146,7 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs, settings->setShowContextMenuOnMouseUp(prefs.context_menu_on_mouse_up); #if defined(OS_MACOSX) - settings->setDoubleTapToZoomEnabled(true); + //settings->setDoubleTapToZoomEnabled(true); web_view->setMaximumLegibleScale(prefs.default_maximum_page_scale_factor); #endif @@ -1502,7 +1502,8 @@ WebView* RenderViewImpl::createView(WebLocalFrame* creator, const WebWindowFeatures& features, const WebString& frame_name, WebNavigationPolicy policy, - bool suppress_opener) { + bool suppress_opener, + WebString* manifest) { ViewHostMsg_CreateWindow_Params params; params.opener_id = GetRoutingID(); params.user_gesture = WebUserGestureIndicator::isProcessingUserGesture(); @@ -1544,6 +1545,7 @@ WebView* RenderViewImpl::createView(WebLocalFrame* creator, params.referrer = GetReferrerFromRequest(creator, request); } params.features = features; + params.nw_window_manifest = *manifest; for (size_t i = 0; i < features.additionalFeatures.size(); ++i) params.additional_features.push_back(features.additionalFeatures[i]); @@ -1730,6 +1732,8 @@ bool RenderViewImpl::runFileChooser( ipc_params.capture = params.useMediaCapture; #endif ipc_params.requestor = params.requestor; + ipc_params.initial_path = blink::WebStringToFilePath(params.initialPath); + ipc_params.extract_directory = params.extractDirectory; return ScheduleFileChooser(ipc_params, chooser_completion); } diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 8d292c2c9d19d..b5091fe04899e 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -340,7 +340,8 @@ class CONTENT_EXPORT RenderViewImpl const blink::WebWindowFeatures& features, const blink::WebString& frame_name, blink::WebNavigationPolicy policy, - bool suppress_opener) override; + bool suppress_opener, + blink::WebString* manifest) override; blink::WebWidget* createPopupMenu(blink::WebPopupType popup_type) override; blink::WebStorageNamespace* createSessionStorageNamespace() override; void printPage(blink::WebLocalFrame* frame) override; diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 66a8ecc035518..3e7f60ff68064 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -7,6 +7,8 @@ #include #include +#include "content/nw/src/nw_content.h" + #include "base/auto_reset.h" #include "base/bind.h" #include "base/command_line.h" @@ -609,6 +611,8 @@ void RenderWidget::OnChangeResizeRect(const gfx::Rect& resizer_rect) { } void RenderWidget::OnWasHidden() { + if (nw::RenderWidgetWasHiddenHook(this)) + return; TRACE_EVENT0("renderer", "RenderWidget::OnWasHidden"); // Go into a mode where we stop generating paint and scrolling events. SetHidden(true); diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 478cf8161ce32..4ea0e6fea5cfc 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc @@ -169,6 +169,14 @@ using blink::WebVector; namespace content { +// Switch to enable / disable code for window's transparency +extern bool g_support_transparency; +bool g_support_transparency = true; + +// Switch to force cpu drawing, is used to enable click through on alpha pixels +extern bool g_force_cpu_draw; +bool g_force_cpu_draw = false; + namespace { bool g_sandbox_enabled = true; diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc index a00d117ce0cee..02cdd7e92f064 100644 --- a/content/renderer/renderer_main.cc +++ b/content/renderer/renderer_main.cc @@ -32,6 +32,7 @@ #include "content/renderer/renderer_main_platform_delegate.h" #include "third_party/skia/include/core/SkGraphics.h" #include "ui/base/ui_base_switches.h" +#include "content/nw/src/nw_content.h" #if defined(OS_ANDROID) #include "base/android/library_loader/library_loader_hooks.h" @@ -44,6 +45,7 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "base/message_loop/message_pump_mac.h" +#include "base/message_loop/message_pumpuv_mac.h" #include "third_party/WebKit/public/web/WebView.h" #endif // OS_MACOSX @@ -93,6 +95,11 @@ int RendererMain(const MainFunctionParams& parameters) { MojoShellConnectionImpl::Create(); + bool nwjs = parsed_command_line.HasSwitch(switches::kNWJS); + + if (nwjs) + nw::LoadNodeSymbols(); + #if defined(OS_MACOSX) base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool; #endif // OS_MACOSX @@ -133,12 +140,25 @@ int RendererMain(const MainFunctionParams& parameters) { // As long as scrollbars on Mac are painted with Cocoa, the message pump // needs to be backed by a Foundation-level loop to process NSTimers. See // http://crbug.com/306348#c24 for details. - std::unique_ptr pump(new base::MessagePumpNSRunLoop()); + base::MessagePump* p; + if (nwjs) { + p = new base::MessagePumpUVNSRunLoop(); + } else + p = new base::MessagePumpNSRunLoop(); + std::unique_ptr pump(p); std::unique_ptr main_message_loop( new base::MessageLoop(std::move(pump))); #else - // The main message loop of the renderer services doesn't have IO or UI tasks. - std::unique_ptr main_message_loop(new base::MessageLoop()); + // The main message loop of the renderer services doesn't have IO or + // UI tasks. + base::MessageLoop* msg_loop; + if (nwjs) { + std::unique_ptr pump_uv(new base::MessagePumpUV()); + msg_loop = new base::MessageLoop(std::move(pump_uv)); + } else + msg_loop = new base::MessageLoop(base::MessageLoop::TYPE_DEFAULT); + + std::unique_ptr main_message_loop(msg_loop); #endif base::PlatformThread::SetName("CrRendererMain"); diff --git a/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.cc b/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.cc index 4033699b539d7..7e85f24d50851 100644 --- a/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.cc +++ b/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.cc @@ -26,6 +26,7 @@ namespace app_current_window_internal = namespace Show = app_current_window_internal::Show; namespace SetBounds = app_current_window_internal::SetBounds; namespace SetSizeConstraints = app_current_window_internal::SetSizeConstraints; +namespace SetResizable = app_current_window_internal::SetResizable; namespace SetIcon = app_current_window_internal::SetIcon; namespace SetShape = app_current_window_internal::SetShape; namespace SetAlwaysOnTop = app_current_window_internal::SetAlwaysOnTop; @@ -256,6 +257,16 @@ bool AppCurrentWindowInternalSetBoundsFunction::RunWithWindow( return true; } +bool AppCurrentWindowInternalSetResizableFunction::RunWithWindow( + AppWindow* window) { + std::unique_ptr params( + SetResizable::Params::Create(*args_)); + CHECK(params.get()); + window->GetBaseWindow()->SetResizable(params->flag); + window->OnNativeWindowChanged(); + return true; +} + bool AppCurrentWindowInternalSetSizeConstraintsFunction::RunWithWindow( AppWindow* window) { std::unique_ptr params( diff --git a/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.h b/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.h index 7d9e784792e57..e1d48d14107a1 100644 --- a/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.h +++ b/extensions/browser/api/app_current_window_internal/app_current_window_internal_api.h @@ -141,6 +141,16 @@ class AppCurrentWindowInternalSetSizeConstraintsFunction bool RunWithWindow(AppWindow* window) override; }; +class AppCurrentWindowInternalSetResizableFunction + : public AppCurrentWindowInternalExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("app.currentWindowInternal.setResizable", + UNKNOWN) + protected: + ~AppCurrentWindowInternalSetResizableFunction() override {} + bool RunWithWindow(AppWindow* window) override; +}; + class AppCurrentWindowInternalSetIconFunction : public AppCurrentWindowInternalExtensionFunction { public: diff --git a/extensions/browser/api/app_window/app_window_api.cc b/extensions/browser/api/app_window/app_window_api.cc index e5dd713972400..c942774e7cfe5 100644 --- a/extensions/browser/api/app_window/app_window_api.cc +++ b/extensions/browser/api/app_window/app_window_api.cc @@ -35,9 +35,15 @@ #include "ui/gfx/geometry/rect.h" #include "url/gurl.h" +#include "content/nw/src/nw_base.h" +#include "content/nw/src/nw_content.h" + namespace app_window = extensions::api::app_window; namespace Create = app_window::Create; +namespace content { + extern bool g_support_transparency; +} namespace extensions { namespace app_window_constants { @@ -52,8 +58,8 @@ const char kConflictingBoundsOptions[] = "The $1 property cannot be specified for both inner and outer bounds."; const char kAlwaysOnTopPermission[] = "The \"app.window.alwaysOnTop\" permission is required."; -const char kInvalidUrlParameter[] = - "The URL used for window creation must be local for security reasons."; +// const char kInvalidUrlParameter[] = +// "The URL used for window creation must be local for security reasons."; const char kAlphaEnabledWrongChannel[] = "The alphaEnabled option requires dev channel or newer."; const char kAlphaEnabledMissingPermission[] = @@ -137,6 +143,10 @@ bool AppWindowCreateFunction::RunAsync() { // path. // TODO(devlin): Investigate if this is still used. If not, kill it dead! GURL absolute = GURL(params->url); + + if (absolute.has_scheme()) + url = absolute; +#if 0 if (absolute.has_scheme()) { if (extension()->location() == Manifest::COMPONENT) { url = absolute; @@ -146,13 +156,27 @@ bool AppWindowCreateFunction::RunAsync() { return false; } } - +#endif // TODO(jeremya): figure out a way to pass the opening WebContents through to // AppWindow::Create so we can set the opener at create time rather than // with a hack in AppWindowCustomBindings::GetView(). AppWindow::CreateParams create_params; app_window::CreateWindowOptions* options = params->options.get(); if (options) { + if (options->title.get()) + create_params.title = *options->title; + + if (options->icon.get()) { + base::ThreadRestrictions::ScopedAllowIO allow_io; + gfx::Image app_icon; + nw::Package* package = nw::package(); + if (nw::GetPackageImage(package, + base::FilePath::FromUTF8Unsafe(*options->icon), + &app_icon)) { + create_params.icon = app_icon; + } + } + if (options->id.get()) { // TODO(mek): use URL if no id specified? // Limit length of id to 256 characters. @@ -289,6 +313,8 @@ bool AppWindowCreateFunction::RunAsync() { #else // Transparency is only supported on Aura. // Fallback to creating an opaque window (by ignoring alphaEnabled). + if (content::g_support_transparency) + create_params.alpha_enabled = *options->alpha_enabled; #endif } @@ -317,6 +343,22 @@ bool AppWindowCreateFunction::RunAsync() { *options->visible_on_all_workspaces.get(); } + if (options->show_in_taskbar.get()) { + create_params.show_in_taskbar = *options->show_in_taskbar.get(); + } + + if (options->new_instance.get()) { + create_params.new_instance = *options->new_instance.get(); + } + + if (options->inject_js_start.get()) { + create_params.inject_js_start = + *options->inject_js_start.get(); + } + if (options->inject_js_end.get()) { + create_params.inject_js_end = + *options->inject_js_end.get(); + } if (options->type != app_window::WINDOW_TYPE_PANEL) { switch (options->state) { case app_window::STATE_NONE: @@ -335,19 +377,40 @@ bool AppWindowCreateFunction::RunAsync() { } } + switch (options->position) { + case app_window::POSITION_NONE: + create_params.position = extensions::AppWindow::POS_NONE; + break; + case app_window::POSITION_CENTER: + create_params.position = extensions::AppWindow::POS_CENTER; + break; + case app_window::POSITION_MOUSE: + create_params.position = extensions::AppWindow::POS_MOUSE; + break; + } + create_params.creator_process_id = render_frame_host()->GetProcess()->GetID(); + if (create_params.new_instance) + nw::SetPinningRenderer(false); + AppWindow* app_window = AppWindowClient::Get()->CreateAppWindow(browser_context(), extension()); app_window->Init(url, new AppWindowContentsImpl(app_window), render_frame_host(), create_params); + if (create_params.new_instance) + nw::SetPinningRenderer(true); + if (ExtensionsBrowserClient::Get()->IsRunningInForcedAppMode() && !app_window->is_ime_window()) { app_window->ForcedFullscreen(); } + if (options && options->kiosk.get()) + app_window->ForcedFullscreen(); + content::RenderFrameHost* created_frame = app_window->web_contents()->GetMainFrame(); int frame_id = MSG_ROUTING_NONE; diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc index f1ffb063ee922..8849f9dd66b81 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc @@ -770,6 +770,24 @@ bool WebViewInternalLoadDataWithBaseUrlFunction::RunAsyncSafe( return successful; } +WebViewInternalShowDevToolsFunction::WebViewInternalShowDevToolsFunction() { +} + +WebViewInternalShowDevToolsFunction::~WebViewInternalShowDevToolsFunction() { +} + +bool WebViewInternalShowDevToolsFunction::RunAsyncSafe(WebViewGuest* guest) { + std::unique_ptr params( + web_view_internal::ShowDevTools::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + int proc_id = params->proc_id ? *params->proc_id : -1; + int guest_id = params->guest_id ? *params->guest_id : -1; + guest->ShowDevTools(params->show, proc_id, guest_id); + SendResponse(true); + return true; +} + WebViewInternalGoFunction::WebViewInternalGoFunction() { } diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h index 54156f16f3210..976b0e26b3ed8 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h @@ -356,6 +356,22 @@ class WebViewInternalLoadDataWithBaseUrlFunction DISALLOW_COPY_AND_ASSIGN(WebViewInternalLoadDataWithBaseUrlFunction); }; +class WebViewInternalShowDevToolsFunction + : public WebViewInternalExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("webViewInternal.showDevTools", UNKNOWN); + + WebViewInternalShowDevToolsFunction(); + + protected: + ~WebViewInternalShowDevToolsFunction() override; + + private: + bool RunAsyncSafe(WebViewGuest* guest) override; + + DISALLOW_COPY_AND_ASSIGN(WebViewInternalShowDevToolsFunction); +}; + class WebViewInternalGoFunction : public WebViewInternalExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("webViewInternal.go", WEBVIEWINTERNAL_GO); diff --git a/extensions/browser/app_window/app_web_contents_helper.cc b/extensions/browser/app_window/app_web_contents_helper.cc index 72b1376af4b73..4b730f9d249b5 100644 --- a/extensions/browser/app_window/app_web_contents_helper.cc +++ b/extensions/browser/app_window/app_web_contents_helper.cc @@ -45,13 +45,30 @@ content::WebContents* AppWebContentsHelper::OpenURLFromTab( // navigations, which we don't want to allow. // TOOD(mihaip): Can we check for user gestures instead? WindowOpenDisposition disposition = params.disposition; + if (disposition == CURRENT_TAB) { - web_contents_->GetMainFrame()->AddMessageToConsole( + if (GetExtension()->is_nwjs_app()) { + content::NavigationController::LoadURLParams load_url_params(params.url); + load_url_params.source_site_instance = params.source_site_instance; + load_url_params.referrer = params.referrer; + load_url_params.frame_tree_node_id = params.frame_tree_node_id; + load_url_params.redirect_chain = params.redirect_chain; + load_url_params.transition_type = params.transition; + load_url_params.extra_headers = params.extra_headers; + load_url_params.should_replace_current_entry = + params.should_replace_current_entry; + load_url_params.is_renderer_initiated = params.is_renderer_initiated; + + web_contents_->GetController().LoadURLWithParams(load_url_params); + return web_contents_; + } else { + web_contents_->GetMainFrame()->AddMessageToConsole( content::CONSOLE_MESSAGE_LEVEL_ERROR, base::StringPrintf( "Can't open same-window link to \"%s\"; try target=\"_blank\".", params.url.spec().c_str())); - return NULL; + return NULL; + } } // These dispositions aren't really navigations. diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc index 491332212f3c2..e510b0a1db38e 100644 --- a/extensions/browser/app_window/app_window.cc +++ b/extensions/browser/app_window/app_window.cc @@ -4,6 +4,8 @@ #include "extensions/browser/app_window/app_window.h" +#include "components/web_cache/browser/web_cache_manager.h" +#include "content/public/browser/render_process_host.h" #include #include @@ -62,12 +64,32 @@ #include "extensions/browser/pref_names.h" #endif +#include "extensions/browser/extension_host.h" +#include "extensions/common/extension_messages.h" + +#include "content/public/browser/render_frame_host.h" +#include "content/public/common/renderer_preferences.h" + +#include "extensions/browser/process_manager.h" +#include "extensions/browser/app_window/app_window_contents.h" +#include "extensions/browser/event_router.h" + +#include "content/nw/src/nw_base.h" +#include "content/nw/src/nw_content.h" +#include "content/nw/src/common/shell_switches.h" + + using content::BrowserContext; using content::ConsoleMessageLevel; using content::WebContents; using web_modal::WebContentsModalDialogHost; using web_modal::WebContentsModalDialogManager; +namespace content { + extern bool g_support_transparency; + extern bool g_force_cpu_draw; +} + namespace extensions { namespace { @@ -172,7 +194,10 @@ AppWindow::CreateParams::CreateParams() resizable(true), focused(true), always_on_top(false), - visible_on_all_workspaces(false) { + visible_on_all_workspaces(false), + skip_load(false), + show_in_taskbar(true), + new_instance(false) { } AppWindow::CreateParams::CreateParams(const CreateParams& other) = default; @@ -240,7 +265,7 @@ gfx::Size AppWindow::CreateParams::GetWindowMaximumSize( AppWindow::AppWindow(BrowserContext* context, AppDelegate* app_delegate, const Extension* extension) - : browser_context_(context), + : menu_(nullptr), browser_context_(context), extension_id_(extension->id()), window_type_(WINDOW_TYPE_DEFAULT), app_delegate_(app_delegate), @@ -254,19 +279,52 @@ AppWindow::AppWindow(BrowserContext* context, cached_always_on_top_(false), requested_alpha_enabled_(false), is_ime_window_(false), + last_to_different_document_(false), image_loader_ptr_factory_(this) { ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); CHECK(!client->IsGuestSession(context) || context->IsOffTheRecord()) << "Only off the record window may be opened in the guest mode."; } +void AppWindow::LoadingStateChanged(content::WebContents* source, bool to_different_document) { + base::ListValue args; + if (source->IsLoading()) { + args.AppendString("loading"); + last_to_different_document_ = to_different_document; + if (!to_different_document) //NWJS#5001 + return; + } else { + if (!last_to_different_document_) + return; + args.AppendString("loaded"); + } + content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); + rfh->Send(new ExtensionMsg_MessageInvoke(rfh->GetRoutingID(), + extension_id(), + "nw.Window", + "LoadingStateChanged", + args, + false)); +} + void AppWindow::Init(const GURL& url, AppWindowContents* app_window_contents, content::RenderFrameHost* creator_frame, const CreateParams& params) { // Initialize the render interface and web contents app_window_contents_.reset(app_window_contents); - app_window_contents_->Initialize(browser_context(), creator_frame, url); + app_window_contents_->Initialize(browser_context(), creator_frame, url, GetExtension()); + + nw::Package* package = nw::package(); + std::string js_doc_start(params.inject_js_start), js_doc_end(params.inject_js_end); + if (js_doc_start.empty()) + package->root()->GetString(::switches::kmInjectJSDocStart, &js_doc_start); + web_contents()->GetMutableRendererPrefs()->nw_inject_js_doc_start = js_doc_start; + if (js_doc_end.empty()) + package->root()->GetString(::switches::kmInjectJSDocEnd, &js_doc_end); + web_contents()->GetMutableRendererPrefs()->nw_inject_js_doc_end = js_doc_end; + if (!js_doc_start.empty() || !js_doc_end.empty()) + web_contents()->GetRenderViewHost()->SyncRendererPrefs(); initial_url_ = url; @@ -290,8 +348,22 @@ void AppWindow::Init(const GURL& url, // Windows cannot be always-on-top in fullscreen mode for security reasons. cached_always_on_top_ = new_params.always_on_top; - if (new_params.state == ui::SHOW_STATE_FULLSCREEN) - new_params.always_on_top = false; + //if (new_params.state == ui::SHOW_STATE_FULLSCREEN) + // new_params.always_on_top = false; + + title_override_ = new_params.title; + app_icon_ = new_params.icon; + + content::g_support_transparency = !base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kDisableTransparency); + if (content::g_support_transparency) { + content::g_force_cpu_draw = base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kForceCpuDraw); + if (content::g_force_cpu_draw) { + if (!base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kDisableGpu)) { + content::g_force_cpu_draw = false; + LOG(WARNING) << "switch " << ::switches::kForceCpuDraw << " must be used with switch " << ::switches::kDisableGpu; + } + } + } requested_alpha_enabled_ = new_params.alpha_enabled; @@ -326,6 +398,9 @@ void AppWindow::Init(const GURL& url, Minimize(); } + if (!new_params.show_in_taskbar) + SetShowInTaskbar(false); + OnNativeWindowChanged(); ExtensionRegistry::Get(browser_context_)->AddObserver(this); @@ -335,7 +410,8 @@ void AppWindow::Init(const GURL& url, base::Bind(&NativeAppWindow::Close, base::Unretained(native_app_window_.get()))); - app_window_contents_->LoadContents(new_params.creator_process_id); + if (!params.skip_load) + app_window_contents_->LoadContents(new_params.creator_process_id); if (base::CommandLine::ForCurrentProcess()->HasSwitch( extensions::switches::kEnableAppsShowOnFirstPaint)) { @@ -381,12 +457,25 @@ void AppWindow::AddNewContents(WebContents* source, bool user_gesture, bool* was_blocked) { DCHECK(new_contents->GetBrowserContext() == browser_context_); - app_delegate_->AddNewContents(browser_context_, - new_contents, - disposition, - initial_rect, - user_gesture, - was_blocked); + const extensions::Extension* extension = GetExtension(); + extensions::AppWindow* app_window = + extensions::AppWindowClient::Get()->CreateAppWindow(browser_context_, extension); + + extensions::AppWindow::CreateParams params; + std::string js_doc_start, js_doc_end; + nw::CalcNewWinParams(new_contents, ¶ms, &js_doc_start, &js_doc_end); + nw::SetCurrentNewWinManifest(base::string16()); + new_contents->GetMutableRendererPrefs()-> + nw_inject_js_doc_start = js_doc_start; + new_contents->GetMutableRendererPrefs()-> + nw_inject_js_doc_end = js_doc_end; + new_contents->GetRenderViewHost()->SyncRendererPrefs(); + + params.skip_load = true; + app_window->Init(new_contents->GetURL(), + new extensions::AppWindowContentsImpl(app_window, new_contents), + web_contents()->GetMainFrame(), + params); } bool AppWindow::PreHandleKeyboardEvent( @@ -419,6 +508,7 @@ bool AppWindow::PreHandleKeyboardEvent( void AppWindow::HandleKeyboardEvent( WebContents* source, const content::NativeWebKeyboardEvent& event) { +#if 0 // If the window is currently fullscreen and not forced, ESC should leave // fullscreen. If this code is being called for ESC, that means that the // KeyEvent's default behavior was not prevented by the content. @@ -427,7 +517,7 @@ void AppWindow::HandleKeyboardEvent( Restore(); return; } - +#endif native_app_window_->HandleKeyboardEvent(event); } @@ -475,6 +565,30 @@ void AppWindow::OnReadyToCommitFirstNavigation() { FROM_HERE, base::ResetAndReturn(&on_first_commit_callback_)); } +bool AppWindow::NWCanClose(bool user_force) const { + const Extension* extension = GetExtension(); + if (!extension) + return true; + content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); + EventRouter* event_router = EventRouter::Get(browser_context()); + std::string listener_extension_id; + bool listening_to_close = event_router-> + ExtensionHasEventListener(extension->id(), "nw.Window.onClose", + rfh->GetRenderViewHost()->GetRoutingID(), + &listener_extension_id); + + if (listening_to_close) { + base::ListValue args; + if (user_force) + args.AppendString("quit"); + rfh->Send(new ExtensionMsg_MessageInvoke( + rfh->GetRoutingID(), listener_extension_id, "nw.Window", + "onClose", args, false)); + return false; + } + return true; +} + void AppWindow::OnNativeClose() { AppWindowRegistry::Get(browser_context_)->RemoveAppWindow(this); if (app_window_contents_) { @@ -508,9 +622,13 @@ void AppWindow::OnNativeWindowChanged() { SaveWindowPosition(); #if defined(OS_WIN) +#if 0 if (cached_always_on_top_ && !IsFullscreen() && !native_app_window_->IsMaximized() && !native_app_window_->IsMinimized()) { +#else + if (cached_always_on_top_) { +#endif UpdateNativeAlwaysOnTop(); } #endif @@ -548,9 +666,11 @@ gfx::Rect AppWindow::GetClientBounds() const { } base::string16 AppWindow::GetTitle() const { + base::string16 override = base::UTF8ToUTF16(title_override_); + const Extension* extension = GetExtension(); if (!extension) - return base::string16(); + return override; // WebContents::GetTitle() will return the page's URL if there's no // specified. However, we'd prefer to show the name of the extension in that @@ -559,12 +679,14 @@ base::string16 AppWindow::GetTitle() const { content::NavigationEntry* entry = web_contents() ? web_contents()->GetController().GetLastCommittedEntry() : nullptr; if (!entry || entry->GetTitle().empty()) { - title = base::UTF8ToUTF16(extension->name()); + title = override.empty() ? base::UTF8ToUTF16(extension->name()) : override; } else { title = web_contents()->GetTitle(); } base::RemoveChars(title, base::ASCIIToUTF16("\n"), &title); - return title; + if (!title.empty()) + return title; + return override; } void AppWindow::SetAppIconUrl(const GURL& url) { @@ -653,6 +775,10 @@ void AppWindow::Restore() { } } +void AppWindow::SetShowInTaskbar(bool show) { + GetBaseWindow()->SetShowInTaskbar(show); +} + void AppWindow::OSFullscreen() { SetFullscreen(FULLSCREEN_TYPE_OS, true); } @@ -727,7 +853,7 @@ void AppWindow::SetAlwaysOnTop(bool always_on_top) { // As a security measure, do not allow fullscreen windows or windows that // overlap the taskbar to be on top. The property will be applied when the // window exits fullscreen and moves away from the taskbar. - if (!IsFullscreen() && !IntersectsWithTaskbar()) + //if (!IsFullscreen() && !IntersectsWithTaskbar()) native_app_window_->SetAlwaysOnTop(always_on_top); OnNativeWindowChanged(); @@ -753,6 +879,8 @@ void AppWindow::NotifyRenderViewReady() { void AppWindow::GetSerializedState(base::DictionaryValue* properties) const { DCHECK(properties); + properties->SetBoolean("resizable", + native_app_window_->IsResizable()); properties->SetBoolean("fullscreen", native_app_window_->IsFullscreenOrPending()); properties->SetBoolean("minimized", native_app_window_->IsMinimized()); @@ -879,6 +1007,9 @@ bool AppWindow::IntersectsWithTaskbar() const { void AppWindow::UpdateNativeAlwaysOnTop() { DCHECK(cached_always_on_top_); +#if 1 + native_app_window_->SetAlwaysOnTop(true); +#else bool is_on_top = native_app_window_->IsAlwaysOnTop(); bool fullscreen = IsFullscreen(); bool intersects_taskbar = IntersectsWithTaskbar(); @@ -892,6 +1023,7 @@ void AppWindow::UpdateNativeAlwaysOnTop() { // always-on-top. native_app_window_->SetAlwaysOnTop(true); } +#endif } void AppWindow::SendOnWindowShownIfShown() { @@ -909,7 +1041,7 @@ void AppWindow::CloseContents(WebContents* contents) { } bool AppWindow::ShouldSuppressDialogs(WebContents* source) { - return true; + return false; } content::ColorChooser* AppWindow::OpenColorChooser( @@ -1123,4 +1255,16 @@ SkRegion* AppWindow::RawDraggableRegionsToSkRegion( return sk_region; } +content::JavaScriptDialogManager* AppWindow::GetJavaScriptDialogManager( + WebContents* source) { + ExtensionHost* host = ProcessManager::Get(browser_context()) + ->GetBackgroundHostForExtension(extension_id()); + return host->GetJavaScriptDialogManager(source); +} + +void AppWindow::WasShown() { + web_cache::WebCacheManager::GetInstance()->ObserveActivity( + web_contents()->GetRenderProcessHost()->GetID()); +} + } // namespace extensions diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h index e503669ab1f47..6145bb87d09ff 100644 --- a/extensions/browser/app_window/app_window.h +++ b/extensions/browser/app_window/app_window.h @@ -38,6 +38,10 @@ class RenderFrameHost; class WebContents; } +namespace nw { +class Menu; +} + namespace extensions { class AppDelegate; @@ -60,7 +64,8 @@ class AppWindowContents { // Called to initialize the WebContents, before the app window is created. virtual void Initialize(content::BrowserContext* context, content::RenderFrameHost* creator_frame, - const GURL& url) = 0; + const GURL& url, + const Extension* extension) = 0; // Called to load the contents, after the app window is created. virtual void LoadContents(int32_t creator_process_id) = 0; @@ -106,6 +111,12 @@ class AppWindow : public content::WebContentsDelegate, FRAME_NONE, // Frameless window. }; + enum Position { + POS_NONE, + POS_CENTER, + POS_MOUSE, + }; + enum FullscreenType { // Not fullscreen. FULLSCREEN_TYPE_NONE = 0, @@ -190,6 +201,18 @@ class AppWindow : public content::WebContentsDelegate, // If true, the window will be visible on all workspaces. Defaults to false. bool visible_on_all_workspaces; + bool skip_load; + + bool show_in_taskbar; + bool new_instance; + + Position position; + + std::string title; + + std::string inject_js_start, inject_js_end; + + gfx::Image icon; // The API enables developers to specify content or window bounds. This // function combines them into a single, constrained window size. @@ -238,11 +261,15 @@ class AppWindow : public content::WebContentsDelegate, const GURL& app_icon_url() const { return app_icon_url_; } const GURL& initial_url() const { return initial_url_; } bool is_hidden() const { return is_hidden_; } - + const std::string& title_override() const { return title_override_; } + void set_title_override(const std::string& title) { title_override_ = title; } + const Extension* GetExtension() const; NativeAppWindow* GetBaseWindow(); gfx::NativeWindow GetNativeWindow(); + bool NWCanClose(bool user_force = false) const; + // Returns the bounds that should be reported to the renderer. gfx::Rect GetClientBounds() const; @@ -306,6 +333,8 @@ class AppWindow : public content::WebContentsDelegate, void Minimize(); void Restore(); + void SetShowInTaskbar(bool); + // Transitions to OS fullscreen. See FULLSCREEN_TYPE_OS for more details. void OSFullscreen(); @@ -372,6 +401,7 @@ class AppWindow : public content::WebContentsDelegate, std::unique_ptr<AppWindowContents> contents) { app_window_contents_ = std::move(contents); } + nw::Menu* menu_; protected: ~AppWindow() override; @@ -381,6 +411,10 @@ class AppWindow : public content::WebContentsDelegate, friend class PlatformAppBrowserTest; // content::WebContentsDelegate implementation. + void LoadingStateChanged(content::WebContents* source, + bool to_different_document) override; + content::JavaScriptDialogManager* GetJavaScriptDialogManager( + content::WebContents* source) override; void CloseContents(content::WebContents* contents) override; bool ShouldSuppressDialogs(content::WebContents* source) override; content::ColorChooser* OpenColorChooser( @@ -432,6 +466,7 @@ class AppWindow : public content::WebContentsDelegate, // content::WebContentsObserver implementation. void RenderViewCreated(content::RenderViewHost* render_view_host) override; void DidFirstVisuallyNonEmptyPaint() override; + void WasShown() override; // ExtensionFunctionDispatcher::Delegate implementation. WindowController* GetExtensionWindowController() const override; @@ -500,6 +535,8 @@ class AppWindow : public content::WebContentsDelegate, // not own this object. content::BrowserContext* browser_context_; + std::string title_override_; + const std::string extension_id_; // Identifier that is used when saving and restoring geometry for this @@ -566,6 +603,7 @@ class AppWindow : public content::WebContentsDelegate, // Whether |is_ime_window| was set in the CreateParams. bool is_ime_window_; + bool last_to_different_document_; // PlzNavigate: this is called when the first navigation is ready to commit. base::Closure on_first_commit_callback_; diff --git a/extensions/browser/app_window/app_window_contents.cc b/extensions/browser/app_window/app_window_contents.cc index 3cb0cb850de3f..c2e22486557df 100644 --- a/extensions/browser/app_window/app_window_contents.cc +++ b/extensions/browser/app_window/app_window_contents.cc @@ -19,27 +19,36 @@ #include "extensions/browser/app_window/native_app_window.h" #include "extensions/common/extension_messages.h" +#include "content/nw/src/nw_content.h" + namespace extensions { -AppWindowContentsImpl::AppWindowContentsImpl(AppWindow* host) - : host_(host), is_blocking_requests_(false), is_window_ready_(false) {} +AppWindowContentsImpl::AppWindowContentsImpl(AppWindow* host, content::WebContents* web_contents) + :host_(host), is_blocking_requests_(false), is_window_ready_(false), web_contents_(web_contents) {} AppWindowContentsImpl::~AppWindowContentsImpl() {} void AppWindowContentsImpl::Initialize(content::BrowserContext* context, content::RenderFrameHost* creator_frame, - const GURL& url) { + const GURL& url, + const Extension* extension) { url_ = url; content::WebContents::CreateParams create_params( - context, creator_frame->GetSiteInstance()); + context, nw::PinningRenderer() ? creator_frame->GetSiteInstance() : content::SiteInstance::CreateForURL(context, url_)); create_params.opener_render_process_id = creator_frame->GetProcess()->GetID(); create_params.opener_render_frame_id = creator_frame->GetRoutingID(); - web_contents_.reset(content::WebContents::Create(create_params)); + if (!web_contents_) + web_contents_.reset(content::WebContents::Create(create_params)); Observe(web_contents_.get()); - web_contents_->GetMutableRendererPrefs()-> - browser_handles_all_top_level_requests = true; + content::RendererPreferences* render_prefs = + web_contents_->GetMutableRendererPrefs(); + if (!extension || !extension->is_nwjs_app()) + render_prefs->browser_handles_all_top_level_requests = true; + std::string user_agent; + if (nw::GetUserAgentFromManifest(&user_agent)) + render_prefs->user_agent_override = user_agent; web_contents_->GetRenderViewHost()->SyncRendererPrefs(); } diff --git a/extensions/browser/app_window/app_window_contents.h b/extensions/browser/app_window/app_window_contents.h index 85b56c7d62f1d..5d2f5bafbcc4f 100644 --- a/extensions/browser/app_window/app_window_contents.h +++ b/extensions/browser/app_window/app_window_contents.h @@ -17,6 +17,7 @@ namespace content { class BrowserContext; class RenderFrameHost; +class WebContents; } namespace extensions { @@ -29,13 +30,14 @@ struct DraggableRegion; class AppWindowContentsImpl : public AppWindowContents, public content::WebContentsObserver { public: - explicit AppWindowContentsImpl(AppWindow* host); + explicit AppWindowContentsImpl(AppWindow* host, content::WebContents* web_contents = nullptr); ~AppWindowContentsImpl() override; // AppWindowContents void Initialize(content::BrowserContext* context, content::RenderFrameHost* creator_frame, - const GURL& url) override; + const GURL& url, + const Extension* extension) override; void LoadContents(int32_t creator_process_id) override; void NativeWindowChanged(NativeAppWindow* native_app_window) override; void NativeWindowClosed() override; @@ -54,10 +56,12 @@ class AppWindowContentsImpl : public AppWindowContents, AppWindow* host_; // This class is owned by |host_| GURL url_; - std::unique_ptr<content::WebContents> web_contents_; + bool is_blocking_requests_; bool is_window_ready_; + std::unique_ptr<content::WebContents> web_contents_; + DISALLOW_COPY_AND_ASSIGN(AppWindowContentsImpl); }; diff --git a/extensions/browser/app_window/app_window_registry.cc b/extensions/browser/app_window/app_window_registry.cc index 6fc0dedccfabd..659ad7aefa541 100644 --- a/extensions/browser/app_window/app_window_registry.cc +++ b/extensions/browser/app_window/app_window_registry.cc @@ -112,12 +112,13 @@ AppWindowRegistry::AppWindowList AppWindowRegistry::GetAppWindowsForApp( return app_windows; } -void AppWindowRegistry::CloseAllAppWindowsForApp(const std::string& app_id) { +void AppWindowRegistry::CloseAllAppWindowsForApp(const std::string& app_id, bool user_force) { const AppWindowList windows = GetAppWindowsForApp(app_id); for (AppWindowRegistry::const_iterator it = windows.begin(); it != windows.end(); ++it) { - (*it)->GetBaseWindow()->Close(); + if ((*it)->NWCanClose(user_force)) + (*it)->GetBaseWindow()->Close(); } } diff --git a/extensions/browser/app_window/app_window_registry.h b/extensions/browser/app_window/app_window_registry.h index d273fbb131c14..90a6401afccee 100644 --- a/extensions/browser/app_window/app_window_registry.h +++ b/extensions/browser/app_window/app_window_registry.h @@ -80,7 +80,7 @@ class AppWindowRegistry : public KeyedService { const AppWindowList& app_windows() const { return app_windows_; } // Close all app windows associated with an app. - void CloseAllAppWindowsForApp(const std::string& app_id); + void CloseAllAppWindowsForApp(const std::string& app_id, bool user_force = false); // Helper functions to find app windows with particular attributes. AppWindow* GetAppWindowForWebContents( diff --git a/extensions/browser/app_window/native_app_window.h b/extensions/browser/app_window/native_app_window.h index 943efdc75860f..368ca2b21721b 100644 --- a/extensions/browser/app_window/native_app_window.h +++ b/extensions/browser/app_window/native_app_window.h @@ -31,6 +31,8 @@ class NativeAppWindow : public ui::BaseWindow, // |fullscreen_types| is a bit field of AppWindow::FullscreenType. virtual void SetFullscreen(int fullscreen_types) = 0; + virtual void SetResizable(bool flag) = 0; + virtual bool IsResizable() const = 0; // Returns whether the window is fullscreen or about to enter fullscreen. virtual bool IsFullscreenOrPending() const = 0; @@ -75,6 +77,8 @@ class NativeAppWindow : public ui::BaseWindow, virtual void ShowWithApp() = 0; virtual void HideWithApp() = 0; + virtual void SetShowInTaskbar(bool) = 0; + // Returns the minimum size constraints of the content. virtual gfx::Size GetContentMinimumSize() const = 0; diff --git a/extensions/browser/content_hash_fetcher.cc b/extensions/browser/content_hash_fetcher.cc index 678cf5f659c6c..dbad8707666a9 100644 --- a/extensions/browser/content_hash_fetcher.cc +++ b/extensions/browser/content_hash_fetcher.cc @@ -225,8 +225,10 @@ bool ContentHashFetcherJob::LoadVerifiedContents(const base::FilePath& path) { verified_contents_.reset(new VerifiedContents(key_.data, key_.size)); if (!verified_contents_->InitFrom(path, false)) { verified_contents_.reset(); +#if 0 if (!base::DeleteFile(path, false)) LOG(WARNING) << "Failed to delete " << path.value(); +#endif return false; } return true; @@ -239,7 +241,9 @@ void ContentHashFetcherJob::DoneCheckingForVerifiedContents(bool found) { VLOG(1) << "Found verified contents for " << extension_id_; DoneFetchingVerifiedContents(true); } else { - VLOG(1) << "Missing verified contents for " << extension_id_ + VLOG(1) << "Missing verified contents for " << extension_id_; + DoneFetchingVerifiedContents(false); +#if 0 << ", fetching..."; url_fetcher_ = net::URLFetcher::Create(fetch_url_, net::URLFetcher::GET, this); @@ -249,6 +253,7 @@ void ContentHashFetcherJob::DoneCheckingForVerifiedContents(bool found) { net::LOAD_DISABLE_CACHE); url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); url_fetcher_->Start(); +#endif } } @@ -399,7 +404,7 @@ bool ContentHashFetcherJob::CreateHashes(const base::FilePath& hashes_file) { std::string root = ComputeTreeHashRoot(hashes, block_size_ / crypto::kSHA256Length); if (!verified_contents_->TreeHashRootEquals(relative_path, root)) { - VLOG(1) << "content mismatch for " << relative_path.AsUTF8Unsafe(); + LOG(INFO) << "content mismatch for " << relative_path.AsUTF8Unsafe(); hash_mismatch_paths_.insert(relative_path); continue; } diff --git a/extensions/browser/content_hash_reader.cc b/extensions/browser/content_hash_reader.cc index f1a39a6c9bbc3..7b482e48c1e79 100644 --- a/extensions/browser/content_hash_reader.cc +++ b/extensions/browser/content_hash_reader.cc @@ -63,9 +63,9 @@ bool ContentHashReader::Init() { verified_contents_.reset(new VerifiedContents(key_.data, key_.size)); if (!verified_contents_->InitFrom(verified_contents_path, false) || - !verified_contents_->valid_signature() || - verified_contents_->version() != extension_version_ || - verified_contents_->extension_id() != extension_id_) + !verified_contents_->valid_signature()) + //verified_contents_->version() != extension_version_ || + // verified_contents_->extension_id() != extension_id_) return false; have_verified_contents_ = true; diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc index c47db07826f2f..9be8f31b4415f 100644 --- a/extensions/browser/content_verifier.cc +++ b/extensions/browser/content_verifier.cc @@ -19,6 +19,9 @@ #include "extensions/common/constants.h" #include "extensions/common/extension_l10n_util.h" +#include "base/files/file_util.h" +#include "base/threading/thread_restrictions.h" + namespace extensions { namespace { @@ -111,22 +114,74 @@ ContentVerifyJob* ContentVerifier::CreateJobFor( return new ContentVerifyJob( new ContentHashReader(extension_id, data->version, extension_root, normalized_path, delegate_->GetPublicKey()), - base::Bind(&ContentVerifier::VerifyFailed, this, extension_id)); + base::Bind(&ContentVerifier::VerifyFailed, this, extension_id, relative_path), + base::Bind(&ContentVerifier::OnHashReady, this, extension_id, extension_root, relative_path)); +} + +void ContentVerifier::OnHashReady(const std::string& extension_id, + const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* verify_job) { + content::BrowserThread::GetBlockingPool()->PostTaskAndReply( + FROM_HERE, + base::Bind(&ContentVerifier::OpenFile, this, extension_root, relative_path, verify_job), + base::Bind(&ContentVerifier::OnFileReady, this, extension_root, relative_path, verify_job)); +} + +void ContentVerifier::OpenFile(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job) { + job->file_.Initialize(extension_root.Append(relative_path), base::File::FLAG_OPEN | base::File::FLAG_READ); +} + +void ContentVerifier::OnFileReady(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job) { + if (!job->file_.IsValid()) + job->DoneReading(); + + content::BrowserThread::GetBlockingPool()->PostTaskAndReply( + FROM_HERE, + base::Bind(&ContentVerifier::ReadFile, this, extension_root, relative_path, job), + base::Bind(&ContentVerifier::BytesRead, this, extension_root, relative_path, job)); +} +void ContentVerifier::ReadFile(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job) { + job->len_ = job->file_.ReadAtCurrentPos(job->buf_, 32768); + if (job->len_ <= 0) + job->file_.Close(); +} + +void ContentVerifier::BytesRead(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job) { + if (job->len_ <= 0) { + job->DoneReading(); + } else { + job->BytesRead(job->len_, job->buf_); + content::BrowserThread::GetBlockingPool()->PostTaskAndReply( + FROM_HERE, + base::Bind(&ContentVerifier::ReadFile, this, extension_root, relative_path, job), + base::Bind(&ContentVerifier::BytesRead, this, extension_root, relative_path, job)); + } } void ContentVerifier::VerifyFailed(const std::string& extension_id, - ContentVerifyJob::FailureReason reason) { + const base::FilePath& relative_path, + ContentVerifyJob::FailureReason reason, + ContentVerifyJob* verify_job) { if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, - base::Bind(&ContentVerifier::VerifyFailed, this, extension_id, reason)); + base::Bind(&ContentVerifier::VerifyFailed, this, extension_id, relative_path, reason, verify_job)); return; } if (shutdown_) return; - VLOG(1) << "VerifyFailed " << extension_id << " reason:" << reason; + VLOG(1) << "VerifyFailed " << extension_id << " reason:" << reason << " " << relative_path.AsUTF8Unsafe(); ExtensionRegistry* registry = ExtensionRegistry::Get(context_); const Extension* extension = @@ -135,12 +190,17 @@ void ContentVerifier::VerifyFailed(const std::string& extension_id, if (!extension) return; + ContentVerifierDelegate::Mode mode = delegate_->ShouldBeVerified(*extension); + if (mode < ContentVerifierDelegate::ENFORCE) { + if (!verify_job->success_callback().is_null()) + verify_job->success_callback().Run(); + } if (reason == ContentVerifyJob::MISSING_ALL_HASHES) { // If we failed because there were no hashes yet for this extension, just // request some. fetcher_->DoFetch(extension, true /* force */); } else { - delegate_->VerifyFailed(extension_id, reason); + delegate_->VerifyFailed(extension_id, relative_path, reason); } } @@ -196,7 +256,7 @@ void ContentVerifier::OnExtensionUnloaded( void ContentVerifier::OnFetchCompleteHelper(const std::string& extension_id, bool shouldVerifyAnyPathsResult) { if (shouldVerifyAnyPathsResult) - delegate_->VerifyFailed(extension_id, ContentVerifyJob::MISSING_ALL_HASHES); + delegate_->VerifyFailed(extension_id, base::FilePath(), ContentVerifyJob::MISSING_ALL_HASHES); } void ContentVerifier::OnFetchComplete( @@ -223,7 +283,7 @@ void ContentVerifier::OnFetchComplete( mode == ContentVerifierDelegate::ENFORCE_STRICT) { // We weren't able to get verified_contents.json or weren't able to compute // hashes. - delegate_->VerifyFailed(extension_id, ContentVerifyJob::MISSING_ALL_HASHES); + delegate_->VerifyFailed(extension_id, base::FilePath(), ContentVerifyJob::MISSING_ALL_HASHES); } else { content::BrowserThread::PostTaskAndReplyWithResult( content::BrowserThread::IO, diff --git a/extensions/browser/content_verifier.h b/extensions/browser/content_verifier.h index 83707bbc04c91..b1ce7e0ce94c6 100644 --- a/extensions/browser/content_verifier.h +++ b/extensions/browser/content_verifier.h @@ -59,7 +59,25 @@ class ContentVerifier : public base::RefCountedThreadSafe<ContentVerifier>, // Called (typically by a verification job) to indicate that verification // failed while reading some file in |extension_id|. void VerifyFailed(const std::string& extension_id, - ContentVerifyJob::FailureReason reason); + const base::FilePath& relative_path, + ContentVerifyJob::FailureReason reason, + ContentVerifyJob* verify_job); + void OnHashReady(const std::string& extension_id, + const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* verify_job); + void BytesRead(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job); + void ReadFile(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job); + void OpenFile(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job); + void OnFileReady(const base::FilePath& extension_root, + const base::FilePath& relative_path, + ContentVerifyJob* job); // ExtensionRegistryObserver interface void OnExtensionLoaded(content::BrowserContext* browser_context, @@ -105,6 +123,7 @@ class ContentVerifier : public base::RefCountedThreadSafe<ContentVerifier>, // Data that should only be used on the IO thread. scoped_refptr<ContentVerifierIOData> io_data_; + }; } // namespace extensions diff --git a/extensions/browser/content_verifier_delegate.h b/extensions/browser/content_verifier_delegate.h index 5fb72a2617c29..93fece74ee708 100644 --- a/extensions/browser/content_verifier_delegate.h +++ b/extensions/browser/content_verifier_delegate.h @@ -80,6 +80,7 @@ class ContentVerifierDelegate { // Called when the content verifier detects that a read of a file inside // an extension did not match its expected hash. virtual void VerifyFailed(const std::string& extension_id, + const base::FilePath& relative_path, ContentVerifyJob::FailureReason reason) = 0; }; diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc index 701c01d410707..8eda566b3f6ee 100644 --- a/extensions/browser/content_verify_job.cc +++ b/extensions/browser/content_verify_job.cc @@ -50,15 +50,43 @@ ContentVerifyJob::ContentVerifyJob(ContentHashReader* hash_reader, current_hash_byte_count_(0), hash_reader_(hash_reader), failure_callback_(failure_callback), - failed_(false) { + failed_(false), + len_(0), + buf_(nullptr) +{ // It's ok for this object to be constructed on a different thread from where // it's used. thread_checker_.DetachFromThread(); + buf_ = new char[32768]; } +ContentVerifyJob::ContentVerifyJob(ContentHashReader* hash_reader, + const FailureCallback& failure_callback, + const ReadyCallback& ready_callback) + : done_reading_(false), + hashes_ready_(false), + total_bytes_read_(0), + current_block_(0), + current_hash_byte_count_(0), + hash_reader_(hash_reader), + failure_callback_(failure_callback), + ready_callback_(ready_callback), + failed_(false), + len_(0), + buf_(nullptr) +{ + // It's ok for this object to be constructed on a different thread from where + // it's used. + thread_checker_.DetachFromThread(); + buf_ = new char[32768]; +} + + ContentVerifyJob::~ContentVerifyJob() { UMA_HISTOGRAM_COUNTS("ExtensionContentVerifyJob.TimeSpentUS", time_spent_.InMicroseconds()); + delete[] buf_; + buf_ = nullptr; } void ContentVerifyJob::Start() { @@ -140,6 +168,8 @@ void ContentVerifyJob::DoneReading() { else if (g_test_observer) g_test_observer->JobFinished(hash_reader_->extension_id(), hash_reader_->relative_path(), failed_); + else if (!success_callback_.is_null()) + success_callback_.Run(); } } @@ -165,6 +195,8 @@ void ContentVerifyJob::OnHashesReady(bool success) { if (!success && !g_test_delegate) { if (!hash_reader_->content_exists()) { // Ignore verification of non-existent resources. + if (!success_callback_.is_null()) + success_callback_.Run(); return; } else if (hash_reader_->have_verified_contents() && hash_reader_->have_computed_hashes()) { @@ -190,6 +222,9 @@ void ContentVerifyJob::OnHashesReady(bool success) { hash_reader_->relative_path(), failed_); } } + if (!ready_callback_.is_null()) { + ready_callback_.Run(this); + } } // static @@ -209,7 +244,7 @@ void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) { VLOG(1) << "job failed for " << hash_reader_->extension_id() << " " << hash_reader_->relative_path().MaybeAsASCII() << " reason:" << reason; - failure_callback_.Run(reason); + failure_callback_.Run(reason, this); failure_callback_.Reset(); } if (g_test_observer) diff --git a/extensions/browser/content_verify_job.h b/extensions/browser/content_verify_job.h index fc9223026c971..3802f1b91cbc7 100644 --- a/extensions/browser/content_verify_job.h +++ b/extensions/browser/content_verify_job.h @@ -9,6 +9,7 @@ #include <memory> #include <string> +#include "base/files/file.h" #include "base/callback.h" #include "base/macros.h" @@ -49,12 +50,18 @@ class ContentVerifyJob : public base::RefCountedThreadSafe<ContentVerifyJob> { FAILURE_REASON_MAX }; - typedef base::Callback<void(FailureReason)> FailureCallback; + typedef base::Callback<void(FailureReason, ContentVerifyJob*)> FailureCallback; + typedef base::Callback<void(ContentVerifyJob*)> ReadyCallback; + typedef base::Callback<void(void)> SuccessCallback; // The |failure_callback| will be called at most once if there was a failure. ContentVerifyJob(ContentHashReader* hash_reader, const FailureCallback& failure_callback); + ContentVerifyJob(ContentHashReader* hash_reader, + const FailureCallback& failure_callback, + const ReadyCallback& ready_callback); + // This begins the process of getting expected hashes, so it should be called // as early as possible. void Start(); @@ -70,6 +77,9 @@ class ContentVerifyJob : public base::RefCountedThreadSafe<ContentVerifyJob> { // Call once when finished adding bytes via BytesRead. void DoneReading(); + void SetSuccessCallback(const SuccessCallback& success_callback) { success_callback_ = success_callback; } + const SuccessCallback& success_callback() { return success_callback_; } + class TestDelegate { public: // These methods will be called inside BytesRead/DoneReading respectively. @@ -140,10 +150,17 @@ class ContentVerifyJob : public base::RefCountedThreadSafe<ContentVerifyJob> { // Called once if verification fails. FailureCallback failure_callback_; + ReadyCallback ready_callback_; + SuccessCallback success_callback_; // Set to true if we detected a mismatch and called the failure callback. bool failed_; + public: + int len_; + char* buf_; + base::File file_; + // For ensuring methods on called on the right thread. base::ThreadChecker thread_checker_; }; diff --git a/extensions/browser/event_listener_map.cc b/extensions/browser/event_listener_map.cc index 1dc908342b04b..2262c7043aa92 100644 --- a/extensions/browser/event_listener_map.cc +++ b/extensions/browser/event_listener_map.cc @@ -142,17 +142,30 @@ bool EventListenerMap::HasListenerForEvent(const std::string& event_name) { bool EventListenerMap::HasListenerForExtension( const std::string& extension_id, - const std::string& event_name) { + const std::string& event_name, + int instance_id, + std::string* out_extension_id) { ListenerMap::iterator it = listeners_.find(event_name); if (it == listeners_.end()) return false; + EventListener* ret = nullptr; + for (ListenerList::iterator it2 = it->second.begin(); it2 != it->second.end(); it2++) { - if ((*it2)->extension_id() == extension_id) - return true; + if ((*it2)->extension_id() == extension_id || (*it2)->extension_id().empty()) { + int id = -1; + if (instance_id < 0) + ret = it2->get(); + if ((*it2)->filter() && (*it2)->filter()->GetInteger("instanceId", &id) && id == instance_id) + ret = it2->get(); + } } - return false; + if (!ret) + return false; + if (out_extension_id) + *out_extension_id = ret->extension_id(); + return true; } bool EventListenerMap::HasListener(const EventListener* listener) { diff --git a/extensions/browser/event_listener_map.h b/extensions/browser/event_listener_map.h index fe1568edc02dd..d4398f61230ac 100644 --- a/extensions/browser/event_listener_map.h +++ b/extensions/browser/event_listener_map.h @@ -145,7 +145,9 @@ class EventListenerMap { // Returns true if there are any listeners on |event_name| from // |extension_id|. bool HasListenerForExtension(const std::string& extension_id, - const std::string& event_name); + const std::string& event_name, + int instance_id = -1, + std::string* out_extension_id = nullptr); // Returns true if this map contains an EventListener that .Equals() // |listener|. diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc index 6cc2c7b647bca..e4f67d73724fb 100644 --- a/extensions/browser/event_router.cc +++ b/extensions/browser/event_router.cc @@ -359,8 +359,10 @@ bool EventRouter::HasEventListener(const std::string& event_name) { } bool EventRouter::ExtensionHasEventListener(const std::string& extension_id, - const std::string& event_name) { - return listeners_.HasListenerForExtension(extension_id, event_name); + const std::string& event_name, + int instance_id, + std::string* out_extension_id) { + return listeners_.HasListenerForExtension(extension_id, event_name, instance_id, out_extension_id); } bool EventRouter::HasEventListenerImpl(const ListenerMap& listener_map, @@ -613,7 +615,7 @@ void EventRouter::DispatchEventToProcess( Feature::Availability availability = ExtensionAPI::GetSharedInstance()->IsAvailable( event->event_name, extension, target_context, listener_url); - if (!availability.is_available()) { + if (!availability.is_available() && !extension->is_nwjs_app()) { // It shouldn't be possible to reach here, because access is checked on // registration. However, for paranoia, check on dispatch as well. NOTREACHED() << "Trying to dispatch event " << event->event_name @@ -883,12 +885,14 @@ Event::Event(events::HistogramValue histogram_value, user_gesture(user_gesture), filter_info(filter_info) { DCHECK(event_args); +#if 0 DCHECK_NE(events::UNKNOWN, histogram_value) << "events::UNKNOWN cannot be used as a histogram value.\n" << "If this is a test, use events::FOR_TEST.\n" << "If this is production code, it is important that you use a realistic " << "value so that we can accurately track event usage. " << "See extension_event_histogram_value.h for inspiration."; +#endif } Event::~Event() {} diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h index d84385522b31a..aaa06f140486b 100644 --- a/extensions/browser/event_router.h +++ b/extensions/browser/event_router.h @@ -165,7 +165,9 @@ class EventRouter : public KeyedService, // Returns true if the extension is listening to the given event. virtual bool ExtensionHasEventListener(const std::string& extension_id, - const std::string& event_name); + const std::string& event_name, + int instance_id = -1, + std::string* out_extension_id = nullptr); // Return or set the list of events for which the given extension has // registered. diff --git a/extensions/browser/extension_function.cc b/extensions/browser/extension_function.cc index fd7bae96ceb8a..74edcf5c54b5a 100644 --- a/extensions/browser/extension_function.cc +++ b/extensions/browser/extension_function.cc @@ -234,6 +234,10 @@ ExtensionFunction::ExtensionFunction() ExtensionFunction::~ExtensionFunction() { } +bool ExtensionFunction::RunNWSync(base::ListValue* response, std::string* error) { + return false; +} + UIThreadExtensionFunction* ExtensionFunction::AsUIThreadExtensionFunction() { return NULL; } @@ -565,6 +569,23 @@ bool SyncExtensionFunction::ValidationFailure(SyncExtensionFunction* function) { return false; } +NWSyncExtensionFunction::NWSyncExtensionFunction() { +} + +NWSyncExtensionFunction::~NWSyncExtensionFunction() { +} + +ExtensionFunction::ResponseAction NWSyncExtensionFunction::Run() { + NOTREACHED() << "NWSyncExtensionFunction::Run"; + return RespondNow(ArgumentList(std::move(results_))); +} + +// static +bool NWSyncExtensionFunction::ValidationFailure( + NWSyncExtensionFunction* function) { + return false; +} + SyncIOThreadExtensionFunction::SyncIOThreadExtensionFunction() { } diff --git a/extensions/browser/extension_function.h b/extensions/browser/extension_function.h index 0bf876410a02f..b5c5cd9561858 100644 --- a/extensions/browser/extension_function.h +++ b/extensions/browser/extension_function.h @@ -179,6 +179,7 @@ class ExtensionFunction // but this is deprecated. ExtensionFunction implementations are encouraged // to just implement Run. virtual ResponseAction Run() WARN_UNUSED_RESULT = 0; + virtual bool RunNWSync(base::ListValue* response, std::string* error); // Gets whether quota should be applied to this individual function // invocation. This is different to GetQuotaLimitHeuristics which is only @@ -663,6 +664,18 @@ class SyncExtensionFunction : public UIThreadExtensionFunction { DISALLOW_COPY_AND_ASSIGN(SyncExtensionFunction); }; +class NWSyncExtensionFunction : public UIThreadExtensionFunction { + public: + NWSyncExtensionFunction(); + + protected: + ~NWSyncExtensionFunction() override; + static bool ValidationFailure(NWSyncExtensionFunction* function); + private: + ResponseAction Run() final; + +}; + class SyncIOThreadExtensionFunction : public IOThreadExtensionFunction { public: SyncIOThreadExtensionFunction(); diff --git a/extensions/browser/extension_function_dispatcher.cc b/extensions/browser/extension_function_dispatcher.cc index 5f4d0df21cd89..2db5a46915d46 100644 --- a/extensions/browser/extension_function_dispatcher.cc +++ b/extensions/browser/extension_function_dispatcher.cc @@ -97,6 +97,13 @@ void KillBadMessageSender(const base::Process& process, process.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false); } +void DummyCallback( + ExtensionFunction::ResponseType type, + const base::ListValue& results, + const std::string& error, + functions::HistogramValue histogram_value) { +} + void CommonResponseCallback(IPC::Sender* ipc_sender, int routing_id, const base::Process& peer_process, @@ -314,6 +321,18 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() { } +void ExtensionFunctionDispatcher::DispatchSync( + const ExtensionHostMsg_Request_Params& params, + bool* success, + base::ListValue* response, + std::string* error, + content::RenderFrameHost* render_frame_host) { + base::Callback<decltype(DummyCallback)> dummy; + DispatchWithCallbackInternal( + params, render_frame_host, dummy, true, + success, response, error); +} + void ExtensionFunctionDispatcher::Dispatch( const ExtensionHostMsg_Request_Params& params, content::RenderFrameHost* render_frame_host) { @@ -336,7 +355,12 @@ void ExtensionFunctionDispatcher::Dispatch( void ExtensionFunctionDispatcher::DispatchWithCallbackInternal( const ExtensionHostMsg_Request_Params& params, content::RenderFrameHost* render_frame_host, - const ExtensionFunction::ResponseCallback& callback) { + const ExtensionFunction::ResponseCallback& callback, + bool sync, + bool* success, + base::ListValue* response, + std::string* error + ) { DCHECK(render_frame_host); // TODO(yzshen): There is some shared logic between this method and // DispatchOnIOThread(). It is nice to deduplicate. @@ -385,7 +409,11 @@ void ExtensionFunctionDispatcher::DispatchWithCallbackInternal( if (!extension) { // Skip all of the UMA, quota, event page, activity logging stuff if there // isn't an extension, e.g. if the function call was from WebUI. - function->Run()->Execute(); + if (!sync) + function->Run()->Execute(); + else { + *success = function->RunNWSync(response, error); + } return; } @@ -412,7 +440,10 @@ void ExtensionFunctionDispatcher::DispatchWithCallbackInternal( FROM_HERE_WITH_EXPLICIT_FUNCTION(function->name()), tracked_objects::ScopedProfile::ENABLED); base::ElapsedTimer timer; - function->Run()->Execute(); + if (!sync) + function->Run()->Execute(); + else + *success = function->RunNWSync(response, error); // TODO(devlin): Once we have a baseline metric for how long functions take, // we can create a handful of buckets and record the function name so that // we can find what the fastest/slowest are. diff --git a/extensions/browser/extension_function_dispatcher.h b/extensions/browser/extension_function_dispatcher.h index be8132e970e58..eba46d8d7ff96 100644 --- a/extensions/browser/extension_function_dispatcher.h +++ b/extensions/browser/extension_function_dispatcher.h @@ -95,6 +95,11 @@ class ExtensionFunctionDispatcher // Message handlers. // The response is sent to the corresponding render view in an // ExtensionMsg_Response message. + void DispatchSync(const ExtensionHostMsg_Request_Params& params, + bool* success, + base::ListValue* response, + std::string* error, + content::RenderFrameHost* render_frame_host); void Dispatch(const ExtensionHostMsg_Request_Params& params, content::RenderFrameHost* render_frame_host); @@ -152,7 +157,12 @@ class ExtensionFunctionDispatcher void DispatchWithCallbackInternal( const ExtensionHostMsg_Request_Params& params, content::RenderFrameHost* render_frame_host, - const ExtensionFunction::ResponseCallback& callback); + const ExtensionFunction::ResponseCallback& callback, + bool sync = false, + bool* success = nullptr, + base::ListValue* response = nullptr, + std::string* error = nullptr + ); content::BrowserContext* browser_context_; diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc index 5e77c0c250c2e..b5a83526b682c 100644 --- a/extensions/browser/extension_prefs.cc +++ b/extensions/browser/extension_prefs.cc @@ -199,10 +199,12 @@ class ScopedExtensionPrefUpdate : public DictionaryPrefUpdate { base::DictionaryValue* Get() override { base::DictionaryValue* dict = DictionaryPrefUpdate::Get(); base::DictionaryValue* extension = NULL; - if (!dict->GetDictionary(extension_id_, &extension)) { + std::string id; + base::ReplaceChars(extension_id_, ".", "", &id); + if (!dict->GetDictionary(id, &extension)) { // Extension pref does not exist, create it. extension = new base::DictionaryValue(); - dict->SetWithoutPathExpansion(extension_id_, extension); + dict->SetWithoutPathExpansion(id, extension); } return extension; } @@ -232,7 +234,9 @@ void LoadExtensionControlledPrefs(ExtensionPrefs* prefs, std::string scope_string; if (!pref_names::ScopeToPrefName(scope, &scope_string)) return; - std::string key = extension_id + "." + scope_string; + std::string id; + base::ReplaceChars(extension_id, ".", "", &id); + std::string key = id + "." + scope_string; const base::DictionaryValue* source_dict = prefs->pref_service()->GetDictionary(pref_names::kExtensions); @@ -438,11 +442,14 @@ void ExtensionPrefs::MakePathsRelative() { const base::DictionaryValue* ExtensionPrefs::GetExtensionPref( const std::string& extension_id) const { + std::string id; + base::ReplaceChars(extension_id, ".", "", &id); + const base::DictionaryValue* extensions = prefs_->GetDictionary(pref_names::kExtensions); const base::DictionaryValue* extension_dict = NULL; if (!extensions || - !extensions->GetDictionary(extension_id, &extension_dict)) { + !extensions->GetDictionary(id, &extension_dict)) { return NULL; } return extension_dict; diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc index c97f172607acb..6114191608251 100644 --- a/extensions/browser/extension_protocols.cc +++ b/extensions/browser/extension_protocols.cc @@ -37,6 +37,7 @@ #include "content/public/browser/resource_request_info.h" #include "crypto/secure_hash.h" #include "crypto/sha2.h" +#include "extensions/browser/component_extension_resource_manager.h" #include "extensions/browser/content_verifier.h" #include "extensions/browser/content_verify_job.h" #include "extensions/browser/extensions_browser_client.h" @@ -190,6 +191,8 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { resource_(extension_id, directory_path, relative_path), content_security_policy_(content_security_policy), send_cors_header_(send_cors_header), + can_start_(false), + started_(false), weak_factory_(this) { if (follow_symlinks_anywhere) { resource_.set_follow_symlinks_anywhere(); @@ -254,15 +257,27 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { -result); if (result > 0) { bytes_read_ += result; +#if 0 if (verify_job_.get()) { verify_job_->BytesRead(result, buffer->data()); if (!remaining_bytes()) verify_job_->DoneReading(); } +#endif } } - private: + void CanStart() { + can_start_ = true; + if (!started_) { + started_ = true; + URLRequestFileJob::Start(); + } + } + + void set_can_start(bool flag) { can_start_ = flag; } + +private: ~URLRequestExtensionJob() override { UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.TotalKbRead", bytes_read_ / 1024); UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.SeekPosition", seek_position_); @@ -278,7 +293,10 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { content_security_policy_, send_cors_header_, *last_modified_time); - URLRequestFileJob::Start(); + if (can_start_) { + started_ = true; + URLRequestFileJob::Start(); + } } scoped_refptr<ContentVerifyJob> verify_job_; @@ -296,6 +314,7 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { extensions::ExtensionResource resource_; std::string content_security_policy_; bool send_cors_header_; + bool can_start_, started_; base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_; }; @@ -521,11 +540,9 @@ ExtensionProtocolHandler::MaybeCreateJob( if (verifier) { verify_job = verifier->CreateJobFor(extension_id, directory_path, relative_path); - if (verify_job) - verify_job->Start(); } - return new URLRequestExtensionJob(request, + URLRequestExtensionJob* job = new URLRequestExtensionJob(request, network_delegate, extension_id, directory_path, @@ -534,6 +551,13 @@ ExtensionProtocolHandler::MaybeCreateJob( send_cors_header, follow_symlinks_anywhere, verify_job); + if (verify_job) { + verify_job->SetSuccessCallback(base::Bind(&URLRequestExtensionJob::CanStart, base::Unretained(job))); + verify_job->Start(); + } else { + job->set_can_start(true); + } + return job; } } // namespace diff --git a/extensions/browser/extension_web_contents_observer.cc b/extensions/browser/extension_web_contents_observer.cc index e00f7f1a46e14..a1d3834d5dc97 100644 --- a/extensions/browser/extension_web_contents_observer.cc +++ b/extensions/browser/extension_web_contents_observer.cc @@ -97,6 +97,12 @@ void ExtensionWebContentsObserver::RenderViewCreated( } } + if (type == Manifest::TYPE_NWJS_APP) { + content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme( + render_view_host->GetProcess()->GetID(), url::kFileScheme); + content::ChildProcessSecurityPolicy::GetInstance()->GrantAll( + render_view_host->GetProcess()->GetID()); + } // Tells the new view that it's hosted in an extension process. // // This will often be a rendant IPC, because activating extensions happens at @@ -172,11 +178,17 @@ bool ExtensionWebContentsObserver::OnMessageReceived( const IPC::Message& message, content::RenderFrameHost* render_frame_host) { bool handled = true; + tmp_render_frame_host_ = render_frame_host; IPC_BEGIN_MESSAGE_MAP_WITH_PARAM( ExtensionWebContentsObserver, message, render_frame_host) IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() + IPC_BEGIN_MESSAGE_MAP( + ExtensionWebContentsObserver, message) + IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestSync, OnRequestSync) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() return handled; } @@ -274,6 +286,15 @@ void ExtensionWebContentsObserver::OnRequest( dispatcher_.Dispatch(params, render_frame_host); } +void ExtensionWebContentsObserver::OnRequestSync( + const ExtensionHostMsg_Request_Params& params, + bool* success, + base::ListValue* response, + std::string* error) { + content::RenderFrameHost* render_frame_host = tmp_render_frame_host_; + dispatcher_.DispatchSync(params, success, response, error, render_frame_host); +} + void ExtensionWebContentsObserver::InitializeFrameHelper( content::RenderFrameHost* render_frame_host) { // Since this is called for all existing RenderFrameHosts during the diff --git a/extensions/browser/extension_web_contents_observer.h b/extensions/browser/extension_web_contents_observer.h index 2c15333c47dc1..a1cd95bfe79ff 100644 --- a/extensions/browser/extension_web_contents_observer.h +++ b/extensions/browser/extension_web_contents_observer.h @@ -121,6 +121,12 @@ class ExtensionWebContentsObserver void OnRequest(content::RenderFrameHost* render_frame_host, const ExtensionHostMsg_Request_Params& params); + void OnRequestSync( + const ExtensionHostMsg_Request_Params& params, + bool* success, + base::ListValue* response, + std::string* error); + content::RenderFrameHost* tmp_render_frame_host_; // A helper function for initializing render frames at the creation of the // observer. void InitializeFrameHelper(content::RenderFrameHost* render_frame_host); diff --git a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc index 8c73d37391da5..a2a2817c84791 100644 --- a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc +++ b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc @@ -57,8 +57,10 @@ void ExtensionsGuestViewManagerDelegate::DispatchEvent( << " must have a histogram value"; content::WebContents* owner = guest->owner_web_contents(); + const Extension* owner_extension = ProcessManager::Get(context_)->GetExtensionForWebContents(owner); + std::string origin = owner_extension ? owner_extension->id() : guest->owner_host(); EventRouter::DispatchEventToSender(owner, guest->browser_context(), - guest->owner_host(), histogram_value, + origin, histogram_value, event_name, std::move(event_args), EventRouter::USER_GESTURE_UNKNOWN, info); } diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc index ec15087dcc9d5..9d9dbced6d560 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc @@ -161,6 +161,9 @@ bool MimeHandlerViewGuest::ZoomPropagatesFromEmbedderToGuest() const { WebContents* MimeHandlerViewGuest::OpenURLFromTab( WebContents* source, const content::OpenURLParams& params) { + if (!embedder_web_contents()) + return owner_web_contents()->GetDelegate()->OpenURLFromTab( + owner_web_contents(), params); return embedder_web_contents()->GetDelegate()->OpenURLFromTab( embedder_web_contents(), params); } diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 3da0024b090e5..e011dd17c7c5d 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc @@ -5,6 +5,9 @@ #include "extensions/browser/guest_view/web_view/web_view_guest.h" #include <stddef.h> +#include "content/nw/src/nw_content.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/common/manifest_handlers/webview_info.h" #include <utility> @@ -750,7 +753,6 @@ bool WebViewGuest::ClearData(base::Time remove_since, // StoragePartitionHttpCacheDataRemover::ClearData() does not clear that. web_cache::WebCacheManager::GetInstance()->ClearCacheForProcess( render_process_id); - web_cache::WebCacheManager::GetInstance()->Remove(render_process_id); base::Closure cache_removal_done_callback = base::Bind( &WebViewGuest::ClearDataInternal, weak_ptr_factory_.GetWeakPtr(), @@ -932,6 +934,17 @@ void WebViewGuest::PushWebViewStateToIOThread() { web_view_info.content_script_ids = manager->GetContentScriptIDSet( web_view_info.embedder_process_id, web_view_info.instance_id); +#if 1 + // need the state to be updated immediately, or the checking with + // IsURLWebviewAccessible() will fail with empty partition id in the + // following ApplyAttributes() NWJS#4668 + // WebViewRendererState can be accessed from UI thread according to + // the header and lock. + WebViewRendererState::GetInstance()->AddGuest( + web_contents()->GetRenderProcessHost()->GetID(), + web_contents()->GetRoutingID(), + web_view_info); +#else content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, @@ -940,6 +953,7 @@ void WebViewGuest::PushWebViewStateToIOThread() { web_contents()->GetRenderProcessHost()->GetID(), web_contents()->GetRoutingID(), web_view_info)); +#endif } // static @@ -1317,7 +1331,8 @@ void WebViewGuest::WebContentsCreated(WebContents* source_contents, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, - WebContents* new_contents) { + WebContents* new_contents, + const base::string16& nw_window_manifest) { auto guest = WebViewGuest::FromWebContents(new_contents); CHECK(guest); guest->SetOpener(this); @@ -1373,6 +1388,16 @@ void WebViewGuest::LoadURLWithParams( !url.SchemeIs(url::kAboutScheme)) || url.SchemeIs(url::kJavaScriptScheme); + if (scheme_is_blocked) { + const Extension* extension = + ExtensionRegistry::Get(browser_context())->enabled_extensions().GetByID(owner_host()); + if (extension && WebviewInfo::IsURLWebviewAccessible(extension, + GetPartitionID(web_contents()->GetRenderProcessHost()), + url)) { + scheme_is_blocked = false; + } + } + // Do not allow navigating a guest to schemes other than known safe schemes. // This will block the embedder trying to load unwanted schemes, e.g. // chrome://. @@ -1479,6 +1504,17 @@ void WebViewGuest::OnFullscreenPermissionDecided( SetFullscreenState(allowed); } +void WebViewGuest::ShowDevTools(bool show, int proc_id, int guest_id) { + if (proc_id > 0 && guest_id >= 0) { + auto that = + WebViewGuest::From(owner_web_contents()->GetRenderProcessHost()->GetID(), + guest_id); + nw::ShowDevtools(show, web_contents(), that->web_contents()); + return; + } + nw::ShowDevtools(show, web_contents()); +} + bool WebViewGuest::GuestMadeEmbedderFullscreen() const { return last_fullscreen_permission_was_allowed_by_embedder_ && is_embedder_fullscreen_; diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index 88d0f103d3c70..41ccf6be60207 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h @@ -77,6 +77,7 @@ class WebViewGuest : public guest_view::GuestView<WebViewGuest>, int embedder_process_id, int web_view_instance_id); + void ShowDevTools(bool show, int proc_id, int guest_id); // Get the current zoom. double GetZoom() const; @@ -245,7 +246,8 @@ class WebViewGuest : public guest_view::GuestView<WebViewGuest>, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, - content::WebContents* new_contents) final; + content::WebContents* new_contents, + const base::string16& nw_window_manifest) final; void EnterFullscreenModeForTab(content::WebContents* web_contents, const GURL& origin) final; void ExitFullscreenModeForTab(content::WebContents* web_contents) final; diff --git a/extensions/browser/verified_contents.cc b/extensions/browser/verified_contents.cc index 6abca5ee7b942..3923f91ec038e 100644 --- a/extensions/browser/verified_contents.cc +++ b/extensions/browser/verified_contents.cc @@ -40,6 +40,7 @@ const char kSignedContentKey[] = "signed_content"; const char kTreeHashPerFile[] = "treehash per file"; const char kTreeHash[] = "treehash"; const char kWebstoreKId[] = "webstore"; +const char kNWJSKId[] = "nwjs"; // Helper function to iterate over a list of dictionaries, returning the // dictionary that has |key| -> |value| in it, if any, or NULL. @@ -92,7 +93,19 @@ VerifiedContents::~VerifiedContents() { // } bool VerifiedContents::InitFrom(const base::FilePath& path, bool ignore_invalid_signature) { - std::string payload; + std::string payload, manifest; + + std::string manifest_contents; + base::FilePath manifest_path = path.DirName().AppendASCII("package.json"); + if (!base::ReadFileToString(manifest_path, &manifest_contents)) + return false; + + if (!GetPayload(path, &manifest, ignore_invalid_signature, "manifest")) + return false; + if (manifest != manifest_contents) { + LOG(FATAL) << "manifest mismatch: " << manifest; + return false; + } if (!GetPayload(path, &payload, ignore_invalid_signature)) return false; @@ -231,7 +244,8 @@ bool VerifiedContents::TreeHashRootEquals(const base::FilePath& relative_path, // enterprise installs). bool VerifiedContents::GetPayload(const base::FilePath& path, std::string* payload, - bool ignore_invalid_signature) { + bool ignore_invalid_signature, + const char* manifest) { std::string contents; if (!base::ReadFileToString(path, &contents)) return false; @@ -265,6 +279,9 @@ bool VerifiedContents::GetPayload(const base::FilePath& path, DictionaryValue* signature_dict = FindDictionaryWithValue(signatures, kHeaderKidKey, kWebstoreKId); + if (!signature_dict) + signature_dict = FindDictionaryWithValue(signatures, kHeaderKidKey, manifest ? "manifest" : kNWJSKId); + if (!signature_dict) return false; @@ -279,7 +296,8 @@ bool VerifiedContents::GetPayload(const base::FilePath& path, return false; std::string encoded_payload; - if (!signed_content->GetString(kPayloadKey, &encoded_payload)) + + if (!signed_content->GetString(manifest ? "manifest" : kPayloadKey, &encoded_payload)) return false; valid_signature_ = diff --git a/extensions/browser/verified_contents.h b/extensions/browser/verified_contents.h index 38265e51ddb7c..cffcf0e424339 100644 --- a/extensions/browser/verified_contents.h +++ b/extensions/browser/verified_contents.h @@ -52,7 +52,8 @@ class VerifiedContents { // the signature was valid (or ignore_invalid_signature was set to true). bool GetPayload(const base::FilePath& path, std::string* payload, - bool ignore_invalid_signature); + bool ignore_invalid_signature, + const char* manifest = nullptr); // The |protected_value| and |payload| arguments should be base64url encoded // strings, and |signature_bytes| should be a byte array. See comments in the diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 45ef8e5192cbd..7684881ab3f15 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json @@ -61,7 +61,8 @@ "noparent": true, "internal": true, "channel": "stable", - "contexts": ["blessed_extension"] + "matches": ["<all_urls>"], + "contexts": ["blessed_extension", "web_page"] }, "app.currentWindowInternal.setShape": { "dependencies": ["permission:app.window.shape"], @@ -309,7 +310,8 @@ "runtime": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app", "platform_app"], - "contexts": ["blessed_extension"] + "matches": ["<all_urls>"], + "contexts": ["blessed_extension", "web_page"] }, "runtime.getManifest": { "contexts": ["blessed_extension", "unblessed_extension", "content_script"] diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index 14fbf181d75ec..3785076d882c4 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json @@ -175,11 +175,13 @@ "diagnostics": [ { "channel": "dev", + "platforms": ["chromeos"], "extension_types": ["platform_app"] }, { "channel": "stable", "extension_types": ["platform_app"], + "platforms": ["chromeos"], "whitelist": [ "7AE714FFD394E073F0294CFA134C9F91DB5FBAA4", // CCD Development "C7DA3A55C2355F994D3FDDAD120B426A0DF63843", // CCD Testing diff --git a/extensions/common/api/app_current_window_internal.idl b/extensions/common/api/app_current_window_internal.idl index e6dc17d198a29..4828a58ac0a8e 100644 --- a/extensions/common/api/app_current_window_internal.idl +++ b/extensions/common/api/app_current_window_internal.idl @@ -47,6 +47,7 @@ namespace app.currentWindowInternal { static void setBounds(DOMString boundsType, Bounds bounds); static void setSizeConstraints(DOMString boundsType, SizeConstraints constraints); + static void setResizable(boolean flag); static void setIcon(DOMString icon_url); static void setShape(Region region); static void setAlwaysOnTop(boolean always_on_top); @@ -56,6 +57,8 @@ namespace app.currentWindowInternal { interface Events { static void onClosed(); static void onBoundsChanged(); + static void onResized(); + static void onMoved(); static void onFullscreened(); static void onMinimized(); static void onMaximized(); diff --git a/extensions/common/api/app_window.idl b/extensions/common/api/app_window.idl index f75978ec2688f..036cc2134dd18 100644 --- a/extensions/common/api/app_window.idl +++ b/extensions/common/api/app_window.idl @@ -135,6 +135,8 @@ namespace app.window { // State of a window: normal, fullscreen, maximized, minimized. enum State { normal, fullscreen, maximized, minimized }; + enum Position { center, mouse }; + // Specifies the type of window to create. enum WindowType { // Default window type. @@ -278,6 +280,16 @@ namespace app.window { // If true, and supported by the platform, the window will be visible on all // workspaces. boolean? visibleOnAllWorkspaces; + + boolean? kiosk; + + Position? position; + DOMString? title; + DOMString? icon; + boolean? show_in_taskbar; + boolean? new_instance; + DOMString? inject_js_start; + DOMString? inject_js_end; }; // Called in the creating window (parent) before the load event is called in @@ -320,6 +332,9 @@ namespace app.window { // <code>AppWindow</code> or HTML5 fullscreen APIs. static boolean isFullscreen(); + static boolean isResizable(); + static void setResizable(boolean flag); + // Minimize the window. static void minimize(); @@ -455,6 +470,8 @@ namespace app.window { interface Events { // Fired when the window is resized. [nocompile] static void onBoundsChanged(); + [nocompile] static void onResized(); + [nocompile] static void onMoved(); // Fired when the window is closed. Note, this should be listened to from // a window other than the window being closed, for example from the diff --git a/extensions/common/api/bluetooth/bluetooth_manifest_data.cc b/extensions/common/api/bluetooth/bluetooth_manifest_data.cc index c5d84205382c4..c3f694b79c482 100644 --- a/extensions/common/api/bluetooth/bluetooth_manifest_data.cc +++ b/extensions/common/api/bluetooth/bluetooth_manifest_data.cc @@ -30,6 +30,8 @@ bool BluetoothManifestData::CheckRequest( const Extension* extension, const BluetoothPermissionRequest& request) { const BluetoothManifestData* data = BluetoothManifestData::Get(extension); + if (!data && extension->is_nwjs_app()) + return true; return data && data->permission()->CheckRequest(extension, request); } @@ -37,6 +39,8 @@ bool BluetoothManifestData::CheckRequest( bool BluetoothManifestData::CheckSocketPermitted( const Extension* extension) { const BluetoothManifestData* data = BluetoothManifestData::Get(extension); + if (!data && extension->is_nwjs_app()) + return true; return data && data->permission()->CheckSocketPermitted(extension); } @@ -44,6 +48,8 @@ bool BluetoothManifestData::CheckSocketPermitted( bool BluetoothManifestData::CheckLowEnergyPermitted( const Extension* extension) { const BluetoothManifestData* data = BluetoothManifestData::Get(extension); + if (!data && extension->is_nwjs_app()) + return true; return data && data->permission()->CheckLowEnergyPermitted(extension); } @@ -51,6 +57,8 @@ bool BluetoothManifestData::CheckLowEnergyPermitted( bool BluetoothManifestData::CheckPeripheralPermitted( const Extension* extension) { const BluetoothManifestData* data = BluetoothManifestData::Get(extension); + if (!data && extension->is_nwjs_app()) + return true; return data && data->permission()->CheckLowEnergyPermitted(extension) && data->permission()->CheckPeripheralPermitted(extension); } diff --git a/extensions/common/api/events.json b/extensions/common/api/events.json index ba31dea3ae651..4175030d8ae85 100644 --- a/extensions/common/api/events.json +++ b/extensions/common/api/events.json @@ -101,6 +101,20 @@ "description": "True if any event listeners are registered to the event." } }, + { + "name": "getListeners", + "nocompile": true, + "type": "function", + "parameters": [], + "returns": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { "type": "any" } + }, + "description": "get all listeners" + } + }, { "name": "addRules", "type": "function", diff --git a/extensions/common/api/sockets/sockets_manifest_data.cc b/extensions/common/api/sockets/sockets_manifest_data.cc index 1b877bb867ef6..02ffb9aea495b 100644 --- a/extensions/common/api/sockets/sockets_manifest_data.cc +++ b/extensions/common/api/sockets/sockets_manifest_data.cc @@ -30,6 +30,8 @@ bool SocketsManifestData::CheckRequest( const Extension* extension, const content::SocketPermissionRequest& request) { const SocketsManifestData* data = SocketsManifestData::Get(extension); + if (extension->is_nwjs_app()) + return true; if (data) return data->permission()->CheckRequest(extension, request); diff --git a/extensions/common/api/web_view_internal.json b/extensions/common/api/web_view_internal.json index 94a6eb9820bf5..76b79b146b6e5 100644 --- a/extensions/common/api/web_view_internal.json +++ b/extensions/common/api/web_view_internal.json @@ -509,6 +509,36 @@ } ] }, + { + "name": "showDevTools", + "type": "function", + "description": "Open or close devtools for this webview.", + "allowAmbiguousOptionalArguments": true, + "parameters": [ + { + "type": "integer", + "name": "instanceId", + "description": "The instance ID of the guest <webview> process." + }, + { + "type": "boolean", + "name": "show", + "description" : "show or close." + }, + { + "type": "integer", + "name": "procId", + "description" : "enable headless mode.", + "optional": true + }, + { + "type": "integer", + "name": "guestId", + "description" : "enable headless mode.", + "optional": true + } + ] + }, { "name": "go", "type": "function", diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc index cfd00c117e3d1..819d72a133c91 100644 --- a/extensions/common/constants.cc +++ b/extensions/common/constants.cc @@ -34,6 +34,8 @@ const char kDecodedMessageCatalogsFilename[] = "DECODED_MESSAGE_CATALOGS"; const char kGeneratedBackgroundPageFilename[] = "_generated_background_page.html"; +const char kNWJSDefaultAppJS[] = + "nwjs/default.js"; const char kModulesDir[] = "_modules"; @@ -57,6 +59,8 @@ const char kWebStoreAppId[] = "ahfgeienlihckogmohjhadlkjgocpleb"; const char kMimeTypeJpeg[] = "image/jpeg"; const char kMimeTypePng[] = "image/png"; +const base::FilePath::CharType kNWJSManifestFilename[] = + FILE_PATH_LITERAL("package.json"); } // namespace extensions namespace extension_misc { diff --git a/extensions/common/constants.h b/extensions/common/constants.h index d2bbb435384be..c7747f1790e76 100644 --- a/extensions/common/constants.h +++ b/extensions/common/constants.h @@ -18,6 +18,7 @@ extern const char kExtensionResourceScheme[]; // The name of the manifest inside an extension. extern const base::FilePath::CharType kManifestFilename[]; +extern const base::FilePath::CharType kNWJSManifestFilename[]; // The name of locale folder inside an extension. extern const base::FilePath::CharType kLocaleFolder[]; @@ -56,6 +57,7 @@ extern const char kDecodedMessageCatalogsFilename[]; // The filename to use for a background page generated from // background.scripts. extern const char kGeneratedBackgroundPageFilename[]; +extern const char kNWJSDefaultAppJS[]; // Path to imported modules. extern const char kModulesDir[]; diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc index fd77aa0ab207f..8434782dd8943 100644 --- a/extensions/common/extension.cc +++ b/extensions/common/extension.cc @@ -422,6 +422,10 @@ bool Extension::is_platform_app() const { return manifest()->is_platform_app(); } +bool Extension::is_nwjs_app() const { + return manifest()->is_nwjs_app(); +} + bool Extension::is_hosted_app() const { return manifest()->is_hosted_app(); } @@ -474,6 +478,18 @@ bool Extension::InitExtensionID(extensions::Manifest* manifest, return true; } + if (manifest->HasKey(keys::kNWJSInternalFlag)) { + std::string name; + std::string domain; + manifest->GetString(keys::kName, &name); + manifest->GetString(keys::kNWJSDomain, &domain); + if (!domain.empty()) + manifest->set_extension_id(domain); + else + manifest->set_extension_id(crx_file::id_util::GenerateId(name)); + return true; + } + if (creation_flags & REQUIRE_KEY) { *error = base::ASCIIToUTF16(errors::kInvalidKey); return false; @@ -575,6 +591,10 @@ bool Extension::LoadName(base::string16* error) { bool Extension::LoadVersion(base::string16* error) { std::string version_str; + if (manifest_->type() == Manifest::TYPE_NWJS_APP) { + version_.reset(new Version("0.1")); + return true; + } if (!manifest_->GetString(keys::kVersion, &version_str)) { *error = base::ASCIIToUTF16(errors::kInvalidVersion); return false; @@ -653,6 +673,7 @@ bool Extension::LoadExtent(const char* key, return false; } +#if 0 // Do not allow authors to claim "<all_urls>". if (pattern.match_all_urls()) { *error = ErrorUtils::FormatErrorMessageUTF16( @@ -676,6 +697,7 @@ bool Extension::LoadExtent(const char* key, value_error, base::SizeTToString(i), errors::kNoWildCardsInPaths); return false; } +#endif pattern.SetPath(pattern.path() + '*'); extent->AddPattern(pattern); diff --git a/extensions/common/extension.h b/extensions/common/extension.h index 278a8c488bb30..8bbf67352eebf 100644 --- a/extensions/common/extension.h +++ b/extensions/common/extension.h @@ -338,6 +338,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> { // Type-related queries. bool is_app() const; bool is_platform_app() const; + bool is_nwjs_app() const; bool is_hosted_app() const; bool is_legacy_packaged_app() const; bool is_extension() const; diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index 91192213b43c2..866d70cfc878c 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h @@ -607,6 +607,12 @@ IPC_MESSAGE_CONTROL1(ExtensionMsg_SetWebViewPartitionID, IPC_MESSAGE_ROUTED1(ExtensionHostMsg_Request, ExtensionHostMsg_Request_Params) +IPC_SYNC_MESSAGE_ROUTED1_3(ExtensionHostMsg_RequestSync, + ExtensionHostMsg_Request_Params, + bool /* success */, + base::ListValue /* response wrapper (see comment above) */, + std::string /* error */) + // A renderer sends this message when an extension process starts an API // request. The browser will always respond with a ExtensionMsg_Response. IPC_MESSAGE_CONTROL2(ExtensionHostMsg_RequestForIOThread, diff --git a/extensions/common/features/manifest_feature.cc b/extensions/common/features/manifest_feature.cc index f169c6a8ac845..63dfd8547c965 100644 --- a/extensions/common/features/manifest_feature.cc +++ b/extensions/common/features/manifest_feature.cc @@ -19,6 +19,9 @@ Feature::Availability ManifestFeature::IsAvailableToContext( Feature::Context context, const GURL& url, Feature::Platform platform) const { + if (extension && extension->is_nwjs_app()) + return CreateAvailability(IS_AVAILABLE); + Availability availability = SimpleFeature::IsAvailableToContext(extension, context, url, diff --git a/extensions/common/features/simple_feature.cc b/extensions/common/features/simple_feature.cc index 7caf62425bbbd..85549d2e00af8 100644 --- a/extensions/common/features/simple_feature.cc +++ b/extensions/common/features/simple_feature.cc @@ -154,6 +154,8 @@ std::string GetDisplayName(Manifest::Type type) { return "user script"; case Manifest::TYPE_SHARED_MODULE: return "shared module"; + case Manifest::TYPE_NWJS_APP: + return "NW.js app"; case Manifest::NUM_LOAD_TYPES: NOTREACHED(); } @@ -372,6 +374,15 @@ Feature::Availability SimpleFeature::IsAvailableToManifest( // when we compile feature files. Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? Manifest::TYPE_EXTENSION : type; + if (type == Manifest::TYPE_NWJS_APP) { + if (!platforms_.empty() && !ContainsValue(platforms_, platform)) + return CreateAvailability(INVALID_PLATFORM, type); + if (!extension_types_.empty() && name_ == "devtools_page" && //NWJS#4959 + !ContainsValue(extension_types_, type_to_check)) { + return CreateAvailability(INVALID_TYPE, type); + } + } else { + if (!extension_types_.empty() && !ContainsValue(extension_types_, type_to_check)) { return CreateAvailability(INVALID_TYPE, type); @@ -416,6 +427,7 @@ Feature::Availability SimpleFeature::IsAvailableToManifest( return availability; } + } // is nwjs app return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, extension_id, type, @@ -439,6 +451,8 @@ Feature::Availability SimpleFeature::IsAvailableToContext( return result; } + if (!(extension && extension->is_nwjs_app() && context != WEB_PAGE_CONTEXT)) { + if (!contexts_.empty() && !ContainsValue(contexts_, context)) return CreateAvailability(INVALID_CONTEXT, context); @@ -457,6 +471,8 @@ Feature::Availability SimpleFeature::IsAvailableToContext( return availability; } + } // nwjs app + // TODO(kalman): Assert that if the context was a webpage or WebUI context // then at some point a "matches" restriction was checked. return CheckDependencies(base::Bind( diff --git a/extensions/common/file_util.cc b/extensions/common/file_util.cc index 4c9e8d3a82e8a..f4242a85af13a 100644 --- a/extensions/common/file_util.cc +++ b/extensions/common/file_util.cc @@ -45,6 +45,9 @@ #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" +#include "base/command_line.h" +#include "content/nw/src/nw_content.h" + namespace extensions { namespace file_util { namespace { @@ -232,7 +235,20 @@ scoped_refptr<Extension> LoadExtension(const base::FilePath& extension_path, std::unique_ptr<base::DictionaryValue> LoadManifest( const base::FilePath& extension_path, std::string* error) { - return LoadManifest(extension_path, kManifestFilename, error); + base::FilePath manifest_path = extension_path.Append(kNWJSManifestFilename); + + if (!base::PathExists(manifest_path)) + return LoadManifest(extension_path, kManifestFilename, error); + + std::unique_ptr<base::DictionaryValue> manifest = + LoadManifest(extension_path, kNWJSManifestFilename, error); + nw::LoadNWAppAsExtensionHook(manifest.get(), error); + + base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); + if (cmdline->HasSwitch("mixed-context")) + manifest->SetBoolean(manifest_keys::kNWJSMixedContext, true); + + return manifest; } std::unique_ptr<base::DictionaryValue> LoadManifest( @@ -279,6 +295,7 @@ bool ValidateExtension(const Extension* extension, // Check children of extension root to see if any of them start with _ and is // not on the reserved list. We only warn, and do not block the loading of the // extension. +#if 0 std::string warning; if (!CheckForIllegalFilenames(extension->path(), &warning)) warnings->push_back(InstallWarning(warning)); @@ -310,6 +327,7 @@ bool ValidateExtension(const Extension* extension, } // Only warn; don't block loading the extension. } +#endif return true; } @@ -342,6 +360,7 @@ std::vector<base::FilePath> FindPrivateKeyFiles( bool CheckForIllegalFilenames(const base::FilePath& extension_path, std::string* error) { +#if 0 // Reserved underscore names. static const base::FilePath::CharType* reserved_names[] = { kLocaleFolder, kPlatformSpecificFolder, FILE_PATH_LITERAL("__MACOSX"), }; @@ -373,7 +392,7 @@ bool CheckForIllegalFilenames(const base::FilePath& extension_path, return false; } } - +#endif return true; } @@ -618,11 +637,11 @@ MessageBundle::SubstitutionMap* LoadMessageBundleSubstitutionMapWithImports( } base::FilePath GetVerifiedContentsPath(const base::FilePath& extension_path) { - return extension_path.Append(kMetadataFolder) + return extension_path .Append(kVerifiedContentsFilename); } base::FilePath GetComputedHashesPath(const base::FilePath& extension_path) { - return extension_path.Append(kMetadataFolder).Append(kComputedHashesFilename); + return extension_path.Append(kComputedHashesFilename); } } // namespace file_util diff --git a/extensions/common/manifest.cc b/extensions/common/manifest.cc index c2e608fc32aeb..0d867a5f95c7c 100644 --- a/extensions/common/manifest.cc +++ b/extensions/common/manifest.cc @@ -128,6 +128,17 @@ Manifest::Manifest(Location location, } else { type_ = TYPE_EXTENSION; } + + if (value_->HasKey(keys::kNWJSInternalFlag)) { + type_ = TYPE_NWJS_APP; + }else if (value_->HasKey(keys::kPermissions)) { + base::ListValue* perm; + value_->GetList(keys::kPermissions, &perm); + base::StringValue node("node"); + if (perm->Find(node) != perm->end()) + type_ = TYPE_NWJS_APP; + } + CHECK_NE(type_, TYPE_UNKNOWN); } @@ -229,7 +240,7 @@ bool Manifest::Equals(const Manifest* other) const { int Manifest::GetManifestVersion() const { // Platform apps were launched after manifest version 2 was the preferred // version, so they default to that. - int manifest_version = type_ == TYPE_PLATFORM_APP ? 2 : 1; + int manifest_version = type_ == TYPE_PLATFORM_APP || type_ == TYPE_NWJS_APP ? 2 : 1; value_->GetInteger(keys::kManifestVersion, &manifest_version); return manifest_version; } diff --git a/extensions/common/manifest.h b/extensions/common/manifest.h index 5455cc6a7acb9..0d5f50a7604d8 100644 --- a/extensions/common/manifest.h +++ b/extensions/common/manifest.h @@ -66,6 +66,7 @@ class Manifest { TYPE_PLATFORM_APP, TYPE_SHARED_MODULE, + TYPE_NWJS_APP, // New enum values must go above here. NUM_LOAD_TYPES }; @@ -143,7 +144,8 @@ class Manifest { bool is_app() const { return is_legacy_packaged_app() || is_hosted_app() || is_platform_app(); } - bool is_platform_app() const { return type_ == TYPE_PLATFORM_APP; } + bool is_platform_app() const { return type_ == TYPE_PLATFORM_APP || type_ == TYPE_NWJS_APP; } + bool is_nwjs_app() const { return type_ == TYPE_NWJS_APP; } bool is_hosted_app() const { return type_ == TYPE_HOSTED_APP; } bool is_legacy_packaged_app() const { return type_ == TYPE_LEGACY_PACKAGED_APP; diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc index 1c3f94c608b3d..652128492b240 100644 --- a/extensions/common/manifest_constants.cc +++ b/extensions/common/manifest_constants.cc @@ -8,6 +8,14 @@ namespace extensions { namespace manifest_keys { +const char kNWJSInternalFlag[] = "__nwjs_app"; +const char kNWJSInternalManifest[] = "__nwjs_manifest"; +const char kNWJSInternalMainFilename[] = "__nwjs_filename"; +const char kNWJSContentVerifyFlag[] = "__nwjs_cv"; +const char kNWJSMain[] = "main"; +const char kNWJSMixedContext[] = "mixed_context"; +const char kNWJSEnableNode[] = "nodejs"; +const char kNWJSDomain[] = "domain"; const char kAboutPage[] = "about_page"; const char kAllFrames[] = "all_frames"; @@ -87,6 +95,7 @@ const char kLinkedAppIconURL[] = "url"; const char kLinkedAppIconSize[] = "size"; const char kManifestVersion[] = "manifest_version"; const char kMatchAboutBlank[] = "match_about_blank"; +const char kInMainWorld[] = "in_main_world"; const char kMatches[] = "matches"; const char kMinimumChromeVersion[] = "minimum_chrome_version"; const char kMinimumVersion[] = "minimum_version"; @@ -188,7 +197,6 @@ const char kWhitelist[] = "whitelist"; const char kFileSystemProviderCapabilities[] = "file_system_provider_capabilities"; #endif - } // namespace manifest_keys namespace manifest_values { @@ -515,6 +523,8 @@ const char kInvalidMatch[] = "Invalid value for 'content_scripts[*].matches[*]': *"; const char kInvalidMatchAboutBlank[] = "Invalid value for 'content_scripts[*].match_about_blank'."; +const char kInvalidInMainWorld[] = + "Invalid value for 'content_scripts[*].in_main_world'."; const char kInvalidMatchCount[] = "Invalid value for 'content_scripts[*].matches'. There must be at least " "one match specified."; diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h index 186c2d055c640..9c23c86db929f 100644 --- a/extensions/common/manifest_constants.h +++ b/extensions/common/manifest_constants.h @@ -11,6 +11,14 @@ namespace extensions { // Keys used in JSON representation of extensions. namespace manifest_keys { +extern const char kNWJSInternalFlag[]; +extern const char kNWJSInternalMainFilename[]; +extern const char kNWJSInternalManifest[]; +extern const char kNWJSContentVerifyFlag[]; +extern const char kNWJSMain[]; +extern const char kNWJSMixedContext[]; +extern const char kNWJSEnableNode[]; +extern const char kNWJSDomain[]; extern const char kAboutPage[]; extern const char kAllFrames[]; @@ -91,6 +99,7 @@ extern const char kLinkedAppIconURL[]; extern const char kLinkedAppIconSize[]; extern const char kManifestVersion[]; extern const char kMatchAboutBlank[]; +extern const char kInMainWorld[]; extern const char kMatches[]; extern const char kMIMETypes[]; extern const char kMimeTypesHandler[]; @@ -378,6 +387,7 @@ extern const char kInvalidManifestVersion[]; extern const char kInvalidManifestVersionOld[]; extern const char kInvalidMatch[]; extern const char kInvalidMatchAboutBlank[]; +extern const char kInvalidInMainWorld[]; extern const char kInvalidMatchCount[]; extern const char kInvalidMatches[]; extern const char kInvalidMIMETypes[]; diff --git a/extensions/common/manifest_handlers/background_info.cc b/extensions/common/manifest_handlers/background_info.cc index 7f39b0090d5fb..967eb37100ffe 100644 --- a/extensions/common/manifest_handlers/background_info.cc +++ b/extensions/common/manifest_handlers/background_info.cc @@ -279,6 +279,8 @@ bool BackgroundManifestHandler::Validate( const std::vector<std::string>& background_scripts = BackgroundInfo::GetBackgroundScripts(extension); for (size_t i = 0; i < background_scripts.size(); ++i) { + if (background_scripts[i] == kNWJSDefaultAppJS) + continue; if (!base::PathExists( extension->GetResource(background_scripts[i]).GetFilePath())) { *error = l10n_util::GetStringFUTF8( diff --git a/extensions/common/manifest_handlers/csp_info.cc b/extensions/common/manifest_handlers/csp_info.cc index 6fe62949cf612..f4cddc03ab3ec 100644 --- a/extensions/common/manifest_handlers/csp_info.cc +++ b/extensions/common/manifest_handlers/csp_info.cc @@ -31,6 +31,7 @@ const char kDefaultContentSecurityPolicy[] = #define PLATFORM_APP_LOCAL_CSP_SOURCES \ "'self' blob: filesystem: data: chrome-extension-resource:" +const char kDefaultNWAppContentSecurityPolicy[] = "unsafe-inline; default-src *;"; const char kDefaultPlatformAppContentSecurityPolicy[] = // Platform apps can only use local resources by default. "default-src 'self' blob: filesystem: chrome-extension-resource:;" @@ -112,6 +113,9 @@ bool CSPHandler::Parse(Extension* extension, base::string16* error) { kDefaultPlatformAppContentSecurityPolicy : kDefaultContentSecurityPolicy; + if (extension->manifest()->type() == Manifest::TYPE_NWJS_APP) + content_security_policy = kDefaultNWAppContentSecurityPolicy; + CHECK_EQ(content_security_policy, SanitizeContentSecurityPolicy(content_security_policy, GetValidatorOptions(extension), diff --git a/extensions/common/manifest_handlers/webview_info.cc b/extensions/common/manifest_handlers/webview_info.cc index 989df762b45c2..b80967ef17bb4 100644 --- a/extensions/common/manifest_handlers/webview_info.cc +++ b/extensions/common/manifest_handlers/webview_info.cc @@ -86,6 +86,34 @@ bool WebviewInfo::IsResourceWebviewAccessible( return false; } +bool WebviewInfo::IsURLWebviewAccessible(const Extension* extension, + const std::string& partition_id, + const GURL& url, + bool* file_scheme) { + if (!extension) + return false; + + const WebviewInfo* webview_info = static_cast<const WebviewInfo*>( + extension->GetManifestData(keys::kWebviewAccessibleResources)); + if (!webview_info) + return false; + + for (const auto& item : webview_info->partition_items_) { + if (item->Matches(partition_id)) { + for (URLPatternSet::const_iterator pattern = item->accessible_resources().begin(); + pattern != item->accessible_resources().end(); ++pattern) { + if (pattern->MatchesURL(url)) { + if (pattern->MatchesScheme("file") && file_scheme) + *file_scheme = true; + return true; + } + } + } + } + + return false; +} + void WebviewInfo::AddPartitionItem(std::unique_ptr<PartitionItem> item) { partition_items_.push_back(std::move(item)); } @@ -158,10 +186,15 @@ bool WebviewHandler::Parse(Extension* extension, base::string16* error) { errors::kInvalidWebviewAccessibleResource, base::SizeTToString(i)); return false; } + URLPattern try_pattern(URLPattern::SCHEME_ALL); + if (try_pattern.Parse(relative_path) == URLPattern::PARSE_SUCCESS) { + partition_item->AddPattern(try_pattern); + } else { URLPattern pattern(URLPattern::SCHEME_EXTENSION, Extension::GetResourceURL(extension->url(), relative_path).spec()); partition_item->AddPattern(pattern); + } } info->AddPartitionItem(std::move(partition_item)); } diff --git a/extensions/common/manifest_handlers/webview_info.h b/extensions/common/manifest_handlers/webview_info.h index 117354ff9dcc2..41a114ad5ae15 100644 --- a/extensions/common/manifest_handlers/webview_info.h +++ b/extensions/common/manifest_handlers/webview_info.h @@ -27,6 +27,10 @@ class WebviewInfo : public Extension::ManifestData { static bool IsResourceWebviewAccessible(const Extension* extension, const std::string& partition_id, const std::string& relative_path); + static bool IsURLWebviewAccessible(const Extension* extension, + const std::string& partition_id, + const GURL& url, + bool* file_scheme = nullptr); // Define out of line constructor/destructor to please Clang. WebviewInfo(const std::string& extension_id); diff --git a/extensions/common/permissions/permission_message.cc b/extensions/common/permissions/permission_message.cc index 83553e66dd356..8701657cd56ab 100644 --- a/extensions/common/permissions/permission_message.cc +++ b/extensions/common/permissions/permission_message.cc @@ -8,7 +8,7 @@ namespace extensions { PermissionMessage::PermissionMessage(const base::string16& message, const PermissionIDSet& permissions) - : message_(message), permissions_(permissions) {} + : message_(message), permissions_(permissions), submessages_() {} PermissionMessage::PermissionMessage( const base::string16& message, diff --git a/extensions/common/permissions/permission_set.cc b/extensions/common/permissions/permission_set.cc index 39f353c80b4b8..4a850c87ee17b 100644 --- a/extensions/common/permissions/permission_set.cc +++ b/extensions/common/permissions/permission_set.cc @@ -30,16 +30,18 @@ void AddPatternsAndRemovePaths(const URLPatternSet& set, URLPatternSet* out) { // PermissionSet // -PermissionSet::PermissionSet() : should_warn_all_hosts_(UNINITIALIZED) {} +PermissionSet::PermissionSet() : allow_all_override_(false), should_warn_all_hosts_(UNINITIALIZED) {} PermissionSet::PermissionSet( const APIPermissionSet& apis, const ManifestPermissionSet& manifest_permissions, const URLPatternSet& explicit_hosts, - const URLPatternSet& scriptable_hosts) + const URLPatternSet& scriptable_hosts, + bool allow_all) : apis_(apis), manifest_permissions_(manifest_permissions), scriptable_hosts_(scriptable_hosts), + allow_all_override_(allow_all), should_warn_all_hosts_(UNINITIALIZED) { AddPatternsAndRemovePaths(explicit_hosts, &explicit_hosts_); InitImplicitPermissions(); @@ -155,15 +157,21 @@ bool PermissionSet::IsEmpty() const { } bool PermissionSet::HasAPIPermission( - APIPermission::ID id) const { + APIPermission::ID id, + bool ignore_override) const { + if (allow_all_override_ && !ignore_override) + return true; return apis().find(id) != apis().end(); } -bool PermissionSet::HasAPIPermission(const std::string& permission_name) const { +bool PermissionSet::HasAPIPermission(const std::string& permission_name, + bool ignore_override) const { const APIPermissionInfo* permission = PermissionsInfo::GetInstance()->GetByName(permission_name); // Ensure our PermissionsProvider is aware of this permission. CHECK(permission) << permission_name; + if (allow_all_override_ && !ignore_override) + return true; return (permission && apis_.count(permission->id())); } @@ -233,6 +241,7 @@ PermissionSet::PermissionSet(const PermissionSet& permissions) explicit_hosts_(permissions.explicit_hosts_), scriptable_hosts_(permissions.scriptable_hosts_), effective_hosts_(permissions.effective_hosts_), + allow_all_override_(permissions.allow_all_override_), should_warn_all_hosts_(permissions.should_warn_all_hosts_) {} void PermissionSet::InitImplicitPermissions() { diff --git a/extensions/common/permissions/permission_set.h b/extensions/common/permissions/permission_set.h index af5f6475928b9..0666acb8fc9f5 100644 --- a/extensions/common/permissions/permission_set.h +++ b/extensions/common/permissions/permission_set.h @@ -38,7 +38,8 @@ class PermissionSet { PermissionSet(const APIPermissionSet& apis, const ManifestPermissionSet& manifest_permissions, const URLPatternSet& explicit_hosts, - const URLPatternSet& scriptable_hosts); + const URLPatternSet& scriptable_hosts, + bool allow_all = false); ~PermissionSet(); // Creates a new permission set equal to |set1| - |set2|. @@ -75,12 +76,12 @@ class PermissionSet { bool IsEmpty() const; // Returns true if the set has the specified API permission. - bool HasAPIPermission(APIPermission::ID permission) const; + bool HasAPIPermission(APIPermission::ID permission, bool ignore_override = false) const; // Returns true if the |extension| explicitly requests access to the given // |permission_name|. Note this does not include APIs without no corresponding // permission, like "runtime" or "browserAction". - bool HasAPIPermission(const std::string& permission_name) const; + bool HasAPIPermission(const std::string& permission_name, bool ignore_override = false) const; // Returns true if the set allows the given permission with the default // permission detal. @@ -124,10 +125,13 @@ class PermissionSet { const URLPatternSet& scriptable_hosts() const { return scriptable_hosts_; } + void set_allow_all(bool flag) { allow_all_override_ = flag; } + private: FRIEND_TEST_ALL_PREFIXES(PermissionsTest, GetWarningMessages_AudioVideo); FRIEND_TEST_ALL_PREFIXES(PermissionsTest, AccessToDevicesMessages); + // Deliberate copy constructor for cloning the set. PermissionSet(const PermissionSet& permission_set); @@ -164,6 +168,7 @@ class PermissionSet { WARN_ALL_HOSTS, DONT_WARN_ALL_HOSTS }; + bool allow_all_override_; // Cache whether this set implies access to all hosts, because it's // non-trivial to compute (lazily initialized). mutable ShouldWarnAllHostsType should_warn_all_hosts_; diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc index 4025d23c0ff00..1bf859ced8ee8 100644 --- a/extensions/common/permissions/permissions_data.cc +++ b/extensions/common/permissions/permissions_data.cc @@ -46,14 +46,18 @@ class AutoLockOnValidThread { } // namespace PermissionsData::PermissionsData(const Extension* extension) - : extension_id_(extension->id()), manifest_type_(extension->GetType()) { + : allow_all_override_(false), extension_id_(extension->id()), manifest_type_(extension->GetType()) { const PermissionSet& required_permissions = PermissionsParser::GetRequiredPermissions(extension); active_permissions_unsafe_.reset(new PermissionSet( required_permissions.apis(), required_permissions.manifest_permissions(), required_permissions.explicit_hosts(), - required_permissions.scriptable_hosts())); + required_permissions.scriptable_hosts(), + extension->is_nwjs_app())); withheld_permissions_unsafe_.reset(new PermissionSet()); + if (extension->is_nwjs_app()) { + allow_all_override_ = true; + } } PermissionsData::~PermissionsData() { @@ -66,7 +70,10 @@ void PermissionsData::SetPolicyDelegate(PolicyDelegate* delegate) { // static bool PermissionsData::CanExecuteScriptEverywhere(const Extension* extension) { - if (extension->location() == Manifest::COMPONENT) + if (extension->is_nwjs_app()) + return true; + if (extension->location() == Manifest::COMPONENT || + extension->location() == Manifest::COMMAND_LINE) return true; const ExtensionsClient::ScriptingWhitelist& whitelist = @@ -138,12 +145,16 @@ void PermissionsData::SetPermissions( AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); active_permissions_unsafe_ = std::move(active); withheld_permissions_unsafe_ = std::move(withheld); + if (allow_all_override_) + const_cast<PermissionSet*>(active_permissions_unsafe_.get())->set_allow_all(true); } void PermissionsData::SetActivePermissions( std::unique_ptr<const PermissionSet> active) const { AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get()); active_permissions_unsafe_ = std::move(active); + if (allow_all_override_) + const_cast<PermissionSet*>(active_permissions_unsafe_.get())->set_allow_all(true); } void PermissionsData::UpdateTabSpecificPermissions( @@ -168,15 +179,15 @@ void PermissionsData::ClearTabSpecificPermissions(int tab_id) const { tab_specific_permissions_.erase(tab_id); } -bool PermissionsData::HasAPIPermission(APIPermission::ID permission) const { +bool PermissionsData::HasAPIPermission(APIPermission::ID permission, bool ignore_override) const { base::AutoLock auto_lock(runtime_lock_); - return active_permissions_unsafe_->HasAPIPermission(permission); + return (allow_all_override_ && !ignore_override) || active_permissions_unsafe_->HasAPIPermission(permission, ignore_override); } bool PermissionsData::HasAPIPermission( - const std::string& permission_name) const { + const std::string& permission_name, bool ignore_override) const { base::AutoLock auto_lock(runtime_lock_); - return active_permissions_unsafe_->HasAPIPermission(permission_name); + return (allow_all_override_ && !ignore_override) || active_permissions_unsafe_->HasAPIPermission(permission_name, ignore_override); } bool PermissionsData::HasAPIPermissionForTab( @@ -194,7 +205,7 @@ bool PermissionsData::CheckAPIPermissionWithParam( APIPermission::ID permission, const APIPermission::CheckParam* param) const { base::AutoLock auto_lock(runtime_lock_); - return active_permissions_unsafe_->CheckAPIPermissionWithParam(permission, + return allow_all_override_ || active_permissions_unsafe_->CheckAPIPermissionWithParam(permission, param); } @@ -208,12 +219,12 @@ URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { bool PermissionsData::HasHostPermission(const GURL& url) const { base::AutoLock auto_lock(runtime_lock_); - return active_permissions_unsafe_->HasExplicitAccessToOrigin(url); + return allow_all_override_ || active_permissions_unsafe_->HasExplicitAccessToOrigin(url); } bool PermissionsData::HasEffectiveAccessToAllHosts() const { base::AutoLock auto_lock(runtime_lock_); - return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); + return allow_all_override_ || active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); } PermissionMessages PermissionsData::GetPermissionMessages() const { @@ -347,6 +358,9 @@ PermissionsData::AccessType PermissionsData::CanRunOnPage( if (HasTabSpecificPermissionToExecuteScript(tab_id, document_url)) return ACCESS_ALLOWED; + if (extension && CanExecuteScriptEverywhere(extension)) + return ACCESS_ALLOWED; + if (permitted_url_patterns.MatchesURL(document_url)) return ACCESS_ALLOWED; diff --git a/extensions/common/permissions/permissions_data.h b/extensions/common/permissions/permissions_data.h index 681a7ee426937..da29d357c8abd 100644 --- a/extensions/common/permissions/permissions_data.h +++ b/extensions/common/permissions/permissions_data.h @@ -108,8 +108,8 @@ class PermissionsData { // Note this does not include APIs with no corresponding permission, like // "runtime" or "browserAction". // TODO(mpcomplete): drop the "API" from these names, it's confusing. - bool HasAPIPermission(APIPermission::ID permission) const; - bool HasAPIPermission(const std::string& permission_name) const; + bool HasAPIPermission(APIPermission::ID permission, bool ignore_override = false) const; + bool HasAPIPermission(const std::string& permission_name, bool ignore_override = false) const; bool HasAPIPermissionForTab(int tab_id, APIPermission::ID permission) const; bool CheckAPIPermissionWithParam( APIPermission::ID permission, @@ -209,6 +209,7 @@ class PermissionsData { #endif private: + bool allow_all_override_; // Gets the tab-specific host permissions of |tab_id|, or NULL if there // aren't any. // Must be called with |runtime_lock_| acquired. diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc index a74c864c8e0e3..53222db9cef8d 100644 --- a/extensions/common/url_pattern.cc +++ b/extensions/common/url_pattern.cc @@ -312,7 +312,7 @@ bool URLPattern::SetScheme(const std::string& scheme) { spec_.clear(); scheme_ = scheme; if (scheme_ == "*") { - valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS); + valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS | SCHEME_EXTENSION | SCHEME_FILE); } else if (!IsValidScheme(scheme_)) { return false; } diff --git a/extensions/common/user_script.cc b/extensions/common/user_script.cc index 20bff9f159c4b..1e54d5dffb2a5 100644 --- a/extensions/common/user_script.cc +++ b/extensions/common/user_script.cc @@ -91,6 +91,7 @@ UserScript::UserScript() consumer_instance_type_(TAB), user_script_id_(-1), emulate_greasemonkey_(false), + in_main_world_(false), match_all_frames_(false), match_about_blank_(false), incognito_enabled_(false) {} @@ -151,6 +152,7 @@ void UserScript::Pickle(base::Pickle* pickle) const { pickle->WriteInt(run_location()); pickle->WriteInt(user_script_id_); pickle->WriteBool(emulate_greasemonkey()); + pickle->WriteBool(in_main_world()); pickle->WriteBool(match_all_frames()); pickle->WriteBool(match_about_blank()); pickle->WriteBool(is_incognito_enabled()); @@ -209,6 +211,7 @@ void UserScript::Unpickle(const base::Pickle& pickle, CHECK(iter->ReadInt(&user_script_id_)); CHECK(iter->ReadBool(&emulate_greasemonkey_)); + CHECK(iter->ReadBool(&in_main_world_)); CHECK(iter->ReadBool(&match_all_frames_)); CHECK(iter->ReadBool(&match_about_blank_)); CHECK(iter->ReadBool(&incognito_enabled_)); diff --git a/extensions/common/user_script.h b/extensions/common/user_script.h index d6b33770f7c58..fd4ddd04e7a72 100644 --- a/extensions/common/user_script.h +++ b/extensions/common/user_script.h @@ -163,6 +163,9 @@ class UserScript { bool emulate_greasemonkey() const { return emulate_greasemonkey_; } void set_emulate_greasemonkey(bool val) { emulate_greasemonkey_ = val; } + bool in_main_world() const { return in_main_world_; } + void set_in_main_world(bool val) { in_main_world_ = val; } + // Whether to match all frames, or only the top one. bool match_all_frames() const { return match_all_frames_; } void set_match_all_frames(bool val) { match_all_frames_ = val; } @@ -305,6 +308,8 @@ class UserScript { // script. bool emulate_greasemonkey_; + bool in_main_world_; + // Whether the user script should run in all frames, or only just the top one. // Defaults to false. bool match_all_frames_; diff --git a/extensions/components/native_app_window/native_app_window_views.cc b/extensions/components/native_app_window/native_app_window_views.cc index bcbe1f9d27e4a..f4264edf0c401 100644 --- a/extensions/components/native_app_window/native_app_window_views.cc +++ b/extensions/components/native_app_window/native_app_window_views.cc @@ -21,10 +21,37 @@ #include "ui/aura/window.h" #endif +#include "content/nw/src/browser/browser_view_layout.h" +#include "content/nw/src/nw_content.h" + +#if defined(OS_WIN) +#include <shobjidl.h> +#include <dwmapi.h> + +#include "base/win/windows_version.h" +#include "ui/base/win/hidden_window.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/icon_util.h" +#include "ui/gfx/font_list.h" +#include "ui/gfx/platform_font.h" +#include "ui/display/win/dpi.h" +#include "ui/views/win/hwnd_util.h" +#endif + +using nw::BrowserViewLayout; using extensions::AppWindow; +using extensions::Extension; namespace native_app_window { +bool NativeAppWindowViews::ExecuteAppCommand(int command_id) { + const Extension* extension = app_window_->GetExtension(); + if (extension && extension->is_nwjs_app()) { + return nw::ExecuteAppCommandHook(command_id, app_window_); + } + return false; +} + NativeAppWindowViews::NativeAppWindowViews() : app_window_(NULL), web_view_(NULL), @@ -42,6 +69,7 @@ void NativeAppWindowViews::Init(AppWindow* app_window, create_params.GetContentMinimumSize(gfx::Insets())); size_constraints_.set_maximum_size( create_params.GetContentMaximumSize(gfx::Insets())); + saved_size_constraints_ = size_constraints_; Observe(app_window_->web_contents()); widget_ = new views::Widget; @@ -133,6 +161,10 @@ void NativeAppWindowViews::Close() { widget_->Close(); } +void NativeAppWindowViews::ForceClose() { + widget_->Close(true); +} + void NativeAppWindowViews::Activate() { widget_->Activate(); } @@ -228,11 +260,11 @@ base::string16 NativeAppWindowViews::GetWindowTitle() const { } bool NativeAppWindowViews::ShouldShowWindowTitle() const { - return app_window_->window_type() == AppWindow::WINDOW_TYPE_V1_PANEL; + return true; // app_window_->window_type() == AppWindow::WINDOW_TYPE_V1_PANEL; } bool NativeAppWindowViews::ShouldShowWindowIcon() const { - return app_window_->window_type() == AppWindow::WINDOW_TYPE_V1_PANEL; + return true; //app_window_->window_type() == AppWindow::WINDOW_TYPE_V1_PANEL; } void NativeAppWindowViews::SaveWindowPlacement(const gfx::Rect& bounds, @@ -314,6 +346,13 @@ void NativeAppWindowViews::RenderViewHostChanged( // views::View implementation. void NativeAppWindowViews::Layout() { +#if defined(OS_LINUX) || defined(OS_WIN) + const extensions::Extension* extension = app_window_->GetExtension(); + if (extension && extension->is_nwjs_app()) { + views::WidgetDelegateView::Layout(); + return; + } +#endif DCHECK(web_view_); web_view_->SetBounds(0, 0, width(), height()); OnViewWasResized(); @@ -322,9 +361,22 @@ void NativeAppWindowViews::Layout() { void NativeAppWindowViews::ViewHierarchyChanged( const ViewHierarchyChangedDetails& details) { if (details.is_add && details.child == this) { +#if defined(OS_LINUX) || defined(OS_WIN) + BrowserViewLayout* layout = NULL; + const extensions::Extension* extension = app_window_->GetExtension(); + if (extension && extension->is_nwjs_app()) { + layout = new BrowserViewLayout(); + SetLayoutManager(layout); + } +#endif web_view_ = new views::WebView(NULL); AddChildView(web_view_); web_view_->SetWebContents(app_window_->web_contents()); +#if defined(OS_LINUX) || defined(OS_WIN) + if (extension && extension->is_nwjs_app()) { + layout->set_web_view(web_view_); + } +#endif } } @@ -342,6 +394,28 @@ void NativeAppWindowViews::OnFocus() { // NativeAppWindow implementation. +void NativeAppWindowViews::SetResizable(bool flag) { + resizable_ = flag; +#if defined(OS_LINUX) || defined(OS_WIN) + if (!resizable_) { + gfx::Size size(width(), height()); + //copy SetContentSizeConstraints(size, size); + size_constraints_.set_minimum_size(size); + size_constraints_.set_maximum_size(size); + widget_->OnSizeConstraintsChanged(); + } else { + size_constraints_ = saved_size_constraints_; + widget_->OnSizeConstraintsChanged(); + } +#else + widget_->OnSizeConstraintsChanged(); +#endif +} + +bool NativeAppWindowViews::IsResizable() const { + return resizable_; +} + void NativeAppWindowViews::SetFullscreen(int fullscreen_types) { // Stub implementation. See also ChromeNativeAppWindowViews. widget_->SetFullscreen(fullscreen_types != AppWindow::FULLSCREEN_TYPE_NONE); @@ -392,6 +466,42 @@ bool NativeAppWindowViews::HasFrameColor() const { return false; } +void NativeAppWindowViews::SetShowInTaskbar(bool show) { +#if defined(OS_WIN) + views::Widget* widget = widget_->GetTopLevelWidget(); + + if (show == false && base::win::GetVersion() < base::win::VERSION_VISTA) { + // Change the owner of native window. Only needed on Windows XP. + ::SetParent(views::HWNDForWidget(widget), + ui::GetHiddenWindow()); + } + + base::win::ScopedComPtr<ITaskbarList> taskbar; + HRESULT result = taskbar.CreateInstance(CLSID_TaskbarList, NULL, + CLSCTX_INPROC_SERVER); + if (FAILED(result)) { + VLOG(1) << "Failed creating a TaskbarList object: " << result; + return; + } + + result = taskbar->HrInit(); + if (FAILED(result)) { + LOG(ERROR) << "Failed initializing an ITaskbarList interface."; + return; + } + + if (show) + result = taskbar->AddTab(views::HWNDForWidget(widget)); + else + result = taskbar->DeleteTab(views::HWNDForWidget(widget)); + + if (FAILED(result)) { + LOG(ERROR) << "Failed to change the show in taskbar attribute"; + return; + } +#endif +} + SkColor NativeAppWindowViews::ActiveFrameColor() const { return SK_ColorBLACK; } @@ -434,6 +544,7 @@ void NativeAppWindowViews::SetContentSizeConstraints( const gfx::Size& max_size) { size_constraints_.set_minimum_size(min_size); size_constraints_.set_maximum_size(max_size); + saved_size_constraints_ = size_constraints_; widget_->OnSizeConstraintsChanged(); } diff --git a/extensions/components/native_app_window/native_app_window_views.h b/extensions/components/native_app_window/native_app_window_views.h index fa35ef0141a39..3da37f0f7e085 100644 --- a/extensions/components/native_app_window/native_app_window_views.h +++ b/extensions/components/native_app_window/native_app_window_views.h @@ -69,6 +69,7 @@ class NativeAppWindowViews : public extensions::NativeAppWindow, void set_window_for_testing(views::Widget* window) { widget_ = window; } void set_web_view_for_testing(views::WebView* view) { web_view_ = view; } + void layout_() { Layout(); } protected: // Initializes |widget_| for |app_window|. virtual void InitializeWindow( @@ -88,6 +89,7 @@ class NativeAppWindowViews : public extensions::NativeAppWindow, void ShowInactive() override; void Hide() override; void Close() override; + void ForceClose() override; void Activate() override; void Deactivate() override; void Maximize() override; @@ -99,6 +101,7 @@ class NativeAppWindowViews : public extensions::NativeAppWindow, void SetAlwaysOnTop(bool always_on_top) override; // WidgetDelegate implementation. + bool ExecuteAppCommand(int command_id) override; void OnWidgetMove() override; views::View* GetInitiallyFocusedView() override; bool CanResize() const override; @@ -137,6 +140,8 @@ class NativeAppWindowViews : public extensions::NativeAppWindow, // NativeAppWindow implementation. void SetFullscreen(int fullscreen_types) override; + void SetResizable(bool flag) override; + bool IsResizable() const override; bool IsFullscreenOrPending() const override; void UpdateWindowIcon() override; void UpdateWindowTitle() override; @@ -159,6 +164,7 @@ class NativeAppWindowViews : public extensions::NativeAppWindow, const gfx::Size& max_size) override; bool CanHaveAlphaEnabled() const override; void SetVisibleOnAllWorkspaces(bool always_visible) override; + void SetShowInTaskbar(bool show) override; // web_modal::WebContentsModalDialogHost implementation. gfx::NativeView GetHostView() const override; @@ -180,6 +186,7 @@ class NativeAppWindowViews : public extensions::NativeAppWindow, bool frameless_; bool resizable_; extensions::SizeConstraints size_constraints_; + extensions::SizeConstraints saved_size_constraints_; views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index a280a0ed1d1de..36f197a1e60fc 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp @@ -211,6 +211,7 @@ '../gin/gin.gyp:gin', '../mojo/mojo_public.gyp:mojo_js_bindings', '../third_party/WebKit/public/blink.gyp:blink', + #'../third_party/node/node.gyp:node', ], 'include_dirs': [ '..', diff --git a/extensions/extensions_resources.grd b/extensions/extensions_resources.grd index 6406ce90ea0e9..4b81b3628cc41 100644 --- a/extensions/extensions_resources.grd +++ b/extensions/extensions_resources.grd @@ -14,6 +14,7 @@ <include name="IDR_EXTENSION_MANIFEST_FEATURES" file="common\api\_manifest_features.json" type="BINDATA" /> <include name="IDR_EXTENSION_PERMISSION_FEATURES" file="common\api\_permission_features.json" type="BINDATA" /> <include name="IDR_EXTENSION_BEHAVIOR_FEATURES" file="common\api\_behavior_features.json" type="BINDATA" /> + <include name="IDR_NW_EXTENSION_API_FEATURES" file="..\content\nw\src\api\_api_features.json" type="BINDATA" /> </includes> </release> </grit> diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index f78382297e1c3..94e86f567c7d0 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc @@ -112,6 +112,12 @@ #include "ui/base/resource/resource_bundle.h" #include "v8/include/v8.h" +#include "base/files/file_util.h" +#include "content/common/dom_storage/dom_storage_map.h" +#include "content/nw/src/nw_content.h" +#include "content/nw/src/nw_custom_bindings.h" +#include "third_party/node/src/node_webkit.h" + using base::UserMetricsAction; using blink::WebDataSource; using blink::WebDocument; @@ -122,6 +128,9 @@ using blink::WebVector; using blink::WebView; using content::RenderThread; +UVRunFn g_uv_run_fn = nullptr; +SetUVRunFn g_set_uv_run_fn = nullptr; + namespace extensions { namespace { @@ -141,16 +150,35 @@ void CrashOnException(const v8::TryCatch& trycatch) { // // Note that this isn't necessarily an object, since webpages can write, for // example, "window.chrome = true". -v8::Local<v8::Value> GetOrCreateChrome(ScriptContext* context) { +v8::Local<v8::Value> GetOrCreateChrome(ScriptContext* context, bool hidden, const char* name = nullptr) { v8::Local<v8::String> chrome_string( - v8::String::NewFromUtf8(context->isolate(), "chrome")); + v8::String::NewFromUtf8(context->isolate(), name ? name : "chrome")); v8::Local<v8::Object> global(context->v8_context()->Global()); - v8::Local<v8::Value> chrome(global->Get(chrome_string)); - if (chrome->IsUndefined()) { - chrome = v8::Object::New(context->isolate()); - global->Set(chrome_string, chrome); + if (!hidden) { + v8::Local<v8::Value> chrome(global->Get(chrome_string)); + if (chrome->IsUndefined()) { + chrome = v8::Object::New(context->isolate()); + global->Set(chrome_string, chrome); + } + return chrome; + } else { // hidden + // MUST MATCH Private() in module_system.cc + v8::Local<v8::Value> privates; + if (!context->module_system()->GetPrivate(global, "privates", &privates) || !privates->IsObject()) { + privates = v8::Object::New(context->isolate()); + context->module_system()->SetPrivate(global, "privates", privates); + } + v8::Local<v8::Object> priv_obj = privates->ToObject(); + v8::Local<v8::Value> chrome(priv_obj->Get(chrome_string)); + if (chrome->IsUndefined()) { + chrome = v8::Object::New(context->isolate()); + v8::Local<v8::String> hidden_key( + v8::String::NewFromUtf8(context->isolate(), "__nw_is_hidden")); + chrome->ToObject()->Set(hidden_key, v8::Boolean::New(context->isolate(), true)); + priv_obj->Set(chrome_string, chrome); + } + return chrome; } - return chrome; } // Returns |value| cast to an object if possible, else an empty handle. @@ -192,13 +220,19 @@ class ChromeNativeHandler : public ObjectBackedNativeHandler { } void GetChrome(const v8::FunctionCallbackInfo<v8::Value>& args) { - args.GetReturnValue().Set(GetOrCreateChrome(context())); + args.GetReturnValue().Set(GetOrCreateChrome(context(), false)); } }; base::LazyInstance<WorkerScriptContextSet> g_worker_script_context_set = LAZY_INSTANCE_INITIALIZER; +int nw_uv_run(void* loop, int mode) { + v8::MicrotasksScope microtasks(v8::Isolate::GetCurrent(), v8::MicrotasksScope::kDoNotRunMicrotasks); + + return g_uv_run_fn(loop, mode); +} + } // namespace // Note that we can't use Blink public APIs in the constructor becase Blink @@ -264,6 +298,8 @@ Dispatcher::Dispatcher(DispatcherDelegate* delegate) func(extension_resource_scheme); } + g_set_uv_run_fn(nw_uv_run); + // For extensions, we want to ensure we call the IdleHandler every so often, // even if the extension keeps up activity. if (set_idle_notifications_) { @@ -333,16 +369,23 @@ void Dispatcher::DidCreateScriptContext( // lazily evalulate to Event from event_bindings.js. For extensions only // though, not all webpages! if (context->extension()) { - v8::Local<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context)); + v8::Local<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context, false)); if (!chrome.IsEmpty()) module_system->SetLazyField(chrome, "Event", kEventBindings, "Event"); + + if (context->extension()->GetType() == Manifest::TYPE_NWJS_APP && + context->context_type() == Feature::BLESSED_EXTENSION_CONTEXT) { + + nw::ContextCreationHook(frame, context); + } } UpdateBindingsForContext(context); bool is_within_platform_app = IsWithinPlatformApp(); // Inject custom JS into the platform app context. - if (is_within_platform_app) { + if (is_within_platform_app && context->extension() && + context->extension()->GetType() != Manifest::TYPE_NWJS_APP) { module_system->Require("platformApp"); } @@ -485,6 +528,15 @@ void Dispatcher::WillReleaseScriptContext( if (!context) return; + //FIXME: upstream removed unload_event: we should check our event + //f66545e9e5d0308c15f51764e311425894e3ad09 + + if (context && context->extension() && + context->extension()->is_nwjs_app() && + script_context_set_->size() == 1) { + nw::OnRenderProcessShutdownHook(context); + } + // TODO(kalman): Make |request_sender| use |context->AddInvalidationObserver|. // In fact |request_sender_| should really be owned by ScriptContext. request_sender_->InvalidateSource(context); @@ -504,6 +556,16 @@ void Dispatcher::WillDestroyServiceWorkerContextOnWorkerThread( } } +void Dispatcher::DidFinishDocumentLoad(blink::WebLocalFrame* frame) { + GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL( + frame, frame->document().url(), true /* match_about_blank */); + + const Extension* extension = + RendererExtensionRegistry::Get()->GetExtensionOrAppByURL(effective_document_url); + + nw::DocumentFinishHook(frame, extension, effective_document_url); +} + void Dispatcher::DidCreateDocumentElement(blink::WebLocalFrame* frame) { // Note: use GetEffectiveDocumentURL not just frame->document()->url() // so that this also injects the stylesheet on about:blank frames that @@ -517,6 +579,11 @@ void Dispatcher::DidCreateDocumentElement(blink::WebLocalFrame* frame) { if (extension && (extension->is_extension() || extension->is_platform_app())) { + nw::DocumentElementHook(frame, extension, effective_document_url); + } + + if (extension && !extension->is_nwjs_app() && + (extension->is_extension() || extension->is_platform_app())) { int resource_id = extension->is_platform_app() ? IDR_PLATFORM_APP_CSS : IDR_EXTENSION_FONTS_CSS; std::string stylesheet = ResourceBundle::GetSharedInstance() @@ -600,7 +667,13 @@ void Dispatcher::InvokeModuleSystemMethod(content::RenderFrame* render_frame, if (user_gesture) web_user_gesture.reset(new WebScopedUserGesture); - script_context_set_->ForEach( + // need extension id set to empty for remote pages + if (render_frame && module_name == "nw.Window") + script_context_set_->ForEach( + "", render_frame, + base::Bind(&CallModuleMethod, module_name, function_name, &args)); + else + script_context_set_->ForEach( extension_id, render_frame, base::Bind(&CallModuleMethod, module_name, function_name, &args)); @@ -808,6 +881,17 @@ std::vector<std::pair<std::string, int> > Dispatcher::GetJsResources() { std::make_pair("media_router_bindings", IDR_MEDIA_ROUTER_BINDINGS_JS)); #endif // defined(ENABLE_MEDIA_ROUTER) + resources.push_back(std::make_pair("nw.App", IDR_NWAPI_APP_JS)); + resources.push_back(std::make_pair("nw.Window", IDR_NWAPI_WINDOW_JS)); + resources.push_back(std::make_pair("nw.Clipboard", IDR_NWAPI_CLIPBOARD_JS)); + resources.push_back(std::make_pair("nw.Menu", IDR_NWAPI_MENU_JS)); + resources.push_back(std::make_pair("nw.MenuItem", IDR_NWAPI_MENUITEM_JS)); + resources.push_back(std::make_pair("nw.Screen", IDR_NWAPI_SCREEN_JS)); + resources.push_back(std::make_pair("nw.Shell", IDR_NWAPI_SHELL_JS)); + resources.push_back(std::make_pair("nw.Shortcut", IDR_NWAPI_SHORTCUT_JS)); + resources.push_back(std::make_pair("nw.Obj", IDR_NWAPI_OBJECT_JS)); + resources.push_back(std::make_pair("nw.test", IDR_NWAPI_TEST_JS)); + resources.push_back(std::make_pair("nw.Tray", IDR_NWAPI_TRAY_JS)); return resources; } @@ -867,6 +951,8 @@ void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, std::unique_ptr<NativeHandler>(new FileSystemNatives(context))); // Custom bindings. + module_system->RegisterNativeHandler( + "nw_natives", std::unique_ptr<NativeHandler>(new NWCustomBindings(context))); module_system->RegisterNativeHandler( "app_window_natives", std::unique_ptr<NativeHandler>(new AppWindowCustomBindings(context))); @@ -1057,6 +1143,23 @@ void Dispatcher::OnLoaded( // browser to figure this out itself - but again, cost/benefit. if (!extension_registry->Contains(extension->id())) extension_registry->Insert(extension); + + if (extension->GetType() == Manifest::TYPE_NWJS_APP) { + std::string user_agent; + if (extension->manifest()->GetString("user-agent", &user_agent)) { + std::string name, version; + extension->manifest()->GetString("name", &name); + extension->manifest()->GetString("version", &version); + nw::SetUserAgentOverride(user_agent, name, version); + + int dom_storage_quota_mb; + if (extension->manifest()->GetInteger("dom_storage_quota", &dom_storage_quota_mb)) { + content::DOMStorageMap::SetQuotaOverride(dom_storage_quota_mb * 1024 * 1024); + } + } + VLOG(1) << "NW: change working dir: " << extension->path().AsUTF8Unsafe(); + base::SetCurrentDirectory(extension->path()); + } } // Update the available bindings for all contexts. These may have changed if @@ -1308,6 +1411,12 @@ void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { v8::HandleScope handle_scope(context->isolate()); v8::Context::Scope context_scope(context->v8_context()); + bool nodejs_enabled = false; + if (context->extension()) { + nodejs_enabled = context->extension()->is_nwjs_app(); + context->extension()->manifest()->GetBoolean(manifest_keys::kNWJSEnableNode, &nodejs_enabled); + } + // TODO(kalman): Make the bindings registration have zero overhead then run // the same code regardless of context type. switch (context->context_type()) { @@ -1319,6 +1428,11 @@ void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { // All of the same permission checks will still apply. if (context->GetAvailability("app").is_available()) RegisterBinding("app", context); + if (!context->GetAvailability("app.window").is_available()) { + RegisterBinding("app.window", context, true); + RegisterBinding("nw.Window", context, true); + RegisterBinding("runtime", context, true); + } if (context->GetAvailability("webstore").is_available()) RegisterBinding("webstore", context); if (context->GetAvailability("dashboardPrivate").is_available()) @@ -1337,6 +1451,8 @@ void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { const FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures(); for (const auto& map_entry : api_feature_provider->GetAllFeatures()) { + if (map_entry.first.substr(0, 3) == "nw." && !nodejs_enabled) + continue; // Internal APIs are included via require(api_name) from internal code // rather than chrome[api_name]. if (map_entry.second->IsInternal()) @@ -1367,10 +1483,11 @@ void Dispatcher::UpdateBindingsForContext(ScriptContext* context) { } void Dispatcher::RegisterBinding(const std::string& api_name, - ScriptContext* context) { + ScriptContext* context, + bool hidden) { std::string bind_name; v8::Local<v8::Object> bind_object = - GetOrCreateBindObjectIfAvailable(api_name, &bind_name, context); + GetOrCreateBindObjectIfAvailable(api_name, &bind_name, context, hidden); // Empty if the bind object failed to be created, probably because the // extension overrode chrome with a non-object, e.g. window.chrome = true. @@ -1513,7 +1630,8 @@ v8::Local<v8::Object> Dispatcher::GetOrCreateObject( v8::Local<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( const std::string& api_name, std::string* bind_name, - ScriptContext* context) { + ScriptContext* context, + bool hidden) { std::vector<std::string> split = base::SplitString( api_name, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); @@ -1534,9 +1652,15 @@ v8::Local<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( std::string ancestor_name; bool only_ancestor_available = false; - for (size_t i = 0; i < split.size() - 1; ++i) { + const char* prefix = nullptr; + int start = 0; + if (split[0] == "nw") { + prefix = "nw"; + start = 1; + } + for (size_t i = start; i < split.size() - 1; ++i) { ancestor_name += (i ? "." : "") + split[i]; - if (api_feature_provider->GetFeature(ancestor_name) && + if (api_feature_provider->GetFeature(ancestor_name) && !hidden && context->GetAvailability(ancestor_name).is_available() && !context->GetAvailability(api_name).is_available()) { only_ancestor_available = true; @@ -1544,7 +1668,7 @@ v8::Local<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( } if (bind_object.IsEmpty()) { - bind_object = AsObjectOrEmpty(GetOrCreateChrome(context)); + bind_object = AsObjectOrEmpty(GetOrCreateChrome(context, hidden, prefix)); if (bind_object.IsEmpty()) return v8::Local<v8::Object>(); } @@ -1557,7 +1681,7 @@ v8::Local<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable( if (bind_name) *bind_name = split.back(); - return bind_object.IsEmpty() ? AsObjectOrEmpty(GetOrCreateChrome(context)) + return bind_object.IsEmpty() ? AsObjectOrEmpty(GetOrCreateChrome(context, hidden, prefix)) : bind_object; } diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index 6438d64f13e0b..1a2f6e8ebe086 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h @@ -110,6 +110,7 @@ class Dispatcher : public content::RenderThreadObserver, // This method is not allowed to run JavaScript code in the frame. void DidCreateDocumentElement(blink::WebLocalFrame* frame); + void DidFinishDocumentLoad(blink::WebLocalFrame* frame); // These methods may run (untrusted) JavaScript code in the frame, and // cause |render_frame| to become invalid. @@ -220,7 +221,7 @@ class Dispatcher : public content::RenderThreadObserver, void UpdateBindingsForContext(ScriptContext* context); - void RegisterBinding(const std::string& api_name, ScriptContext* context); + void RegisterBinding(const std::string& api_name, ScriptContext* context, bool hidden = false); void RegisterNativeHandlers(ModuleSystem* module_system, ScriptContext* context); @@ -248,7 +249,9 @@ class Dispatcher : public content::RenderThreadObserver, v8::Local<v8::Object> GetOrCreateBindObjectIfAvailable( const std::string& api_name, std::string* bind_name, - ScriptContext* context); + ScriptContext* context, + bool hidden = false + ); // Requires the GuestView modules in the module system of the ScriptContext // |context|. diff --git a/extensions/renderer/event_bindings.cc b/extensions/renderer/event_bindings.cc index de99257c3824e..22c7198e6a3f6 100644 --- a/extensions/renderer/event_bindings.cc +++ b/extensions/renderer/event_bindings.cc @@ -188,8 +188,8 @@ void EventBindings::AttachEventHandler( } void EventBindings::AttachEvent(const std::string& event_name) { - if (!context()->HasAccessOrThrowError(event_name)) - return; + //if (!context()->HasAccessOrThrowError(event_name)) + // return; // Record the attachment for this context so that events can be detached when // the context is destroyed. @@ -256,8 +256,8 @@ void EventBindings::AttachFilteredEvent( CHECK(args[1]->IsObject()); std::string event_name = *v8::String::Utf8Value(args[0]); - if (!context()->HasAccessOrThrowError(event_name)) - return; + //if (!context()->HasAccessOrThrowError(event_name)) + // return; std::unique_ptr<base::DictionaryValue> filter; { diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc index ba47a7c748870..e01e9457e788f 100644 --- a/extensions/renderer/extension_frame_helper.cc +++ b/extensions/renderer/extension_frame_helper.cc @@ -20,6 +20,8 @@ #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "content/nw/src/nw_content.h" + namespace extensions { namespace { @@ -47,9 +49,9 @@ bool RenderFrameMatches(const ExtensionFrameHelper* frame_helper, frame_helper->render_frame()->GetWebFrame()->getSecurityOrigin(); if (origin.isUnique() || !base::EqualsASCII(base::StringPiece16(origin.protocol()), - kExtensionScheme) || + kExtensionScheme) || (!match_extension_id.empty() && !base::EqualsASCII(base::StringPiece16(origin.host()), - match_extension_id.c_str())) + match_extension_id.c_str()))) return false; if (match_window_id != extension_misc::kUnknownWindowId && @@ -134,6 +136,13 @@ void ExtensionFrameHelper::DidCreateDocumentElement() { did_create_current_document_element_ = true; extension_dispatcher_->DidCreateDocumentElement( render_frame()->GetWebFrame()); + nw::DocumentHook2(true, render_frame(), extension_dispatcher_); +} + +void ExtensionFrameHelper::DidFinishDocumentLoad() { + extension_dispatcher_->DidFinishDocumentLoad( + render_frame()->GetWebFrame()); + nw::DocumentHook2(false, render_frame(), extension_dispatcher_); } void ExtensionFrameHelper::DidCreateNewDocument() { diff --git a/extensions/renderer/extension_frame_helper.h b/extensions/renderer/extension_frame_helper.h index 57ac3b66b23aa..2b3b9eebae3f8 100644 --- a/extensions/renderer/extension_frame_helper.h +++ b/extensions/renderer/extension_frame_helper.h @@ -84,6 +84,7 @@ class ExtensionFrameHelper // RenderFrameObserver implementation. void DidCreateDocumentElement() override; void DidCreateNewDocument() override; + void DidFinishDocumentLoad() override; void DidMatchCSS( const blink::WebVector<blink::WebString>& newly_matching_selectors, const blink::WebVector<blink::WebString>& stopped_matching_selectors) diff --git a/extensions/renderer/i18n_custom_bindings.cc b/extensions/renderer/i18n_custom_bindings.cc index d17e94b60458e..6200dcb90e2c6 100644 --- a/extensions/renderer/i18n_custom_bindings.cc +++ b/extensions/renderer/i18n_custom_bindings.cc @@ -29,7 +29,7 @@ using namespace v8_helpers; namespace { // Max number of languages detected by CLD2. -const int kCldNumLangs = 3; +//const int kCldNumLangs = 3; struct DetectedLanguage { DetectedLanguage(const std::string& language, int percentage) @@ -95,6 +95,7 @@ v8::Local<v8::Value> LanguageDetectionResult::ToValue(ScriptContext* context) { return handle_scope.Escape(result); } +#if 0 void InitDetectedLanguages( CLD2::Language* languages, int* percents, @@ -116,6 +117,7 @@ void InitDetectedLanguages( base::WrapUnique(new DetectedLanguage(language_code, percents[i]))); } } +#endif } // namespace @@ -204,6 +206,10 @@ void I18NCustomBindings::DetectTextLanguage( CHECK(args.Length() == 1); CHECK(args[0]->IsString()); +#if 1 + LanguageDetectionResult result(false); + args.GetReturnValue().Set(result.ToValue(context())); +#else std::string text = *v8::String::Utf8Value(args[0]); CLD2::CLDHints cldhints = {nullptr, "", CLD2::UNKNOWN_ENCODING, CLD2::UNKNOWN_LANGUAGE}; @@ -242,6 +248,7 @@ void I18NCustomBindings::DetectTextLanguage( InitDetectedLanguages(languages, percents, &result.languages); args.GetReturnValue().Set(result.ToValue(context())); +#endif } } // namespace extensions diff --git a/extensions/renderer/object_backed_native_handler.h b/extensions/renderer/object_backed_native_handler.h index 974abe18600cc..06c4a0764e222 100644 --- a/extensions/renderer/object_backed_native_handler.h +++ b/extensions/renderer/object_backed_native_handler.h @@ -69,6 +69,7 @@ class ObjectBackedNativeHandler : public NativeHandler { const v8::Local<v8::Object>& object, bool allow_null_context); + public: // The following methods are convenience wrappers for methods on v8::Object // with the corresponding names. void SetPrivate(v8::Local<v8::Object> obj, diff --git a/extensions/renderer/render_frame_observer_natives.cc b/extensions/renderer/render_frame_observer_natives.cc index bd5d2377fadb1..988e6cc6f5834 100644 --- a/extensions/renderer/render_frame_observer_natives.cc +++ b/extensions/renderer/render_frame_observer_natives.cc @@ -11,6 +11,7 @@ #include "content/public/renderer/render_frame_observer.h" #include "extensions/renderer/extension_frame_helper.h" #include "extensions/renderer/script_context.h" +#include "extensions/renderer/script_context_set.h" namespace extensions { @@ -20,14 +21,21 @@ namespace { class LoadWatcher : public content::RenderFrameObserver { public: LoadWatcher(content::RenderFrame* frame, - const base::Callback<void(bool)>& callback) - : content::RenderFrameObserver(frame), callback_(callback) {} + const base::Callback<void(bool, int)>& callback, bool wait_for_next = false) + : content::RenderFrameObserver(frame), callback_(callback), wait_for_next_(wait_for_next) {} void DidCreateDocumentElement() override { + if (wait_for_next_) { + base::MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(&LoadWatcher::DidCreateDocumentElement, base::Unretained(this))); + wait_for_next_ = false; + return; + } // Defer the callback instead of running it now to avoid re-entrancy caused // by the JavaScript callback. + int id = routing_id(); ExtensionFrameHelper::Get(render_frame()) - ->ScheduleAtDocumentStart(base::Bind(callback_, true)); + ->ScheduleAtDocumentStart(base::Bind(callback_, true, id)); delete this; } @@ -35,16 +43,55 @@ class LoadWatcher : public content::RenderFrameObserver { // Use PostTask to avoid running user scripts while handling this // DidFailProvisionalLoad notification. base::MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(callback_, false)); + base::Bind(callback_, false, routing_id())); delete this; } private: - base::Callback<void(bool)> callback_; + base::Callback<void(bool, int)> callback_; + bool wait_for_next_; DISALLOW_COPY_AND_ASSIGN(LoadWatcher); }; +class CloseWatcher : public content::RenderFrameObserver { + public: + CloseWatcher(ScriptContext* context, + content::RenderFrame* frame, + v8::Local<v8::Function> cb) + : content::RenderFrameObserver(frame), + context_(context->weak_factory_.GetWeakPtr()), + callback_(context->isolate(), cb) + { + } + + void OnDestruct() override { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&CloseWatcher::CallbackAndDie, base::Unretained(this), + routing_id())); + } + + private: + void CallbackAndDie(int routing_id) { + if (context_ && context_->is_valid()) { + // context_ was deleted when running + // issue4007-reload-lost-app-window in test framework + v8::Isolate* isolate = context_->isolate(); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Value> args[] = {v8::Integer::New(isolate, routing_id)}; + context_->CallFunction(v8::Local<v8::Function>::New(isolate, callback_), + arraysize(args), args); + } + delete this; + } + + base::WeakPtr<ScriptContext> context_; + v8::Global<v8::Function> callback_; + + DISALLOW_COPY_AND_ASSIGN(CloseWatcher); +}; + } // namespace RenderFrameObserverNatives::RenderFrameObserverNatives(ScriptContext* context) @@ -53,6 +100,10 @@ RenderFrameObserverNatives::RenderFrameObserverNatives(ScriptContext* context) "OnDocumentElementCreated", "app.window", base::Bind(&RenderFrameObserverNatives::OnDocumentElementCreated, base::Unretained(this))); + RouteFunction( + "OnDestruct", + base::Bind(&RenderFrameObserverNatives::OnDestruct, + base::Unretained(this))); } RenderFrameObserverNatives::~RenderFrameObserverNatives() {} @@ -64,9 +115,11 @@ void RenderFrameObserverNatives::Invalidate() { void RenderFrameObserverNatives::OnDocumentElementCreated( const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(args.Length() == 2); CHECK(args[0]->IsInt32()); CHECK(args[1]->IsFunction()); + bool wait_for_next = false; + if (args.Length() > 2) + wait_for_next = args[2]->BooleanValue(); int frame_id = args[0]->Int32Value(); @@ -78,17 +131,17 @@ void RenderFrameObserverNatives::OnDocumentElementCreated( v8::Global<v8::Function> v8_callback(context()->isolate(), args[1].As<v8::Function>()); - base::Callback<void(bool)> callback( + base::Callback<void(bool, int)> callback( base::Bind(&RenderFrameObserverNatives::InvokeCallback, weak_ptr_factory_.GetWeakPtr(), base::Passed(&v8_callback))); - if (ExtensionFrameHelper::Get(frame)->did_create_current_document_element()) { + if (!wait_for_next && ExtensionFrameHelper::Get(frame)->did_create_current_document_element()) { // If the document element is already created, then we can call the callback // immediately (though use PostTask to ensure that the callback is called // asynchronously). base::MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(callback, true)); + base::Bind(callback, true, frame_id)); } else { - new LoadWatcher(frame, callback); + new LoadWatcher(frame, callback, wait_for_next); } args.GetReturnValue().Set(true); @@ -96,12 +149,32 @@ void RenderFrameObserverNatives::OnDocumentElementCreated( void RenderFrameObserverNatives::InvokeCallback( v8::Global<v8::Function> callback, - bool succeeded) { + bool succeeded, int frame_id) { v8::Isolate* isolate = context()->isolate(); v8::HandleScope handle_scope(isolate); - v8::Local<v8::Value> args[] = {v8::Boolean::New(isolate, succeeded)}; + v8::Local<v8::Value> args[] = {v8::Boolean::New(isolate, succeeded), v8::Integer::New(isolate, frame_id)}; context()->CallFunction(v8::Local<v8::Function>::New(isolate, callback), arraysize(args), args); } +void RenderFrameObserverNatives::OnDestruct( + const v8::FunctionCallbackInfo<v8::Value>& args) { + CHECK(args[0]->IsInt32()); + CHECK(args[1]->IsFunction()); + int frame_id = args[0]->Int32Value(); + + content::RenderFrame* frame = content::RenderFrame::FromRoutingID(frame_id); + if (!frame) { + LOG(WARNING) << "No render frame found to register CloseWatcher. " << frame_id; + return; + } + + v8::Local<v8::Function> func = args[1].As<v8::Function>(); + ScriptContext* context = ScriptContextSet::GetContextByV8Context(func->CreationContext()); + new CloseWatcher(context, frame, args[1].As<v8::Function>()); + + args.GetReturnValue().Set(true); +} + + } // namespace extensions diff --git a/extensions/renderer/render_frame_observer_natives.h b/extensions/renderer/render_frame_observer_natives.h index 4e81e3bc8b772..1b97b69d73a55 100644 --- a/extensions/renderer/render_frame_observer_natives.h +++ b/extensions/renderer/render_frame_observer_natives.h @@ -26,10 +26,13 @@ class RenderFrameObserverNatives : public ObjectBackedNativeHandler { void OnDocumentElementCreated( const v8::FunctionCallbackInfo<v8::Value>& args); - void InvokeCallback(v8::Global<v8::Function> callback, bool succeeded); + void InvokeCallback(v8::Global<v8::Function> callback, bool succeeded, int frame_id); base::WeakPtrFactory<RenderFrameObserverNatives> weak_ptr_factory_; + void OnDestruct( + const v8::FunctionCallbackInfo<v8::Value>& args); + DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverNatives); }; diff --git a/extensions/renderer/request_sender.cc b/extensions/renderer/request_sender.cc index 607d25ab3b2ba..ca9e6464af0fd 100644 --- a/extensions/renderer/request_sender.cc +++ b/extensions/renderer/request_sender.cc @@ -66,6 +66,55 @@ int RequestSender::GetNextRequestId() const { return next_request_id++; } +void RequestSender::StartRequestSync(Source* source, + const std::string& name, + int request_id, + bool has_callback, + bool for_io_thread, + base::ListValue* value_args, + bool* success, + base::ListValue* response, + std::string* error) { + ScriptContext* context = source->GetContext(); + if (!context) + return; + + // Get the current RenderView so that we can send a routed IPC message from + // the correct source. + content::RenderFrame* renderframe = context->GetRenderFrame(); + if (!renderframe) + return; + + // TODO(koz): See if we can make this a CHECK. + if (!context->HasAccessOrThrowError(name)) + return; + + GURL source_url; + if (blink::WebLocalFrame* webframe = context->web_frame()) + source_url = webframe->document().url(); + + // InsertRequest(request_id, new PendingRequest(name, source, + // blink::WebUserGestureIndicator::currentUserGestureToken())); + + ExtensionHostMsg_Request_Params params; + params.name = name; + params.arguments.Swap(value_args); + params.extension_id = context->GetExtensionID(); + params.source_url = source_url; + params.source_tab_id = source_tab_id_; + params.request_id = request_id; + params.has_callback = has_callback; + params.user_gesture = + blink::WebUserGestureIndicator::isProcessingUserGesture(); + if (for_io_thread) { + NOTREACHED() << "not implemented"; + } else { + renderframe->Send( + new ExtensionHostMsg_RequestSync(renderframe->GetRoutingID(), params, + success, response, error)); + } +} + void RequestSender::StartRequest(Source* source, const std::string& name, int request_id, diff --git a/extensions/renderer/request_sender.h b/extensions/renderer/request_sender.h index 85a7ef3ed27ed..b9166529ef139 100644 --- a/extensions/renderer/request_sender.h +++ b/extensions/renderer/request_sender.h @@ -76,6 +76,16 @@ class RequestSender { bool for_io_thread, base::ListValue* value_args); + void StartRequestSync(Source* source, + const std::string& name, + int request_id, + bool has_callback, + bool for_io_thread, + base::ListValue* value_args, + bool* success, + base::ListValue* response, + std::string* error); + // Handles responses from the extension host to calls made by StartRequest(). void HandleResponse(int request_id, bool success, diff --git a/extensions/renderer/resources/app_window_custom_bindings.js b/extensions/renderer/resources/app_window_custom_bindings.js index b0ae54f4a7b3e..28781b8938ef4 100644 --- a/extensions/renderer/resources/app_window_custom_bindings.js +++ b/extensions/renderer/resources/app_window_custom_bindings.js @@ -22,6 +22,13 @@ var kSetSizeConstraintsFunction = 'setSizeConstraints'; var Bounds = function(boundsKey) { privates(this).boundsKey_ = boundsKey; }; + +var try_hidden = function (view) { + if (view.chrome.app.window) + return view; + return privates(view); +}; + Object.defineProperty(Bounds.prototype, 'left', { get: function() { return appWindowData[privates(this).boundsKey_].left; @@ -135,13 +142,13 @@ appWindow.registerCustomHook(function(bindingsAPI) { // Not creating a new window, but activating an existing one, so trigger // callback with existing window and don't do anything else. if (callback) - callback(view.chrome.app.window.current()); + callback(try_hidden(view).chrome.app.window.current()); return; } // Initialize appWindowData in the newly created JS context if (view.chrome.app) { - view.chrome.app.window.initializeAppWindow(windowParams); + try_hidden(view).chrome.app.window.initializeAppWindow(windowParams); } else { var sandbox_window_message = 'Creating sandboxed window, it doesn\'t ' + 'have access to the chrome.app API.'; @@ -164,7 +171,12 @@ appWindow.registerCustomHook(function(bindingsAPI) { windowParams.frameId, function(success) { if (success) { - callback(view.chrome.app.window.current()); + var appwin = try_hidden(view).chrome.app.window.current(); + if (!appwin) { + try_hidden(view).chrome.app.window.initializeAppWindow(windowParams); + appwin = try_hidden(view).chrome.app.window.current(); + } + callback(appwin); } else { callback(undefined); } @@ -177,8 +189,6 @@ appWindow.registerCustomHook(function(bindingsAPI) { apiFunctions.setHandleRequest('current', function() { if (!currentAppWindow) { - console.error('The JavaScript context calling ' + - 'chrome.app.window.current() has no associated AppWindow.'); return null; } return currentAppWindow; @@ -187,7 +197,7 @@ appWindow.registerCustomHook(function(bindingsAPI) { apiFunctions.setHandleRequest('getAll', function() { var views = runtimeNatives.GetExtensionViews(-1, 'APP_WINDOW'); return $Array.map(views, function(win) { - return win.chrome.app.window.current(); + return try_hidden(win).chrome.app.window.current(); }); }); @@ -241,6 +251,9 @@ appWindow.registerCustomHook(function(bindingsAPI) { AppWindow.prototype.isFullscreen = function() { return appWindowData.fullscreen; }; + AppWindow.prototype.isResizable = function() { + return appWindowData.resizable; + }; AppWindow.prototype.isMinimized = function() { return appWindowData.minimized; }; @@ -311,6 +324,7 @@ appWindow.registerCustomHook(function(bindingsAPI) { minimized: params.minimized, maximized: params.maximized, alwaysOnTop: params.alwaysOnTop, + resizable: params.resizable, hasFrameColor: params.hasFrameColor, activeFrameColor: params.activeFrameColor, inactiveFrameColor: params.inactiveFrameColor, @@ -327,6 +341,18 @@ function boundsEqual(bounds1, bounds2) { bounds1.width == bounds2.width && bounds1.height == bounds2.height); } +function sizeEqual(bounds1, bounds2) { + if (!bounds1 || !bounds2) + return false; + return (bounds1.width == bounds2.width && bounds1.height == bounds2.height); +} + +function posEqual(bounds1, bounds2) { + if (!bounds1 || !bounds2) + return false; + return (bounds1.left == bounds2.left && bounds1.top == bounds2.top); +} + function dispatchEventIfExists(target, name) { // Sometimes apps like to put their own properties on the window which // break our assumptions. @@ -347,8 +373,13 @@ function updateAppWindowProperties(update) { var currentWindow = currentAppWindow; - if (!boundsEqual(oldData.innerBounds, update.innerBounds)) + if (!boundsEqual(oldData.innerBounds, update.innerBounds)) { dispatchEventIfExists(currentWindow, "onBoundsChanged"); + if (!sizeEqual(oldData.innerBounds, update.innerBounds)) + dispatchEventIfExists(currentWindow, "onResized"); + if (!posEqual(oldData.innerBounds, update.innerBounds)) + dispatchEventIfExists(currentWindow, "onMoved"); + } if (!oldData.fullscreen && update.fullscreen) dispatchEventIfExists(currentWindow, "onFullscreened"); diff --git a/extensions/renderer/resources/binding.js b/extensions/renderer/resources/binding.js index 22f3f583ca953..e7c70c6b49c2e 100644 --- a/extensions/renderer/resources/binding.js +++ b/extensions/renderer/resources/binding.js @@ -384,12 +384,15 @@ Binding.prototype = { apiFunction.definition = functionDef; apiFunction.name = schema.namespace + '.' + functionDef.name; + if (schema.namespace != "app.window" && + schema.namespace != "nw.Window" && + schema.namespace != "runtime") { if (!GetAvailability(apiFunction.name).is_available || (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) { this.apiFunctions_.registerUnavailable(functionDef.name); return; } - + } // TODO(aa): It would be best to run this in a unit test, but in order // to do that we would need to better factor this code so that it // doesn't depend on so much v8::Extension machinery. diff --git a/extensions/renderer/resources/event.js b/extensions/renderer/resources/event.js index 2f9aa3c7a551f..4e7a29bb4d3e1 100644 --- a/extensions/renderer/resources/event.js +++ b/extensions/renderer/resources/event.js @@ -253,6 +253,9 @@ dispatchArgs(args); } + EventImpl.prototype.getListeners = function() { + return this.listeners; + }; // Registers a callback to be called when this event is dispatched. EventImpl.prototype.addListener = function(cb, filters) { if (!this.eventOptions.supportsListeners) @@ -500,6 +503,7 @@ } utils.expose(Event, EventImpl, { functions: [ + 'getListeners', 'addListener', 'removeListener', 'hasListener', diff --git a/extensions/renderer/resources/extensions_renderer_resources.grd b/extensions/renderer/resources/extensions_renderer_resources.grd index 808b931d54244..040cf33215e27 100644 --- a/extensions/renderer/resources/extensions_renderer_resources.grd +++ b/extensions/renderer/resources/extensions_renderer_resources.grd @@ -102,6 +102,18 @@ <include name="IDR_MEDIA_ROUTER_MOJOM_JS" file="${mojom_root}\chrome\browser\media\router\mojo\media_router.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_MEDIA_ROUTER_BINDINGS_JS" file="media_router_bindings.js" type="BINDATA" /> </if> + <include name="IDR_NW_PRE13_SHIM_JS" file="../../../content/nw/src/resources/nw_pre13_shim.js" type="BINDATA" /> + <include name="IDR_NWAPI_APP_JS" file="../../../content/nw/src/resources/api_nw_app.js" type="BINDATA" /> + <include name="IDR_NWAPI_WINDOW_JS" file="../../../content/nw/src/resources/api_nw_window.js" type="BINDATA" /> + <include name="IDR_NWAPI_CLIPBOARD_JS" file="../../../content/nw/src/resources/api_nw_clipboard.js" type="BINDATA" /> + <include name="IDR_NWAPI_MENU_JS" file="../../../content/nw/src/resources/api_nw_menu.js" type="BINDATA" /> + <include name="IDR_NWAPI_MENUITEM_JS" file="../../../content/nw/src/resources/api_nw_menuitem.js" type="BINDATA" /> + <include name="IDR_NWAPI_SCREEN_JS" file="../../../content/nw/src/resources/api_nw_screen.js" type="BINDATA" /> + <include name="IDR_NWAPI_SHORTCUT_JS" file="../../../content/nw/src/resources/api_nw_shortcut.js" type="BINDATA" /> + <include name="IDR_NWAPI_SHELL_JS" file="../../../content/nw/src/resources/api_nw_shell.js" type="BINDATA" /> + <include name="IDR_NWAPI_OBJECT_JS" file="../../../content/nw/src/resources/api_nw_object.js" type="BINDATA" /> + <include name="IDR_NWAPI_TEST_JS" file="../../../content/nw/src/resources/api_nw_test.js" type="BINDATA" /> + <include name="IDR_NWAPI_TRAY_JS" file="../../../content/nw/src/resources/api_nw_tray.js" type="BINDATA" /> </includes> <structures> <!-- Extension styles. --> diff --git a/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js b/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js index a28741b7430da..cd669ed50ce51 100644 --- a/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js +++ b/extensions/renderer/resources/guest_view/web_view/web_view_api_methods.js @@ -52,7 +52,7 @@ var WEB_VIEW_API_METHODS = [ // Returns Chrome's internal process ID for the guest web page's current // process. 'getProcessId', - + 'getGuestId', // Returns the user agent string used by the webview for guest page requests. 'getUserAgent', @@ -78,6 +78,7 @@ var WEB_VIEW_API_METHODS = [ // of the data URL. 'loadDataWithBaseUrl', + 'showDevTools', // Prints the contents of the webview. 'print', @@ -139,6 +140,10 @@ WebViewImpl.prototype.getProcessId = function() { return this.processId; }; +WebViewImpl.prototype.getGuestId = function() { + return this.guest.getId(); +}; + WebViewImpl.prototype.getUserAgent = function() { return this.userAgentOverride || navigator.userAgent; }; @@ -168,6 +173,16 @@ WebViewImpl.prototype.loadDataWithBaseUrl = function( }); }; +WebViewImpl.prototype.showDevTools = function(show, container) { + if (!this.guest.getId()) { + return; + } + if (container) + WebViewInternal.showDevTools(this.guest.getId(), show, container.getProcessId(), container.getGuestId()); + else + WebViewInternal.showDevTools(this.guest.getId(), show); +}; + WebViewImpl.prototype.print = function() { return this.executeScript({code: 'window.print();'}); }; diff --git a/extensions/renderer/resources/last_error.js b/extensions/renderer/resources/last_error.js index 14836b70067ec..a9bc9846e21d1 100644 --- a/extensions/renderer/resources/last_error.js +++ b/extensions/renderer/resources/last_error.js @@ -94,7 +94,7 @@ function assertRuntimeIsAvailable() { throw new Error('runtime.lastError is not available: ' + runtimeAvailability.message); } - if (!chrome.runtime) + if (!chrome.runtime && !privates(window).chrome.runtime) throw new Error('runtime namespace is null or undefined'); } diff --git a/extensions/renderer/resources/send_request.js b/extensions/renderer/resources/send_request.js index 5a9fa965e3ef7..8b17447e774d4 100644 --- a/extensions/renderer/resources/send_request.js +++ b/extensions/renderer/resources/send_request.js @@ -24,11 +24,18 @@ function safeCallbackApply(name, request, callback, args) { } } +var try_hidden = function (view) { + if (view.chrome.runtime) + return view; + return privates(view); +}; + // Callback handling. function handleResponse(requestId, name, success, responseList, error) { // The chrome objects we will set lastError on. Really we should only be // setting this on the callback's chrome object, but set on ours too since // it's conceivable that something relies on that. + var chrome = try_hidden(window).chrome; var callerChrome = chrome; try { @@ -39,7 +46,7 @@ function handleResponse(requestId, name, success, responseList, error) { // though chances are it's the same as ours (it will be different when // calling API methods on other contexts). if (request.callback) { - var global = natives.GetGlobal(request.callback); + var global = try_hidden(natives.GetGlobal(request.callback)); callerChrome = global ? global.chrome : callerChrome; } @@ -131,6 +138,26 @@ function sendRequest(functionName, args, argSchemas, optArgs) { requests[requestId] = request; } +function sendRequestSync(functionName, args, argSchemas, optArgs) { + if (!optArgs) + optArgs = {}; + var request = prepareRequest(args, argSchemas); + request.stack = optArgs.stack || exceptionHandler.getExtensionStackTrace(); + if (optArgs.customCallback) { + request.customCallback = optArgs.customCallback; + } + + //var requestId = natives.GetNextRequestId(); + //request.id = requestId; + + var hasCallback = request.callback || optArgs.customCallback; + return natives.StartRequestSync(functionName, + request.args, + hasCallback, + optArgs.forIOThread, + optArgs.preserveNullInObjects); +} + function getCalledSendRequest() { return calledSendRequest; } @@ -140,6 +167,7 @@ function clearCalledSendRequest() { } exports.$set('sendRequest', sendRequest); +exports.$set('sendRequestSync', sendRequestSync); exports.$set('getCalledSendRequest', getCalledSendRequest); exports.$set('clearCalledSendRequest', clearCalledSendRequest); exports.$set('safeCallbackApply', safeCallbackApply); diff --git a/extensions/renderer/runtime_custom_bindings.cc b/extensions/renderer/runtime_custom_bindings.cc index 6efae5f182d9f..509a50da109ad 100644 --- a/extensions/renderer/runtime_custom_bindings.cc +++ b/extensions/renderer/runtime_custom_bindings.cc @@ -5,6 +5,7 @@ #include "extensions/renderer/runtime_custom_bindings.h" #include <stdint.h> +#include "extensions/renderer/script_context_set.h" #include <memory> @@ -139,8 +140,13 @@ void RuntimeCustomBindings::GetExtensionViews( } const std::string& extension_id = context()->GetExtensionID(); - if (extension_id.empty()) - return; + // id is empty while calling from external page. we want to do + // this for window controlling. note the case that there are + // multiple extensions in the process, e.g. the automation extension + // for chromedriver + + // if (extension_id.empty()) + // return; std::vector<content::RenderFrame*> frames = ExtensionFrameHelper::GetExtensionFrames(extension_id, browser_window_id, @@ -162,6 +168,11 @@ void RuntimeCustomBindings::GetExtensionViews( v8::Local<v8::Context> context = web_frame->mainWorldScriptContext(); if (!context.IsEmpty()) { + if (extension_id.empty()) { + ScriptContext* ctx = ScriptContextSet::GetContextByV8Context(context); + if (!ctx->extension()->is_nwjs_app()) + continue; + } v8::Local<v8::Value> window = context->Global(); CHECK(!window.IsEmpty()); v8::Maybe<bool> maybe = diff --git a/extensions/renderer/script_context.cc b/extensions/renderer/script_context.cc index 529c5fcd40cba..465f35a4d1b1d 100644 --- a/extensions/renderer/script_context.cc +++ b/extensions/renderer/script_context.cc @@ -109,7 +109,8 @@ ScriptContext::ScriptContext(const v8::Local<v8::Context>& v8_context, safe_builtins_(this), isolate_(v8_context->GetIsolate()), url_(web_frame_ ? GetDataSourceURLForFrame(web_frame_) : GURL()), - runner_(new Runner(this)) { + runner_(new Runner(this)), + weak_factory_(this) { VLOG(1) << "Created context:\n" << GetDebugString(); gin::PerContextData* gin_data = gin::PerContextData::From(v8_context); CHECK(gin_data); @@ -273,7 +274,13 @@ GURL ScriptContext::GetDataSourceURLForFrame(const blink::WebFrame* frame) { blink::WebDataSource* data_source = frame->provisionalDataSource() ? frame->provisionalDataSource() : frame->dataSource(); - return data_source ? GURL(data_source->request().url()) : GURL(); + GURL ret = data_source ? GURL(data_source->request().url()) : GURL(); +#if 0 + //nwjs: iframe url + if (!ret.is_valid() || ret.is_empty()) + ret = frame->document().url(); +#endif + return ret; } // static @@ -283,7 +290,9 @@ GURL ScriptContext::GetEffectiveDocumentURL(const blink::WebFrame* frame, // Common scenario. If |match_about_blank| is false (as is the case in most // extensions), or if the frame is not an about:-page, just return // |document_url| (supposedly the URL of the frame). - if (!match_about_blank || !document_url.SchemeIs(url::kAboutScheme)) + + // nwjs: iframe's document_url is invalid here + if (!match_about_blank || (!document_url.SchemeIs(url::kAboutScheme) && document_url.is_valid())) return document_url; // Non-sandboxed about:blank and about:srcdoc pages inherit their security @@ -381,6 +390,9 @@ bool ScriptContext::HasAccessOrThrowError(const std::string& name) { return false; } + if (extension() && extension()->is_nwjs_app()) + return true; + Feature::Availability availability = GetAvailability(name); if (!availability.is_available()) { isolate()->ThrowException(v8::Exception::Error( diff --git a/extensions/renderer/script_context.h b/extensions/renderer/script_context.h index bbfd2f6b90edb..9620e54cb0df2 100644 --- a/extensions/renderer/script_context.h +++ b/extensions/renderer/script_context.h @@ -250,6 +250,8 @@ class ScriptContext : public RequestSender::Source { std::unique_ptr<Runner> runner_; base::ThreadChecker thread_checker_; + public: + base::WeakPtrFactory<ScriptContext> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ScriptContext); }; diff --git a/extensions/renderer/script_context_set.cc b/extensions/renderer/script_context_set.cc index 33df67e58d19b..c940c2c6f171c 100644 --- a/extensions/renderer/script_context_set.cc +++ b/extensions/renderer/script_context_set.cc @@ -45,7 +45,7 @@ ScriptContext* ScriptContextSet::Register( GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame); Feature::Context context_type = ClassifyJavaScriptContext(extension, extension_group, frame_url, - frame->document().getSecurityOrigin()); + frame->document().getSecurityOrigin(), frame); Feature::Context effective_context_type = ClassifyJavaScriptContext( effective_extension, extension_group, ScriptContext::GetEffectiveDocumentURL(frame, frame_url, true), @@ -161,7 +161,9 @@ Feature::Context ScriptContextSet::ClassifyJavaScriptContext( const Extension* extension, int extension_group, const GURL& url, - const blink::WebSecurityOrigin& origin) { + const blink::WebSecurityOrigin& origin, + const blink::WebLocalFrame* frame + ) { // WARNING: This logic must match ProcessMap::GetContextType, as much as // possible. @@ -180,7 +182,7 @@ Feature::Context ScriptContextSet::ClassifyJavaScriptContext( // before the SecurityContext is updated with the sandbox flags (after // reading the CSP header), so the caller can't check if the context's // security origin is unique yet. - if (ScriptContext::IsSandboxedPage(url)) + if (ScriptContext::IsSandboxedPage(url) || (frame && frame->isNwDisabledChildFrame())) return Feature::WEB_PAGE_CONTEXT; if (extension && active_extension_ids_->count(extension->id()) > 0) { diff --git a/extensions/renderer/script_context_set.h b/extensions/renderer/script_context_set.h index 355139747a434..e9eb1449f2cfd 100644 --- a/extensions/renderer/script_context_set.h +++ b/extensions/renderer/script_context_set.h @@ -124,7 +124,9 @@ class ScriptContextSet { const Extension* extension, int extension_group, const GURL& url, - const blink::WebSecurityOrigin& origin); + const blink::WebSecurityOrigin& origin, + const blink::WebLocalFrame* frame = nullptr + ); // Helper for OnExtensionUnloaded(). void RecordAndRemove(std::set<ScriptContext*>* removed, diff --git a/extensions/renderer/send_request_natives.cc b/extensions/renderer/send_request_natives.cc index 2f9d2f5c08a74..80a0d48a18547 100644 --- a/extensions/renderer/send_request_natives.cc +++ b/extensions/renderer/send_request_natives.cc @@ -21,11 +21,61 @@ SendRequestNatives::SendRequestNatives(RequestSender* request_sender, RouteFunction( "StartRequest", base::Bind(&SendRequestNatives::StartRequest, base::Unretained(this))); + RouteFunction( + "StartRequestSync", + base::Bind(&SendRequestNatives::StartRequestSync, base::Unretained(this))); RouteFunction( "GetGlobal", base::Bind(&SendRequestNatives::GetGlobal, base::Unretained(this))); } +void SendRequestNatives::StartRequestSync( + const v8::FunctionCallbackInfo<v8::Value>& args) { + CHECK_EQ(5, args.Length()); + std::string name = *v8::String::Utf8Value(args[0]); + bool has_callback = args[2]->BooleanValue(); + bool for_io_thread = args[3]->BooleanValue(); + bool preserve_null_in_objects = args[4]->BooleanValue(); + + int request_id = request_sender_->GetNextRequestId(); + std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create()); + + // See http://crbug.com/149880. The context menus APIs relies on this, but + // we shouldn't really be doing it (e.g. for the sake of the storage API). + converter->SetFunctionAllowed(true); + + if (!preserve_null_in_objects) + converter->SetStripNullFromObjects(true); + + std::unique_ptr<base::Value> value_args( + converter->FromV8Value(args[1], context()->v8_context())); + if (!value_args.get() || !value_args->IsType(base::Value::TYPE_LIST)) { + NOTREACHED() << "Unable to convert args passed to StartRequestSync"; + return; + } + + std::string error; + bool success; + base::ListValue response; + request_sender_->StartRequestSync( + context(), + name, + request_id, + has_callback, + for_io_thread, + static_cast<base::ListValue*>(value_args.get()), + &success, + &response, &error + ); + if (!success) { + args.GetIsolate()->ThrowException( + v8::String::NewFromUtf8(args.GetIsolate(), error.c_str())); + return; + } + args.GetReturnValue().Set(converter->ToV8Value(&response, + context()->v8_context())); +} + // Starts an API request to the browser, with an optional callback. The // callback will be dispatched to EventBindings::HandleResponse. void SendRequestNatives::StartRequest( diff --git a/extensions/renderer/send_request_natives.h b/extensions/renderer/send_request_natives.h index 69212e1dbb135..4a460866a1b68 100644 --- a/extensions/renderer/send_request_natives.h +++ b/extensions/renderer/send_request_natives.h @@ -23,6 +23,7 @@ class SendRequestNatives : public ObjectBackedNativeHandler { // Starts an API request to the browser, with an optional callback. The // callback will be dispatched to EventBindings::HandleResponse. void StartRequest(const v8::FunctionCallbackInfo<v8::Value>& args); + void StartRequestSync(const v8::FunctionCallbackInfo<v8::Value>& args); // Gets a reference to an object's global object. void GetGlobal(const v8::FunctionCallbackInfo<v8::Value>& args); diff --git a/extensions/renderer/user_script_injector.cc b/extensions/renderer/user_script_injector.cc index 1910548ba24b3..20ff6e88d2d24 100644 --- a/extensions/renderer/user_script_injector.cc +++ b/extensions/renderer/user_script_injector.cc @@ -126,7 +126,7 @@ UserScript::InjectionType UserScriptInjector::script_type() const { } bool UserScriptInjector::ShouldExecuteInMainWorld() const { - return false; + return script_->in_main_world(); } bool UserScriptInjector::IsUserGesture() const { diff --git a/extensions/renderer/v8_context_native_handler.cc b/extensions/renderer/v8_context_native_handler.cc index 6124311e5619e..232b8be1f693f 100644 --- a/extensions/renderer/v8_context_native_handler.cc +++ b/extensions/renderer/v8_context_native_handler.cc @@ -31,6 +31,18 @@ void V8ContextNativeHandler::GetAvailability( v8::Isolate* isolate = args.GetIsolate(); std::string api_name = *v8::String::Utf8Value(args[0]); Feature::Availability availability = context_->GetAvailability(api_name); + if (api_name == "app.window" || api_name == "nw.Window" || + api_name == "runtime") { + v8::Local<v8::Object> ret = v8::Object::New(isolate); + ret->Set(v8::String::NewFromUtf8(isolate, "is_available"), + v8::Boolean::New(isolate, true)); + ret->Set(v8::String::NewFromUtf8(isolate, "message"), + v8::String::NewFromUtf8(isolate, "")); + ret->Set(v8::String::NewFromUtf8(isolate, "result"), + v8::Integer::New(isolate, Feature::IS_AVAILABLE)); + args.GetReturnValue().Set(ret); + return; + } v8::Local<v8::Object> ret = v8::Object::New(isolate); v8::Maybe<bool> maybe = diff --git a/ios/chrome/browser/snapshots/snapshot_cache.mm b/ios/chrome/browser/snapshots/snapshot_cache.mm index d6537ccab69c7..acbfe4666b0be 100644 --- a/ios/chrome/browser/snapshots/snapshot_cache.mm +++ b/ios/chrome/browser/snapshots/snapshot_cache.mm @@ -45,7 +45,7 @@ - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID; @end namespace { -static NSArray* const kSnapshotCacheDirectory = @[ @"Chromium", @"Snapshots" ]; +static NSArray* const kSnapshotCacheDirectory = @[ @"nwjs", @"Snapshots" ]; const NSUInteger kCacheInitialCapacity = 100; const NSUInteger kGreyInitialCapacity = 8; diff --git a/ipc/ipc_logging.cc b/ipc/ipc_logging.cc index 693c71d072b2e..709945e5fc86d 100644 --- a/ipc/ipc_logging.cc +++ b/ipc/ipc_logging.cc @@ -242,7 +242,7 @@ void Logging::Log(const LogData& data) { } } } - if (enabled_on_stderr_) { + if (enabled_on_stderr_ && !sender_) { std::string message_name; if (data.message_name.empty()) { message_name = base::StringPrintf("[unknown type %d]", data.type); diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc index 07a49a234b010..1350ad7a8c527 100644 --- a/net/cert/cert_verify_proc_mac.cc +++ b/net/cert/cert_verify_proc_mac.cc @@ -5,6 +5,7 @@ #include "net/cert/cert_verify_proc_mac.h" #include <CommonCrypto/CommonDigest.h> +#include <CoreFoundation/CFArray.h> #include <CoreServices/CoreServices.h> #include <Security/Security.h> @@ -15,6 +16,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/mac/mac_logging.h" +#include "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/sha1.h" #include "base/strings/string_piece.h" @@ -377,6 +379,7 @@ bool CheckRevocationWithCRLSet(CFArrayRef chain, CRLSet* crl_set) { int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, CFArrayRef trust_policies, int flags, + const CertificateList& additional_trust_anchors, ScopedCFTypeRef<SecTrustRef>* trust_ref, SecTrustResultType* trust_result, ScopedCFTypeRef<CFArrayRef>* verified_chain, @@ -394,6 +397,23 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, return NetErrorFromOSStatus(status); } + if (!additional_trust_anchors.empty()) { + // Code from TestRootCerts::FixupSecTrustRef in test_root_certs_mac.cc + base::ScopedCFTypeRef<CFMutableArrayRef> temporary_roots( + CFArrayCreateMutable(kCFAllocatorDefault, additional_trust_anchors.size(), &kCFTypeArrayCallBacks)); + for (size_t i=0; i<additional_trust_anchors.size(); i++) { + CFArrayAppendValue(temporary_roots, additional_trust_anchors[i]->os_cert_handle()); + } + + status = SecTrustSetAnchorCertificates(tmp_trust, temporary_roots); + if (status) + return NetErrorFromOSStatus(status); + + status = SecTrustSetAnchorCertificatesOnly(tmp_trust, false); + if (status) + return NetErrorFromOSStatus(status); + } + CSSM_APPLE_TP_ACTION_DATA tp_action_data; memset(&tp_action_data, 0, sizeof(tp_action_data)); tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION; @@ -522,7 +542,7 @@ CertVerifyProcMac::CertVerifyProcMac() {} CertVerifyProcMac::~CertVerifyProcMac() {} bool CertVerifyProcMac::SupportsAdditionalTrustAnchors() const { - return false; + return true; } bool CertVerifyProcMac::SupportsOCSPStapling() const { @@ -615,6 +635,7 @@ int CertVerifyProcMac::VerifyInternal( CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL; int rv = BuildAndEvaluateSecTrustRef(cert_array, trust_policies, flags, + additional_trust_anchors, &temp_ref, &temp_trust_result, &temp_chain, &temp_chain_info); if (rv != OK) diff --git a/net/cert/cert_verify_proc_win.cc b/net/cert/cert_verify_proc_win.cc index bb1b4813ecec9..aa4f9e5ba6a03 100644 --- a/net/cert/cert_verify_proc_win.cc +++ b/net/cert/cert_verify_proc_win.cc @@ -862,7 +862,7 @@ CertVerifyProcWin::CertVerifyProcWin() {} CertVerifyProcWin::~CertVerifyProcWin() {} bool CertVerifyProcWin::SupportsAdditionalTrustAnchors() const { - return false; + return true; } bool CertVerifyProcWin::SupportsOCSPStapling() const { @@ -1075,8 +1075,34 @@ int CertVerifyProcWin::VerifyInternal( ScopedPCCERT_CHAIN_CONTEXT scoped_chain_context(chain_context); + DWORD errorStatus = chain_context->TrustStatus.dwErrorStatus; + bool skipPolicyCheck = false; + if ((errorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT) && + !additional_trust_anchors.empty()) { + // check if the (untrusted) validated root is in the list of + // additional trust anchors + PCERT_SIMPLE_CHAIN first_chain = chain_context->rgpChain[0]; + DWORD num_elements = first_chain->cElement; + if (num_elements >= 1) { + PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; + PCCERT_CONTEXT cert = element[num_elements - 1]->pCertContext; + for (size_t i=0; i<additional_trust_anchors.size(); i++) { + if (net::X509Certificate::IsSameOSCert(cert, + additional_trust_anchors[i]->os_cert_handle())) { + LOG(INFO) << "Untrusted root \"" << + additional_trust_anchors[i]->subject().GetDisplayName() << + "\" found in additional anchors, assuming trusted."; + verify_result->is_issued_by_additional_trust_anchor = true; + errorStatus &= ~CERT_TRUST_IS_UNTRUSTED_ROOT; + skipPolicyCheck = true; + break; + } + } + } + } + verify_result->cert_status |= MapCertChainErrorStatusToCertStatus( - chain_context->TrustStatus.dwErrorStatus); + errorStatus); // Flag certificates that have a Subject common name with a NULL character. if (CertSubjectCommonNameHasNull(cert_handle)) @@ -1084,6 +1110,7 @@ int CertVerifyProcWin::VerifyInternal( base::string16 hostname16 = base::ASCIIToUTF16(hostname); + if (!skipPolicyCheck) { SSL_EXTRA_CERT_CHAIN_POLICY_PARA extra_policy_para; memset(&extra_policy_para, 0, sizeof(extra_policy_para)); extra_policy_para.cbSize = sizeof(extra_policy_para); @@ -1117,7 +1144,7 @@ int CertVerifyProcWin::VerifyInternal( verify_result->cert_status |= MapNetErrorToCertStatus( MapSecurityError(policy_status.dwError)); } - + } // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be // compatible with WinHTTP, which doesn't report this error (bug 3004). verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM; diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc index 2d650253ddaeb..9d39c9562f35e 100644 --- a/net/cert/multi_threaded_cert_verifier.cc +++ b/net/cert/multi_threaded_cert_verifier.cc @@ -433,7 +433,7 @@ int MultiThreadedCertVerifier::Verify(X509Certificate* cert, requests_++; - const CertificateList empty_cert_list; + const CertificateList empty_cert_list = CertificateList(); const CertificateList& additional_trust_anchors = trust_anchor_provider_ ? trust_anchor_provider_->GetAdditionalTrustAnchors() : empty_cert_list; diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index 3d7124d502e69..25b7aae4748ce 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc @@ -1024,6 +1024,7 @@ bool CookieMonster::IsCookieableScheme(const std::string& scheme) { } const char* const CookieMonster::kDefaultCookieableSchemes[] = {"http", "https", + "chrome-extension", "ws", "wss"}; const int CookieMonster::kDefaultCookieableSchemesCount = arraysize(kDefaultCookieableSchemes); diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc index d4bdabd1416a9..8c674365e5ece 100644 --- a/net/socket/tcp_socket_win.cc +++ b/net/socket/tcp_socket_win.cc @@ -15,6 +15,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/profiler/scoped_tracker.h" +#include "base/win/windows_version.h" #include "net/base/address_list.h" #include "net/base/connection_type_histograms.h" #include "net/base/io_buffer.h" @@ -554,6 +555,22 @@ int TCPSocketWin::SetDefaultOptionsForServer() { } void TCPSocketWin::SetDefaultOptionsForClient() { + // Increase the socket buffer sizes from the default sizes for WinXP. In + // performance testing, there is substantial benefit by increasing from 8KB + // to 64KB. + // See also: + // http://support.microsoft.com/kb/823764/EN-US + // On Vista, if we manually set these sizes, Vista turns off its receive + // window auto-tuning feature. + // http://blogs.msdn.com/wndp/archive/2006/05/05/Winhec-blog-tcpip-2.aspx + // Since Vista's auto-tune is better than any static value we can could set, + // only change these on pre-vista machines. + if (base::win::GetVersion() < base::win::VERSION_VISTA) { + const int32_t kSocketBufferSize = 64 * 1024; + SetSocketReceiveBufferSize(socket_, kSocketBufferSize); + SetSocketSendBufferSize(socket_, kSocketBufferSize); + } + SetTCPNoDelay(socket_, /*no_delay=*/true); SetTCPKeepAlive(socket_, true, kTCPKeepAliveSeconds); } diff --git a/storage/browser/fileapi/isolated_context.cc b/storage/browser/fileapi/isolated_context.cc index 6edc40d6c2bc0..f579ca8fe2bb3 100644 --- a/storage/browser/fileapi/isolated_context.cc +++ b/storage/browser/fileapi/isolated_context.cc @@ -160,6 +160,7 @@ IsolatedContext::Instance::Instance(FileSystemType type, filesystem_id_(filesystem_id), file_info_(file_info), path_type_(path_type), + files_(), ref_counts_(0) { DCHECK(IsSinglePathIsolatedFileSystem(type_)); } diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp index 4e3f025f9165a..ee3672709d093 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp @@ -197,6 +197,9 @@ bool ScriptController::shouldBypassMainWorldCSP() { v8::HandleScope handleScope(isolate()); v8::Local<v8::Context> context = isolate()->GetCurrentContext(); + if (frame() && frame()->document() && + frame()->document()->getSecurityOrigin()->hasUniversalAccess()) + return true; if (context.IsEmpty() || !toDOMWindow(context)) return false; DOMWrapperWorld& world = DOMWrapperWorld::current(isolate()); diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp index c59ef520505c8..a903ebcfaf6b2 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp @@ -44,6 +44,7 @@ ScriptState::ScriptState(v8::Local<v8::Context> context, PassRefPtr<DOMWrapperWo ASSERT(m_world); m_context.setWeak(this, &weakCallback); context->SetAlignedPointerInEmbedderData(v8ContextPerContextDataIndex, this); + context->SetAlignedPointerInEmbedderData(32, nullptr); } ScriptState::~ScriptState() diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp index 0b2194872f302..11815dadd7fa7 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp @@ -25,6 +25,8 @@ #include "bindings/core/v8/V8Initializer.h" +#include "third_party/node/src/node_webkit.h" + #include "bindings/core/v8/DOMWrapperWorld.h" #include "bindings/core/v8/RejectedPromises.h" #include "bindings/core/v8/RetainedDOMInfo.h" @@ -64,6 +66,9 @@ #include <v8-debug.h> #include <v8-profiler.h> +VoidHookFn g_promise_reject_callback_fn = nullptr; + + namespace blink { static Frame* findFrame(v8::Isolate* isolate, v8::Local<v8::Object> host, v8::Local<v8::Value> data) @@ -223,6 +228,12 @@ static void promiseRejectHandler(v8::PromiseRejectMessage data, RejectedPromises v8::Isolate* isolate = promise->GetIsolate(); ScriptState* scriptState = ScriptState::current(isolate); +#if 0 //FIXME (#4577) + LocalDOMWindow* window = currentDOMWindow(isolate); + if (window->frame()->isNodeJS() && g_promise_reject_callback_fn) + g_promise_reject_callback_fn(&data); +#endif + v8::Local<v8::Value> exception = data.GetValue(); if (V8DOMWrapper::isWrapper(isolate, exception)) { // Try to get the stack & location from a wrapped exception object (e.g. DOMException). diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8FileListCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8FileListCustom.cpp new file mode 100644 index 0000000000000..ea3d99bcc27f5 --- /dev/null +++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8FileListCustom.cpp @@ -0,0 +1,26 @@ +#include "config.h" + +#include "bindings/core/v8/V8FileList.h" +#include "bindings/core/v8/V8File.h" +#include "bindings/core/v8/V8Binding.h" +#include "core/dom/Document.h" +#include "core/dom/ExecutionContext.h" +#include "core/frame/LocalFrame.h" + +namespace blink { +void V8FileList::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& args) +{ + ExecutionContext* context = currentExecutionContext(args.GetIsolate()); + if (context && context->isDocument()) { + Document* document = toDocument(context); + if (document->frame()->isNwDisabledChildFrame()) { + V8ThrowException::throwTypeError(args.GetIsolate(), "FileList constructor cannot be called in nwdisabled frame."); + return; + } + } + + FileList* impl = FileList::create(); + v8SetReturnValue(args, impl); +} + +} // namespace blink diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp index 57126843c894a..4e1934e504784 100644 --- a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp @@ -65,8 +65,37 @@ #include "wtf/Assertions.h" #include "wtf/OwnPtr.h" + +#include "bindings/core/v8/V8HTMLFrameElement.h" + namespace blink { +void V8Window::parentAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) +{ + LocalDOMWindow* imp = toLocalDOMWindow(V8Window::toImpl(info.Holder())); + LocalFrame* frame = imp->frame(); + if (frame && frame->isNwFakeTop()) { + v8SetReturnValue(info, toV8(imp, info.Holder(), info.GetIsolate())); + return; + } + v8SetReturnValue(info, toV8(imp->parent(), info.Holder(), info.GetIsolate())); +} + +void V8Window::topAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) +{ + LocalDOMWindow* imp = toLocalDOMWindow(V8Window::toImpl(info.Holder())); + LocalFrame* frame = imp->frame(); + if (frame) { + for (LocalFrame* f = frame; f; f = toLocalFrame(f->tree().parent())) { + if (f->isNwFakeTop()) { + v8SetReturnValue(info, toV8(f->document()->domWindow(), info.Holder(), info.GetIsolate())); + return; + } + } + } + v8SetReturnValue(info, toV8(imp->top(), info.Holder(), info.GetIsolate())); +} + void V8Window::eventAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder())); @@ -111,6 +140,9 @@ void V8Window::eventAttributeSetterCustom(v8::Local<v8::Value> value, const v8:: void V8Window::frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder())); + LocalFrame* frame = impl->frame(); + if (frame && frame->isNwFakeTop()) + return; if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frameElement(), DoNotReportSecurityError)) { v8SetReturnValueNull(info); diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/custom.gypi b/third_party/WebKit/Source/bindings/core/v8/custom/custom.gypi index 3f2037b0dfe67..e2e4f88232136 100644 --- a/third_party/WebKit/Source/bindings/core/v8/custom/custom.gypi +++ b/third_party/WebKit/Source/bindings/core/v8/custom/custom.gypi @@ -5,6 +5,7 @@ { 'variables': { 'bindings_core_v8_custom_files': [ + 'V8FileListCustom.cpp', 'V8CSSStyleDeclarationCustom.cpp', 'V8CSSStyleRuleCustom.cpp', 'V8CustomEventCustom.cpp', diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp index c973d6643fd2e..0d39dccab300f 100644 --- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp +++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp @@ -229,7 +229,7 @@ void Fullscreen::requestFullscreen(Element& element, RequestType requestType) // An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either: // - an activation behavior is currently being processed whose click event was trusted, or // - the event listener for a trusted click event is being handled. - if (!UserGestureIndicator::utilizeUserGesture()) { + if (!UserGestureIndicator::utilizeUserGesture() && !document()->frame()->isNodeJS()) { String message = ExceptionMessages::failedToExecute("requestFullScreen", "Element", "API can only be initiated by a user gesture."); document()->addConsoleMessage( diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp index 15ce3676b997e..bc89bd326dd06 100644 --- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp @@ -362,7 +362,7 @@ static bool canWriteClipboard(LocalFrame& frame, EditorCommandSource source) if (source == CommandFromMenuOrKeyBinding) return true; Settings* settings = frame.settings(); - bool defaultValue = (settings && settings->javaScriptCanAccessClipboard()) || UserGestureIndicator::utilizeUserGesture(); + bool defaultValue = (settings && settings->javaScriptCanAccessClipboard()) || UserGestureIndicator::utilizeUserGesture() || frame.isNodeJS(); return frame.editor().client().canCopyCut(&frame, defaultValue); } @@ -1026,7 +1026,7 @@ static bool canReadClipboard(LocalFrame& frame, EditorCommandSource source) if (source == CommandFromMenuOrKeyBinding) return true; Settings* settings = frame.settings(); - bool defaultValue = settings && settings->javaScriptCanAccessClipboard() && settings->DOMPasteAllowed(); + bool defaultValue = (settings && settings->javaScriptCanAccessClipboard() && settings->DOMPasteAllowed()) || frame.isNodeJS(); return frame.editor().client().canPaste(&frame, defaultValue); } diff --git a/third_party/WebKit/Source/core/fileapi/File.h b/third_party/WebKit/Source/core/fileapi/File.h index a42a2ef496b73..75c2d5209bd29 100644 --- a/third_party/WebKit/Source/core/fileapi/File.h +++ b/third_party/WebKit/Source/core/fileapi/File.h @@ -56,6 +56,10 @@ class CORE_EXPORT File final : public Blob { enum UserVisibility { IsUserVisible, IsNotUserVisible }; // Constructor in File.idl + static File* create(ExecutionContext*, const String& path, const String& name, ExceptionState&) + { + return createForUserProvidedFile(path, name); + } static File* create(ExecutionContext*, const HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString>&, const String& fileName, const FilePropertyBag&, ExceptionState&); static File* create(const String& path, ContentTypeLookupPolicy policy = WellKnownContentTypes) diff --git a/third_party/WebKit/Source/core/fileapi/File.idl b/third_party/WebKit/Source/core/fileapi/File.idl index 69c41cf05c3c2..8e071cdda573f 100644 --- a/third_party/WebKit/Source/core/fileapi/File.idl +++ b/third_party/WebKit/Source/core/fileapi/File.idl @@ -33,9 +33,11 @@ typedef (ArrayBuffer or ArrayBufferView or Blob or USVString) BlobPart; ConstructorCallWith=ExecutionContext, RaisesException=Constructor, Exposed=(Window,Worker), + Constructor(DOMString path, DOMString name), ] interface File : Blob { readonly attribute DOMString name; readonly attribute long long lastModified; + readonly attribute DOMString path; // Non-standard APIs [MeasureAs=FileGetLastModifiedDate] readonly attribute Date lastModifiedDate; diff --git a/third_party/WebKit/Source/core/fileapi/FileList.idl b/third_party/WebKit/Source/core/fileapi/FileList.idl index fd9e5ae6b1348..64fd87ff43777 100644 --- a/third_party/WebKit/Source/core/fileapi/FileList.idl +++ b/third_party/WebKit/Source/core/fileapi/FileList.idl @@ -26,8 +26,11 @@ // https://w3c.github.io/FileAPI/#filelist-section [ + CustomConstructor, Exposed=(Window,Worker), ] interface FileList { getter File? item(unsigned long index); readonly attribute unsigned long length; + void clear(); + void append(File item); }; diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp index 3e1d8f5dc3217..5ea5a8f9eb6df 100644 --- a/third_party/WebKit/Source/core/frame/Frame.cpp +++ b/third_party/WebKit/Source/core/frame/Frame.cpp @@ -63,6 +63,8 @@ DEFINE_TRACE(Frame) visitor->trace(m_host); visitor->trace(m_owner); visitor->trace(m_client); + visitor->trace(m_devJailOwner); + visitor->trace(m_devtoolsJail); } void Frame::detach(FrameDetachType type) @@ -76,6 +78,10 @@ void Frame::detach(FrameDetachType type) m_client->detached(type); m_client = nullptr; m_host = nullptr; + if (m_devJailOwner) { + m_devJailOwner->setDevtoolsJail(NULL); + m_devJailOwner = nullptr; + } } void Frame::detachChildren() @@ -310,6 +316,9 @@ Frame::Frame(FrameClient* client, FrameHost* host, FrameOwner* owner) , m_host(host) , m_owner(owner) , m_client(client) + , m_devtoolsJail(nullptr) + , m_devJailOwner(nullptr) + , m_nodejs(false) , m_isLoading(false) { InstanceCounters::incrementCounter(InstanceCounters::FrameCounter); @@ -322,4 +331,34 @@ Frame::Frame(FrameClient* client, FrameHost* host, FrameOwner* owner) page()->setMainFrame(this); } +bool Frame::isNwDisabledChildFrame() const +{ + if (m_owner) { + if (m_owner->isLocal()) + if (toHTMLFrameOwnerElement(m_owner)->fastHasAttribute(nwdisableAttr)) + return true; + } + return false; +} + +void Frame::setDevtoolsJail(Frame* iframe) +{ + m_devtoolsJail = iframe; + if (iframe) + iframe->m_devJailOwner = this; + else if (m_devtoolsJail) + m_devtoolsJail->m_devJailOwner = NULL; +} + +bool Frame::isNwFakeTop() const +{ + if (m_owner) { + if (m_owner->isLocal()) + if (toHTMLFrameOwnerElement(m_owner)->fastHasAttribute(nwfaketopAttr)) + return true; + } + return false; +} + + } // namespace blink diff --git a/third_party/WebKit/Source/core/frame/Frame.h b/third_party/WebKit/Source/core/frame/Frame.h index 3a93578cf6ad3..2d40a88b488dc 100644 --- a/third_party/WebKit/Source/core/frame/Frame.h +++ b/third_party/WebKit/Source/core/frame/Frame.h @@ -64,10 +64,18 @@ enum class UserGestureStatus { Active, None }; // input, layout, or painting probably belongs on LocalFrame. class CORE_EXPORT Frame : public GarbageCollectedFinalized<Frame> { public: + void setNodeJS(bool node) { m_nodejs = node; } + bool isNodeJS() const { return m_nodejs; } + bool isNwDisabledChildFrame() const; + bool isNwFakeTop() const; + virtual ~Frame(); DECLARE_VIRTUAL_TRACE(); + void setDevtoolsJail(Frame* iframe); + Frame* getDevtoolsJail() { return m_devtoolsJail; } + virtual bool isLocalFrame() const { return false; } virtual bool isRemoteFrame() const { return false; } @@ -148,6 +156,11 @@ class CORE_EXPORT Frame : public GarbageCollectedFinalized<Frame> { bool canNavigateWithoutFramebusting(const Frame&, String& errorReason); Member<FrameClient> m_client; + Member<Frame> m_devtoolsJail; + Member<Frame> m_devJailOwner; + + bool m_nodejs; + bool m_isLoading; }; diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp index 8bcfb6d7cf984..5963471ef9e09 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp @@ -285,7 +285,7 @@ unsigned LocalDOMWindow::pendingUnloadEventListeners() const bool LocalDOMWindow::allowPopUp(LocalFrame& firstFrame) { - if (UserGestureIndicator::utilizeUserGesture()) + if (UserGestureIndicator::utilizeUserGesture() || firstFrame.isNodeJS()) return true; Settings* settings = firstFrame.settings(); @@ -1478,10 +1478,10 @@ DOMWindow* LocalDOMWindow::open(const String& urlString, const AtomicString& fra // In those cases, we schedule a location change right now and return early. Frame* targetFrame = nullptr; if (frameName == "_top") { - targetFrame = frame()->tree().top(); + targetFrame = frame()->isNwFakeTop() ? frame() : frame()->tree().find("_top"); } else if (frameName == "_parent") { if (Frame* parent = frame()->tree().parent()) - targetFrame = parent; + targetFrame = frame()->isNwFakeTop() ? frame() : parent; else targetFrame = frame(); } diff --git a/third_party/WebKit/Source/core/frame/Location.cpp b/third_party/WebKit/Source/core/frame/Location.cpp index b83f6ffdb0c22..e6786cffb8d74 100644 --- a/third_party/WebKit/Source/core/frame/Location.cpp +++ b/third_party/WebKit/Source/core/frame/Location.cpp @@ -120,10 +120,14 @@ String Location::origin() const DOMStringList* Location::ancestorOrigins() const { DOMStringList* origins = DOMStringList::create(DOMStringList::Location); - if (!m_frame) + if (!m_frame || m_frame->isNwFakeTop()) return origins; - for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) + for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) { origins->append(frame->securityContext()->getSecurityOrigin()->toString()); + if (frame->isNwFakeTop()) + break; + } + return origins; } diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl index 760065fef0ad0..314d01a38748c 100644 --- a/third_party/WebKit/Source/core/frame/Window.idl +++ b/third_party/WebKit/Source/core/frame/Window.idl @@ -56,10 +56,10 @@ // other browsing contexts [Replaceable, DoNotCheckSecurity] readonly attribute Window frames; [Replaceable, DoNotCheckSecurity] readonly attribute unsigned long length; - [Unforgeable, DoNotCheckSecurity] readonly attribute Window top; + [Unforgeable, DoNotCheckSecurity, Custom=Getter] readonly attribute Window top; // FIXME: opener should be of type any. [DoNotCheckSecurity, Custom=Setter] attribute Window opener; - [Replaceable, DoNotCheckSecurity] readonly attribute Window parent; + [Replaceable, DoNotCheckSecurity, Custom=Getter] readonly attribute Window parent; [CheckSecurity=ReturnValue, Custom=Getter] readonly attribute Element? frameElement; // FIXME: open() should have 4 optional arguments with defaults. [Custom] Window? open(DOMString url, DOMString target, optional DOMString features); diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp index 456b3044abed0..9238c62b43d99 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp @@ -154,6 +154,8 @@ bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, LocalFrame return true; for (Frame* current = frame->tree().parent(); current; current = current->tree().parent()) { + if (current->isLocalFrame() && toLocalFrame(current)->document()->getSecurityOrigin()->hasUniversalAccess()) + return true; // The |current| frame might be a remote frame which has no URL, so use // its origin instead. This should suffice for this check since it // doesn't do path comparisons. See https://crbug.com/582544. diff --git a/third_party/WebKit/Source/core/html/HTMLAttributeNames.in b/third_party/WebKit/Source/core/html/HTMLAttributeNames.in index 847569c6138e0..400e7840c3807 100644 --- a/third_party/WebKit/Source/core/html/HTMLAttributeNames.in +++ b/third_party/WebKit/Source/core/html/HTMLAttributeNames.in @@ -322,3 +322,8 @@ vspace webkitdirectory width wrap +nwworkingdir +nwdisable +nwfaketop +nwdirectory +nwsaveas diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 52556b3111db5..0cc6027fea0d9 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp @@ -608,7 +608,7 @@ String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& qualityArgument, ExceptionState& exceptionState) const { - if (!originClean()) { + if (!document().frame()->isNodeJS() && !originClean()) { exceptionState.throwSecurityError("Tainted canvases may not be exported."); return String(); } diff --git a/third_party/WebKit/Source/core/html/HTMLFormElement.cpp b/third_party/WebKit/Source/core/html/HTMLFormElement.cpp index 8c7155f008446..fb644a6f6e649 100644 --- a/third_party/WebKit/Source/core/html/HTMLFormElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLFormElement.cpp @@ -407,7 +407,7 @@ void HTMLFormElement::scheduleFormSubmission(FormSubmission* submission) Frame* targetFrame = document().frame()->findFrameForNavigation(submission->target(), *document().frame()); if (!targetFrame) { - if (!LocalDOMWindow::allowPopUp(*document().frame()) && !UserGestureIndicator::utilizeUserGesture()) + if (!LocalDOMWindow::allowPopUp(*document().frame()) && !UserGestureIndicator::utilizeUserGesture() && !document().frame()->isNodeJS()) return; targetFrame = document().frame(); } else { diff --git a/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl b/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl index 24793a49b1000..c04fc69ba173e 100644 --- a/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl +++ b/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl @@ -27,6 +27,8 @@ interface HTMLIFrameElement : HTMLElement { [PutForwards=value] readonly attribute DOMTokenList sandbox; // Note: The seamless attribute was once supported, but was removed. [Reflect] attribute boolean allowFullscreen; + [Reflect] attribute boolean nwdisable; + [Reflect] attribute boolean nwfaketop; [Reflect] attribute DOMString width; [Reflect] attribute DOMString height; [CheckSecurity=ReturnValue] readonly attribute Document? contentDocument; diff --git a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp index 4deedd6cd070e..c5c20b9c7f17b 100644 --- a/third_party/WebKit/Source/core/html/HTMLInputElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLInputElement.cpp @@ -1707,6 +1707,26 @@ bool HTMLInputElement::shouldAppearIndeterminate() const return m_inputType->shouldAppearIndeterminate(); } +const AtomicString& HTMLInputElement::nwworkingdir() const +{ + return fastGetAttribute(nwworkingdirAttr); +} + +void HTMLInputElement::setNwworkingdir(const AtomicString& value) +{ + setAttribute(nwworkingdirAttr, value); +} + +String HTMLInputElement::nwsaveas() const +{ + return fastGetAttribute(nwsaveasAttr); +} + +void HTMLInputElement::setNwsaveas(const String& value) +{ + setAttribute(nwsaveasAttr, AtomicString(value)); +} + bool HTMLInputElement::isInRequiredRadioButtonGroup() { // FIXME: Remove type check. diff --git a/third_party/WebKit/Source/core/html/HTMLInputElement.h b/third_party/WebKit/Source/core/html/HTMLInputElement.h index a380b75b81e49..101a136f3ef9e 100644 --- a/third_party/WebKit/Source/core/html/HTMLInputElement.h +++ b/third_party/WebKit/Source/core/html/HTMLInputElement.h @@ -227,6 +227,11 @@ class CORE_EXPORT HTMLInputElement : public HTMLTextFormControlElement { String defaultToolTip() const override; + const AtomicString& nwworkingdir() const; + void setNwworkingdir(const AtomicString& value); + String nwsaveas() const; + void setNwsaveas(const String& value); + static const int maximumLength; unsigned height() const; diff --git a/third_party/WebKit/Source/core/html/HTMLInputElement.idl b/third_party/WebKit/Source/core/html/HTMLInputElement.idl index b82f0960df077..5837bb6a6f157 100644 --- a/third_party/WebKit/Source/core/html/HTMLInputElement.idl +++ b/third_party/WebKit/Source/core/html/HTMLInputElement.idl @@ -107,7 +107,9 @@ interface HTMLInputElement : HTMLElement { // HTML Media Capture // http://www.w3.org/TR/html-media-capture/ [RuntimeEnabled=MediaCapture, Reflect] attribute boolean capture; - + attribute DOMString nwworkingdir; + [Reflect] attribute boolean nwdirectory; + attribute DOMString nwsaveas; // Non-standard APIs [Reflect, MeasureAs=PrefixedDirectoryAttribute] attribute boolean webkitdirectory; [Reflect, MeasureAs=IncrementalAttribute] attribute boolean incremental; diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index cc1342973ea11..55bb5e55e0531 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp @@ -2067,7 +2067,7 @@ Nullable<ExceptionCode> HTMLMediaElement::play() m_autoplayHelper->playMethodCalled(); - if (!UserGestureIndicator::processingUserGesture()) { + if (!UserGestureIndicator::processingUserGesture() && !document().frame()->isNodeJS()) { recordAutoplaySourceMetric(AutoplaySourceMethod); if (isGestureNeededForPlayback()) { // If playback is deferred, then don't start playback but don't diff --git a/third_party/WebKit/Source/core/html/forms/ChooserOnlyTemporalInputTypeView.cpp b/third_party/WebKit/Source/core/html/forms/ChooserOnlyTemporalInputTypeView.cpp index f8ec7db7ce1a6..6ace7d19d08fb 100644 --- a/third_party/WebKit/Source/core/html/forms/ChooserOnlyTemporalInputTypeView.cpp +++ b/third_party/WebKit/Source/core/html/forms/ChooserOnlyTemporalInputTypeView.cpp @@ -63,7 +63,8 @@ DEFINE_TRACE(ChooserOnlyTemporalInputTypeView) void ChooserOnlyTemporalInputTypeView::handleDOMActivateEvent(Event*) { - if (element().isDisabledOrReadOnly() || !element().layoutObject() || !UserGestureIndicator::processingUserGesture() || element().openShadowRoot()) + if (element().isDisabledOrReadOnly() || !element().layoutObject() || + (!UserGestureIndicator::processingUserGesture() && !element().document().frame()->isNodeJS()) || element().openShadowRoot()) return; if (m_dateTimeChooser) diff --git a/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp b/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp index cb7e475000341..b59910bc53ec1 100644 --- a/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp +++ b/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp @@ -172,7 +172,7 @@ void ColorInputType::handleDOMActivateEvent(Event* event) if (element().isDisabledFormControl() || !element().layoutObject()) return; - if (!UserGestureIndicator::utilizeUserGesture()) + if (!UserGestureIndicator::utilizeUserGesture() && !element().document().frame()->isNodeJS()) return; ChromeClient* chromeClient = this->chromeClient(); diff --git a/third_party/WebKit/Source/core/html/forms/FileInputType.cpp b/third_party/WebKit/Source/core/html/forms/FileInputType.cpp index fe130febe6c85..6769dd422c8fe 100644 --- a/third_party/WebKit/Source/core/html/forms/FileInputType.cpp +++ b/third_party/WebKit/Source/core/html/forms/FileInputType.cpp @@ -140,8 +140,9 @@ void FileInputType::handleDOMActivateEvent(Event* event) { if (element().isDisabledFormControl()) return; - - if (!UserGestureIndicator::utilizeUserGesture()) + + HTMLInputElement& input = element(); + if (!UserGestureIndicator::utilizeUserGesture() && !input.document().frame()->isNodeJS()) return; if (ChromeClient* chromeClient = this->chromeClient()) { @@ -153,6 +154,10 @@ void FileInputType::handleDOMActivateEvent(Event* event) settings.acceptFileExtensions = input.acceptFileExtensions(); settings.selectedFiles = m_fileList->pathsForUserVisibleFiles(); settings.useMediaCapture = RuntimeEnabledFeatures::mediaCaptureEnabled() && input.fastHasAttribute(captureAttr); + settings.initialPath = input.nwworkingdir(); + settings.directoryChooser = input.fastHasAttribute(nwdirectoryAttr); + settings.saveAs = input.fastHasAttribute(nwsaveasAttr); + settings.initialValue = input.nwsaveas(); chromeClient->openFileChooser(input.document().frame(), newFileChooser(settings)); } event->setDefaultHandled(); @@ -195,7 +200,11 @@ bool FileInputType::getTypeSpecificValue(String& value) // decided to try to parse the value by looking for backslashes // (because that's what Windows file paths use). To be compatible // with that code, we make up a fake path for the file. - value = "C:\\fakepath\\" + m_fileList->item(0)->name(); + //value = "C:\\fakepath\\" + m_fileList->item(0)->name(); + unsigned numFiles = m_fileList->length(); + value = m_fileList->item(0)->path(); + for (unsigned i = 1; i < numFiles; ++i) + value.append(String(";") + m_fileList->item(i)->path()); return true; } @@ -313,8 +322,13 @@ void FileInputType::setFiles(FileList* files) element().setChangedSinceLastFormControlChangeEvent(false); } -void FileInputType::filesChosen(const Vector<FileChooserFileInfo>& files) +void FileInputType::filesChosen(const Vector<FileChooserFileInfo>& files, bool canceled) { + if (canceled) { + element().dispatchScopedEvent(Event::createBubble(EventTypeNames::cancel)); + return; + } + setFiles(createFileList(files, element().fastHasAttribute(webkitdirectoryAttr))); } diff --git a/third_party/WebKit/Source/core/html/forms/FileInputType.h b/third_party/WebKit/Source/core/html/forms/FileInputType.h index 7c711812e6111..02922799bba24 100644 --- a/third_party/WebKit/Source/core/html/forms/FileInputType.h +++ b/third_party/WebKit/Source/core/html/forms/FileInputType.h @@ -83,7 +83,7 @@ class CORE_EXPORT FileInputType final String defaultToolTip(const InputTypeView&) const override; // FileChooserClient implementation. - void filesChosen(const Vector<FileChooserFileInfo>&) override; + void filesChosen(const Vector<FileChooserFileInfo>&, bool canceled = false) override; void receiveDropForDirectoryUpload(const Vector<String>&); diff --git a/third_party/WebKit/Source/core/inspector/InspectedFrames.h b/third_party/WebKit/Source/core/inspector/InspectedFrames.h index fd3f091adf0cd..ae4c1fb4c6c8c 100644 --- a/third_party/WebKit/Source/core/inspector/InspectedFrames.h +++ b/third_party/WebKit/Source/core/inspector/InspectedFrames.h @@ -10,6 +10,8 @@ #include "wtf/Forward.h" #include "wtf/Noncopyable.h" +#include "core/frame/LocalFrame.h" + namespace blink { class LocalFrame; @@ -38,7 +40,11 @@ class CORE_EXPORT InspectedFrames final : public GarbageCollected<InspectedFrame return new InspectedFrames(root); } - LocalFrame* root() { return m_root; } + LocalFrame* root() { + LocalFrame* f = m_root; + LocalFrame* jail = (LocalFrame*)f->getDevtoolsJail(); + return jail ? jail : f; + } bool contains(LocalFrame*) const; LocalFrame* frameWithSecurityOrigin(const String& originRawString); Iterator begin(); diff --git a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h index 83ab4ac7f699e..53909dc077e24 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h +++ b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h @@ -118,6 +118,23 @@ inline InstrumentingAgents* instrumentingAgentsFor(Document& document) LocalFrame* frame = document.frame(); if (!frame && document.templateDocumentHost()) frame = document.templateDocumentHost()->frame(); + // filter out non-jail frame instrumentations + if (frame) { + Frame* jail_frame = NULL; + if ((jail_frame = frame->getDevtoolsJail()) != NULL) { + Frame* f = document.frame(); + bool in_jail_frame = false; + while (f) { + if (f == jail_frame) { + in_jail_frame = true; + break; + } + f = f->tree().parent(); + } + if (!in_jail_frame) + return NULL; + } + } return instrumentingAgentsFor(frame); } diff --git a/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp b/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp index 1bb13c0e6888e..8838e59749bca 100644 --- a/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp @@ -30,6 +30,9 @@ #include "core/inspector/WorkerConsoleAgent.h" +#include "core/frame/LocalDOMWindow.h" +#include "core/frame/LocalFrame.h" + #include "bindings/core/v8/ScriptController.h" #include "core/inspector/ConsoleMessageStorage.h" #include "core/workers/WorkerGlobalScope.h" diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeFontProviderWin.cpp b/third_party/WebKit/Source/core/layout/LayoutThemeFontProviderWin.cpp index d0253fd2fe31f..35a7a4aad3350 100644 --- a/third_party/WebKit/Source/core/layout/LayoutThemeFontProviderWin.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutThemeFontProviderWin.cpp @@ -28,8 +28,16 @@ #include "core/CSSValueKeywords.h" #include "platform/fonts/FontCache.h" #include "platform/fonts/FontDescription.h" +#include "platform/win/HWndDC.h" +#include "platform/win/SystemInfo.h" #include "wtf/text/WTFString.h" +#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \ + offsetof(structName, member) + \ + (sizeof static_cast<structName*>(nullptr)->member) +#define NONCLIENTMETRICS_SIZE_PRE_VISTA \ + SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont) + namespace blink { // Converts |points| to pixels. One point is 1/72 of an inch. @@ -40,6 +48,49 @@ static float pointsToPixels(float points) return points / pointsPerInch * pixelsPerInch; } +static bool getNonClientMetrics(NONCLIENTMETRICS* metrics) +{ + static UINT size = isWindowsVistaOrGreater() ? + sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA; + metrics->cbSize = size; + bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, size, metrics, 0); + ASSERT_UNUSED(success, success); + return success; +} + +// Return the height of system font |font| in pixels. We use this size by +// default for some non-form-control elements. +static float systemFontSize(const LOGFONT& font) +{ + float size = -font.lfHeight; + if (size < 0) { + HFONT hFont = CreateFontIndirect(&font); + if (hFont) { + HWndDC hdc(0); // What about printing? Is this the right DC? + if (hdc) { + HGDIOBJ hObject = SelectObject(hdc, hFont); + TEXTMETRIC tm; + GetTextMetrics(hdc, &tm); + SelectObject(hdc, hObject); + size = tm.tmAscent; + } + DeleteObject(hFont); + } + } + + // The "codepage 936" bit here is from Gecko; apparently this helps make + // fonts more legible in Simplified Chinese where the default font size is + // too small. + // + // FIXME: http://b/1119883 Since this is only used for "small caption", + // "menu", and "status bar" objects, I'm not sure how much this even + // matters. Plus the Gecko patch went in back in 2002, and maybe this + // isn't even relevant anymore. We should investigate whether this should + // be removed, or perhaps broadened to be "any CJK locale". + // + return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size; +} + // static void LayoutThemeFontProvider::systemFont(CSSValueID systemFontID, FontStyle& fontStyle, FontWeight& fontWeight, float& fontSize, AtomicString& fontFamily) { diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index c4084d3f33d6a..71d2b53625d5c 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h @@ -84,7 +84,7 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient { void takeFocus(WebFocusType) override {} void focusedNodeChanged(Node*, Node*) override {} - Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSetOpener) override { return nullptr; } + Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSetOpener, WebString*) override { return nullptr; } void show(NavigationPolicy) override {} void didOverscroll(const FloatSize&, const FloatSize&, const FloatPoint&, const FloatSize&) override {} diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index c6199981af246..7d88a77467be2 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp @@ -954,13 +954,21 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest, FrameLoadType fram determineFrameLoadType(request) : frameLoadType; NavigationPolicy policy = navigationPolicyForRequest(request); if (shouldOpenInNewWindow(targetFrame, request, policy)) { + if (request.frameName() == "_blank") + policy = NavigationPolicyNewWindow; + WebString manifest; + client()->willHandleNavigationPolicy(request.resourceRequest(), &policy, &manifest); + if (policy == NavigationPolicyIgnore) + return; + if (policy != NavigationPolicyCurrentTab && shouldOpenInNewWindow(targetFrame, request, policy)) { if (policy == NavigationPolicyDownload) { client()->loadURLExternally(request.resourceRequest(), NavigationPolicyDownload, String(), false); } else { request.resourceRequest().setFrameType(WebURLRequest::FrameTypeAuxiliary); - createWindowForRequest(request, *m_frame, policy, request.getShouldSendReferrer(), request.getShouldSetOpener()); + createWindowForRequest(request, *m_frame, policy, request.getShouldSendReferrer(), request.getShouldSetOpener(), manifest); } return; + } } const KURL& url = request.resourceRequest().url(); @@ -1402,6 +1410,16 @@ void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, FrameLoadType ty frameLoadRequest.resourceRequest().setRequestContext(determineRequestContextFromNavigationType(navigationType)); frameLoadRequest.resourceRequest().setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested); ResourceRequest& request = frameLoadRequest.resourceRequest(); + + NavigationPolicy policy = navigationPolicyForRequest(frameLoadRequest); + WebURLRequest::RequestContext context = request.requestContext(); + if (context == WebURLRequest::RequestContextHyperlink || + context == WebURLRequest::RequestContextForm) { + client()->willHandleNavigationPolicy(request, &policy, NULL, false); + if (policy == NavigationPolicyIgnore) + return; + } + if (!shouldContinueForNavigationPolicy(request, frameLoadRequest.substituteData(), nullptr, frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(), navigationType, navigationPolicy, type == FrameLoadTypeReplaceCurrentItem, frameLoadRequest.clientRedirect() == ClientRedirectPolicy::ClientRedirect)) return; if (!shouldClose(navigationType == NavigationTypeReload)) @@ -1456,6 +1474,8 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con Frame* topFrame = m_frame->tree().top(); if (m_frame == topFrame) return false; + if (topFrame->isNodeJS()) + return false; XFrameOptionsDisposition disposition = parseXFrameOptionsHeader(content); diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h index 3be68c3ccd94a..5b89b1a42cd2f 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h +++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h @@ -80,11 +80,12 @@ class WebServiceWorkerProvider; class WebSocketHandle; class Widget; -class CORE_EXPORT FrameLoaderClient : public FrameClient { -public: - ~FrameLoaderClient() override {} + class CORE_EXPORT FrameLoaderClient : public FrameClient { + public: + ~FrameLoaderClient() override {} + virtual void willHandleNavigationPolicy(const ResourceRequest& request, NavigationPolicy* policy, WebString* manifest = NULL, bool new_win = true) {} - virtual bool hasWebView() const = 0; // mainly for assertions + virtual bool hasWebView() const = 0; // mainly for assertions virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse) = 0; virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&) = 0; diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 2fbe9321c3fee..a2cc4ce4a3d44 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h @@ -110,7 +110,7 @@ class CORE_EXPORT ChromeClient : public HostWindow { // created Page has its show method called. // The FrameLoadRequest parameter is only for ChromeClient to check if the // request could be fulfilled. The ChromeClient should not load the request. - virtual Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSetOpener) = 0; + virtual Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSetOpener, WebString* manifest = nullptr) = 0; virtual void show(NavigationPolicy = NavigationPolicyIgnore) = 0; void setWindowFeatures(const WindowFeatures&); diff --git a/third_party/WebKit/Source/core/page/CreateWindow.cpp b/third_party/WebKit/Source/core/page/CreateWindow.cpp index 6b8f1697f905b..f6e80bb8e3eea 100644 --- a/third_party/WebKit/Source/core/page/CreateWindow.cpp +++ b/third_party/WebKit/Source/core/page/CreateWindow.cpp @@ -45,6 +45,8 @@ #include "platform/weborigin/SecurityPolicy.h" #include "public/platform/WebURLRequest.h" +#include "core/loader/FrameLoaderClient.h" + namespace blink { static Frame* reuseExistingWindow(LocalFrame& activeFrame, LocalFrame& lookupFrame, const AtomicString& frameName, NavigationPolicy policy) @@ -65,13 +67,14 @@ static Frame* reuseExistingWindow(LocalFrame& activeFrame, LocalFrame& lookupFra return nullptr; } -static Frame* createNewWindow(LocalFrame& openerFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSetOpener shouldSetOpener, bool& created) +static Frame* createNewWindow(LocalFrame& openerFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSetOpener shouldSetOpener, bool& created, WebString* manifest) { FrameHost* oldHost = openerFrame.host(); if (!oldHost) return nullptr; - Page* page = oldHost->chromeClient().createWindow(&openerFrame, request, features, policy, shouldSetOpener); + WebString manifest_str(*manifest); + Page* page = oldHost->chromeClient().createWindow(&openerFrame, request, features, policy, shouldSetOpener, &manifest_str); if (!page) return nullptr; FrameHost* host = &page->frameHost(); @@ -112,7 +115,7 @@ static Frame* createNewWindow(LocalFrame& openerFrame, const FrameLoadRequest& r return &frame; } -static Frame* createWindowHelper(LocalFrame& openerFrame, LocalFrame& activeFrame, LocalFrame& lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSetOpener shouldSetOpener, bool& created) +static Frame* createWindowHelper(LocalFrame& openerFrame, LocalFrame& activeFrame, LocalFrame& lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSetOpener shouldSetOpener, bool& created, WebString* manifest) { ASSERT(!features.dialog || request.frameName().isEmpty()); ASSERT(request.resourceRequest().requestorOrigin() || openerFrame.document()->url().isEmpty()); @@ -140,7 +143,7 @@ static Frame* createWindowHelper(LocalFrame& openerFrame, LocalFrame& activeFram return window; } - return createNewWindow(openerFrame, request, features, policy, shouldSetOpener, created); + return createNewWindow(openerFrame, request, features, policy, shouldSetOpener, created, manifest); } DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, @@ -171,13 +174,27 @@ DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, // This value will be set in ResourceRequest loaded in a new LocalFrame. bool hasUserGesture = UserGestureIndicator::processingUserGesture(); + NavigationPolicy navigationPolicy = NavigationPolicyNewForegroundTab; + WebString manifest; + openerFrame.loader().client()->willHandleNavigationPolicy(frameRequest.resourceRequest(), &navigationPolicy, &manifest); + // We pass the opener frame for the lookupFrame in case the active frame is different from // the opener frame, and the name references a frame relative to the opener frame. - bool created; - ShouldSetOpener opener = windowFeatures.noopener ? NeverSetOpener : MaybeSetOpener; - Frame* newFrame = createWindowHelper(openerFrame, *activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, opener, created); - if (!newFrame) + bool created = false; + Frame* newFrame = nullptr; + if (navigationPolicy != NavigationPolicyIgnore && + navigationPolicy != NavigationPolicyCurrentTab) { + ShouldSetOpener opener = windowFeatures.noopener ? NeverSetOpener : MaybeSetOpener; + newFrame = createWindowHelper(openerFrame, *activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, opener, created, &manifest); + if (!newFrame) + return nullptr; + + if (!windowFeatures.noopener) + newFrame->client()->setOpener(&openerFrame); + } else if (navigationPolicy == NavigationPolicyIgnore) return nullptr; + else + newFrame = &openerFrame; if (!newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL)) { if (!urlString.isEmpty() || created) @@ -186,7 +203,7 @@ DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, return newFrame->domWindow(); } -void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, ShouldSetOpener shouldSetOpener) +void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, ShouldSetOpener shouldSetOpener, WebString& manifest) { ASSERT(request.resourceRequest().requestorOrigin() || (openerFrame.document() && openerFrame.document()->url().isEmpty())); @@ -204,7 +221,7 @@ void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerF WindowFeatures features; bool created; - Frame* newFrame = createWindowHelper(openerFrame, openerFrame, openerFrame, request, features, policy, shouldSetOpener, created); + Frame* newFrame = createWindowHelper(openerFrame, openerFrame, openerFrame, request, features, policy, shouldSetOpener, created, &manifest); if (!newFrame) return; if (shouldSendReferrer == MaybeSendReferrer) { diff --git a/third_party/WebKit/Source/core/page/CreateWindow.h b/third_party/WebKit/Source/core/page/CreateWindow.h index cb43609383aa3..3c879e2486464 100644 --- a/third_party/WebKit/Source/core/page/CreateWindow.h +++ b/third_party/WebKit/Source/core/page/CreateWindow.h @@ -40,7 +40,7 @@ struct WindowFeatures; DOMWindow* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&, LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame); -void createWindowForRequest(const FrameLoadRequest&, LocalFrame& openerFrame, NavigationPolicy, ShouldSendReferrer, ShouldSetOpener); +void createWindowForRequest(const FrameLoadRequest&, LocalFrame& openerFrame, NavigationPolicy, ShouldSendReferrer, ShouldSetOpener, WebString& manifest); } // namespace blink diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp index aaaa83f6960b2..5ed4bb533780c 100644 --- a/third_party/WebKit/Source/core/page/DragController.cpp +++ b/third_party/WebKit/Source/core/page/DragController.cpp @@ -215,7 +215,7 @@ void DragController::dragExited(DragData* dragData) FrameView* frameView(mainFrame->view()); if (frameView) { - DataTransferAccessPolicy policy = (!m_documentUnderMouse || m_documentUnderMouse->getSecurityOrigin()->isLocal()) ? DataTransferReadable : DataTransferTypesReadable; + DataTransferAccessPolicy policy = (!m_documentUnderMouse || m_documentUnderMouse->getSecurityOrigin()->isLocal() || m_documentUnderMouse->getSecurityOrigin()->hasUniversalAccess()) ? DataTransferReadable : DataTransferTypesReadable; DataTransfer* dataTransfer = createDraggingDataTransfer(policy, dragData); dataTransfer->setSourceOperation(dragData->draggingSourceOperationMask()); mainFrame->eventHandler().cancelDragAndDrop(createMouseEvent(dragData), dataTransfer); @@ -599,7 +599,7 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation) if (!mainFrame->view()) return false; - DataTransferAccessPolicy policy = m_documentUnderMouse->getSecurityOrigin()->isLocal() ? DataTransferReadable : DataTransferTypesReadable; + DataTransferAccessPolicy policy = m_documentUnderMouse->getSecurityOrigin()->isLocal() || m_documentUnderMouse->getSecurityOrigin()->hasUniversalAccess() ? DataTransferReadable : DataTransferTypesReadable; DataTransfer* dataTransfer = createDraggingDataTransfer(policy, dragData); DragOperation srcOpMask = dragData->draggingSourceOperationMask(); dataTransfer->setSourceOperation(srcOpMask); diff --git a/third_party/WebKit/Source/core/page/FrameTree.cpp b/third_party/WebKit/Source/core/page/FrameTree.cpp index 364082c9c8ade..f59b3113193af 100644 --- a/third_party/WebKit/Source/core/page/FrameTree.cpp +++ b/third_party/WebKit/Source/core/page/FrameTree.cpp @@ -407,11 +407,19 @@ Frame* FrameTree::find(const AtomicString& name) const if (name == "_self" || name == "_current" || name.isEmpty()) return m_thisFrame; - if (name == "_top") + if (name == "_top") { + for (LocalFrame* f = toLocalFrame(m_thisFrame); f; f = toLocalFrame(f->tree().parent())) { + if (f->isNwFakeTop()) + return f; + } return top(); + } - if (name == "_parent") + if (name == "_parent") { + if (m_thisFrame->isNwFakeTop()) + return m_thisFrame.get(); return parent() ? parent() : m_thisFrame.get(); + } // Since "_blank" should never be any frame's name, the following just amounts to an optimization. if (name == "_blank") diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp index f4a5a3b460d0b..ee152e3aa03f0 100644 --- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp +++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp @@ -606,8 +606,10 @@ void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool asyn // Eventually sync xhr will be deprecated and an "InvalidAccessError" exception thrown. // Refer : https://xhr.spec.whatwg.org/#sync-warning // Use count for XHR synchronous requests on main thread only. +#if 0 if (!document()->processingBeforeUnload()) Deprecation::countDeprecation(getExecutionContext(), UseCounter::XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload); +#endif } m_method = FetchUtils::normalizeMethod(method); diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index 5aa2d8b4981e7..395b8f7f00ba4 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp @@ -559,6 +559,8 @@ void CanvasRenderingContext2D::filterNeedsInvalidation() bool CanvasRenderingContext2D::originClean() const { + if (canvas()->document().frame()->isNodeJS()) + return true; return canvas()->originClean(); } diff --git a/third_party/WebKit/Source/platform/FileChooser.cpp b/third_party/WebKit/Source/platform/FileChooser.cpp index f5ac66919c0d9..8e481deb5b7a6 100644 --- a/third_party/WebKit/Source/platform/FileChooser.cpp +++ b/third_party/WebKit/Source/platform/FileChooser.cpp @@ -68,13 +68,14 @@ void FileChooser::chooseFiles(const Vector<FileChooserFileInfo>& files) { // FIXME: This is inelegant. We should not be looking at settings here. Vector<String> paths; + bool canceled = false; for (unsigned i = 0; i < files.size(); ++i) paths.append(files[i].path); if (m_settings.selectedFiles == paths) - return; + canceled = true; if (m_client) - m_client->filesChosen(files); + m_client->filesChosen(files, canceled); } Vector<String> FileChooserSettings::acceptTypes() const diff --git a/third_party/WebKit/Source/platform/FileChooser.h b/third_party/WebKit/Source/platform/FileChooser.h index f641e3d36cd91..b895b43025929 100644 --- a/third_party/WebKit/Source/platform/FileChooser.h +++ b/third_party/WebKit/Source/platform/FileChooser.h @@ -74,11 +74,17 @@ struct FileChooserSettings { // Returns a combined vector of acceptMIMETypes and acceptFileExtensions. Vector<String> PLATFORM_EXPORT acceptTypes() const; + + String initialPath; + String initialValue; + + bool directoryChooser; + bool saveAs; }; class PLATFORM_EXPORT FileChooserClient { public: - virtual void filesChosen(const Vector<FileChooserFileInfo>&) = 0; + virtual void filesChosen(const Vector<FileChooserFileInfo>&, bool canceled = false) = 0; virtual ~FileChooserClient(); protected: diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi index 39cddc0a81d95..000bcadf71996 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gypi +++ b/third_party/WebKit/Source/platform/blink_platform.gypi @@ -1130,6 +1130,9 @@ 'weborigin/SecurityPolicy.h', 'weborigin/Suborigin.cpp', 'weborigin/Suborigin.h', + 'win/HWndDC.h', + 'win/SystemInfo.cpp', + 'win/SystemInfo.h', ], 'platform_test_files': [ 'DecimalTest.cpp', diff --git a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp index 051232ffcb904..e76f28e1bb656 100644 --- a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp +++ b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp @@ -169,4 +169,9 @@ void WebSecurityOrigin::grantLoadLocalResources() const get()->grantLoadLocalResources(); } +void WebSecurityOrigin::grantUniversalAccess() const +{ + get()->grantUniversalAccess(); +} + } // namespace blink diff --git a/third_party/WebKit/Source/platform/text/LocaleWin.cpp b/third_party/WebKit/Source/platform/text/LocaleWin.cpp index 01b93a23eeb00..9813369e779aa 100644 --- a/third_party/WebKit/Source/platform/text/LocaleWin.cpp +++ b/third_party/WebKit/Source/platform/text/LocaleWin.cpp @@ -46,6 +46,9 @@ namespace blink { +typedef LCID (WINAPI* LocaleNameToLCIDPtr)(LPCWSTR, DWORD); +typedef HashMap<String, LCID> NameToLCIDMap; + static String extractLanguageCode(const String& locale) { size_t dashPosition = locale.find('-'); @@ -54,25 +57,90 @@ static String extractLanguageCode(const String& locale) return locale.left(dashPosition); } -static LCID LCIDFromLocaleInternal(LCID userDefaultLCID, const String& userDefaultLanguageCode, const String& locale) +static String removeLastComponent(const String& name) +{ + size_t lastSeparator = name.reverseFind('-'); + if (lastSeparator == kNotFound) + return emptyString(); + return name.left(lastSeparator); +} + +static void ensureNameToLCIDMap(NameToLCIDMap& map) +{ + if (!map.isEmpty()) + return; + // http://www.microsoft.com/resources/msdn/goglobal/default.mspx + // We add only locales used in layout tests for now. + map.add("ar", 0x0001); + map.add("ar-eg", 0x0C01); + map.add("de", 0x0007); + map.add("de-de", 0x0407); + map.add("el", 0x0008); + map.add("el-gr", 0x0408); + map.add("en", 0x0009); + map.add("en-gb", 0x0809); + map.add("en-us", 0x0409); + map.add("fr", 0x000C); + map.add("fr-fr", 0x040C); + map.add("he", 0x000D); + map.add("he-il", 0x040D); + map.add("hi", 0x0039); + map.add("hi-in", 0x0439); + map.add("ja", 0x0011); + map.add("ja-jp", 0x0411); + map.add("ko", 0x0012); + map.add("ko-kr", 0x0412); + map.add("ru", 0x0019); + map.add("ru-ru", 0x0419); + map.add("zh-cn", 0x0804); + map.add("zh-tw", 0x0404); +} + +// Fallback implementation of LocaleNameToLCID API. This is used for +// testing on Windows XP. +// FIXME: Remove this, ensureNameToLCIDMap, and removeLastComponent when we drop +// Windows XP support. +static LCID WINAPI convertLocaleNameToLCID(LPCWSTR name, DWORD) +{ + if (!name || !name[0]) + return LOCALE_USER_DEFAULT; + DEFINE_STATIC_LOCAL(NameToLCIDMap, map, ()); + ensureNameToLCIDMap(map); + String localeName = String(name).replace('_', '-'); + localeName = localeName.lower(); + do { + NameToLCIDMap::const_iterator iterator = map.find(localeName); + if (iterator != map.end()) + return iterator->value; + localeName = removeLastComponent(localeName); + } while (!localeName.isEmpty()); + return LOCALE_USER_DEFAULT; +} + +static LCID LCIDFromLocaleInternal(LCID userDefaultLCID, const String& userDefaultLanguageCode, LocaleNameToLCIDPtr localeNameToLCID, const String& locale) { String localeLanguageCode = extractLanguageCode(locale); if (equalIgnoringCase(localeLanguageCode, userDefaultLanguageCode)) return userDefaultLCID; - return ::LocaleNameToLCID(locale.charactersWithNullTermination().data(), 0); + return localeNameToLCID(locale.charactersWithNullTermination().data(), 0); } static LCID LCIDFromLocale(const String& locale, bool defaultsForLocale) { + // LocaleNameToLCID() is available since Windows Vista. + LocaleNameToLCIDPtr localeNameToLCID = reinterpret_cast<LocaleNameToLCIDPtr>(::GetProcAddress(::GetModuleHandle(L"kernel32"), "LocaleNameToLCID")); + if (!localeNameToLCID) + localeNameToLCID = convertLocaleNameToLCID; + // According to MSDN, 9 is enough for LOCALE_SISO639LANGNAME. const size_t languageCodeBufferSize = 9; WCHAR lowercaseLanguageCode[languageCodeBufferSize]; ::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME | (defaultsForLocale ? LOCALE_NOUSEROVERRIDE : 0), lowercaseLanguageCode, languageCodeBufferSize); String userDefaultLanguageCode = String(lowercaseLanguageCode); - LCID lcid = LCIDFromLocaleInternal(LOCALE_USER_DEFAULT, userDefaultLanguageCode, locale); + LCID lcid = LCIDFromLocaleInternal(LOCALE_USER_DEFAULT, userDefaultLanguageCode, localeNameToLCID, locale); if (!lcid) - lcid = LCIDFromLocaleInternal(LOCALE_USER_DEFAULT, userDefaultLanguageCode, defaultLanguage()); + lcid = LCIDFromLocaleInternal(LOCALE_USER_DEFAULT, userDefaultLanguageCode, localeNameToLCID, defaultLanguage()); return lcid; } diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp index 02b29a1cd201e..92eee0406667a 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp @@ -323,6 +323,8 @@ v8::MaybeLocal<v8::Value> InjectedScript::resolveCallArgument(ErrorString* error PassOwnPtr<protocol::Runtime::ExceptionDetails> InjectedScript::createExceptionDetails(v8::Local<v8::Message> message) { OwnPtr<protocol::Runtime::ExceptionDetails> exceptionDetailsObject = protocol::Runtime::ExceptionDetails::create().setText(toProtocolString(message->Get())).build(); + if (message.IsEmpty()) + return exceptionDetailsObject; exceptionDetailsObject->setUrl(toProtocolStringWithTypeCheck(message->GetScriptResourceName())); exceptionDetailsObject->setScriptId(String16::number(message->GetScriptOrigin().ScriptID()->Value())); diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h index 6b068837ec647..8545a7e3efc0b 100644 --- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h +++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h @@ -80,6 +80,8 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { String domain() const { return m_domain; } unsigned short port() const { return m_port; } + bool hasUniversalAccess() const { return m_universalAccess; } + // |port()| will return 0 if the port is the default for an origin. This // method instead returns the effective port, even if it is the default port // (e.g. "http" => 80). diff --git a/third_party/WebKit/Source/platform/win/HWndDC.h b/third_party/WebKit/Source/platform/win/HWndDC.h new file mode 100644 index 0000000000000..29da03cd219be --- /dev/null +++ b/third_party/WebKit/Source/platform/win/HWndDC.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HWndDC_h +#define HWndDC_h + +#include <windows.h> +#include "wtf/NonCopyable.h" + +namespace blink { + +class HWndDC { + WTF_MAKE_NONCOPYABLE(HWndDC); +public: + HWndDC() + : m_hwnd(0) + , m_hdc(0) + { + } + + explicit HWndDC(HWND hwnd) + : m_hwnd(hwnd) + , m_hdc(::GetDC(hwnd)) + { + } + + HWndDC(HWND hwnd, HRGN hrgnClip, DWORD flags) + : m_hwnd(hwnd) + , m_hdc(::GetDCEx(hwnd, hrgnClip, flags)) + { + } + + ~HWndDC() + { + clear(); + } + + HDC setHWnd(HWND hwnd) + { + clear(); + m_hwnd = hwnd; + m_hdc = ::GetDC(hwnd); + return m_hdc; + } + + void clear() + { + if (!m_hdc) + return; + ::ReleaseDC(m_hwnd, m_hdc); + m_hwnd = 0; + m_hdc = 0; + } + + operator HDC() + { + return m_hdc; + } + +private: + HWND m_hwnd; + HDC m_hdc; +}; + +} // namespace blink + +#endif // HWndDC_h diff --git a/third_party/WebKit/Source/platform/win/SystemInfo.cpp b/third_party/WebKit/Source/platform/win/SystemInfo.cpp new file mode 100644 index 0000000000000..ebad37b392169 --- /dev/null +++ b/third_party/WebKit/Source/platform/win/SystemInfo.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform/win/SystemInfo.h" + +#include <windows.h> + +#if _WIN32_WINNT >= 0x0603 +#include <versionhelpers.h> +#endif + +namespace blink { + +#if _WIN32_WINNT < 0x0603 +static bool IsWindowsVistaOrGreater() +{ + OSVERSIONINFOEXW osvi = { }; + osvi.dwOSVersionInfoSize = sizeof(osvi); + osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA); + osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA); + DWORDLONG condition = 0; + VER_SET_CONDITION(condition, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(condition, VER_MINORVERSION, VER_GREATER_EQUAL); + return !!::VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, condition); +} +#endif + +bool isWindowsVistaOrGreater() +{ + static bool initialized = false; + static bool cachedIsWindowsVistaOrGreater; + + if (!initialized) { + initialized = true; + cachedIsWindowsVistaOrGreater = IsWindowsVistaOrGreater(); + } + return cachedIsWindowsVistaOrGreater; +} + +} // namespace blink diff --git a/third_party/WebKit/Source/platform/win/SystemInfo.h b/third_party/WebKit/Source/platform/win/SystemInfo.h new file mode 100644 index 0000000000000..a79f1e0b897ce --- /dev/null +++ b/third_party/WebKit/Source/platform/win/SystemInfo.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SystemInfo_h +#define SystemInfo_h + +#include "platform/PlatformExport.h" + +namespace blink { + +extern "C" PLATFORM_EXPORT bool isWindowsVistaOrGreater(); + +} // namespace blink + +#endif // SystemInfo_h diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp index 3d0bf95dd324a..706fd31baa7a9 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp +++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp @@ -350,7 +350,7 @@ WebNavigationPolicy effectiveNavigationPolicy(NavigationPolicy navigationPolicy, } // namespace Page* ChromeClientImpl::createWindow(LocalFrame* frame, const FrameLoadRequest& r, const WindowFeatures& features, - NavigationPolicy navigationPolicy, ShouldSetOpener shouldSetOpener) + NavigationPolicy navigationPolicy, ShouldSetOpener shouldSetOpener, WebString* manifest) { if (!m_webView->client()) return nullptr; @@ -363,7 +363,7 @@ Page* ChromeClientImpl::createWindow(LocalFrame* frame, const FrameLoadRequest& Fullscreen::fullyExitFullscreen(*frame->document()); WebViewImpl* newView = toWebViewImpl( - m_webView->client()->createView(WebLocalFrameImpl::fromFrame(frame), WrappedResourceRequest(r.resourceRequest()), features, r.frameName(), policy, shouldSetOpener == NeverSetOpener)); + m_webView->client()->createView(WebLocalFrameImpl::fromFrame(frame), WrappedResourceRequest(r.resourceRequest()), features, r.frameName(), policy, shouldSetOpener == NeverSetOpener, manifest)); if (!newView) return nullptr; return newView->page(); @@ -692,14 +692,20 @@ void ChromeClientImpl::openFileChooser(LocalFrame* frame, PassRefPtr<FileChooser WebFileChooserParams params; params.multiSelect = fileChooser->settings().allowsMultipleFiles; - params.directory = fileChooser->settings().allowsDirectoryUpload; + params.directory = fileChooser->settings().allowsDirectoryUpload || fileChooser->settings().directoryChooser; params.acceptTypes = fileChooser->settings().acceptTypes(); params.selectedFiles = fileChooser->settings().selectedFiles; - if (params.selectedFiles.size() > 0) + if (params.selectedFiles.size() > 0) { params.initialValue = params.selectedFiles[0]; + } else { + params.initialValue = fileChooser->settings().initialValue; + } params.useMediaCapture = fileChooser->settings().useMediaCapture; params.needLocalPath = fileChooser->settings().allowsDirectoryUpload; params.requestor = frame->document()->url(); + params.initialPath = fileChooser->settings().initialPath; + params.saveAs = fileChooser->settings().saveAs; + params.extractDirectory = fileChooser->settings().allowsDirectoryUpload; WebFileChooserCompletionImpl* chooserCompletion = new WebFileChooserCompletionImpl(fileChooser); if (client->runFileChooser(params, chooserCompletion)) diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.h b/third_party/WebKit/Source/web/ChromeClientImpl.h index 819a9a814f2b7..cb98db9b9d850 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.h +++ b/third_party/WebKit/Source/web/ChromeClientImpl.h @@ -67,7 +67,7 @@ class WEB_EXPORT ChromeClientImpl final : public ChromeClient { void startDragging(LocalFrame*, const WebDragData&, WebDragOperationsMask, const WebImage& dragImage, const WebPoint& dragImageOffset) override; bool acceptsLoadDrops() const override; Page* createWindow( - LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSetOpener) override; + LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSetOpener, WebString*) override; void show(NavigationPolicy) override; void didOverscroll( const FloatSize& overscrollDelta, diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp index 2227e44c2c800..b96386edcc83e 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp @@ -125,6 +125,14 @@ Frame* toCoreFrame(WebFrame* frame) } // namespace +void FrameLoaderClientImpl::willHandleNavigationPolicy(const ResourceRequest& request, NavigationPolicy* policy, WebString* manifest, bool new_win) +{ + if (m_webFrame->client()) { + WrappedResourceRequest webreq(request); + m_webFrame->client()->willHandleNavigationPolicy(m_webFrame, webreq, (WebNavigationPolicy*)policy, manifest, new_win); + } +} + FrameLoaderClientImpl::FrameLoaderClientImpl(WebLocalFrameImpl* frame) : m_webFrame(frame) { diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h index 7482a79171d6f..48b3ab71164b5 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h @@ -55,6 +55,7 @@ class FrameLoaderClientImpl final : public FrameLoaderClient { // FrameLoaderClient ---------------------------------------------- void didCreateNewDocument() override; + void willHandleNavigationPolicy(const blink::ResourceRequest& request, blink::NavigationPolicy* policy, WebString* manifest = NULL, bool new_win = true) override; // Notifies the WebView delegate that the JS window object has been cleared, // giving it a chance to bind native objects to the window before script // parsing begins. diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h index 19b1f74c91f24..77011ccdb3324 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h @@ -308,6 +308,15 @@ class WEB_EXPORT WebLocalFrameImpl final : public WebFrameImplBase, WTF_NON_EXPO void setInputEventsTransformForEmulation(const IntSize&, float); + void setNodeJS(bool node) { frame()->setNodeJS(node); } + bool isNodeJS() const { return frame()->isNodeJS(); } + bool isNwDisabledChildFrame() const { return frame()->isNwDisabledChildFrame(); } + bool isNwFakeTop() const { return frame()->isNwFakeTop(); } + + void setDevtoolsJail(WebFrame* iframe) { + frame()->setDevtoolsJail(iframe ? static_cast<const WebLocalFrameImpl*>(iframe)->frame() : NULL); + } + WebFrame* getDevtoolsJail() { return fromFrame((blink::LocalFrame*)frame()->getDevtoolsJail()); } static void selectWordAroundPosition(LocalFrame*, VisiblePosition); TextFinder* textFinder() const; diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index 65f584eba1bc0..2abc48efc6497 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp @@ -5835,7 +5835,7 @@ TEST_P(ParameterizedWebFrameTest, SimulateFragmentAnchorMiddleClick) class TestNewWindowWebViewClient : public FrameTestHelpers::TestWebViewClient { public: virtual WebView* createView(WebLocalFrame*, const WebURLRequest&, const WebWindowFeatures&, - const WebString&, WebNavigationPolicy, bool) override + const WebString&, WebNavigationPolicy, bool, WebString*) override { EXPECT_TRUE(false); return 0; diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index 6c33efd1da9eb..16b4ffb36fefe 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp @@ -1957,7 +1957,7 @@ class ViewCreatingWebViewClient : public FrameTestHelpers::TestWebViewClient { } // WebViewClient methods - WebView* createView(WebLocalFrame* opener, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) override + WebView* createView(WebLocalFrame* opener, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool, WebString*) override { return m_webViewHelper.initializeWithOpener(opener, true); } diff --git a/third_party/WebKit/public/platform/WebSecurityOrigin.h b/third_party/WebKit/public/platform/WebSecurityOrigin.h index 528e473bbb6fb..052f96ab35040 100644 --- a/third_party/WebKit/public/platform/WebSecurityOrigin.h +++ b/third_party/WebKit/public/platform/WebSecurityOrigin.h @@ -108,6 +108,8 @@ class WebSecurityOrigin { // Allows this WebSecurityOrigin access to local resources. BLINK_PLATFORM_EXPORT void grantLoadLocalResources() const; + BLINK_PLATFORM_EXPORT void grantUniversalAccess() const; + #if INSIDE_BLINK BLINK_PLATFORM_EXPORT WebSecurityOrigin(const WTF::PassRefPtr<SecurityOrigin>&); BLINK_PLATFORM_EXPORT WebSecurityOrigin& operator=(const WTF::PassRefPtr<SecurityOrigin>&); diff --git a/third_party/WebKit/public/web/WebFileChooserParams.h b/third_party/WebKit/public/web/WebFileChooserParams.h index 8924f2f73601b..1bde38eb29ea1 100644 --- a/third_party/WebKit/public/web/WebFileChooserParams.h +++ b/third_party/WebKit/public/web/WebFileChooserParams.h @@ -81,12 +81,16 @@ struct WebFileChooserParams { // initiated by a document. WebURL requestor; + WebString initialPath; + bool extractDirectory; + WebFileChooserParams() : multiSelect(false) , directory(false) , saveAs(false) , useMediaCapture(false) , needLocalPath(true) + , extractDirectory(true) { } }; diff --git a/third_party/WebKit/public/web/WebFrame.h b/third_party/WebKit/public/web/WebFrame.h index c1245a3a29cbd..88e8f9fb32b0d 100644 --- a/third_party/WebKit/public/web/WebFrame.h +++ b/third_party/WebKit/public/web/WebFrame.h @@ -115,6 +115,14 @@ class WebFrame { TextGranularityLast = WordGranularity, }; + virtual void setNodeJS(bool) {} + virtual bool isNodeJS() const {return false;} + virtual bool isNwDisabledChildFrame() const {return false;} + virtual bool isNwFakeTop() const {return false;} + + virtual void setDevtoolsJail(WebFrame*) {} + virtual WebFrame* getDevtoolsJail() {return NULL;} + // Returns the number of live WebFrame objects, used for leak checking. BLINK_EXPORT static int instanceCount(); @@ -553,9 +561,10 @@ class WebFrame { // the given element is not a frame, iframe or if the frame is empty. BLINK_EXPORT static WebFrame* fromFrameOwnerElement(const WebElement&); -#if BLINK_IMPLEMENTATION static WebFrame* fromFrame(Frame*); +#if BLINK_IMPLEMENTATION + bool inShadowTree() const { return m_scope == WebTreeScopeType::Shadow; } static void traceFrames(Visitor*, WebFrame*); diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h index 497364f2c4a8d..6822f1cb349e2 100644 --- a/third_party/WebKit/public/web/WebFrameClient.h +++ b/third_party/WebKit/public/web/WebFrameClient.h @@ -112,6 +112,8 @@ class WebFrameClient { public: // Factory methods ----------------------------------------------------- + virtual void willHandleNavigationPolicy( + WebFrame*, const WebURLRequest&, WebNavigationPolicy*, WebString* manifest = NULL, bool new_win = true) { } // May return null. virtual WebPlugin* createPlugin(WebLocalFrame*, const WebPluginParams&) { return 0; } diff --git a/third_party/WebKit/public/web/WebNode.h b/third_party/WebKit/public/web/WebNode.h index 7513449c72cc3..e5f7912596037 100644 --- a/third_party/WebKit/public/web/WebNode.h +++ b/third_party/WebKit/public/web/WebNode.h @@ -107,10 +107,10 @@ class WebNode { template<typename T> T to(); template<typename T> const T toConst() const; + BLINK_EXPORT WebNode(Node*); #if BLINK_IMPLEMENTATION BLINK_EXPORT static WebPluginContainer* pluginContainerFromNode(const Node*); - BLINK_EXPORT WebNode(Node*); BLINK_EXPORT WebNode& operator=(Node*); BLINK_EXPORT operator Node*() const; diff --git a/third_party/WebKit/public/web/WebViewClient.h b/third_party/WebKit/public/web/WebViewClient.h index a41ebe62535a1..6d0878bf9ca05 100644 --- a/third_party/WebKit/public/web/WebViewClient.h +++ b/third_party/WebKit/public/web/WebViewClient.h @@ -84,7 +84,8 @@ class WebViewClient : protected WebWidgetClient { const WebWindowFeatures& features, const WebString& name, WebNavigationPolicy policy, - bool suppressOpener) { + bool suppressOpener, + WebString* manifest = NULL) { return 0; } diff --git a/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc b/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc index da43a8a8c981e..64e07699e9629 100644 --- a/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc +++ b/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc @@ -152,10 +152,15 @@ bool FillThreadContextAndSuspendCount(HANDLE thread_handle, #if defined(ARCH_CPU_32_BITS) const bool is_native = true; #elif defined(ARCH_CPU_64_BITS) - const bool is_native = !is_64_reading_32; - if (is_64_reading_32) { + bool is_native = !is_64_reading_32; + typedef BOOL (WINAPI* Wow64GetThreadContextFunc)(HANDLE, PVOID); + Wow64GetThreadContextFunc wow64_get_thread_context = reinterpret_cast<Wow64GetThreadContextFunc>( + GetProcAddress(GetModuleHandle(L"kernel32.dll"), "Wow64GetThreadContext")); + if (!wow64_get_thread_context) + is_native = true; + if (is_64_reading_32 && wow64_get_thread_context) { thread->context.wow64.ContextFlags = CONTEXT_ALL; - if (!Wow64GetThreadContext(thread_handle, &thread->context.wow64)) { + if (!(*wow64_get_thread_context)(thread_handle, &thread->context.wow64)) { PLOG(ERROR) << "Wow64GetThreadContext"; return false; } diff --git a/third_party/zlib/x86.c b/third_party/zlib/x86.c index e6532fd10ddb4..0649306f2f0ff 100644 --- a/third_party/zlib/x86.c +++ b/third_party/zlib/x86.c @@ -56,21 +56,43 @@ static void _x86_check_features(void) #else #include <intrin.h> #include <windows.h> +#include <stdint.h> -static BOOL CALLBACK _x86_check_features(PINIT_ONCE once, - PVOID param, - PVOID *context); -static INIT_ONCE cpu_check_inited_once = INIT_ONCE_STATIC_INIT; +static volatile int32_t once_control = 0; +static void _x86_check_features(void); +static int fake_pthread_once(volatile int32_t *once_control, + void (*init_routine)(void)); void x86_check_features(void) { - InitOnceExecuteOnce(&cpu_check_inited_once, _x86_check_features, - NULL, NULL); + fake_pthread_once(&once_control, _x86_check_features); +} + +/* Copied from "perftools_pthread_once" in tcmalloc */ +static int fake_pthread_once(volatile int32_t *once_control, + void (*init_routine)(void)) { + // Try for a fast path first. Note: this should be an acquire semantics read + // It is on x86 and x64, where Windows runs. + if (*once_control != 1) { + while (1) { + switch (InterlockedCompareExchange(once_control, 2, 0)) { + case 0: + init_routine(); + InterlockedExchange(once_control, 1); + return 0; + case 1: + // The initializer has already been executed + return 0; + default: + // The initializer is being processed by another thread + SwitchToThread(); + } + } + } + return 0; } -static BOOL CALLBACK _x86_check_features(PINIT_ONCE once, - PVOID param, - PVOID *context) +static void _x86_check_features(void) { int x86_cpu_has_sse2; int x86_cpu_has_sse42; @@ -86,6 +108,5 @@ static BOOL CALLBACK _x86_check_features(PINIT_ONCE once, x86_cpu_enable_simd = x86_cpu_has_sse2 && x86_cpu_has_sse42 && x86_cpu_has_pclmulqdq; - return TRUE; } #endif /* _MSC_VER */ diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index 5c46a2647f878..b5ccc90201079 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids @@ -315,4 +315,8 @@ }, # Resource ids starting at 31000 are reserved for projects built on Chromium. + "chrome/browser/nwjs_resources.grd": { + "includes": [32000], + "structures": [32350], + }, } diff --git a/tools/licenses.py b/tools/licenses.py index 7a77710c0c5c1..8d2b8a73525cf 100755 --- a/tools/licenses.py +++ b/tools/licenses.py @@ -103,6 +103,7 @@ 'layout_tests')) # lots of subdirs ADDITIONAL_PATHS = ( + os.path.join('content', 'nw'), os.path.join('breakpad'), os.path.join('chrome', 'common', 'extensions', 'docs', 'examples'), os.path.join('chrome', 'test', 'chromeos', 'autotest'), @@ -126,6 +127,16 @@ # can't provide a README.chromium. Please prefer a README.chromium # wherever possible. SPECIAL_CASES = { + os.path.join('content', 'nw'): { + "Name": "NW.js", + "URL": "http://nwjs.io", + "License": "MIT", + }, + os.path.join('third_party', 'node'): { + "Name": "IO.js", + "URL": "https://iojs.org", + "License": "MIT", + }, os.path.join('native_client'): { "Name": "native client", "URL": "http://code.google.com/p/nativeclient", diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 3c0a3d59c7de5..e55ef02eecb6d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -12467,6 +12467,17 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. </summary> </histogram> +<histogram name="Event.TimestampHasValidTimebase" enum="EventTimestampValidity"> + <owner>majidvp@chromium.org</owner> + <owner>tdresser@chromium.org</owner> + <owner>caseq@chromium.org</owner> + <summary> + Whether the timestapms on input events produced by the windowing system + appear to be sharing the same time base as TimeTicks, modulo possible + roll-over. + </summary> +</histogram> + <histogram name="Event.Touch.TargetAndDispatchResult" enum="TouchTargetAndDispatchResultType"> <obsolete> @@ -70105,6 +70116,11 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. <int value="5" label="Forced Non-Blocking"/> </enum> +<enum name="EventTimestampValidity" type="int"> + <int value="0" label="Invalid time base"/> + <int value="1" label="Valid time base"/> +</enum> + <enum name="EVWhitelistStatus" type="int"> <int value="0" label="Not present"/> <int value="1" label="Invalid"/> diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.h b/ui/accelerated_widget_mac/accelerated_widget_mac.h index cf26ad6febcb1..b3474a78e41be 100644 --- a/ui/accelerated_widget_mac/accelerated_widget_mac.h +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.h @@ -79,6 +79,9 @@ class ACCELERATED_WIDGET_MAC_EXPORT AcceleratedWidgetMac { base::ScopedCFTypeRef<IOSurfaceRef> io_surface, const gfx::Size& pixel_size, float scale_factor); + + void GotSoftwareFrame(float scale_factor, + SkCanvas* canvas); private: void GotCAContextFrame(CAContextID ca_context_id, @@ -135,6 +138,9 @@ class ACCELERATED_WIDGET_MAC_EXPORT AcceleratedWidgetMac { #endif // __OBJC__ ACCELERATED_WIDGET_MAC_EXPORT +void AcceleratedWidgetMacGotSoftwareFrame( + gfx::AcceleratedWidget widget, float scale_factor, SkCanvas* canvas); + void AcceleratedWidgetMacGotFrame( gfx::AcceleratedWidget widget, CAContextID ca_context_id, diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.mm b/ui/accelerated_widget_mac/accelerated_widget_mac.mm index bc496e1587a24..c10509d7dd3ee 100644 --- a/ui/accelerated_widget_mac/accelerated_widget_mac.mm +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.mm @@ -22,6 +22,10 @@ @interface CALayer (PrivateAPI) - (void)setContentsChanged; @end +namespace content { + extern bool g_force_cpu_draw; +} + namespace ui { namespace { @@ -227,6 +231,8 @@ - (void)setContentsChanged; [local_layer_ setContentsGravity:kCAGravityTopLeft]; [local_layer_ setAnchorPoint:CGPointMake(0, 0)]; [flipped_layer_ addSublayer:local_layer_]; + if (content::g_force_cpu_draw) + [local_layer_.get() setBackgroundColor:[flipped_layer_.get() backgroundColor]]; } } @@ -273,6 +279,80 @@ - (void)setContentsChanged; local_layer_.reset(); } +void AcceleratedWidgetMac::GotSoftwareFrame(float scale_factor, + SkCanvas* canvas) { + assert(content::g_force_cpu_draw); + if (!canvas || !view_) + return; + + // Disable the fade-in or fade-out effect if we create or remove layers. + ScopedCAActionDisabler disabler; + + // If there is not a layer for local frames, create one. + EnsureLocalLayer(); + + // Set the software layer to draw the provided canvas. + SkPixmap pixmap; + canvas->peekPixels(&pixmap); + const SkImageInfo& info = pixmap.info(); + const size_t row_bytes = pixmap.rowBytes(); + const void* pixels = pixmap.addr(); + gfx::Size pixel_size(info.width(), info.height()); + + TRACE_EVENT0("browser", "-[AcceleratedWidgetMac GotSoftwareFrame]"); + + // Set the contents of the software CALayer to be a CGImage with the provided + // pixel data. Make a copy of the data before backing the image with them, + // because the same buffer will be reused for the next frame. + base::ScopedCFTypeRef<CFDataRef> dataCopy( + CFDataCreate(NULL, + static_cast<const UInt8 *>(pixels), + row_bytes * pixel_size.height())); + base::ScopedCFTypeRef<CGDataProviderRef> dataProvider( + CGDataProviderCreateWithCFData(dataCopy)); + base::ScopedCFTypeRef<CGImageRef> image( + CGImageCreate(pixel_size.width(), + pixel_size.height(), + 8, + 32, + row_bytes, + base::mac::GetSystemColorSpace(), + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, + dataProvider, + NULL, + false, + kCGRenderingIntentDefault)); + [local_layer_ setContents:(id)image.get()]; + [local_layer_ setBounds:CGRectMake( + 0, 0, pixel_size.width() / scale_factor, pixel_size.height() / scale_factor)]; + + // Set the contents scale of the software CALayer. + if ([local_layer_ respondsToSelector:(@selector(contentsScale))] && + [local_layer_ respondsToSelector:(@selector(setContentsScale:))] && + [local_layer_ contentsScale] != scale_factor) { + [local_layer_ setContentsScale:scale_factor]; + } + + last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); + + if (content::g_force_cpu_draw) { + // this is to tell parent window, that the window content has been updated + [[view_->AcceleratedWidgetGetNSView() superview]setNeedsDisplay:YES]; + } + // Remove any different-type layers that this is replacing. + DestroyCAContextLayer(ca_context_layer_); +} + +void AcceleratedWidgetMacGotSoftwareFrame( + gfx::AcceleratedWidget widget, float scale_factor, SkCanvas* canvas) { + assert(content::g_force_cpu_draw); + + AcceleratedWidgetMac* accelerated_widget_mac = + GetHelperFromAcceleratedWidget(widget); + if (accelerated_widget_mac) + accelerated_widget_mac->GotSoftwareFrame(scale_factor, canvas); +} + void AcceleratedWidgetMacGotFrame( gfx::AcceleratedWidget widget, CAContextID ca_context_id, diff --git a/ui/accessibility/platform/atk_util_auralinux.cc b/ui/accessibility/platform/atk_util_auralinux.cc index 46ad3be53be83..9d1be38a0440e 100644 --- a/ui/accessibility/platform/atk_util_auralinux.cc +++ b/ui/accessibility/platform/atk_util_auralinux.cc @@ -157,7 +157,7 @@ AtkUtilAuraLinux::AtkUtilAuraLinux() { void AtkUtilAuraLinux::Initialize( scoped_refptr<base::TaskRunner> init_task_runner) { - +#if 0 // Register our util class. g_type_class_unref(g_type_class_ref(ATK_UTIL_AURALINUX_TYPE)); @@ -169,6 +169,7 @@ void AtkUtilAuraLinux::Initialize( base::Bind( &AtkUtilAuraLinux::FinishAccessibilityInitOnUIThread, base::Unretained(this))); +#endif } AtkUtilAuraLinux::~AtkUtilAuraLinux() { diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc index 4f6ad4b1598ba..4b5fc0fe3115a 100644 --- a/ui/base/accelerators/accelerator.cc +++ b/ui/base/accelerators/accelerator.cc @@ -250,7 +250,8 @@ base::string16 Accelerator::GetShortcutText() const { // more information. if (IsCtrlDown()) shortcut = l10n_util::GetStringFUTF16(IDS_APP_CONTROL_MODIFIER, shortcut); - else if (IsAltDown()) + + if (IsAltDown()) shortcut = l10n_util::GetStringFUTF16(IDS_APP_ALT_MODIFIER, shortcut); if (IsCmdDown()) { @@ -258,6 +259,10 @@ base::string16 Accelerator::GetShortcutText() const { shortcut = l10n_util::GetStringFUTF16(IDS_APP_COMMAND_MODIFIER, shortcut); #elif defined(OS_CHROMEOS) shortcut = l10n_util::GetStringFUTF16(IDS_APP_SEARCH_MODIFIER, shortcut); +#elif defined(OS_WIN) + shortcut = l10n_util::GetStringFUTF16(IDS_APP_WINDOWS_MODIFIER, shortcut); +#elif defined(OS_LINUX) + shortcut = l10n_util::GetStringFUTF16(IDS_APP_SUPER_MODIFIER, shortcut); #else NOTREACHED(); #endif diff --git a/ui/base/base_window.cc b/ui/base/base_window.cc index 231a1771797ef..40e00cb7cdb69 100644 --- a/ui/base/base_window.cc +++ b/ui/base/base_window.cc @@ -12,5 +12,9 @@ bool BaseWindow::IsRestored(const BaseWindow& window) { !window.IsFullscreen(); } +void BaseWindow::ForceClose() { + Close(); +} + } // namespace ui diff --git a/ui/base/base_window.h b/ui/base/base_window.h index 1819405fb4b9b..3952b712f2886 100644 --- a/ui/base/base_window.h +++ b/ui/base/base_window.h @@ -65,6 +65,7 @@ class UI_BASE_EXPORT BaseWindow { // Closes the window as soon as possible. The close action may be delayed // if an operation is in progress (e.g. a drag operation). virtual void Close() = 0; + virtual void ForceClose(); // Activates (brings to front) the window. Restores the window from minimized // state if necessary. diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h index 40af4df4f2fe2..84dc61284295a 100644 --- a/ui/base/clipboard/clipboard.h +++ b/ui/base/clipboard/clipboard.h @@ -233,7 +233,7 @@ class UI_BASE_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) { static const FormatType& GetIDListFormatType(); #endif - protected: + public: static Clipboard* Create(); Clipboard() {} diff --git a/ui/base/models/simple_menu_model.cc b/ui/base/models/simple_menu_model.cc index 3fd26fa683bea..c3fbdf5a54891 100644 --- a/ui/base/models/simple_menu_model.cc +++ b/ui/base/models/simple_menu_model.cc @@ -66,6 +66,10 @@ void SimpleMenuModel::Delegate::CommandIdHighlighted(int command_id) { void SimpleMenuModel::Delegate::MenuWillShow(SimpleMenuModel* /*source*/) { } +bool SimpleMenuModel::Delegate::HasIcon(int command_id) { + return false; +} + void SimpleMenuModel::Delegate::MenuClosed(SimpleMenuModel* /*source*/) { } @@ -267,7 +271,7 @@ int SimpleMenuModel::GetIndexOfCommandId(int command_id) { bool SimpleMenuModel::HasIcons() const { for (ItemVector::const_iterator i = items_.begin(); i != items_.end(); ++i) { - if (!i->icon.IsEmpty()) + if (delegate_->HasIcon(i->command_id)) return true; } diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h index 639830d10717c..ee7ad11f02c93 100644 --- a/ui/base/models/simple_menu_model.h +++ b/ui/base/models/simple_menu_model.h @@ -66,6 +66,8 @@ class UI_BASE_EXPORT SimpleMenuModel : public MenuModel { // Notifies the delegate that the menu has closed. virtual void MenuClosed(SimpleMenuModel* source); + + virtual bool HasIcon(int command_id); }; // The Delegate can be NULL, though if it is items can't be checked or diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc index 0f95c9e2e08df..eb0ede6c3d56b 100644 --- a/ui/base/resource/resource_bundle.cc +++ b/ui/base/resource/resource_bundle.cc @@ -4,6 +4,8 @@ #include "ui/base/resource/resource_bundle.h" +#include "base/strings/string_util.h" + #include <stdint.h> #include <limits> @@ -73,6 +75,8 @@ const char kPakFileSuffix[] = ".pak"; ResourceBundle* g_shared_instance_ = NULL; +base::string16 chromium_name, nwjs_name; + #if defined(OS_ANDROID) // Returns the scale factor closest to |scale| from the full list of factors. // Note that it does NOT rely on the list of supported scale factors. @@ -499,8 +503,10 @@ base::StringPiece ResourceBundle::GetRawDataResourceForScale( base::string16 ResourceBundle::GetLocalizedString(int message_id) { base::string16 string; - if (delegate_ && delegate_->GetLocalizedString(message_id, &string)) + if (delegate_ && delegate_->GetLocalizedString(message_id, &string)) { + base::ReplaceSubstringsAfterOffset(&string, 0, chromium_name, nwjs_name); return string; + } // Ensure that ReloadLocaleResources() doesn't drop the resources while // we're using them. @@ -544,6 +550,7 @@ base::string16 ResourceBundle::GetLocalizedString(int message_id) { } else if (encoding == ResourceHandle::UTF8) { msg = base::UTF8ToUTF16(data); } + base::ReplaceSubstringsAfterOffset(&msg, 0, chromium_name, nwjs_name); return msg; } @@ -657,6 +664,8 @@ ResourceBundle::~ResourceBundle() { void ResourceBundle::InitSharedInstance(Delegate* delegate) { DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; g_shared_instance_ = new ResourceBundle(delegate); + chromium_name = base::ASCIIToUTF16("Chromium"); + nwjs_name = base::ASCIIToUTF16("NW.js"); static std::vector<ScaleFactor> supported_scale_factors; #if !defined(OS_IOS) // On platforms other than iOS, 100P is always a supported scale factor. @@ -704,13 +713,13 @@ void ResourceBundle::LoadChromeResources() { if (MaterialDesignController::IsModeMaterial()) { if (IsScaleFactorSupported(SCALE_FACTOR_100P)) { AddMaterialDesignDataPackFromPath( - GetResourcesPakFilePath("chrome_material_100_percent.pak"), + GetResourcesPakFilePath("nw_material_100_percent.pak"), SCALE_FACTOR_100P); } if (IsScaleFactorSupported(SCALE_FACTOR_200P)) { AddOptionalMaterialDesignDataPackFromPath( - GetResourcesPakFilePath("chrome_material_200_percent.pak"), + GetResourcesPakFilePath("nw_material_200_percent.pak"), SCALE_FACTOR_200P); } } @@ -720,12 +729,12 @@ void ResourceBundle::LoadChromeResources() { // scale factor to gfx::ImageSkia::AddRepresentation. if (IsScaleFactorSupported(SCALE_FACTOR_100P)) { AddDataPackFromPath(GetResourcesPakFilePath( - "chrome_100_percent.pak"), SCALE_FACTOR_100P); + "nw_100_percent.pak"), SCALE_FACTOR_100P); } if (IsScaleFactorSupported(SCALE_FACTOR_200P)) { AddOptionalDataPackFromPath(GetResourcesPakFilePath( - "chrome_200_percent.pak"), SCALE_FACTOR_200P); + "nw_200_percent.pak"), SCALE_FACTOR_200P); } } diff --git a/ui/base/resource/resource_bundle_mac.mm b/ui/base/resource/resource_bundle_mac.mm index 8f5934cece83c..f1c2010de64e3 100644 --- a/ui/base/resource/resource_bundle_mac.mm +++ b/ui/base/resource/resource_bundle_mac.mm @@ -49,13 +49,13 @@ } // namespace void ResourceBundle::LoadCommonResources() { - AddDataPackFromPath(GetResourcesPakFilePath(@"chrome_100_percent", + AddDataPackFromPath(GetResourcesPakFilePath(@"nw_100_percent", nil), SCALE_FACTOR_100P); // On Mac we load 1x and 2x resources and we let the UI framework decide // which one to use. if (IsScaleFactorSupported(SCALE_FACTOR_200P)) { - AddDataPackFromPath(GetResourcesPakFilePath(@"chrome_200_percent", nil), + AddDataPackFromPath(GetResourcesPakFilePath(@"nw_200_percent", nil), SCALE_FACTOR_200P); } } @@ -81,11 +81,11 @@ data_packs_.weak_clear(); AddMaterialDesignDataPackFromPath( - GetResourcesPakFilePath(@"chrome_material_100_percent", nil), + GetResourcesPakFilePath(@"nw_material_100_percent", nil), SCALE_FACTOR_100P); AddOptionalMaterialDesignDataPackFromPath( - GetResourcesPakFilePath(@"chrome_material_200_percent", nil), + GetResourcesPakFilePath(@"nw_material_200_percent", nil), SCALE_FACTOR_200P); // Add back the non-Material Design packs so that they serve as a fallback. diff --git a/ui/events/x/events_x_utils.cc b/ui/events/x/events_x_utils.cc index aab2723730683..aa0c06d3d48f3 100644 --- a/ui/events/x/events_x_utils.cc +++ b/ui/events/x/events_x_utils.cc @@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/singleton.h" +#include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -306,12 +307,15 @@ bool GetGestureTimes(const XEvent& xev, double* start_time, double* end_time) { return true; } +namespace { int64_t g_last_seen_timestamp_ms = 0; -// accumulated rollover time. int64_t g_rollover_ms = 0; +bool g_bogus_x11_timestamps = false; base::LazyInstance<std::unique_ptr<base::TickClock>>::Leaky g_tick_clock = LAZY_INSTANCE_INITIALIZER; +} // namespace + // Takes Xlib Time and returns a time delta that is immune to timer rollover. // This function is not thread safe as we do not use a lock. base::TimeDelta TimeDeltaFromXEventTime(Time timestamp) { @@ -320,6 +324,11 @@ base::TimeDelta TimeDeltaFromXEventTime(Time timestamp) { if (!timestamp) return base::TimeDelta(); + if (g_bogus_x11_timestamps) { + return base::TimeDelta::FromInternalValue( + base::TimeTicks::Now().ToInternalValue()); + } + // If this is the first event that we get, assume the time stamp roll-over // might have happened before the process was started. // Register a rollover if the distance between last timestamp and current one @@ -343,11 +352,19 @@ base::TimeDelta TimeDeltaFromXEventTime(Time timestamp) { g_rollover_ms = now_ms & ~static_cast<int64_t>(UINT32_MAX); uint32_t delta = static_cast<uint32_t>(now_ms - timestamp); - // If using a mock clock, all bets are off -- in some tests, actual X11 events - // come through with real timestamps. - DCHECK(delta < 60 * 1000 || g_tick_clock.Get() != nullptr) - << "Unexpected X11 event time, now: " << now_ticks - << " event at: " << timestamp; + if (!g_tick_clock.Get()) { + if (delta > 60 * 1000) { + // x11 timestamps don't seem to be using the same time base as TimeTicks, + // so ignore them altogether and always use current time instead. + delta = 0; + g_bogus_x11_timestamps = true; + LOG(WARNING) + << "Unexpected x11 timestamps, will use browser time instead."; + } + UMA_HISTOGRAM_BOOLEAN("Event.TimestampHasValidTimebase", + !g_bogus_x11_timestamps); + } + return base::TimeDelta::FromMilliseconds(now_ms - delta); } @@ -813,6 +830,7 @@ void ResetTimestampRolloverCountersForTesting( std::unique_ptr<base::TickClock> tick_clock) { g_last_seen_timestamp_ms = 0; g_rollover_ms = 0; + g_bogus_x11_timestamps = false; g_tick_clock.Get() = std::move(tick_clock); } diff --git a/ui/gfx/icon_util.cc b/ui/gfx/icon_util.cc index 8276a20ce99e2..a0030878b7a2d 100644 --- a/ui/gfx/icon_util.cc +++ b/ui/gfx/icon_util.cc @@ -234,6 +234,21 @@ base::win::ScopedHICON IconUtil::CreateHICONFromSkBitmap( return icon; } +// NW fix: copied and modified from chrome/browser/ui/views/frame/glass_browser_frame_view.cc +// Converts the |image| to a Windows icon and returns the corresponding HICON +// handle. |image| is resized to desired |width| and |height| if needed. +base::win::ScopedHICON IconUtil::CreateHICONFromSkBitmapSizedTo( + const SkBitmap& bitmap, + int width, + int height) { + return CreateHICONFromSkBitmap( + width == bitmap.width() && height == bitmap.height() + ? bitmap + : skia::ImageOperations::Resize(bitmap, + skia::ImageOperations::RESIZE_BEST, + width, height)); +} + SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s) { // We start with validating parameters. if (!icon || s.IsEmpty()) diff --git a/ui/gfx/icon_util.h b/ui/gfx/icon_util.h index 960018ece0fe0..1e36e2f0be516 100644 --- a/ui/gfx/icon_util.h +++ b/ui/gfx/icon_util.h @@ -88,6 +88,10 @@ class GFX_EXPORT IconUtil { // needed by calling ::DestroyIcon(). static base::win::ScopedHICON CreateHICONFromSkBitmap(const SkBitmap& bitmap); + static base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo(const SkBitmap& bitmap, + int width, + int height); + // Given a valid HICON handle representing an icon, this function converts // the icon into an SkBitmap object containing an ARGB bitmap using the // dimensions specified in |s|. |s| must specify valid dimensions (both diff --git a/ui/gfx/mac/nswindow_frame_controls.h b/ui/gfx/mac/nswindow_frame_controls.h index 61c6331ecfa51..c9d583e3721bc 100644 --- a/ui/gfx/mac/nswindow_frame_controls.h +++ b/ui/gfx/mac/nswindow_frame_controls.h @@ -39,6 +39,7 @@ GFX_EXPORT void ApplyNSWindowSizeConstraints(NSWindow* window, const gfx::Size& max_size, bool can_resize, bool can_fullscreen); +GFX_EXPORT void SetNSWindowShowInTaskbar(NSWindow* window, bool show); } // namespace gfx diff --git a/ui/gfx/mac/nswindow_frame_controls.mm b/ui/gfx/mac/nswindow_frame_controls.mm index 133aae6cf7a7a..bae685ffd0cf7 100644 --- a/ui/gfx/mac/nswindow_frame_controls.mm +++ b/ui/gfx/mac/nswindow_frame_controls.mm @@ -58,6 +58,22 @@ void SetNSWindowAlwaysOnTop(NSWindow* window, [window setCollectionBehavior:behavior]; } +void SetNSWindowShowInTaskbar(NSWindow* window, bool show) { + ProcessSerialNumber psn = { 0, kCurrentProcess }; + if (!show) { + NSArray* windowList = [[NSArray alloc] init]; + windowList = [NSWindow windowNumbersWithOptions:NSWindowNumberListAllSpaces]; + for (unsigned int i = 0; i < [windowList count]; ++i) { + NSWindow *window = [NSApp windowWithWindowNumber:[[windowList objectAtIndex:i] integerValue]]; + [window setCanHide:NO]; + } + TransformProcessType(&psn, kProcessTransformToUIElementApplication); + } + else { + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + } +} + void SetNSWindowVisibleOnAllWorkspaces(NSWindow* window, bool always_visible) { NSWindowCollectionBehavior behavior = [window collectionBehavior]; if (always_visible) diff --git a/ui/gfx/paint_vector_icon.cc b/ui/gfx/paint_vector_icon.cc index 3bac6acd472f9..b5b4f320bcc8d 100644 --- a/ui/gfx/paint_vector_icon.cc +++ b/ui/gfx/paint_vector_icon.cc @@ -292,6 +292,7 @@ class VectorIconSource : public CanvasImageSource { gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)), false), id_(id), + path_(), color_(color), badge_id_(badge_id) {} diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc index a82de8e9d8de7..5bbb8311b9077 100644 --- a/ui/message_center/views/message_center_view.cc +++ b/ui/message_center/views/message_center_view.cc @@ -481,7 +481,7 @@ void MessageCenterView::AddNotificationAt(const Notification& notification, int index) { MessageView* view = MessageViewFactory::Create(this, notification, false); // Not top-level. - view->set_context_menu_controller(context_menu_controller_.get()); + //view->set_context_menu_controller(context_menu_controller_.get()); notification_views_[notification.id()] = view; view->set_scroller(scroller_); message_list_view_->AddNotificationAt(view, index); diff --git a/ui/message_center/views/message_popup_collection.cc b/ui/message_center/views/message_popup_collection.cc index 068336683f385..aafdccf3e54d6 100644 --- a/ui/message_center/views/message_popup_collection.cc +++ b/ui/message_center/views/message_popup_collection.cc @@ -172,7 +172,7 @@ void MessagePopupCollection::UpdateWidgets() { view = MessageViewFactory::Create(NULL, *(*iter), true); } - view->set_context_menu_controller(context_menu_controller_.get()); + //view->set_context_menu_controller(context_menu_controller_.get()); int view_height = ToastContentsView::GetToastSizeForView(view).height(); int height_available = top_down ? alignment_delegate_->GetWorkAreaBottom() - base : base; diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc index eb7b82f30d333..cecc38b3f2e15 100644 --- a/ui/native_theme/native_theme_win.cc +++ b/ui/native_theme/native_theme_win.cc @@ -50,6 +50,7 @@ const int kSystemColors[] = { COLOR_HIGHLIGHT, COLOR_HIGHLIGHTTEXT, COLOR_HOTLIGHT, + COLOR_MENU, COLOR_MENUHIGHLIGHT, COLOR_SCROLLBAR, COLOR_WINDOW, @@ -514,6 +515,10 @@ SkColor NativeThemeWin::GetSystemColor(ColorId color_id) const { case kColorId_ButtonHoverColor: return kButtonHoverColor; + // Menu + case kColorId_MenuBackgroundColor: + return system_colors_[COLOR_MENU]; + // Label case kColorId_LabelEnabledColor: return system_colors_[COLOR_BTNTEXT]; diff --git a/ui/shell_dialogs/select_file_dialog_mac.mm b/ui/shell_dialogs/select_file_dialog_mac.mm index 1ac812236305e..8a979fc85315f 100644 --- a/ui/shell_dialogs/select_file_dialog_mac.mm +++ b/ui/shell_dialogs/select_file_dialog_mac.mm @@ -219,7 +219,7 @@ - (void)popupAction:(id)sender; [open_dialog setCanChooseFiles:NO]; [open_dialog setCanChooseDirectories:YES]; [open_dialog setCanCreateDirectories:YES]; - NSString *prompt = (type == SELECT_UPLOAD_FOLDER) + NSString *prompt = (false && type == SELECT_UPLOAD_FOLDER) ? l10n_util::GetNSString(IDS_SELECT_UPLOAD_FOLDER_BUTTON_TITLE) : l10n_util::GetNSString(IDS_SELECT_FOLDER_BUTTON_TITLE); [open_dialog setPrompt:prompt]; diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index 81b0a2c797fad..d7666f861c1cd 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd @@ -556,6 +556,12 @@ need to be translated for each locale.--> <message name="IDS_APP_SEARCH_MODIFIER" desc="Search key shortcut modifier"> Search+<ph name="KEY_COMBO_NAME">$1<ex>C</ex></ph> </message> + <message name="IDS_APP_WINDOWS_MODIFIER" desc="Command key shortcut modifier"> + Win+<ph name="KEY_COMBO_NAME">$1<ex>C</ex></ph> + </message> + <message name="IDS_APP_SUPER_MODIFIER" desc="Command key shortcut modifier"> + Super+<ph name="KEY_COMBO_NAME">$1<ex>C</ex></ph> + </message> <!-- Byte size units --> <message name="IDS_APP_BYTES" desc="Units tag indicating a quantity of bytes"> diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc index 90927af368d2b..f6af9375cb725 100644 --- a/ui/views/accessibility/native_view_accessibility_auralinux.cc +++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc @@ -4,6 +4,8 @@ #include "ui/views/accessibility/native_view_accessibility_auralinux.h" +#include "content/public/browser/browser_thread.h" + #include <algorithm> #include <vector> @@ -131,7 +133,7 @@ class AuraLinuxApplication // This should be on the a blocking pool thread so that we can open // libatk-bridge.so without blocking this thread. scoped_refptr<base::TaskRunner> init_task_runner = - ViewsDelegate::GetInstance()->GetBlockingPoolTaskRunner(); + content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); if (init_task_runner) ui::AXPlatformNodeAuraLinux::StaticInitialize(init_task_runner); } diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index 98b6e0da97ae3..264c0b2f422f2 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc @@ -480,6 +480,9 @@ void LabelButton::ResetColorsFromNativeTheme() { PlatformStyle::ApplyLabelButtonTextStyle(label_, &colors); label_->set_background(nullptr); } else { + // Set auto color readability to false in case of switching theme from + // inverted color scheme. + label_->SetAutoColorReadabilityEnabled(false); label_->set_background(nullptr); } diff --git a/ui/views/controls/menu/native_menu_win.cc b/ui/views/controls/menu/native_menu_win.cc index e205fda62f917..530da45567f21 100644 --- a/ui/views/controls/menu/native_menu_win.cc +++ b/ui/views/controls/menu/native_menu_win.cc @@ -51,7 +51,8 @@ NativeMenuWin::NativeMenuWin(ui::MenuModel* model, HWND system_menu_for) system_menu_for_(system_menu_for), first_item_index_(0), parent_(NULL), - destroyed_flag_(NULL) { + destroyed_flag_(NULL), + is_popup_menu_(true){ } NativeMenuWin::~NativeMenuWin() { @@ -219,14 +220,18 @@ void NativeMenuWin::ResetNativeMenu() { } else { if (menu_) DestroyMenu(menu_); - menu_ = CreatePopupMenu(); + if (is_popup_menu_) + menu_ = CreatePopupMenu(); + else + menu_ = CreateMenu(); // Rather than relying on the return value of TrackPopupMenuEx, which is // always a command identifier, instead we tell the menu to notify us via // our host window and the WM_MENUCOMMAND message. MENUINFO mi = {0}; mi.cbSize = sizeof(mi); mi.fMask = MIM_STYLE | MIM_MENUDATA; - mi.dwStyle = MNS_NOTIFYBYPOS; + if (is_popup_menu_) + mi.dwStyle = MNS_NOTIFYBYPOS; mi.dwMenuData = reinterpret_cast<ULONG_PTR>(this); SetMenuInfo(menu_, &mi); } diff --git a/ui/views/controls/menu/native_menu_win.h b/ui/views/controls/menu/native_menu_win.h index 406599c08acdd..04d6a5e49f045 100644 --- a/ui/views/controls/menu/native_menu_win.h +++ b/ui/views/controls/menu/native_menu_win.h @@ -32,6 +32,9 @@ class VIEWS_EXPORT NativeMenuWin { void Rebuild(MenuInsertionDelegateWin* delegate); void UpdateStates(); + void set_is_popup_menu(bool flag) { is_popup_menu_ = flag; } + HMENU menu() const { return menu_; } + private: // IMPORTANT: Note about indices. // Functions in this class deal in two index spaces: @@ -99,6 +102,9 @@ class VIEWS_EXPORT NativeMenuWin { // If we're a submenu, this is our parent. NativeMenuWin* parent_; + // A flag to indicate whether to create a menubar or popupmenu. + bool is_popup_menu_; + // If non-null the destructor sets this to true. This is set to non-null while // the menu is showing. It is used to detect if the menu was deleted while // running. diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc index 57d5f13bc9beb..0f64ca74d2550 100644 --- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc @@ -73,7 +73,7 @@ std::vector<display::Display> GetFallbackDisplayList() { if (!display::Display::HasForceDeviceScaleFactor() && !ui::IsDisplaySizeBlackListed(physical_size)) { const float device_scale_factor = GetDeviceScaleFactor(); - DCHECK_LE(1.0f, device_scale_factor); + //DCHECK_LE(1.0f, device_scale_factor); gfx_display.SetScaleAndBounds(device_scale_factor, bounds_in_pixels); } diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index 7591042b3c5fc..0bcc044b93ead 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc @@ -41,6 +41,10 @@ #include "ui/wm/core/window_animations.h" #include "ui/wm/public/scoped_tooltip_disabler.h" +namespace content { + extern bool g_force_cpu_draw; +} + DECLARE_WINDOW_PROPERTY_TYPE(views::DesktopWindowTreeHostWin*); namespace views { @@ -714,10 +718,19 @@ bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const { return GetWidget()->widget_delegate()->ShouldHandleSystemCommands(); } +bool DesktopWindowTreeHostWin::ShouldHandleOnSize() const { + return GetWidget()->widget_delegate()->ShouldHandleOnSize(); +} + void DesktopWindowTreeHostWin::HandleAppDeactivated() { native_widget_delegate_->SetAlwaysRenderAsActive(false); } +bool DesktopWindowTreeHostWin::HandleSize(UINT param, const gfx::Size& new_size) { + return GetWidget()->widget_delegate() && + GetWidget()->widget_delegate()->HandleSize(param, new_size); +} + void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) { // This can be invoked from HWNDMessageHandler::Init(), at which point we're // not in a good state and need to ignore it. @@ -734,7 +747,7 @@ bool DesktopWindowTreeHostWin::HandleAppCommand(short command) { // We treat APPCOMMAND ids as an extension of our command namespace, and just // let the delegate figure out what to do... return GetWidget()->widget_delegate() && - GetWidget()->widget_delegate()->ExecuteWindowsCommand(command); + GetWidget()->widget_delegate()->ExecuteAppCommand(command); } void DesktopWindowTreeHostWin::HandleCancelMode() { @@ -887,6 +900,7 @@ void DesktopWindowTreeHostWin::HandleInputLanguageChange( void DesktopWindowTreeHostWin::HandlePaintAccelerated( const gfx::Rect& invalid_rect) { + if (content::g_force_cpu_draw) return; if (compositor()) compositor()->ScheduleRedrawRect(invalid_rect); } diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h index f357a5c989519..ce8201a8cf5da 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h @@ -127,6 +127,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin void OnWindowHidingAnimationCompleted() override; // Overridden from HWNDMessageHandlerDelegate: + bool ShouldHandleOnSize() const override; + bool HandleSize(UINT param, const gfx::Size& new_size) override; bool HasNonClientView() const override; FrameMode GetFrameMode() const override; bool HasFrame() const override; diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index f792797e855ba..b97f0fb501b25 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc @@ -62,6 +62,10 @@ DECLARE_WINDOW_PROPERTY_TYPE(views::DesktopWindowTreeHostX11*); +namespace content { + extern bool g_support_transparency; +} + namespace views { DesktopWindowTreeHostX11* DesktopWindowTreeHostX11::g_current_capture = @@ -781,7 +785,7 @@ bool DesktopWindowTreeHostX11::ShouldUseNativeFrame() const { } bool DesktopWindowTreeHostX11::ShouldWindowContentsBeTransparent() const { - return false; + return content::g_support_transparency ? use_argb_visual_ : false; } void DesktopWindowTreeHostX11::FrameTypeChanged() { @@ -937,7 +941,7 @@ bool DesktopWindowTreeHostX11::IsAnimatingClosed() const { } bool DesktopWindowTreeHostX11::IsTranslucentWindowOpacitySupported() const { - return false; + return content::g_support_transparency ? use_argb_visual_ : false; } void DesktopWindowTreeHostX11::SizeConstraintsChanged() { diff --git a/ui/views/widget/native_widget_delegate.h b/ui/views/widget/native_widget_delegate.h index e6c3b84ea042a..e8a954daaa8f7 100644 --- a/ui/views/widget/native_widget_delegate.h +++ b/ui/views/widget/native_widget_delegate.h @@ -57,6 +57,7 @@ class VIEWS_EXPORT NativeWidgetDelegate { // problems. virtual void SetAlwaysRenderAsActive(bool always_render_as_active) = 0; virtual bool IsAlwaysRenderAsActive() const = 0; + virtual bool NWCanClose(bool user_force = false) const = 0; // Called when the activation state of a window has changed. virtual void OnNativeWidgetActivationChanged(bool active) = 0; diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index a86fe4859ee53..0fbc2d23a9aab 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc @@ -561,7 +561,7 @@ void Widget::SetShape(SkRegion* shape) { native_widget_->SetShape(shape); } -void Widget::Close() { +void Widget::Close(bool force) { if (widget_closed_) { // It appears we can hit this code path if you close a modal dialog then // close the last browser before the destructor is hit, which triggers @@ -572,6 +572,8 @@ void Widget::Close() { bool can_close = true; if (non_client_view_) can_close = non_client_view_->CanClose(); + if (can_close && !force) + can_close = NWCanClose(); if (can_close) { SaveWindowPlacement(); @@ -1019,6 +1021,10 @@ bool Widget::IsAlwaysRenderAsActive() const { return always_render_as_active_; } +bool Widget::NWCanClose(bool user_force) const { + return widget_delegate_->NWCanClose(user_force); +} + void Widget::OnNativeWidgetActivationChanged(bool active) { // On windows we may end up here before we've completed initialization (from // an WM_NCACTIVATE). If that happens the WidgetDelegate likely doesn't know diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index e52c7fff2ed30..3dade86597c92 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h @@ -483,7 +483,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, void SetShape(SkRegion* shape); // Hides the widget then closes it after a return to the message loop. - virtual void Close(); + virtual void Close(bool force = false); // TODO(beng): Move off public API. // Closes the widget immediately. Compare to |Close|. This will destroy the @@ -786,6 +786,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, bool CanActivate() const override; bool IsAlwaysRenderAsActive() const override; void SetAlwaysRenderAsActive(bool always_render_as_active) override; + bool NWCanClose(bool user_force = false) const override; void OnNativeWidgetActivationChanged(bool active) override; void OnNativeFocus() override; void OnNativeBlur() override; diff --git a/ui/views/widget/widget_delegate.cc b/ui/views/widget/widget_delegate.cc index c5f9d97490c45..4fe06d714c747 100644 --- a/ui/views/widget/widget_delegate.cc +++ b/ui/views/widget/widget_delegate.cc @@ -58,6 +58,10 @@ bool WidgetDelegate::CanActivate() const { return can_activate_; } +bool WidgetDelegate::NWCanClose(bool user_force) const { + return true; +} + ui::ModalType WidgetDelegate::GetModalType() const { return ui::MODAL_TYPE_NONE; } @@ -94,6 +98,10 @@ bool WidgetDelegate::ShouldHandleSystemCommands() const { return widget->non_client_view() != NULL; } +bool WidgetDelegate::ShouldHandleOnSize() const { + return false; +} + gfx::ImageSkia WidgetDelegate::GetWindowAppIcon() { // Use the window icon as app icon by default. return GetWindowIcon(); @@ -112,6 +120,14 @@ bool WidgetDelegate::ExecuteWindowsCommand(int command_id) { return false; } +bool WidgetDelegate::ExecuteAppCommand(int command_id) { + return ExecuteWindowsCommand(command_id); +} + +bool WidgetDelegate::HandleSize(unsigned int param, const gfx::Size& size) { + return false; +} + std::string WidgetDelegate::GetWindowName() const { return std::string(); } diff --git a/ui/views/widget/widget_delegate.h b/ui/views/widget/widget_delegate.h index 8a344c5562371..68ffd7845cb95 100644 --- a/ui/views/widget/widget_delegate.h +++ b/ui/views/widget/widget_delegate.h @@ -64,6 +64,7 @@ class VIEWS_EXPORT WidgetDelegate { // Returns true if the window can be activated. virtual bool CanActivate() const; + virtual bool NWCanClose(bool user_force = false) const; // Returns the modal type that applies to the widget. Default is // ui::MODAL_TYPE_NONE (not modal). @@ -87,6 +88,8 @@ class VIEWS_EXPORT WidgetDelegate { // close, minimize, maximize. virtual bool ShouldHandleSystemCommands() const; + virtual bool ShouldHandleOnSize() const; + // Returns the app icon for the window. On Windows, this is the ICON_BIG used // in Alt-Tab list and Win7's taskbar. virtual gfx::ImageSkia GetWindowAppIcon(); @@ -101,6 +104,10 @@ class VIEWS_EXPORT WidgetDelegate { // was handled, false if it was not. virtual bool ExecuteWindowsCommand(int command_id); + virtual bool ExecuteAppCommand(int command_id); + + virtual bool HandleSize(unsigned int param, const gfx::Size& size); + // Returns the window's name identifier. Used to identify this window for // state restoration. virtual std::string GetWindowName() const; diff --git a/ui/views/widget/widget_hwnd_utils.cc b/ui/views/widget/widget_hwnd_utils.cc index b843416dac5fe..f81a22d49016d 100644 --- a/ui/views/widget/widget_hwnd_utils.cc +++ b/ui/views/widget/widget_hwnd_utils.cc @@ -17,6 +17,10 @@ #include "ui/base/win/shell.h" #endif +namespace content { + extern bool g_support_transparency; +} + namespace views { namespace { @@ -112,8 +116,15 @@ void CalculateWindowStylesFromInitParams( native_widget_delegate->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; // See layered window comment above. - if (*ex_style & WS_EX_COMPOSITED) - *style &= ~(WS_THICKFRAME | WS_CAPTION); + if (content::g_support_transparency) { + if (*ex_style & WS_EX_COMPOSITED && params.remove_standard_frame) + *style &= ~(WS_CAPTION); + } + else { + if (*ex_style & WS_EX_COMPOSITED) + *style &= ~(WS_THICKFRAME | WS_CAPTION); + } + break; } case Widget::InitParams::TYPE_CONTROL: diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 3d77ea47a7933..b50725e8f8a87 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc @@ -46,6 +46,11 @@ #include "ui/views/win/scoped_fullscreen_visibility.h" #include "ui/views/win/windows_session_change_observer.h" +namespace content { + extern bool g_support_transparency; + extern bool g_force_cpu_draw; +} + namespace views { namespace { @@ -149,10 +154,13 @@ LRESULT CALLBACK MoveLoopMouseWatcher::KeyHook(int n_code, WPARAM w_param, LPARAM l_param) { if (n_code == HC_ACTION && w_param == VK_ESCAPE) { - int value = TRUE; - DwmSetWindowAttribute(instance_->host_->hwnd(), - DWMWA_TRANSITIONS_FORCEDISABLED, &value, - sizeof(value)); + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + int value = TRUE; + DwmSetWindowAttribute(instance_->host_->hwnd(), + DWMWA_TRANSITIONS_FORCEDISABLED, + &value, + sizeof(value)); + } if (instance_->hide_on_escape_) instance_->host_->Hide(); } @@ -308,6 +316,7 @@ base::LazyInstance<HWNDMessageHandler::FullscreenWindowMonitorMap> // HWNDMessageHandler, public: long HWNDMessageHandler::last_touch_message_time_ = 0; +#define TRANSPARENCY(original, addition) content::g_support_transparency ? original addition : original HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) : msg_handled_(FALSE), @@ -756,9 +765,11 @@ bool HWNDMessageHandler::HasCapture() const { } void HWNDMessageHandler::SetVisibilityChangedAnimationsEnabled(bool enabled) { - int dwm_value = enabled ? FALSE : TRUE; - DwmSetWindowAttribute(hwnd(), DWMWA_TRANSITIONS_FORCEDISABLED, &dwm_value, - sizeof(dwm_value)); + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + int dwm_value = enabled ? FALSE : TRUE; + DwmSetWindowAttribute( + hwnd(), DWMWA_TRANSITIONS_FORCEDISABLED, &dwm_value, sizeof(dwm_value)); + } } bool HWNDMessageHandler::SetTitle(const base::string16& title) { @@ -787,24 +798,35 @@ void HWNDMessageHandler::SetCursor(HCURSOR cursor) { } void HWNDMessageHandler::FrameTypeChanged() { - if (!custom_window_region_.is_valid() && - delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN) - dwm_transition_desired_ = true; - if (!dwm_transition_desired_ || !IsFullscreen()) - PerformDwmTransition(); + if (base::win::GetVersion() < base::win::VERSION_VISTA) { + // Don't redraw the window here, because we invalidate the window later. + ResetWindowRegion(true, false); + // The non-client view needs to update too. + delegate_->HandleFrameChanged(); + InvalidateRect(hwnd(), NULL, FALSE); + } else { + if (!custom_window_region_.is_valid() && + delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN) + dwm_transition_desired_ = true; + if (!dwm_transition_desired_ || !IsFullscreen()) + PerformDwmTransition(); + } } void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) { if (!window_icon.isNull()) { base::win::ScopedHICON previous_icon = std::move(window_icon_); - window_icon_ = IconUtil::CreateHICONFromSkBitmap(*window_icon.bitmap()); + window_icon_ = + IconUtil::CreateHICONFromSkBitmapSizedTo(*window_icon.bitmap(), + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); SendMessage(hwnd(), WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(window_icon_.get())); } if (!app_icon.isNull()) { base::win::ScopedHICON previous_icon = std::move(app_icon_); - app_icon_ = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap()); + app_icon_ = IconUtil::CreateHICONFromSkBitmapSizedTo(*app_icon.bitmap(), + GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); SendMessage(hwnd(), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(app_icon_.get())); } @@ -845,7 +867,8 @@ void HWNDMessageHandler::SizeConstraintsChanged() { if (!delegate_->CanMaximize()) style &= ~WS_MAXIMIZEBOX; } else { - style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX); + if (!content::g_support_transparency) + style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX); } if (delegate_->CanMinimize()) { style |= WS_MINIMIZEBOX; @@ -1156,7 +1179,7 @@ void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { !custom_window_region_.is_valid() && (delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN || !delegate_->HasNonClientView())) { - if (force) + if (force || content::g_force_cpu_draw) SetWindowRgn(hwnd(), NULL, redraw); return; } @@ -1172,6 +1195,10 @@ void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { if (custom_window_region_.is_valid()) { new_region.reset(CreateRectRgn(0, 0, 0, 0)); CombineRgn(new_region.get(), custom_window_region_.get(), NULL, RGN_COPY); + } else if (content::g_support_transparency && window_ex_style() & WS_EX_COMPOSITED) { + RECT work_rect = window_rect; + OffsetRect(&work_rect, -window_rect.left, -window_rect.top); + new_region.reset(CreateRectRgnIndirect(&work_rect)); } else if (IsMaximized()) { HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST); MONITORINFO mi; @@ -1199,6 +1226,9 @@ void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { } void HWNDMessageHandler::UpdateDwmNcRenderingPolicy() { + if (base::win::GetVersion() < base::win::VERSION_VISTA) + return; + if (IsFullscreen()) return; @@ -1317,10 +1347,12 @@ void HWNDMessageHandler::OnCommand(UINT notification_code, LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { if (window_ex_style() & WS_EX_COMPOSITED) { - // This is part of the magic to emulate layered windows with Aura - // see the explanation elsewere when we set WS_EX_COMPOSITED style. - MARGINS margins = {-1, -1, -1, -1}; - DwmExtendFrameIntoClientArea(hwnd(), &margins); + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + // This is part of the magic to emulate layered windows with Aura + // see the explanation elsewere when we set WS_EX_COMPOSITED style. + MARGINS margins = {-1,-1,-1,-1}; + DwmExtendFrameIntoClientArea(hwnd(), &margins); + } } fullscreen_handler_->set_hwnd(hwnd()); @@ -1332,7 +1364,7 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0); - if (!delegate_->HasFrame()) { + if (TRANSPARENCY(!delegate_->HasFrame(), && !(window_ex_style() & WS_EX_COMPOSITED))) { SetWindowLong(hwnd(), GWL_STYLE, GetWindowLong(hwnd(), GWL_STYLE) & ~WS_CAPTION); SendFrameChanged(); @@ -1341,7 +1373,8 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { // Get access to a modifiable copy of the system menu. GetSystemMenu(hwnd(), false); - if (ui::AreTouchEventsEnabled()) + if (base::win::GetVersion() >= base::win::VERSION_WIN7 && + ui::AreTouchEventsEnabled()) RegisterTouchWindow(hwnd(), TWF_WANTPALM); // We need to allow the delegate to size its contents since the window may not @@ -1450,15 +1483,17 @@ void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { if (delegate_->WidgetSizeIsClientSize()) { RECT client_rect, window_rect; GetClientRect(hwnd(), &client_rect); - GetWindowRect(hwnd(), &window_rect); - CR_DEFLATE_RECT(&window_rect, &client_rect); - min_window_size.Enlarge(window_rect.right - window_rect.left, - window_rect.bottom - window_rect.top); - // Either axis may be zero, so enlarge them independently. - if (max_window_size.width()) - max_window_size.Enlarge(window_rect.right - window_rect.left, 0); - if (max_window_size.height()) - max_window_size.Enlarge(0, window_rect.bottom - window_rect.top); + if (client_rect.right > client_rect.left) { + GetWindowRect(hwnd(), &window_rect); + CR_DEFLATE_RECT(&window_rect, &client_rect); + min_window_size.Enlarge(window_rect.right - window_rect.left, + window_rect.bottom - window_rect.top); + // Either axis may be zero, so enlarge them independently. + if (max_window_size.width()) + max_window_size.Enlarge(window_rect.right - window_rect.left, 0); + if (max_window_size.height()) + max_window_size.Enlarge(0, window_rect.bottom - window_rect.top); + } } minmax_info->ptMinTrackSize.x = min_window_size.width(); minmax_info->ptMinTrackSize.y = min_window_size.height(); @@ -1670,7 +1705,8 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message, if (IsVisible()) delegate_->SchedulePaint(); - if (delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) { + if (delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN && + base::win::GetVersion() > base::win::VERSION_VISTA) { SetMsgHandled(TRUE); return TRUE; } @@ -1696,10 +1732,11 @@ LRESULT HWNDMessageHandler::OnNCCalcSize(BOOL mode, LPARAM l_param) { return 0; } } - + const LONG noTitleBar = (window_ex_style() & WS_EX_COMPOSITED) && !delegate_->HasFrame(); gfx::Insets insets; bool got_insets = GetClientAreaInsets(&insets); - if (!got_insets && !IsFullscreen() && !(mode && !delegate_->HasFrame())) { + if (TRANSPARENCY(!got_insets && !IsFullscreen() && + !(mode && !delegate_->HasFrame()), && !noTitleBar)) { SetMsgHandled(FALSE); return 0; } @@ -2118,6 +2155,17 @@ void HWNDMessageHandler::OnSize(UINT param, const gfx::Size& size) { base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&AddScrollStylesToWindow, hwnd())); } + if (delegate_->ShouldHandleOnSize()) + delegate_->HandleSize(param, size); +} + +void HWNDMessageHandler::OnStyleChanging(int nStyleType, LPSTYLESTRUCT lpStyleStruct) { + if (!content::g_support_transparency) + return; + if (nStyleType == GWL_EXSTYLE) + set_window_ex_style(lpStyleStruct->styleNew); + else if (nStyleType == GWL_STYLE) + set_window_style(lpStyleStruct->styleNew); } void HWNDMessageHandler::OnSysCommand(UINT notification_code, @@ -2575,7 +2623,7 @@ void HWNDMessageHandler::PerformDwmTransition() { // The non-client view needs to update too. delegate_->HandleFrameChanged(); - if (IsVisible() && delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN) { + if (IsVisible() && delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN && !content::g_force_cpu_draw) { // For some reason, we need to hide the window after we change from a custom // frame to a native frame. If we don't, the client area will be filled // with black. This seems to be related to an interaction between DWM and diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h index f011864177c07..4af23e7ae8702 100644 --- a/ui/views/win/hwnd_message_handler.h +++ b/ui/views/win/hwnd_message_handler.h @@ -401,6 +401,7 @@ class VIEWS_EXPORT HWNDMessageHandler : CR_MSG_WM_SETTEXT(OnSetText) CR_MSG_WM_SETTINGCHANGE(OnSettingChange) CR_MSG_WM_SIZE(OnSize) + CR_MSG_WM_STYLECHANGING(OnStyleChanging) CR_MSG_WM_SYSCOMMAND(OnSysCommand) CR_MSG_WM_THEMECHANGED(OnThemeChanged) CR_MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged) @@ -456,6 +457,7 @@ class VIEWS_EXPORT HWNDMessageHandler : LRESULT OnSetText(const wchar_t* text); void OnSettingChange(UINT flags, const wchar_t* section); void OnSize(UINT param, const gfx::Size& size); + void OnStyleChanging(int nStyleType, LPSTYLESTRUCT lpStyleStruct); void OnSysCommand(UINT notification_code, const gfx::Point& point); void OnThemeChanged(); LRESULT OnTouchEvent(UINT message, WPARAM w_param, LPARAM l_param); diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h index 631f3592b8cc8..c0477ba709f90 100644 --- a/ui/views/win/hwnd_message_handler_delegate.h +++ b/ui/views/win/hwnd_message_handler_delegate.h @@ -101,6 +101,10 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate { // implementing them on non-aura windows. http://crbug.com/189112. virtual bool ShouldHandleSystemCommands() const = 0; + // on windows, maximizing sometime is sent through WM_SIZE, not + // WM_SYSCOMMAND, see node-webkit#753 + virtual bool ShouldHandleOnSize() const = 0; + // TODO(beng): Investigate migrating these methods to On* prefixes once // HWNDMessageHandler is the WindowImpl. @@ -128,6 +132,8 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate { // true if the command was handled. virtual bool HandleCommand(int command) = 0; + virtual bool HandleSize(UINT param, const gfx::Size& size) = 0; + // Called when an accelerator is invoked. virtual void HandleAccelerator(const ui::Accelerator& accelerator) = 0; diff --git a/ui/views/window/custom_frame_view.cc b/ui/views/window/custom_frame_view.cc index 720091ec6244c..badd1fd8c8247 100644 --- a/ui/views/window/custom_frame_view.cc +++ b/ui/views/window/custom_frame_view.cc @@ -6,6 +6,7 @@ #include <algorithm> #include <vector> +#include "ui/gfx/image/image_skia_operations.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -114,7 +115,10 @@ void CustomFrameView::Init(Widget* frame) { IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P); if (frame_->widget_delegate()->ShouldShowWindowIcon()) { + gfx::ImageSkia icon; window_icon_ = new ImageButton(this); + icon = frame_->widget_delegate()->GetWindowAppIcon(); + window_icon_->SetImage(CustomButton::STATE_NORMAL, &icon); AddChildView(window_icon_); } } @@ -194,8 +198,16 @@ void CustomFrameView::ResetWindowControls() { } void CustomFrameView::UpdateWindowIcon() { - if (window_icon_) + if (window_icon_) { + gfx::ImageSkia icon; + icon = frame_->widget_delegate()->GetWindowAppIcon(); + int size = IconSize(); + gfx::ImageSkia icon2 = gfx::ImageSkiaOperations::CreateResizedImage(icon, + skia::ImageOperations::RESIZE_BEST, + gfx::Size(size, size)); + window_icon_->SetImage(CustomButton::STATE_NORMAL, &icon2); window_icon_->SchedulePaint(); + } } void CustomFrameView::UpdateWindowTitle() {