diff --git a/DEPS b/DEPS index 8312b4c..b1ef680 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '205f1ac9152d85504bc964a3f81a2aa68de49501', + 'skia_revision': '14bbe1dcd58c386da8168bba496d19f066dc56fd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '81ecb4200a7bfbae78c07b6ecf6b5b8455cb0e12', + 'v8_revision': 'f45494e40d832ef27e813376bb6dc409e43a5d36', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -193,7 +193,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '525a71ab8ee3b61da48138f7e1c406989d2879fc', 'src/third_party/libjingle/source/talk': - Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'cb124eec069bd28f486bde5f95b5603e2b823219', # commit position 10196 + Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '49460575f3cf8e99012eea942d46369d249d37f0', # commit position 10255 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215 @@ -217,7 +217,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'dd1d405d54622392d726dacf0b36b454c189c1f2', # commit position 10197 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '8b3854ad414184f379b3f3ca7d1754dc506ce6f9', # commit position 10255 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/android_webview/apk/java/proguard.flags b/android_webview/apk/java/proguard.flags index 8dbce53..d8f80cc 100644 --- a/android_webview/apk/java/proguard.flags +++ b/android_webview/apk/java/proguard.flags
@@ -75,6 +75,11 @@ public void setSmartClipResultHandler(android.os.Handler); } +# AwDebug is accessed by reflection. +-keep class org.chromium.android_webview.AwDebug { + public static boolean dumpWithoutCrashing(...); +} + # Ignore notes and warnings about the support library, which uses reflection and # may reference classes no longer in the SDK. -dontnote android.support.**
diff --git a/android_webview/crash_reporter/aw_microdump_crash_reporter.cc b/android_webview/crash_reporter/aw_microdump_crash_reporter.cc index ce94174..165c4b3 100644 --- a/android_webview/crash_reporter/aw_microdump_crash_reporter.cc +++ b/android_webview/crash_reporter/aw_microdump_crash_reporter.cc
@@ -5,9 +5,11 @@ #include "android_webview/crash_reporter/aw_microdump_crash_reporter.h" #include "android_webview/common/aw_version_info_values.h" +#include "base/debug/dump_without_crashing.h" #include "base/files/file_path.h" #include "base/lazy_instance.h" #include "base/scoped_native_library.h" +#include "base/synchronization/lock.h" #include "build/build_config.h" #include "components/crash/content/app/breakpad_linux.h" #include "components/crash/content/app/crash_reporter_client.h" @@ -19,7 +21,7 @@ class AwCrashReporterClient : public ::crash_reporter::CrashReporterClient { public: - AwCrashReporterClient() {} + AwCrashReporterClient() : dump_fd_(-1) {} // crash_reporter::CrashReporterClient implementation. bool IsRunningUnattended() override { return false; } @@ -35,7 +37,19 @@ // only when NO_UNWIND_TABLES == 1). bool ShouldEnableBreakpadMicrodumps() override { return true; } + int GetAndroidMinidumpDescriptor() override { return dump_fd_; } + + bool DumpWithoutCrashingToFd(int fd) { + base::AutoLock lock(dump_lock_); + dump_fd_ = fd; + base::debug::DumpWithoutCrashing(); + dump_fd_ = -1; + return true; + } + private: + int dump_fd_; + base::Lock dump_lock_; DISALLOW_COPY_AND_ASSIGN(AwCrashReporterClient); }; @@ -120,5 +134,9 @@ breakpad::AddGpuFingerprintToMicrodumpCrashHandler(gpu_fingerprint); } +bool DumpWithoutCrashingToFd(int fd) { + return g_crash_reporter_client.Pointer()->DumpWithoutCrashingToFd(fd); +} + } // namespace crash_reporter } // namespace android_webview
diff --git a/android_webview/crash_reporter/aw_microdump_crash_reporter.h b/android_webview/crash_reporter/aw_microdump_crash_reporter.h index 5fcda99a..067363f 100644 --- a/android_webview/crash_reporter/aw_microdump_crash_reporter.h +++ b/android_webview/crash_reporter/aw_microdump_crash_reporter.h
@@ -13,7 +13,7 @@ void EnableMicrodumpCrashReporter(); void AddGpuFingerprintToMicrodumpCrashHandler( const std::string& gpu_fingerprint); - +bool DumpWithoutCrashingToFd(int fd); } // namespace crash_reporter } // namespace android_webview
diff --git a/android_webview/java/src/org/chromium/android_webview/AwDebug.java b/android_webview/java/src/org/chromium/android_webview/AwDebug.java new file mode 100644 index 0000000..72b125a --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/AwDebug.java
@@ -0,0 +1,43 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview; + +import org.chromium.base.annotations.JNINamespace; + +import java.io.File; +import java.io.IOException; + +/** + * Provides Android WebView debugging entrypoints. + * + * Methods in this class can be called from any thread, including threads created by + * the client of WebView. + */ +@JNINamespace("android_webview") +public class AwDebug { + /** + * Dump webview state (predominantly a minidump for all threads, + * but including other information) to the file descriptor fd. + * + * It is expected that this method is found by reflection, as it + * is not currently exposed by the android framework, and thus it + * needs to be protected from the unwanted attention of ProGuard. + * + * The File argument must refer to a pre-existing file, which must + * be able to be re-opened for reading and writing via its + * canonical path. The file will be truncated upon re-opening. + */ + public static boolean dumpWithoutCrashing(File dumpFile) { + String dumpPath; + try { + dumpPath = dumpFile.getCanonicalPath(); + } catch (IOException e) { + return false; + } + return nativeDumpWithoutCrashing(dumpPath); + } + + private static native boolean nativeDumpWithoutCrashing(String dumpPath); +}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java new file mode 100644 index 0000000..33bebb6d --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java
@@ -0,0 +1,33 @@ +// Copyright 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. + +package org.chromium.android_webview.test; + +import android.os.Build; +import android.test.suitebuilder.annotation.SmallTest; + +import org.chromium.android_webview.AwDebug; +import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.MinAndroidSdkLevel; + +import java.io.File; + +/** + * A test suite for AwDebug class. + */ +@MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT) +public class AwDebugTest extends AwTestBase { + @SmallTest + @Feature({"AndroidWebView", "Debug"}) + public void testDump() throws Throwable { + File f = File.createTempFile("dump", ".dmp"); + try { + assertTrue(AwDebug.dumpWithoutCrashing(f)); + assertTrue(f.canRead()); + assertTrue(f.length() != 0); + } finally { + assertTrue(f.delete()); + } + } +}
diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc index add2d2c..275e29b0 100644 --- a/android_webview/native/android_webview_jni_registrar.cc +++ b/android_webview/native/android_webview_jni_registrar.cc
@@ -11,6 +11,7 @@ #include "android_webview/native/aw_contents_client_bridge.h" #include "android_webview/native/aw_contents_io_thread_client_impl.h" #include "android_webview/native/aw_contents_statics.h" +#include "android_webview/native/aw_debug.h" #include "android_webview/native/aw_dev_tools_server.h" #include "android_webview/native/aw_form_database.h" #include "android_webview/native/aw_http_auth_handler.h" @@ -42,6 +43,7 @@ { "AwContentsClientBridge", RegisterAwContentsClientBridge }, { "AwContentsIoThreadClientImpl", RegisterAwContentsIoThreadClientImpl }, { "AwContentsStatics", RegisterAwContentsStatics }, + { "AwDebug", RegisterAwDebug }, { "AwDevToolsServer", RegisterAwDevToolsServer }, { "AwFormDatabase", RegisterAwFormDatabase }, { "AwPicture", RegisterAwPicture },
diff --git a/android_webview/native/aw_debug.cc b/android_webview/native/aw_debug.cc new file mode 100644 index 0000000..fcfb50b1 --- /dev/null +++ b/android_webview/native/aw_debug.cc
@@ -0,0 +1,42 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "android_webview/native/aw_debug.h" + +#include "android_webview/crash_reporter/aw_microdump_crash_reporter.h" +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/debug/dump_without_crashing.h" +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/threading/thread_restrictions.h" +#include "jni/AwDebug_jni.h" + +using base::android::ConvertJavaStringToUTF16; +using base::android::ConvertUTF8ToJavaString; +using base::android::ScopedJavaLocalRef; + +namespace android_webview { + +static jboolean DumpWithoutCrashing(JNIEnv* env, + const JavaParamRef<jclass>& clazz, + const JavaParamRef<jstring>& dump_path) { + // This may be called from any thread, and we might be in a state + // where it is impossible to post tasks, so we have to be prepared + // to do IO from this thread. + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::File target(base::FilePath(ConvertJavaStringToUTF8(env, dump_path)), + base::File::FLAG_OPEN_TRUNCATED | base::File::FLAG_READ | + base::File::FLAG_WRITE); + if (!target.IsValid()) + return false; + // breakpad_linux::HandleCrashDump will close this fd once it is done. + return crash_reporter::DumpWithoutCrashingToFd(target.TakePlatformFile()); +} + +bool RegisterAwDebug(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +} // namespace android_webview
diff --git a/android_webview/native/aw_debug.h b/android_webview/native/aw_debug.h new file mode 100644 index 0000000..c1eadaa --- /dev/null +++ b/android_webview/native/aw_debug.h
@@ -0,0 +1,21 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANDROID_WEBVIEW_NATIVE_AW_DEBUG_H_ +#define ANDROID_WEBVIEW_NATIVE_AW_DEBUG_H_ + +#include <jni.h> + +#include "base/android/jni_weak_ref.h" +#include "base/android/scoped_java_ref.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/web_contents_observer.h" + +namespace android_webview { + +bool RegisterAwDebug(JNIEnv* env); + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_NATIVE_AW_DEBUG_H_
diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp index 33d5401..9cdb1eb 100644 --- a/android_webview/native/webview_native.gyp +++ b/android_webview/native/webview_native.gyp
@@ -51,6 +51,8 @@ 'aw_contents_io_thread_client_impl.h', 'aw_contents_statics.cc', 'aw_contents_statics.h', + 'aw_debug.cc', + 'aw_debug.h', 'aw_dev_tools_server.cc', 'aw_dev_tools_server.h', 'aw_form_database.cc', @@ -132,6 +134,7 @@ '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', + '../java/src/org/chromium/android_webview/AwDebug.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java',
diff --git a/ash/drag_drop/drag_drop_interactive_uitest.cc b/ash/drag_drop/drag_drop_interactive_uitest.cc index a29e9ba5..c54e51d8 100644 --- a/ash/drag_drop/drag_drop_interactive_uitest.cc +++ b/ash/drag_drop/drag_drop_interactive_uitest.cc
@@ -82,7 +82,7 @@ } void QuitLoop() { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } void DragDropAcrossMultiDisplay_Step4() {
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index ab1d9a39..d4cd5c3 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -115,7 +115,7 @@ ++animation_steps_; if (IsDoneAnimating()) { done_waiting_ = true; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } }
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index 7618cd7..e87aab0 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -184,7 +184,7 @@ } void ShellDelegateImpl::Exit() { - base::MessageLoopForUI::current()->Quit(); + base::MessageLoopForUI::current()->QuitWhenIdle(); } keyboard::KeyboardUI* ShellDelegateImpl::CreateKeyboardUI() {
diff --git a/ash/test/shelf_view_test_api.cc b/ash/test/shelf_view_test_api.cc index 48d503b4..1ab9dcbe 100644 --- a/ash/test/shelf_view_test_api.cc +++ b/ash/test/shelf_view_test_api.cc
@@ -24,7 +24,7 @@ // views::BoundsAnimatorObserver overrides: void OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) override {} void OnBoundsAnimatorDone(views::BoundsAnimator* animator) override { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } private:
diff --git a/ash/test/test_system_tray_delegate.cc b/ash/test/test_system_tray_delegate.cc index 19daea2b..7745bc95 100644 --- a/ash/test/test_system_tray_delegate.cc +++ b/ash/test/test_system_tray_delegate.cc
@@ -95,7 +95,7 @@ } void TestSystemTrayDelegate::SignOut() { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } } // namespace test
diff --git a/base/base_switches.cc b/base/base_switches.cc index 76827b8..b7835c0 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc
@@ -14,6 +14,11 @@ // generated internally. const char kEnableCrashReporter[] = "enable-crash-reporter"; +// Makes memory allocators keep track of their allocations and context, so a +// detailed breakdown of memory usage can be presented in chrome://tracing when +// the memory-infra category is enabled. +const char kEnableHeapProfiling[] = "enable-heap-profiling"; + // Generates full memory crash dump. const char kFullMemoryCrashReport[] = "full-memory-crash-report";
diff --git a/base/base_switches.h b/base/base_switches.h index 95f6bff..9c1eaf4 100644 --- a/base/base_switches.h +++ b/base/base_switches.h
@@ -12,11 +12,12 @@ namespace switches { extern const char kDisableBreakpad[]; +extern const char kDisableLowEndDeviceMode[]; extern const char kEnableCrashReporter[]; +extern const char kEnableHeapProfiling[]; +extern const char kEnableLowEndDeviceMode[]; extern const char kForceFieldTrials[]; extern const char kFullMemoryCrashReport[]; -extern const char kEnableLowEndDeviceMode[]; -extern const char kDisableLowEndDeviceMode[]; extern const char kNoErrorDialogs[]; extern const char kProfilerTiming[]; extern const char kProfilerTimingDisabledValue[];
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index a2fa953..fe8423a 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include "base/atomic_sequence_num.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/thread_task_runner_handle.h" @@ -110,6 +111,11 @@ tracing_process_id_(kInvalidTracingProcessId), skip_core_dumpers_auto_registration_for_testing_(false) { g_next_guid.GetNext(); // Make sure that first guid is not zero. + + heap_profiling_enabled_ = CommandLine::InitializedForCurrentProcess() + ? CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableHeapProfiling) + : false; } MemoryDumpManager::~MemoryDumpManager() { @@ -170,6 +176,9 @@ dump_providers_.erase(iter_new.first); dump_providers_.insert(mdp_info); } + + if (heap_profiling_enabled_) + mdp->OnHeapProfilingEnabled(true); } void MemoryDumpManager::RegisterDumpProvider(MemoryDumpProvider* mdp) {
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h index 0f352ed..db963111 100644 --- a/base/trace_event/memory_dump_manager.h +++ b/base/trace_event/memory_dump_manager.h
@@ -227,6 +227,9 @@ // Skips the auto-registration of the core dumpers during Initialize(). bool skip_core_dumpers_auto_registration_for_testing_; + // Whether new memory dump providers should be told to enable heap profiling. + bool heap_profiling_enabled_; + DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager); };
diff --git a/base/trace_event/memory_dump_provider.h b/base/trace_event/memory_dump_provider.h index 3b1f1362..35df620 100644 --- a/base/trace_event/memory_dump_provider.h +++ b/base/trace_event/memory_dump_provider.h
@@ -33,6 +33,10 @@ virtual bool OnMemoryDump(const MemoryDumpArgs& args, ProcessMemoryDump* pmd) = 0; + // Called by the MemoryDumpManager when an allocator should start or stop + // collecting extensive allocation data, if supported. + virtual void OnHeapProfilingEnabled(bool enabled) {} + protected: MemoryDumpProvider() {} virtual ~MemoryDumpProvider() {}
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc index df26ef5..2369439 100644 --- a/base/trace_event/process_memory_dump.cc +++ b/base/trace_event/process_memory_dump.cc
@@ -7,6 +7,10 @@ #include "base/trace_event/process_memory_totals.h" #include "base/trace_event/trace_event_argument.h" +#if defined(OS_POSIX) +#include <sys/mman.h> +#endif + namespace base { namespace trace_event { @@ -19,6 +23,49 @@ } } // namespace +#if defined(COUNT_RESIDENT_BYTES_SUPPORTED) +// static +size_t ProcessMemoryDump::CountResidentBytes(void* start_address, + size_t mapped_size) { + const size_t page_size = base::GetPageSize(); + const uintptr_t start_pointer = reinterpret_cast<uintptr_t>(start_address); + DCHECK_EQ(0u, start_pointer % page_size); + + // This function allocates a char vector of size number of pages in the given + // mapped_size. To avoid allocating a large array, the memory is split into + // chunks. Maximum size of vector allocated, will be + // kPageChunkSize / page_size. + const size_t kMaxChunkSize = 32 * 1024 * 1024; + size_t offset = 0; + size_t total_resident_size = 0; + while (offset < mapped_size) { + void* chunk_start = reinterpret_cast<void*>(start_pointer + offset); + const size_t chunk_size = std::min(mapped_size - offset, kMaxChunkSize); + const size_t page_count = (chunk_size + page_size - 1) / page_size; + size_t resident_page_count = 0; + +#if defined(OS_MACOSX) || defined(OS_IOS) + scoped_ptr<char[]> vec(new char[page_count + 1]); + int res = mincore(chunk_start, chunk_size, &vec.get()[0]); + DCHECK(!res); + for (size_t i = 0; i < page_count; i++) + resident_page_count += vec[i] & MINCORE_INCORE ? 1 : 0; + +#else // defined(OS_MACOSX) || defined(OS_IOS) + scoped_ptr<unsigned char[]> vec(new unsigned char[page_count + 1]); + int res = mincore(chunk_start, chunk_size, &vec.get()[0]); + DCHECK(!res); + for (size_t i = 0; i < page_count; i++) + resident_page_count += vec[i]; +#endif // defined(OS_MACOSX) || defined(OS_IOS) + + total_resident_size += resident_page_count * page_size; + offset += kMaxChunkSize; + } + return total_resident_size; +} +#endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) + ProcessMemoryDump::ProcessMemoryDump( const scoped_refptr<MemoryDumpSessionState>& session_state) : has_process_totals_(false),
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h index 7a16aa4..4f7d141 100644 --- a/base/trace_event/process_memory_dump.h +++ b/base/trace_event/process_memory_dump.h
@@ -18,6 +18,12 @@ #include "base/trace_event/process_memory_maps.h" #include "base/trace_event/process_memory_totals.h" +// Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the +// resident memory. +#if defined(OS_POSIX) && !defined(OS_NACL) +#define COUNT_RESIDENT_BYTES_SUPPORTED +#endif + namespace base { namespace trace_event { @@ -41,6 +47,14 @@ using AllocatorDumpsMap = SmallMap<hash_map<std::string, MemoryAllocatorDump*>>; +#if defined(COUNT_RESIDENT_BYTES_SUPPORTED) + // Returns the total bytes resident for a virtual address range, with given + // |start_address| and |mapped_size|. |mapped_size| is specified in bytes. The + // value returned is valid only if the given range is currently mmapped by the + // process. The |start_address| must be page-aligned. + static size_t CountResidentBytes(void* start_address, size_t mapped_size); +#endif + ProcessMemoryDump(const scoped_refptr<MemoryDumpSessionState>& session_state); ~ProcessMemoryDump();
diff --git a/base/trace_event/process_memory_dump_unittest.cc b/base/trace_event/process_memory_dump_unittest.cc index 1e1fbc6..132bb475 100644 --- a/base/trace_event/process_memory_dump_unittest.cc +++ b/base/trace_event/process_memory_dump_unittest.cc
@@ -4,7 +4,8 @@ #include "base/trace_event/process_memory_dump.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/aligned_memory.h" +#include "base/process/process_metrics.h" #include "base/trace_event/memory_allocator_dump_guid.h" #include "base/trace_event/trace_event_argument.h" #include "testing/gtest/include/gtest/gtest.h" @@ -154,5 +155,28 @@ pmd.reset(); } +#if defined(COUNT_RESIDENT_BYTES_SUPPORTED) +TEST(ProcessMemoryDumpTest, CountResidentBytes) { + const size_t page_size = base::GetPageSize(); + + // Allocate few page of dirty memory and check if it is resident. + const size_t size1 = 5 * page_size; + scoped_ptr<char, base::AlignedFreeDeleter> memory1( + static_cast<char*>(base::AlignedAlloc(size1, page_size))); + memset(memory1.get(), 0, size1); + size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1.get(), size1); + ASSERT_EQ(res1, size1); + + // Allocate a large memory segment (>32Mib). + const size_t kVeryLargeMemorySize = 34 * 1024 * 1024; + scoped_ptr<char, base::AlignedFreeDeleter> memory2( + static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size))); + memset(memory2.get(), 0, kVeryLargeMemorySize); + size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(), + kVeryLargeMemorySize); + ASSERT_EQ(res2, kVeryLargeMemorySize); +} +#endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) + } // namespace trace_event } // namespace base
diff --git a/build/android/adb_gdb b/build/android/adb_gdb index 2d670dd..823d6af1 100755 --- a/build/android/adb_gdb +++ b/build/android/adb_gdb
@@ -691,7 +691,7 @@ package is installed?" fi -# Return the timestamp of a given time, as number of seconds since epoch. +# Return the timestamp of a given file, as number of seconds since epoch. # $1: file path # Out: file timestamp get_file_timestamp () { @@ -769,6 +769,7 @@ HOST_FINGERPRINT= DEVICE_FINGERPRINT=$(adb_shell getprop ro.build.fingerprint) +[[ "$DEVICE_FINGERPRINT" ]] || panic "Failed to get the device fingerprint" log "Device build fingerprint: $DEVICE_FINGERPRINT" # If --pull-libs-dir is not specified, and this is a platform build, look @@ -796,11 +797,11 @@ # fingerprints of the device, and the cached system libraries on the host. # if [ -z "$NO_PULL_LIBS" -a -z "$PULL_LIBS" ]; then - if [ ! -f "$PULL_LIBS_DIR/build.prop" ]; then + if [ ! -f "$PULL_LIBS_DIR/build.fingerprint" ]; then log "Auto-config: --pull-libs (no cached libraries)" PULL_LIBS=true else - HOST_FINGERPRINT=$(get_build_fingerprint_from "$PULL_LIBS_DIR/build.prop") + HOST_FINGERPRINT=$(< "$PULL_LIBS_DIR/build.fingerprint") log "Host build fingerprint: $HOST_FINGERPRINT" if [ "$HOST_FINGERPRINT" == "$DEVICE_FINGERPRINT" ]; then log "Auto-config: --no-pull-libs (fingerprint match)" @@ -899,7 +900,6 @@ # we need by looking at /proc/$PID/maps instead if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then echo "Extracting system libraries into: $PULL_LIBS_DIR" - rm -f $PULL_LIBS_DIR/build.prop MAPPINGS=$(adb_shell $COMMAND_PREFIX cat /proc/$PID/maps $COMMAND_SUFFIX) if [ $? != 0 ]; then echo "ERROR: Could not list process's memory mappings." @@ -909,6 +909,8 @@ panic "Use --su-prefix if the application is not debuggable." fi fi + # Remove the fingerprint file in case pulling one of the libs fails. + rm -f "$PULL_LIBS_DIR/build.fingerprint" SYSTEM_LIBS=$(echo "$MAPPINGS" | \ awk '$6 ~ /\/system\/.*\.so$/ { print $6; }' | sort -u) for SYSLIB in /system/bin/linker $SYSTEM_LIBS; do @@ -918,9 +920,8 @@ mkdir -p "$DST_DIR" && adb pull $SYSLIB "$DST_FILE" 2>/dev/null fail_panic "Could not pull $SYSLIB from device !?" done - echo "Pulling device build.prop" - adb pull /system/build.prop $PULL_LIBS_DIR/build.prop - fail_panic "Could not pull device build.prop !?" + echo "Writing the device fingerprint" + echo "$DEVICE_FINGERPRINT" > "$PULL_LIBS_DIR/build.fingerprint" fi # Find all the sub-directories of $PULL_LIBS_DIR, up to depth 4
diff --git a/build/android/chrome_with_libs.gyp b/build/android/chrome_with_libs.gyp deleted file mode 100644 index 690be885..0000000 --- a/build/android/chrome_with_libs.gyp +++ /dev/null
@@ -1,82 +0,0 @@ -# Copyright 2013 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. - -# This file is meant to add more loadable libs into Chrome_apk. -# -# This is useful when building Chrome_apk with some loadable modules which are -# not included in Chrome_apk. -# As an example, when building Chrome_apk with -# libpeer_target_type=loadable_module, -# the libpeerconnection.so is not included in Chrome_apk. To add the missing -# lib, follow the steps below: -# - Run gyp: -# GYP_DEFINES="$GYP_DEFINES libpeer_target_type=loadable_module" CHROMIUM_GYP_FILE="build/android/chrome_with_libs.gyp" build/gyp_chromium -# - Build chrome_with_libs: -# ninja (or make) chrome_with_libs -# -# This tool also allows replacing the loadable module with a new one via the -# following steps: -# - Build Chrome_apk with the gyp define: -# GYP_DEFINES="$GYP_DEFINES libpeer_target_type=loadable_module" build/gyp_chromium -# ninja (or make) Chrome_apk -# - Replace libpeerconnection.so with a new one: -# cp the_new_one path/to/libpeerconnection.so -# - Run gyp: -# GYP_DEFINES="$GYP_DEFINES libpeer_target_type=loadable_module" CHROMIUM_GYP_FILE="build/android/chrome_with_libs.gyp" build/gyp_chromium -# - Build chrome_with_libs: -# ninja (or make) chrome_with_libs -{ - 'targets': [ - { - # An "All" target is required for a top-level gyp-file. - 'target_name': 'All', - 'type': 'none', - 'dependencies': [ - 'chrome_with_libs', - ], - }, - { - 'target_name': 'chrome_with_libs', - 'type': 'none', - 'variables': { - 'intermediate_dir': '<(PRODUCT_DIR)/prebuilt_libs/', - 'chrome_unsigned_path': '<(PRODUCT_DIR)/chrome_apk/Chrome-unsigned.apk', - 'chrome_with_libs_unsigned': '<(intermediate_dir)/Chrome-with-libs-unsigned.apk', - 'chrome_with_libs_final': '<(PRODUCT_DIR)/apks/Chrome-with-libs.apk', - }, - 'dependencies': [ - '<(DEPTH)/clank/native/framework/clank.gyp:chrome_apk' - ], - 'copies': [ - { - 'destination': '<(intermediate_dir)/lib/<(android_app_abi)', - 'files': [ - '<(PRODUCT_DIR)/libpeerconnection.so', - ], - }, - ], - 'actions': [ - { - 'action_name': 'put_libs_in_chrome', - 'variables': { - 'inputs': [ - '<(intermediate_dir)/lib/<(android_app_abi)/libpeerconnection.so', - ], - 'input_apk_path': '<(chrome_unsigned_path)', - 'output_apk_path': '<(chrome_with_libs_unsigned)', - 'libraries_top_dir%': '<(intermediate_dir)', - }, - 'includes': [ 'create_standalone_apk_action.gypi' ], - }, - { - 'action_name': 'finalize_chrome_with_libs', - 'variables': { - 'input_apk_path': '<(chrome_with_libs_unsigned)', - 'output_apk_path': '<(chrome_with_libs_final)', - }, - 'includes': [ 'finalize_apk_action.gypi'], - }, - ], - }], -}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 7e7e84e..13460ddd 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -7661,18 +7661,12 @@ <message name="IDS_CLEAR_BROWSING_DATA_SOME_STUFF_REMAINS" desc="Information that some data may remain even though the user clears their browsing history. The text in '|'s and '#'s will be turned into buttons. The translated text should contain exactly one phrase in '|'s and one in '#'s."> Saved |content settings| and #search engines# will not be cleared and may reflect your browsing habits. </message> - <message name="IDS_CLEAR_BROWSING_DATA_SOME_STUFF_REMAINS_SIMPLE" desc="Information that some data may remain even though the user clears their browsing history. The text in '|'s will be turned into a button. The translated text should contain exactly one phrase in '|'s."> - Some settings that may reflect browsing habits |will not be cleared|. + <message name="IDS_CLEAR_BROWSING_DATA_SOME_STUFF_REMAINS_SIMPLE" desc="A text shown at the bottom of the Clear Browsing Data dialog, informing the user that some data types will not be cleared."> + Some settings that may reflect browsing habits will not be cleared. </message> <message name="IDS_CLEAR_BROWSING_DATA_SYNCED_DELETION" desc="Information that data which is synced across user's devices will be deleted from all those devices."> This clears synced data from all devices. </message> - <message name="IDS_FLAGS_SIMPLE_CLEAR_BROWSING_DATA_SUPPORT_STRING_NAME" desc="Name of the flag that simplifies the support string in the Clear browsing data dialog."> - Use a simple support string in the Clear browsing data dialog. - </message> - <message name="IDS_FLAGS_SIMPLE_CLEAR_BROWSING_DATA_SUPPORT_STRING_DESCRIPTION" desc="Description of the flag that simplifies the support string in the Clear browsing data dialog."> - Instead of enumerating data types that are not deleted in the dialog, use a simple support string linking to an article with more information. - </message> <message name="IDS_FLAGS_ENABLE_CLEAR_BROWSING_DATA_COUNTERS_NAME" desc="Name of the flag that enables the data volume counters in the Clear browsing data dialog."> Enable Clear browsing data counters. </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 36990e60..de72288 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -133,6 +133,7 @@ "//components/metrics:net", "//components/metrics:profiler", "//components/metrics/proto:proto", + "//components/metrics:ui", "//components/mime_util", "//components/navigation_metrics", "//components/network_time", @@ -542,8 +543,12 @@ if (is_chromeos || is_ios) { sources -= [ + "metrics/chrome_signin_status_metrics_provider_delegate.cc", + "metrics/chrome_signin_status_metrics_provider_delegate.h", "metrics/signin_status_metrics_provider.cc", "metrics/signin_status_metrics_provider.h", + "metrics/signin_status_metrics_provider_delegate.cc", + "metrics/signin_status_metrics_provider_delegate.h", ] }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index c1f7ca8f..805876c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2019,12 +2019,6 @@ kOsAll, SINGLE_VALUE_TYPE(switches::kEnableClearBrowsingDataCounters) }, - {"simple-clear-browsing-data-support-string", - IDS_FLAGS_SIMPLE_CLEAR_BROWSING_DATA_SUPPORT_STRING_NAME, - IDS_FLAGS_SIMPLE_CLEAR_BROWSING_DATA_SUPPORT_STRING_DESCRIPTION, - kOsAll, - SINGLE_VALUE_TYPE(switches::kSimpleClearBrowsingDataSupportString) - }, #if defined(ENABLE_TASK_MANAGER) {"disable-new-task-manager", IDS_FLAGS_DISABLE_NEW_TASK_MANAGER_NAME,
diff --git a/chrome/browser/android/popular_sites.cc b/chrome/browser/android/popular_sites.cc index 6a0b1df..e32107bc 100644 --- a/chrome/browser/android/popular_sites.cc +++ b/chrome/browser/android/popular_sites.cc
@@ -123,6 +123,11 @@ .c_str())); } +GURL GetPopularSitesFallbackURL(Profile* profile) { + return GetPopularSitesURL(profile, kPopularSitesDefaultCountryCode, + kPopularSitesDefaultVersion, std::string()); +} + base::FilePath GetPopularSitesPath() { base::FilePath dir; PathService::Get(chrome::DIR_USER_DATA, &dir); @@ -186,52 +191,77 @@ const std::string& override_filename, bool force_download, const FinishedCallback& callback) - : callback_(callback), weak_ptr_factory_(this) { + : callback_(callback), + popular_sites_local_path_(GetPopularSitesPath()), + weak_ptr_factory_(this) { // Re-download the file once on every Chrome startup, but use the cached // local file afterwards. static bool first_time = true; FetchPopularSites(GetPopularSitesURL(profile, override_country, override_version, override_filename), - profile->GetRequestContext(), first_time || force_download); + profile, first_time || force_download); first_time = false; } PopularSites::PopularSites(Profile* profile, const GURL& url, const FinishedCallback& callback) - : callback_(callback), weak_ptr_factory_(this) { - FetchPopularSites(url, profile->GetRequestContext(), true); + : callback_(callback), + popular_sites_local_path_(GetPopularSitesPath()), + weak_ptr_factory_(this) { + FetchPopularSites(url, profile, true); } PopularSites::~PopularSites() {} -void PopularSites::FetchPopularSites( - const GURL& url, - net::URLRequestContextGetter* request_context, - bool force_download) { - base::FilePath path = GetPopularSitesPath(); - downloader_.reset(new FileDownloader( - url, path, force_download, request_context, - base::Bind(&PopularSites::OnDownloadDone, base::Unretained(this), path))); +void PopularSites::FetchPopularSites(const GURL& url, + Profile* profile, + bool force_download) { + downloader_.reset( + new FileDownloader(url, popular_sites_local_path_, force_download, + profile->GetRequestContext(), + base::Bind(&PopularSites::OnDownloadDone, + base::Unretained(this), profile))); } -void PopularSites::OnDownloadDone(const base::FilePath& path, bool success) { +void PopularSites::FetchFallbackSites(Profile* profile) { + downloader_.reset(new FileDownloader( + GetPopularSitesFallbackURL(profile), popular_sites_local_path_, + true /* force_download */, profile->GetRequestContext(), + base::Bind(&PopularSites::OnDownloadFallbackDone, + base::Unretained(this)))); +} + +void PopularSites::OnDownloadDone(Profile* profile, bool success) { if (success) { - base::PostTaskAndReplyWithResult( - BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN).get(), - FROM_HERE, - base::Bind(&ReadAndParseJsonFile, path), - base::Bind(&PopularSites::OnJsonParsed, - weak_ptr_factory_.GetWeakPtr())); + ParseSiteList(popular_sites_local_path_); + downloader_.reset(); } else { - DLOG(WARNING) << "Download failed"; + DLOG(WARNING) << "Download country site list failed"; + FetchFallbackSites(profile); + } +} + +void PopularSites::OnDownloadFallbackDone(bool success) { + if (success) { + ParseSiteList(popular_sites_local_path_); + } else { + DLOG(WARNING) << "Download fallback site list failed"; callback_.Run(false); } - downloader_.reset(); } +void PopularSites::ParseSiteList(const base::FilePath& path) { + base::PostTaskAndReplyWithResult( + BrowserThread::GetBlockingPool() + ->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN) + .get(), + FROM_HERE, base::Bind(&ReadAndParseJsonFile, path), + base::Bind(&PopularSites::OnJsonParsed, weak_ptr_factory_.GetWeakPtr())); +} + void PopularSites::OnJsonParsed(scoped_ptr<std::vector<Site>> sites) { if (sites) sites_.swap(*sites);
diff --git a/chrome/browser/android/popular_sites.h b/chrome/browser/android/popular_sites.h index d5d8696..52ef461c 100644 --- a/chrome/browser/android/popular_sites.h +++ b/chrome/browser/android/popular_sites.h
@@ -8,16 +8,13 @@ #include <vector> #include "base/callback.h" +#include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "url/gurl.h" -namespace base { -class FilePath; -} - namespace net { class URLRequestContextGetter; } @@ -71,15 +68,25 @@ const std::vector<Site>& sites() const { return sites_; } private: + // Fetch the popular sites at the given URL. |force_download| should be true + // if any previously downloaded site list should be overwritten. void FetchPopularSites(const GURL& url, - net::URLRequestContextGetter* request_context, + Profile* profile, bool force_download); - void OnDownloadDone(const base::FilePath& path, bool success); + void OnDownloadDone(Profile* profile, bool success); + + // Fetch the default popular site list. This method will always overwrite + // a previously downloaded site list. + void FetchFallbackSites(Profile* profile); + void OnDownloadFallbackDone(bool success); + + void ParseSiteList(const base::FilePath& path); void OnJsonParsed(scoped_ptr<std::vector<Site>> sites); FinishedCallback callback_; scoped_ptr<FileDownloader> downloader_; std::vector<Site> sites_; + base::FilePath popular_sites_local_path_; base::WeakPtrFactory<PopularSites> weak_ptr_factory_;
diff --git a/chrome/browser/apps/app_browsertest.cc b/chrome/browser/apps/app_browsertest.cc index c62cf7b..db3344de 100644 --- a/chrome/browser/apps/app_browsertest.cc +++ b/chrome/browser/apps/app_browsertest.cc
@@ -41,8 +41,8 @@ #include "extensions/browser/app_window/native_app_window.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_prefs.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/browser/extension_registry_observer.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/notification_types.h" #include "extensions/browser/pref_names.h" #include "extensions/common/api/app_runtime.h" #include "extensions/common/constants.h" @@ -954,36 +954,33 @@ namespace { -// Utility class to ensure extension installation does or does not occur in -// certain scenarios. -class CheckExtensionInstalledObserver - : public extensions::ExtensionRegistryObserver { +// Simple observer to check for +// NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED events to ensure +// installation does or does not occur in certain scenarios. +class CheckExtensionInstalledObserver : public content::NotificationObserver { public: - explicit CheckExtensionInstalledObserver(Profile* profile) - : seen_(false), registry_(extensions::ExtensionRegistry::Get(profile)) { - registry_->AddObserver(this); - } - ~CheckExtensionInstalledObserver() override { - registry_->RemoveObserver(this); + CheckExtensionInstalledObserver() : seen_(false) { + registrar_.Add( + this, + extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, + content::NotificationService::AllSources()); } bool seen() const { return seen_; } - // ExtensionRegistryObserver: - void OnExtensionWillBeInstalled(content::BrowserContext* browser_context, - const extensions::Extension* extension, - bool is_update, - bool from_ephemeral, - const std::string& old_name) override { + // NotificationObserver: + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override { EXPECT_FALSE(seen_); seen_ = true; } private: bool seen_; - extensions::ExtensionRegistry* registry_; + content::NotificationRegistrar registrar_; }; } // namespace @@ -994,7 +991,7 @@ // the script resource in the opened app window. IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, PRE_PRE_ComponentAppBackgroundPage) { - CheckExtensionInstalledObserver should_install(browser()->profile()); + CheckExtensionInstalledObserver should_install; // Ensure that we wait until the background page is run (to register the // OnLaunched listener) before trying to open the application. This is similar @@ -1028,7 +1025,7 @@ // in a different observer (which would timeout if not the app was not // previously installed properly) and then check this observer to make sure it // never saw the NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED event. - CheckExtensionInstalledObserver should_not_install(browser()->profile()); + CheckExtensionInstalledObserver should_not_install; const Extension* extension = LoadExtensionAsComponent( test_data_dir_.AppendASCII("platform_apps").AppendASCII("component")); ASSERT_TRUE(extension); @@ -1059,7 +1056,7 @@ // Component App Test 3 of 3: simulate a component extension upgrade that // re-adds the OnLaunched event, and allows the app to be launched. IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ComponentAppBackgroundPage) { - CheckExtensionInstalledObserver should_install(browser()->profile()); + CheckExtensionInstalledObserver should_install; // Since we are forcing an upgrade, we need to wait for the load again. content::WindowedNotificationObserver app_loaded_observer( content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc index d437f32..d93ec84 100644 --- a/chrome/browser/background/background_contents_service.cc +++ b/chrome/browser/background/background_contents_service.cc
@@ -58,6 +58,8 @@ #if defined(ENABLE_NOTIFICATIONS) #include "ui/message_center/message_center.h" +#include "ui/message_center/notification_types.h" +#include "ui/message_center/notifier_settings.h" #endif using content::SiteInstance; @@ -69,6 +71,7 @@ namespace { const char kNotificationPrefix[] = "app.background.crashed."; +const char kNotifierId[] = "app.background.crashed"; bool g_disable_close_balloon_for_testing = false; void CloseBalloon(const std::string& balloon_id, ProfileID profile_id) { @@ -170,12 +173,17 @@ // Origin URL must be different from the crashed extension to avoid the // conflict. NotificationSystemObserver will cancel all notifications from // the same origin when NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED. - Notification notification(GURL("chrome://extension-crash"), + Notification notification(message_center::NOTIFICATION_TYPE_SIMPLE, base::string16(), message, notification_icon, + message_center::NotifierId( + message_center::NotifierId::SYSTEM_COMPONENT, + kNotifierId), base::string16(), + GURL("chrome://extension-crash"), delegate->id(), + message_center::RichNotificationData(), delegate.get()); g_browser_process->notification_ui_manager()->Add(notification, profile);
diff --git a/chrome/browser/chromeos/power/peripheral_battery_observer.cc b/chrome/browser/chromeos/power/peripheral_battery_observer.cc index d21891a..6f2e927b 100644 --- a/chrome/browser/chromeos/power/peripheral_battery_observer.cc +++ b/chrome/browser/chromeos/power/peripheral_battery_observer.cc
@@ -40,6 +40,7 @@ const int kNotificationIntervalSec = 60; const char kNotificationOriginUrl[] = "chrome://peripheral-battery"; +const char kNotifierId[] = "power.peripheral-battery"; // HID Bluetooth device's battery sysfs entry path looks like // "/sys/class/power_supply/hid-AA:BB:CC:DD:EE:FF-battery". @@ -212,7 +213,8 @@ message_center::NOTIFICATION_TYPE_SIMPLE, base::UTF8ToUTF16(battery.name), string_text, ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_NOTIFICATION_PERIPHERAL_BATTERY_LOW), - message_center::NotifierId(GURL(kNotificationOriginUrl)), + message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, + kNotifierId), base::string16(), GURL(kNotificationOriginUrl), address, message_center::RichNotificationData(), new PeripheralBatteryNotificationDelegate(address));
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc index ec0d6b9..c06a4b8 100644 --- a/chrome/browser/extensions/api/debugger/debugger_api.cc +++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -29,8 +29,7 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" @@ -177,8 +176,7 @@ // is dismissed or the object itself is destroyed. // It listens to all tabs in all browsers and adds/removes confirm infobar // to each of the tabs. -class GlobalConfirmInfoBar : public chrome::BrowserListObserver, - public TabStripModelObserver, +class GlobalConfirmInfoBar : public TabStripModelObserver, public infobars::InfoBarManager::Observer { public: GlobalConfirmInfoBar(const base::Closure& dismissed_callback, @@ -188,10 +186,6 @@ private: using InfoBarMap = std::map<InfoBarService*, infobars::InfoBar*>; - // chrome::BrowserListObserver: - void OnBrowserAdded(Browser* browser) override; - void OnBrowserRemoved(Browser* browser) override; - // TabStripModelObserver: void TabInsertedAt(content::WebContents* web_contents, int index, @@ -206,6 +200,7 @@ base::Closure dismissed_callback_; std::string client_name_; InfoBarMap infobars_; + BrowserTabStripTracker browser_tab_strip_tracker_; DISALLOW_COPY_AND_ASSIGN(GlobalConfirmInfoBar); }; @@ -213,10 +208,11 @@ GlobalConfirmInfoBar::GlobalConfirmInfoBar( const base::Closure& dismissed_callback, const std::string& client_name) - : dismissed_callback_(dismissed_callback), client_name_(client_name) { - BrowserList::AddObserver(this); - for (Browser* browser : *BrowserList::GetInstance(chrome::GetActiveDesktop())) - OnBrowserAdded(browser); + : dismissed_callback_(dismissed_callback), + client_name_(client_name), + browser_tab_strip_tracker_(this, nullptr, nullptr) { + browser_tab_strip_tracker_.Init( + BrowserTabStripTracker::InitWith::BROWSERS_IN_ACTIVE_DESKTOP); } GlobalConfirmInfoBar::~GlobalConfirmInfoBar() { @@ -224,22 +220,6 @@ InfoBarMap::iterator it = infobars_.begin(); it->first->RemoveInfoBar(it->second); } - - for (Browser* browser : *BrowserList::GetInstance(chrome::GetActiveDesktop())) - OnBrowserRemoved(browser); - BrowserList::RemoveObserver(this); -} - -void GlobalConfirmInfoBar::OnBrowserAdded(Browser* browser) { - TabStripModel* tab_strip_model = browser->tab_strip_model(); - tab_strip_model->AddObserver(this); - - for (int index = 0; index < tab_strip_model->count(); ++index) - TabInsertedAt(tab_strip_model->GetWebContentsAt(index), index, false); -} - -void GlobalConfirmInfoBar::OnBrowserRemoved(Browser* browser) { - browser->tab_strip_model()->RemoveObserver(this); } void GlobalConfirmInfoBar::TabInsertedAt(content::WebContents* web_contents,
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc index 74a12c9..504acf6 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -118,47 +118,21 @@ } TabsEventRouter::TabsEventRouter(Profile* profile) - : profile_(profile), favicon_scoped_observer_(this) { + : profile_(profile), + favicon_scoped_observer_(this), + browser_tab_strip_tracker_(this, this, this) { DCHECK(!profile->IsOffTheRecord()); - BrowserList::AddObserver(this); - - // Init() can happen after the browser is running, so catch up with any - // windows that already exist. - for (chrome::BrowserIterator it; !it.done(); it.Next()) { - RegisterForBrowserNotifications(*it); - - // Also catch up our internal bookkeeping of tab entries. - Browser* browser = *it; - if (ExtensionTabUtil::BrowserSupportsTabs(browser)) { - for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { - WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(i); - int tab_id = ExtensionTabUtil::GetTabId(contents); - tab_entries_[tab_id] = make_linked_ptr(new TabEntry(contents)); - } - } - } + browser_tab_strip_tracker_.Init( + BrowserTabStripTracker::InitWith::ALL_BROWERS); } TabsEventRouter::~TabsEventRouter() { - BrowserList::RemoveObserver(this); } -void TabsEventRouter::OnBrowserAdded(Browser* browser) { - RegisterForBrowserNotifications(browser); -} - -void TabsEventRouter::RegisterForBrowserNotifications(Browser* browser) { - if (!profile_->IsSameProfile(browser->profile()) || - !ExtensionTabUtil::BrowserSupportsTabs(browser)) - return; - // Start listening to TabStripModel events for this browser. - TabStripModel* tab_strip = browser->tab_strip_model(); - tab_strip->AddObserver(this); - - for (int i = 0; i < tab_strip->count(); ++i) { - RegisterForTabNotifications(tab_strip->GetWebContentsAt(i)); - } +bool TabsEventRouter::ShouldTrackBrowser(Browser* browser) { + return profile_->IsSameProfile(browser->profile()) && + ExtensionTabUtil::BrowserSupportsTabs(browser); } void TabsEventRouter::RegisterForTabNotifications(WebContents* contents) { @@ -190,14 +164,6 @@ ZoomController::FromWebContents(contents)->RemoveObserver(this); } -void TabsEventRouter::OnBrowserRemoved(Browser* browser) { - if (!profile_->IsSameProfile(browser->profile())) - return; - - // Stop listening to TabStripModel events for this browser. - browser->tab_strip_model()->RemoveObserver(this); -} - void TabsEventRouter::OnBrowserSetLastActive(Browser* browser) { TabsWindowsAPI* tabs_window_api = TabsWindowsAPI::Get(profile_); if (tabs_window_api) { @@ -240,12 +206,16 @@ void TabsEventRouter::TabInsertedAt(WebContents* contents, int index, bool active) { - // If tab is new, send created event. int tab_id = ExtensionTabUtil::GetTabId(contents); if (GetTabEntry(contents).get() == NULL) { tab_entries_[tab_id] = make_linked_ptr(new TabEntry(contents)); - TabCreatedAt(contents, index, active); + // We've never seen this tab, send create event as long as we're not in the + // constructor. + if (browser_tab_strip_tracker_.is_processing_initial_browsers()) + RegisterForTabNotifications(contents); + else + TabCreatedAt(contents, index, active); return; }
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.h b/chrome/browser/extensions/api/tabs/tabs_event_router.h index 1c6a9eb..d8af725 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.h +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.h
@@ -14,6 +14,8 @@ #include "base/scoped_observer.h" #include "chrome/browser/extensions/api/tabs/tabs_api.h" #include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/ui/browser_tab_strip_tracker.h" +#include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "components/favicon/core/favicon_driver_observer.h" #include "components/ui/zoom/zoom_observer.h" @@ -35,6 +37,7 @@ // TabsEventRouter will only route events from windows/tabs within a profile to // extension processes in the same profile. class TabsEventRouter : public TabStripModelObserver, + public BrowserTabStripTrackerDelegate, public chrome::BrowserListObserver, public content::NotificationObserver, public favicon::FaviconDriverObserver, @@ -43,12 +46,13 @@ explicit TabsEventRouter(Profile* profile); ~TabsEventRouter() override; - // chrome::BrowserListObserver - void OnBrowserAdded(Browser* browser) override; - void OnBrowserRemoved(Browser* browser) override; + // BrowserTabStripTrackerDelegate: + bool ShouldTrackBrowser(Browser* browser) override; + + // chrome::BrowserListObserver: void OnBrowserSetLastActive(Browser* browser) override; - // TabStripModelObserver + // TabStripModelObserver: void TabInsertedAt(content::WebContents* contents, int index, bool active) override; @@ -75,16 +79,16 @@ void TabPinnedStateChanged(content::WebContents* contents, int index) override; - // content::NotificationObserver. + // content::NotificationObserver: void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) override; - // ZoomObserver. + // ZoomObserver: void OnZoomChanged( const ui_zoom::ZoomController::ZoomChangedEventData& data) override; - // favicon::FaviconDriverObserver. + // favicon::FaviconDriverObserver: void OnFaviconAvailable(const gfx::Image& image) override; void OnFaviconUpdated(favicon::FaviconDriver* favicon_driver, bool icon_url_changed) override; @@ -124,10 +128,6 @@ scoped_ptr<base::DictionaryValue> changed_properties); // Register ourselves to receive the various notifications we are interested - // in for a browser. - void RegisterForBrowserNotifications(Browser* browser); - - // Register ourselves to receive the various notifications we are interested // in for a tab. void RegisterForTabNotifications(content::WebContents* contents); @@ -197,6 +197,8 @@ ScopedObserver<favicon::FaviconDriver, TabsEventRouter> favicon_scoped_observer_; + BrowserTabStripTracker browser_tab_strip_tracker_; + DISALLOW_COPY_AND_ASSIGN(TabsEventRouter); };
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc index 2e8522f..6597f0ef 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -74,7 +74,7 @@ WebNavigationEventRouter::PendingWebContents::~PendingWebContents() {} WebNavigationEventRouter::WebNavigationEventRouter(Profile* profile) - : profile_(profile) { + : profile_(profile), browser_tab_strip_tracker_(this, this, nullptr) { CHECK(registrar_.IsEmpty()); registrar_.Add(this, chrome::NOTIFICATION_RETARGETING, @@ -86,27 +86,15 @@ content::NOTIFICATION_WEB_CONTENTS_DESTROYED, content::NotificationService::AllSources()); - BrowserList::AddObserver(this); - for (chrome::BrowserIterator it; !it.done(); it.Next()) - OnBrowserAdded(*it); + browser_tab_strip_tracker_.Init( + BrowserTabStripTracker::InitWith::ALL_BROWERS); } WebNavigationEventRouter::~WebNavigationEventRouter() { - for (chrome::BrowserIterator it; !it.done(); it.Next()) - OnBrowserRemoved(*it); - BrowserList::RemoveObserver(this); } -void WebNavigationEventRouter::OnBrowserAdded(Browser* browser) { - if (!profile_->IsSameProfile(browser->profile())) - return; - browser->tab_strip_model()->AddObserver(this); -} - -void WebNavigationEventRouter::OnBrowserRemoved(Browser* browser) { - if (!profile_->IsSameProfile(browser->profile())) - return; - browser->tab_strip_model()->RemoveObserver(this); +bool WebNavigationEventRouter::ShouldTrackBrowser(Browser* browser) { + return profile_->IsSameProfile(browser->profile()); } void WebNavigationEventRouter::TabReplacedAt(
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h index 74c43aa0..c2b62825 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
@@ -15,7 +15,8 @@ #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h" #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/ui/browser_tab_strip_tracker.h" +#include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -112,7 +113,7 @@ // Observes navigation notifications and routes them as events to the extension // system. class WebNavigationEventRouter : public TabStripModelObserver, - public chrome::BrowserListObserver, + public BrowserTabStripTrackerDelegate, public content::NotificationObserver { public: explicit WebNavigationEventRouter(Profile* profile); @@ -134,16 +135,15 @@ GURL target_url; }; + // BrowserTabStripTrackerDelegate implementation. + bool ShouldTrackBrowser(Browser* browser) override; + // TabStripModelObserver implementation. void TabReplacedAt(TabStripModel* tab_strip_model, content::WebContents* old_contents, content::WebContents* new_contents, int index) override; - // chrome::BrowserListObserver implementation. - void OnBrowserAdded(Browser* browser) override; - void OnBrowserRemoved(Browser* browser) override; - // content::NotificationObserver implementation. void Observe(int type, const content::NotificationSource& source, @@ -172,6 +172,8 @@ // The profile that owns us via ExtensionService. Profile* profile_; + BrowserTabStripTracker browser_tab_strip_tracker_; + DISALLOW_COPY_AND_ASSIGN(WebNavigationEventRouter); };
diff --git a/chrome/browser/local_discovery/privet_notifications.cc b/chrome/browser/local_discovery/privet_notifications.cc index 9c529a9..ddecc24 100644 --- a/chrome/browser/local_discovery/privet_notifications.cc +++ b/chrome/browser/local_discovery/privet_notifications.cc
@@ -261,7 +261,8 @@ message_center::NOTIFICATION_TYPE_SIMPLE, title, body, ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_LOCAL_DISCOVERY_CLOUDPRINT_ICON), - message_center::NotifierId(GURL(kPrivetNotificationOriginUrl)), + message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, + kPrivetNotificationID), product_name, GURL(kPrivetNotificationOriginUrl), kPrivetNotificationID, rich_notification_data, new PrivetNotificationDelegate(profile_));
diff --git a/chrome/browser/memory/tab_manager.cc b/chrome/browser/memory/tab_manager.cc index 3527bbd..cd75f1f 100644 --- a/chrome/browser/memory/tab_manager.cc +++ b/chrome/browser/memory/tab_manager.cc
@@ -101,19 +101,19 @@ // TabManager TabManager::TabManager() - : discard_count_(0), recent_tab_discard_(false), discard_once_(false) { + : discard_count_(0), + recent_tab_discard_(false), + discard_once_(false), + browser_tab_strip_tracker_(this, nullptr, nullptr) { #if defined(OS_CHROMEOS) delegate_.reset(new TabManagerDelegate); #endif - BrowserList::AddObserver(this); + browser_tab_strip_tracker_.Init( + BrowserTabStripTracker::InitWith::ALL_BROWERS); } TabManager::~TabManager() { Stop(); - for (chrome::BrowserIterator iterator; !iterator.done(); iterator.Next()) - iterator->tab_strip_model()->RemoveObserver(this); - - BrowserList::RemoveObserver(this); } void TabManager::Start(bool discard_once) { @@ -475,14 +475,6 @@ // consider to call PurgeBrowserMemory() before CRITICAL is reached. } -void TabManager::OnBrowserAdded(Browser* browser) { - browser->tab_strip_model()->AddObserver(this); -} - -void TabManager::OnBrowserRemoved(Browser* browser) { - browser->tab_strip_model()->RemoveObserver(this); -} - bool TabManager::IsAudioTab(WebContents* contents) const { if (contents->WasRecentlyAudible()) return true;
diff --git a/chrome/browser/memory/tab_manager.h b/chrome/browser/memory/tab_manager.h index aced917..ac98970 100644 --- a/chrome/browser/memory/tab_manager.h +++ b/chrome/browser/memory/tab_manager.h
@@ -15,7 +15,7 @@ #include "base/strings/string16.h" #include "base/timer/timer.h" #include "chrome/browser/memory/tab_stats.h" -#include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" class BrowserList; @@ -44,8 +44,7 @@ // Note that the browser tests are only active for platforms that use // TabManager (CrOS only for now) and need to be adjusted accordingly if // support for new platforms is added. -class TabManager : public chrome::BrowserListObserver, - public TabStripModelObserver { +class TabManager : public TabStripModelObserver { public: TabManager(); ~TabManager() override; @@ -127,10 +126,6 @@ void OnMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); - // chrome::BrowserListObserver overrides. - void OnBrowserAdded(Browser* browser) override; - void OnBrowserRemoved(Browser* browser) override; - // TabStripModelObserver overrides. void TabChangedAt(content::WebContents* contents, int index, @@ -179,6 +174,8 @@ scoped_ptr<TabManagerDelegate> delegate_; #endif + BrowserTabStripTracker browser_tab_strip_tracker_; + DISALLOW_COPY_AND_ASSIGN(TabManager); };
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 67dec95..275d600 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -40,6 +40,7 @@ #include "components/metrics/profiler/profiler_metrics_provider.h" #include "components/metrics/profiler/tracking_synchronizer.h" #include "components/metrics/stability_metrics_helper.h" +#include "components/metrics/ui/screen_info_metrics_provider.h" #include "components/metrics/url_constants.h" #include "components/omnibox/browser/omnibox_metrics_provider.h" #include "components/variations/variations_associated_data.h" @@ -76,6 +77,7 @@ #endif #if !defined(OS_CHROMEOS) +#include "chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.h" #include "chrome/browser/metrics/signin_status_metrics_provider.h" #endif // !defined(OS_CHROMEOS) @@ -321,6 +323,9 @@ g_browser_process->local_state()))); metrics_service_->RegisterMetricsProvider( scoped_ptr<metrics::MetricsProvider>(new metrics::GPUMetricsProvider)); + metrics_service_->RegisterMetricsProvider( + scoped_ptr<metrics::MetricsProvider>( + new metrics::ScreenInfoMetricsProvider)); drive_metrics_provider_ = new metrics::DriveMetricsProvider( content::BrowserThread::GetMessageLoopProxyForThread( @@ -379,7 +384,8 @@ #if !defined(OS_CHROMEOS) metrics_service_->RegisterMetricsProvider( scoped_ptr<metrics::MetricsProvider>( - SigninStatusMetricsProvider::CreateInstance())); + SigninStatusMetricsProvider::CreateInstance( + make_scoped_ptr(new ChromeSigninStatusMetricsProviderDelegate)))); #endif // !defined(OS_CHROMEOS) // Clear stability metrics if it is the first time cellular upload logic
diff --git a/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.cc b/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.cc new file mode 100644 index 0000000..2aa770fb --- /dev/null +++ b/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.cc
@@ -0,0 +1,140 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.h" + +#include <string> +#include <vector> + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/metrics/signin_status_metrics_provider.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_info_cache.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "components/signin/core/browser/signin_manager.h" + +#if !defined(OS_ANDROID) && !defined(OS_IOS) +#include "chrome/browser/ui/browser_finder.h" +#endif + +ChromeSigninStatusMetricsProviderDelegate:: + ChromeSigninStatusMetricsProviderDelegate() {} + +ChromeSigninStatusMetricsProviderDelegate:: + ~ChromeSigninStatusMetricsProviderDelegate() { +#if !defined(OS_ANDROID) && !defined(OS_IOS) + BrowserList::RemoveObserver(this); +#endif + + SigninManagerFactory* factory = SigninManagerFactory::GetInstance(); + if (factory) + factory->RemoveObserver(this); +} + +void ChromeSigninStatusMetricsProviderDelegate::Initialize() { +#if !defined(OS_ANDROID) && !defined(OS_IOS) + // On Android, there is always only one profile in any situation, opening new + // windows (which is possible with only some Android devices) will not change + // the opened profiles signin status. + BrowserList::AddObserver(this); +#endif + + SigninManagerFactory* factory = SigninManagerFactory::GetInstance(); + if (factory) + factory->AddObserver(this); +} + +AccountsStatus +ChromeSigninStatusMetricsProviderDelegate::GetStatusOfAllAccounts() { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + std::vector<Profile*> profile_list = profile_manager->GetLoadedProfiles(); + + AccountsStatus accounts_status; + accounts_status.num_accounts = profile_list.size(); + for (Profile* profile : profile_list) { +#if !defined(OS_ANDROID) && !defined(OS_IOS) + if (chrome::GetTotalBrowserCountForProfile(profile) == 0) { + // The profile is loaded, but there's no opened browser for this profile. + continue; + } +#endif + accounts_status.num_opened_accounts++; + + SigninManager* manager = + SigninManagerFactory::GetForProfile(profile->GetOriginalProfile()); + if (manager && manager->IsAuthenticated()) + accounts_status.num_signed_in_accounts++; + } + + return accounts_status; +} + +std::vector<SigninManager*> +ChromeSigninStatusMetricsProviderDelegate::GetSigninManagersForAllAccounts() { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); + + std::vector<SigninManager*> managers; + for (Profile* profile : profiles) { + SigninManager* manager = + SigninManagerFactory::GetForProfileIfExists(profile); + if (manager) + managers.push_back(manager); + } + + return managers; +} + +void ChromeSigninStatusMetricsProviderDelegate::OnBrowserAdded( + Browser* browser) { + SigninManager* manager = + SigninManagerFactory::GetForProfile(browser->profile()); + + // Nothing will change if the opened browser is in incognito mode. + if (!manager) + return; + + const bool signed_in = manager->IsAuthenticated(); + UpdateStatusWhenBrowserAdded(signed_in); +} + +void ChromeSigninStatusMetricsProviderDelegate::SigninManagerCreated( + SigninManagerBase* manager) { + owner()->OnSigninManagerCreated(manager); +} + +void ChromeSigninStatusMetricsProviderDelegate::SigninManagerShutdown( + SigninManagerBase* manager) { + owner()->OnSigninManagerShutdown(manager); +} + +void ChromeSigninStatusMetricsProviderDelegate::UpdateStatusWhenBrowserAdded( + bool signed_in) { +#if !defined(OS_ANDROID) && !defined(OS_IOS) + SigninStatusMetricsProviderBase::SigninStatus status = + owner()->signin_status(); + + // NOTE: If |status| is MIXED_SIGNIN_STATUS, this method + // intentionally does not update it. + if ((status == SigninStatusMetricsProviderBase::ALL_PROFILES_NOT_SIGNED_IN && + signed_in) || + (status == SigninStatusMetricsProviderBase::ALL_PROFILES_SIGNED_IN && + !signed_in)) { + owner()->UpdateSigninStatus( + SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS); + } else if (status == SigninStatusMetricsProviderBase::UNKNOWN_SIGNIN_STATUS) { + // If when function ProvideGeneralMetrics() is called, Chrome is + // running in the background with no browser window opened, |signin_status_| + // will be reset to |UNKNOWN_SIGNIN_STATUS|. Then this newly added browser + // is the only opened browser/profile and its signin status represents + // the whole status. + owner()->UpdateSigninStatus( + signed_in + ? SigninStatusMetricsProviderBase::ALL_PROFILES_SIGNED_IN + : SigninStatusMetricsProviderBase::ALL_PROFILES_NOT_SIGNED_IN); + } +#endif +}
diff --git a/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.h b/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.h new file mode 100644 index 0000000..647ad0f2 --- /dev/null +++ b/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.h
@@ -0,0 +1,43 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_METRICS_CHROME_SIGNIN_STATUS_METRICS_PROVIDER_DELEGATE_H_ +#define CHROME_BROWSER_METRICS_CHROME_SIGNIN_STATUS_METRICS_PROVIDER_DELEGATE_H_ + +#include "base/gtest_prod_util.h" +#include "chrome/browser/metrics/signin_status_metrics_provider_delegate.h" +#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/ui/browser_list_observer.h" + +class ChromeSigninStatusMetricsProviderDelegate + : public SigninStatusMetricsProviderDelegate, + public chrome::BrowserListObserver, + public SigninManagerFactory::Observer { + public: + ChromeSigninStatusMetricsProviderDelegate(); + ~ChromeSigninStatusMetricsProviderDelegate() override; + + private: + FRIEND_TEST_ALL_PREFIXES(ChromeSigninStatusMetricsProviderDelegateTest, + UpdateStatusWhenBrowserAdded); + + // SigninStatusMetricsProviderDelegate: + void Initialize() override; + AccountsStatus GetStatusOfAllAccounts() override; + std::vector<SigninManager*> GetSigninManagersForAllAccounts() override; + + // chrome::BrowserListObserver: + void OnBrowserAdded(Browser* browser) override; + + // SigninManagerFactoryObserver: + void SigninManagerCreated(SigninManagerBase* manager) override; + void SigninManagerShutdown(SigninManagerBase* manager) override; + + // Updates the sign-in status right after a new browser is opened. + void UpdateStatusWhenBrowserAdded(bool signed_in); + + DISALLOW_COPY_AND_ASSIGN(ChromeSigninStatusMetricsProviderDelegate); +}; + +#endif // CHROME_BROWSER_METRICS_CHROME_SIGNIN_STATUS_METRICS_PROVIDER_DELEGATE_H_
diff --git a/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate_unittest.cc b/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate_unittest.cc new file mode 100644 index 0000000..8442f01 --- /dev/null +++ b/chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate_unittest.cc
@@ -0,0 +1,58 @@ +// Copyright 2014 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 "chrome/browser/metrics/chrome_signin_status_metrics_provider_delegate.h" + +#include "chrome/browser/metrics/signin_status_metrics_provider.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if !defined(OS_ANDROID) && !defined(OS_IOS) +TEST(ChromeSigninStatusMetricsProviderDelegateTest, + UpdateStatusWhenBrowserAdded) { + content::TestBrowserThreadBundle thread_bundle; + + scoped_ptr<ChromeSigninStatusMetricsProviderDelegate> delegate( + new ChromeSigninStatusMetricsProviderDelegate); + ChromeSigninStatusMetricsProviderDelegate* raw_delegate = delegate.get(); + scoped_ptr<SigninStatusMetricsProvider> metrics_provider( + SigninStatusMetricsProvider::CreateInstance(delegate.Pass())); + + // Initial status is all signed in and then a signed-in browser is opened. + metrics_provider->UpdateInitialSigninStatusForTesting(2, 2); + raw_delegate->UpdateStatusWhenBrowserAdded(true); + EXPECT_EQ(SigninStatusMetricsProviderBase::ALL_PROFILES_SIGNED_IN, + metrics_provider->GetSigninStatusForTesting()); + + // Initial status is all signed in and then a signed-out browser is opened. + metrics_provider->UpdateInitialSigninStatusForTesting(2, 2); + raw_delegate->UpdateStatusWhenBrowserAdded(false); + EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, + metrics_provider->GetSigninStatusForTesting()); + + // Initial status is all signed out and then a signed-in browser is opened. + metrics_provider->UpdateInitialSigninStatusForTesting(2, 0); + raw_delegate->UpdateStatusWhenBrowserAdded(true); + EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, + metrics_provider->GetSigninStatusForTesting()); + + // Initial status is all signed out and then a signed-out browser is opened. + metrics_provider->UpdateInitialSigninStatusForTesting(2, 0); + raw_delegate->UpdateStatusWhenBrowserAdded(false); + EXPECT_EQ(SigninStatusMetricsProviderBase::ALL_PROFILES_NOT_SIGNED_IN, + metrics_provider->GetSigninStatusForTesting()); + + // Initial status is mixed and then a signed-in browser is opened. + metrics_provider->UpdateInitialSigninStatusForTesting(2, 1); + raw_delegate->UpdateStatusWhenBrowserAdded(true); + EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, + metrics_provider->GetSigninStatusForTesting()); + + // Initial status is mixed and then a signed-out browser is opened. + metrics_provider->UpdateInitialSigninStatusForTesting(2, 1); + raw_delegate->UpdateStatusWhenBrowserAdded(false); + EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, + metrics_provider->GetSigninStatusForTesting()); +} +#endif
diff --git a/chrome/browser/metrics/signin_status_metrics_provider.cc b/chrome/browser/metrics/signin_status_metrics_provider.cc index 741684f6..5b78456 100644 --- a/chrome/browser/metrics/signin_status_metrics_provider.cc +++ b/chrome/browser/metrics/signin_status_metrics_provider.cc
@@ -4,26 +4,13 @@ #include "chrome/browser/metrics/signin_status_metrics_provider.h" -#include <string> -#include <vector> - #include "base/bind.h" #include "base/location.h" #include "base/metrics/histogram.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_info_cache.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" #include "components/signin/core/browser/signin_manager.h" -#if !defined(OS_ANDROID) && !defined(OS_IOS) -#include "chrome/browser/ui/browser_finder.h" -#endif - namespace { // The event of calling function ComputeCurrentSigninStatus and the errors @@ -45,32 +32,26 @@ } // namespace -SigninStatusMetricsProvider::SigninStatusMetricsProvider(bool is_test) - : scoped_observer_(this), +SigninStatusMetricsProvider::SigninStatusMetricsProvider( + scoped_ptr<SigninStatusMetricsProviderDelegate> delegate, + bool is_test) + : delegate_(delegate.Pass()), + scoped_observer_(this), is_test_(is_test), weak_ptr_factory_(this) { + DCHECK(delegate_ || is_test_); if (is_test_) return; + delegate_->SetOwner(this); + // Postpone the initialization until all threads are created. base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&SigninStatusMetricsProvider::Initialize, weak_ptr_factory_.GetWeakPtr())); } -SigninStatusMetricsProvider::~SigninStatusMetricsProvider() { - if (is_test_) - return; - // TODO(ios): should we provide an implementation of BrowserListObserver - // that works on iOS, http://crbug.com/403371 -#if !defined(OS_ANDROID) && !defined(OS_IOS) - BrowserList::RemoveObserver(this); -#endif - - SigninManagerFactory* factory = SigninManagerFactory::GetInstance(); - if (factory) - factory->RemoveObserver(this); -} +SigninStatusMetricsProvider::~SigninStatusMetricsProvider() {} void SigninStatusMetricsProvider::ProvideGeneralMetrics( metrics::ChromeUserMetricsExtension* uma_proto) { @@ -83,26 +64,12 @@ } // static -SigninStatusMetricsProvider* SigninStatusMetricsProvider::CreateInstance() { - return new SigninStatusMetricsProvider(false); +SigninStatusMetricsProvider* SigninStatusMetricsProvider::CreateInstance( + scoped_ptr<SigninStatusMetricsProviderDelegate> delegate) { + return new SigninStatusMetricsProvider(delegate.Pass(), false); } -void SigninStatusMetricsProvider::OnBrowserAdded(Browser* browser) { - if (signin_status() == MIXED_SIGNIN_STATUS) - return; - - SigninManager* manager = SigninManagerFactory::GetForProfile( - browser->profile()); - - // Nothing will change if the opened browser is in incognito mode. - if (!manager) - return; - - const bool signed_in = manager->IsAuthenticated(); - UpdateStatusWhenBrowserAdded(signed_in); -} - -void SigninStatusMetricsProvider::SigninManagerCreated( +void SigninStatusMetricsProvider::OnSigninManagerCreated( SigninManagerBase* manager) { // Whenever a new profile is created, a new SigninManagerBase will be created // for it. This ensures that all sign-in or sign-out actions of all opened @@ -113,13 +80,12 @@ // SigninManagerBase and the corresponding profile should be the only opened // profile. if (signin_status() == UNKNOWN_SIGNIN_STATUS) { - size_t signed_in_count = - manager->IsAuthenticated() ? 1 : 0; + size_t signed_in_count = manager->IsAuthenticated() ? 1 : 0; UpdateInitialSigninStatus(1, signed_in_count); } } -void SigninStatusMetricsProvider::SigninManagerShutdown( +void SigninStatusMetricsProvider::OnSigninManagerShutdown( SigninManagerBase* manager) { if (scoped_observer_.IsObserving(manager)) scoped_observer_.Remove(manager); @@ -131,11 +97,11 @@ const std::string& password) { SigninStatus recorded_signin_status = signin_status(); if (recorded_signin_status == ALL_PROFILES_NOT_SIGNED_IN) { - SetSigninStatus(MIXED_SIGNIN_STATUS); + UpdateSigninStatus(MIXED_SIGNIN_STATUS); } else if (recorded_signin_status == UNKNOWN_SIGNIN_STATUS) { // There should have at least one browser opened if the user can sign in, so // signin_status_ value should not be unknown. - SetSigninStatus(ERROR_GETTING_SIGNIN_STATUS); + UpdateSigninStatus(ERROR_GETTING_SIGNIN_STATUS); RecordComputeSigninStatusHistogram(USER_SIGNIN_WHEN_STATUS_UNKNOWN); } } @@ -144,44 +110,29 @@ const std::string& username) { SigninStatus recorded_signin_status = signin_status(); if (recorded_signin_status == ALL_PROFILES_SIGNED_IN) { - SetSigninStatus(MIXED_SIGNIN_STATUS); + UpdateSigninStatus(MIXED_SIGNIN_STATUS); } else if (recorded_signin_status == UNKNOWN_SIGNIN_STATUS) { // There should have at least one browser opened if the user can sign out, // so signin_status_ value should not be unknown. - SetSigninStatus(ERROR_GETTING_SIGNIN_STATUS); + UpdateSigninStatus(ERROR_GETTING_SIGNIN_STATUS); RecordComputeSigninStatusHistogram(USER_SIGNOUT_WHEN_STATUS_UNKNOWN); } } void SigninStatusMetricsProvider::Initialize() { - // Add observers. - // TODO(ios): should we provide an implementation of BrowserListObserver - // that works on iOS, http://crbug.com/403371 -#if !defined(OS_ANDROID) && !defined(OS_IOS) - // On Android, there is always only one profile in any situation, opening new - // windows (which is possible with only some Android devices) will not change - // the opened profiles signin status. - BrowserList::AddObserver(this); -#endif - SigninManagerFactory::GetInstance()->AddObserver(this); + delegate_->Initialize(); // Start observing all already-created SigninManagers. - ProfileManager* profile_manager = g_browser_process->profile_manager(); - std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); - for (size_t i = 0; i < profiles.size(); ++i) { - SigninManager* manager = SigninManagerFactory::GetForProfileIfExists( - profiles[i]); - if (manager) { - DCHECK(!scoped_observer_.IsObserving(manager)); - scoped_observer_.Add(manager); - } + for (SigninManager* manager : delegate_->GetSigninManagersForAllAccounts()) { + DCHECK(!scoped_observer_.IsObserving(manager)); + scoped_observer_.Add(manager); } // It is possible that when this object is created, no SigninManager is // created yet, for example, when Chrome is opened for the first time after // installation on desktop, or when Chrome on Android is loaded into memory. - if (profiles.empty()) { - SetSigninStatus(UNKNOWN_SIGNIN_STATUS); + if (delegate_->GetStatusOfAllAccounts().num_accounts == 0) { + UpdateSigninStatus(UNKNOWN_SIGNIN_STATUS); } else { ComputeCurrentSigninStatus(); } @@ -192,68 +143,39 @@ size_t signed_in_profiles_count) { // total_count is known to be bigger than 0. if (signed_in_profiles_count == 0) { - SetSigninStatus(ALL_PROFILES_NOT_SIGNED_IN); + UpdateSigninStatus(ALL_PROFILES_NOT_SIGNED_IN); } else if (total_count == signed_in_profiles_count) { - SetSigninStatus(ALL_PROFILES_SIGNED_IN); + UpdateSigninStatus(ALL_PROFILES_SIGNED_IN); } else { - SetSigninStatus(MIXED_SIGNIN_STATUS); + UpdateSigninStatus(MIXED_SIGNIN_STATUS); } } -void SigninStatusMetricsProvider::UpdateStatusWhenBrowserAdded(bool signed_in) { -#if !defined(OS_ANDROID) && !defined(OS_IOS) - SigninStatus recorded_signin_status = signin_status(); - if ((recorded_signin_status == ALL_PROFILES_NOT_SIGNED_IN && signed_in) || - (recorded_signin_status == ALL_PROFILES_SIGNED_IN && !signed_in)) { - SetSigninStatus(MIXED_SIGNIN_STATUS); - } else if (recorded_signin_status == UNKNOWN_SIGNIN_STATUS) { - // If when function ProvideGeneralMetrics() is called, Chrome is - // running in the background with no browser window opened, |signin_status_| - // will be reset to |UNKNOWN_SIGNIN_STATUS|. Then this newly added browser - // is the only opened browser/profile and its signin status represents - // the whole status. - SetSigninStatus(signed_in ? ALL_PROFILES_SIGNED_IN : - ALL_PROFILES_NOT_SIGNED_IN); - } -#endif -} - void SigninStatusMetricsProvider::ComputeCurrentSigninStatus() { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - std::vector<Profile*> profile_list = profile_manager->GetLoadedProfiles(); - - size_t opened_profiles_count = 0; - size_t signed_in_profiles_count = 0; - - for (size_t i = 0; i < profile_list.size(); ++i) { -#if !defined(OS_ANDROID) && !defined(OS_IOS) - if (chrome::GetTotalBrowserCountForProfile(profile_list[i]) == 0) { - // The profile is loaded, but there's no opened browser for this profile. - continue; - } -#endif - opened_profiles_count++; - SigninManager* manager = SigninManagerFactory::GetForProfile( - profile_list[i]->GetOriginalProfile()); - if (manager && manager->IsAuthenticated()) - signed_in_profiles_count++; - } - RecordComputeSigninStatusHistogram(ENTERED_COMPUTE_SIGNIN_STATUS); - if (profile_list.empty()) { + + AccountsStatus accounts_status = delegate_->GetStatusOfAllAccounts(); + if (accounts_status.num_accounts == 0) { // This should not happen. If it does, record it in histogram. RecordComputeSigninStatusHistogram(ERROR_NO_PROFILE_FOUND); - SetSigninStatus(ERROR_GETTING_SIGNIN_STATUS); - } else if (opened_profiles_count == 0) { + UpdateSigninStatus(ERROR_GETTING_SIGNIN_STATUS); + } else if (accounts_status.num_opened_accounts == 0) { // The code indicates that Chrome is running in the background but no // browser window is opened. RecordComputeSigninStatusHistogram(NO_BROWSER_OPENED); - SetSigninStatus(UNKNOWN_SIGNIN_STATUS); + UpdateSigninStatus(UNKNOWN_SIGNIN_STATUS); } else { - UpdateInitialSigninStatus(opened_profiles_count, signed_in_profiles_count); + UpdateInitialSigninStatus(accounts_status.num_opened_accounts, + accounts_status.num_signed_in_accounts); } } +void SigninStatusMetricsProvider::UpdateInitialSigninStatusForTesting( + size_t total_count, + size_t signed_in_profiles_count) { + UpdateInitialSigninStatus(total_count, signed_in_profiles_count); +} + SigninStatusMetricsProvider::SigninStatus SigninStatusMetricsProvider::GetSigninStatusForTesting() { return signin_status();
diff --git a/chrome/browser/metrics/signin_status_metrics_provider.h b/chrome/browser/metrics/signin_status_metrics_provider.h index 90b6b28..8aff120 100644 --- a/chrome/browser/metrics/signin_status_metrics_provider.h +++ b/chrome/browser/metrics/signin_status_metrics_provider.h
@@ -5,29 +5,26 @@ #ifndef CHROME_BROWSER_METRICS_SIGNIN_STATUS_METRICS_PROVIDER_H_ #define CHROME_BROWSER_METRICS_SIGNIN_STATUS_METRICS_PROVIDER_H_ -#include <string> - #include "base/gtest_prod_util.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" +#include "build/build_config.h" #include "chrome/browser/metrics/signin_status_metrics_provider_base.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/metrics/signin_status_metrics_provider_delegate.h" #include "components/signin/core/browser/signin_manager_base.h" -class Browser; - namespace metrics { class ChromeUserMetricsExtension; } +class SigninStatusMetricsProviderDelegate; + // Collect login status of all opened profiles during one UMA session and // record the value into a histogram before UMA log is uploaded on platform // Windows, Linux, Mac and Android. class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase, - public chrome::BrowserListObserver, - public SigninManagerBase::Observer, - public SigninManagerFactory::Observer { + public SigninManagerBase::Observer { public: ~SigninStatusMetricsProvider() override; @@ -36,29 +33,36 @@ metrics::ChromeUserMetricsExtension* uma_proto) override; // Factory method, creates a new instance of this class. - static SigninStatusMetricsProvider* CreateInstance(); + static SigninStatusMetricsProvider* CreateInstance( + scoped_ptr<SigninStatusMetricsProviderDelegate> delegate); + + // Update the sign-in status when a SigninManager is created. + void OnSigninManagerCreated(SigninManagerBase* manager); + + // Update the sign-in status when a SigninManager is shut down. + void OnSigninManagerShutdown(SigninManagerBase* manager); + + // Updates the initial sign-in status. For testing purpose only. + void UpdateInitialSigninStatusForTesting(size_t total_count, + size_t signed_in_count); + + // Get the current recorded sign-in status. For testing purpose only. + SigninStatus GetSigninStatusForTesting(); private: + FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProviderTest, + UpdateInitialSigninStatus); + FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProviderTest, + GoogleSigninSucceeded); + FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProviderTest, GoogleSignedOut); + // The boolean |is_test| indicates whether or not this is an instance for // testing purpose. If so, skip the initialization. Except for testing // purpose, this class's instance should be created through the static // CreateInstance() method. - explicit SigninStatusMetricsProvider(bool is_test); - - FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProvider, - UpdateInitialSigninStatus); - FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProvider, - UpdateStatusWhenBrowserAdded); - FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProvider, GoogleSigninSucceeded); - FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProvider, GoogleSignedOut); - - // chrome::BrowserListObserver: - // This will never be called on Android. - void OnBrowserAdded(Browser* browser) override; - - // SigninManagerFactory::Observer: - void SigninManagerCreated(SigninManagerBase* manager) override; - void SigninManagerShutdown(SigninManagerBase* manager) override; + SigninStatusMetricsProvider( + scoped_ptr<SigninStatusMetricsProviderDelegate> delegate, + bool is_test); // SigninManagerBase::Observer: void GoogleSigninSucceeded(const std::string& account_id, @@ -77,18 +81,14 @@ // |total_count| profiles. void UpdateInitialSigninStatus(size_t total_count, size_t signed_in_count); - // Update the sign-in status right after a new browser is opened. - void UpdateStatusWhenBrowserAdded(bool signed_in); - // Compute current sign-in status of all opened profiles. void ComputeCurrentSigninStatus(); - // Get the current recorded sign-in status. For testing purpose only. - SigninStatus GetSigninStatusForTesting(); + scoped_ptr<SigninStatusMetricsProviderDelegate> delegate_; // Used to track the SigninManagers that this instance is observing so that // this instance can be removed as an observer on its destruction. - ScopedObserver<SigninManagerBase, SigninStatusMetricsProvider> + ScopedObserver<SigninManagerBase, SigninManagerBase::Observer> scoped_observer_; // Whether the instance is for testing or not.
diff --git a/chrome/browser/metrics/signin_status_metrics_provider_base.cc b/chrome/browser/metrics/signin_status_metrics_provider_base.cc index be807be..69c103ba 100644 --- a/chrome/browser/metrics/signin_status_metrics_provider_base.cc +++ b/chrome/browser/metrics/signin_status_metrics_provider_base.cc
@@ -7,19 +7,18 @@ #include "base/metrics/histogram.h" SigninStatusMetricsProviderBase::SigninStatusMetricsProviderBase() - : signin_status_(UNKNOWN_SIGNIN_STATUS) { -} + : signin_status_(UNKNOWN_SIGNIN_STATUS) {} -SigninStatusMetricsProviderBase::~SigninStatusMetricsProviderBase() { -} +SigninStatusMetricsProviderBase::~SigninStatusMetricsProviderBase() {} void SigninStatusMetricsProviderBase::RecordSigninStatusHistogram( SigninStatus signin_status) { - UMA_HISTOGRAM_ENUMERATION( - "UMA.ProfileSignInStatus", signin_status, SIGNIN_STATUS_MAX); + UMA_HISTOGRAM_ENUMERATION("UMA.ProfileSignInStatus", signin_status, + SIGNIN_STATUS_MAX); } -void SigninStatusMetricsProviderBase::SetSigninStatus(SigninStatus new_status) { +void SigninStatusMetricsProviderBase::UpdateSigninStatus( + SigninStatus new_status) { // The recorded sign-in status value can't be changed once it's recorded as // error until the next UMA upload. if (signin_status_ == ERROR_GETTING_SIGNIN_STATUS)
diff --git a/chrome/browser/metrics/signin_status_metrics_provider_base.h b/chrome/browser/metrics/signin_status_metrics_provider_base.h index 3ad083e..36f1dc8 100644 --- a/chrome/browser/metrics/signin_status_metrics_provider_base.h +++ b/chrome/browser/metrics/signin_status_metrics_provider_base.h
@@ -31,21 +31,21 @@ SIGNIN_STATUS_MAX, }; + // Sets the value of |signin_status_|. It ensures that |signin_status_| will + // not be changed if its value is already ERROR_GETTING_SIGNIN_STATUS. + void UpdateSigninStatus(SigninStatus new_status); + + SigninStatus signin_status() const { return signin_status_; } + protected: // Record the sign in status into the proper histogram bucket. This should be // called exactly once for each UMA session. void RecordSigninStatusHistogram(SigninStatus signin_status); - // Sets the value of |signin_status_|. It ensures that |signin_status_| will - // not be changed if its value is already ERROR_GETTING_SIGNIN_STATUS. - void SetSigninStatus(SigninStatus new_status); - // Resets the value of |signin_status_| to be UNKNOWN_SIGNIN_STATUS regardless // of its current value; void ResetSigninStatus(); - SigninStatus signin_status() const { return signin_status_; } - private: // Sign-in status of all profiles seen so far. SigninStatus signin_status_;
diff --git a/chrome/browser/metrics/signin_status_metrics_provider_chromeos.cc b/chrome/browser/metrics/signin_status_metrics_provider_chromeos.cc index 08e5af8f..4eb0c79 100644 --- a/chrome/browser/metrics/signin_status_metrics_provider_chromeos.cc +++ b/chrome/browser/metrics/signin_status_metrics_provider_chromeos.cc
@@ -45,8 +45,8 @@ void SigninStatusMetricsProviderChromeOS::SetCurrentSigninStatus() { if (IsSignedInNonGuest()) - SetSigninStatus(ALL_PROFILES_SIGNED_IN); - SetSigninStatus(ALL_PROFILES_NOT_SIGNED_IN); + UpdateSigninStatus(ALL_PROFILES_SIGNED_IN); + UpdateSigninStatus(ALL_PROFILES_NOT_SIGNED_IN); } SigninStatusMetricsProviderBase::SigninStatus
diff --git a/chrome/browser/metrics/signin_status_metrics_provider_delegate.cc b/chrome/browser/metrics/signin_status_metrics_provider_delegate.cc new file mode 100644 index 0000000..2f439cb --- /dev/null +++ b/chrome/browser/metrics/signin_status_metrics_provider_delegate.cc
@@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/metrics/signin_status_metrics_provider_delegate.h" + +#include "base/logging.h" +#include "chrome/browser/metrics/signin_status_metrics_provider.h" + +AccountsStatus::AccountsStatus() + : num_accounts(0), num_opened_accounts(0), num_signed_in_accounts(0) {} + +SigninStatusMetricsProviderDelegate::SigninStatusMetricsProviderDelegate() + : owner_(nullptr) {} + +SigninStatusMetricsProviderDelegate::~SigninStatusMetricsProviderDelegate() {} + +void SigninStatusMetricsProviderDelegate::SetOwner( + SigninStatusMetricsProvider* owner) { + DCHECK(owner); + DCHECK(!owner_); + owner_ = owner; +}
diff --git a/chrome/browser/metrics/signin_status_metrics_provider_delegate.h b/chrome/browser/metrics/signin_status_metrics_provider_delegate.h new file mode 100644 index 0000000..02e520d --- /dev/null +++ b/chrome/browser/metrics/signin_status_metrics_provider_delegate.h
@@ -0,0 +1,57 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_METRICS_SIGNIN_STATUS_METRICS_PROVIDER_DELEGATE_H_ +#define CHROME_BROWSER_METRICS_SIGNIN_STATUS_METRICS_PROVIDER_DELEGATE_H_ + +#include <vector> + +#include "base/macros.h" +#include "build/build_config.h" + +class SigninManager; +class SigninStatusMetricsProvider; + +// Provides information relating to the status of accounts in the embedder: how +// many there are, how many are open, and how many are signed in. Note that +// "open" is an embedder-defined concept; in some embedders, all accounts are +// open. +struct AccountsStatus { + AccountsStatus(); + + size_t num_accounts; + size_t num_opened_accounts; + size_t num_signed_in_accounts; +}; + +// Delegate for SigninStatusMetricsProvider to abstract dependencies on +// embedder. +class SigninStatusMetricsProviderDelegate { + public: + SigninStatusMetricsProviderDelegate(); + virtual ~SigninStatusMetricsProviderDelegate(); + + // Set the |owner_| field to the owning SigninStatusMetricsProvider. + void SetOwner(SigninStatusMetricsProvider* owner); + + // Initializes the instance. SetOwner() must have been called before this + // method. + virtual void Initialize() = 0; + + // Returns the status of all accounts. + virtual AccountsStatus GetStatusOfAllAccounts() = 0; + + // Returns the SigninManager instance (if any) associated with each account. + virtual std::vector<SigninManager*> GetSigninManagersForAllAccounts() = 0; + + protected: + SigninStatusMetricsProvider* owner() { return owner_; } + + private: + SigninStatusMetricsProvider* owner_; + + DISALLOW_COPY_AND_ASSIGN(SigninStatusMetricsProviderDelegate); +}; + +#endif // CHROME_BROWSER_METRICS_SIGNIN_STATUS_METRICS_PROVIDER_DELEGATE_H_
diff --git a/chrome/browser/metrics/signin_status_metrics_provider_unittest.cc b/chrome/browser/metrics/signin_status_metrics_provider_unittest.cc index dc4ceb1..2d803a33 100644 --- a/chrome/browser/metrics/signin_status_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/signin_status_metrics_provider_unittest.cc
@@ -6,11 +6,11 @@ #include <string> -#include "base/files/file_path.h" #include "testing/gtest/include/gtest/gtest.h" -TEST(SigninStatusMetricsProvider, UpdateInitialSigninStatus) { - SigninStatusMetricsProvider metrics_provider(true); +TEST(SigninStatusMetricsProviderTest, UpdateInitialSigninStatus) { + SigninStatusMetricsProvider metrics_provider(nullptr, true); + metrics_provider.UpdateInitialSigninStatus(2, 2); EXPECT_EQ(SigninStatusMetricsProviderBase::ALL_PROFILES_SIGNED_IN, metrics_provider.GetSigninStatusForTesting()); @@ -22,50 +22,8 @@ metrics_provider.GetSigninStatusForTesting()); } -#if !defined(OS_ANDROID) && !defined(OS_IOS) -TEST(SigninStatusMetricsProvider, UpdateStatusWhenBrowserAdded) { - SigninStatusMetricsProvider metrics_provider(true); - - // Initial status is all signed in and then a signed-in browser is opened. - metrics_provider.UpdateInitialSigninStatus(2, 2); - metrics_provider.UpdateStatusWhenBrowserAdded(true); - EXPECT_EQ(SigninStatusMetricsProviderBase::ALL_PROFILES_SIGNED_IN, - metrics_provider.GetSigninStatusForTesting()); - - // Initial status is all signed in and then a signed-out browser is opened. - metrics_provider.UpdateInitialSigninStatus(2, 2); - metrics_provider.UpdateStatusWhenBrowserAdded(false); - EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, - metrics_provider.GetSigninStatusForTesting()); - - // Initial status is all signed out and then a signed-in browser is opened. - metrics_provider.UpdateInitialSigninStatus(2, 0); - metrics_provider.UpdateStatusWhenBrowserAdded(true); - EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, - metrics_provider.GetSigninStatusForTesting()); - - // Initial status is all signed out and then a signed-out browser is opened. - metrics_provider.UpdateInitialSigninStatus(2, 0); - metrics_provider.UpdateStatusWhenBrowserAdded(false); - EXPECT_EQ(SigninStatusMetricsProviderBase::ALL_PROFILES_NOT_SIGNED_IN, - metrics_provider.GetSigninStatusForTesting()); - - // Initial status is mixed and then a signed-in browser is opened. - metrics_provider.UpdateInitialSigninStatus(2, 1); - metrics_provider.UpdateStatusWhenBrowserAdded(true); - EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, - metrics_provider.GetSigninStatusForTesting()); - - // Initial status is mixed and then a signed-out browser is opened. - metrics_provider.UpdateInitialSigninStatus(2, 1); - metrics_provider.UpdateStatusWhenBrowserAdded(false); - EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, - metrics_provider.GetSigninStatusForTesting()); -} -#endif - -TEST(SigninStatusMetricsProvider, GoogleSigninSucceeded) { - SigninStatusMetricsProvider metrics_provider(true); +TEST(SigninStatusMetricsProviderTest, GoogleSigninSucceeded) { + SigninStatusMetricsProvider metrics_provider(nullptr, true); // Initial status is all signed out and then one of the profiles is signed in. metrics_provider.UpdateInitialSigninStatus(2, 0); @@ -82,8 +40,8 @@ metrics_provider.GetSigninStatusForTesting()); } -TEST(SigninStatusMetricsProvider, GoogleSignedOut) { - SigninStatusMetricsProvider metrics_provider(true); +TEST(SigninStatusMetricsProviderTest, GoogleSignedOut) { + SigninStatusMetricsProvider metrics_provider(nullptr, true); // Initial status is all signed in and then one of the profiles is signed out. metrics_provider.UpdateInitialSigninStatus(2, 2);
diff --git a/chrome/browser/net/file_downloader.cc b/chrome/browser/net/file_downloader.cc index 1b5c2c2..fdc70ab 100644 --- a/chrome/browser/net/file_downloader.cc +++ b/chrome/browser/net/file_downloader.cc
@@ -26,23 +26,24 @@ const DownloadFinishedCallback& callback) : callback_(callback), fetcher_(URLFetcher::Create(url, URLFetcher::GET, this)), + local_path_(path), weak_ptr_factory_(this) { fetcher_->SetRequestContext(request_context); fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); fetcher_->SetAutomaticallyRetryOnNetworkChanges(kNumRetries); - fetcher_->SaveResponseToFileAtPath( - path, + fetcher_->SaveResponseToTemporaryFile( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); if (overwrite) { fetcher_->Start(); } else { base::PostTaskAndReplyWithResult( - BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN).get(), - FROM_HERE, - base::Bind(&base::PathExists, path), + BrowserThread::GetBlockingPool() + ->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN) + .get(), + FROM_HERE, base::Bind(&base::PathExists, local_path_), base::Bind(&FileDownloader::OnFileExistsCheckDone, weak_ptr_factory_.GetWeakPtr())); } @@ -52,9 +53,6 @@ void FileDownloader::OnURLFetchComplete(const net::URLFetcher* source) { DCHECK_EQ(fetcher_.get(), source); - // Delete |fetcher_| when we leave this method. This is necessary so the - // download file will be deleted if the download failed. - scoped_ptr<net::URLFetcher> fetcher(fetcher_.Pass()); const net::URLRequestStatus& status = source->GetStatus(); if (!status.is_success()) { @@ -72,10 +70,21 @@ return; } - // Take ownership of the new file. base::FilePath response_path; - bool success = source->GetResponseAsFilePath(true, &response_path); - callback_.Run(success); + bool success = source->GetResponseAsFilePath(false, &response_path); + if (!success) { + callback_.Run(false); + return; + } + + base::PostTaskAndReplyWithResult( + BrowserThread::GetBlockingPool() + ->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN) + .get(), + FROM_HERE, base::Bind(&base::Move, response_path, local_path_), + base::Bind(&FileDownloader::OnFileMoveDone, + weak_ptr_factory_.GetWeakPtr())); } void FileDownloader::OnFileExistsCheckDone(bool exists) { @@ -84,3 +93,12 @@ else fetcher_->Start(); } + +void FileDownloader::OnFileMoveDone(bool success) { + if (!success) { + DLOG(WARNING) << "Could not move file to " + << local_path_.LossyDisplayName(); + } + + callback_.Run(success); +}
diff --git a/chrome/browser/net/file_downloader.h b/chrome/browser/net/file_downloader.h index d85b902..8282a66 100644 --- a/chrome/browser/net/file_downloader.h +++ b/chrome/browser/net/file_downloader.h
@@ -6,14 +6,11 @@ #define CHROME_BROWSER_NET_FILE_DOWNLOADER_H_ #include "base/callback.h" +#include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "net/url_request/url_fetcher_delegate.h" -namespace base { -class FilePath; -} // namespace base - namespace net { class URLFetcher; class URLRequestContextGetter; @@ -44,10 +41,14 @@ void OnFileExistsCheckDone(bool exists); + void OnFileMoveDone(bool success); + DownloadFinishedCallback callback_; scoped_ptr<net::URLFetcher> fetcher_; + base::FilePath local_path_; + base::WeakPtrFactory<FileDownloader> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(FileDownloader);
diff --git a/chrome/browser/notifications/message_center_notifications_browsertest.cc b/chrome/browser/notifications/message_center_notifications_browsertest.cc index 8cbc3be8..cb67a36 100644 --- a/chrome/browser/notifications/message_center_notifications_browsertest.cc +++ b/chrome/browser/notifications/message_center_notifications_browsertest.cc
@@ -22,6 +22,8 @@ #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_switches.h" #include "ui/message_center/message_center_types.h" +#include "ui/message_center/notification_types.h" +#include "ui/message_center/notifier_settings.h" class TestAddObserver : public message_center::MessageCenterObserver { public: @@ -103,12 +105,15 @@ new_delegate->AddRef(); } - return Notification(GURL("chrome-test://testing/"), + return Notification(message_center::NOTIFICATION_TYPE_SIMPLE, base::ASCIIToUTF16("title"), base::ASCIIToUTF16("message"), gfx::Image(), + message_center::NotifierId(), base::UTF8ToUTF16("chrome-test://testing/"), + GURL("chrome-test://testing/"), "REPLACE-ME", + message_center::RichNotificationData(), new_delegate); }
diff --git a/chrome/browser/notifications/message_center_notifications_unittest.cc b/chrome/browser/notifications/message_center_notifications_unittest.cc index de4e654..99cb8d4 100644 --- a/chrome/browser/notifications/message_center_notifications_unittest.cc +++ b/chrome/browser/notifications/message_center_notifications_unittest.cc
@@ -22,6 +22,7 @@ #include "ui/message_center/message_center_impl.h" #include "ui/message_center/message_center_tray.h" #include "ui/message_center/message_center_types.h" +#include "ui/message_center/notification_types.h" #include "ui/message_center/notifier_settings.h" #if defined(OS_CHROMEOS) @@ -77,12 +78,15 @@ const ::Notification GetANotification(const std::string& id) { return ::Notification( - GURL("chrome-extension://adflkjsdflkdsfdsflkjdsflkdjfs"), + message_center::NOTIFICATION_TYPE_SIMPLE, base::string16(), base::string16(), gfx::Image(), + NotifierId(NotifierId::APPLICATION, "adflkjsdflkdsfdsflkjdsflkdjfs"), base::string16(), + GURL("chrome-extension://adflkjsdflkdsfdsflkjdsflkdjfs"), id, + message_center::RichNotificationData(), new MockNotificationDelegate(id)); }
diff --git a/chrome/browser/notifications/notification.cc b/chrome/browser/notifications/notification.cc index 076e780..1bd2496 100644 --- a/chrome/browser/notifications/notification.cc +++ b/chrome/browser/notifications/notification.cc
@@ -4,26 +4,6 @@ #include "chrome/browser/notifications/notification.h" -Notification::Notification(const GURL& origin_url, - const base::string16& title, - const base::string16& body, - const gfx::Image& icon, - const base::string16& display_source, - const std::string& tag, - NotificationDelegate* delegate) - : message_center::Notification(message_center::NOTIFICATION_TYPE_SIMPLE, - delegate->id(), - title, - body, - icon, - display_source, - origin_url, - message_center::NotifierId(origin_url), - message_center::RichNotificationData(), - delegate), - tag_(tag), - delegate_(delegate) {} - Notification::Notification( message_center::NotificationType type, const base::string16& title,
diff --git a/chrome/browser/notifications/notification.h b/chrome/browser/notifications/notification.h index d07ef76..668fa0fa 100644 --- a/chrome/browser/notifications/notification.h +++ b/chrome/browser/notifications/notification.h
@@ -23,14 +23,6 @@ // Representation of a notification to be shown to the user. class Notification : public message_center::Notification { public: - Notification(const GURL& origin_url, - const base::string16& title, - const base::string16& body, - const gfx::Image& icon, - const base::string16& display_source, - const std::string& tag, - NotificationDelegate* delegate); - Notification( message_center::NotificationType type, const base::string16& title,
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index f30b74b..9ffb9331 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -36,6 +36,7 @@ #include "content/public/common/platform_notification_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/message_center/notification_types.h" #include "ui/message_center/notifier_settings.h" #include "ui/resources/grit/ui_resources.h" #include "url/url_constants.h" @@ -355,9 +356,11 @@ // different pixel density. Be smarter about this when the API gets updated // with a way for developers to specify images of different resolutions. Notification notification( - origin, notification_data.title, notification_data.body, - gfx::Image::CreateFrom1xBitmap(icon), base::UTF8ToUTF16(origin.host()), - notification_data.tag, delegate); + message_center::NOTIFICATION_TYPE_SIMPLE, notification_data.title, + notification_data.body, gfx::Image::CreateFrom1xBitmap(icon), + message_center::NotifierId(origin), base::UTF8ToUTF16(origin.host()), + origin, notification_data.tag, message_center::RichNotificationData(), + delegate); notification.set_context_message( DisplayNameForContextMessage(profile, origin)); @@ -387,8 +390,6 @@ notification.set_buttons(buttons); - notification.set_is_web_notification(true); - // On desktop, notifications with require_interaction==true stay on-screen // rather than minimizing to the notification center after a timeout. // On mobile, this is ignored (notifications are minimized at all times).
diff --git a/chrome/browser/resources/net_internals/log_util.js b/chrome/browser/resources/net_internals/log_util.js index 5438c64..2ca415e0 100644 --- a/chrome/browser/resources/net_internals/log_util.js +++ b/chrome/browser/resources/net_internals/log_util.js
@@ -34,7 +34,7 @@ function createLogDump(userComments, constants, events, polledData, tabData, numericDate, privacyStripping) { if (privacyStripping) - events = events.map(stripCookiesAndLoginInfo); + events = events.map(stripPrivacyInfo); var logDump = { 'userComments': userComments,
diff --git a/chrome/browser/resources/net_internals/log_view_painter.js b/chrome/browser/resources/net_internals/log_view_painter.js index bbfaae41..5969699 100644 --- a/chrome/browser/resources/net_internals/log_view_painter.js +++ b/chrome/browser/resources/net_internals/log_view_painter.js
@@ -6,7 +6,7 @@ var createLogEntryTablePrinter; var proxySettingsToString; -var stripCookiesAndLoginInfo; +var stripPrivacyInfo; // Start of anonymous namespace. (function() { @@ -244,7 +244,7 @@ function writeParameters(entry, privacyStripping, out) { if (privacyStripping) { // If privacy stripping is enabled, remove data as needed. - entry = stripCookiesAndLoginInfo(entry); + entry = stripPrivacyInfo(entry); } else { // If headers are in an object, convert them to an array for better display. entry = reformatHeaders(entry); @@ -479,6 +479,9 @@ * Removes a cookie or unencrypted login information from a single HTTP header * line, if present, and returns the modified line. Otherwise, just returns * the original line. + * + * Note: this logic should be kept in sync with + * net::ElideHeaderValueForNetLog in net/http/http_log_util.cc. */ function stripCookieOrLoginInfo(line) { var patterns = [ @@ -545,16 +548,40 @@ } /** + * Remove debug data from HTTP/2 GOAWAY frame due to privacy considerations, see + * https://httpwg.github.io/specs/rfc7540.html#GOAWAY. + * + * Note: this logic should be kept in sync with + * net::ElideGoAwayDebugDataForNetLog in net/http/http_log_util.cc. + */ +function stripGoAwayDebugData(value) { + return '[' + value.length + ' bytes were stripped]'; +} + +/** * If |entry| has headers, returns a copy of |entry| with all cookie and * unencrypted login text removed. Otherwise, returns original |entry| object. * This is needed so that JSON log dumps can be made without affecting the * source data. Converts headers stored in objects to arrays. - * - * Note: this logic should be kept in sync with - * net::ElideHeaderForNetLog in net/http/http_log_util.cc. */ -stripCookiesAndLoginInfo = function(entry) { - if (!entry.params || entry.params.headers === undefined || +stripPrivacyInfo = function(entry) { + if (!entry.params) { + return entry; + } + + if (entry.type == EventType.HTTP2_SESSION_GOAWAY && + entry.params.debug_data != undefined) { + // Duplicate the top level object, and |entry.params|. All other fields are + // just pointers to the original values, as they won't be modified, other + // than |entry.params.debug_data|. + entry = shallowCloneObject(entry); + entry.params = shallowCloneObject(entry.params); + entry.params.debug_data = + stripGoAwayDebugData(entry.params.debug_data); + return entry; + } + + if (entry.params.headers === undefined || !(entry.params.headers instanceof Object)) { return entry; }
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.html b/chrome/browser/resources/options/clear_browser_data_overlay.html index 6f86879..c77344ec 100644 --- a/chrome/browser/resources/options/clear_browser_data_overlay.html +++ b/chrome/browser/resources/options/clear_browser_data_overlay.html
@@ -83,7 +83,8 @@ </div> <div class="action-area"> <div class="hbox stretch"> - <a target="_blank" i18n-content="learnMore" + <a id="clear-browser-data-old-learn-more-link" hidden + target="_blank" i18n-content="learnMore" i18n-values="href:clearBrowsingDataLearnMoreUrl"></a> </div> <div class="action-area-right"> @@ -97,6 +98,11 @@ </div> </div> <div id="some-stuff-remains-footer" class="gray-bottom-bar"> - <p><!--This is filled by JavaScript--></p> + <p> + <span><!--This is filled by JavaScript--></span> + <a id="clear-browser-data-footer-learn-more-link" hidden + target="_blank" i18n-content="learnMore" + i18n-values="href:clearBrowsingDataLearnMoreUrl"></a> + </p> </div> </div>
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.js b/chrome/browser/resources/options/clear_browser_data_overlay.js index 883d81c9..e598111 100644 --- a/chrome/browser/resources/options/clear_browser_data_overlay.js +++ b/chrome/browser/resources/options/clear_browser_data_overlay.js
@@ -106,7 +106,7 @@ // and braces and converts them into buttons whereas the remainders are // represented as span elements. var footer = - document.querySelector('#some-stuff-remains-footer p'); + document.querySelector('#some-stuff-remains-footer p span'); var footerFragments = loadTimeData.getString('clearBrowserDataSupportString') .split(/([|#])/); @@ -122,10 +122,7 @@ var linkId = ''; if (i + 2 < footerFragments.length) { if (footerFragments[i] == '|' && footerFragments[i + 2] == '|') { - if (simple) - linkId = 'open-not-deleted-help-from-clear-browsing-data'; - else - linkId = 'open-content-settings-from-clear-browsing-data'; + linkId = 'open-content-settings-from-clear-browsing-data'; } else if (footerFragments[i] == '#' && footerFragments[i + 2] == '#') { linkId = 'open-search-engines-from-clear-browsing-data'; @@ -150,13 +147,7 @@ } } - if (simple) { - $('open-not-deleted-help-from-clear-browsing-data').onclick = - function(event) { - // TODO(msramek): Link to the exact page when the article is written. - window.open('https://support.google.com/chrome/'); - }; - } else { + if (!simple) { $('open-content-settings-from-clear-browsing-data').onclick = function(event) { PageManager.showPageByName('content'); @@ -166,6 +157,9 @@ PageManager.showPageByName('searchEngines'); }; } + + $('clear-browser-data-old-learn-more-link').hidden = simple; + $('clear-browser-data-footer-learn-more-link').hidden = !simple; }, /**
diff --git a/chrome/browser/status_icons/desktop_notification_balloon.cc b/chrome/browser/status_icons/desktop_notification_balloon.cc index c6d2d37..91eb63e 100644 --- a/chrome/browser/status_icons/desktop_notification_balloon.cc +++ b/chrome/browser/status_icons/desktop_notification_balloon.cc
@@ -17,6 +17,8 @@ #include "chrome/browser/profiles/profile_manager.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/image/image_skia.h" +#include "ui/message_center/notification_types.h" +#include "ui/message_center/notifier_settings.h" namespace { @@ -31,6 +33,7 @@ // Prefix added to the notification ids. const char kNotificationPrefix[] = "desktop_notification_balloon."; +const char kNotifierId[] = "status-icons.desktop-notification-balloon"; // Timeout for automatically dismissing the notification balloon. const size_t kTimeoutSeconds = 6; @@ -83,8 +86,16 @@ NotificationDelegate* delegate = new DummyNotificationDelegate(base::IntToString(id_count_++), profile_); - Notification notification(GURL(), title, contents, gfx::Image(icon), - base::string16(), std::string(), delegate); + // TODO(johnme): In theory the desktop notification balloon class can be used + // by lots of other features, which would not fall under a single system + // component id. So callers should pass in the notifier_id to be used here, + // see https://crbug.com/542232 + Notification notification(message_center::NOTIFICATION_TYPE_SIMPLE, title, + contents, gfx::Image(icon), + message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, + kNotifierId), + base::string16(), GURL(), std::string(), + message_center::RichNotificationData(), delegate); g_browser_process->notification_ui_manager()->Add(notification, profile);
diff --git a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc index f65b46b..24dc4bf 100644 --- a/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/autofill_data_type_controller_unittest.cc
@@ -11,9 +11,8 @@ #include "base/run_loop.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/sync/glue/autofill_data_type_controller.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/sync/profile_sync_service_mock.h" #include "chrome/browser/web_data_service_factory.h" +#include "chrome/test/base/testing_profile.h" #include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/sync_driver/data_type_controller_mock.h" @@ -136,7 +135,6 @@ public: SyncAutofillDataTypeControllerTest() : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD), - service_(&profile_), last_start_result_(sync_driver::DataTypeController::OK), weak_ptr_factory_(this) {} ~SyncAutofillDataTypeControllerTest() override {} @@ -179,7 +177,6 @@ protected: content::TestBrowserThreadBundle thread_bundle_; TestingProfile profile_; - ProfileSyncServiceMock service_; scoped_refptr<AutofillDataTypeController> autofill_dtc_; // Stores arguments of most recent call of OnStartFinished().
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc index 5ebc7e6..fa48e20a 100644 --- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/profile_sync_service_mock.h" #include "chrome/test/base/testing_profile.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/test/bookmark_test_helpers.h" @@ -26,6 +25,7 @@ #include "components/sync_driver/change_processor_mock.h" #include "components/sync_driver/data_type_controller_mock.h" #include "components/sync_driver/fake_sync_client.h" +#include "components/sync_driver/fake_sync_service.h" #include "components/sync_driver/model_associator_mock.h" #include "components/sync_driver/sync_api_component_factory_mock.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -87,8 +87,7 @@ public sync_driver::FakeSyncClient { public: SyncBookmarkDataTypeControllerTest() - : thread_bundle_(content::TestBrowserThreadBundle::DEFAULT), - service_(&profile_) {} + : thread_bundle_(content::TestBrowserThreadBundle::DEFAULT) {} // FakeSyncClient overrides. bookmarks::BookmarkModel* GetBookmarkModel() override { @@ -182,7 +181,7 @@ TestingProfile profile_; BookmarkModel* bookmark_model_; HistoryMock* history_service_; - ProfileSyncServiceMock service_; + sync_driver::FakeSyncService service_; ModelAssociatorMock* model_associator_; ChangeProcessorMock* change_processor_; StartCallbackMock start_callback_;
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc index 01adcfb..e8310ae 100644 --- a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc
@@ -13,16 +13,14 @@ #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" #include "base/tracked_objects.h" -#include "chrome/browser/sync/profile_sync_service_mock.h" -#include "chrome/test/base/profile_mock.h" #include "components/sync_driver/change_processor_mock.h" #include "components/sync_driver/data_type_controller_mock.h" #include "components/sync_driver/fake_sync_client.h" +#include "components/sync_driver/fake_sync_service.h" #include "components/sync_driver/frontend_data_type_controller.h" #include "components/sync_driver/frontend_data_type_controller_mock.h" #include "components/sync_driver/model_associator_mock.h" #include "components/sync_driver/sync_api_component_factory_mock.h" -#include "content/public/test/test_browser_thread_bundle.h" using browser_sync::FrontendDataTypeController; using browser_sync::FrontendDataTypeControllerMock; @@ -87,8 +85,7 @@ public: SyncFrontendDataTypeControllerTest() : sync_driver::FakeSyncClient(&profile_sync_factory_), - thread_bundle_(content::TestBrowserThreadBundle::DEFAULT), - service_(&profile_) {} + service_() {} // FakeSyncClient overrides. sync_driver::SyncService* GetSyncService() override { @@ -153,12 +150,11 @@ void PumpLoop() { base::MessageLoop::current()->RunUntilIdle(); } - content::TestBrowserThreadBundle thread_bundle_; + base::MessageLoop message_loop_; scoped_refptr<FrontendDataTypeControllerFake> frontend_dtc_; SyncApiComponentFactoryMock profile_sync_factory_; scoped_refptr<FrontendDataTypeControllerMock> dtc_mock_; - ProfileMock profile_; - ProfileSyncServiceMock service_; + sync_driver::FakeSyncService service_; ModelAssociatorMock* model_associator_; ChangeProcessorMock* change_processor_; StartCallbackMock start_callback_;
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc index 3d3e58b..b7042b34 100644 --- a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc
@@ -14,11 +14,10 @@ #include "base/test/test_timeouts.h" #include "base/thread_task_runner_handle.h" #include "base/tracked_objects.h" -#include "chrome/browser/sync/profile_sync_service_mock.h" -#include "chrome/test/base/profile_mock.h" #include "components/sync_driver/change_processor_mock.h" #include "components/sync_driver/data_type_controller_mock.h" #include "components/sync_driver/fake_sync_client.h" +#include "components/sync_driver/fake_sync_service.h" #include "components/sync_driver/model_associator_mock.h" #include "components/sync_driver/non_frontend_data_type_controller.h" #include "components/sync_driver/non_frontend_data_type_controller_mock.h" @@ -113,7 +112,6 @@ SyncNonFrontendDataTypeControllerTest() : sync_driver::FakeSyncClient(&profile_sync_factory_), thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD), - service_(&profile_), model_associator_(NULL), change_processor_(NULL) {} @@ -206,8 +204,7 @@ content::TestBrowserThreadBundle thread_bundle_; scoped_refptr<NonFrontendDataTypeControllerFake> non_frontend_dtc_; scoped_refptr<NonFrontendDataTypeControllerMock> dtc_mock_; - ProfileMock profile_; - ProfileSyncServiceMock service_; + sync_driver::FakeSyncService service_; SyncApiComponentFactoryMock profile_sync_factory_; ModelAssociatorMock* model_associator_; ChangeProcessorMock* change_processor_;
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc index 69972140..83201e0a 100644 --- a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
@@ -11,7 +11,6 @@ #include "base/tracked_objects.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/search_engines/template_url_service_factory_test_util.h" -#include "chrome/browser/sync/profile_sync_service_mock.h" #include "chrome/test/base/profile_mock.h" #include "components/search_engines/search_engine_data_type_controller.h" #include "components/sync_driver/data_type_controller_mock.h" @@ -48,7 +47,6 @@ } void SetUp() override { - service_.reset(new ProfileSyncServiceMock(&profile_)); // Feed the DTC the profile so it is reused later. // This allows us to control the associated TemplateURLService. search_engine_dtc_ = new SearchEngineDataTypeController( @@ -61,7 +59,6 @@ // Must be done before we pump the loop. syncable_service_.StopSyncing(syncer::SEARCH_ENGINES); search_engine_dtc_ = NULL; - service_.reset(); } protected: @@ -94,7 +91,6 @@ TemplateURLServiceFactoryTestUtil test_util_; scoped_refptr<SearchEngineDataTypeController> search_engine_dtc_; SyncApiComponentFactoryMock profile_sync_factory_; - scoped_ptr<ProfileSyncServiceMock> service_; syncer::FakeSyncableService syncable_service_; sync_driver::StartCallbackMock start_callback_; sync_driver::ModelLoadCallbackMock model_load_callback_;
diff --git a/chrome/browser/sync/glue/typed_url_model_associator_unittest.cc b/chrome/browser/sync/glue/typed_url_model_associator_unittest.cc index 1acb7b7..c72dc68 100644 --- a/chrome/browser/sync/glue/typed_url_model_associator_unittest.cc +++ b/chrome/browser/sync/glue/typed_url_model_associator_unittest.cc
@@ -9,8 +9,8 @@ #include "base/synchronization/waitable_event.h" #include "base/test/test_timeouts.h" #include "base/time/time.h" -#include "chrome/browser/sync/profile_sync_service_mock.h" #include "components/history/core/browser/history_types.h" +#include "components/sync_driver/fake_sync_service.h" #include "components/sync_driver/glue/typed_url_model_associator.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -70,10 +70,10 @@ base::WaitableEvent* aborted, base::WaitableEvent* done, TypedUrlModelAssociator** associator, - ProfileSyncServiceMock* mock) { + sync_driver::SyncService* service) { // Grab the done lock - when we exit, this will be released and allow the // test to finish. - *associator = new TypedUrlModelAssociator(mock, NULL, NULL); + *associator = new TypedUrlModelAssociator(service, NULL, NULL); // Signal frontend to call AbortAssociation and proceed after it's called. startup->Signal(); @@ -413,14 +413,13 @@ base::WaitableEvent startup(false, false); base::WaitableEvent aborted(false, false); base::WaitableEvent done(false, false); - TestingProfile profile; - ProfileSyncServiceMock mock(&profile); + sync_driver::FakeSyncService service; TypedUrlModelAssociator* associator(NULL); // Fire off to the DB thread to create the model associator and start // model association. base::Closure callback = base::Bind( &CreateModelAssociatorAsync, &startup, &aborted, &done, &associator, - &mock); + &service); BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, callback); // Wait for the model associator to get created and start assocation. ASSERT_TRUE(startup.TimedWait(TestTimeouts::action_timeout()));
diff --git a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc index 31cffa6..a3eb043 100644 --- a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc +++ b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
@@ -104,9 +104,10 @@ : launcher_controller_(launcher_controller), observed_activation_clients_(this), observed_root_windows_(this), - settings_window_observer_(new SettingsWindowObserver) { + settings_window_observer_(new SettingsWindowObserver), + browser_tab_strip_tracker_(this, this, this) { DCHECK(launcher_controller_); - BrowserList::AddObserver(this); + chrome::SettingsWindowManager::GetInstance()->AddObserver( settings_window_observer_.get()); @@ -127,6 +128,9 @@ } ash::Shell::GetInstance()->GetScreen()->AddObserver(this); } + + browser_tab_strip_tracker_.Init( + BrowserTabStripTracker::InitWith::ALL_BROWERS); } BrowserStatusMonitor::~BrowserStatusMonitor() { @@ -138,14 +142,7 @@ chrome::SettingsWindowManager::GetInstance()->RemoveObserver( settings_window_observer_.get()); - BrowserList::RemoveObserver(this); - - BrowserList* browser_list = - BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); - for (BrowserList::const_iterator i = browser_list->begin(); - i != browser_list->end(); ++i) { - OnBrowserRemoved(*i); - } + browser_tab_strip_tracker_.StopObservingAndSendOnBrowserRemoved(); STLDeleteContainerPairSecondPointers(webcontents_to_observer_map_.begin(), webcontents_to_observer_map_.end()); @@ -211,28 +208,22 @@ aura::client::GetActivationClient(window)); } -void BrowserStatusMonitor::OnBrowserAdded(Browser* browser) { - if (browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) - return; +bool BrowserStatusMonitor::ShouldTrackBrowser(Browser* browser) { + return browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH; +} +void BrowserStatusMonitor::OnBrowserAdded(Browser* browser) { if (browser->is_type_popup() && browser->is_app()) { // Note: A V1 application will set the tab strip observer when the app gets // added to the shelf. This makes sure that in the multi user case we will // only set the observer while the app item exists in the shelf. AddV1AppToShelf(browser); - } else { - browser->tab_strip_model()->AddObserver(this); } } void BrowserStatusMonitor::OnBrowserRemoved(Browser* browser) { - if (browser->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) - return; - if (browser->is_type_popup() && browser->is_app()) RemoveV1AppFromShelf(browser); - else - browser->tab_strip_model()->RemoveObserver(this); UpdateBrowserItemState(); } @@ -349,8 +340,6 @@ void BrowserStatusMonitor::AddV1AppToShelf(Browser* browser) { DCHECK(browser->is_type_popup() && browser->is_app()); - browser->tab_strip_model()->AddObserver(this); - std::string app_id = web_app::GetExtensionIdFromApplicationName(browser->app_name()); if (!app_id.empty()) { @@ -362,8 +351,6 @@ void BrowserStatusMonitor::RemoveV1AppFromShelf(Browser* browser) { DCHECK(browser->is_type_popup() && browser->is_app()); - browser->tab_strip_model()->RemoveObserver(this); - if (browser_to_app_id_map_.find(browser) != browser_to_app_id_map_.end()) { launcher_controller_->UnlockV1AppWithID(browser_to_app_id_map_[browser]); browser_to_app_id_map_.erase(browser);
diff --git a/chrome/browser/ui/ash/launcher/browser_status_monitor.h b/chrome/browser/ui/ash/launcher/browser_status_monitor.h index e7671ba..1f63488 100644 --- a/chrome/browser/ui/ash/launcher/browser_status_monitor.h +++ b/chrome/browser/ui/ash/launcher/browser_status_monitor.h
@@ -14,6 +14,8 @@ #include "base/scoped_observer.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/ui/browser_tab_strip_tracker.h" +#include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "ui/aura/window_observer.h" #include "ui/gfx/display_observer.h" @@ -34,6 +36,7 @@ // active tab changes. class BrowserStatusMonitor : public aura::client::ActivationChangeObserver, public aura::WindowObserver, + public BrowserTabStripTrackerDelegate, public chrome::BrowserListObserver, public gfx::DisplayObserver, public TabStripModelObserver { @@ -64,6 +67,9 @@ // aura::WindowObserver overrides: void OnWindowDestroyed(aura::Window* window) override; + // BrowserTabStripTrackerDelegate overrides: + bool ShouldTrackBrowser(Browser* browser) override; + // chrome::BrowserListObserver overrides: void OnBrowserAdded(Browser* browser) override; void OnBrowserRemoved(Browser* browser) override; @@ -141,6 +147,8 @@ WebContentsToObserverMap webcontents_to_observer_map_; scoped_ptr<SettingsWindowObserver> settings_window_observer_; + BrowserTabStripTracker browser_tab_strip_tracker_; + DISALLOW_COPY_AND_ASSIGN(BrowserStatusMonitor); };
diff --git a/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.cc b/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.cc index bed0f5e9e..726720a 100644 --- a/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.cc +++ b/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.cc
@@ -8,26 +8,18 @@ #include "ash/metrics/user_metrics_recorder.h" #include "ash/shell.h" #include "base/logging.h" -#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -ChromeUserMetricsRecorder::ChromeUserMetricsRecorder() { - BrowserList::AddObserver(this); +ChromeUserMetricsRecorder::ChromeUserMetricsRecorder() + : browser_tab_strip_tracker_(this, nullptr, nullptr) { + browser_tab_strip_tracker_.Init( + BrowserTabStripTracker::InitWith::ALL_BROWERS); } ChromeUserMetricsRecorder::~ChromeUserMetricsRecorder() { DCHECK(BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH)->empty()); - BrowserList::RemoveObserver(this); -} - -void ChromeUserMetricsRecorder::OnBrowserAdded(Browser* browser) { - browser->tab_strip_model()->AddObserver(this); -} - -void ChromeUserMetricsRecorder::OnBrowserRemoved(Browser* browser) { - browser->tab_strip_model()->RemoveObserver(this); } void ChromeUserMetricsRecorder::ActiveTabChanged(
diff --git a/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.h b/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.h index 81236e9..a937626 100644 --- a/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.h +++ b/chrome/browser/ui/ash/metrics/chrome_user_metrics_recorder.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_UI_ASH_METRICS_CHROME_USER_METRICS_RECORDER_H_ #include "base/macros.h" -#include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/ui/browser_tab_strip_tracker.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" namespace content { @@ -14,16 +14,11 @@ } // namespace content // A bridge proxy between chrome/browser events and ash::UserMetricsRecorder. -class ChromeUserMetricsRecorder : public chrome::BrowserListObserver, - public TabStripModelObserver { +class ChromeUserMetricsRecorder : public TabStripModelObserver { public: ChromeUserMetricsRecorder(); ~ChromeUserMetricsRecorder() override; - // chrome::BroswerListObserver: - void OnBrowserAdded(Browser* browser) override; - void OnBrowserRemoved(Browser* browser) override; - // TabStripModelObserver: void ActiveTabChanged(content::WebContents* old_contents, content::WebContents* new_contents, @@ -34,6 +29,8 @@ // Called when a different tab becomes active due to a user gesture. void OnTabSwitchedByUserGesture(); + BrowserTabStripTracker browser_tab_strip_tracker_; + DISALLOW_COPY_AND_ASSIGN(ChromeUserMetricsRecorder); };
diff --git a/chrome/browser/ui/browser_tab_strip_tracker.cc b/chrome/browser/ui/browser_tab_strip_tracker.cc new file mode 100644 index 0000000..ef34ce3 --- /dev/null +++ b/chrome/browser/ui/browser_tab_strip_tracker.cc
@@ -0,0 +1,99 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/browser_tab_strip_tracker.h" + +#include "base/auto_reset.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_iterator.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" + +BrowserTabStripTracker::BrowserTabStripTracker( + TabStripModelObserver* tab_strip_model_observer, + BrowserTabStripTrackerDelegate* delegate, + BrowserListObserver* browser_list_observer) + : tab_strip_model_observer_(tab_strip_model_observer), + delegate_(delegate), + browser_list_observer_(browser_list_observer), + is_processing_initial_browsers_(false) { + DCHECK(tab_strip_model_observer_); +} + +BrowserTabStripTracker::~BrowserTabStripTracker() { + for (Browser* browser : browsers_observing_) + browser->tab_strip_model()->RemoveObserver(tab_strip_model_observer_); + + BrowserList::RemoveObserver(this); +} + +void BrowserTabStripTracker::Init(InitWith init_with) { + BrowserList::AddObserver(this); + + base::AutoReset<bool> restter(&is_processing_initial_browsers_, true); + if (init_with == InitWith::BROWSERS_IN_ACTIVE_DESKTOP) { + for (Browser* browser : + *BrowserList::GetInstance(chrome::GetActiveDesktop())) + MaybeTrackBrowser(browser); + } else { + DCHECK(InitWith::ALL_BROWERS == init_with); + for (chrome::BrowserIterator it; !it.done(); it.Next()) + MaybeTrackBrowser(*it); + } +} + +void BrowserTabStripTracker::StopObservingAndSendOnBrowserRemoved() { + Browsers current_browsers; + current_browsers.swap(browsers_observing_); + + for (Browser* browser : current_browsers) { + browser->tab_strip_model()->RemoveObserver(tab_strip_model_observer_); + if (browser_list_observer_) + browser_list_observer_->OnBrowserRemoved(browser); + } +} + +bool BrowserTabStripTracker::ShouldTrackBrowser(Browser* browser) { + return !delegate_ || delegate_->ShouldTrackBrowser(browser); +} + +void BrowserTabStripTracker::MaybeTrackBrowser(Browser* browser) { + if (!ShouldTrackBrowser(browser)) + return; + + browsers_observing_.insert(browser); + + if (browser_list_observer_) + browser_list_observer_->OnBrowserAdded(browser); + + TabStripModel* tab_strip_model = browser->tab_strip_model(); + tab_strip_model->AddObserver(tab_strip_model_observer_); + const int active_index = tab_strip_model->active_index(); + for (int i = 0; i < tab_strip_model->count(); ++i) { + tab_strip_model_observer_->TabInsertedAt( + tab_strip_model->GetWebContentsAt(i), i, i == active_index); + } +} + +void BrowserTabStripTracker::OnBrowserAdded(Browser* browser) { + MaybeTrackBrowser(browser); +} + +void BrowserTabStripTracker::OnBrowserRemoved(Browser* browser) { + auto it = browsers_observing_.find(browser); + if (it == browsers_observing_.end()) + return; + + browsers_observing_.erase(it); + browser->tab_strip_model()->RemoveObserver(tab_strip_model_observer_); + + if (browser_list_observer_) + browser_list_observer_->OnBrowserRemoved(browser); +} + +void BrowserTabStripTracker::OnBrowserSetLastActive(Browser* browser) { + if (browser_list_observer_) + browser_list_observer_->OnBrowserSetLastActive(browser); +}
diff --git a/chrome/browser/ui/browser_tab_strip_tracker.h b/chrome/browser/ui/browser_tab_strip_tracker.h new file mode 100644 index 0000000..48e0cc0 --- /dev/null +++ b/chrome/browser/ui/browser_tab_strip_tracker.h
@@ -0,0 +1,87 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_H_ +#define CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_H_ + +#include <set> + +#include "base/basictypes.h" +#include "chrome/browser/ui/browser_list_observer.h" + +class BrowserTabStripTrackerDelegate; +class TabStripModelObserver; + +// BrowserTabStripTracker is useful when you want to attach a +// TabStripModelObserver to a subset of the available browsers, as well as +// tracking new Browsers as they are added. +// +// To constrain the set of Browsers to track use a +// BrowserTabStripTrackerDelegate. BrowserTabStripTracker queries the delegate +// for each Browser to determine if the Browser should be tracked. A null +// delegate indicates all Browsers should be observed. +// +// If you are interested in BrowserListObserver functions specify a +// BrowserListObserver in the constructor. OnBrowserAdded() and +// OnBrowserRemoved() are only called if the delegate indicates the browser +// should be tracked. +class BrowserTabStripTracker : public chrome::BrowserListObserver { + public: + // See Init() for details. + enum class InitWith { + BROWSERS_IN_ACTIVE_DESKTOP, + ALL_BROWERS, + }; + + // See class description for details. You only need specify a + // TabStripModelObserver. |delegate| and |browser_list_observer| are + // optional. + BrowserTabStripTracker(TabStripModelObserver* tab_strip_model_observer, + BrowserTabStripTrackerDelegate* delegate, + BrowserListObserver* browser_list_observer); + ~BrowserTabStripTracker() override; + + // Starts tracking BrowserList for changes and additionally observes the + // existing Browsers matching |init_with|. If there is a + // BrowserTabStripTrackerDelegate it is called to determine if the Browser + // should be observed. If an existing Browser should be observed + // TabInsertedAt() is called for any existing tabs. If a delegate needs to + // differentiate between Browsers observed by way of Init() vs. a Browser + // added after the fact use is_processing_initial_browsers(). + void Init(InitWith init_with); + + // Returns true if processing an existing Browser in Init(). + bool is_processing_initial_browsers() const { + return is_processing_initial_browsers_; + } + + // Stops observing the current set of observed browsers and calls + // BrowserListObserver::OnBrowserRemoved(). + void StopObservingAndSendOnBrowserRemoved(); + + private: + using Browsers = std::set<Browser*>; + + // Returns true if a TabStripModelObserver should be added to |browser|. + bool ShouldTrackBrowser(Browser* browser); + + // If ShouldTrackBrowser() returns true for |browser| then a + // TabStripModelObserver is attached. + void MaybeTrackBrowser(Browser* browser); + + // BrowserListObserver: + void OnBrowserAdded(Browser* browser) override; + void OnBrowserRemoved(Browser* browser) override; + void OnBrowserSetLastActive(Browser* browser) override; + + TabStripModelObserver* tab_strip_model_observer_; + BrowserTabStripTrackerDelegate* delegate_; + BrowserListObserver* browser_list_observer_; + bool is_processing_initial_browsers_; + Browsers browsers_observing_; + + DISALLOW_COPY_AND_ASSIGN(BrowserTabStripTracker); +}; + +#endif // CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_H_
diff --git a/chrome/browser/ui/browser_tab_strip_tracker_delegate.h b/chrome/browser/ui/browser_tab_strip_tracker_delegate.h new file mode 100644 index 0000000..0975bad --- /dev/null +++ b/chrome/browser/ui/browser_tab_strip_tracker_delegate.h
@@ -0,0 +1,22 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_DELEGATE_H_ +#define CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_DELEGATE_H_ + +#include "chrome/browser/ui/browser_list_observer.h" + +class Browser; + +class BrowserTabStripTrackerDelegate { + public: + // Called to determine if the supplied Browser should be tracked. See + // BrowserTabStripTracker for details. + virtual bool ShouldTrackBrowser(Browser* browser) = 0; + + protected: + virtual ~BrowserTabStripTrackerDelegate() {} +}; + +#endif // CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_DELEGATE_H_
diff --git a/chrome/browser/ui/webui/options/clear_browser_data_handler.cc b/chrome/browser/ui/webui/options/clear_browser_data_handler.cc index 66ecb553..5648c684 100644 --- a/chrome/browser/ui/webui/options/clear_browser_data_handler.cc +++ b/chrome/browser/ui/webui/options/clear_browser_data_handler.cc
@@ -45,11 +45,6 @@ switches::kEnableClearBrowsingDataCounters); } -bool IsSupportStringSimplified() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSimpleClearBrowsingDataSupportString); -} - } // namespace namespace options { @@ -83,9 +78,7 @@ AddCounter(make_scoped_ptr(new HistoryCounter()), IDS_DEL_BROWSING_HISTORY_COUNTER); // TODO(msramek): Add a counter for cache. - } - if (IsSupportStringSimplified()) { sync_service_ = ProfileSyncServiceFactory::GetForProfile(Profile::FromWebUI(web_ui())); if (sync_service_) @@ -96,7 +89,7 @@ void ClearBrowserDataHandler::InitializePage() { web_ui()->CallJavascriptFunction( "ClearBrowserDataOverlay.createFooter", - base::FundamentalValue(IsSupportStringSimplified()), + base::FundamentalValue(AreCountersEnabled()), base::FundamentalValue(sync_service_ && sync_service_->IsSyncActive())); UpdateInfoBannerVisibility(); OnBrowsingHistoryPrefChanged(); @@ -142,7 +135,7 @@ static OptionsStringResource resources[] = { { "clearBrowserDataLabel", IDS_CLEAR_BROWSING_DATA_LABEL }, { "clearBrowserDataSyncWarning", IDS_CLEAR_BROWSING_DATA_SYNCED_DELETION }, - { "clearBrowserDataSupportString", IsSupportStringSimplified() + { "clearBrowserDataSupportString", AreCountersEnabled() ? IDS_CLEAR_BROWSING_DATA_SOME_STUFF_REMAINS_SIMPLE : IDS_CLEAR_BROWSING_DATA_SOME_STUFF_REMAINS }, { "deleteBrowsingHistoryCheckbox", IDS_DEL_BROWSING_HISTORY_CHKBOX },
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b4558dd..55427b73 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -1886,12 +1886,16 @@ 'browser/metrics/metrics_services_manager.h', 'browser/metrics/perf/perf_provider_chromeos.cc', 'browser/metrics/perf/perf_provider_chromeos.h', + 'browser/metrics/chrome_signin_status_metrics_provider_delegate.cc', + 'browser/metrics/chrome_signin_status_metrics_provider_delegate.h', 'browser/metrics/signin_status_metrics_provider.cc', 'browser/metrics/signin_status_metrics_provider.h', 'browser/metrics/signin_status_metrics_provider_base.cc', 'browser/metrics/signin_status_metrics_provider_base.h', 'browser/metrics/signin_status_metrics_provider_chromeos.cc', 'browser/metrics/signin_status_metrics_provider_chromeos.h', + 'browser/metrics/signin_status_metrics_provider_delegate.cc', + 'browser/metrics/signin_status_metrics_provider_delegate.h', 'browser/metrics/thread_watcher.cc', 'browser/metrics/thread_watcher.h', 'browser/metrics/thread_watcher_android.cc', @@ -3115,6 +3119,7 @@ '../components/components.gyp:invalidation_impl', '../components/components.gyp:metrics', '../components/components.gyp:metrics_net', + '../components/components.gyp:metrics_ui', '../components/components.gyp:navigation_metrics', '../components/components.gyp:network_time', '../components/components.gyp:offline_pages', @@ -3381,8 +3386,12 @@ }], ['chromeos==1', { 'sources!': [ + 'browser/metrics/chrome_signin_status_metrics_provider_delegate.cc', + 'browser/metrics/chrome_signin_status_metrics_provider_delegate.h', 'browser/metrics/signin_status_metrics_provider.cc', 'browser/metrics/signin_status_metrics_provider.h', + 'browser/metrics/signin_status_metrics_provider_delegate.cc', + 'browser/metrics/signin_status_metrics_provider_delegate.h', ], }], ['enable_extensions==1', {
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 4a3f45ae..118289a 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -1521,6 +1521,9 @@ 'browser/ui/browser_tab_restorer.cc', 'browser/ui/browser_tab_strip_model_delegate.cc', 'browser/ui/browser_tab_strip_model_delegate.h', + 'browser/ui/browser_tab_strip_tracker.cc', + 'browser/ui/browser_tab_strip_tracker.h', + 'browser/ui/browser_tab_strip_tracker_delegate.h', 'browser/ui/browser_tabrestore.cc', 'browser/ui/browser_tabrestore.h', 'browser/ui/browser_tabstrip.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 52f4490..7e0f1cb 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -136,6 +136,7 @@ 'browser/metrics/chrome_metrics_service_accessor_unittest.cc', 'browser/metrics/cloned_install_detector_unittest.cc', 'browser/metrics/perf/perf_provider_chromeos_unittest.cc', + 'browser/metrics/chrome_signin_status_metrics_provider_delegate_unittest.cc', 'browser/metrics/signin_status_metrics_provider_chromeos_unittest.cc', 'browser/metrics/signin_status_metrics_provider_unittest.cc', 'browser/metrics/thread_watcher_android_unittest.cc', @@ -2285,6 +2286,7 @@ }], ['chromeos==1', { 'sources!': [ + 'browser/metrics/chrome_signin_status_metrics_provider_delegate_unittest.cc', 'browser/metrics/signin_status_metrics_provider_unittest.cc', ], }],
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 3017946d..5d310e3 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -988,10 +988,6 @@ // one wishes to use Chrome as an ash server. const char kSilentLaunch[] = "silent-launch"; -// Simplifies the support string in the Clear Browsing Data dialog. -const char kSimpleClearBrowsingDataSupportString[] = - "simple-clear-browsing-data-support-string"; - // Simulates that elevation is needed to recover upgrade channel. const char kSimulateElevatedRecovery[] = "simulate-elevated-recovery";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 0ad9eb5d..69b5c48 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -272,7 +272,6 @@ extern const char kEnableShowSavedCopyPrimary[]; extern const char kEnableShowSavedCopySecondary[]; extern const char kDisableShowSavedCopy[]; -extern const char kSimpleClearBrowsingDataSupportString[]; extern const char kSimulateElevatedRecovery[]; extern const char kSimulateUpgrade[]; extern const char kSimulateCriticalUpdate[];
diff --git a/chrome/common/extensions/permissions/OWNERS b/chrome/common/extensions/permissions/OWNERS new file mode 100644 index 0000000..1b2e1c5 --- /dev/null +++ b/chrome/common/extensions/permissions/OWNERS
@@ -0,0 +1,2 @@ +rdevlin.cronin@chromium.org +treib@chromium.org
diff --git a/chrome/common/localized_error.cc b/chrome/common/localized_error.cc index 6fde4f5..24628b0 100644 --- a/chrome/common/localized_error.cc +++ b/chrome/common/localized_error.cc
@@ -584,20 +584,21 @@ error_code == error_page::DNS_PROBE_FINISHED_NO_INTERNET) { error_strings->SetString("primaryParagraph", l10n_util::GetStringUTF16(options.summary_resource_id)); - - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - - // Check if easter egg should be disabled. - if (command_line->HasSwitch(switches::kDisableDinosaurEasterEgg)) { - // The prescence of this string disables the easter egg. Acts as a flag. - error_strings->SetString("disabledEasterEgg", - l10n_util::GetStringUTF16(IDS_ERRORPAGE_FUN_DISABLED)); - } } else { // Set summary message in the details. summary->SetString("msg", l10n_util::GetStringUTF16(options.summary_resource_id)); } + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + + // Check if easter egg should be disabled. + if (command_line->HasSwitch(switches::kDisableDinosaurEasterEgg)) { + // The presence of this string disables the easter egg. Acts as a flag. + error_strings->SetString("disabledEasterEgg", + l10n_util::GetStringUTF16(IDS_ERRORPAGE_FUN_DISABLED)); + } + summary->SetString("failedUrl", failed_url_string); summary->SetString("hostName", url_formatter::IDNToUnicode(failed_url.host(), accept_languages)); @@ -715,7 +716,6 @@ if (!use_default_suggestions) return; - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); const std::string& show_saved_copy_value = command_line->GetSwitchValueASCII(switches::kShowSavedCopy); bool show_saved_copy_primary = (show_saved_copy_value ==
diff --git a/chrome/installer/linux/common/installer.include b/chrome/installer/linux/common/installer.include index b058942..68c6555e 100644 --- a/chrome/installer/linux/common/installer.include +++ b/chrome/installer/linux/common/installer.include
@@ -173,13 +173,6 @@ install -m 644 "${PEPPERFLASH_SRCDIR}/manifest.json" \ "${PEPPERFLASH_DESTDIR}/" - # peerconnection shared library - if [ -f "${BUILDDIR}/lib/libpeerconnection.so" ]; then - install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/lib/" - - install -m 644 -s "${BUILDDIR}/lib/libpeerconnection.so" "${STAGEDIR}/${INSTALLDIR}/lib/" - fi - # libc++ if [ -f "${BUILDDIR}/lib/libc++.so" ]; then install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/lib/"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 71b4238..e6cd5875 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1618,8 +1618,10 @@ sources -= [ "../browser/download/download_request_infobar_delegate_unittest.cc" ] } if (is_ios || is_chromeos) { - sources -= - [ "../browser/metrics/signin_status_metrics_provider_unittest.cc" ] + sources -= [ + "../browser/metrics/chrome_signin_status_metrics_provider_delegate_unittest.cc", + "../browser/metrics/signin_status_metrics_provider_unittest.cc", + ] } if (enable_background) { sources += rebase_path(
diff --git a/chrome/test/data/webui/net_internals/log_view_painter.js b/chrome/test/data/webui/net_internals/log_view_painter.js index 688b07a..406ba452a 100644 --- a/chrome/test/data/webui/net_internals/log_view_painter.js +++ b/chrome/test/data/webui/net_internals/log_view_painter.js
@@ -9,8 +9,7 @@ (function() { /** - * Check that stripCookiesAndLoginInfo correctly removes cookies and login - * information. + * Check that stripPrivacyInfo correctly removes cookies and login information. */ TEST_F('NetInternalsTest', 'netInternalsLogViewPainterStripInfo', function() { // Each entry in |expectations| is a list consisting of a header element @@ -85,7 +84,7 @@ }; entry.params.headers[position] = expectation[0]; - var stripped = stripCookiesAndLoginInfo(entry); + var stripped = stripPrivacyInfo(entry); // The entry should be duplicated, so the original still has the deleted // information. expectNotEquals(stripped, entry); @@ -114,7 +113,7 @@ 'type': EventSourceType.HTTP_TRANSACTION_HTTP2_SEND_REQUEST_HEADERS }; var strippedSpdyRequestHeadersEntry = - stripCookiesAndLoginInfo(spdyRequestHeadersEntry); + stripPrivacyInfo(spdyRequestHeadersEntry); expectEquals('cookie: [4 bytes were stripped]', strippedSpdyRequestHeadersEntry.params.headers[3]); @@ -122,6 +121,35 @@ }); /** + * Check that stripPrivacyInfo correctly removes HTTP/2 GOAWAY frame debug data. + */ +TEST_F('NetInternalsTest', 'netInternalsLogViewPainterStripGoAway', function() { + var entry = { + 'params': { + 'active_streams': 1, + 'debug_data': 'potentially privacy sensitive information', + 'last_accepted_stream_id': 1, + 'status': 0, + 'unclaimed_streams': 0, + }, + 'phase': 0, + 'source': {'id': 404, 'type': 5}, + 'time': '49236780', + 'type': EventType.HTTP2_SESSION_GOAWAY, + }; + + var stripped = stripPrivacyInfo(entry); + + // The entry should be duplicated, so the original still has the deleted + // information. + expectNotEquals(stripped, entry); + expectEquals('[41 bytes were stripped]', + stripped.params.debug_data); + + testDone(); +}); + +/** * Tests the formatting of log entries to fixed width text. */ TEST_F('NetInternalsTest', 'netInternalsLogViewPainterPrintAsText', function() {
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index c0bc4b7..358bff1 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -81,6 +81,10 @@ "//components/metrics:gpu", "//components/metrics:net", "//components/metrics:profiler", + + # TODO(gfhuang): Eliminate this dependency if ScreenInfoMetricsProvider + # isn't needed. crbug.com/541577 + "//components/metrics:ui", "//components/network_hints/browser", "//content", "//content/public/browser",
diff --git a/chromecast/browser/metrics/cast_metrics_service_client.cc b/chromecast/browser/metrics/cast_metrics_service_client.cc index ba878fc5..20f1b57 100644 --- a/chromecast/browser/metrics/cast_metrics_service_client.cc +++ b/chromecast/browser/metrics/cast_metrics_service_client.cc
@@ -29,6 +29,7 @@ #include "components/metrics/net/net_metrics_log_uploader.h" #include "components/metrics/net/network_metrics_provider.h" #include "components/metrics/profiler/profiler_metrics_provider.h" +#include "components/metrics/ui/screen_info_metrics_provider.h" #include "components/metrics/url_constants.h" #include "content/public/common/content_switches.h" @@ -291,6 +292,14 @@ metrics_service_->OnApplicationNotIdle(); } +void CastMetricsServiceClient::ProcessExternalEvents(const base::Closure& cb) { +#if defined(OS_LINUX) + external_metrics_->ProcessExternalEvents(cb); +#else + cb.Run(); +#endif // defined(OS_LINUX) +} + void CastMetricsServiceClient::SetForceClientId( const std::string& client_id) { DCHECK(force_client_id_.empty()); @@ -334,6 +343,12 @@ metrics_service_->RegisterMetricsProvider( scoped_ptr< ::metrics::MetricsProvider>( new ::metrics::GPUMetricsProvider)); + + // TODO(gfhuang): Does ChromeCast actually need metrics about screen info? + // crbug.com/541577 + metrics_service_->RegisterMetricsProvider( + scoped_ptr< ::metrics::MetricsProvider>( + new ::metrics::ScreenInfoMetricsProvider)); } metrics_service_->RegisterMetricsProvider( scoped_ptr< ::metrics::MetricsProvider>(
diff --git a/chromecast/browser/metrics/cast_metrics_service_client.h b/chromecast/browser/metrics/cast_metrics_service_client.h index 29eb807..264a6cbb3 100644 --- a/chromecast/browser/metrics/cast_metrics_service_client.h +++ b/chromecast/browser/metrics/cast_metrics_service_client.h
@@ -53,6 +53,11 @@ void SetForceClientId(const std::string& client_id); void OnApplicationNotIdle(); + // Processes all events from shared file. This should be used to consume all + // events in the file before shutdown. This function is safe to call from any + // thread. + void ProcessExternalEvents(const base::Closure& cb); + void Initialize(CastService* cast_service); void Finalize();
diff --git a/chromecast/browser/metrics/external_metrics.cc b/chromecast/browser/metrics/external_metrics.cc index d8706a3..698e02b 100644 --- a/chromecast/browser/metrics/external_metrics.cc +++ b/chromecast/browser/metrics/external_metrics.cc
@@ -76,6 +76,15 @@ DCHECK(result); } +void ExternalMetrics::ProcessExternalEvents(const base::Closure& cb) { + content::BrowserThread::PostTaskAndReply( + content::BrowserThread::FILE, FROM_HERE, + base::Bind( + base::IgnoreResult(&ExternalMetrics::CollectEvents), + weak_factory_.GetWeakPtr()), + cb); +} + void ExternalMetrics::RecordCrash(const std::string& crash_kind) { content::BrowserThread::PostTask( content::BrowserThread::UI,
diff --git a/chromecast/browser/metrics/external_metrics.h b/chromecast/browser/metrics/external_metrics.h index 5c45161..c06102c 100644 --- a/chromecast/browser/metrics/external_metrics.h +++ b/chromecast/browser/metrics/external_metrics.h
@@ -32,6 +32,11 @@ // Destroys itself in appropriate thread. void StopAndDestroy(); + // Processes all events from shared file. This should be used to consume all + // events in the file before shutdown. This function is safe to call from any + // thread. + void ProcessExternalEvents(const base::Closure& cb); + private: friend class base::DeleteHelper<ExternalMetrics>;
diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp index ef0027c3..ee7afaa 100644 --- a/chromecast/chromecast.gyp +++ b/chromecast/chromecast.gyp
@@ -335,6 +335,10 @@ '../components/components.gyp:metrics_gpu', '../components/components.gyp:metrics_net', '../components/components.gyp:metrics_profiler', + + # TODO(gfhuang): Eliminate this dependency if ScreenInfoMetricsProvider + # isn't needed. crbug.com/541577 + '../components/components.gyp:metrics_ui', '../content/content.gyp:content', '../content/content.gyp:content_app_both', '../skia/skia.gyp:skia',
diff --git a/chromeos/dbus/services/service_provider_test_helper.cc b/chromeos/dbus/services/service_provider_test_helper.cc index 9b70172..67162441 100644 --- a/chromeos/dbus/services/service_provider_test_helper.cc +++ b/chromeos/dbus/services/service_provider_test_helper.cc
@@ -158,7 +158,7 @@ response_ = response.Pass(); response_received_ = true; if (base::MessageLoop::current()->is_running()) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } } // namespace chromeos
diff --git a/chromeos/login/auth/mock_auth_status_consumer.cc b/chromeos/login/auth/mock_auth_status_consumer.cc index abf6e96..1d8e14d 100644 --- a/chromeos/login/auth/mock_auth_status_consumer.cc +++ b/chromeos/login/auth/mock_auth_status_consumer.cc
@@ -19,59 +19,59 @@ // static void MockAuthStatusConsumer::OnRetailModeSuccessQuit( const UserContext& user_context) { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnRetailModeSuccessQuitAndFail( const UserContext& user_context) { ADD_FAILURE() << "Retail mode login should have failed!"; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnGuestSuccessQuit() { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnGuestSuccessQuitAndFail() { ADD_FAILURE() << "Guest login should have failed!"; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnSuccessQuit(const UserContext& user_context) { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnSuccessQuitAndFail( const UserContext& user_context) { ADD_FAILURE() << "Login should NOT have succeeded!"; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnFailQuit(const AuthFailure& error) { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnFailQuitAndFail(const AuthFailure& error) { ADD_FAILURE() << "Login should not have failed!"; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnMigrateQuit() { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // static void MockAuthStatusConsumer::OnMigrateQuitAndFail() { ADD_FAILURE() << "Should not have detected a PW change!"; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } } // namespace chromeos
diff --git a/chromeos/login/auth/mock_url_fetchers.cc b/chromeos/login/auth/mock_url_fetchers.cc index 0b4879b..48a5543 100644 --- a/chromeos/login/auth/mock_url_fetchers.cc +++ b/chromeos/login/auth/mock_url_fetchers.cc
@@ -40,7 +40,9 @@ void ExpectCanceledFetcher::CompleteFetch() { ADD_FAILURE() << "Fetch completed in ExpectCanceledFetcher!"; - base::MessageLoop::current()->Quit(); // Allow exiting even if we mess up. + + // Allow exiting even if we mess up. + base::MessageLoop::current()->QuitWhenIdle(); } GotCanceledFetcher::GotCanceledFetcher(
diff --git a/chromeos/process_proxy/process_proxy_unittest.cc b/chromeos/process_proxy/process_proxy_unittest.cc index b7b7c7f5..c838f31 100644 --- a/chromeos/process_proxy/process_proxy_unittest.cc +++ b/chromeos/process_proxy/process_proxy_unittest.cc
@@ -79,7 +79,7 @@ if (!valid || TestSucceeded()) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::MessageLoop::QuitClosure()); + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); } } @@ -142,7 +142,7 @@ } EXPECT_EQ("exit", type); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::MessageLoop::QuitClosure()); + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); } void StartRegistryTest(ProcessProxyRegistry* registry) override { @@ -167,7 +167,7 @@ // eventually received exit event. if (type == "exit") { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::MessageLoop::QuitClosure()); + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); } } @@ -211,7 +211,7 @@ registry_->ShutDown(); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::MessageLoop::QuitClosure()); + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); } void RunTest() {
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 513fc7f..21bf32a 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -333,7 +333,6 @@ 'metrics/call_stack_profile_metrics_provider_unittest.cc', 'metrics/daily_event_unittest.cc', 'metrics/drive_metrics_provider_unittest.cc', - 'metrics/gpu/gpu_metrics_provider_unittest.cc', 'metrics/histogram_encoder_unittest.cc', 'metrics/machine_id_provider_win_unittest.cc', 'metrics/metrics_hashes_unittest.cc', @@ -347,6 +346,7 @@ 'metrics/profiler/profiler_metrics_provider_unittest.cc', 'metrics/profiler/tracking_synchronizer_unittest.cc', 'metrics/stability_metrics_helper_unittest.cc', + 'metrics/ui/screen_info_metrics_provider_unittest.cc', ], 'mime_util_unittest_sources': [ 'mime_util/mime_util_unittest.cc', @@ -959,6 +959,7 @@ 'components.gyp:metrics', 'components.gyp:metrics_net', 'components.gyp:metrics_test_support', + 'components.gyp:metrics_ui', 'components.gyp:net_log', 'components.gyp:network_time', 'components.gyp:offline_pages',
diff --git a/components/crash/content/app/breakpad_linux.cc b/components/crash/content/app/breakpad_linux.cc index d92953e..f93dda7f 100644 --- a/components/crash/content/app/breakpad_linux.cc +++ b/components/crash/content/app/breakpad_linux.cc
@@ -603,7 +603,7 @@ return false; } - DCHECK(!minidump.IsFD()); + DCHECK(!(upload && minidump.IsFD())); BreakpadInfo info = {0}; info.filename = minidump.path(); @@ -812,6 +812,19 @@ nullptr, CrashDoneInProcessNoUpload, nullptr, true, -1); } +void GenerateMinidumpOnDemandForAndroid() { + // TODO(tobiasjs) this still calls FinalizeCrashDoneAndroid, which + // generates logspam. Consider refactoring. + int dump_fd = GetCrashReporterClient()->GetAndroidMinidumpDescriptor(); + if (dump_fd >= 0) { + MinidumpDescriptor minidump_descriptor(dump_fd); + minidump_descriptor.set_size_limit(-1); + ExceptionHandler(minidump_descriptor, nullptr, CrashDoneNoUpload, nullptr, + false, -1) + .WriteMinidump(); + } +} + void MicrodumpInfo::SetGpuFingerprint(const std::string& gpu_fingerprint) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!microdump_gpu_fingerprint_); @@ -860,6 +873,18 @@ reinterpret_cast<void*>(is_browser_process), true, // Install handlers. -1); // Server file descriptor. -1 for in-process. + + if (process_type == "webview") { + // We do not use |DumpProcess()| for handling programatically + // generated dumps for WebView because we only know the file + // descriptor to which we are dumping at the time of the call to + // |DumpWithoutCrashing()|. Therefore we need to construct the + // |MinidumpDescriptor| and |ExceptionHandler| instances as + // needed, instead of setting up |g_breakpad| at initialization + // time. + base::debug::SetDumpWithoutCrashingFunction( + &GenerateMinidumpOnDemandForAndroid); + } } #else
diff --git a/components/html_viewer/web_url_loader_impl.cc b/components/html_viewer/web_url_loader_impl.cc index 7853532..2de84cd 100644 --- a/components/html_viewer/web_url_loader_impl.cc +++ b/components/html_viewer/web_url_loader_impl.cc
@@ -95,7 +95,6 @@ : client_(NULL), web_blob_registry_(web_blob_registry), referrer_policy_(blink::WebReferrerPolicyDefault), - handle_watcher_(15), expected_content_length_(-1), current_length_(0), weak_factory_(this) {
diff --git a/components/message_port/web_message_port_channel_impl.cc b/components/message_port/web_message_port_channel_impl.cc index 613cfd3..db30963 100644 --- a/components/message_port/web_message_port_channel_impl.cc +++ b/components/message_port/web_message_port_channel_impl.cc
@@ -35,7 +35,7 @@ WebMessagePortChannelImpl::WebMessagePortChannelImpl( mojo::ScopedMessagePipeHandle pipe) - : client_(nullptr), pipe_(pipe.Pass()), handle_watcher_(13) { + : client_(nullptr), pipe_(pipe.Pass()) { WaitForNextMessage(); }
diff --git a/components/metrics.gypi b/components/metrics.gypi index 5910f74..1004449 100644 --- a/components/metrics.gypi +++ b/components/metrics.gypi
@@ -122,6 +122,23 @@ ], }, { + # GN version: //components/metrics:ui + 'target_name': 'metrics_ui', + 'type': 'static_library', + 'include_dirs': [ + '..', + ], + 'dependencies': [ + '../base/base.gyp:base', + '../ui/gfx/gfx.gyp:gfx', + 'metrics', + ], + 'sources': [ + 'metrics/ui/screen_info_metrics_provider.cc', + 'metrics/ui/screen_info_metrics_provider.h', + ], + }, + { # Protobuf compiler / generator for UMA (User Metrics Analysis). # # GN version: //components/metrics/proto:proto @@ -201,7 +218,6 @@ 'dependencies': [ '../base/base.gyp:base', '../content/content.gyp:content_browser', - '../ui/gfx/gfx.gyp:gfx', 'component_metrics_proto', 'metrics', ],
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 52ab51d..52d75281 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -97,7 +97,6 @@ "//base", "//content/public/browser", "//gpu/config", - "//ui/gfx", ] } } @@ -129,6 +128,22 @@ ] } +# GYP version: components/metrics.gypi:metrics_ui +source_set("ui") { + sources = [ + "ui/screen_info_metrics_provider.cc", + "ui/screen_info_metrics_provider.h", + ] + + public_deps = [ + ":metrics", + ] + deps = [ + "//base", + "//ui/gfx", + ] +} + if (!is_ios) { # GYP version: components/metrics.gypi:metrics_profiler source_set("profiler") { @@ -202,12 +217,14 @@ "net/net_metrics_log_uploader_unittest.cc", "persisted_logs_unittest.cc", "stability_metrics_helper_unittest.cc", + "ui/screen_info_metrics_provider_unittest.cc", ] deps = [ ":metrics", ":net", ":test_support", + ":ui", "//base:prefs_test_support", "//base/test:test_support", "//components/variations", @@ -221,7 +238,6 @@ ":profiler", ] sources += [ - "gpu/gpu_metrics_provider_unittest.cc", "profiler/profiler_metrics_provider_unittest.cc", "profiler/tracking_synchronizer_unittest.cc", ]
diff --git a/components/metrics/gpu/DEPS b/components/metrics/gpu/DEPS index 537521e..c2ff8a0 100644 --- a/components/metrics/gpu/DEPS +++ b/components/metrics/gpu/DEPS
@@ -1,5 +1,4 @@ include_rules = [ "+content/public/browser", "+gpu/config", - "+ui/gfx", ]
diff --git a/components/metrics/gpu/gpu_metrics_provider.cc b/components/metrics/gpu/gpu_metrics_provider.cc index f6c4d08..19cf9b4 100644 --- a/components/metrics/gpu/gpu_metrics_provider.cc +++ b/components/metrics/gpu/gpu_metrics_provider.cc
@@ -7,55 +7,9 @@ #include "components/metrics/proto/system_profile.pb.h" #include "content/public/browser/gpu_data_manager.h" #include "gpu/config/gpu_info.h" -#include "ui/gfx/screen.h" namespace metrics { -#if defined(OS_WIN) - -#include <windows.h> - -namespace { - -struct ScreenDPIInformation { - double max_dpi_x; - double max_dpi_y; -}; - -// Called once for each connected monitor. -BOOL CALLBACK GetMonitorDPICallback(HMONITOR, HDC hdc, LPRECT, LPARAM dwData) { - const double kMillimetersPerInch = 25.4; - ScreenDPIInformation* screen_info = - reinterpret_cast<ScreenDPIInformation*>(dwData); - // Size of screen, in mm. - DWORD size_x = GetDeviceCaps(hdc, HORZSIZE); - DWORD size_y = GetDeviceCaps(hdc, VERTSIZE); - double dpi_x = (size_x > 0) ? - GetDeviceCaps(hdc, HORZRES) / (size_x / kMillimetersPerInch) : 0; - double dpi_y = (size_y > 0) ? - GetDeviceCaps(hdc, VERTRES) / (size_y / kMillimetersPerInch) : 0; - screen_info->max_dpi_x = std::max(dpi_x, screen_info->max_dpi_x); - screen_info->max_dpi_y = std::max(dpi_y, screen_info->max_dpi_y); - return TRUE; -} - -void WriteScreenDPIInformationProto(SystemProfileProto::Hardware* hardware) { - HDC desktop_dc = GetDC(NULL); - if (desktop_dc) { - ScreenDPIInformation si = {0, 0}; - if (EnumDisplayMonitors(desktop_dc, NULL, GetMonitorDPICallback, - reinterpret_cast<LPARAM>(&si))) { - hardware->set_max_dpi_x(si.max_dpi_x); - hardware->set_max_dpi_y(si.max_dpi_y); - } - ReleaseDC(GetDesktopWindow(), desktop_dc); - } -} - -} // namespace - -#endif // defined(OS_WIN) - GPUMetricsProvider::GPUMetricsProvider() { } @@ -77,30 +31,6 @@ gpu->set_driver_date(gpu_info.driver_date); gpu->set_gl_vendor(gpu_info.gl_vendor); gpu->set_gl_renderer(gpu_info.gl_renderer); - - const gfx::Size display_size = GetScreenSize(); - hardware->set_primary_screen_width(display_size.width()); - hardware->set_primary_screen_height(display_size.height()); - hardware->set_primary_screen_scale_factor(GetScreenDeviceScaleFactor()); - hardware->set_screen_count(GetScreenCount()); - -#if defined(OS_WIN) - WriteScreenDPIInformationProto(hardware); -#endif -} - -gfx::Size GPUMetricsProvider::GetScreenSize() const { - return gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel(); -} - -float GPUMetricsProvider::GetScreenDeviceScaleFactor() const { - return gfx::Screen::GetNativeScreen()-> - GetPrimaryDisplay().device_scale_factor(); -} - -int GPUMetricsProvider::GetScreenCount() const { - // TODO(scottmg): NativeScreen maybe wrong. http://crbug.com/133312 - return gfx::Screen::GetNativeScreen()->GetNumDisplays(); } } // namespace metrics
diff --git a/components/metrics/gpu/gpu_metrics_provider.h b/components/metrics/gpu/gpu_metrics_provider.h index 4ca2a96d..9cbdd9641 100644 --- a/components/metrics/gpu/gpu_metrics_provider.h +++ b/components/metrics/gpu/gpu_metrics_provider.h
@@ -7,7 +7,6 @@ #include "base/basictypes.h" #include "components/metrics/metrics_provider.h" -#include "ui/gfx/geometry/size.h" namespace metrics { @@ -21,18 +20,6 @@ void ProvideSystemProfileMetrics( SystemProfileProto* system_profile_proto) override; - protected: - // Exposed for the sake of mocking in test code. - - // Returns the screen size for the primary monitor. - virtual gfx::Size GetScreenSize() const; - - // Returns the device scale factor for the primary monitor. - virtual float GetScreenDeviceScaleFactor() const; - - // Returns the number of monitors the user is using. - virtual int GetScreenCount() const; - private: DISALLOW_COPY_AND_ASSIGN(GPUMetricsProvider); };
diff --git a/components/metrics/ui/DEPS b/components/metrics/ui/DEPS new file mode 100644 index 0000000..b273ae3 --- /dev/null +++ b/components/metrics/ui/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+ui/gfx", +]
diff --git a/components/metrics/ui/screen_info_metrics_provider.cc b/components/metrics/ui/screen_info_metrics_provider.cc new file mode 100644 index 0000000..b832542b --- /dev/null +++ b/components/metrics/ui/screen_info_metrics_provider.cc
@@ -0,0 +1,93 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/ui/screen_info_metrics_provider.h" + +#include "components/metrics/proto/system_profile.pb.h" +#include "ui/gfx/screen.h" + +namespace metrics { + +#if defined(OS_WIN) + +#include <windows.h> + +namespace { + +struct ScreenDPIInformation { + double max_dpi_x; + double max_dpi_y; +}; + +// Called once for each connected monitor. +BOOL CALLBACK GetMonitorDPICallback(HMONITOR, HDC hdc, LPRECT, LPARAM dwData) { + const double kMillimetersPerInch = 25.4; + ScreenDPIInformation* screen_info = + reinterpret_cast<ScreenDPIInformation*>(dwData); + // Size of screen, in mm. + DWORD size_x = GetDeviceCaps(hdc, HORZSIZE); + DWORD size_y = GetDeviceCaps(hdc, VERTSIZE); + double dpi_x = (size_x > 0) ? + GetDeviceCaps(hdc, HORZRES) / (size_x / kMillimetersPerInch) : 0; + double dpi_y = (size_y > 0) ? + GetDeviceCaps(hdc, VERTRES) / (size_y / kMillimetersPerInch) : 0; + screen_info->max_dpi_x = std::max(dpi_x, screen_info->max_dpi_x); + screen_info->max_dpi_y = std::max(dpi_y, screen_info->max_dpi_y); + return TRUE; +} + +void WriteScreenDPIInformationProto(SystemProfileProto::Hardware* hardware) { + HDC desktop_dc = GetDC(NULL); + if (desktop_dc) { + ScreenDPIInformation si = {0, 0}; + if (EnumDisplayMonitors(desktop_dc, NULL, GetMonitorDPICallback, + reinterpret_cast<LPARAM>(&si))) { + hardware->set_max_dpi_x(si.max_dpi_x); + hardware->set_max_dpi_y(si.max_dpi_y); + } + ReleaseDC(GetDesktopWindow(), desktop_dc); + } +} + +} // namespace + +#endif // defined(OS_WIN) + +ScreenInfoMetricsProvider::ScreenInfoMetricsProvider() { +} + +ScreenInfoMetricsProvider::~ScreenInfoMetricsProvider() { +} + +void ScreenInfoMetricsProvider::ProvideSystemProfileMetrics( + SystemProfileProto* system_profile_proto) { + SystemProfileProto::Hardware* hardware = + system_profile_proto->mutable_hardware(); + + const gfx::Size display_size = GetScreenSize(); + hardware->set_primary_screen_width(display_size.width()); + hardware->set_primary_screen_height(display_size.height()); + hardware->set_primary_screen_scale_factor(GetScreenDeviceScaleFactor()); + hardware->set_screen_count(GetScreenCount()); + +#if defined(OS_WIN) + WriteScreenDPIInformationProto(hardware); +#endif +} + +gfx::Size ScreenInfoMetricsProvider::GetScreenSize() const { + return gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel(); +} + +float ScreenInfoMetricsProvider::GetScreenDeviceScaleFactor() const { + return gfx::Screen::GetNativeScreen()-> + GetPrimaryDisplay().device_scale_factor(); +} + +int ScreenInfoMetricsProvider::GetScreenCount() const { + // TODO(scottmg): NativeScreen maybe wrong. http://crbug.com/133312 + return gfx::Screen::GetNativeScreen()->GetNumDisplays(); +} + +} // namespace metrics
diff --git a/components/metrics/ui/screen_info_metrics_provider.h b/components/metrics/ui/screen_info_metrics_provider.h new file mode 100644 index 0000000..1d4b759d --- /dev/null +++ b/components/metrics/ui/screen_info_metrics_provider.h
@@ -0,0 +1,42 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_METRICS_UI_SCREEN_INFO_METRICS_PROVIDER_H_ +#define COMPONENTS_METRICS_UI_SCREEN_INFO_METRICS_PROVIDER_H_ + +#include "base/basictypes.h" +#include "components/metrics/metrics_provider.h" +#include "ui/gfx/geometry/size.h" + +namespace metrics { + +// ScreenInfoMetricsProvider provides metrics related to screen info. +class ScreenInfoMetricsProvider : public MetricsProvider { + public: + ScreenInfoMetricsProvider(); + ~ScreenInfoMetricsProvider() override; + + // MetricsProvider: + void ProvideSystemProfileMetrics( + SystemProfileProto* system_profile_proto) override; + + protected: + // Exposed for the sake of mocking in test code. + + // Returns the screen size for the primary monitor. + virtual gfx::Size GetScreenSize() const; + + // Returns the device scale factor for the primary monitor. + virtual float GetScreenDeviceScaleFactor() const; + + // Returns the number of monitors the user is using. + virtual int GetScreenCount() const; + + private: + DISALLOW_COPY_AND_ASSIGN(ScreenInfoMetricsProvider); +}; + +} // namespace metrics + +#endif // COMPONENTS_METRICS_UI_SCREEN_INFO_METRICS_PROVIDER_H_
diff --git a/components/metrics/gpu/gpu_metrics_provider_unittest.cc b/components/metrics/ui/screen_info_metrics_provider_unittest.cc similarity index 66% rename from components/metrics/gpu/gpu_metrics_provider_unittest.cc rename to components/metrics/ui/screen_info_metrics_provider_unittest.cc index 83d345d..7077078 100644 --- a/components/metrics/gpu/gpu_metrics_provider_unittest.cc +++ b/components/metrics/ui/screen_info_metrics_provider_unittest.cc
@@ -1,8 +1,8 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/metrics/gpu/gpu_metrics_provider.h" +#include "components/metrics/ui/screen_info_metrics_provider.h" #include "base/basictypes.h" #include "components/metrics/proto/chrome_user_metrics_extension.pb.h" @@ -18,10 +18,10 @@ const int kScreenCount = 3; const float kScreenScaleFactor = 2; -class TestGPUMetricsProvider : public GPUMetricsProvider { +class TestScreenInfoMetricsProvider : public ScreenInfoMetricsProvider { public: - TestGPUMetricsProvider() {} - ~TestGPUMetricsProvider() override {} + TestScreenInfoMetricsProvider() {} + ~TestScreenInfoMetricsProvider() override {} private: gfx::Size GetScreenSize() const override { @@ -34,22 +34,22 @@ int GetScreenCount() const override { return kScreenCount; } - DISALLOW_COPY_AND_ASSIGN(TestGPUMetricsProvider); + DISALLOW_COPY_AND_ASSIGN(TestScreenInfoMetricsProvider); }; } // namespace -class GPUMetricsProviderTest : public testing::Test { +class ScreenInfoMetricsProviderTest : public testing::Test { public: - GPUMetricsProviderTest() {} - ~GPUMetricsProviderTest() override {} + ScreenInfoMetricsProviderTest() {} + ~ScreenInfoMetricsProviderTest() override {} private: - DISALLOW_COPY_AND_ASSIGN(GPUMetricsProviderTest); + DISALLOW_COPY_AND_ASSIGN(ScreenInfoMetricsProviderTest); }; -TEST_F(GPUMetricsProviderTest, ProvideSystemProfileMetrics) { - TestGPUMetricsProvider provider; +TEST_F(ScreenInfoMetricsProviderTest, ProvideSystemProfileMetrics) { + TestScreenInfoMetricsProvider provider; ChromeUserMetricsExtension uma_proto; provider.ProvideSystemProfileMetrics(uma_proto.mutable_system_profile());
diff --git a/components/policy.gypi b/components/policy.gypi index d032ace..7788538 100644 --- a/components/policy.gypi +++ b/components/policy.gypi
@@ -22,6 +22,8 @@ '<(policy_out_dir)/policy/cloud_policy_generated.cc', 'app_restrictions_path': '<(policy_out_dir)/app_restrictions.xml', + 'risk_tag_header_path': + '<(policy_out_dir)/risk_tag.h', # This is the "full" protobuf, which defines one protobuf message per # policy. It is also the format currently used by the server. 'chrome_settings_proto_path': @@ -123,6 +125,7 @@ '<(chrome_settings_proto_path)', '<(cloud_policy_proto_path)', '<(app_restrictions_path)', + '<(risk_tag_header_path)', ], 'action_name': 'generate_policy_source', 'action': [ @@ -134,6 +137,7 @@ '--cloud-policy-protobuf=<(cloud_policy_proto_path)', '--cloud-policy-decoder=<(protobuf_decoder_path)', '--app-restrictions-definition=<(app_restrictions_path)', + '--risk-tag-header=<(risk_tag_header_path)', '<(DEPTH)/chrome/VERSION', '<(OS)', '<(chromeos)', @@ -215,6 +219,7 @@ 'sources': [ '<(policy_constant_header_path)', '<(policy_constant_source_path)', + '<(risk_tag_header_path)', '<(protobuf_decoder_path)', ], 'include_dirs': [ @@ -355,7 +360,7 @@ { 'target_name' : 'policy_jni_headers', 'type': 'none', - 'sources': [ + 'sources': [ 'policy/android/java/src/org/chromium/policy/CombinedPolicyProvider.java', 'policy/android/java/src/org/chromium/policy/PolicyConverter.java', ], @@ -433,6 +438,7 @@ 'sources': [ '<(policy_constant_header_path)', '<(policy_constant_source_path)', + '<(risk_tag_header_path)', ], 'include_dirs': [ '<(DEPTH)',
diff --git a/components/policy/BUILD.gn b/components/policy/BUILD.gn index 13fc478..7b5cca1 100644 --- a/components/policy/BUILD.gn +++ b/components/policy/BUILD.gn
@@ -76,6 +76,7 @@ constants_source_path = "$policy_gen_dir/policy_constants.cc" protobuf_decoder_path = "$policy_gen_dir/cloud_policy_generated.cc" app_restrictions_path = "$policy_gen_dir/app_restrictions.xml" + risk_tag_header_path = "$policy_gen_dir/risk_tag.h" action("cloud_policy_code_generate") { script = "tools/generate_policy_source.py" @@ -99,6 +100,7 @@ chrome_settings_proto_path, cloud_policy_proto_path, app_restrictions_path, + risk_tag_header_path, ] if (target_os != "android") { @@ -118,6 +120,7 @@ rebase_path(protobuf_decoder_path, root_build_dir), "--app-restrictions-definition=" + rebase_path(app_restrictions_path, root_build_dir), + "--risk-tag-header=" + rebase_path(risk_tag_header_path, root_build_dir), chrome_version_path, target_os, chromeos_flag, @@ -205,6 +208,7 @@ constants_header_path, constants_source_path, protobuf_decoder_path, + risk_tag_header_path, ] defines = [ "POLICY_COMPONENT_IMPLEMENTATION" ]
diff --git a/components/policy/core/DEPS b/components/policy/core/DEPS index c4c9613..86fa898 100644 --- a/components/policy/core/DEPS +++ b/components/policy/core/DEPS
@@ -12,4 +12,5 @@ "+policy/proto/policy_signing_key.pb.h", "+policy/proto/cloud_policy.pb.h", "+policy/proto/device_management_backend.pb.h", + "+policy/risk_tag.h", ]
diff --git a/components/policy/core/common/policy_details.h b/components/policy/core/common/policy_details.h index 832033690..4f33286 100644 --- a/components/policy/core/common/policy_details.h +++ b/components/policy/core/common/policy_details.h
@@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/callback_forward.h" #include "components/policy/policy_export.h" +#include "policy/risk_tag.h" namespace policy { @@ -29,6 +30,9 @@ // allowed for that data. // Otherwise this field is 0 and doesn't have any meaning. size_t max_external_data_size; + + // Contains tags that describe impact on a user's privacy or security. + RiskTag risk_tags[kMaxRiskTagCount]; }; // A typedef for functions that match the signature of
diff --git a/components/policy/policy_common.gypi b/components/policy/policy_common.gypi index 55573e6..5e876ac 100644 --- a/components/policy/policy_common.gypi +++ b/components/policy/policy_common.gypi
@@ -141,6 +141,7 @@ 'core/common/schema_registry_tracking_policy_provider.cc', 'core/common/schema_registry_tracking_policy_provider.h', 'policy_export.h', + 'policy/policy_risk_tag.h' ], 'conditions': [ ['OS=="android"', {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 8fe6451..03f75c1 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -35,6 +35,17 @@ # 'external' - a policy that references external data. # NOTE: This type is currently supported on Chrome OS only. # +# Each policy is tagged with risk tags that indicate potential privacy or +# security risks. They are defined at the beginning of this file (tag +# 'risk_tag_definitions'). +# Each risk tag contains the following information: +# - name: The name of the risk tag. May not contain spaces. +# - description: Description for developers so they know which tags apply to +# newly added policies. +# - user-description: A text that helps users understand what a policy with +# this tag means for their privacy and/or security. +# TODO(fhorschig|tnagel): Revisit policy tags after reviews. +# # Policy group descriptions, policy captions and similar texts are localized # strings taken from the <message> nodes of the .grd file. Their name # attributes are generated from the JSON keys. @@ -144,6 +155,63 @@ # is applied as mandatory policy unless a different setting is received from # the cloud. # + 'risk_tag_definitions' : [ + # All following tags are ordered by severity of their impact. + # TODO(fhorschig|tnagel): Revisit user-descriptions after reviews. + { + 'name': 'full-admin-access', + 'description': '''Policies with this tag enable an administrator to + execute arbitrary code or configure a machine in a way that a + man-in-the-middle situation can occur.''', + 'user-description': '''Your administrator has set up certificates or applications that could potentially access all of your data. + This could possibly allow inspecting and modifying all data sent and received by Chrome.''' + }, + { + 'name': 'system-security', + 'description': '''Policies with this tag can make the user vulnerable + against attacks which are not possible when the policies are unset. + This includes execution of deprecated code or unsafe configuration of + network settings and proxies.''', + 'user-description': '''Policy set by your administrator could enable functionality that is outdated or that could reduce the security of the system in other ways.''' + }, + { + 'name': 'website-sharing', + 'description': '''Setting Policies with this tag will allow sharing + information with a server that would normally not be allowed. + Those information can include geolocation, audio/video device inputs or + data that can be used to identify the user.''', + 'user-description': '''Policy set by your administrator could enable sharing of data with websites. + Some of these data might suffice to identify you or could be used to record private information.''' + }, + { + 'name': 'admin-sharing', + 'description': '''Policies with this tag enable an administrator to log + the user's activity or traffic.''', + 'user-description': '''Policy configured by your administrator might allow them to gather general information about your device and your activity.''' + }, + { + 'name': 'filtering', + 'description': '''Policies with this tag can restrict the information a + user can query from the world-wide web. This includes blocked websites, + enforced search settings and partly data synchronization.''', + 'user-description': '''Your administrator has set up policy that may restrict your access to websites, services or search results.''' + }, + { + 'name': 'local-data-access', + 'description': '''Policies with this tag can cause storing data to or + reading data from a local file system without the user's knowledge. This + includes import of existing settings to the cloud or avoiding clean-up of + local history data.''', + 'user-description': '''Your administrator has set up policy that could cause private data to be imported from your system or could cause private data to be written to an admin-specified place.''' + }, + { + 'name': 'google-sharing', + 'description': '''Set policies might enforce sharing data with google, + like crash reports or history.''', + 'user-description': '''There are policies set by your administrator which can affect the communication with Google services. + Therefore, some services could either be unreachable or you might not be able to restrict sent data.''' + } + ], 'policy_definitions': [ { 'name': 'Homepage', @@ -166,6 +234,7 @@ 'example_value': 'https://www.chromium.org', 'id': 1, 'caption': '''Configure the home page URL''', + 'tags': [], 'desc': '''Configures the default home page URL in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing it. The home page is the page opened by the Home button. The pages that open on startup are controlled by the RestoreOnStartup policies. @@ -193,6 +262,7 @@ 'example_value': True, 'id': 2, 'caption': '''Use New Tab Page as homepage''', + 'tags': [], 'desc': '''Configures the type of the default home page in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing home page preferences. The home page can either be set to a URL you specify or set to the New Tab Page. If you enable this setting, the New Tab Page is always used for the home page, and the home page URL location is ignored. @@ -220,6 +290,7 @@ 'example_value': True, 'id': 3, 'caption': '''Set <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> as Default Browser''', + 'tags': [], 'desc': '''Configures the default browser checks in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing them. If you enable this setting, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will always check on startup whether it is the default browser and automatically register itself if possible. @@ -242,6 +313,7 @@ 'example_value': 'en', 'id': 4, 'caption': '''Application locale''', + 'tags': [], 'desc': '''Configures the application locale in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing the locale. If you enable this setting, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> uses the specified locale. If the configured locale is not supported, 'en-US' is used instead. @@ -266,6 +338,7 @@ 'example_value': True, 'id': 5, 'caption': '''Enable alternate error pages''', + 'tags': [], 'desc': '''Enables the use of alternate error pages that are built into <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> (such as 'page not found') and prevents users from changing this setting. If you enable this setting, alternate error pages are used. @@ -294,6 +367,7 @@ 'example_value': True, 'id': 6, 'caption': '''Enable search suggestions''', + 'tags': [], 'desc': '''Enables search suggestions in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s omnibox and prevents users from changing this setting. If you enable this setting, search suggestions are used. @@ -317,6 +391,7 @@ 'example_value': True, 'id': 7, 'caption': '''Enable network prediction''', + 'tags': [], 'desc': '''Enables network prediction in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing this setting. This controls not only DNS prefetching but also TCP and SSL preconnection and prerendering of web pages. The policy name refers to DNS prefetching for historical reasons. @@ -359,6 +434,7 @@ 'example_value': 1, 'id': 273, 'caption': '''Enable network prediction''', + 'tags': [], 'desc': '''Enables network prediction in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing this setting. This controls DNS prefetching, TCP and SSL preconnection and prerendering of web pages. @@ -379,6 +455,7 @@ 'example_value': True, 'id': 261, 'caption': '''Enable WPAD optimization''', + 'tags': ['system-security'], 'desc': '''Allows to turn off WPAD (Web Proxy Auto-Discovery) optimization in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If this policy is set to false, WPAD optimization is disabled causing <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to wait longer for DNS-based WPAD servers. If the policy is not set or is enabled, WPAD optimization is enabled. @@ -397,6 +474,7 @@ 'example_value': True, 'id': 8, 'caption': '''Disable SPDY protocol''', + 'tags': [], 'desc': '''Disables use of the SPDY protocol in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If this policy is enabled the SPDY protocol will not be available in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. @@ -421,6 +499,7 @@ 'example_value': ['file', 'https'], 'id': 85, 'caption': '''Disable URL protocol schemes''', + 'tags': [], 'desc': '''This policy is deprecated, please use URLBlacklist instead. Disables the listed protocol schemes in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. @@ -443,6 +522,7 @@ 'example_value': True, 'id': 9, 'caption': '''Enable JavaScript''', + 'tags': [], 'desc': '''This policy is deprecated, please use DefaultJavaScriptSetting instead. Can be used to disabled JavaScript in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. @@ -464,6 +544,7 @@ 'example_value': False, 'id': 10, 'caption': '''Enable Incognito mode''', + 'tags': [], 'desc': '''This policy is deprecated. Please, use IncognitoModeAvailability instead. Enables Incognito mode in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. @@ -509,6 +590,7 @@ 'example_value': 1, 'id': 93, 'caption': '''Incognito mode availability''', + 'tags': ['filtering'], 'desc': '''Specifies whether the user may open pages in Incognito mode in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If 'Enabled' is selected or the policy is left unset, pages may be opened in Incognito mode. @@ -529,6 +611,7 @@ 'example_value': True, 'id': 11, 'caption': '''Disable saving browser history''', + 'tags': [], 'desc': '''Disables saving browser history in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing this setting. If this setting is enabled, browsing history is not saved. This setting also disables tab syncing. @@ -552,6 +635,7 @@ 'example_value': True, 'id': 187, 'caption': '''Enable deleting browser and download history''', + 'tags': [], 'desc': '''Enables deleting browser history and download history in <ph name="PRODUCT_NAME">$<ex>Google Chrome</ex></ph> and prevents users from changing this setting. Note that even with this policy disabled, the browsing and download history are not guaranteed to be retained: users may be able to edit or delete the history database files directly, and the browser itself may expire or archive any or all history items at any time. @@ -581,6 +665,7 @@ 'example_value': False, 'id': 94, 'caption': '''Enable firewall traversal from remote access client''', + 'tags': [], 'desc': '''This policy is no longer supported. Enables usage of STUN and relay servers when connecting to a remote client. @@ -600,6 +685,7 @@ 'example_value': False, 'id': 95, 'caption': '''Enable firewall traversal from remote access host''', + 'tags': [], 'desc': '''Enables usage of STUN servers when remote clients are trying to establish a connection to this machine. If this setting is enabled, then remote clients can discover and connect to this machines even if they are separated by a firewall. @@ -620,6 +706,7 @@ 'example_value': 'my-awesome-domain.com', 'id': 154, 'caption': '''Configure the required domain name for remote access hosts''', + 'tags': [], 'desc': '''Configures the required host domain name that will be imposed on remote access hosts and prevents users from changing it. If this setting is enabled, then hosts can be shared only using accounts registered on the specified domain name. @@ -640,6 +727,7 @@ 'example_value': False, 'id': 155, 'caption': '''Enable two-factor authentication for remote access hosts''', + 'tags': [], 'desc': '''Enables two-factor authentication for remote access hosts instead of a user-specified PIN. If this setting is enabled, then users must provide a valid two-factor code when accessing a host. @@ -658,6 +746,7 @@ 'example_value': 'chromoting-host', 'id': 156, 'caption': '''Configure the TalkGadget prefix for remote access hosts''', + 'tags': [], 'desc': '''Configures the TalkGadget prefix that will be used by remote access hosts and prevents users from changing it. If specified, this prefix is prepended to the base TalkGadget name to create a full domain name for the TalkGadget. The base TalkGadget domain name is '.talkgadget.google.com'. @@ -680,6 +769,7 @@ 'example_value': False, 'id': 157, 'caption': '''Enable curtaining of remote access hosts''', + 'tags': ['system-security'], 'desc': '''Enables curtaining of remote access hosts while a connection is in progress. If this setting is enabled, then hosts' physical input and output devices are disabled while a remote connection is in progress. @@ -698,6 +788,7 @@ 'example_value': False, 'id': 234, 'caption': '''Enable or disable PIN-less authentication for remote access hosts''', + 'tags': [], 'desc': '''If this setting is enabled or not configured, then users can opt to pair clients and hosts at connection time, eliminating the need to enter a PIN every time. If this setting is disabled, then this feature will not be available.''', @@ -714,6 +805,7 @@ 'example_value': True, 'id': 257, 'caption': '''Allow gnubby authentication for remote access hosts''', + 'tags': [], 'desc': '''If this setting is enabled, then gnubby authentication requests will be proxied across a remote host connection. If this setting is disabled or not configured, gnubby authentication requests will not be proxied.''', @@ -730,6 +822,7 @@ 'example_value': False, 'id': 263, 'caption': '''Enable the use of relay servers by the remote access host''', + 'tags': [], 'desc': '''Enables usage of relay servers when remote clients are trying to establish a connection to this machine. If this setting is enabled, then remote clients can use relay servers to connect to this machine when a direct connection is not available (e.g. due to firewall restrictions). @@ -750,6 +843,7 @@ 'example_value': '12400-12409', 'id': 264, 'caption': '''Restrict the UDP port range used by the remote access host''', + 'tags': [], 'desc': '''Restricts the UDP port range used by the remote access host in this machine. If this policy is left not set, or if it is set to an empty string, the remote access host will be allowed to use any available port, unless the policy <ph name="REMOTEACCESSHOSTFIREWALLTRAVERSAL_POLICY_NAME">RemoteAccessHostFirewallTraversal</ph> is disabled, in which case the remote access host will use UDP ports in the 12400-12409 range.''', @@ -766,6 +860,7 @@ 'example_value': False, 'id': 285, 'caption': '''Requires that the name of the local user and the remote access host owner match''', + 'tags': [], 'desc': '''Requires that the name of the local user and the remote access host owner match. If this setting is enabled, then the remote access host compares the name of the local user (that the host is associated with) and the name of the Google account registered as the host owner (i.e. "johndoe" if the host is owned by "johndoe@example.com" Google account). The remote access host will not start if the name of the host owner is different from the name of the local user that the host is associated with. RemoteAccessHostMatchUsername policy should be used together with RemoteAccessHostDomain to also enforce that the Google account of the host owner is associated with a specific domain (i.e. "example.com"). @@ -784,6 +879,7 @@ 'example_value': 'https://example.com/issue', 'id': 286, 'caption': '''URL where remote access clients should obtain their authentication token''', + 'tags': ['website-sharing'], 'desc': '''URL where remote access clients should obtain their authentication token. If this policy is set, the remote access host will require authenticating clients to obtain an authentication token from this URL in order to connect. Must be used in conjunction with RemoteAccessHostTokenValidationUrl. @@ -802,6 +898,7 @@ 'example_value': 'https://example.com/validate', 'id': 287, 'caption': '''URL for validating remote access client authentication token''', + 'tags': ['website-sharing'], 'desc': '''URL for validating remote access client authentication token. If this policy is set, the remote access host will use this URL to validate authentication tokens from remote access clients, in order to accept connections. Must be used in conjunction with RemoteAccessHostTokenUrl. @@ -820,6 +917,7 @@ 'example_value': 'Example Certificate Authority', 'id': 288, 'caption': '''Client certificate for connecting to RemoteAccessHostTokenValidationUrl''', + 'tags': [], 'desc': '''Client certificate for connecting to RemoteAccessHostTokenValidationUrl. If this policy is set, the host will use a client certificate with the given issuer CN to authenticate to RemoteAccessHostTokenValidationUrl. Set it to "*" to use any available client certificate. @@ -838,6 +936,7 @@ 'example_value': '{ "RemoteAccessHostMatchUsername": true }', 'id': 289, 'caption': '''Policy overrides for Debug builds of the remote access host''', + 'tags': [], 'desc': '''Overrides policies on Debug builds of the remote access host. The value is parsed as a JSON dictionary of policy name to policy value mappings.''', @@ -856,6 +955,7 @@ 'example_value': True, 'id': 12, 'caption': '''Enable printing''', + 'tags': [], 'desc': '''Enables printing in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing this setting. If this setting is enabled or not configured, users can print. @@ -874,6 +974,7 @@ 'example_value': True, 'id': 13, 'caption': '''Enable <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> proxy''', + 'tags': [], 'desc': '''Enables <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to act as a proxy between <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> and legacy printers connected to the machine. If this setting is enabled or not configured, users can enable the cloud print proxy by authentication with their Google account. @@ -894,6 +995,7 @@ 'example_value': False, 'id': 162, 'caption': '''Force SafeSearch''', + 'tags': ['filtering'], 'desc': '''This policy is deprecated, please use ForceGoogleSafeSearch and ForceYouTubeSafetyMode instead. This policy will be ignored if either the ForceGoogleSafeSearch or ForceYouTubeSafetyMode policies are set. Forces queries in Google Web Search to be done with SafeSearch set to active and prevents users from changing this setting. This setting also forces Safety Mode on YouTube. @@ -915,6 +1017,7 @@ 'example_value': False, 'id': 282, 'caption': '''Force Google SafeSearch''', + 'tags': ['filtering'], 'desc': '''Forces queries in Google Web Search to be done with SafeSearch set to active and prevents users from changing this setting. If you enable this setting, SafeSearch in Google Search is always active. @@ -934,6 +1037,7 @@ 'example_value': False, 'id': 283, 'caption': '''Force YouTube Safety Mode''', + 'tags': ['filtering'], 'desc': '''Forces YouTube Safety Mode to active and prevents users from changing this setting. If you enable this setting, Safety Mode on YouTube is always active. @@ -953,6 +1057,7 @@ 'example_value': True, 'id': 14, 'caption': '''Enable Safe Browsing''', + 'tags': ['system-security'], 'desc': '''Enables <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s Safe Browsing feature and prevents users from changing this setting. If you enable this setting, Safe Browsing is always active. @@ -976,6 +1081,7 @@ 'example_value': True, 'id': 15, 'caption': '''Enable reporting of usage and crash-related data''', + 'tags': ['google-sharing'], 'desc': '''Enables anonymous reporting of usage and crash-related data about <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to Google and prevents users from changing this setting. If this setting is enabled, anonymous reporting of usage and crash-related @@ -1012,6 +1118,7 @@ 'example_value': True, 'id': 16, 'caption': '''Enable saving passwords to the password manager''', + 'tags': [], 'desc': ''' If this setting is enabled, users can have <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> memorize passwords @@ -1037,6 +1144,7 @@ 'example_value': False, 'id': 17, 'caption': '''Allow users to show passwords in Password Manager''', + 'tags': [], 'desc': '''Controls whether the user may show passwords in clear text in the password manager. If you disable this setting, the password manager does not allow showing stored passwords in clear text in the password manager window. @@ -1063,6 +1171,7 @@ 'example_value': False, 'id': 18, 'caption': '''Enable AutoFill''', + 'tags': [], 'desc': '''Enables <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s AutoFill feature and allows users to auto complete web forms using previously stored information such as address or credit card information. If you disable this setting, AutoFill will be inaccessible to users. @@ -1084,6 +1193,7 @@ 'example_value': ['Java', 'Shockwave Flash', 'Chrome PDF Viewer'], 'id': 19, 'caption': '''Specify a list of disabled plugins''', + 'tags': [], 'desc': '''Specifies a list of plugins that are disabled in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing this setting. The wildcard characters '*' and '?' can be used to match sequences of arbitrary characters. '*' matches an arbitrary number of characters while '?' specifies an optional single character, i.e. matches zero or one characters. The escape character is '\\', so to match actual '*', '?', or '\\' characters, you can put a '\\' in front of them. @@ -1110,6 +1220,7 @@ 'example_value': ['Java', 'Shockwave Flash', 'Chrome PDF Viewer'], 'id': 78, 'caption': '''Specify a list of enabled plugins''', + 'tags': ['system-security'], 'desc': '''Specifies a list of plugins that are enabled in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing this setting. The wildcard characters '*' and '?' can be used to match sequences of arbitrary characters. '*' matches an arbitrary number of characters while '?' specifies an optional single character, i.e. matches zero or one characters. The escape character is '\\', so to match actual '*', '?', or '\\' characters, you can put a '\\' in front of them. @@ -1136,6 +1247,7 @@ 'example_value': ['Java', 'Shockwave Flash', 'Chrome PDF Viewer'], 'id': 79, 'caption': '''Specify a list of plugins that the user can enable or disable''', + 'tags': [], 'desc': '''Specifies a list of plugins that user can enable or disable in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. The wildcard characters '*' and '?' can be used to match sequences of arbitrary characters. '*' matches an arbitrary number of characters while '?' specifies an optional single character, i.e. matches zero or one characters. The escape character is '\\', so to match actual '*', '?', or '\\' characters, you can put a '\\' in front of them. @@ -1161,6 +1273,7 @@ 'example_value': True, 'id': 66, 'caption': '''Specify whether the plugin finder should be disabled''', + 'tags': [], 'desc': '''If you set this setting to enabled the automatic search and installation of missing plugins will be disabled in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. Setting this option to disabled or leave it not set the plugin finder will be active.''', @@ -1178,6 +1291,7 @@ 'example_value': True, 'id': 20, 'caption': '''Disable synchronization of data with Google''', + 'tags': ['filtering', 'google-sharing'], 'desc': '''Disables data synchronization in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> using Google-hosted synchronization services and prevents users from changing this setting. If you enable this setting, users cannot change or override this setting in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. @@ -1197,6 +1311,7 @@ 'example_value': True, 'id': 190, 'caption': '''Allows sign in to <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>''', + 'tags': [], 'desc': '''This policy is deprecated, consider using SyncDisabled instead. Allows the user to sign in to <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. @@ -1216,6 +1331,7 @@ 'example_value': False, 'id': 265, 'caption': '''Enables the old web-based signin''', + 'tags': [], 'desc': '''Enables the old web-based signin flow. This setting was named EnableWebBasedSignin prior to Chrome 42, and support for it will be removed entirely in Chrome 43. @@ -1238,6 +1354,7 @@ 'example_value': '${users}/${user_name}/Chrome', 'id': 63, 'caption': '''Set user data directory''', + 'tags': ['local-data-access'], 'desc': '''Configures the directory that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use for storing user data. If you set this policy, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the provided directory regardless whether the user has specified the '--user-data-dir' flag or not. @@ -1259,6 +1376,7 @@ 'example_value': '${user_home}/Chrome_cache', 'id': 88, 'caption': '''Set disk cache directory''', + 'tags': [], 'desc': '''Configures the directory that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use for storing cached files on the disk. If you set this policy, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the provided directory regardless whether the user has specified the '--disk-cache-dir' flag or not. @@ -1280,6 +1398,7 @@ 'example_value': 104857600, 'id': 110, 'caption': '''Set disk cache size in bytes''', + 'tags': [], 'desc': '''Configures the cache size that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use for storing cached files on the disk. If you set this policy, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the provided cache size regardless whether the user has specified the '--disk-cache-size' flag or not. The value specified in this policy is not a hard boundary but rather a suggestion to the caching system, any value below a few megabytes is too small and will be rounded up to a sane minimum. @@ -1301,6 +1420,7 @@ 'example_value': 104857600, 'id': 111, 'caption': '''Set media disk cache size in bytes''', + 'tags': [], 'desc': '''Configures the cache size that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use for storing cached media files on the disk. If you set this policy, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the provided cache size regardless whether the user has specified the '--media-cache-size' flag or not. The value specified in this policy is not a hard boundary but rather a suggestion to the caching system, any value below a few megabytes is too small and will be rounded up to a sane minimum. @@ -1323,6 +1443,7 @@ 'example_value': '/home/${user_name}/Downloads', 'id': 64, 'caption': '''Set download directory''', + 'tags': ['local-data-access'], 'desc': '''Configures the directory that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use for downloading files. If you set this policy, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the provided directory regardless whether the user has specified one or enabled the flag to be prompted for download location every time. @@ -1346,6 +1467,7 @@ 'example_value': True, 'id': 65, 'caption': '''Clear site data on browser shutdown (deprecated)''', + 'tags': [], 'desc': '''This policy has been retired as of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> version 29.''', 'label': '''Clear site data on browser shutdown (deprecated)''', }, @@ -1363,6 +1485,7 @@ 'default_for_enterprise_users': False, 'id': 295, 'caption': '''Captive portal authentication ignores proxy''', + 'tags': [], 'desc': '''This policy allows <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> to bypass any proxy for captive portal authentication. This policy only takes effect if a proxy is configured (for example through policy, by the user in chrome://settings, or by extensions). @@ -1441,6 +1564,7 @@ 'example_value': 'direct', 'id': 21, 'caption': '''Choose how to specify proxy server settings''', + 'tags': [], 'desc': '''Allows you to specify the proxy server used by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing proxy settings. If you choose to never use a proxy server and always connect directly, all other options are ignored. @@ -1501,6 +1625,7 @@ 'example_value': 2, 'id': 22, 'caption': '''Choose how to specify proxy server settings''', + 'tags': [], 'desc': '''This policy is deprecated, use ProxyMode instead. Allows you to specify the proxy server used by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and prevents users from changing proxy settings. @@ -1535,6 +1660,7 @@ 'example_value': '123.123.123.123:8080', 'id': 23, 'caption': '''Address or URL of proxy server''', + 'tags': [], 'desc': '''You can specify the URL of the proxy server here. This policy only takes effect if you have selected manual proxy settings at 'Choose how to specify proxy server settings'. @@ -1561,6 +1687,7 @@ 'example_value': 'https://internal.site/example.pac', 'id': 24, 'caption': '''URL to a proxy .pac file''', + 'tags': [], 'desc': '''You can specify a URL to a proxy .pac file here. This policy only takes effect if you have selected manual proxy settings at 'Choose how to specify proxy server settings'. @@ -1587,6 +1714,7 @@ 'example_value': 'https://www.example1.com,https://www.example2.com,https://internalsite/', 'id': 25, 'caption': '''Proxy bypass rules''', + 'tags': [], 'desc': '''<ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will bypass any proxy for the list of hosts given here. This policy only takes effect if you have selected manual proxy settings at 'Choose how to specify proxy server settings'. @@ -1630,6 +1758,7 @@ 'example_value': { "ProxyMode": "direct" }, 'id': 116, 'caption': '''Proxy settings''', + 'tags': ['system-security'], 'desc': '''Configures the proxy settings for <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. This policy isn't ready for usage yet, please don't use it.''', @@ -1652,6 +1781,7 @@ 'example_value': 'basic,digest,ntlm,negotiate', 'id': 26, 'caption': '''Supported authentication schemes''', + 'tags': [], 'desc': '''Specifies which HTTP Authentication schemes are supported by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. Possible values are 'basic', 'digest', 'ntlm' and 'negotiate'. Separate multiple values with commas. @@ -1670,6 +1800,7 @@ 'example_value': False, 'id': 27, 'caption': '''Disable CNAME lookup when negotiating Kerberos authentication''', + 'tags': [], 'desc': '''Specifies whether the generated Kerberos SPN is based on the canonical DNS name or the original name entered. If you enable this setting, CNAME lookup will be skipped and the server name will be used as entered. @@ -1688,6 +1819,7 @@ 'example_value': False, 'id': 28, 'caption': '''Include non-standard port in Kerberos SPN''', + 'tags': [], 'desc': '''Specifies whether the generated Kerberos SPN should include a non-standard port. If you enable this setting, and a non-standard port (i.e., a port other than 80 or 443) is entered, it will be included in the generated Kerberos SPN. @@ -1706,6 +1838,7 @@ 'example_value': '*example.com,foobar.com,*baz', 'id': 29, 'caption': '''Authentication server whitelist''', + 'tags': [], 'desc': '''Specifies which servers should be whitelisted for integrated authentication. Integrated authentication is only enabled when <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> receives an authentication challenge from a proxy or from a server which is in this permitted list. Separate multiple server names with commas. Wildcards (*) are allowed. @@ -1724,6 +1857,7 @@ 'example_value': 'foobar.example.com', 'id': 30, 'caption': '''Kerberos delegation server whitelist''', + 'tags': [], 'desc': '''Servers that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> may delegate to. Separate multiple server names with commas. Wildcards (*) are allowed. @@ -1742,6 +1876,7 @@ 'example_value': 'libgssapi_krb5.so.2', 'id': 31, 'caption': '''GSSAPI library name''', + 'tags': [], 'desc': '''Specifies which GSSAPI library to use for HTTP Authentication. You can set either just a library name, or a full path. If no setting is provided, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will fall back to using a default library name.''', @@ -1758,6 +1893,7 @@ 'example_value': 'com.example.spnego', 'id': 305, 'caption': '''Account Type for Negotiate Authentication''', + 'tags': [], 'desc': '''Specifies the account type of the accounts provided by the Android authentication app that supports HTTP Negotiate authentication (e.g. Kerberos authentication). This information should be available from the supplier of the Authentication app. For more details see https://goo.gl/hajyfN. If no setting is provided then Negotiate Authentication will be disabled on Android.''', @@ -1774,6 +1910,7 @@ 'example_value': False, 'id': 89, 'caption': '''Cross-origin HTTP Basic Auth prompts''', + 'tags': ['website-sharing'], 'desc': '''Controls whether third-party sub-content on a page is allowed to pop-up an HTTP Basic Auth dialog box. Typically this is disabled as a phishing defense. If this policy is not set, this is disabled and third-party sub-content will not be allowed to pop up a HTTP Basic Auth dialog box.''', @@ -1801,6 +1938,7 @@ 'example_value': ['extension_id1', 'extension_id2'], 'id': 32, 'caption': '''Configure extension installation blacklist''', + 'tags': [], 'desc': '''Allows you to specify which extensions the users can NOT install. Extensions already installed will be removed if blacklisted. A blacklist value of '*' means all extensions are blacklisted unless they are explicitly listed in the whitelist. @@ -1823,6 +1961,7 @@ 'example_value': ['extension_id1', 'extension_id2'], 'id': 33, 'caption': '''Configure extension installation whitelist''', + 'tags': [], 'desc': '''Allows you to specify which extensions are not subject to the blacklist. A blacklist value of * means all extensions are blacklisted and users can only install extensions listed in the whitelist. @@ -1845,6 +1984,7 @@ 'example_value': ['gbchcmhmhahfdphkhkmpfmihenigjmpp;https://clients2.google.com/service/update2/crx'], 'id': 34, 'caption': '''Configure the list of force-installed apps and extensions''', + 'tags': ['full-admin-access'], 'desc': ''' Specifies a list of apps and extensions that are installed silently, without user interaction, and which cannot be uninstalled by the @@ -1911,6 +2051,7 @@ 'example_value': ['https://corp.mycompany.com/*'], 'id': 148, 'caption': '''Configure extension, app, and user script install sources''', + 'tags': ['full-admin-access', 'system-security'], 'desc': '''Allows you to specify which URLs are allowed to install extensions, apps, and themes. Starting in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> 21, it is more difficult to install extensions, apps, and user scripts from outside the Chrome Web Store. Previously, users could click on a link to a *.crx file, and <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> would offer to install the file after a few warnings. After <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> 21, such files must be downloaded and dragged onto the <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> settings page. This setting allows specific URLs to have the old, easier installation flow. @@ -1946,6 +2087,7 @@ 'example_value': ['hosted_app'], 'id': 168, 'caption': '''Configure allowed app/extension types''', + 'tags': [], 'desc': '''Controls which app/extension types are allowed to be installed. This setting white-lists the allowed types of extension/apps that can be installed in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. The value is a list of strings, each of which should be one of the following: "extension", "theme", "user_script", "hosted_app", "legacy_packaged_app", "platform_app". See the <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> extensions documentation for more information on these types. @@ -2054,6 +2196,7 @@ }, 'id': 278, 'caption': 'Extension management settings', + 'tags': [], 'desc': '''Configures extension management settings for <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. This policy controls multiple settings, including settings controlled by any existing extension-related policies. This policy will override any legacy policies if both are set. @@ -2102,6 +2245,7 @@ 'example_value': True, 'id': 35, 'caption': '''Show Home button on toolbar''', + 'tags': [], 'desc': '''Shows the Home button on <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s toolbar. If you enable this setting, the Home button is always shown. @@ -2124,6 +2268,7 @@ 'example_value': False, 'id': 36, 'caption': '''Disable Developer Tools''', + 'tags': [], 'desc': '''Disables the Developer Tools and the JavaScript console. If you enable this setting, the Developer Tools can not be accessed and web-site elements can not be inspected anymore. Any keyboard shortcuts and any menu or context menu entries to open the Developer Tools or the JavaScript Console will be disabled. @@ -2171,6 +2316,7 @@ 'example_value': 4, 'id': 37, 'caption': '''Action on startup''', + 'tags': [], 'desc': '''Allows you to specify the behavior on startup. If you choose 'Open New Tab Page' the New Tab Page will always be opened when you start <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. @@ -2203,6 +2349,7 @@ 'example_value': ['https://example.com', 'https://www.chromium.org'], 'id': 38, 'caption': '''URLs to open on startup''', + 'tags': [], 'desc': '''If 'Open a list of URLs' is selected as the startup action, this allows you to specify the list of URLs that are opened. If left not set no URL will be opened on start up. This policy only works if the 'RestoreOnStartup' policy is set to 'RestoreOnStartupIsURLs'. @@ -2225,6 +2372,7 @@ 'example_value': False, 'id': 39, 'caption': '''Block third party cookies''', + 'tags': [], 'desc': '''Blocks third party cookies. Enabling this setting prevents cookies from being set by web page elements that are not from the domain that is in the browser's address bar. @@ -2258,6 +2406,7 @@ 'example_value': True, 'id': 40, 'caption': '''Enable the default search provider''', + 'tags': [], 'desc': '''Enables the use of a default search provider. If you enable this setting, a default search is performed when the user types text in the omnibox that is not a URL. @@ -2290,6 +2439,7 @@ 'example_value': 'My Intranet Search', 'id': 41, 'caption': '''Default search provider name''', + 'tags': ['website-sharing'], 'desc': '''Specifies the name of the default search provider. If left empty or not set, the host name specified by the search URL will be used. This policy is only considered if the 'DefaultSearchProviderEnabled' policy is enabled.''', @@ -2311,6 +2461,7 @@ 'example_value': 'mis', 'id': 42, 'caption': '''Default search provider keyword''', + 'tags': [], 'desc': '''Specifies the keyword, which is the shortcut used in the omnibox to trigger the search for this provider. This policy is optional. If not set, no keyword will activate the search provider. @@ -2334,6 +2485,7 @@ 'example_value': 'https://search.my.company/search?q={searchTerms}', 'id': 43, 'caption': '''Default search provider search URL''', + 'tags': ['website-sharing'], 'desc': '''Specifies the URL of the search engine used when doing a default search. The URL should contain the string '<ph name="SEARCH_TERM_MARKER">{searchTerms}</ph>', which will be replaced at query time by the terms the user is searching for. This option must be set when the 'DefaultSearchProviderEnabled' policy is enabled and will only be respected if this is the case.''', @@ -2350,6 +2502,7 @@ 'example_value': 'https://search.my.company/suggest?q={searchTerms}', 'id': 44, 'caption': '''Default search provider suggest URL''', + 'tags': [], 'desc': '''Specifies the URL of the search engine used to provide search suggestions. The URL should contain the string '<ph name="SEARCH_TERM_MARKER">{searchTerms}</ph>', which will be replaced at query time by the text the user has entered so far. This policy is optional. If not set, no suggest URL will be used. @@ -2368,6 +2521,7 @@ 'example_value': 'https://search.my.company/suggest?q={searchTerms}', 'id': 45, 'caption': '''Default search provider instant URL''', + 'tags': [], 'desc': '''Specifies the URL of the search engine used to provide instant results. The URL should contain the string <ph name="SEARCH_TERM_MARKER">'{searchTerms}'</ph>, which will be replaced at query time by the text the user has entered so far. This policy is optional. If not set, no instant search results will be provided. @@ -2386,6 +2540,7 @@ 'example_value': 'https://search.my.company/favicon.ico', 'id': 46, 'caption': '''Default search provider icon''', + 'tags': [], 'desc': '''Specifies the favorite icon URL of the default search provider. This policy is optional. If not set, no icon will be present for the search provider. @@ -2407,6 +2562,7 @@ 'example_value': ['UTF-8', 'UTF-16', 'GB2312', 'ISO-8859-1'], 'id': 47, 'caption': '''Default search provider encodings''', + 'tags': [], 'desc': '''Specifies the character encodings supported by the search provider. Encodings are code page names like UTF-8, GB2312, and ISO-8859-1. They are tried in the order provided. This policy is optional. If not set, the default will be used which is UTF-8. @@ -2428,6 +2584,7 @@ 'example_value': ['https://search.my.company/suggest#q={searchTerms}', 'https://search.my.company/suggest/search#q={searchTerms}'], 'id': 161, 'caption': '''List of alternate URLs for the default search provider''', + 'tags': [], 'desc': '''Specifies a list of alternate URLs that can be used to extract search terms from the search engine. The URLs should contain the string <ph name="SEARCH_TERM_MARKER">'{searchTerms}'</ph>, which will be used to extract the search terms. This policy is optional. If not set, no alternate urls will be used to extract search terms. @@ -2446,6 +2603,7 @@ 'example_value': 'espv', 'id': 171, 'caption': '''Parameter controlling search term placement for the default search provider''', + 'tags': [], 'desc': '''If this policy is set and a search URL suggested from the omnibox contains this parameter in the query string or in the fragment identifier, then the suggestion will show the search terms and search provider instead of the raw search URL. This policy is optional. If not set, no search term replacement will be performed. @@ -2464,6 +2622,7 @@ 'example_value': 'https://search.my.company/searchbyimage/upload', 'id': 229, 'caption': '''Parameter providing search-by-image feature for the default search provider''', + 'tags': [], 'desc': '''Specifies the URL of the search engine used to provide image search. Search requests will be sent using the GET method. If the DefaultSearchProviderImageURLPostParams policy is set then image search requests will use the POST method instead. This policy is optional. If not set, no image search will be used. @@ -2482,6 +2641,7 @@ 'example_value': 'https://search.my.company/newtab', 'id': 237, 'caption': '''Default search provider new tab page URL''', + 'tags': [], 'desc': '''Specifies the URL that a search engine uses to provide a new tab page. This policy is optional. If not set, no new tab page will be provided. @@ -2500,6 +2660,7 @@ 'example_value': 'q={searchTerms},ie=utf-8,oe=utf-8', 'id': 230, 'caption': '''Parameters for search URL which uses POST''', + 'tags': [], 'desc': '''Specifies the parameters used when searching a URL with POST. It consists of comma-separated name/value pairs. If a value is a template parameter, like {searchTerms} in above example, it will be replaced with real search terms data. This policy is optional. If not set, search request will be sent using the GET method. @@ -2518,6 +2679,7 @@ 'example_value': 'q={searchTerms},ie=utf-8,oe=utf-8', 'id': 231, 'caption': '''Parameters for suggest URL which uses POST''', + 'tags': [], 'desc': '''Specifies the parameters used when doing suggestion search with POST. It consists of comma-separated name/value pairs. If a value is a template parameter, like {searchTerms} in above example, it will be replaced with real search terms data. This policy is optional. If not set, suggest search request will be sent using the GET method. @@ -2536,6 +2698,7 @@ 'example_value': 'q={searchTerms},ie=utf-8,oe=utf-8', 'id': 232, 'caption': '''Parameters for instant URL which uses POST''', + 'tags': [], 'desc': '''Specifies the parameters used when doing instant search with POST. It consists of comma-separated name/value pairs. If a value is a template parameter, like {searchTerms} in above example, it will be replaced with real search terms data. This policy is optional. If not set, instant search request will be sent using the GET method. @@ -2554,6 +2717,7 @@ 'example_value': 'content={imageThumbnail},url={imageURL},sbisrc={SearchSource}', 'id': 233, 'caption': '''Parameters for image URL which uses POST''', + 'tags': [], 'desc': '''Specifies the parameters used when doing image search with POST. It consists of comma-separated name/value pairs. If a value is a template parameter, like {imageThumbnail} in above example, it will be replaced with real image thumbnail data. This policy is optional. If not set, image search request will be sent using the GET method. @@ -2607,6 +2771,7 @@ 'example_value': 1, 'id': 48, 'caption': '''Default cookies setting''', + 'tags': [], 'desc': '''Allows you to set whether websites are allowed to set local data. Setting local data can be either allowed for all websites or denied for all websites. If this policy is set to 'Keep cookies for the duration of the session' then cookies will be cleared when the session closes. Note that if <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is running in 'background mode', the session may not close when the last window is closed. Please see the 'BackgroundModeEnabled' policy for more information about configuring this behavior. @@ -2640,6 +2805,7 @@ 'example_value': 1, 'id': 49, 'caption': '''Default images setting''', + 'tags': [], 'desc': '''Allows you to set whether websites are allowed to display images. Displaying images can be either allowed for all websites or denied for all websites. If this policy is left not set, 'AllowImages' will be used and the user will be able to change it.''', @@ -2671,6 +2837,7 @@ 'example_value': 1, 'id': 50, 'caption': '''Default JavaScript setting''', + 'tags': [], 'desc': '''Allows you to set whether websites are allowed to run JavaScript. Running JavaScript can be either allowed for all websites or denied for all websites. If this policy is left not set, 'AllowJavaScript' will be used and the user will be able to change it.''', @@ -2707,6 +2874,7 @@ 'example_value': 1, 'id': 51, 'caption': '''Default plugins setting''', + 'tags': [], 'desc': '''Allows you to set whether websites are allowed to automatically run plugins. Automatically running plugins can be either allowed for all websites or denied for all websites. Click to play allows plugins to run but the user must click them to start their execution. @@ -2745,6 +2913,7 @@ 'example_value': 1, 'id': 52, 'caption': '''Default popups setting''', + 'tags': [], 'desc': '''Allows you to set whether websites are allowed to show pop-ups. Showing popups can be either allowed for all websites or denied for all websites. If this policy is left not set, 'BlockPopups' will be used and the user will be able to change it.''', @@ -2781,6 +2950,7 @@ 'example_value': 2, 'id': 53, 'caption': '''Default notification setting''', + 'tags': [], 'desc': '''Allows you to set whether websites are allowed to display desktop notifications. Displaying desktop notifications can be allowed by default, denied by default or the user can be asked every time a website wants to show desktop notifications. If this policy is left not set, 'AskNotifications' will be used and the user will be able to change it.''', @@ -2817,6 +2987,7 @@ 'example_value': 0, 'id': 54, 'caption': '''Default geolocation setting''', + 'tags': ['website-sharing'], 'desc': '''Allows you to set whether websites are allowed to track the users' physical location. Tracking the users' physical location can be allowed by default, denied by default or the user can be asked every time a website requests the physical location. If this policy is left not set, 'AskGeolocation' will be used and the user will be able to change it.''', @@ -2849,6 +3020,7 @@ 'example_value': 2, 'id': 149, 'caption': '''Default mediastream setting''', + 'tags': ['website-sharing'], 'desc': '''Allows you to set whether websites are allowed to get access to media capture devices. Access to media capture devices can be allowed by default, or the user can be asked every time a website wants to get access to media capture devices. If this policy is left not set, 'PromptOnAccess' will be used and the user will be able to change it.''', @@ -2868,6 +3040,7 @@ 'example_value': ["{\\\"pattern\\\":\\\"https://www.example.com\\\",\\\"filter\\\":{\\\"ISSUER\\\":{\\\"CN\\\":\\\"certificate issuer name\\\"}}}"], 'id': 102, 'caption': '''Automatically select client certificates for these sites''', + 'tags': ['website-sharing'], 'desc': '''Allows you to specify a list of url patterns that specify sites for which <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> should automatically select a client certificate, if the site requests a certificate. The value must be an array of stringified JSON dictionaries. Each dictionary must have the form { "pattern": "$URL_PATTERN", "filter" : $FILTER }, where $URL_PATTERN is a content setting pattern. $FILTER restricts from which client certificates the browser will automatically select. Independent of the filter, only certificates will be selected that match the server's certificate request. If $FILTER has the form { "ISSUER": { "CN": "$ISSUER_CN" } }, additionally only client certificates are selected that are issued by a certificate with the CommonName $ISSUER_CN. If $FILTER is the empty dictionary {}, the selection of client certificates is not additionally restricted. @@ -2894,6 +3067,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 77, 'caption': '''Allow cookies on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to set cookies. If this policy is left not set the global default value will be used for all sites either from the 'DefaultCookiesSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -2918,6 +3092,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 67, 'caption': '''Block cookies on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to set cookies. If this policy is left not set the global default value will be used for all sites either from the 'DefaultCookiesSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -2942,6 +3117,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 68, 'caption': '''Allow session only cookies on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to set session only cookies. If this policy is left not set the global default value will be used for all sites either from the 'DefaultCookiesSetting' policy if it is set, or the user's personal configuration otherwise. @@ -2965,6 +3141,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 69, 'caption': '''Allow images on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to display images. If this policy is left not set the global default value will be used for all sites either from the 'DefaultImagesSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -2984,6 +3161,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 70, 'caption': '''Block images on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to display images. If this policy is left not set the global default value will be used for all sites either from the 'DefaultImagesSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3003,6 +3181,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 71, 'caption': '''Allow JavaScript on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to run JavaScript. If this policy is left not set the global default value will be used for all sites either from the 'DefaultJavaScriptSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3022,6 +3201,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 72, 'caption': '''Block JavaScript on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to run JavaScript. If this policy is left not set the global default value will be used for all sites either from the 'DefaultJavaScriptSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3041,6 +3221,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 73, 'caption': '''Allow plugins on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to run plugins. If this policy is left not set the global default value will be used for all sites either from the 'DefaultPluginsSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3060,6 +3241,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 74, 'caption': '''Block plugins on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to run plugins. If this policy is left not set the global default value will be used for all sites either from the 'DefaultPluginsSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3084,6 +3266,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 75, 'caption': '''Allow popups on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to open popups. If this policy is left not set the global default value will be used for all sites either from the 'DefaultPopupsSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3122,6 +3305,7 @@ 'example_value': [{'protocol': 'mailto', 'url': 'https://mail.google.com/mail/?extsrc=mailto&url=%s', 'default': True}], 'id': 268, 'caption': '''Register protocol handlers''', + 'tags': [], 'desc': '''Allows you to register a list of protocol handlers. This can only be a recommended policy. The property |protocol| should be set to the scheme such as 'mailto' and the property |url| should be set to the URL pattern of the application that handles the scheme. The pattern can include a '%s', which if present will be replaced by the handled URL. The protocol handlers registered by policy are merged with the ones registered by the user and both are available for use. The user can override the protocol handlers installed by policy by installing a new default handler, but cannot remove a protocol handler registered by policy.''', @@ -3146,6 +3330,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 76, 'caption': '''Block popups on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to open popups. If this policy is left not set the global default value will be used for all sites either from the 'DefaultPopupsSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3165,6 +3350,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 105, 'caption': '''Allow notifications on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to display notifications. If this policy is left not set the global default value will be used for all sites either from the 'DefaultNotificationsSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3184,6 +3370,7 @@ 'example_value': ['https://www.example.com', '[*.]example.edu'], 'id': 106, 'caption': '''Block notifications on these sites''', + 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to display notifications. If this policy is left not set the global default value will be used for all sites either from the 'DefaultNotificationsSetting' policy if it is set, or the user's personal configuration otherwise.''', @@ -3214,6 +3401,7 @@ ], 'id': 251, 'caption': '''Configure native messaging blacklist''', + 'tags': [], 'desc': '''Allows you to specify which native messaging hosts that should not be loaded. A blacklist value of '*' means all native messaging hosts are blacklisted unless they are explicitly listed in the whitelist. @@ -3239,6 +3427,7 @@ ], 'id': 252, 'caption': '''Configure native messaging whitelist''', + 'tags': [], 'desc': '''Allows you to specify which native messaging hosts are not subject to the blacklist. A blacklist value of * means all native messaging hosts are blacklisted and only native messaging hosts listed in the whitelist will be loaded. @@ -3258,6 +3447,7 @@ 'example_value': False, 'id': 253, 'caption': '''Allow user-level Native Messaging hosts (installed without admin permissions).''', + 'tags': [], 'desc': '''Enables user-level installation of Native Messaging hosts. If this setting is enabled then <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> allows @@ -3283,6 +3473,7 @@ 'example_value': False, 'id': 55, 'caption': '''Disable support for 3D graphics APIs''', + 'tags': [], 'desc': '''Disable support for 3D graphics APIs. Enabling this setting prevents web pages from accessing the graphics processing unit (GPU). Specifically, web pages can not access the WebGL API and plugins can not use the Pepper 3D API. @@ -3303,6 +3494,7 @@ 'example_value': 3600000, 'id': 56, 'caption': '''Refresh rate for user policy''', + 'tags': [], 'desc': '''Specifies the period in milliseconds at which the device management service is queried for user policy information. Setting this policy overrides the default value of 3 hours. Valid values for this policy are in the range from 1800000 (30 minutes) to 86400000 (1 day). Any values not in this range will be clamped to the respective boundary. @@ -3321,6 +3513,7 @@ 'example_value': 10000, 'id': 228, 'caption': '''Maximum fetch delay after a policy invalidation''', + 'tags': [], 'desc': '''Specifies the maximum delay in milliseconds between receiving a policy invalidation and fetching the new policy from the device management service. Setting this policy overrides the default value of 5000 milliseconds. Valid values for this policy are in the range from 1000 (1 second) to 300000 (5 minutes). Any values not in this range will be clamped to the respective boundary. @@ -3362,6 +3555,7 @@ 'example_value': 1, 'id': 57, 'caption': '''Default HTML renderer for <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph>''', + 'tags': [], 'desc': '''Allows you to configure the default HTML renderer when <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> is installed. The default setting used when this policy is left not set is to allow the host browser do the rendering, but you can optionally override this and have <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> render HTML pages by default.''', }, @@ -3379,6 +3573,7 @@ 'example_value': ['https://www.example.com', 'https://www.example.edu'], 'id': 58, 'caption': '''Always render the following URL patterns in <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph>''', + 'tags': [], 'desc': '''Customize the list of URL patterns that should always be rendered by <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph>. If this policy is not set the default renderer will be used for all sites as specified by the 'ChromeFrameRendererSettings' policy. @@ -3399,6 +3594,7 @@ 'example_value': ['https://www.example.com', 'https://www.example.edu'], 'id': 59, 'caption': '''Always render the following URL patterns in the host browser''', + 'tags': [], 'desc': '''Customize the list of URL patterns that should always be rendered by the host browser. If this policy is not set the default renderer will be used for all sites as specified by the 'ChromeFrameRendererSettings' policy. @@ -3416,6 +3612,7 @@ 'example_value': '--enable-media-stream --enable-media-source', 'id': 141, 'caption': '''Additional command line parameters for <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>''', + 'tags': [], 'desc': '''Allows you to specify additional parameters that are used when <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> launches <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If this policy is not set the default command line will be used.''', @@ -3431,6 +3628,7 @@ 'example_value': False, 'id': 238, 'caption': '''Skip the meta tag check in <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph>''', + 'tags': [], 'desc': '''Normally pages with X-UA-Compatible set to chrome=1 will be rendered in <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> regardless of the 'ChromeFrameRendererSettings' policy. If you enable this setting, pages will not be scanned for meta tags. @@ -3461,6 +3659,7 @@ 'example_value': ['text/xml', 'application/xml'], 'id': 60, 'caption': '''Allow <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> to handle the listed content types''', + 'tags': [], 'desc': '''Allow <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> to handle the listed content types. If this policy is not set the default renderer will be used for all sites as specified by the 'ChromeFrameRendererSettings' policy.''', @@ -3480,6 +3679,7 @@ 'example_value': True, 'id': 61, 'caption': '''Enable lock when the device become idle or suspended''', + 'tags': [], 'desc': '''Enable lock when <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices become idle or suspended. If you enable this setting, users will be asked for a password to unlock the device from sleep. @@ -3527,6 +3727,7 @@ 'default_for_enterprise_users': 'primary-only', 'id': 244, 'caption': '''Control the user behavior in a multiprofile session''', + 'tags': [], 'desc': '''Control the user behavior in a multiprofile session on <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices. If this policy is set to 'MultiProfileUserBehaviorUnrestricted', the user can be either primary or secondary user in a multiprofile session. @@ -3555,6 +3756,7 @@ 'example_value': True, 'id': 62, 'caption': '''Enable Instant''', + 'tags': [], 'desc': '''Enables <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s Instant feature and prevents users from changing this setting. If you enable this setting, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> Instant is enabled. @@ -3585,6 +3787,7 @@ 'example_value': True, 'id': 80, 'caption': '''Enable Translate''', + 'tags': [], 'desc': '''Enables the integrated Google Translate service on <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If you enable this setting, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will show an integrated toolbar offering to translate the page for the user, when appropriate. @@ -3607,6 +3810,7 @@ 'example_value': True, 'id': 81, 'caption': '''Allow running plugins that are outdated''', + 'tags': ['system-security'], 'desc': '''Allows <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to run plugins that are outdated. If you enable this setting, outdated plugins are used as normal plugins. @@ -3627,6 +3831,7 @@ 'example_value': True, 'id': 86, 'caption': '''Always runs plugins that require authorization''', + 'tags': ['system-security'], 'desc': '''Allows <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to run plugins that require authorization. If you enable this setting, plugins that are not outdated always run. @@ -3646,6 +3851,7 @@ 'example_value': True, 'id': 82, 'caption': '''Enable Bookmark Bar''', + 'tags': [], 'desc': '''Enables the bookmark bar on <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If you enable this setting, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will show a bookmark bar. @@ -3668,6 +3874,7 @@ 'example_value': False, 'id': 83, 'caption': '''Enables or disables bookmark editing''', + 'tags': [], 'desc': '''Enables or disables editing bookmarks in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If you enable this setting, bookmarks can be added, removed or modified. This is the default also when this policy is not set. @@ -3686,6 +3893,7 @@ 'example_value': False, 'id': 267, 'caption': '''Show the apps shortcut in the bookmark bar''', + 'tags': [], 'desc': '''Enables or disables the apps shortcut in the bookmark bar. If this policy is not set then the user can choose to show or hide the apps shortcut from the bookmark bar context menu. @@ -3704,6 +3912,7 @@ 'example_value': True, 'id': 84, 'caption': '''Allow invocation of file selection dialogs''', + 'tags': [], 'desc': '''Allows access to local files on the machine by allowing <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to display file selection dialogs. If you enable this setting, users can open file selection dialogs as normal. @@ -3723,6 +3932,7 @@ 'example_value': '${user_home}/Chrome Frame', 'id': 87, 'caption': '''Set <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> user data directory''', + 'tags': [], 'desc': '''Configures the directory that <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> will use for storing user data. If you set this policy, <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> will use the provided directory. @@ -3744,6 +3954,7 @@ 'example_value': 3600000, 'id': 90, 'caption': '''Refresh rate for Device Policy''', + 'tags': [], 'desc': '''Specifies the period in milliseconds at which the device management service is queried for device policy information. Setting this policy overrides the default value of 3 hours. Valid values for this policy are in the range from 1800000 (30 minutes) to 86400000 (1 day). Any values not in this range will be clamped to the respective boundary. @@ -3763,6 +3974,7 @@ 'example_value': True, 'id': 97, 'caption': '''Import bookmarks from default browser on first run''', + 'tags': ['local-data-access'], 'desc': '''This policy forces bookmarks to be imported from the current default browser if enabled. If enabled, this policy also affects the import dialog. If disabled, no bookmarks are imported. @@ -3783,6 +3995,7 @@ 'example_value': True, 'id': 98, 'caption': '''Import browsing history from default browser on first run''', + 'tags': ['local-data-access'], 'desc': '''This policy forces the browsing history to be imported from the current default browser if enabled. If enabled, this policy also affects the import dialog. If disabled, no browsing history is imported. @@ -3802,6 +4015,7 @@ 'example_value': True, 'id': 99, 'caption': '''Import of homepage from default browser on first run''', + 'tags': ['local-data-access'], 'desc': '''This policy forces the home page to be imported from the current default browser if enabled. If disabled, the home page is not imported. @@ -3822,6 +4036,7 @@ 'example_value': True, 'id': 100, 'caption': '''Import search engines from default browser on first run''', + 'tags': ['local-data-access'], 'desc': '''This policy forces search engines to be imported from the current default browser if enabled. If enabled, this policy also affects the import dialog. If disabled, the default search engine is not imported. @@ -3842,6 +4057,7 @@ 'example_value': True, 'id': 101, 'caption': '''Import saved passwords from default browser on first run''', + 'tags': ['local-data-access'], 'desc': '''This policy forces the saved passwords to be imported from the previous default browser if enabled. If enabled, this policy also affects the import dialog. If disabled, the saved passwords are not imported. @@ -3862,6 +4078,7 @@ 'example_value': True, 'id': 277, 'caption': '''Import autofill form data from default browser on first run''', + 'tags': ['local-data-access'], 'desc': '''This policy forces the autofill form data to be imported from the previous default browser if enabled. If enabled, this policy also affects the import dialog. If disabled, the autofill form data is not imported. @@ -3881,6 +4098,7 @@ 'example_value': 32, 'id': 92, 'caption': '''Maximal number of concurrent connections to the proxy server''', + 'tags': [], 'desc': '''Specifies the maximal number of simultaneous connections to the proxy server. Some proxy servers can not handle high number of concurrent connections per client and this can be solved by setting this policy to a lower value. @@ -3903,6 +4121,7 @@ 'example_value': False, 'id': 96, 'caption': '''Prevent app promotions from appearing on the new tab page''', + 'tags': [], 'desc': '''When set to True, promotions for Chrome Web Store apps will not appear on the new tab page. Setting this option to False or leaving it not set will make the promotions for Chrome Web Store apps appear on the new tab page''', @@ -3927,6 +4146,7 @@ 'example_value': ['example.com', 'https://ssl.server.com', 'hosting.com/bad_path', 'https://server:8080/path', '.exact.hostname.com', 'file://*', '*'], 'id': 103, 'caption': '''Block access to a list of URLs''', + 'tags': ['filtering'], 'desc': '''Blocks access to the listed URLs. This policy prevents the user from loading web pages from blacklisted URLs. The blacklist provides a list of URL patterns that specify which URLs will be blacklisted. @@ -3963,6 +4183,7 @@ 'example_value': ['example.com', 'https://ssl.server.com', 'hosting.com/bad_path', 'https://server:8080/path', '.exact.hostname.com'], 'id': 104, 'caption': '''Allows access to a list of URLs''', + 'tags': [], 'desc': '''Allows access to the listed URLs, as exceptions to the URL blacklist. See the description of the URL blacklist policy for the format of entries of this list. @@ -3987,6 +4208,7 @@ 'example_value': '{ "NetworkConfigurations": [ { "GUID": "{4b224dfd-6849-7a63-5e394343244ae9c9}", "Name": "my WiFi", "Type": "WiFi", "WiFi": { "SSID": "my WiFi", "HiddenSSID": false, "Security": "None", "AutoConnect": true } } ] }', 'id': 107, 'caption': '''User-level network configuration''', + 'tags': ['full-admin-access'], 'desc': '''Allows pushing network configuration to be applied per-user to a <ph name="PRODUCT_OS_NAME">$2<ex>Chromium OS</ex></ph> device. The network configuration is a JSON-formatted string as defined by the Open Network Configuration format described at <ph name="ONC_SPEC_URL">https://sites.google.com/a/chromium.org/dev/chromium-os/chromiumos-design-docs/open-network-configuration</ph>''', }, { @@ -4001,6 +4223,7 @@ 'example_value': '{ "NetworkConfigurations": [ { "GUID": "{4b224dfd-6849-7a63-5e394343244ae9c9}", "Name": "my WiFi", "Type": "WiFi", "WiFi": { "SSID": "my WiFi", "HiddenSSID": false, "Security": "None", "AutoConnect": true } } ] }', 'id': 108, 'caption': '''Device-level network configuration''', + 'tags': ['full-admin-access'], 'desc': '''Allows pushing network configuration to be applied for all users of a <ph name="PRODUCT_OS_NAME">$2<ex>Chromium OS</ex></ph> device. The network configuration is a JSON-formatted string as defined by the Open Network Configuration format described at <ph name="ONC_SPEC_URL">https://sites.google.com/a/chromium.org/dev/chromium-os/chromiumos-design-docs/open-network-configuration</ph>''', }, { @@ -4015,6 +4238,7 @@ 'example_value': True, 'id': 109, 'caption': '''Enable submission of documents to <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph>''', + 'tags': [], 'desc': '''Enables <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to submit documents to <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> for printing. NOTE: This only affects <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> support in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. It does not prevent users from submitting print jobs on web sites. If this setting is enabled or not configured, users can print to <ph name="CLOUD_PRINT_NAME">Google Cloud Print</ph> from the <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> print dialog. @@ -4034,6 +4258,7 @@ 'example_value': 'https://company-intranet/chromeapps', 'id': 112, 'caption': '''Enterprise web store URL (deprecated)''', + 'tags': [], 'desc': '''This setting has been retired as of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> version 29. The recommended way to set up organization-hosted extension/app collections is to include the site hosting the CRX packages in ExtensionInstallSources and put direct download links to the packages on a web page. A launcher for that web page can be created using the ExtensionInstallForcelist policy.''', }, { @@ -4049,6 +4274,7 @@ 'example_value': 'WidgCo Chrome Apps', 'id': 113, 'caption': '''Enterprise web store name (deprecated)''', + 'tags': [], 'desc': '''This setting has been retired as of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> version 29. The recommended way to set up organization-hosted extension/app collections is to include the site hosting the CRX packages in ExtensionInstallSources and put direct download links to the packages on a web page. A launcher for that web page can be created using the ExtensionInstallForcelist policy.''', }, { @@ -4065,6 +4291,7 @@ 'example_value': True, 'id': 114, 'caption': '''Enable TLS domain-bound certificates extension (deprecated)''', + 'tags': [], 'desc': '''This policy has been retired as of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> version 36. Specifies whether the TLS domain-bound certificates extension should be enabled. @@ -4085,6 +4312,7 @@ 'example_value': False, 'id': 115, 'caption': '''Enable reporting memory info (JS heap size) to page (deprecated)''', + 'tags': [], 'desc': '''This policy has been retired as of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> version 35. Memory info is anyway reported to page, regardless of the option value, but the sizes reported are @@ -4104,6 +4332,7 @@ 'example_value': False, 'id': 117, 'caption': '''Disable Print Preview (deprecated)''', + 'tags': [], 'desc': '''Show the system print dialog instead of print preview. When this setting is enabled, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will open the system print dialog instead of the built-in print preview when a user requests a page to be printed. @@ -4122,6 +4351,7 @@ 'example_value': True, 'id': 118, 'caption': '''Disable TLS False Start''', + 'tags': [], 'desc': '''Specifies whether the TLS False Start optimization should be disabled. For historical reasons, this policy is named DisableSSLRecordSplitting. If the policy is not set, or is set to false, then TLS False Start will be enabled. If it is set to true, TLS False Start will be disabled.''', @@ -4138,6 +4368,7 @@ 'example_value': False, 'id': 129, 'caption': '''Whether online OCSP/CRL checks are performed''', + 'tags': ['website-sharing'], 'desc': '''In light of the fact that soft-fail, online revocation checks provide no effective security benefit, they are disabled by default in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> version 19 and later. By setting this policy to true, the previous behavior is restored and online OCSP/CRL checks will be performed. If the policy is not set, or is set to false, then <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will not perform online revocation checks in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> 19 and later.''', @@ -4154,6 +4385,7 @@ 'example_value': False, 'id': 235, 'caption': '''Whether online OCSP/CRL checks are required for local trust anchors''', + 'tags': [], 'desc': '''When this setting is enabled, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will always perform revocation checking for server certificates that successfully validate and are signed by locally-installed CA certificates. If <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is unable to obtain revocation status information, such certificates will be treated as revoked ('hard-fail'). @@ -4172,6 +4404,7 @@ 'example_value': True, 'id': 245, 'caption': '''Ephemeral profile''', + 'tags': [], 'desc': '''If set to enabled this policy forces the profile to be switched to ephemeral mode. If this policy is specified as an OS policy (e.g. GPO on Windows) it will apply to every profile on the system; if the policy is set as a Cloud policy it will apply only to a profile signed in with a managed account. In this mode the profile data is persisted on disk only for the length of the user session. Features like browser history, extensions and their data, web data like cookies and web databases are not preserved after the browser is closed. However this does not prevent the user from downloading any data to disk manually, save pages or print them. @@ -4192,6 +4425,7 @@ 'example_value': 32, 'id': 254, 'caption': '''Limit the time for which a user authenticated via SAML can log in offline''', + 'tags': [], 'desc': '''Limit the time for which a user authenticated via SAML can log in offline. During login, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can authenticate against a server (online) or using a cached password (offline). @@ -4232,6 +4466,7 @@ 'example_value': 'remove-lru', 'id': 246, 'caption': '''Selects the strategy used to free up disk space during automatic clean-up (deprecated)''', + 'tags': [], 'desc': '''This policy is deprecated. <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will always use the 'RemoveLRU' clean-up strategy. Controls the automatic clean-up behavior on <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices. Automatic clean-up is triggered when the amount of free disk space reaches a critical level to recover some disk space. @@ -4254,6 +4489,7 @@ 'example_value': False, 'id': 119, 'caption': '''Report OS and firmware version''', + 'tags': ['admin-sharing'], 'desc': '''Report OS and firmware version of enrolled devices. If this setting is not set or set to True, enrolled devices will report the OS and firmware version periodically. If this setting is set to False, version info will not be reported.''', @@ -4270,6 +4506,7 @@ 'example_value': False, 'id': 120, 'caption': '''Report device activity times''', + 'tags': ['admin-sharing'], 'desc': '''Report device activity times. If this setting is not set or set to True, enrolled devices will report time periods when a user is active on the device. If this setting is set to False, device activity times will not be recorded or reported.''', @@ -4286,6 +4523,7 @@ 'example_value': False, 'id': 121, 'caption': '''Report device boot mode''', + 'tags': ['admin-sharing'], 'desc': '''Report the state of the device's dev switch at boot. If the policy is set to false, the state of the dev switch will not be reported.''', @@ -4303,6 +4541,7 @@ 'example_value': False, 'id': 143, 'caption': '''Report device location''', + 'tags': ['admin-sharing'], 'desc': '''Report the geographic location of the device. If the policy is not set, or set to false, the location will not be reported.''', @@ -4319,6 +4558,7 @@ 'example_value': False, 'id': 224, 'caption': '''Report device network interfaces''', + 'tags': ['admin-sharing'], 'desc': '''Report list of network interfaces with their types and hardware addresses to the server. If the policy is set to false, the interface list will not be reported.''', @@ -4335,6 +4575,7 @@ 'example_value': False, 'id': 248, 'caption': '''Report device users''', + 'tags': ['admin-sharing'], 'desc': '''Report list of device users that have recently logged in. If the policy is set to false, the users will not be reported.''', @@ -4351,6 +4592,7 @@ 'example_value': False, 'id': 290, 'caption': '''Report hardware status''', + 'tags': ['admin-sharing'], 'desc': '''Report hardware statistics such as CPU/RAM usage. If the policy is set to false, the statistics will not be reported. @@ -4368,6 +4610,7 @@ 'example_value': False, 'id': 291, 'caption': '''Report information about active kiosk sessions''', + 'tags': ['admin-sharing'], 'desc': '''Report information about the active kiosk session, such as application ID and version. @@ -4387,6 +4630,7 @@ 'example_value': 180000, 'id': 292, 'caption': '''Frequency of device status report uploads''', + 'tags': ['admin-sharing'], 'desc': '''How frequently device status uploads are sent, in milliseconds. If this policy is unset, the default frequency is 3 hours. The minimum @@ -4404,6 +4648,7 @@ 'example_value': False, 'id': 293, 'caption': '''Send monitoring heartbeats to the management server''', + 'tags': ['admin-sharing'], 'desc': '''Send monitoring heartbeats to the management server, to allow the server to detect if the device is offline. @@ -4422,6 +4667,7 @@ 'example_value': 180000, 'id': 294, 'caption': '''Frequency of monitoring heartbeats''', + 'tags': [], 'desc': '''How frequently monitoring heartbeats are sent, in milliseconds. If this policy is unset, the default frequency is 3 minutes. The minimum @@ -4440,6 +4686,7 @@ 'example_value': False, 'id': 306, 'caption': '''Send system logs to the management server''', + 'tags': [], 'desc': '''Send system logs to the management server, to allow admins to monitor system logs. @@ -4461,6 +4708,7 @@ 'example_value': [ 'madmax@managedchrome.com' ], 'id': 122, 'caption': '''Login user white list''', + 'tags': [], 'desc': '''Defines the list of users that are allowed to login to the device. Entries are of the form <ph name="USER_WHITELIST_ENTRY_FORMAT">user@domain</ph>, such as <ph name="USER_WHITELIST_ENTRY_EXAMPLE">madmax@managedchrome.com</ph>. To allow arbitrary users on a domain, use entries of the form <ph name="USER_WHITELIST_ENTRY_WILDCARD">*@domain</ph>. If this policy is not configured, there are no restrictions on which users are allowed to sign in. Note that creating new users still requires the <ph name="DEVICEALLOWNEWUSERS_POLICY_NAME">DeviceAllowNewUsers</ph> policy to be configured appropriately.''', @@ -4477,6 +4725,7 @@ 'example_value': True, 'id': 123, 'caption': '''Allow creation of new user accounts''', + 'tags': [], 'desc': '''Controls whether <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> allows new user accounts to be created. If this policy is set to false, users that do not have an account already will not be able to login. If this policy is set to true or not configured, new user accounts will be allowed to be created provided that <ph name="DEVICEUSERWHITELISTPROTO_POLICY_NAME">DeviceUserWhitelist</ph> does not prevent the user from logging in.''', @@ -4493,6 +4742,7 @@ 'example_value': True, 'id': 124, 'caption': '''Enable guest mode''', + 'tags': [], 'desc': '''If this policy is set to true or not configured, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will enable guest logins. Guest logins are anonymous user sessions and do not require a password. If this policy is set to false, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will not allow guest sessions to be started.''', @@ -4509,6 +4759,7 @@ 'example_value': True, 'id': 125, 'caption': '''Show usernames on login screen''', + 'tags': [], 'desc': '''If this policy is set to true or not configured, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will show existing users on the login screen and allow to pick one. If this policy is set to false, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will use the username/password prompt for login.''', }, { @@ -4523,6 +4774,7 @@ 'example_value': True, 'id': 126, 'caption': '''Enable data roaming''', + 'tags': [], 'desc': '''Determines whether data roaming should be enabled for the device. If set to true, data roaming is allowed. If left unconfigured or set to false, data roaming will be not available.''', }, { @@ -4537,6 +4789,7 @@ 'example_value': True, 'id': 127, 'caption': '''Enable metrics reporting''', + 'tags': ['admin-sharing'], 'desc': '''Controls whether usage metrics are reported back to Google. If set to true, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will report usage metrics. If not configured or set to false, metrics reporting will be disabled.''', }, { @@ -4571,6 +4824,7 @@ 'example_value': 'stable-channel', 'id': 91, 'caption': '''Release channel''', + 'tags': [], 'desc': '''Specifies the release channel that this device should be locked to.''', }, { @@ -4585,6 +4839,7 @@ 'example_value': False, 'id': 134, 'caption': '''Whether the release channel should be configurable by the user''', + 'tags': [], 'desc': '''If this policy is set to True and the ChromeOsReleaseChannel policy is not specified then users of the enrolling domain will be allowed to change the release channel of the device. If this policy is set to false the device will be locked in whatever channel it was last set. The user selected channel will be overridden by the ChromeOsReleaseChannel policy, but if the policy channel is more stable than the one that was installed on the device, then the channel will only switch after the version of the more stable channel reaches a higher version number than the one installed on the device.''', @@ -4601,6 +4856,7 @@ 'example_value': True, 'id': 128, 'caption': '''Wipe user data on sign-out''', + 'tags': [], 'desc': '''Determines whether <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> keeps local account data after logout. If set to true, no persistent accounts are kept by <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> and all data from the user session will be discarded after logout. If this policy is set to false or not configured, the device may keep (encrypted) local user data.''', }, { @@ -4618,6 +4874,7 @@ 'example_value': [ 'https://google.com', 'chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaa/' ], 'id': 137, 'caption': '''Load specified urls on demo login''', + 'tags': [], 'desc': '''This policy is active in retail mode only. Determines the set of URLs to be loaded when the demo session is started. This policy will override any other mechanisms for setting the initial URL and thus can only be applied to a session not associated with a particular user.''', @@ -4634,6 +4891,7 @@ 'example_value': 60000, 'id': 130, 'caption': '''Timeout until idle user log-out is executed''', + 'tags': [], 'desc': '''This policy is active in retail mode only. When the value of this policy is set and is not 0 then the currently logged in demo user will be logged out automatically after an inactivity time of the specified duration has elapsed. @@ -4652,6 +4910,7 @@ 'example_value': 15000, 'id': 131, 'caption': '''Duration of the idle log-out warning message''', + 'tags': [], 'desc': '''This policy is active in retail mode only. When DeviceIdleLogoutTimeout is specified this policy defines the duration of the warning box with a count down timer that is shown to the user before the logout is executed. @@ -4670,6 +4929,7 @@ 'example_value': 'fhblcfnmnbehmifidkddcenilbpddlfk', 'id': 132, 'caption': '''Screen saver to be used on the sign-in screen in retail mode''', + 'tags': [], 'desc': '''This policy is active in retail mode only. Determines the id of the extension to be used as a screen saver on the sign-in screen. The extension must be part of the AppPack that is configured for this domain through the DeviceAppPack policy.''', @@ -4686,6 +4946,7 @@ 'example_value': 120000, 'id': 133, 'caption': '''Duration of inactivity before the screen saver is shown on the sign-in screen in retail mode''', + 'tags': [], 'desc': '''This policy is active in retail mode only. Determines the duration before the screen saver is shown on the sign-in screen for devices in retail mode. @@ -4707,6 +4968,7 @@ 'example_value': [ { "extension-id": "khgabmflimjjbclkmljlpmgaleanedem", "update-url": "https://clients2.google.com/service/update2/crx" } ], 'id': 135, 'caption': '''List of AppPack extensions''', + 'tags': [], 'desc': '''This policy is active in retail mode only. Lists extensions that are automatically installed for the Demo user, for devices in retail mode. These extensions are saved in the device and can be installed while offline, after the installation. @@ -4725,6 +4987,7 @@ 'example_value': True, 'id': 136, 'caption': '''Disables Auto Update''', + 'tags': ['system-security'], 'desc': '''Disables automatic updates when set to True. <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices automatically check for updates when this setting is not configured or set to False.''', @@ -4741,6 +5004,7 @@ 'example_value': False, 'id': 242, 'caption': '''Auto update p2p enabled''', + 'tags': [], 'desc': '''Specifies whether p2p is to be used for OS update payloads. If set to True, devices will share and attempt to consume update payloads on the LAN, potentially reducing Internet bandwidth usage and congestion. If the update payload is not available on the LAN, the device will fall back to downloading from an update server. If set to False or not configured, p2p will not be used.''', }, { @@ -4755,6 +5019,7 @@ 'example_value': '1412.', 'id': 142, 'caption': '''Target Auto Update Version''', + 'tags': ['system-security'], 'desc': '''Sets a target version for Auto Updates. Specifies the prefix of a target version <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> should update to. If the device is running a version that's before the specified prefix, it will update to the latest version with the given prefix. If the device is already on a later version, there is no effect (i.e. no downgrades are performed) and the device will remain on the current version. The prefix format works component-wise as is demonstrated in the following example: @@ -4776,6 +5041,7 @@ 'example_value': 7200, 'id': 145, 'caption': '''Auto update scatter factor''', + 'tags': ['system-security'], 'desc': '''Specifies the number of seconds up to which a device may randomly delay its download of an update from the time the update was first pushed out to the server. The device may wait a portion of this time in terms of wall-clock-time and the remaining portion in terms of the number of update checks. In any case, the scatter is upper bounded to a constant amount of time so that a device does not ever get stuck waiting to download an update forever.''', }, { @@ -4793,6 +5059,7 @@ 'example_value': [ 'ethernet' ], 'id': 146, 'caption': '''Connection types allowed for updates''', + 'tags': [], 'desc': ''' The types of connections that are allowed to use for OS updates. OS updates potentially put heavy strain on the connection due to their size and may incur additional cost. Therefore, they are by default not enabled for connection types that are considered expensive, which include WiMax, Bluetooth and Cellular at the moment. The recognized connection type identifiers are "ethernet", "wifi", "wimax", "bluetooth" and "cellular".''', @@ -4811,6 +5078,7 @@ 'example_value': True, 'id': 243, 'caption': '''Allow autoupdate downloads via HTTP''', + 'tags': [], 'desc': '''Auto-update payloads on <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can be downloaded via HTTP instead of HTTPS. This allows transparent HTTP caching of HTTP downloads. If this policy is set to true, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will attempt to download auto-update payloads via HTTP. If the policy is set to false or not set, HTTPS will be used for downloading auto-update payloads.''', @@ -4830,6 +5098,7 @@ 'example_value': [ "demo@example.com" ], 'id': 163, 'caption': '''Device-local accounts''', + 'tags': [], 'desc': '''Specifies the list of device-local accounts to be shown on the login screen. Every list entry specifies an identifier, which is used internally to tell the different device-local accounts apart.''', @@ -4846,6 +5115,7 @@ 'example_value': "public@example.com", 'id': 194, 'caption': '''Public session for auto-login''', + 'tags': [], 'desc': '''A public session to auto-login after a delay. If this policy is set, the specified session will be automatically logged in after a period of time has elapsed at the login screen without user interaction. The public session must already be configured (see |DeviceLocalAccounts|). @@ -4864,6 +5134,7 @@ 'example_value': 180000, 'id': 195, 'caption': '''Public session auto-login timer''', + 'tags': [], 'desc': '''The public session auto-login delay. If the |DeviceLocalAccountAutoLoginId| policy is unset, this policy has no effect. Otherwise: @@ -4886,6 +5157,7 @@ 'example_value': True, 'id': 202, 'caption': '''Enable bailout keyboard shortcut for auto-login''', + 'tags': [], 'desc': '''Enable bailout keyboard shortcut for auto-login. If this policy is unset or set to True and a device-local account is configured for zero-delay auto-login, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will honor the keyboard shortcut Ctrl+Alt+S for bypassing auto-login and showing the login screen. @@ -4904,6 +5176,7 @@ 'example_value': True, 'id': 250, 'caption': '''Enable network configuration prompt when offline''', + 'tags': [], 'desc': '''Enable network configuration prompt when offline. If this policy is unset or set to True and a device-local account is configured for zero-delay auto-login and the device does not have access to the Internet, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will show a network configuration prompt. @@ -4922,6 +5195,7 @@ 'example_value': True, 'id': 266, 'caption': '''Block developer mode''', + 'tags': [], 'desc': '''Block developer mode. If this policy is set to True, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will prevent the device from booting into developer mode. The system will refuse to boot and show an error screen when the developer switch is turned on. @@ -4941,6 +5215,7 @@ 'example_value': True, 'id': 138, 'caption': '''Continue running background apps when <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is closed''', + 'tags': ['system-security'], 'desc': '''Determines whether a <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> process is started on OS login and keeps running when the last browser window is closed, allowing background apps and the current browsing session to remain active, including any session cookies. The background process displays an icon in the system tray and can always be closed from there. If this policy is set to True, background mode is enabled and cannot be controlled by the user in the browser settings. @@ -4967,6 +5242,7 @@ 'example_value': True, 'id': 139, 'caption': '''Disables Drive in the <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> Files app''', + 'tags': [], 'desc': '''Disables Google Drive syncing in the <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> Files app when set to True. In that case, no data is uploaded to Google Drive. If not set or set to False, then users will be able to transfer files to Google Drive.''', @@ -4983,6 +5259,7 @@ 'example_value': True, 'id': 140, 'caption': '''Disables Google Drive over cellular connections in the <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> Files app''', + 'tags': [], 'desc': '''Disables Google Drive syncing in the <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> Files app when using a cellular connection when set to True. In that case, data is only synced to Google Drive when connected via WiFi or Ethernet. If not set or set to False, then users will be able to transfer files to Google Drive via cellular connections.''', @@ -5005,6 +5282,7 @@ 'example_value': ['pjkljhegncpnkpknbcohdijeoejaedia'], 'id': 144, 'caption': '''List of pinned apps to show in the launcher''', + 'tags': [], 'desc': '''Lists the application identifiers <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> shows as pinned apps in the launcher bar. If this policy is configured, the set of applications is fixed and can't be changed by the user. @@ -5023,6 +5301,7 @@ 'example_value': '*@domain.com', 'id': 147, 'caption': '''Restrict which users are allowed to sign in to <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>''', + 'tags': [], 'desc': '''Contains a regular expression which is used to determine which users can sign in to <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. An appropriate error is displayed if a user tries to log in with a username that does not match this pattern. @@ -5041,6 +5320,7 @@ 'example_value': True, 'id': 150, 'caption': '''Disable proceeding from the Safe Browsing warning page''', + 'tags': [], 'desc': '''The Safe Browsing service shows a warning page when users navigate to sites that are flagged as potentially malicious. Enabling this setting prevents users from proceeding anyway from the warning page to the malicious site. If this setting is disabled or not configured then users can choose to proceed to the flagged site after being shown the warning.''', @@ -5057,6 +5337,7 @@ 'example_value': True, 'id': 299, 'caption': '''Allow users to opt in to Safe Browsing extended reporting''', + 'tags': [], 'desc': '''Setting this policy to false stops users from choosing to send information about security errors they encounter to Google servers. If this setting is true or not configured, then users will be allowed to send information when they encounter an SSL error or Safe Browsing warning.''', }, { @@ -5072,6 +5353,7 @@ 'example_value': False, 'id': 151, 'caption': '''Enable or disable spell checking web service''', + 'tags': [], 'desc': '''<ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> can use a Google web service to help resolve spelling errors. If this setting is enabled, then this service is always used. If this setting is disabled, then this service is never used. Spell checking can still be performed using a downloaded dictionary; this policy only controls the usage of the online service. @@ -5090,6 +5372,7 @@ 'example_value': True, 'id': 152, 'caption': '''Disable mounting of external storage''', + 'tags': [], 'desc': '''Disable mounting of external storage. When this policy is set to true, external storage will not be available in the file browser. @@ -5110,6 +5393,7 @@ 'example_value': False, 'id': 159, 'caption': '''Allow playing audio''', + 'tags': [], 'desc': '''Allow playing audio. When this policy is set to false, audio output will not be available on the device while the user is logged in. @@ -5130,6 +5414,7 @@ 'example_value': False, 'id': 160, 'caption': '''Allow or deny audio capture''', + 'tags': [], 'desc': '''Allow or deny audio capture. If enabled or not configured (default), the user will be prompted for @@ -5156,6 +5441,7 @@ 'example_value': ['https://www.example.com/', 'https://[*.]example.edu/'], 'id': 208, 'caption': '''URLs that will be granted access to audio capture devices without prompt''', + 'tags': ['website-sharing'], 'desc': '''Patterns in this list will be matched against the security origin of the requesting URL. If a match is found, access to audio capture devices will be granted without prompt. @@ -5174,6 +5460,7 @@ 'example_value': False, 'id': 167, 'caption': '''Allow or deny video capture''', + 'tags': [], 'desc': '''Allow or deny video capture. If enabled or not configured (default), the user will be prompted for @@ -5200,6 +5487,7 @@ 'example_value': ['https://www.example.com/', 'https://[*.]example.edu/'], 'id': 209, 'caption': '''URLs that will be granted access to video capture devices without prompt''', + 'tags': ['website-sharing'], 'desc': '''Patterns in this list will be matched against the security origin of the requesting URL. If a match is found, access to audio capture devices will be granted without prompt. @@ -5218,6 +5506,7 @@ 'example_value': True, 'id': 153, 'caption': '''Disable taking screenshots''', + 'tags': [], 'desc': '''Disables taking screenshots. If enabled screenshots cannot be taken using keyboard shortcuts or extension APIs. @@ -5236,6 +5525,7 @@ 'example_value': 'America/Los_Angeles', 'id': 158, 'caption': '''Timezone''', + 'tags': [], 'desc': '''Specifies the timezone to be used for the device. Users can override the specified timezone for the current session. However, on logout it is set back to the specified timezone. If an invalid value is provided, the policy is still activated using "GMT" instead. If an empty string is provided, the policy is ignored. If this policy is not used, the currently active timezone will remain in use however users can change the timezone and the change is persistent. Thus a change by one user affects the login-screen and all other users. @@ -5256,6 +5546,7 @@ 'example_value': True, 'id': 236, 'caption': '''Use 24 hour clock by default''', + 'tags': [], 'desc': '''Specifies the clock format be used for the device. This policy configures the clock format to use on the login screen and as a default for user sessions. Users can still override the clock format for their account. @@ -5276,6 +5567,7 @@ 'example_value': False, 'id': 269, 'caption': '''Enable virtual keyboard''', + 'tags': [], 'desc': '''This policy configures enabling the virtual keyboard as an input device on ChromeOS. Users cannot override this policy. If the policy is set to true, the on-screen virtual keyboard will always be enabled. @@ -5298,6 +5590,7 @@ 'example_value': True, 'id': 164, 'caption': '''Add a logout button to the system tray''', + 'tags': [], 'desc': '''Adds a logout button to the system tray. If enabled, a big, red logout button is shown in the system tray while a session is active and the screen is not locked. @@ -5316,6 +5609,7 @@ 'example_value': True, 'id': 165, 'caption': '''Use built-in DNS client''', + 'tags': [], 'desc': '''Controls whether the built-in DNS client is used in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If this policy is set to true, the built-in DNS client will be used, if available. @@ -5355,6 +5649,7 @@ 'example_value': 'Always', 'id': 166, 'caption': '''Control shelf auto-hiding''', + 'tags': [], 'desc': '''Control auto-hiding of the <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> shelf. If this policy is set to 'AlwaysAutoHideShelf', the shelf will always auto-hide. @@ -5377,6 +5672,7 @@ 'example_value': 'Policy User', 'id': 169, 'caption': '''Set the display name for device-local accounts''', + 'tags': [], 'desc': '''Controls the account name <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> shows on the login screen for the corresponding device-local account. If this policy is set, the login screen will use the specified string in the picture-based login chooser for the corresponding device-local account. @@ -5397,6 +5693,7 @@ 'example_value': 3600000, 'id': 170, 'caption': '''Limit the session length''', + 'tags': [], 'desc': '''Limit the maximum length of a user session. When this policy is set, it specifies the length of time after which a user is automatically logged out, terminating the session. The user is informed about the remaining time by a countdown timer shown in the system tray. @@ -5419,6 +5716,7 @@ 'example_value': True, 'id': 240, 'caption': '''Allow fullscreen mode''', + 'tags': [], 'desc': '''Allow fullscreen mode. This policy controls the availability of fullscreen mode in which all <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> UI is hidden and only web content is visible. @@ -5453,6 +5751,7 @@ 'example_value': 420000, 'id': 172, 'caption': '''Screen dim delay when running on AC power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the screen is dimmed when running on AC power. When this policy is set to a value greater than zero, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> dims the screen. @@ -5479,6 +5778,7 @@ 'example_value': 480000, 'id': 173, 'caption': '''Screen off delay when running on AC power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the screen is turned off when running on AC power. When this policy is set to a value greater than zero, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> turns off the screen. @@ -5505,6 +5805,7 @@ 'example_value': 600000, 'id': 174, 'caption': '''Screen lock delay when running on AC power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the screen is locked when running on AC power. When this policy is set to a value greater than zero, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> locks the screen. @@ -5533,6 +5834,7 @@ 'example_value': 545000, 'id': 197, 'caption': '''Idle warning delay when running on AC power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which a warning dialog is shown when running on AC power. When this policy is set, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> shows a warning dialog telling the user that the idle action is about to be taken. @@ -5557,6 +5859,7 @@ 'example_value': 1800000, 'id': 175, 'caption': '''Idle delay when running on AC power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the idle action is taken when running on AC power. When this policy is set, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes the idle action, which can be configured separately. @@ -5581,6 +5884,7 @@ 'example_value': 300000, 'id': 176, 'caption': '''Screen dim delay when running on battery power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the screen is dimmed when running on battery power. When this policy is set to a value greater than zero, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> dims the screen. @@ -5607,6 +5911,7 @@ 'example_value': 360000, 'id': 177, 'caption': '''Screen off delay when running on battery power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the screen is turned off when running on battery power. When this policy is set to a value greater than zero, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> turns off the screen. @@ -5633,6 +5938,7 @@ 'example_value': 600000, 'id': 178, 'caption': '''Screen lock delay when running on battery power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the screen is locked when running on battery power. When this policy is set to a value greater than zero, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> locks the screen. @@ -5661,6 +5967,7 @@ 'example_value': 545000, 'id': 198, 'caption': '''Idle warning delay when running on battery power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which a warning dialog is shown when running on battery power. When this policy is set, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> shows a warning dialog telling the user that the idle action is about to be taken. @@ -5685,6 +5992,7 @@ 'example_value': 600000, 'id': 179, 'caption': '''Idle delay when running on battery power''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the idle action is taken when running on battery power. When this policy is set, it specifies the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes the idle action, which can be configured separately. @@ -5731,6 +6039,7 @@ 'example_value': 0, 'id': 180, 'caption': '''Action to take when the idle delay is reached''', + 'tags': [], 'desc': '''Specify the action to take when the idle delay is reached. Note that this policy is deprecated and will be removed in the future. @@ -5777,6 +6086,7 @@ 'example_value': 0, 'id': 226, 'caption': '''Action to take when the idle delay is reached while running on AC power''', + 'tags': [], 'desc': '''Specify the action to take when the idle delay is reached while running on AC power. When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user remains idle for the length of time given by the idle delay, which can be configured separately. @@ -5823,6 +6133,7 @@ 'example_value': 0, 'id': 222, 'caption': '''Action to take when the idle delay is reached while running on battery power''', + 'tags': [], 'desc': '''Specify the action to take when the idle delay is reached while running on battery power. When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user remains idle for the length of time given by the idle delay, which can be configured separately. @@ -5868,6 +6179,7 @@ 'example_value': 0, 'id': 181, 'caption': '''Action to take when the user closes the lid''', + 'tags': [], 'desc': '''Specify the action to take when the user closes the lid. When this policy is set, it specifies the action that <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> takes when the user closes the device's lid. @@ -5888,6 +6200,7 @@ 'example_value': True, 'id': 182, 'caption': '''Specify whether audio activity affects power management''', + 'tags': [], 'desc': '''Specifies whether audio activity affects power management. If this policy is set to True or is unset, the user is not considered to be idle while audio is playing. This prevents the idle timeout from being reached and the idle action from being taken. However, screen dimming, screen off and screen lock will be performed after the configured timeouts, irrespective of audio activity. @@ -5906,6 +6219,7 @@ 'example_value': True, 'id': 183, 'caption': '''Specify whether video activity affects power management''', + 'tags': [], 'desc': '''Specifies whether video activity affects power management. If this policy is set to True or is unset, the user is not considered to be idle while video is playing. This prevents the idle delay, screen dim delay, screen off delay and screen lock delay from being reached and the corresponding actions from being taken. @@ -5925,6 +6239,7 @@ 'example_value': 200, 'id': 184, 'caption': '''Percentage by which to scale the idle delay in presentation mode (deprecated)''', + 'tags': [], 'desc': '''This policy has been retired as of <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> version 29. Please use the PresentationScreenDimDelayScale policy instead.''', }, { @@ -5939,6 +6254,7 @@ 'example_value': 200, 'id': 220, 'caption': '''Percentage by which to scale the screen dim delay in presentation mode''', + 'tags': [], 'desc': '''Specifies the percentage by which the screen dim delay is scaled when the device is in presentation mode. If this policy is set, it specifies the percentage by which the screen dim delay is scaled when the device is in presentation mode. When the screen dim delay is scaled, the screen off, screen lock and idle delays get adjusted to maintain the same distances from the screen dim delay as originally configured. @@ -5959,6 +6275,7 @@ 'example_value': False, 'id': 203, 'caption': '''Allow screen wake locks''', + 'tags': [], 'desc': '''Specifies whether screen wake locks are allowed. Screen wake locks can be requested by extensions via the power management extension API. If this policy is set to true or left not set, screen wake locks will be honored for power management. @@ -5977,6 +6294,7 @@ 'example_value': 200, 'id': 210, 'caption': '''Percentage by which to scale the screen dim delay if the user becomes active after dimming''', + 'tags': [], 'desc': '''Specifies the percentage by which the screen dim delay is scaled when user activity is observed while the screen is dimmed or soon after the screen has been turned off. If this policy is set, it specifies the percentage by which the screen dim delay is scaled when user activity is observed while the screen is dimmed or soon after the screen has been turned off. When the dim delay is scaled, the screen off, screen lock and idle delays get adjusted to maintain the same distances from the screen dim delay as originally configured. @@ -5997,6 +6315,7 @@ 'example_value': True, 'id': 247, 'caption': '''Wait for initial user activity''', + 'tags': [], 'desc': '''Specifies whether power management delays and the session length limit should only start running after the first user activity has been observed in a session. If this policy is set to True, power management delays and the session length limit do not start running until after the first user activity has been observed in a session. @@ -6067,6 +6386,7 @@ }, 'id': 258, 'caption': '''Power management settings when the user becomes idle''', + 'tags': [], 'desc': '''Configure power management settings when the user becomes idle. This policy controls multiple settings for the power management strategy when the user becomes idle. @@ -6123,6 +6443,7 @@ }, 'id': 259, 'caption': '''Screen lock delays''', + 'tags': [], 'desc': '''Specifies the length of time without user input after which the screen is locked when running on AC power or battery. When the length of time is set to a value greater than zero, it represents the length of time that the user must remain idle before <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> locks the screen. @@ -6206,6 +6527,7 @@ }, 'id': 225, 'caption': '''Power management on the login screen''', + 'tags': [], 'desc': '''Configure power management on the login screen in <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph>. This policy lets you configure how <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> behaves when there is no user activity for some amount of time while the login screen is being shown. The policy controls multiple settings. For their individual semantics and value ranges, see the corresponding policies that control power management within a session. The only deviations from these policies are: @@ -6228,6 +6550,7 @@ 'example_value': True, 'id': 185, 'caption': '''Allow users to redeem offers through Chrome OS Registration''', + 'tags': [], 'desc': '''IT admins for enterprise devices can use this flag to control whether to allow users to redeem offers through Chrome OS Registration. If this policy is set to true or left not set, users will be able to redeem offers through Chrome OS Registration. @@ -6246,6 +6569,7 @@ 'example_value': 'https://www.example.com/terms_of_service.txt', 'id': 186, 'caption': '''Set the Terms of Service for a device-local account''', + 'tags': [], 'desc': '''Sets the Terms of Service that the user must accept before starting a device-local account session. If this policy is set, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will download the Terms of Service and present them to the user whenever a device-local account session is starting. The user will only be allowed into the session after accepting the Terms of Service. @@ -6273,6 +6597,7 @@ 'example_value': True, 'id': 188, 'caption': '''Show accessibility options in system tray menu''', + 'tags': [], 'desc': '''Show <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> accessibility options in the system menu. If this policy is set to true, Accessibility options always appear in system tray menu. @@ -6296,6 +6621,7 @@ 'example_value': True, 'id': 211, 'caption': '''Enable large cursor''', + 'tags': [], 'desc': '''Enable the large cursor accessibility feature. If this policy is set to true, the large cursor will always be enabled. @@ -6319,6 +6645,7 @@ 'example_value': True, 'id': 212, 'caption': '''Enable spoken feedback''', + 'tags': [], 'desc': '''Enable the spoken feedback accessibility feature. If this policy is set to true, spoken feedback will always be enabled. @@ -6342,6 +6669,7 @@ 'example_value': True, 'id': 213, 'caption': '''Enable high contrast mode''', + 'tags': [], 'desc': '''Enable the high contrast mode accessibility feature. If this policy is set to true, high contrast mode will always be enabled. @@ -6365,6 +6693,7 @@ 'example_value': True, 'id': 255, 'caption': '''Enable on-screen keyboard''', + 'tags': [], 'desc': '''Enable the on-screen keyboard accessibility feature. If this policy is set to true, the on-screen keyboard will always be enabled. @@ -6388,6 +6717,7 @@ 'example_value': True, 'id': 260, 'caption': '''Media keys default to function keys''', + 'tags': [], 'desc': '''Changes the default behaviour of the top row keys to function keys. If this policy is set to true, the keyboard's top row of keys will produce function key commands per default. The search key has to be pressed to revert their behavior back to media keys. @@ -6422,6 +6752,7 @@ 'example_value': 1, 'id': 214, 'caption': '''Set screen magnifier type''', + 'tags': [], 'desc': '''Set the type of screen magnifier that is enabled. If this policy is set, it controls the type of screen magnifier that is enabled. Setting the policy to "None" disables the screen magnifier. @@ -6442,6 +6773,7 @@ 'example_value': True, 'id': 215, 'caption': '''Set default state of the large cursor on the login screen''', + 'tags': [], 'desc': '''Set the default state of the large cursor accessibility feature on the login screen. If this policy is set to true, the large cursor will be enabled when the login screen is shown. @@ -6464,6 +6796,7 @@ 'example_value': True, 'id': 216, 'caption': '''Set the default state of spoken feedback on the login screen''', + 'tags': [], 'desc': '''Set the default state of the spoken feedback accessibility feature on the login screen. If this policy is set to true, spoken feedback will be enabled when the login screen is shown. @@ -6486,6 +6819,7 @@ 'example_value': True, 'id': 217, 'caption': '''Set the default state of high contrast mode on the login screen''', + 'tags': [], 'desc': '''Set the default state of the high contrast mode accessibility feature on the login screen. If this policy is set to true, high contrast mode will be enabled when the login screen is shown. @@ -6508,6 +6842,7 @@ 'example_value': True, 'id': 256, 'caption': '''Set default state of the on-screen keyboard on the login screen''', + 'tags': [], 'desc': '''Set the default state of the on-screen keyboard accessibility feature on the login screen. If this policy is set to true, the on-screen keyboard will be enabled when the login screen is shown. @@ -6545,6 +6880,7 @@ 'example_value': 1, 'id': 218, 'caption': '''Set the default screen magnifier type enabled on the login screen''', + 'tags': [], 'desc': '''Set the default type of screen magnifier that is enabled on the login screen. If this policy is set, it controls the type of screen magnifier that is enabled when the login screen is shown. Setting the policy to "None" disables the screen magnifier. @@ -6567,6 +6903,7 @@ 'example_value': True, 'id': 189, 'caption': '''Hide the web store from the New Tab Page and app launcher''', + 'tags': [], 'desc': '''Hide the Chrome Web Store app and footer link from the New Tab Page and <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> app launcher. When this policy is set to true, the icons are hidden. @@ -6588,6 +6925,7 @@ 'example_value': [ "enable-managed-mode", "my-cool-flag" ], 'id': 191, 'caption': '''System wide flags to be applied on <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> start-up''', + 'tags': [], 'desc': '''Specifies the flags that should be applied to <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> when it starts. The specified flags are applied before <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is started even for the sign-in screen.''', }, { @@ -6602,6 +6940,7 @@ 'example_value': 86400, 'id': 192, 'caption': '''Limit device uptime by automatically rebooting''', + 'tags': [], 'desc': '''Limit the device uptime by scheduling automatic reboots. When this policy is set, it specifies the length of device uptime after which an automatic reboot is scheduled. @@ -6628,6 +6967,7 @@ 'example_value': True, 'id': 193, 'caption': '''Automatically reboot after update''', + 'tags': [], 'desc': '''Schedule an automatic reboot after a <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> update has been applied. When this policy is set to true, an automatic reboot is scheduled when a <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> update has been applied and a reboot is required to complete the update process. The reboot is scheduled immediately but may be delayed on the device by up to 24 hours if a user is currently using the device. @@ -6651,6 +6991,7 @@ 'id': 196, 'future': True, 'caption': '''Set the restriction on the fetching of the Variations seed''', + 'tags': [], 'desc': '''Add a parameter to the fetching of the Variations seed in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. If specified, will add a query parameter called 'restrict' to the URL used to fetch the Variations seed. The value of the parameter will be the value specified in this policy. @@ -6670,6 +7011,7 @@ 'id': 199, 'future': True, 'caption': '''Set the restriction on the fetching of the Variations seed''', + 'tags': [], 'desc': '''Add a parameter to the fetching of the Variations seed in <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph>. If specified, will add a query parameter called 'restrict' to the URL used to fetch the Variations seed. The value of the parameter will be the value specified in this policy. @@ -6694,6 +7036,7 @@ 'example_value': True, 'id': 207, 'caption': '''Enable remote attestation for the device''', + 'tags': [], 'desc': '''If true, remote attestation is allowed for the device and a certificate will automatically be generated and uploaded to the Device Management Server. If it is set to false, or if it is not set, no certificate will be generated and calls to the enterprise.platformKeysPrivate extension API will fail.''', @@ -6710,6 +7053,7 @@ 'example_value': True, 'id': 200, 'caption': '''Enable remote attestation for the user''', + 'tags': [], 'desc': '''If true, the user can use the hardware on Chrome devices to remote attest its identity to the privacy CA via the Enterprise Platform Keys API chrome.enterprise.platformKeysPrivate.challengeUserKey(). If it is set to false, or if it is not set, calls to the API will fail with an error code.''', @@ -6729,6 +7073,7 @@ 'example_value': ['ghdilpkmfbfdnomkmaiogjhjnggaggoi'], 'id': 201, 'caption': '''Extensions allowed to to use the remote attestation API''', + 'tags': [], 'desc': '''This policy specifies the allowed extensions to use Enterprise Platform Keys API chrome.enterprise.platformKeysPrivate.challengeUserKey() for remote attestation. Extensions must be added to this list to use the API. If an extension is not in the list, or the list is not set, the call to the API will fail with an error code.''', @@ -6745,6 +7090,7 @@ 'example_value': True, 'id': 239, 'caption': '''Enable the use of remote attestation for content protection for the device''', + 'tags': [], 'desc': '''Chrome OS devices can use remote attestation (Verified Access) to get a certificate issued by the Chrome OS CA that asserts the device is eligible to play protected content. This process involves sending hardware endorsement information to the Chrome OS CA which uniquely identifies the device. If this setting is false, the device will not use remote attestation for content protection and the device may be unable to play protected content. @@ -6756,6 +7102,7 @@ { 'name': 'SuppressChromeFrameTurndownPrompt', 'caption': '''Suppress the <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph> turndown prompt''', + 'tags': [], 'desc': '''Suppresses the turndown prompt that appears when a site is rendered by <ph name="PRODUCT_FRAME_NAME">$3<ex>Google Chrome Frame</ex></ph>.''', 'type': 'main', 'schema': { 'type': 'boolean' }, @@ -6806,6 +7153,7 @@ 'example_value': 2, 'id': 204, 'caption': '''Default behavior for sites not in any content pack''', + 'tags': [], 'desc': '''The default behavior for sites not in any content pack. This policy is for internal use by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> itself.''', @@ -6832,6 +7180,7 @@ }, 'id': 205, 'caption': '''Managed user manual exception hosts''', + 'tags': [], 'desc': '''A dictionary mapping hostnames to a boolean flag specifying whether access to the host should be allowed (true) or blocked (false). This policy is for internal use by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> itself.''', @@ -6858,6 +7207,7 @@ }, 'id': 206, 'caption': '''Managed user manual exception URLs''', + 'tags': [], 'desc': '''A dictionary mapping URLs to a boolean flag specifying whether access to the host should be allowed (true) or blocked (false). This policy is for internal use by <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> itself.''', @@ -6874,6 +7224,7 @@ 'example_value': True, 'id': 219, 'caption': '''Enable supervised users''', + 'tags': [], 'desc': '''If set to true, supervised users can be created and used. If set to false or not configured, supervised-user creation and login will be disabled. All existing supervised users will be hidden. @@ -6892,6 +7243,7 @@ 'example_value': True, 'id': 223, 'caption': '''Enable creation of supervised users''', + 'tags': [], 'desc': '''If set to false, supervised-user creation by this user will be disabled. Any existing supervised users will still be available. If set to true or not configured, supervised users can be created and managed by this user.''' @@ -6949,6 +7301,7 @@ ], 'id': 227, 'caption': '''Managed Bookmarks''', + 'tags': [], 'desc': '''Configures a list of managed bookmarks. The policy consists of a list of bookmarks whereas each bookmark is a @@ -6974,6 +7327,7 @@ 'example_value': True, 'id': 241, 'caption': '''Enable the data compression proxy feature''', + 'tags': [], 'desc': '''Enable or disable the data compression proxy and prevents users from changing this setting. If you enable or disable this setting, users cannot change or override this setting. @@ -6999,6 +7353,7 @@ 'max_size': 524288, 'id': 249, 'caption': '''User avatar image''', + 'tags': [], 'desc': '''Configure user avatar image. This policy allows you to configure the avatar image representing the user on the login screen. The policy is set by specifying the URL from which <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can download the avatar image and a cryptographic hash used to verify the integrity of the download. The image must be in JPEG format, its size must not exceed 512kB. The URL must be accessible without any authentication. @@ -7045,6 +7400,7 @@ 'max_size': 16777216, 'id': 262, 'caption': '''Wallpaper image''', + 'tags': [], 'desc': '''Configure wallpaper image. This policy allows you to configure the wallpaper image that is shown on the desktop and on the login screen background for the user. The policy is set by specifying the URL from which <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> can download the wallpaper image and a cryptographic hash used to verify the integrity of the download. The image must be in JPEG format, its file size must not exceed 16MB. The URL must be accessible without any authentication. @@ -7099,6 +7455,7 @@ 'example_value': ['ShowModalDialog_EffectiveUntil20150430'], 'id': 270, 'caption': '''Enable deprecated web platform features for a limited time''', + 'tags': ['system-security'], 'desc': '''Specify a list of deprecated web platform features to re-enable temporarily. This policy gives administrators the ability to re-enable deprecated web platform features for a limited time. Features are identified by a string tag and the features corresponding to the tags included in the list specified by this policy will get re-enabled. @@ -7120,6 +7477,7 @@ 'example_value': True, 'id': 271, 'caption': '''Transfer SAML IdP cookies during login''', + 'tags': [], 'desc': '''Specifies whether authentication cookies set by a SAML IdP during login should be transferred to the user's profile. When a user authenticates via a SAML IdP during login, cookies set by the IdP are written to a temporary profile at first. These cookies can be transferred to the user's profile to carry forward the authentication state. @@ -7143,6 +7501,7 @@ 'default_for_enterprise_users': False, 'id': 272, 'caption': '''Allows Smart Lock to be used''', + 'tags': [], 'desc': '''Allows Smart Lock to be used on <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices. If you enable this setting, users will be allowed to use Smart Lock if the requirements for the feature are satisfied. @@ -7167,6 +7526,7 @@ 'example_value': ['de', 'fr'], 'id': 274, 'caption': '''Set the recommended locales for a public session''', + 'tags': [], 'desc': '''Sets one or more recommended locales for a public sessions, allowing users to easily choose one of these locales. The user can choose a locale and a keyboard layout before starting a public session. By default, all locales supported by <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> are listed in alphabetic order. You can use this policy to move a set of recommended locales to the top of the list. @@ -7196,6 +7556,7 @@ 'example_value': True, 'id': 275, 'caption': '''Enable guest mode in browser''', + 'tags': [], 'desc': '''If this policy is set to true or not configured, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will enable guest logins. Guest logins are <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> profiles where all windows are in incognito mode. If this policy is set to false, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will not allow guest profiles to be started.''', @@ -7212,6 +7573,7 @@ 'example_value': True, 'id': 276, 'caption': '''Enable add person in profile manager''', + 'tags': [], 'desc': '''If this policy is set to true or not configured, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will allow Add Person from the user manager. If this policy is set to false, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will not allow creation of new profiles from the profile manager.''', @@ -7263,6 +7625,7 @@ 'example_value': 'ssl3', 'id': 279, 'caption': '''Minimum SSL version enabled''', + 'tags': [], 'desc': '''Warning: SSLv3 support will be entirely removed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> after version 43 (around July 2015) and this policy will be removed at the same time. If this policy is not configured then <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> uses a default minimum version which is SSLv3 in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> 39 and TLS 1.0 in later versions. @@ -7312,6 +7675,7 @@ 'example_value': 'tls1.1', 'id': 280, 'caption': '''Minimum TLS version to fallback to''', + 'tags': [], 'desc': '''Warning: The TLS 1.0 version fallback will be removed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> after version 47 (around January 2016) and the "tls1" option will stop working then. When a TLS handshake fails, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will retry the connection with a lesser version of TLS in order to work around bugs in HTTPS servers. This setting configures the version at which this fallback process will stop. If a server performs version negotiation correctly (i.e. without breaking the connection) then this setting doesn't apply. Regardless, the resulting connection must still comply with SSLVersionMin. @@ -7336,6 +7700,7 @@ 'example_value': True, 'id': 281, 'caption': '''Enable Touch to Search''', + 'tags': [], 'desc': '''Enables the availability of Touch to Search in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s content view. If you enable this setting, Touch to Search will be available to the user and they can choose to turn the feature on or off. @@ -7356,6 +7721,7 @@ 'example_value': True, 'id': 284, 'caption': '''Automatic reboot on device shutdown''', + 'tags': [], 'desc': '''If this policy is set to false or not configured, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will allow the user to shut down the device. If this policy is set to true, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will trigger a reboot when the user shuts down the device. <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> replaces all occurrences of shutdown buttons in the UI by reboot buttons. If the user shuts down the device using the power button, it will not automatically reboot, even if the policy is enabled.''', }, @@ -7371,6 +7737,7 @@ 'example_value': 104857600, 'id': 296, 'caption': '''Set Apps and Extensions cache size (in bytes)''', + 'tags': [], 'desc': '''<ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> caches Apps and Extensions for installation by multiple users of a single device to avoid re-downloading them for each user. If this policy is not configured or the value is lower than 1 MB, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will use the default cache size.''', }, @@ -7386,6 +7753,7 @@ 'example_value': 'students.school.edu', 'id': 297, 'caption': '''Enable domain name autocomplete during user sign in''', + 'tags': [], 'desc': '''If this policy is set to a blank string or not configured, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will not show an autocomplete option during user sign-in flow. If this policy is set to a string representing a domain name, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will show an autocomplete option during user sign-in allowing the user to type in only his user name without the domain name extension. The user will be able to overwrite this domain name extension.''', }, @@ -7401,6 +7769,7 @@ 'example_value': True, 'id': 298, 'caption': '''Maximize the first browser window on first run''', + 'tags': [], 'desc': '''If this policy is set to true, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will unconditionally maximize the the first window shown on first run. If this policy is set to false or not configured, a heuristic will decide whether to maximize the first window shown, based on the screen size.''', }, @@ -7416,6 +7785,7 @@ 'example_value': True, 'id': 300, 'caption': '''Allow proceeding from the SSL warning page''', + 'tags': [], 'desc': '''Chrome shows a warning page when users navigate to sites that have SSL errors. By default or when this policy is set to true, users are allowed to click through these warning pages. Setting this policy to false disallows users to click through any warning page.''', }, @@ -7431,6 +7801,7 @@ 'example_value': True, 'id': 301, 'caption': '''Allows QUIC protocol''', + 'tags': [], 'desc': '''If this policy is set to true or not set usage of QUIC protocol in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is allowed. If this policy is set to false usage of QUIC protocol is disallowed.''', }, @@ -7464,6 +7835,7 @@ }, 'id': 302, 'caption': 'Key Permissions', + 'tags': [], 'desc': '''Grants access to corporate keys to extensions. Keys are designated for corporate usage if they're generated using the chrome.enterprise.platformKeys API on a managed account. Keys imported or generated in another way are not designated for corporate usage. @@ -7481,6 +7853,7 @@ 'schema': { 'type': 'boolean' }, 'id': 303, 'caption': 'Enable showing the welcome page on the first browser launch following OS upgrade.', + 'tags': [], 'desc': '''Enable showing the welcome page on the first browser launch following OS upgrade. If this policy is set to true or not configured, the browser will re-show the welcome page on the first launch following an OS upgrade. @@ -7504,6 +7877,7 @@ 'example_value': True, 'id': 304, 'caption': '''Use hardware acceleration when available''', + 'tags': [], 'desc': '''Use hardware acceleration when available. If this policy is set to true or left unset, hardware acceleration will be enabled unless a certain GPU feature is blacklisted. @@ -7523,6 +7897,7 @@ 'example_value': True, 'id': 307, 'caption': '''Make Unified Desktop available and turn on by default.''', + 'tags': [], 'desc': '''If this policy is set to true, Unified Desktop is allowed and enabled by default, which allows applications to span multiple displays. The user may disable Unified Desktop for individual displays by unchecking
diff --git a/components/policy/tools/generate_policy_source.py b/components/policy/tools/generate_policy_source.py index 31a88e5..83e9a14 100755 --- a/components/policy/tools/generate_policy_source.py +++ b/components/policy/tools/generate_policy_source.py
@@ -11,6 +11,7 @@ template is the path to a .json policy template file.''' from __future__ import with_statement +from collections import OrderedDict from functools import partial import json from optparse import OptionParser @@ -62,9 +63,12 @@ self.caption = PolicyDetails._RemovePlaceholders(item['caption']) self.value = item['value'] - def __init__(self, policy, chrome_major_version, os, is_chromium_os): + def __init__(self, policy, chrome_major_version, os, is_chromium_os, + valid_tags): self.id = policy['id'] self.name = policy['name'] + self.tags = policy.get('tags', None) + self._CheckTagsValidity(valid_tags) features = policy.get('features', {}) self.can_be_recommended = features.get('can_be_recommended', False) self.can_be_mandatory = features.get('can_be_mandatory', True) @@ -124,6 +128,18 @@ PH_PATTERN = re.compile('<ph[^>]*>([^<]*|[^<]*<ex>([^<]*)</ex>[^<]*)</ph>') + def _CheckTagsValidity(self, valid_tags): + if self.tags == None: + raise RuntimeError('Policy ' + self.name + ' has to contain a list of ' + 'tags!\n An empty list is also valid but means ' + 'setting this policy can never harm the user\'s ' + 'privacy or security.\n'); + for tag in self.tags: + if not tag in valid_tags: + raise RuntimeError('Invalid Tag:' + tag + '!\n' + 'Chose a valid tag from \'risk_tag_definitions\' (a ' + 'subproperty of root in policy_templates.json)!') + # Simplistic grit placeholder stripper. @staticmethod def _RemovePlaceholders(text): @@ -174,7 +190,10 @@ help='generate an XML file as specified by ' 'Android\'s App Restriction Schema', metavar='FILE') - + parser.add_option('--rth', '--risk-tag-header', + dest='risk_header_path', + help='generate header file for policy risk tags', + metavar='FILE') (opts, args) = parser.parse_args() if len(args) != 4: @@ -190,18 +209,23 @@ major_version = ParseVersionFile(version_path) template_file_contents = _LoadJSONFile(template_file_name) - policy_details = [ PolicyDetails(policy, major_version, os, is_chromium_os) + riskTags = RiskTags(template_file_contents) + policy_details = [ PolicyDetails(policy, major_version, os, is_chromium_os, + riskTags.GetValidTags()) for policy in _Flatten(template_file_contents) ] + riskTags.ComputeMaxTags(policy_details) sorted_policy_details = sorted(policy_details, key=lambda policy: policy.name) def GenerateFile(path, writer, sorted=False, xml=False): if path: with open(path, 'w') as f: _OutputGeneratedWarningHeader(f, template_file_name, xml) - writer(sorted and sorted_policy_details or policy_details, os, f) + writer(sorted and sorted_policy_details or policy_details, + os, f, riskTags) GenerateFile(opts.header_path, _WritePolicyConstantHeader, sorted=True) GenerateFile(opts.source_path, _WritePolicyConstantSource, sorted=True) + GenerateFile(opts.risk_header_path, _WritePolicyRiskTagHeader) GenerateFile(opts.cloud_policy_proto_path, _WriteCloudPolicyProtobuf) GenerateFile(opts.chrome_settings_proto_path, _WriteChromeSettingsProtobuf) GenerateFile(opts.cloud_policy_decoder_path, _WriteCloudPolicyDecoder) @@ -268,7 +292,7 @@ #------------------ policy constants header ------------------------# -def _WritePolicyConstantHeader(policies, os, f): +def _WritePolicyConstantHeader(policies, os, f, riskTags): f.write('#ifndef CHROME_COMMON_POLICY_CONSTANTS_H_\n' '#define CHROME_COMMON_POLICY_CONSTANTS_H_\n' '\n' @@ -632,19 +656,18 @@ self.properties_nodes = map(partial(self.ResolveID, 3), self.properties_nodes) -def _WritePolicyConstantSource(policies, os, f): +def _WritePolicyConstantSource(policies, os, f, riskTags): f.write('#include "policy/policy_constants.h"\n' '\n' '#include <algorithm>\n' '#include <climits>\n' '\n' '#include "base/logging.h"\n' + '#include "policy/risk_tag.h"\n' '#include "components/policy/core/common/policy_types.h"\n' '#include "components/policy/core/common/schema_internal.h"\n' '\n' 'namespace policy {\n' - '\n' - 'namespace {\n' '\n') # Generate the Chrome schema. @@ -659,18 +682,20 @@ chrome_schema['properties'][policy.name] = policy.schema # Note: this list must be kept in sync with the known property list of the - # Chrome schema, so that binary seaching in the PropertyNode array gets the + # Chrome schema, so that binary searching in the PropertyNode array gets the # right index on this array as well. See the implementation of # GetChromePolicyDetails() below. f.write('const PolicyDetails kChromePolicyDetails[] = {\n' '// is_deprecated is_device_policy id max_external_data_size\n') for policy in policies: if policy.is_supported: - f.write(' { %-14s %-16s %3s, %24s },\n' % ( + f.write(' { %-14s %-16s %3s, %24s,\n' + ' %s },\n' % ( 'true,' if policy.is_deprecated else 'false,', 'true,' if policy.is_device_only else 'false,', policy.id, - policy.max_size)) + policy.max_size, + riskTags.ToInitString(policy.tags))) f.write('};\n\n') schema_generator = SchemaNodesGenerator(shared_strings) @@ -678,6 +703,9 @@ schema_generator.ResolveReferences() schema_generator.Write(f) + f.write('\n' + 'namespace {\n') + f.write('bool CompareKeys(const internal::PropertyNode& node,\n' ' const std::string& key) {\n' ' return node.key < key;\n' @@ -769,6 +797,87 @@ '} // namespace policy\n') +#------------------ policy risk tag header ------------------------# + +class RiskTags(object): + '''Generates files and strings to translate the parsed risk tags.''' + # TODO(fhorschig|tnagel): Add, Check & Generate translation descriptions. + + def __init__(self, template_file_contents): + self.max_tags = None + self.enum_for_tag = OrderedDict() # Ordered by severity as stated in JSON. + self._ReadRiskTagMetaData(template_file_contents) + + def GenerateEnum(self): + values = [' ' + self.enum_for_tag[tag] for tag in self.enum_for_tag] + values.append(' RISK_TAG_COUNT') + values.append(' RISK_TAG_NONE') + enum_text = 'enum RiskTag {\n' + enum_text +=',\n'.join(values) + '\n};\n' + return enum_text + + def GetMaxTags(self): + return str(self.max_tags) + + def GetValidTags(self): + return [tag for tag in self.enum_for_tag] + + def ToInitString(self, tags): + all_tags = [self._ToEnum(tag) for tag in tags] + all_tags += ["RISK_TAG_NONE" for missing in range(len(tags), self.max_tags)] + str_tags = "{ " + ", ".join(all_tags) + " }" + return "\n ".join(textwrap.wrap(str_tags, 69)) + + def ComputeMaxTags(self, policies): + self.max_tags = 0 + for policy in policies: + if not policy.is_supported or policy.tags == None: + continue; + self.max_tags = max(len(policy.tags), self.max_tags) + + def _ToEnum(self, tag): + if tag in self.enum_for_tag: + return self.enum_for_tag[tag] + raise RuntimeError('Invalid Tag:' + tag + '!\n' + 'Chose a valid tag from \'risk_tag_definitions\' (a ' + 'subproperty of root in policy_templates.json)!') + + def _ReadRiskTagMetaData(self, template_file_contents): + for tag in template_file_contents['risk_tag_definitions']: + if tag.get('name', None) == None: + raise RuntimeError('Tag in \'risk_tag_definitions\' without ' + 'description found!') + if tag.get('description', None) == None: + raise RuntimeError('Tag ' + tag['name'] + ' has no description!') + if tag.get('user-description', None) == None: + raise RuntimeError('Tag ' + tag['name'] + ' has no user-description!') + self.enum_for_tag[tag['name']] = "RISK_TAG_" + \ + tag['name'].replace("-","_").upper() + +def _WritePolicyRiskTagHeader(policies, os, f, riskTags): + f.write('#ifndef CHROME_COMMON_POLICY_RISK_TAG_H_\n' + '#define CHROME_COMMON_POLICY_RISK_TAG_H_\n' + '\n' + '#include "base/basictypes.h"\n' + '\n' + 'namespace policy {\n' + '\n' + \ + '// The tag of a policy indicates which impact a policy can have on\n' + '// a user\'s privacy and/or security. Ordered descending by \n' + '// impact.\n' + '// The explanation of the single tags is stated in\n' + '// policy_templates.json within the \'risk_tag_definitions\' tag.' + '\n' + riskTags.GenerateEnum() + '\n' + '// This constant describes how many risk tags were used by the\n' + '// policy which uses the most risk tags. \n' + 'const size_t kMaxRiskTagCount = ' + \ + riskTags.GetMaxTags() + ';\n' + '\n' + '} // namespace policy\n' + '\n' + '#endif // CHROME_COMMON_POLICY_RISK_TAG_H_' + '\n') + #------------------ policy protobufs --------------------------------# CHROME_SETTINGS_PROTO_HEAD = ''' @@ -856,7 +965,7 @@ (policy.name, policy.name, policy.id + RESERVED_IDS) ] -def _WriteChromeSettingsProtobuf(policies, os, f): +def _WriteChromeSettingsProtobuf(policies, os, f, riskTags): f.write(CHROME_SETTINGS_PROTO_HEAD) fields = [] @@ -874,7 +983,7 @@ f.write('}\n\n') -def _WriteCloudPolicyProtobuf(policies, os, f): +def _WriteCloudPolicyProtobuf(policies, os, f, riskTags): f.write(CLOUD_POLICY_PROTO_HEAD) f.write('message CloudPolicySettings {\n') for policy in policies: @@ -1021,7 +1130,7 @@ ' }\n') -def _WriteCloudPolicyDecoder(policies, os, f): +def _WriteCloudPolicyDecoder(policies, os, f, riskTags): f.write(CPP_HEAD) for policy in policies: if policy.is_supported and not policy.is_device_only: @@ -1029,7 +1138,7 @@ f.write(CPP_FOOT) -def _WriteAppRestrictions(policies, os, f): +def _WriteAppRestrictions(policies, os, f, riskTags): def WriteRestrictionCommon(key): f.write(' <restriction\n'
diff --git a/components/policy/tools/syntax_check_policy_template_json.py b/components/policy/tools/syntax_check_policy_template_json.py index ed1c222..fd0cedd7 100755 --- a/components/policy/tools/syntax_check_policy_template_json.py +++ b/components/policy/tools/syntax_check_policy_template_json.py
@@ -184,7 +184,7 @@ if key not in ('name', 'type', 'caption', 'desc', 'device_only', 'supported_on', 'label', 'policies', 'items', 'example_value', 'features', 'deprecated', 'future', - 'id', 'schema', 'max_size', + 'id', 'schema', 'max_size', 'tags', 'default_for_enterprise_users'): self.warning_count += 1 print ('In policy %s: Warning: Unknown key: %s' % @@ -243,6 +243,9 @@ id = self._CheckContains(policy, 'id', int) self._AddPolicyID(id, policy_ids, policy) + # Each policy must have a tag list. + self._CheckContains(policy, 'tags', list) + # 'schema' is the new 'type'. # TODO(joaodasilva): remove the 'type' checks once 'schema' is used # everywhere.
diff --git a/components/scheduler/base/task_queue_manager.cc b/components/scheduler/base/task_queue_manager.cc index 00f0734..fda6e7e 100644 --- a/components/scheduler/base/task_queue_manager.cc +++ b/components/scheduler/base/task_queue_manager.cc
@@ -210,19 +210,16 @@ delayed_run_time)); return; } - if (delayed_run_time > lazy_now->Now()) { - // Make sure there's one (and only one) task posted to |main_task_runner_| - // to call |DelayedDoWork| at |delayed_run_time|. - if (delayed_wakeup_map_.find(delayed_run_time) == - delayed_wakeup_map_.end()) { - base::TimeDelta delay = delayed_run_time - lazy_now->Now(); - main_task_runner_->PostDelayedTask(FROM_HERE, - delayed_queue_wakeup_closure_, delay); - } - delayed_wakeup_map_.insert(std::make_pair(delayed_run_time, queue)); - } else { - WakeupReadyDelayedQueues(lazy_now); + + // Make sure there's one (and only one) task posted to |main_task_runner_| + // to call |DelayedDoWork| at |delayed_run_time|. + if (delayed_wakeup_map_.find(delayed_run_time) == delayed_wakeup_map_.end()) { + base::TimeDelta delay = + std::max(base::TimeDelta(), delayed_run_time - lazy_now->Now()); + main_task_runner_->PostDelayedTask(FROM_HERE, delayed_queue_wakeup_closure_, + delay); } + delayed_wakeup_map_.insert(std::make_pair(delayed_run_time, queue)); } void TaskQueueManager::DelayedDoWork() {
diff --git a/components/scheduler/base/task_queue_manager_unittest.cc b/components/scheduler/base/task_queue_manager_unittest.cc index f7ccc02..39972eb8 100644 --- a/components/scheduler/base/task_queue_manager_unittest.cc +++ b/components/scheduler/base/task_queue_manager_unittest.cc
@@ -1306,4 +1306,18 @@ manager_->SetObserver(nullptr); } +TEST_F(TaskQueueManagerTest, ScheduleDelayedWorkIsNotReEntrant) { + Initialize(1u); + + // Post two tasks into the past. The second one used to trigger a deadlock + // because it tried to re-entrantly wake the first task in the same queue. + runners_[0]->PostDelayedTaskAt( + FROM_HERE, base::Bind(&NullTask), + base::TimeTicks() + base::TimeDelta::FromMicroseconds(100)); + runners_[0]->PostDelayedTaskAt( + FROM_HERE, base::Bind(&NullTask), + base::TimeTicks() + base::TimeDelta::FromMicroseconds(200)); + test_task_runner_->RunUntilIdle(); +} + } // namespace scheduler
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 5aa0567..bf3da73 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -71,6 +71,7 @@ #include "net/ssl/ssl_config_service.h" #include "ipc/mojo/scoped_ipc_support.h" #include "skia/ext/skia_memory_dump_provider.h" +#include "sql/sql_memory_dump_provider.h" #include "ui/base/clipboard/clipboard.h" #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS)) @@ -661,6 +662,8 @@ HostSharedBitmapManager::current()); base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( skia::SkiaMemoryDumpProvider::GetInstance()); + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + sql::SqlMemoryDumpProvider::GetInstance()); #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED) trace_memory_controller_.reset(new base::trace_event::TraceMemoryController(
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 805e1e1..9edf3ab 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -102,6 +102,7 @@ #if defined(OS_WIN) switches::kEnableAcceleratedVpxDecode, #endif + switches::kEnableHeapProfiling, switches::kEnableLogging, switches::kEnableShareGroupAsyncTextureUpload, #if defined(OS_CHROMEOS)
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index dc03b79..ae6be5c 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1271,6 +1271,7 @@ switches::kEnableExperimentalCanvasFeatures, switches::kEnableExperimentalWebPlatformFeatures, switches::kEnableFeatures, + switches::kEnableHeapProfiling, switches::kEnableGPUClientLogging, switches::kEnableGpuClientTracing, switches::kEnableGpuMemoryBufferVideoFrames,
diff --git a/content/browser/resources/media/dump_creator.js b/content/browser/resources/media/dump_creator.js index 019d7b30..6aca1b6 100644 --- a/content/browser/resources/media/dump_creator.js +++ b/content/browser/resources/media/dump_creator.js
@@ -33,26 +33,26 @@ '</button></a></div>' + '<p><label><input type=checkbox>' + 'Enable diagnostic audio recordings</label></p>' + - '<p>A diagnostic audio recording is used for analyzing audio' + - ' problems. It contains the audio played out from the speaker and' + - ' recorded from the microphone and is saved to the local disk.' + - ' Checking this box will enable the recording for ongoing WebRTC' + - ' calls and for future WebRTC calls. When the box is unchecked or' + - ' this page is closed, all ongoing recordings will be stopped and' + - ' this recording functionality will be disabled for future WebRTC' + - ' calls. Recordings in multiple tabs are supported as well as' + - ' multiple recordings in the same tab. When enabling, you select a' + - ' base filename to save the dump(s) to. The base filename will have a' + - ' suffix appended to it as <base filename>.<render process' + - ' ID>.<recording ID>. If recordings are' + - ' disabled and then enabled using the same base filename, the' + - ' file(s) will be appended to and may become invalid. It is' + - ' recommended to choose a new base filename each time or move' + - ' the resulting files before enabling again. If track processing is' + - ' disabled (--disable-audio-track-processing): (1) Only one recording' + - ' per render process is supported. (2) When the box is unchecked or' + - ' this page is closed, ongoing recordings will continue until the' + - ' call ends or the page with the recording is closed</p>'; + '<p class=audio-recordings-info>A diagnostic audio recording is used' + + ' for analyzing audio problems. It consists of two files and contains' + + ' the audio played out from the speaker and recorded from the' + + ' microphone and is saved to the local disk. Checking this box will' + + ' enable the recording for ongoing WebRTC calls and for future WebRTC' + + ' calls. When the box is unchecked or this page is closed, all' + + ' ongoing recordings will be stopped and this recording' + + ' functionality will be disabled for future WebRTC calls. Recordings' + + ' in multiple tabs are supported as well as multiple recordings in' + + ' the same tab. When enabling, you select a base filename to which' + + ' suffixes will be appended as</p>' + + '<p><div><base filename>.<render process ID>' + + '.aec_dump.<recording ID></div>' + + '<div><base filename>.<render process ID>' + + '.source_input.<stream ID>.pcm</div></p>' + + '<p class=audio-recordings-info>If recordings are disabled and then' + + ' enabled using the same base filename, the files will be appended' + + ' to and may become invalid. It is recommended to choose a new base' + + ' filename each time or move the produced files before enabling' + + ' again.</p>'; content.getElementsByTagName('a')[0].addEventListener( 'click', this.onDownloadData_.bind(this));
diff --git a/content/browser/resources/media/webrtc_internals.css b/content/browser/resources/media/webrtc_internals.css index e98d399..54eec7e 100644 --- a/content/browser/resources/media/webrtc_internals.css +++ b/content/browser/resources/media/webrtc_internals.css
@@ -117,3 +117,7 @@ .user-media-request-div-class > div { margin: 5px 0 5px 0; } + +.audio-recordings-info { + max-width: 60em; +}
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc index 01b7947..b8e1b3be 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -131,6 +131,7 @@ static const char* kForwardSwitches[] = { switches::kAllowSandboxDebugging, switches::kDisableSeccompFilterSandbox, + switches::kEnableHeapProfiling, switches::kEnableLogging, // Support, e.g., --enable-logging=stderr. // Zygote process needs to know what resources to have loaded when it // becomes a renderer process.
diff --git a/content/child/web_data_consumer_handle_impl.cc b/content/child/web_data_consumer_handle_impl.cc index dbe27be..fff3110 100644 --- a/content/child/web_data_consumer_handle_impl.cc +++ b/content/child/web_data_consumer_handle_impl.cc
@@ -31,7 +31,7 @@ WebDataConsumerHandleImpl::ReaderImpl::ReaderImpl( scoped_refptr<Context> context, Client* client) - : context_(context), handle_watcher_(14), client_(client) { + : context_(context), client_(client) { if (client_) StartWatching(); }
diff --git a/content/common/host_discardable_shared_memory_manager.cc b/content/common/host_discardable_shared_memory_manager.cc index 97351e5..8d904e1d 100644 --- a/content/common/host_discardable_shared_memory_manager.cc +++ b/content/common/host_discardable_shared_memory_manager.cc
@@ -196,6 +196,22 @@ child_tracing_process_id, segment_id); pmd->CreateSharedGlobalAllocatorDump(shared_segment_guid); pmd->AddOwnershipEdge(dump->guid(), shared_segment_guid); + +#if defined(COUNT_RESIDENT_BYTES_SUPPORTED) + if (args.level_of_detail == + base::trace_event::MemoryDumpLevelOfDetail::DETAILED) { + size_t resident_size = + base::trace_event::ProcessMemoryDump::CountResidentBytes( + segment->memory()->memory(), segment->memory()->mapped_size()); + + // This is added to the global dump since it has to be attributed to + // both the allocator dumps involved. + pmd->GetSharedGlobalAllocatorDump(shared_segment_guid) + ->AddScalar("resident_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + static_cast<uint64>(resident_size)); + } +#endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) } } return true;
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc index e0e3a489..c939e64 100644 --- a/content/renderer/media/webrtc_audio_device_impl.cc +++ b/content/renderer/media/webrtc_audio_device_impl.cc
@@ -44,13 +44,13 @@ Terminate(); } -int32_t WebRtcAudioDeviceImpl::AddRef() { +int32_t WebRtcAudioDeviceImpl::AddRef() const { // We can be AddRefed and released on both the UI thread as well as // libjingle's signaling thread. return base::subtle::Barrier_AtomicIncrement(&ref_count_, 1); } -int32_t WebRtcAudioDeviceImpl::Release() { +int32_t WebRtcAudioDeviceImpl::Release() const { // We can be AddRefed and released on both the UI thread as well as // libjingle's signaling thread. int ret = base::subtle::Barrier_AtomicIncrement(&ref_count_, -1);
diff --git a/content/renderer/media/webrtc_audio_device_impl.h b/content/renderer/media/webrtc_audio_device_impl.h index 0368a90..a89e407 100644 --- a/content/renderer/media/webrtc_audio_device_impl.h +++ b/content/renderer/media/webrtc_audio_device_impl.h
@@ -251,8 +251,8 @@ // The creator must call AddRef() after construction and use Release() // to release the reference and delete this object. // Called on the main render thread. - int32_t AddRef() override; - int32_t Release() override; + int32_t AddRef() const override; + int32_t Release() const override; private: // webrtc::AudioDeviceModule implementation. @@ -352,7 +352,7 @@ base::ThreadChecker signaling_thread_checker_; base::ThreadChecker worker_thread_checker_; - int ref_count_; + mutable int ref_count_; // List of captures which provides access to the native audio input layer // in the browser process.
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 2f928a92..c18e4ff 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -230,6 +230,10 @@ command_line->AppendSwitch(switches::kEnableFontAntialiasing); } if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAlwaysUseComplexText)) { + command_line->AppendSwitch(switches::kAlwaysUseComplexText); + } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kExposeInternalsForTesting)) { command_line->AppendSwitch(switches::kExposeInternalsForTesting); }
diff --git a/content/shell/common/shell_switches.cc b/content/shell/common/shell_switches.cc index 9bce7af..df7d3fe 100644 --- a/content/shell/common/shell_switches.cc +++ b/content/shell/common/shell_switches.cc
@@ -41,6 +41,9 @@ // Enable font antialiasing for pixel tests. const char kEnableFontAntialiasing[] = "enable-font-antialiasing"; +// Always use the complex text path for layout tests. +const char kAlwaysUseComplexText[] = "always-use-complex-text"; + // Enables the leak detection of loading webpages. This allows us to check // whether or not reloading a webpage releases web-related objects correctly. const char kEnableLeakDetection[] = "enable-leak-detection";
diff --git a/content/shell/common/shell_switches.h b/content/shell/common/shell_switches.h index 7e947e1..129924c 100644 --- a/content/shell/common/shell_switches.h +++ b/content/shell/common/shell_switches.h
@@ -22,6 +22,7 @@ extern const char kExposeIpcEcho[]; extern const char kEnableAccelerated2DCanvas[]; extern const char kEnableFontAntialiasing[]; +extern const char kAlwaysUseComplexText[]; extern const char kEnableLeakDetection[]; extern const char kEncodeBinary[]; extern const char kExposeInternalsForTesting[];
diff --git a/content/shell/renderer/layout_test/layout_test_render_process_observer.cc b/content/shell/renderer/layout_test/layout_test_render_process_observer.cc index c818b73..71d29c4d 100644 --- a/content/shell/renderer/layout_test/layout_test_render_process_observer.cc +++ b/content/shell/renderer/layout_test/layout_test_render_process_observer.cc
@@ -75,7 +75,10 @@ switches::kEnableFontAntialiasing)) { blink::setFontAntialiasingEnabledForTest(true); } - + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAlwaysUseComplexText)) { + blink::setAlwaysUseComplexTextForTest(true); + } } void LayoutTestRenderProcessObserver::OnRenderProcessShutdown() {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 1e50f93..0f1a6a8 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -474,6 +474,7 @@ ] } else { sources -= [ + "../browser/accessibility/touch_accessibility_aura_browsertest.cc", "../browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc", "../browser/web_contents/web_contents_view_aura_browsertest.cc", ] @@ -578,7 +579,9 @@ ] } - data_deps = [ "//third_party/mesa:osmesa" ] + data_deps = [ + "//third_party/mesa:osmesa", + ] if (!is_win) { sources += [ "../browser/file_descriptor_info_impl_unittest.cc" ]
diff --git a/device/bluetooth/bluetooth_chromeos_unittest.cc b/device/bluetooth/bluetooth_chromeos_unittest.cc index 1f15bbd..49b5b59 100644 --- a/device/bluetooth/bluetooth_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_chromeos_unittest.cc
@@ -157,7 +157,7 @@ void QuitMessageLoop() { if (base::MessageLoop::current() && base::MessageLoop::current()->is_running()) { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } } }; @@ -354,7 +354,7 @@ void QuitMessageLoop() { if (base::MessageLoop::current() && base::MessageLoop::current()->is_running()) { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } } };
diff --git a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc index 24eebaf..d93dcc2f 100644 --- a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
@@ -168,7 +168,7 @@ void QuitMessageLoop() { if (base::MessageLoop::current() && base::MessageLoop::current()->is_running()) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } base::MessageLoop message_loop_;
diff --git a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc b/device/bluetooth/bluetooth_socket_chromeos_unittest.cc index 747b857..477f3a7 100644 --- a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_socket_chromeos_unittest.cc
@@ -100,7 +100,7 @@ void SuccessCallback() { ++success_callback_count_; - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void ErrorCallback(const std::string& message) { @@ -108,21 +108,21 @@ last_message_ = message; if (message_loop_.is_running()) - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void ConnectToServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) { ++success_callback_count_; last_socket_ = socket; - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void SendSuccessCallback(int bytes_sent) { ++success_callback_count_; last_bytes_sent_ = bytes_sent; - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void ReceiveSuccessCallback(int bytes_received, @@ -131,7 +131,7 @@ last_bytes_received_ = bytes_received; last_io_buffer_ = io_buffer; - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void ReceiveErrorCallback(BluetoothSocket::ErrorReason reason, @@ -140,7 +140,7 @@ last_reason_ = reason; last_message_ = error_message; - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void CreateServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) { @@ -148,7 +148,7 @@ last_socket_ = socket; if (message_loop_.is_running()) - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void AcceptSuccessCallback(const BluetoothDevice* device, @@ -157,7 +157,7 @@ last_device_ = device; last_socket_ = socket; - message_loop_.Quit(); + message_loop_.QuitWhenIdle(); } void ImmediateSuccessCallback() {
diff --git a/device/bluetooth/test/test_bluetooth_adapter_observer.cc b/device/bluetooth/test/test_bluetooth_adapter_observer.cc index 74903a0..811ffb6 100644 --- a/device/bluetooth/test/test_bluetooth_adapter_observer.cc +++ b/device/bluetooth/test/test_bluetooth_adapter_observer.cc
@@ -302,7 +302,7 @@ void TestBluetoothAdapterObserver::QuitMessageLoop() { if (base::MessageLoop::current() && base::MessageLoop::current()->is_running()) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } } // namespace device
diff --git a/extensions/browser/api/alarms/alarms_api_unittest.cc b/extensions/browser/api/alarms/alarms_api_unittest.cc index 61a469b8..b08eed39 100644 --- a/extensions/browser/api/alarms/alarms_api_unittest.cc +++ b/extensions/browser/api/alarms/alarms_api_unittest.cc
@@ -32,7 +32,7 @@ void OnAlarm(const std::string& extension_id, const Alarm& alarm) override { alarms_seen.push_back(alarm.js_alarm->name); if (base::MessageLoop::current()->is_running()) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } std::vector<std::string> alarms_seen;
diff --git a/extensions/browser/api_test_utils.cc b/extensions/browser/api_test_utils.cc index 47bcb0e..83ed5fc 100644 --- a/extensions/browser/api_test_utils.cc +++ b/extensions/browser/api_test_utils.cc
@@ -55,7 +55,7 @@ response_.reset(new bool); *response_ = success; if (should_post_quit_) { - base::MessageLoopForUI::current()->Quit(); + base::MessageLoopForUI::current()->QuitWhenIdle(); } }
diff --git a/extensions/browser/extension_icon_image_unittest.cc b/extensions/browser/extension_icon_image_unittest.cc index 29bb1ff..88c2fe41 100644 --- a/extensions/browser/extension_icon_image_unittest.cc +++ b/extensions/browser/extension_icon_image_unittest.cc
@@ -129,7 +129,7 @@ void OnExtensionIconImageChanged(IconImage* image) override { image_loaded_count_++; if (quit_in_image_loaded_) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } gfx::ImageSkia GetDefaultIcon() {
diff --git a/extensions/browser/file_reader_unittest.cc b/extensions/browser/file_reader_unittest.cc index efd43675..5d40d31 100644 --- a/extensions/browser/file_reader_unittest.cc +++ b/extensions/browser/file_reader_unittest.cc
@@ -45,7 +45,7 @@ void DidReadFile(bool success, const std::string& data) { succeeded_ = success; data_ = data; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } bool succeeded_;
diff --git a/extensions/browser/image_loader_unittest.cc b/extensions/browser/image_loader_unittest.cc index f1f2aad..530a006b 100644 --- a/extensions/browser/image_loader_unittest.cc +++ b/extensions/browser/image_loader_unittest.cc
@@ -47,14 +47,14 @@ void OnImageLoaded(const gfx::Image& image) { image_loaded_count_++; if (quit_in_image_loaded_) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); image_ = image; } void OnImageFamilyLoaded(const gfx::ImageFamily& image_family) { image_loaded_count_++; if (quit_in_image_loaded_) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); image_family_ = image_family; }
diff --git a/extensions/browser/value_store/value_store_frontend_unittest.cc b/extensions/browser/value_store/value_store_frontend_unittest.cc index be65b7b..b3030f5 100644 --- a/extensions/browser/value_store/value_store_frontend_unittest.cc +++ b/extensions/browser/value_store/value_store_frontend_unittest.cc
@@ -56,7 +56,7 @@ void GetAndWait(scoped_ptr<base::Value>* output, scoped_ptr<base::Value> result) { *output = result.Pass(); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } scoped_ptr<ValueStoreFrontend> storage_;
diff --git a/extensions/common/permissions/OWNERS b/extensions/common/permissions/OWNERS new file mode 100644 index 0000000..1b2e1c5 --- /dev/null +++ b/extensions/common/permissions/OWNERS
@@ -0,0 +1,2 @@ +rdevlin.cronin@chromium.org +treib@chromium.org
diff --git a/extensions/shell/browser/shell_desktop_controller_aura.cc b/extensions/shell/browser/shell_desktop_controller_aura.cc index f89714a..2cf78efd 100644 --- a/extensions/shell/browser/shell_desktop_controller_aura.cc +++ b/extensions/shell/browser/shell_desktop_controller_aura.cc
@@ -246,8 +246,8 @@ const aura::WindowTreeHost* host) { DCHECK_EQ(host_.get(), host); CloseAppWindows(); - base::MessageLoop::current()->PostTask(FROM_HERE, - base::MessageLoop::QuitClosure()); + base::MessageLoop::current()->PostTask( + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); } void ShellDesktopControllerAura::InitWindowManager() {
diff --git a/extensions/test/extension_test_message_listener.cc b/extensions/test/extension_test_message_listener.cc index a1970be..2712dc3c 100644 --- a/extensions/test/extension_test_message_listener.cc +++ b/extensions/test/extension_test_message_listener.cc
@@ -110,7 +110,7 @@ if (waiting_) { waiting_ = false; - base::MessageLoopForUI::current()->Quit(); + base::MessageLoopForUI::current()->QuitWhenIdle(); } } }
diff --git a/ipc/attachment_broker_privileged_mac.cc b/ipc/attachment_broker_privileged_mac.cc index 0fbf2c4..29e7833 100644 --- a/ipc/attachment_broker_privileged_mac.cc +++ b/ipc/attachment_broker_privileged_mac.cc
@@ -68,15 +68,29 @@ base::ProcessId destination_process) { switch (attachment->GetBrokerableType()) { case BrokerableAttachment::MACH_PORT: { - const internal::MachPortAttachmentMac* mach_port_attachment = - static_cast<const internal::MachPortAttachmentMac*>(attachment); + internal::MachPortAttachmentMac* mach_port_attachment = + static_cast<internal::MachPortAttachmentMac*>(attachment); MachPortWireFormat wire_format = mach_port_attachment->GetWireFormat(destination_process); - MachPortWireFormat new_wire_format = - DuplicateMachPort(wire_format, base::Process::Current().Pid()); - if (new_wire_format.mach_port == 0) + + if (destination_process == base::Process::Current().Pid()) { + RouteWireFormatToSelf(wire_format); + mach_port_attachment->reset_mach_port_ownership(); + return true; + } + + mach_port_name_t intermediate_port = CreateIntermediateMachPort( + wire_format.destination_process, + base::mac::ScopedMachSendRight(wire_format.mach_port)); + mach_port_attachment->reset_mach_port_ownership(); + if (intermediate_port == MACH_PORT_NULL) { + // TODO(erikchen): UMA metric. return false; - RouteDuplicatedMachPort(new_wire_format); + } + + MachPortWireFormat intermediate_wire_format = + CopyWireFormat(wire_format, intermediate_port); + RouteWireFormatToAnother(intermediate_wire_format); return true; } default: @@ -99,8 +113,10 @@ void AttachmentBrokerPrivilegedMac::OnDuplicateMachPort( const IPC::Message& message) { AttachmentBrokerMsg_DuplicateMachPort::Param param; - if (!AttachmentBrokerMsg_DuplicateMachPort::Read(&message, ¶m)) + if (!AttachmentBrokerMsg_DuplicateMachPort::Read(&message, ¶m)) { + // TODO(erikchen): UMA metric. return; + } IPC::internal::MachPortAttachmentMac::WireFormat wire_format = base::get<0>(param); @@ -109,21 +125,40 @@ return; } - MachPortWireFormat new_wire_format = - DuplicateMachPort(wire_format, message.get_sender_pid()); - RouteDuplicatedMachPort(new_wire_format); -} + // Acquire a send right to the Mach port. + base::ProcessId sender_pid = message.get_sender_pid(); + DCHECK_NE(sender_pid, base::GetCurrentProcId()); + base::mac::ScopedMachSendRight send_right( + AcquireSendRight(sender_pid, wire_format.mach_port)); -void AttachmentBrokerPrivilegedMac::RouteDuplicatedMachPort( - const MachPortWireFormat& wire_format) { - // This process is the destination. - if (wire_format.destination_process == base::Process::Current().Pid()) { - scoped_refptr<BrokerableAttachment> attachment( - new internal::MachPortAttachmentMac(wire_format)); - HandleReceivedAttachment(attachment); + if (wire_format.destination_process == base::GetCurrentProcId()) { + // Intentionally leak the reference, as the consumer of the Chrome IPC + // message will take ownership. + mach_port_t final_mach_port = send_right.release(); + MachPortWireFormat final_wire_format( + CopyWireFormat(wire_format, final_mach_port)); + RouteWireFormatToSelf(final_wire_format); return; } + mach_port_name_t intermediate_mach_port = CreateIntermediateMachPort( + wire_format.destination_process, + base::mac::ScopedMachSendRight(send_right.release())); + RouteWireFormatToAnother(CopyWireFormat(wire_format, intermediate_mach_port)); +} + +void AttachmentBrokerPrivilegedMac::RouteWireFormatToSelf( + const MachPortWireFormat& wire_format) { + DCHECK_EQ(wire_format.destination_process, base::Process::Current().Pid()); + scoped_refptr<BrokerableAttachment> attachment( + new internal::MachPortAttachmentMac(wire_format)); + HandleReceivedAttachment(attachment); +} + +void AttachmentBrokerPrivilegedMac::RouteWireFormatToAnother( + const MachPortWireFormat& wire_format) { + DCHECK_NE(wire_format.destination_process, base::Process::Current().Pid()); + // Another process is the destination. base::ProcessId dest = wire_format.destination_process; Sender* sender = GetSenderWithProcessId(dest); @@ -141,40 +176,24 @@ sender->Send(new AttachmentBrokerMsg_MachPortHasBeenDuplicated(wire_format)); } -AttachmentBrokerPrivilegedMac::MachPortWireFormat -AttachmentBrokerPrivilegedMac::DuplicateMachPort( - const MachPortWireFormat& wire_format, - base::ProcessId source_pid) { - // If the source is the destination, just increment the ref count. - if (source_pid == wire_format.destination_process) { - mach_port_t task_port = - port_provider_->TaskForPid(wire_format.destination_process); - kern_return_t kr = mach_port_mod_refs(task_port, wire_format.mach_port, - MACH_PORT_RIGHT_SEND, 1); - if (kr != KERN_SUCCESS) { - // TODO(erikchen): UMA metric. - return CopyWireFormat(wire_format, MACH_PORT_NULL); - } - return wire_format; +mach_port_name_t AttachmentBrokerPrivilegedMac::CreateIntermediateMachPort( + base::ProcessId pid, + base::mac::ScopedMachSendRight port_to_insert) { + DCHECK_NE(pid, base::GetCurrentProcId()); + mach_port_t task_port = port_provider_->TaskForPid(pid); + if (task_port == MACH_PORT_NULL) { + // TODO(erikchen): UMA metric. + return MACH_PORT_NULL; } - - // Acquire a send right to the memory object. - base::mac::ScopedMachSendRight memory_object( - AcquireSendRight(source_pid, wire_format.mach_port)); - if (!memory_object) - return CopyWireFormat(wire_format, MACH_PORT_NULL); - - mach_port_t task_port = - port_provider_->TaskForPid(wire_format.destination_process); - mach_port_name_t inserted_memory_object = - InsertIndirectMachPort(task_port, memory_object); - return CopyWireFormat(wire_format, inserted_memory_object); + return CreateIntermediateMachPort( + task_port, base::mac::ScopedMachSendRight(port_to_insert.release())); } -mach_port_name_t AttachmentBrokerPrivilegedMac::InsertIndirectMachPort( +mach_port_name_t AttachmentBrokerPrivilegedMac::CreateIntermediateMachPort( mach_port_t task_port, - mach_port_t port_to_insert) { + base::mac::ScopedMachSendRight port_to_insert) { DCHECK_NE(mach_task_self(), task_port); + DCHECK_NE(static_cast<mach_port_name_t>(MACH_PORT_NULL), task_port); // Make a port with receive rights in the destination task. mach_port_name_t endpoint;
diff --git a/ipc/attachment_broker_privileged_mac.h b/ipc/attachment_broker_privileged_mac.h index bf0418a..f8a2871b 100644 --- a/ipc/attachment_broker_privileged_mac.h +++ b/ipc/attachment_broker_privileged_mac.h
@@ -18,6 +18,32 @@ // This class is a concrete subclass of AttachmentBrokerPrivileged for the // OSX platform. +// +// An example of the typical process by which a Mach port gets brokered. +// Definitions: +// 1. Let there be three processes P1, U2, U3. P1 is privileged. +// 2. U2 wants to send a Mach port M2 to U3. If this port is inserted into P1, +// it will be called M1. If it is inserted into U3, it will be called M3. +// 3. name() returns a serializable representation of a Mach port that can be +// passed over chrome IPC. +// 4. pid() returns the process id of a process. +// +// Process: +// 1. U2 sends a AttachmentBrokerMsg_DuplicateMachPort message to P1. The +// message contains name(M2), and pid(U3). +// 2. P1 extracts M2 into its own namespace, making M1. +// 3. P1 makes a new Mach port R in U3. +// 4. P1 sends a mach_msg with M1 to R. +// 5. P1 sends name(R) to U3. +// 6. U3 retrieves the queued message from R. The kernel automatically +// translates M1 into the namespace of U3, making M3. +// +// The logic of this class is a little bit more complex becauese any or all of +// P1, U2 and U3 may be the same, and depending on the exact configuration, +// the creation of R may not be necessary. +// +// For the rest of this file, and the corresponding implementation file, R will +// be called the "intermediate Mach port" and M3 the "final Mach port". class IPC_EXPORT AttachmentBrokerPrivilegedMac : public AttachmentBrokerPrivileged { public: @@ -51,12 +77,22 @@ MachPortWireFormat DuplicateMachPort(const MachPortWireFormat& wire_format, base::ProcessId source_process); - // Returns the name of the inserted right of a port, which contains a queued - // message with |port_to_insert|. Returns |MACH_PORT_NULL| on failure. - // |task_port| must be for a different task, and |port_to_insert| is a port - // right in the current task. - mach_port_name_t InsertIndirectMachPort(mach_port_t task_port, - mach_port_t port_to_insert); + // |pid| must be another process. + // |port_to_insert| must be a send right in the current task's name space. + // Creates an intermediate Mach port in |pid| and sends |port_to_insert| as a + // mach_msg to the intermediate Mach port. + // On success, returns the name of the intermediate Mach port. + // On failure, returns |MACH_PORT_NULL|. + // This method takes ownership of |port_to_insert|. On success, ownership is + // passed to the intermediate Mach port. + mach_port_name_t CreateIntermediateMachPort( + base::ProcessId pid, + base::mac::ScopedMachSendRight port_to_insert); + + // Same as the above method, where |task_port| is the task port of |pid|. + mach_port_name_t CreateIntermediateMachPort( + mach_port_t task_port, + base::mac::ScopedMachSendRight port_to_insert); // Acquire a send right to a named right in |pid|. // Returns MACH_PORT_NULL on error. @@ -73,9 +109,18 @@ MachPortWireFormat CopyWireFormat(const MachPortWireFormat& wire_format, uint32_t mach_port); - // If the mach port's destination is this process, queue it and notify the - // observers. Otherwise, send it in an IPC to its destination. - void RouteDuplicatedMachPort(const MachPortWireFormat& wire_format); + // |wire_format.destination_process| must be this process. + // |wire_format.mach_port| must be the final Mach port. + // Consumes a reference to |wire_format.mach_port|, as ownership is implicitly + // passed to the consumer of the Chrome IPC message. + // Makes an attachment, queues it, and notifies the observers. + void RouteWireFormatToSelf(const MachPortWireFormat& wire_format); + + // |wire_format.destination_process| must be another process. + // |wire_format.mach_port| must be the intermediate Mach port. + // Ownership of |wire_format.mach_port| is implicitly passed to the process + // that receives the Chrome IPC message. + void RouteWireFormatToAnother(const MachPortWireFormat& wire_format); base::PortProvider* port_provider_;
diff --git a/ipc/attachment_broker_privileged_mac_unittest.cc b/ipc/attachment_broker_privileged_mac_unittest.cc index 3c5f3173..8c82b8d9 100644 --- a/ipc/attachment_broker_privileged_mac_unittest.cc +++ b/ipc/attachment_broker_privileged_mac_unittest.cc
@@ -163,6 +163,12 @@ return names_count; } +// Increments the ref count for the right/name pair. +void IncrementMachRefCount(mach_port_name_t name, mach_port_right_t right) { + kern_return_t kr = mach_port_mod_refs(mach_task_self(), name, right, 1); + MACH_CHECK(kr == KERN_SUCCESS, kr) << "GetRefCount"; +} + // Sets up the mach communication ports with the server. Returns a port to which // the server will send mach objects. // |original_name_count| is an output variable that describes the number of @@ -266,9 +272,13 @@ CreateAndPopulateSharedMemoryHandle(s_memory_size); ASSERT_TRUE(shared_memory->handle().IsValid()); - // Insert it indirectly into the destination task. - mach_port_name_t inserted_memory_object = broker.InsertIndirectMachPort( - client_task_port_, shared_memory->handle().GetMemoryObject()); + // Insert the memory object into the destination task, via an intermediate + // port. + IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), + MACH_PORT_RIGHT_SEND); + mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( + client_task_port_, base::mac::ScopedMachSendRight( + shared_memory->handle().GetMemoryObject())); EXPECT_NE(inserted_memory_object, static_cast<mach_port_name_t>(MACH_PORT_NULL)); SendUInt32(client_port_, inserted_memory_object); @@ -323,10 +333,14 @@ CreateAndPopulateSharedMemoryHandle(s_memory_size); ASSERT_TRUE(shared_memory->handle().IsValid()); - // Insert it indirectly into the destination task, twice. + // Insert the memory object into the destination task, via an intermediate + // port, twice. for (int i = 0; i < 2; ++i) { - mach_port_name_t inserted_memory_object = broker.InsertIndirectMachPort( - client_task_port_, shared_memory->handle().GetMemoryObject()); + IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), + MACH_PORT_RIGHT_SEND); + mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( + client_task_port_, base::mac::ScopedMachSendRight( + shared_memory->handle().GetMemoryObject())); EXPECT_NE(inserted_memory_object, static_cast<mach_port_name_t>(MACH_PORT_NULL)); SendUInt32(client_port_, inserted_memory_object); @@ -408,9 +422,13 @@ CreateAndPopulateSharedMemoryHandle(s_memory_size); ASSERT_TRUE(shared_memory->handle().IsValid()); - // Insert it indirectly into the destination task. - mach_port_name_t inserted_memory_object = broker.InsertIndirectMachPort( - client_task_port_, shared_memory->handle().GetMemoryObject()); + // Insert the memory object into the destination task, via an intermediate + // port. + IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), + MACH_PORT_RIGHT_SEND); + mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( + client_task_port_, base::mac::ScopedMachSendRight( + shared_memory->handle().GetMemoryObject())); EXPECT_NE(inserted_memory_object, static_cast<mach_port_name_t>(MACH_PORT_NULL)); SendUInt32(client_port_, inserted_memory_object);
diff --git a/ipc/ipc_channel_posix_unittest.cc b/ipc/ipc_channel_posix_unittest.cc index 99bd68b..5dc4de46 100644 --- a/ipc/ipc_channel_posix_unittest.cc +++ b/ipc/ipc_channel_posix_unittest.cc
@@ -89,7 +89,7 @@ loop->QuitNow(); } else { // Die as soon as Run is called. - loop->task_runner()->PostTask(FROM_HERE, loop->QuitClosure()); + loop->task_runner()->PostTask(FROM_HERE, loop->QuitWhenIdleClosure()); } } @@ -189,7 +189,8 @@ // in the case of a bad test. Usually, the run loop will quit sooner than // that because all tests use a IPCChannelPosixTestListener which quits the // current run loop on any channel activity. - loop->task_runner()->PostDelayedTask(FROM_HERE, loop->QuitClosure(), delay); + loop->task_runner()->PostDelayedTask(FROM_HERE, loop->QuitWhenIdleClosure(), + delay); loop->Run(); }
diff --git a/ipc/ipc_fuzzing_tests.cc b/ipc/ipc_fuzzing_tests.cc index 769922d0..7f89308 100644 --- a/ipc/ipc_fuzzing_tests.cc +++ b/ipc/ipc_fuzzing_tests.cc
@@ -185,7 +185,7 @@ --message_count_; --pending_messages_; if (0 == message_count_) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } void ReplyMsgNotHandled(uint32_t type_id) { @@ -212,7 +212,7 @@ bool OnMessageReceived(const IPC::Message& msg) override { last_msg_ = new IPC::Message(msg); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); return true; }
diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc index 22965da2..a3b4d4e8 100644 --- a/ipc/ipc_send_fds_test.cc +++ b/ipc/ipc_send_fds_test.cc
@@ -73,7 +73,7 @@ } void OnChannelError() override { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } protected: @@ -96,7 +96,7 @@ ++num_fds_received_; if (num_fds_received_ == kNumFDsToSend * kNumMessages) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } private:
diff --git a/ipc/ipc_test_channel_listener.cc b/ipc/ipc_test_channel_listener.cc index 7d1832d..4d25ca3 100644 --- a/ipc/ipc_test_channel_listener.cc +++ b/ipc/ipc_test_channel_listener.cc
@@ -49,12 +49,12 @@ void TestChannelListener::OnChannelError() { // There is a race when closing the channel so the last message may be lost. EXPECT_LE(messages_left_, 1); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } void TestChannelListener::SendNextMessage() { if (--messages_left_ <= 0) - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); else SendOneMessage(sender_, "Foo"); }
diff --git a/ipc/ipc_test_sink.h b/ipc/ipc_test_sink.h index 5539c98..d964498 100644 --- a/ipc/ipc_test_sink.h +++ b/ipc/ipc_test_sink.h
@@ -59,7 +59,7 @@ // public: // virtual bool OnMessageReceived(const IPC::Message& msg) { // <do something with the message> -// MessageLoop::current()->Quit(); +// MessageLoop::current()->QuitWhenIdle(); // return false; // to store the message in the sink, or true to drop it // } // };
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc index 58d3e9f7..f1982533b 100644 --- a/ipc/mojo/ipc_channel_mojo_unittest.cc +++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -44,7 +44,7 @@ EXPECT_TRUE(iter.ReadString(&should_be_ok)); EXPECT_EQ(should_be_ok, "OK"); received_ok_ = true; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); return true; } @@ -202,14 +202,14 @@ } void OnChannelConnected(int32_t peer_pid) override { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } bool OnMessageReceived(const IPC::Message& message) override { return true; } void OnChannelError() override { has_error_ = true; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } bool has_error() const { return has_error_; } @@ -244,7 +244,7 @@ } void OnChannelConnected(int32_t peer_pid) override { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } }; @@ -394,7 +394,7 @@ bool OnMessageReceived(const IPC::Message& message) override { base::PickleIterator iter(message); HandleSendingHelper::ReadReceivedPipe(message, &iter); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); ListenerThatExpectsOK::SendOK(sender_); return true; } @@ -478,7 +478,7 @@ MojoClose(handle.value()); } - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); ListenerThatExpectsOK::SendOK(sender_); return true; } @@ -597,7 +597,7 @@ void OnChannelConnected(int32_t peer_pid) override { ListenerThatExpectsOK::SendOK(sender_); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } void set_sender(IPC::Sender* sender) { sender_ = sender; } @@ -686,7 +686,7 @@ bool OnMessageReceived(const IPC::Message& message) override { base::PickleIterator iter(message); HandleSendingHelper::ReadReceivedFile(message, &iter); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); ListenerThatExpectsOK::SendOK(sender_); return true; } @@ -751,7 +751,7 @@ base::PickleIterator iter(message); HandleSendingHelper::ReadReceivedFile(message, &iter); HandleSendingHelper::ReadReceivedPipe(message, &iter); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); ListenerThatExpectsOK::SendOK(sender_); return true; } @@ -816,7 +816,7 @@ public: void OnChannelConnected(int32_t peer_pid) override { EXPECT_EQ(peer_pid, kMagicChildId); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } bool OnMessageReceived(const IPC::Message& message) override {
diff --git a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc index 528c235..391e9530 100644 --- a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc +++ b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
@@ -37,11 +37,11 @@ mojo::embedder::ScopedPlatformHandle handle, int32 peer_pid) { passed_ = true; - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } void TestingDelegate::OnBootstrapError() { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // Times out on Android; see http://crbug.com/502290
diff --git a/ipc/sync_socket_unittest.cc b/ipc/sync_socket_unittest.cc index 9bf19dd6..7184761 100644 --- a/ipc/sync_socket_unittest.cc +++ b/ipc/sync_socket_unittest.cc
@@ -95,9 +95,7 @@ // When the client responds, it sends back a shutdown message, // which causes the message loop to exit. - void OnMsgClassShutdown() { - base::MessageLoop::current()->Quit(); - } + void OnMsgClassShutdown() { base::MessageLoop::current()->QuitWhenIdle(); } IPC::Channel* chan_; @@ -153,7 +151,7 @@ EXPECT_EQ(0U, socket_->Peek()); IPC::Message* msg = new MsgClassShutdown(); EXPECT_TRUE(chan_->Send(msg)); - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } base::SyncSocket* socket_;
diff --git a/mojo/android/system/core_impl.cc b/mojo/android/system/core_impl.cc index 56ad006..21589876 100644 --- a/mojo/android/system/core_impl.cc +++ b/mojo/android/system/core_impl.cc
@@ -369,7 +369,7 @@ MojoAsyncWaitID cancel_id; if (static_cast<MojoHandle>(mojo_handle) != MOJO_HANDLE_INVALID) { cancel_id = Environment::GetDefaultAsyncWaiter()->AsyncWait( - 1, mojo_handle, signals, deadline, AsyncWaitCallback, callback_data); + mojo_handle, signals, deadline, AsyncWaitCallback, callback_data); } else { cancel_id = kInvalidHandleCancelID; base::MessageLoop::current()->PostTask(
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc index a9ce5566..b6e18f7 100644 --- a/mojo/edk/system/core.cc +++ b/mojo/edk/system/core.cc
@@ -546,7 +546,7 @@ for (uint32_t i = 0; i < num_handles; i++) { scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); if (!dispatcher) { - if (result_index && result_index) + if (result_index) *result_index = i; return MOJO_RESULT_INVALID_ARGUMENT; }
diff --git a/mojo/edk/system/data_pipe_consumer_dispatcher.cc b/mojo/edk/system/data_pipe_consumer_dispatcher.cc index baf0f1ac..798537de 100644 --- a/mojo/edk/system/data_pipe_consumer_dispatcher.cc +++ b/mojo/edk/system/data_pipe_consumer_dispatcher.cc
@@ -215,17 +215,7 @@ (flags & MOJO_READ_DATA_FLAG_PEEK)) return MOJO_RESULT_INVALID_ARGUMENT; - bool all_or_none = flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE; - uint32_t min_num_bytes_to_read = 0; - if (all_or_none) { - min_num_bytes_to_read = *buffer_num_bytes; - if (min_num_bytes_to_read % options_.element_num_bytes != 0) - return MOJO_RESULT_INVALID_ARGUMENT; - } - uint32_t max_num_bytes_to_read = static_cast<uint32_t>(data_.size()); - if (min_num_bytes_to_read > max_num_bytes_to_read) - return error_ ? MOJO_RESULT_FAILED_PRECONDITION : MOJO_RESULT_OUT_OF_RANGE; if (max_num_bytes_to_read == 0) return error_ ? MOJO_RESULT_FAILED_PRECONDITION : MOJO_RESULT_SHOULD_WAIT; @@ -243,6 +233,7 @@ if (!in_two_phase_read_) return MOJO_RESULT_FAILED_PRECONDITION; + HandleSignalsState old_state = GetHandleSignalsStateImplNoLock(); MojoResult rv; if (num_bytes_read > two_phase_max_bytes_read_ || num_bytes_read % options_.element_num_bytes != 0) { @@ -255,10 +246,8 @@ in_two_phase_read_ = false; two_phase_max_bytes_read_ = 0; - // If we're now readable, we *became* readable (since we weren't readable - // during the two-phase read), so awake consumer awakables. HandleSignalsState new_state = GetHandleSignalsStateImplNoLock(); - if (new_state.satisfies(MOJO_HANDLE_SIGNAL_READABLE)) + if (!new_state.equals(old_state)) awakable_list_.AwakeForStateChange(new_state); return rv;
diff --git a/mojo/edk/system/data_pipe_producer_dispatcher.cc b/mojo/edk/system/data_pipe_producer_dispatcher.cc index 2b37c17..3a579c8 100644 --- a/mojo/edk/system/data_pipe_producer_dispatcher.cc +++ b/mojo/edk/system/data_pipe_producer_dispatcher.cc
@@ -164,19 +164,6 @@ if (error_) return MOJO_RESULT_FAILED_PRECONDITION; - bool all_or_none = flags & MOJO_WRITE_DATA_FLAG_ALL_OR_NONE; - uint32_t min_num_bytes_to_write = 0; - if (all_or_none) { - min_num_bytes_to_write = *buffer_num_bytes; - if (min_num_bytes_to_write % options_.element_num_bytes != 0) - return MOJO_RESULT_INVALID_ARGUMENT; - if (min_num_bytes_to_write > options_.capacity_num_bytes) { - // Don't return "should wait" since you can't wait for a specified amount - // of data. - return MOJO_RESULT_OUT_OF_RANGE; - } - } - // See comment in WriteDataImplNoLock about ignoring capacity_num_bytes. if (*buffer_num_bytes == 0) *buffer_num_bytes = options_.capacity_num_bytes;
diff --git a/mojo/edk/system/data_pipe_unittest.cc b/mojo/edk/system/data_pipe_unittest.cc index 1fdb02d..bfb3aef 100644 --- a/mojo/edk/system/data_pipe_unittest.cc +++ b/mojo/edk/system/data_pipe_unittest.cc
@@ -943,150 +943,6 @@ ASSERT_EQ(0u, num_bytes); } -TEST_F(DataPipeTest, DISABLED_TwoPhaseAllOrNone) { - const MojoCreateDataPipeOptions options = { - kSizeOfOptions, // |struct_size|. - MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. - static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|. - 10 * sizeof(int32_t) // |capacity_num_bytes|. - }; - ASSERT_EQ(MOJO_RESULT_OK, Create(&options)); - MojoHandleSignalsState hss; - - // Try writing way too much (two-phase). - uint32_t num_bytes = 20u * sizeof(int32_t); - void* write_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE, - BeginWriteData(&write_ptr, &num_bytes, true)); - - // Try writing an amount which isn't a multiple of the element size - // (two-phase). - static_assert(sizeof(int32_t) > 1u, "Wow! int32_t's have size 1"); - num_bytes = 1u; - write_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - BeginWriteData(&write_ptr, &num_bytes, true)); - - // Try reading way too much (two-phase). - num_bytes = 20u * sizeof(int32_t); - const void* read_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE, - BeginReadData(&read_ptr, &num_bytes, true)); - - // Write half (two-phase). - num_bytes = 5u * sizeof(int32_t); - write_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_OK, BeginWriteData(&write_ptr, &num_bytes, true)); - // May provide more space than requested. - EXPECT_GE(num_bytes, 5u * sizeof(int32_t)); - EXPECT_TRUE(write_ptr); - Seq(0, 5, static_cast<int32_t*>(write_ptr)); - ASSERT_EQ(MOJO_RESULT_OK, EndWriteData(5u * sizeof(int32_t))); - - // Wait for data. - // TODO(vtl): (See corresponding TODO in AllOrNone.) - hss = MojoHandleSignalsState(); - ASSERT_EQ(MOJO_RESULT_OK, - MojoWait(consumer_, MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfiable_signals); - - // Try reading an amount which isn't a multiple of the element size - // (two-phase). - num_bytes = 1u; - read_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - BeginReadData(&read_ptr, &num_bytes, true)); - - // Read one (two-phase). - num_bytes = 1u * sizeof(int32_t); - read_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_OK, BeginReadData(&read_ptr, &num_bytes, true)); - EXPECT_GE(num_bytes, 1u * sizeof(int32_t)); - ASSERT_EQ(0, static_cast<const int32_t*>(read_ptr)[0]); - ASSERT_EQ(MOJO_RESULT_OK, EndReadData(1u * sizeof(int32_t))); - - // We should have four left, leaving room for six. - num_bytes = 0u; - ASSERT_EQ(MOJO_RESULT_OK, QueryData(&num_bytes)); - ASSERT_EQ(4u * sizeof(int32_t), num_bytes); - - // Assuming a tight circular buffer of the specified capacity, we can't do a - // two-phase write of six now. - num_bytes = 6u * sizeof(int32_t); - write_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE, - BeginWriteData(&write_ptr, &num_bytes, true)); - - // TODO(vtl): Hack (see also the TODO above): We can't currently wait for a - // specified amount of space to be available, so poll. - for (size_t i = 0; i < kMaxPoll; i++) { - // Write six elements (simple), filling the buffer. - num_bytes = 6u * sizeof(int32_t); - int32_t buffer[100]; - Seq(100, 6, buffer); - MojoResult result = WriteData(buffer, &num_bytes, true); - if (result == MOJO_RESULT_OK) - break; - ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE, result); - - test::Sleep(test::EpsilonDeadline()); - } - ASSERT_EQ(6u * sizeof(int32_t), num_bytes); - - // TODO(vtl): Hack: poll again. - for (size_t i = 0; i < kMaxPoll; i++) { - // We have ten. - num_bytes = 0u; - ASSERT_EQ(MOJO_RESULT_OK, QueryData(&num_bytes)); - if (num_bytes >= 10u * sizeof(int32_t)) - break; - - test::Sleep(test::EpsilonDeadline()); - } - ASSERT_EQ(10u * sizeof(int32_t), num_bytes); - - // Note: Whether a two-phase read of ten would fail here or not is - // implementation-dependent. - - // Close the producer. - CloseProducer(); - - // A two-phase read of nine should work. - num_bytes = 9u * sizeof(int32_t); - read_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_OK, BeginReadData(&read_ptr, &num_bytes, true)); - EXPECT_GE(num_bytes, 9u * sizeof(int32_t)); - ASSERT_EQ(1, static_cast<const int32_t*>(read_ptr)[0]); - ASSERT_EQ(2, static_cast<const int32_t*>(read_ptr)[1]); - ASSERT_EQ(3, static_cast<const int32_t*>(read_ptr)[2]); - ASSERT_EQ(4, static_cast<const int32_t*>(read_ptr)[3]); - ASSERT_EQ(100, static_cast<const int32_t*>(read_ptr)[4]); - ASSERT_EQ(101, static_cast<const int32_t*>(read_ptr)[5]); - ASSERT_EQ(102, static_cast<const int32_t*>(read_ptr)[6]); - ASSERT_EQ(103, static_cast<const int32_t*>(read_ptr)[7]); - ASSERT_EQ(104, static_cast<const int32_t*>(read_ptr)[8]); - ASSERT_EQ(MOJO_RESULT_OK, EndReadData(9u * sizeof(int32_t))); - - // Wait for peer closed. - hss = MojoHandleSignalsState(); - ASSERT_EQ(MOJO_RESULT_OK, - MojoWait(consumer_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, - MOJO_DEADLINE_INDEFINITE, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfied_signals); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfiable_signals); - - // A two-phase read of two should fail, with "failed precondition". - num_bytes = 2u * sizeof(int32_t); - read_ptr = nullptr; - ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - BeginReadData(&read_ptr, &num_bytes, true)); -} - /* jam: this is testing that the implementation uses a circular buffer, which we don't use currently.
diff --git a/mojo/edk/system/message_pipe_dispatcher.cc b/mojo/edk/system/message_pipe_dispatcher.cc index 0e09554..1af5b4d 100644 --- a/mojo/edk/system/message_pipe_dispatcher.cc +++ b/mojo/edk/system/message_pipe_dispatcher.cc
@@ -266,7 +266,7 @@ // TODO(jam): Copied below from RawChannelWin. See commment above // GetReadPlatformHandles. - ScopedPlatformHandleVectorPtr platform_handles; + ScopedPlatformHandleVectorPtr temp_platform_handles; if (message_view.transport_data_buffer()) { size_t num_platform_handles; const void* platform_handle_table; @@ -275,10 +275,10 @@ &platform_handle_table); if (num_platform_handles > 0) { - platform_handles = + temp_platform_handles = GetReadPlatformHandles(num_platform_handles, platform_handle_table).Pass(); - if (!platform_handles) { + if (!temp_platform_handles) { LOG(ERROR) << "Invalid number of platform handles received"; return nullptr; } @@ -292,7 +292,8 @@ DCHECK(message_view.transport_data_buffer()); message->SetDispatchers(TransportData::DeserializeDispatchers( message_view.transport_data_buffer(), - message_view.transport_data_buffer_size(), platform_handles.Pass())); + message_view.transport_data_buffer_size(), + temp_platform_handles.Pass())); } rv->message_queue_.AddMessage(message.Pass());
diff --git a/mojo/environment/default_async_waiter_impl.cc b/mojo/environment/default_async_waiter_impl.cc index 0887f99..a27aa93d 100644 --- a/mojo/environment/default_async_waiter_impl.cc +++ b/mojo/environment/default_async_waiter_impl.cc
@@ -19,15 +19,14 @@ callback(closure, result); } -MojoAsyncWaitID AsyncWait(int id, - MojoHandle handle, +MojoAsyncWaitID AsyncWait(MojoHandle handle, MojoHandleSignals signals, MojoDeadline deadline, MojoAsyncWaitCallback callback, void* closure) { CHECK(handle != MOJO_HANDLE_INVALID); // This instance will be deleted when done or cancelled. - common::HandleWatcher* watcher = new common::HandleWatcher(id); + common::HandleWatcher* watcher = new common::HandleWatcher(); watcher->Start(Handle(handle), signals, deadline, base::Bind(&OnHandleReady, watcher, callback, closure)); return reinterpret_cast<MojoAsyncWaitID>(watcher);
diff --git a/mojo/message_pump/handle_watcher.cc b/mojo/message_pump/handle_watcher.cc index 146c6f2f..964f1e2 100644 --- a/mojo/message_pump/handle_watcher.cc +++ b/mojo/message_pump/handle_watcher.cc
@@ -42,12 +42,8 @@ // Tracks the data for a single call to Start(). struct WatchData { WatchData() - : location(0), - id(0), - handle_signals(MOJO_HANDLE_SIGNAL_NONE), - task_runner(NULL) {} + : id(0), handle_signals(MOJO_HANDLE_SIGNAL_NONE), task_runner(NULL) {} - int location; WatcherID id; Handle handle; MojoHandleSignals handle_signals; @@ -103,8 +99,9 @@ DCHECK_EQ(0u, handle_to_data_.count(data.handle)); handle_to_data_[data.handle] = data; - MessagePumpMojo::current()->AddHandler(data.location, this, data.handle, - data.handle_signals, data.deadline); + MessagePumpMojo::current()->AddHandler(this, data.handle, + data.handle_signals, + data.deadline); } void WatcherBackend::StopWatching(WatcherID watcher_id) { @@ -166,8 +163,7 @@ // stop watching the handle. When the handle is ready |callback| is notified // on the thread StartWatching() was invoked on. // This may be invoked on any thread. - WatcherID StartWatching(int location, - const Handle& handle, + WatcherID StartWatching(const Handle& handle, MojoHandleSignals handle_signals, base::TimeTicks deadline, const base::Callback<void(MojoResult)>& callback); @@ -230,14 +226,12 @@ } WatcherID WatcherThreadManager::StartWatching( - int location, const Handle& handle, MojoHandleSignals handle_signals, base::TimeTicks deadline, const base::Callback<void(MojoResult)>& callback) { RequestData request_data; request_data.type = REQUEST_START; - request_data.start_data.location = location; request_data.start_data.id = watcher_id_generator_.GetNext(); request_data.start_data.handle = handle; request_data.start_data.callback = callback; @@ -378,9 +372,8 @@ handle_(handle) { DCHECK(MessagePumpMojo::IsCurrent()); - MessagePumpMojo::current()->AddHandler(watcher->location(), this, handle, - handle_signals, - MojoDeadlineToTimeTicks(deadline)); + MessagePumpMojo::current()->AddHandler( + this, handle, handle_signals, MojoDeadlineToTimeTicks(deadline)); } ~SameThreadWatchingState() override { @@ -422,7 +415,8 @@ : StateBase(watcher, callback), weak_factory_(this) { watcher_id_ = WatcherThreadManager::GetInstance()->StartWatching( - watcher->location(), handle, handle_signals, + handle, + handle_signals, MojoDeadlineToTimeTicks(deadline), base::Bind(&SecondaryThreadWatchingState::NotifyHandleReady, weak_factory_.GetWeakPtr())); @@ -449,7 +443,8 @@ // HandleWatcher --------------------------------------------------------------- -HandleWatcher::HandleWatcher(int location) : location_(location) {} +HandleWatcher::HandleWatcher() { +} HandleWatcher::~HandleWatcher() { }
diff --git a/mojo/message_pump/handle_watcher.h b/mojo/message_pump/handle_watcher.h index 5da816d..4f7115a 100644 --- a/mojo/message_pump/handle_watcher.h +++ b/mojo/message_pump/handle_watcher.h
@@ -7,7 +7,6 @@ #include "base/basictypes.h" #include "base/callback_forward.h" -#include "base/location.h" #include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "mojo/message_pump/mojo_message_pump_export.h" @@ -27,13 +26,11 @@ // when the handle is ready, or the deadline has expired. class MOJO_MESSAGE_PUMP_EXPORT HandleWatcher { public: - explicit HandleWatcher(int location); + HandleWatcher(); // The destructor implicitly stops listening. See Stop() for details. ~HandleWatcher(); - int location() const { return location_; } - // Starts listening for |handle|. This implicitly invokes Stop(). In other // words, Start() performs one asynchronous watch at a time. It is ok to call // Start() multiple times, but it cancels any existing watches. |callback| is @@ -55,8 +52,6 @@ class SameThreadWatchingState; class SecondaryThreadWatchingState; - const int location_; - // If non-NULL Start() has been invoked. scoped_ptr<StateBase> state_;
diff --git a/mojo/message_pump/handle_watcher_unittest.cc b/mojo/message_pump/handle_watcher_unittest.cc index 8248005..bfbfa9f 100644 --- a/mojo/message_pump/handle_watcher_unittest.cc +++ b/mojo/message_pump/handle_watcher_unittest.cc
@@ -152,7 +152,7 @@ MessagePipe test_pipe; ASSERT_TRUE(test_pipe.handle0.is_valid()); CallbackHelper callback_helper; - HandleWatcher watcher(0); + HandleWatcher watcher; callback_helper.Start(&watcher, test_pipe.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper.got_callback()); @@ -175,21 +175,21 @@ ASSERT_TRUE(test_pipe2.handle0.is_valid()); ASSERT_TRUE(test_pipe3.handle0.is_valid()); - HandleWatcher watcher1(0); + HandleWatcher watcher1; callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper1.got_callback()); EXPECT_FALSE(callback_helper2.got_callback()); EXPECT_FALSE(callback_helper3.got_callback()); - HandleWatcher watcher2(0); + HandleWatcher watcher2; callback_helper2.Start(&watcher2, test_pipe2.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper1.got_callback()); EXPECT_FALSE(callback_helper2.got_callback()); EXPECT_FALSE(callback_helper3.got_callback()); - HandleWatcher watcher3(0); + HandleWatcher watcher3; callback_helper3.Start(&watcher3, test_pipe3.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper1.got_callback()); @@ -237,13 +237,13 @@ ASSERT_TRUE(test_pipe1.handle0.is_valid()); ASSERT_TRUE(test_pipe2.handle0.is_valid()); - HandleWatcher watcher1(0); + HandleWatcher watcher1; callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper1.got_callback()); EXPECT_FALSE(callback_helper2.got_callback()); - HandleWatcher watcher2(0); + HandleWatcher watcher2; callback_helper2.Start(&watcher2, test_pipe2.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper1.got_callback()); @@ -286,7 +286,7 @@ CallbackHelper callback_helper; ASSERT_TRUE(test_pipe.handle0.is_valid()); - HandleWatcher watcher(0); + HandleWatcher watcher; callback_helper.Start(&watcher, test_pipe.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper.got_callback()); @@ -311,7 +311,7 @@ ASSERT_TRUE(test_pipe3.handle0.is_valid()); // Add a watcher with an infinite timeout. - HandleWatcher watcher1(0); + HandleWatcher watcher1; callback_helper1.Start(&watcher1, test_pipe1.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper1.got_callback()); @@ -319,7 +319,7 @@ EXPECT_FALSE(callback_helper3.got_callback()); // Add another watcher wth a timeout of 500 microseconds. - HandleWatcher watcher2(0); + HandleWatcher watcher2; watcher2.Start(test_pipe2.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, 500, callback_helper2.GetCallback()); RunUntilIdle(); @@ -331,7 +331,7 @@ // watcher to wake up the background thread. tick_clock_.Advance(base::TimeDelta::FromMicroseconds(501)); - HandleWatcher watcher3(0); + HandleWatcher watcher3; callback_helper3.Start(&watcher3, test_pipe3.handle0.get()); callback_helper2.RunUntilGotCallback(); @@ -344,7 +344,7 @@ MessagePipe test_pipe; CallbackHelper callback_helper; - HandleWatcher* watcher = new HandleWatcher(0); + HandleWatcher* watcher = new HandleWatcher(); callback_helper.StartWithCallback(watcher, test_pipe.handle1.get(), base::Bind(&DeleteWatcherAndForwardResult, watcher, @@ -360,7 +360,7 @@ MojoResult result = MOJO_RESULT_OK; MessagePipe pipe; - HandleWatcher watcher(0); + HandleWatcher watcher; watcher.Start(pipe.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, @@ -397,8 +397,6 @@ base::RunLoop* run_loop, int* active_count) { struct TestData { - TestData() : watcher(0) {} - MessagePipe pipe; HandleWatcher watcher; }; @@ -411,7 +409,7 @@ MessagePipe test_pipe; ASSERT_TRUE(test_pipe.handle0.is_valid()); CallbackHelper callback_helper; - HandleWatcher watcher(0); + HandleWatcher watcher; callback_helper.Start(&watcher, test_pipe.handle0.get()); RunUntilIdle(); EXPECT_FALSE(callback_helper.got_callback());
diff --git a/mojo/message_pump/message_pump_mojo.cc b/mojo/message_pump/message_pump_mojo.cc index fd783d4b..a24349b 100644 --- a/mojo/message_pump/message_pump_mojo.cc +++ b/mojo/message_pump/message_pump_mojo.cc
@@ -38,10 +38,8 @@ // State needed for one iteration of WaitMany. The first handle and flags // corresponds to that of the control pipe. struct MessagePumpMojo::WaitState { - // This uses individual vectors for better use with WaitMany(). std::vector<Handle> handles; std::vector<MojoHandleSignals> wait_signals; - std::vector<int> locations; }; struct MessagePumpMojo::RunState { @@ -79,8 +77,7 @@ return g_tls_current_pump.Pointer()->Get(); } -void MessagePumpMojo::AddHandler(int location, - MessagePumpMojoHandler* handler, +void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler, const Handle& handle, MojoHandleSignals wait_signals, base::TimeTicks deadline) { @@ -89,7 +86,6 @@ // Assume it's an error if someone tries to reregister an existing handle. CHECK_EQ(0u, handlers_.count(handle)); Handler handler_data; - handler_data.location = location; handler_data.handler = handler; handler_data.wait_signals = wait_signals; handler_data.deadline = deadline; @@ -206,12 +202,6 @@ break; default: base::debug::Alias(&result); - base::debug::Alias(&wait_many_result.index); - if (wait_many_result.IsIndexValid()) { - const int location = wait_state.locations[wait_many_result.index]; - base::debug::Alias(&location); - } - // Unexpected result is likely fatal, crash so we can determine cause. CHECK(false); } @@ -271,13 +261,11 @@ WaitState wait_state; wait_state.handles.push_back(run_state.read_handle.get()); wait_state.wait_signals.push_back(MOJO_HANDLE_SIGNAL_READABLE); - wait_state.locations.push_back(6); for (HandleToHandler::const_iterator i = handlers_.begin(); i != handlers_.end(); ++i) { wait_state.handles.push_back(i->first); wait_state.wait_signals.push_back(i->second.wait_signals); - wait_state.locations.push_back(i->second.location); } return wait_state; }
diff --git a/mojo/message_pump/message_pump_mojo.h b/mojo/message_pump/message_pump_mojo.h index 75ef47a..d4028f1 100644 --- a/mojo/message_pump/message_pump_mojo.h +++ b/mojo/message_pump/message_pump_mojo.h
@@ -50,8 +50,7 @@ // Registers a MessagePumpMojoHandler for the specified handle. Only one // handler can be registered for a specified handle. // NOTE: a value of 0 for |deadline| indicates an indefinite timeout. - void AddHandler(int location, - MessagePumpMojoHandler* handler, + void AddHandler(MessagePumpMojoHandler* handler, const Handle& handle, MojoHandleSignals wait_signals, base::TimeTicks deadline); @@ -73,13 +72,8 @@ // Contains the data needed to track a request to AddHandler(). struct Handler { - Handler() - : location(0), - handler(nullptr), - wait_signals(MOJO_HANDLE_SIGNAL_NONE), - id(0) {} + Handler() : handler(NULL), wait_signals(MOJO_HANDLE_SIGNAL_NONE), id(0) {} - int location; MessagePumpMojoHandler* handler; MojoHandleSignals wait_signals; base::TimeTicks deadline;
diff --git a/mojo/message_pump/message_pump_mojo_unittest.cc b/mojo/message_pump/message_pump_mojo_unittest.cc index eea8e23..51f3670c 100644 --- a/mojo/message_pump/message_pump_mojo_unittest.cc +++ b/mojo/message_pump/message_pump_mojo_unittest.cc
@@ -60,7 +60,8 @@ base::MessageLoop message_loop(MessagePumpMojo::Create()); CountingMojoHandler handler; MessagePipe handles; - MessagePumpMojo::current()->AddHandler(0, &handler, handles.handle0.get(), + MessagePumpMojo::current()->AddHandler(&handler, + handles.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, base::TimeTicks()); WriteMessageRaw( @@ -80,7 +81,8 @@ CountingMojoHandler handler; MessagePipe handles; - MessagePumpMojo::current()->AddHandler(0, &handler, handles.handle0.get(), + MessagePumpMojo::current()->AddHandler(&handler, + handles.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, base::TimeTicks()); WriteMessageRaw( @@ -106,7 +108,9 @@ CountingMojoHandler handler; MessagePipe handles; MessagePumpMojo::current()->AddHandler( - 0, &handler, handles.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE, + &handler, + handles.handle0.get(), + MOJO_HANDLE_SIGNAL_READABLE, base::TimeTicks::Now() - base::TimeDelta::FromSeconds(1)); for (int i = 0; i < 2; ++i) { base::RunLoop run_loop;
diff --git a/mojo/services/network/http_connection_impl.cc b/mojo/services/network/http_connection_impl.cc index 3a24f0fea..965c27e 100644 --- a/mojo/services/network/http_connection_impl.cc +++ b/mojo/services/network/http_connection_impl.cc
@@ -36,7 +36,7 @@ using CompletionCallback = base::Callback<void(SimpleDataPipeReader*, scoped_ptr<std::string>)>; - SimpleDataPipeReader() : watcher_(11) {} + SimpleDataPipeReader() {} ~SimpleDataPipeReader() {} void Start(ScopedDataPipeConsumerHandle consumer,
diff --git a/mojo/services/network/public/cpp/web_socket_read_queue.cc b/mojo/services/network/public/cpp/web_socket_read_queue.cc index 9da7d3ab..c5923d3 100644 --- a/mojo/services/network/public/cpp/web_socket_read_queue.cc +++ b/mojo/services/network/public/cpp/web_socket_read_queue.cc
@@ -26,10 +26,8 @@ }; WebSocketReadQueue::WebSocketReadQueue(DataPipeConsumerHandle handle) - : handle_(handle), - handle_watcher_(7), - is_busy_(false), - weak_factory_(this) {} + : handle_(handle), is_busy_(false), weak_factory_(this) { +} WebSocketReadQueue::~WebSocketReadQueue() { }
diff --git a/mojo/services/network/public/cpp/web_socket_write_queue.cc b/mojo/services/network/public/cpp/web_socket_write_queue.cc index f3485d5..9a0079c 100644 --- a/mojo/services/network/public/cpp/web_socket_write_queue.cc +++ b/mojo/services/network/public/cpp/web_socket_write_queue.cc
@@ -20,10 +20,8 @@ }; WebSocketWriteQueue::WebSocketWriteQueue(DataPipeProducerHandle handle) - : handle_(handle), - handle_watcher_(8), - is_busy_(false), - weak_factory_(this) {} + : handle_(handle), is_busy_(false), weak_factory_(this) { +} WebSocketWriteQueue::~WebSocketWriteQueue() { }
diff --git a/mojo/services/network/tcp_connected_socket_impl.cc b/mojo/services/network/tcp_connected_socket_impl.cc index 3616d48..44fba13 100644 --- a/mojo/services/network/tcp_connected_socket_impl.cc +++ b/mojo/services/network/tcp_connected_socket_impl.cc
@@ -18,9 +18,7 @@ scoped_ptr<mojo::AppRefCount> app_refcount) : socket_(socket.Pass()), send_stream_(send_stream.Pass()), - receive_handle_watcher_(9), receive_stream_(receive_stream.Pass()), - send_handle_watcher_(10), binding_(this, request.Pass()), app_refcount_(app_refcount.Pass()), weak_ptr_factory_(this) {
diff --git a/mojo/services/network/url_loader_impl.cc b/mojo/services/network/url_loader_impl.cc index 5abbb10..002f2ee4 100644 --- a/mojo/services/network/url_loader_impl.cc +++ b/mojo/services/network/url_loader_impl.cc
@@ -136,7 +136,6 @@ InterfaceRequest<URLLoader> request, scoped_ptr<mojo::AppRefCount> app_refcount) : context_(context), - handle_watcher_(12), response_body_buffer_size_(0), auto_follow_redirects_(true), connected_(true),
diff --git a/native_client_sdk/src/libraries/third_party/pthreads-win32/README.chromium b/native_client_sdk/src/libraries/third_party/pthreads-win32/README.chromium index 15b8f7c7..4a88c79 100644 --- a/native_client_sdk/src/libraries/third_party/pthreads-win32/README.chromium +++ b/native_client_sdk/src/libraries/third_party/pthreads-win32/README.chromium
@@ -1,5 +1,5 @@ Name: pthreads-win32 -URL: http://sources.redhat.com/pthreads-win32/ +URL: https://www.sourceware.org/pthreads-win32/ Version: 2.9.1.0 Date: 2012-08-21 License: LGPL 2.1 @@ -13,7 +13,7 @@ This library is not shipped with Chromium. Description: -From http://sources.redhat.com/pthreads-win32/ +From https://www.sourceware.org/pthreads-win32/ The POSIX 1003.1-2001 standard defines an application programming interface (API) for writing multithreaded applications. This interface is known more
diff --git a/net/cert/ct_known_logs_static.h b/net/cert/ct_known_logs_static.h index 1f9522c..e87e5c4 100644 --- a/net/cert/ct_known_logs_static.h +++ b/net/cert/ct_known_logs_static.h
@@ -100,8 +100,6 @@ "https://ctlog.api.venafi.com/"}}; const size_t kNumKnownCTLogs = 8; -const int kGoogleOperatorId = 0; -const size_t kMaxOperatorId = 5; // The list is sorted. const char kGoogleLogIDs[][33] = {
diff --git a/net/http/http_log_util.cc b/net/http/http_log_util.cc index 87c2fd99..500f2209 100644 --- a/net/http/http_log_util.cc +++ b/net/http/http_log_util.cc
@@ -4,6 +4,7 @@ #include "net/http/http_log_util.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "net/http/http_auth_challenge_tokenizer.h" @@ -42,7 +43,7 @@ if (redact_begin == redact_end && !capture_mode.include_cookies_and_credentials()) { - // Note: this logic should be kept in sync with stripCookiesAndLoginInfo in + // Note: this logic should be kept in sync with stripCookieOrLoginInfo in // chrome/browser/resources/net_internals/log_view_painter.js. if (base::EqualsCaseInsensitiveASCII(header, "set-cookie") || @@ -73,4 +74,16 @@ std::string(redact_end, value.end()); } +std::string ElideGoAwayDebugDataForNetLog(NetLogCaptureMode capture_mode, + base::StringPiece debug_data) { + // Note: this logic should be kept in sync with stripGoAwayDebugData in + // chrome/browser/resources/net_internals/log_view_painter.js. + if (capture_mode.include_cookies_and_credentials()) { + return debug_data.as_string(); + } + + return std::string("[") + base::SizeTToString(debug_data.size()) + + std::string(" bytes were stripped]"); +} + } // namespace net
diff --git a/net/http/http_log_util.h b/net/http/http_log_util.h index 7758943..5fda79c 100644 --- a/net/http/http_log_util.h +++ b/net/http/http_log_util.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/strings/string_piece.h" #include "net/base/net_export.h" #include "net/log/net_log.h" @@ -19,6 +20,12 @@ const std::string& header, const std::string& value); +// Given an HTTP/2 GOAWAY frame |debug_data|, returns the elided version +// according to |capture_mode|. +NET_EXPORT_PRIVATE std::string ElideGoAwayDebugDataForNetLog( + NetLogCaptureMode capture_mode, + base::StringPiece debug_data); + } // namespace net #endif // NET_HTTP_HTTP_LOG_UTIL_
diff --git a/net/http/http_log_util_unittest.cc b/net/http/http_log_util_unittest.cc index bd9c79f..6b8d48e 100644 --- a/net/http/http_log_util_unittest.cc +++ b/net/http/http_log_util_unittest.cc
@@ -68,4 +68,14 @@ "WWW-Authenticate", "NTLM 1234 ")); } +TEST(HttpLogUtilTest, ElideGoAwayDebugDataForNetLog) { + // Only elide for appropriate log level. + EXPECT_EQ( + "[6 bytes were stripped]", + ElideGoAwayDebugDataForNetLog(NetLogCaptureMode::Default(), "foobar")); + EXPECT_EQ("foobar", + ElideGoAwayDebugDataForNetLog( + NetLogCaptureMode::IncludeCookiesAndCredentials(), "foobar")); +} + } // namspace net
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index 6b44dbb..4a36144 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -339,9 +339,7 @@ EXPECT_EQ(OK, rv); EXPECT_TRUE(handle_.is_initialized()); ASSERT_TRUE(handle_.socket()); - HttpProxyClientSocket* tunnel_socket = - static_cast<HttpProxyClientSocket*>(handle_.socket()); - EXPECT_TRUE(tunnel_socket->IsConnected()); + EXPECT_TRUE(handle_.socket()->IsConnected()); EXPECT_FALSE(proxy_delegate->on_before_tunnel_request_called()); EXPECT_FALSE(proxy_delegate->on_tunnel_headers_received_called()); EXPECT_TRUE(proxy_delegate->on_tunnel_request_completed_called()); @@ -446,9 +444,7 @@ EXPECT_EQ(OK, rv); EXPECT_TRUE(handle_.is_initialized()); ASSERT_TRUE(handle_.socket()); - HttpProxyClientSocket* tunnel_socket = - static_cast<HttpProxyClientSocket*>(handle_.socket()); - EXPECT_TRUE(tunnel_socket->IsConnected()); + EXPECT_TRUE(handle_.socket()->IsConnected()); proxy_delegate->VerifyOnTunnelHeadersReceived( "www.google.com:443", proxy_host_port.c_str(),
diff --git a/net/log/net_log_capture_mode.cc b/net/log/net_log_capture_mode.cc index 606dec6..a8914d4 100644 --- a/net/log/net_log_capture_mode.cc +++ b/net/log/net_log_capture_mode.cc
@@ -14,12 +14,13 @@ // for methods of NetLogCaptureMode, which expect that higher values represent a // strict superset of the capabilities of lower values. enum InternalValue { - // Log all events, but do not include the actual transferred bytes and - // remove cookies and HTTP credentials. + // Log all events, but do not include the actual transferred bytes, and + // remove cookies and HTTP credentials and HTTP/2 GOAWAY frame debug data. DEFAULT, // Log all events, but do not include the actual transferred bytes as // parameters for bytes sent/received events. + // TODO(bnc): Consider renaming to INCLUDE_PRIVACY_INFO. INCLUDE_COOKIES_AND_CREDENTIALS, // Log everything possible, even if it is slow and memory expensive.
diff --git a/net/log/net_log_capture_mode.h b/net/log/net_log_capture_mode.h index e08e2ad..8865e5f 100644 --- a/net/log/net_log_capture_mode.h +++ b/net/log/net_log_capture_mode.h
@@ -32,6 +32,7 @@ // no effort to strip cookies and credentials. // include_cookies_and_credentials() --> true // include_socket_bytes() --> false + // TODO(bnc): Consider renaming to IncludePrivacyInfo(). static NetLogCaptureMode IncludeCookiesAndCredentials(); // Constructs a capture mode which logs the data sent/received from sockets. @@ -41,6 +42,7 @@ // If include_cookies_and_credentials() is true , then it is OK to log // events which contain cookies, credentials or other privacy sensitive data. + // TODO(bnc): Consider renaming to include_privacy_info(). bool include_cookies_and_credentials() const; // If include_socket_bytes() is true, then it is OK to output the actual
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc index 2fa15b8..c1fede5d 100644 --- a/net/spdy/buffered_spdy_framer.cc +++ b/net/spdy/buffered_spdy_framer.cc
@@ -8,6 +8,13 @@ namespace net { +namespace { + +// GOAWAY frame debug data is only buffered up to this many bytes. +size_t kGoAwayDebugDataMaxSize = 1024; + +} // namespace + SpdyMajorVersion NextProtoToSpdyMajorVersion(NextProto next_proto) { switch (next_proto) { case kProtoDeprecatedSPDY2: @@ -226,7 +233,26 @@ } void BufferedSpdyFramer::OnGoAway(SpdyStreamId last_accepted_stream_id, SpdyGoAwayStatus status) { - visitor_->OnGoAway(last_accepted_stream_id, status); + DCHECK(!goaway_fields_); + goaway_fields_.reset(new GoAwayFields()); + goaway_fields_->last_accepted_stream_id = last_accepted_stream_id; + goaway_fields_->status = status; +} + +bool BufferedSpdyFramer::OnGoAwayFrameData(const char* goaway_data, + size_t len) { + if (len > 0) { + if (goaway_fields_->debug_data.size() < kGoAwayDebugDataMaxSize) { + goaway_fields_->debug_data.append( + goaway_data, std::min(len, kGoAwayDebugDataMaxSize - + goaway_fields_->debug_data.size())); + } + return true; + } + visitor_->OnGoAway(goaway_fields_->last_accepted_stream_id, + goaway_fields_->status, goaway_fields_->debug_data); + goaway_fields_.reset(); + return true; } void BufferedSpdyFramer::OnWindowUpdate(SpdyStreamId stream_id, @@ -354,8 +380,9 @@ // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyGoAwayIR). SpdyFrame* BufferedSpdyFramer::CreateGoAway( SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) const { - SpdyGoAwayIR go_ir(last_accepted_stream_id, status, ""); + SpdyGoAwayStatus status, + base::StringPiece debug_data) const { + SpdyGoAwayIR go_ir(last_accepted_stream_id, status, debug_data); return spdy_framer_.SerializeGoAway(go_ir); }
diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h index ee73f08..46cda47 100644 --- a/net/spdy/buffered_spdy_framer.h +++ b/net/spdy/buffered_spdy_framer.h
@@ -100,7 +100,8 @@ // Called when a GOAWAY frame has been parsed. virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) = 0; + SpdyGoAwayStatus status, + base::StringPiece debug_data) = 0; // Called when a WINDOW_UPDATE frame has been parsed. virtual void OnWindowUpdate(SpdyStreamId stream_id, @@ -173,6 +174,7 @@ void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override; void OnGoAway(SpdyStreamId last_accepted_stream_id, SpdyGoAwayStatus status) override; + bool OnGoAwayFrameData(const char* goaway_data, size_t len) override; void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override; void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id, @@ -203,9 +205,9 @@ SpdyRstStreamStatus status) const; SpdyFrame* CreateSettings(const SettingsMap& values) const; SpdyFrame* CreatePingFrame(SpdyPingId unique_id, bool is_ack) const; - SpdyFrame* CreateGoAway( - SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) const; + SpdyFrame* CreateGoAway(SpdyStreamId last_accepted_stream_id, + SpdyGoAwayStatus status, + base::StringPiece debug_data) const; SpdyFrame* CreateHeaders(SpdyStreamId stream_id, SpdyControlFlags flags, SpdyPriority priority, @@ -287,6 +289,14 @@ }; scoped_ptr<ControlFrameFields> control_frame_fields_; + // Collection of fields of a GOAWAY frame that this class needs to buffer. + struct GoAwayFields { + SpdyStreamId last_accepted_stream_id; + SpdyGoAwayStatus status; + std::string debug_data; + }; + scoped_ptr<GoAwayFields> goaway_fields_; + DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer); };
diff --git a/net/spdy/buffered_spdy_framer_unittest.cc b/net/spdy/buffered_spdy_framer_unittest.cc index 5f05fa1..aa1b2ab 100644 --- a/net/spdy/buffered_spdy_framer_unittest.cc +++ b/net/spdy/buffered_spdy_framer_unittest.cc
@@ -21,9 +21,9 @@ syn_reply_frame_count_(0), headers_frame_count_(0), push_promise_frame_count_(0), + goaway_count_(0), header_stream_id_(static_cast<SpdyStreamId>(-1)), - promised_stream_id_(static_cast<SpdyStreamId>(-1)) { - } + promised_stream_id_(static_cast<SpdyStreamId>(-1)) {} void OnError(SpdyFramer::SpdyError error_code) override { LOG(INFO) << "SpdyFramer Error: " << error_code; @@ -100,7 +100,13 @@ SpdyRstStreamStatus status) override {} void OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) override {} + SpdyGoAwayStatus status, + StringPiece debug_data) override { + goaway_count_++; + goaway_last_accepted_stream_id_ = last_accepted_stream_id; + goaway_status_ = status; + goaway_debug_data_.assign(debug_data.data(), debug_data.size()); + } bool OnCredentialFrameData(const char*, size_t) { LOG(FATAL) << "Unexpected OnCredentialFrameData call."; @@ -162,6 +168,7 @@ int syn_reply_frame_count_; int headers_frame_count_; int push_promise_frame_count_; + int goaway_count_; // Header block streaming state: SpdyStreamId header_stream_id_; @@ -170,6 +177,11 @@ // Headers from OnSyn, OnSynReply, OnHeaders and OnPushPromise for // verification. SpdyHeaderBlock headers_; + + // OnGoAway parameters. + SpdyStreamId goaway_last_accepted_stream_id_; + SpdyGoAwayStatus goaway_status_; + std::string goaway_debug_data_; }; } // namespace @@ -340,4 +352,22 @@ EXPECT_EQ(2u, visitor.promised_stream_id_); } +TEST_P(BufferedSpdyFramerTest, GoAwayDebugData) { + if (spdy_version() < HTTP2) + return; + BufferedSpdyFramer framer(spdy_version(), true); + scoped_ptr<SpdyFrame> goaway_frame( + framer.CreateGoAway(2u, GOAWAY_FRAME_SIZE_ERROR, "foo")); + + TestBufferedSpdyVisitor visitor(spdy_version()); + visitor.SimulateInFramer( + reinterpret_cast<unsigned char*>(goaway_frame.get()->data()), + goaway_frame.get()->size()); + EXPECT_EQ(0, visitor.error_count_); + EXPECT_EQ(1, visitor.goaway_count_); + EXPECT_EQ(2u, visitor.goaway_last_accepted_stream_id_); + EXPECT_EQ(GOAWAY_FRAME_SIZE_ERROR, visitor.goaway_status_); + EXPECT_EQ("foo", visitor.goaway_debug_data_); +} + } // namespace net
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 4055422..9c1c7a7 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc
@@ -257,13 +257,16 @@ int active_streams, int unclaimed_streams, SpdyGoAwayStatus status, - NetLogCaptureMode /* capture_mode */) { + StringPiece debug_data, + NetLogCaptureMode capture_mode) { scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("last_accepted_stream_id", static_cast<int>(last_stream_id)); dict->SetInteger("active_streams", active_streams); dict->SetInteger("unclaimed_streams", unclaimed_streams); dict->SetInteger("status", static_cast<int>(status)); + dict->SetString("debug_data", + ElideGoAwayDebugDataForNetLog(capture_mode, debug_data)); return dict.Pass(); } @@ -2452,15 +2455,17 @@ } void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) { + SpdyGoAwayStatus status, + StringPiece debug_data) { CHECK(in_io_loop_); // TODO(jgraettinger): UMA histogram on |status|. - net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_GOAWAY, - base::Bind(&NetLogSpdyGoAwayCallback, - last_accepted_stream_id, active_streams_.size(), - unclaimed_pushed_streams_.size(), status)); + net_log_.AddEvent( + NetLog::TYPE_HTTP2_SESSION_GOAWAY, + base::Bind(&NetLogSpdyGoAwayCallback, last_accepted_stream_id, + active_streams_.size(), unclaimed_pushed_streams_.size(), + status, debug_data)); MakeUnavailable(); if (status == GOAWAY_HTTP_1_1_REQUIRED) { // TODO(bnc): Record histogram with number of open streams capped at 50.
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index f6475bc..3d0c857 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h
@@ -821,7 +821,8 @@ void OnPing(SpdyPingId unique_id, bool is_ack) override; void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override; void OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) override; + SpdyGoAwayStatus status, + StringPiece debug_data) override; void OnDataFrameHeader(SpdyStreamId stream_id, size_t length, bool fin) override;
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc index 0f89c4f0..23b9dacf 100644 --- a/net/spdy/spdy_session_unittest.cc +++ b/net/spdy/spdy_session_unittest.cc
@@ -1551,7 +1551,8 @@ TEST_P(SpdySessionTest, NetLogOnSessionGoaway) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); + scoped_ptr<SpdyFrame> goaway( + spdy_util_.ConstructSpdyGoAway(42, GOAWAY_ENHANCE_YOUR_CALM, "foo")); MockRead reads[] = { CreateMockRead(*goaway), MockRead(SYNCHRONOUS, 0, 0) // EOF @@ -1575,18 +1576,35 @@ log_.GetEntries(&entries); EXPECT_LT(0u, entries.size()); + if (GetParam() == kProtoHTTP2) { + int pos = ExpectLogContainsSomewhere( + entries, 0, NetLog::TYPE_HTTP2_SESSION_GOAWAY, NetLog::PHASE_NONE); + TestNetLogEntry entry = entries[pos]; + int last_accepted_stream_id; + ASSERT_TRUE(entry.GetIntegerValue("last_accepted_stream_id", + &last_accepted_stream_id)); + EXPECT_EQ(42, last_accepted_stream_id); + int active_streams; + ASSERT_TRUE(entry.GetIntegerValue("active_streams", &active_streams)); + EXPECT_EQ(0, active_streams); + int unclaimed_streams; + ASSERT_TRUE(entry.GetIntegerValue("unclaimed_streams", &unclaimed_streams)); + EXPECT_EQ(0, unclaimed_streams); + int status; + ASSERT_TRUE(entry.GetIntegerValue("status", &status)); + EXPECT_EQ(GOAWAY_ENHANCE_YOUR_CALM, status); + std::string debug_data; + ASSERT_TRUE(entry.GetStringValue("debug_data", &debug_data)); + EXPECT_EQ("foo", debug_data); + } + // Check that we logged SPDY_SESSION_CLOSE correctly. int pos = ExpectLogContainsSomewhere( entries, 0, NetLog::TYPE_HTTP2_SESSION_CLOSE, NetLog::PHASE_NONE); - - if (pos < static_cast<int>(entries.size())) { - TestNetLogEntry entry = entries[pos]; - int error_code = 0; - ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); - EXPECT_EQ(OK, error_code); - } else { - ADD_FAILURE(); - } + TestNetLogEntry entry = entries[pos]; + int error_code = 0; + ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); + EXPECT_EQ(OK, error_code); } TEST_P(SpdySessionTest, NetLogOnSessionEOF) {
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index 8755cc0..34352e4 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc
@@ -251,7 +251,8 @@ void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override {} void OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) override {} + SpdyGoAwayStatus status, + StringPiece debug_data) override {} void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {} void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
diff --git a/net/tools/flip_server/spdy_interface.h b/net/tools/flip_server/spdy_interface.h index cbaeab18..45d1885e1 100644 --- a/net/tools/flip_server/spdy_interface.h +++ b/net/tools/flip_server/spdy_interface.h
@@ -125,7 +125,8 @@ // Called when a GOAWAY frame has been parsed. void OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyGoAwayStatus status) override {} + SpdyGoAwayStatus status, + StringPiece debug_data) override {} // Called when a WINDOW_UPDATE frame has been parsed. void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {}
diff --git a/net/tools/flip_server/spdy_interface_test.cc b/net/tools/flip_server/spdy_interface_test.cc index 23c7a9d..d47a8725 100644 --- a/net/tools/flip_server/spdy_interface_test.cc +++ b/net/tools/flip_server/spdy_interface_test.cc
@@ -71,7 +71,7 @@ MOCK_METHOD3(OnSetting, void(SpdySettingsIds, uint8, uint32)); MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack)); MOCK_METHOD2(OnRstStream, void(SpdyStreamId, SpdyRstStreamStatus)); - MOCK_METHOD2(OnGoAway, void(SpdyStreamId, SpdyGoAwayStatus)); + MOCK_METHOD3(OnGoAway, void(SpdyStreamId, SpdyGoAwayStatus, StringPiece)); MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId, int)); MOCK_METHOD3(OnPushPromise, void(SpdyStreamId, SpdyStreamId, const SpdyHeaderBlock&));
diff --git a/sql/BUILD.gn b/sql/BUILD.gn index 57f1b38..8d071a3e 100644 --- a/sql/BUILD.gn +++ b/sql/BUILD.gn
@@ -15,6 +15,8 @@ "meta_table.h", "recovery.cc", "recovery.h", + "sql_memory_dump_provider.cc", + "sql_memory_dump_provider.h", "statement.cc", "statement.h", "transaction.cc", @@ -77,6 +79,7 @@ "connection_unittest.cc", "meta_table_unittest.cc", "recovery_unittest.cc", + "sql_memory_dump_provider_unittest.cc", "sqlite_features_unittest.cc", "statement_unittest.cc", "test/paths.cc",
diff --git a/sql/connection.cc b/sql/connection.cc index 20f0f07..61aebbe 100644 --- a/sql/connection.cc +++ b/sql/connection.cc
@@ -19,6 +19,8 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" +#include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/process_memory_dump.h" #include "sql/statement.h" #include "third_party/sqlite/sqlite3.h" @@ -217,6 +219,44 @@ return current_ignorer_cb_->Run(error); } +bool Connection::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + if (args.level_of_detail == + base::trace_event::MemoryDumpLevelOfDetail::LIGHT || + !db_) { + return true; + } + + // The high water mark is not tracked for the following usages. + int cache_size, dummy_int; + sqlite3_db_status(db_, SQLITE_DBSTATUS_CACHE_USED, &cache_size, &dummy_int, + 0 /* resetFlag */); + int schema_size; + sqlite3_db_status(db_, SQLITE_DBSTATUS_SCHEMA_USED, &schema_size, &dummy_int, + 0 /* resetFlag */); + int statement_size; + sqlite3_db_status(db_, SQLITE_DBSTATUS_STMT_USED, &statement_size, &dummy_int, + 0 /* resetFlag */); + + std::string name = base::StringPrintf( + "sqlite/%s_connection/%p", + histogram_tag_.empty() ? "Unknown" : histogram_tag_.c_str(), this); + base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(name); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + cache_size + schema_size + statement_size); + dump->AddScalar("cache_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + cache_size); + dump->AddScalar("schema_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + schema_size); + dump->AddScalar("statement_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + statement_size); + return true; +} + // static void Connection::SetErrorIgnorer(Connection::ErrorIgnorerCallback* cb) { CHECK(current_ignorer_cb_ == NULL); @@ -291,9 +331,13 @@ update_time_histogram_(NULL), query_time_histogram_(NULL), clock_(new TimeSource()) { + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + this); } Connection::~Connection() { + base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( + this); Close(); }
diff --git a/sql/connection.h b/sql/connection.h index d456b6cd..7d2ab6a3 100644 --- a/sql/connection.h +++ b/sql/connection.h
@@ -18,6 +18,7 @@ #include "base/memory/scoped_ptr.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" +#include "base/trace_event/memory_dump_provider.h" #include "sql/sql_export.h" struct sqlite3; @@ -102,7 +103,7 @@ DISALLOW_COPY_AND_ASSIGN(TimeSource); }; -class SQL_EXPORT Connection { +class SQL_EXPORT Connection : public base::trace_event::MemoryDumpProvider { private: class StatementRef; // Forward declaration, see real one below. @@ -110,7 +111,7 @@ // The database is opened by calling Open[InMemory](). Any uncommitted // transactions will be rolled back when this object is deleted. Connection(); - ~Connection(); + ~Connection() override; // Pre-init configuration ---------------------------------------------------- @@ -464,6 +465,11 @@ // tests. static bool ShouldIgnoreSqliteError(int error); + // base::trace_event::MemoryDumpProvider implementation. + bool OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* process_memory_dump) override; + private: // For recovery module. friend class Recovery;
diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc index 0038a1d..d933a6d 100644 --- a/sql/connection_unittest.cc +++ b/sql/connection_unittest.cc
@@ -11,6 +11,7 @@ #include "base/metrics/statistics_recorder.h" #include "base/strings/stringprintf.h" #include "base/test/histogram_tester.h" +#include "base/trace_event/process_memory_dump.h" #include "sql/connection.h" #include "sql/correct_sql_test_base.h" #include "sql/meta_table.h" @@ -1378,4 +1379,12 @@ } #endif +TEST_F(SQLConnectionTest, OnMemoryDump) { + base::trace_event::ProcessMemoryDump pmd(nullptr); + base::trace_event::MemoryDumpArgs args = { + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + ASSERT_TRUE(db().OnMemoryDump(args, &pmd)); + EXPECT_GE(pmd.allocator_dumps().size(), 1u); +} + } // namespace
diff --git a/sql/sql.gyp b/sql/sql.gyp index 115a93bd..362597e 100644 --- a/sql/sql.gyp +++ b/sql/sql.gyp
@@ -29,6 +29,8 @@ 'meta_table.h', 'recovery.cc', 'recovery.h', + 'sql_memory_dump_provider.cc', + 'sql_memory_dump_provider.h', 'statement.cc', 'statement.h', 'transaction.cc', @@ -89,6 +91,7 @@ 'connection_unittest.cc', 'meta_table_unittest.cc', 'recovery_unittest.cc', + 'sql_memory_dump_provider_unittest.cc', 'sqlite_features_unittest.cc', 'statement_unittest.cc', 'test/paths.cc',
diff --git a/sql/sql_memory_dump_provider.cc b/sql/sql_memory_dump_provider.cc new file mode 100644 index 0000000..bb6d813 --- /dev/null +++ b/sql/sql_memory_dump_provider.cc
@@ -0,0 +1,62 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sql/sql_memory_dump_provider.h" + +#include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/process_memory_dump.h" +#include "third_party/sqlite/sqlite3.h" + +namespace sql { + +// static +SqlMemoryDumpProvider* SqlMemoryDumpProvider::GetInstance() { + return base::Singleton< + SqlMemoryDumpProvider, + base::LeakySingletonTraits<SqlMemoryDumpProvider>>::get(); +} + +SqlMemoryDumpProvider::SqlMemoryDumpProvider() {} + +SqlMemoryDumpProvider::~SqlMemoryDumpProvider() {} + +bool SqlMemoryDumpProvider::OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + int memory_used = 0; + int memory_high_water = 0; + int status = sqlite3_status(SQLITE_STATUS_MEMORY_USED, &memory_used, + &memory_high_water, 1 /*resetFlag */); + if (status != SQLITE_OK) + return false; + + base::trace_event::MemoryAllocatorDump* dump = + pmd->CreateAllocatorDump("sqlite"); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + memory_used); + dump->AddScalar("malloc_high_wmark_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + memory_high_water); + + int dummy_high_water = -1; + int malloc_count = -1; + status = sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &malloc_count, + &dummy_high_water, 0 /* resetFlag */); + if (status == SQLITE_OK) { + dump->AddScalar("malloc_count", + base::trace_event::MemoryAllocatorDump::kUnitsObjects, + malloc_count); + } + + const char* system_allocator_name = + base::trace_event::MemoryDumpManager::GetInstance() + ->system_allocator_pool_name(); + if (system_allocator_name) { + pmd->AddSuballocation(dump->guid(), system_allocator_name); + } + return true; +} + +} // namespace sql
diff --git a/sql/sql_memory_dump_provider.h b/sql/sql_memory_dump_provider.h new file mode 100644 index 0000000..051755f --- /dev/null +++ b/sql/sql_memory_dump_provider.h
@@ -0,0 +1,36 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SQL_PROCESS_MEMORY_DUMP_PROVIDER_H +#define SQL_PROCESS_MEMORY_DUMP_PROVIDER_H + +#include "base/memory/singleton.h" +#include "base/trace_event/memory_dump_provider.h" +#include "sql/sql_export.h" + +namespace sql { + +// Adds process-wide memory usage statistics about sqlite to chrome://tracing. +// sql::Connection::OnMemoryDump adds per-connection memory statistics. +class SQL_EXPORT SqlMemoryDumpProvider + : public base::trace_event::MemoryDumpProvider { + public: + static SqlMemoryDumpProvider* GetInstance(); + + // MemoryDumpProvider implementation. + bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) override; + + private: + friend struct base::DefaultSingletonTraits<SqlMemoryDumpProvider>; + + SqlMemoryDumpProvider(); + ~SqlMemoryDumpProvider() override; + + DISALLOW_COPY_AND_ASSIGN(SqlMemoryDumpProvider); +}; + +} // namespace sql + +#endif // SQL_PROCESS_MEMORY_DUMP_PROVIDER_H
diff --git a/sql/sql_memory_dump_provider_unittest.cc b/sql/sql_memory_dump_provider_unittest.cc new file mode 100644 index 0000000..1f1dcf9 --- /dev/null +++ b/sql/sql_memory_dump_provider_unittest.cc
@@ -0,0 +1,22 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sql/sql_memory_dump_provider.h" + +#include "base/trace_event/process_memory_dump.h" +#include "sql/test/sql_test_base.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +using SQLMemoryDumpProviderTest = sql::SQLTestBase; +} + +TEST_F(SQLMemoryDumpProviderTest, OnMemoryDump) { + base::trace_event::ProcessMemoryDump pmd(nullptr); + base::trace_event::MemoryDumpArgs args = { + base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; + ASSERT_TRUE( + sql::SqlMemoryDumpProvider::GetInstance()->OnMemoryDump(args, &pmd)); + ASSERT_TRUE(pmd.GetAllocatorDump("sqlite")); +}
diff --git a/testing/chromoting/browser_tests_launcher.py b/testing/chromoting/browser_tests_launcher.py index 4e7b34c9..9d33bce4 100644 --- a/testing/chromoting/browser_tests_launcher.py +++ b/testing/chromoting/browser_tests_launcher.py
@@ -135,12 +135,6 @@ # All tests completed. Include host-logs in the test results. PrintHostLogContents(host_log_files) - if TEST_FAILURE: - print '++++++++++AT LEAST 1 TEST FAILED++++++++++' - print FAILING_TESTS.rstrip('\n') - print '++++++++++++++++++++++++++++++++++++++++++' - raise Exception('At least one test failed.') - return host_log_files if __name__ == '__main__': @@ -163,6 +157,11 @@ host_logs = '' try: host_logs = main(command_line_args) + if TEST_FAILURE: + print '++++++++++AT LEAST 1 TEST FAILED++++++++++' + print FAILING_TESTS.rstrip('\n') + print '++++++++++++++++++++++++++++++++++++++++++' + raise Exception('At least one test failed.') finally: # Stop host and cleanup user-profile-dir. TestMachineCleanup(command_line_args.user_profile_dir, host_logs)
diff --git a/testing/chromoting/chromoting_test_driver_launcher.py b/testing/chromoting/chromoting_test_driver_launcher.py index c982279..66058e7 100644 --- a/testing/chromoting/chromoting_test_driver_launcher.py +++ b/testing/chromoting/chromoting_test_driver_launcher.py
@@ -24,17 +24,19 @@ args: Command line args, used for test-case startup tasks. command: Chromoting Test Driver command line. Returns: - "command" if there was a test environment failure, otherwise a string of the - names of failed tests. + command, host_log_file_names: Tuple of: + "command" if there was a test-environment failure, or any failing test, and + list of host-log file-names. """ + host_log_file_names = [] - TestCaseSetup(args) + host_log_file_names.append(TestCaseSetup(args)) results = RunCommandInSubProcess(command) tear_down_index = results.find(TEST_ENVIRONMENT_TEAR_DOWN_INDICATOR) if tear_down_index == -1: # The test environment did not tear down. Something went horribly wrong. - return '[Command failed]: ' + command + return '[Command failed]: ' + command, host_log_file_names end_results_list = results[tear_down_index:].split('\n') failed_tests_list = [] @@ -47,33 +49,32 @@ # Note: Skipping the first one is intentional. for i in range(1, len(failed_tests_list)): test_result += ' ' + failed_tests_list[i] - return test_result + return test_result, host_log_file_names # All tests passed! - return '' + return '', host_log_file_names def main(args): InitialiseTestMachineForLinux(args.cfg_file) failed_tests = '' - + host_log_files = [] with open(args.commands_file) as f: for line in f: # Replace the PROD_DIR value in the command-line with # the passed in value. line = line.replace(PROD_DIR_ID, args.prod_dir) # Launch specified command line for test. - failed_tests += LaunchCTDCommand(args, line) + test_results, log_files = LaunchCTDCommand(args, line) + failed_tests += test_results + host_log_files.extend(log_files) # All tests completed. Include host-logs in the test results. - PrintHostLogContents() + PrintHostLogContents(host_log_files) - if failed_tests: - print '++++++++++FAILED TESTS++++++++++' - print failed_tests.rstrip('\n') - print '++++++++++++++++++++++++++++++++' - raise Exception('At least one test failed.') + return failed_tests, host_log_files + if __name__ == '__main__': parser = argparse.ArgumentParser() @@ -91,8 +92,15 @@ '-u', '--user_profile_dir', help='path to user-profile-dir, used by connect-to-host tests.') command_line_args = parser.parse_args() + host_logs = '' + failing_tests = '' try: - main(command_line_args) + failing_tests, host_logs = main(command_line_args) + if failing_tests: + print '++++++++++FAILED TESTS++++++++++' + print failing_tests.rstrip('\n') + print '++++++++++++++++++++++++++++++++' + raise Exception('At least one test failed.') finally: # Stop host and cleanup user-profile-dir. - TestMachineCleanup(command_line_args.user_profile_dir) + TestMachineCleanup(command_line_args.user_profile_dir, host_logs)
diff --git a/testing/chromoting/chromoting_test_utilities.py b/testing/chromoting/chromoting_test_utilities.py index 24d88e1..79620f43 100644 --- a/testing/chromoting/chromoting_test_utilities.py +++ b/testing/chromoting/chromoting_test_utilities.py
@@ -67,8 +67,9 @@ RunCommandInSubProcess(CHROMOTING_HOST_PATH + ' --stop') # Cleanup any host logs. - for host_log in host_logs: - RunCommandInSubProcess('rm %s' % host_log) + if host_logs: + for host_log in host_logs: + RunCommandInSubProcess('rm %s' % host_log) # Remove the user-profile dir if os.path.exists(user_profile_dir): @@ -192,12 +193,13 @@ def PrintHostLogContents(host_log_files=None): - host_log_contents = '' - for log_file in sorted(host_log_files): - with open(log_file, 'r') as log: - host_log_contents += '\nHOST LOG %s\n CONTENTS:\n%s' % ( - log_file, log.read()) - print host_log_contents + if host_log_files: + host_log_contents = '' + for log_file in sorted(host_log_files): + with open(log_file, 'r') as log: + host_log_contents += '\nHOST LOG %s\n CONTENTS:\n%s' % ( + log_file, log.read()) + print host_log_contents def TestCaseSetup(args):
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a7e014e..b97940e 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1023,7 +1023,6 @@ crbug.com/509025 [ Yosemite ] fast/text/custom-font-data-crash2.html [ Failure ] crbug.com/509025 [ Yosemite ] fast/text/glyph-reordering.html [ Failure ] crbug.com/509025 [ Yosemite ] fast/text/large-text-composed-char.html [ Failure ] -crbug.com/509025 [ Yosemite ] fast/text/missing-glyph-in-combining-character-sequence.html [ Failure ] crbug.com/509025 [ Yosemite ] http/tests/misc/acid2.html [ Failure ] crbug.com/509025 [ Yosemite ] http/tests/navigation/navigation-redirect-schedule-crash.html [ Failure ] crbug.com/509025 [ Yosemite ] http/tests/security/contentTypeOptions/nosniff-script-without-content-type-blocked.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt index 18f37787..af312af 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
@@ -48,6 +48,7 @@ PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_presentation.defaultRequest is null +PASS window.cached_navigator_presentation.receiver.onconnectionavailable is null PASS window.cached_navigator_serviceWorker.controller is null PASS window.cached_navigator_serviceWorker.oncontrollerchange is null PASS window.cached_navigator_serviceWorker.onmessage is null
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt index 80746e7..bec90ae 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -48,6 +48,7 @@ PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_presentation.defaultRequest is null +PASS window.cached_navigator_presentation.receiver.onconnectionavailable is null PASS window.cached_navigator_serviceWorker.controller is null PASS window.cached_navigator_serviceWorker.oncontrollerchange is null PASS window.cached_navigator_serviceWorker.onmessage is null
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt index 7e48d80..5962ffc 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -48,6 +48,7 @@ PASS window.cached_navigator_connection.onchange is null PASS window.cached_navigator_connection.ontypechange is null PASS window.cached_navigator_presentation.defaultRequest is null +PASS window.cached_navigator_presentation.receiver.onconnectionavailable is null PASS window.cached_navigator_serviceWorker.controller is null PASS window.cached_navigator_serviceWorker.oncontrollerchange is null PASS window.cached_navigator_serviceWorker.onmessage is null
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt index 7ae7a9cf..2d1d7903 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -55,6 +55,7 @@ PASS oldChildWindow.navigator.onLine is newChildWindow.navigator.onLine PASS oldChildWindow.navigator.platform is newChildWindow.navigator.platform PASS oldChildWindow.navigator.presentation.defaultRequest is newChildWindow.navigator.presentation.defaultRequest +PASS oldChildWindow.navigator.presentation.receiver.onconnectionavailable is newChildWindow.navigator.presentation.receiver.onconnectionavailable PASS oldChildWindow.navigator.product is newChildWindow.navigator.product PASS oldChildWindow.navigator.productSub is newChildWindow.navigator.productSub PASS oldChildWindow.navigator.serviceWorker.controller is newChildWindow.navigator.serviceWorker.controller
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt index 12b15ad..6cbaad7 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
@@ -55,6 +55,7 @@ PASS childWindow.navigator.onLine is window.navigator.onLine PASS childWindow.navigator.platform is window.navigator.platform FAIL childWindow.navigator.presentation.defaultRequest should be null. Threw exception TypeError: Cannot read property 'defaultRequest' of null +FAIL childWindow.navigator.presentation.receiver.onconnectionavailable should be null. Threw exception TypeError: Cannot read property 'receiver' of null PASS childWindow.navigator.product is window.navigator.product PASS childWindow.navigator.productSub is window.navigator.productSub FAIL childWindow.navigator.serviceWorker.controller should be null. Threw exception TypeError: Cannot read property 'controller' of null
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt index 98b57dfc..995fd099 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
@@ -54,6 +54,7 @@ PASS childWindow.navigator.onLine is window.navigator.onLine PASS childWindow.navigator.platform is window.navigator.platform FAIL childWindow.navigator.presentation.defaultRequest should be null. Threw exception TypeError: Cannot read property 'defaultRequest' of null +FAIL childWindow.navigator.presentation.receiver.onconnectionavailable should be null. Threw exception TypeError: Cannot read property 'receiver' of null PASS childWindow.navigator.product is window.navigator.product PASS childWindow.navigator.productSub is window.navigator.productSub FAIL childWindow.navigator.serviceWorker.controller should be null. Threw exception TypeError: Cannot read property 'controller' of null
diff --git a/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped-expected.html b/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped-expected.html index c8b271d..c6466fe 100644 --- a/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped-expected.html +++ b/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped-expected.html
@@ -12,6 +12,7 @@ border: medium solid gray; width: 400px; margin: 20px; + line-height: 1.2; } </style> </head>
diff --git a/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped.html b/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped.html index abe4680..4f41e5fa 100644 --- a/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped.html +++ b/third_party/WebKit/LayoutTests/fast/text/international/bdi-neutral-wrapped.html
@@ -35,6 +35,7 @@ border: medium solid gray; width: 400px; margin: 20px; + line-height: 1.2; } </style> </head>
diff --git a/third_party/WebKit/LayoutTests/fast/text/missing-glyph-in-combining-character-sequence.html b/third_party/WebKit/LayoutTests/fast/text/missing-glyph-in-combining-character-sequence.html deleted file mode 100644 index 26d5e8a..0000000 --- a/third_party/WebKit/LayoutTests/fast/text/missing-glyph-in-combining-character-sequence.html +++ /dev/null
@@ -1,12 +0,0 @@ -<style> -@font-face { - font-family: myfont; - src: url(../../resources/Ahem.ttf); -} -.test { - margin: 20px; - font-family: myfont; -} -</style> -You should not see an empty rectangle above the black square. -<div class="test">ỏ</div>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/missing-glyph-in-combining-character-sequence-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/missing-glyph-in-combining-character-sequence-expected.png deleted file mode 100644 index 44d42639..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/missing-glyph-in-combining-character-sequence-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/missing-glyph-in-combining-character-sequence-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/missing-glyph-in-combining-character-sequence-expected.txt deleted file mode 100644 index e82d9ea..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/missing-glyph-in-combining-character-sequence-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x572 - LayoutBlockFlow (anonymous) at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 381x19 - text run at (0,0) width 381: "You should not see an empty rectangle above the black square." - LayoutBlockFlow {DIV} at (20,40) size 744x19 - LayoutText {#text} at (0,2) size 16x16 - text run at (0,2) width 16: "o\x{309}"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-lion/fast/text/missing-glyph-in-combining-character-sequence-expected.png b/third_party/WebKit/LayoutTests/platform/mac-lion/fast/text/missing-glyph-in-combining-character-sequence-expected.png deleted file mode 100644 index 557a3d4..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-lion/fast/text/missing-glyph-in-combining-character-sequence-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/text/missing-glyph-in-combining-character-sequence-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/text/missing-glyph-in-combining-character-sequence-expected.png deleted file mode 100644 index 04bfa6e..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mavericks/fast/text/missing-glyph-in-combining-character-sequence-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/text/missing-glyph-in-combining-character-sequence-expected.png b/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/text/missing-glyph-in-combining-character-sequence-expected.png deleted file mode 100644 index 1007d48..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-snowleopard/fast/text/missing-glyph-in-combining-character-sequence-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/missing-glyph-in-combining-character-sequence-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/missing-glyph-in-combining-character-sequence-expected.png deleted file mode 100644 index 3c0b215..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/missing-glyph-in-combining-character-sequence-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/missing-glyph-in-combining-character-sequence-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/text/missing-glyph-in-combining-character-sequence-expected.txt deleted file mode 100644 index 1282b6e..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/missing-glyph-in-combining-character-sequence-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x572 - LayoutBlockFlow (anonymous) at (0,0) size 784x18 - LayoutText {#text} at (0,0) size 403x18 - text run at (0,0) width 403: "You should not see an empty rectangle above the black square." - LayoutBlockFlow {DIV} at (20,38) size 744x21 - LayoutText {#text} at (0,3) size 16x16 - text run at (0,3) width 16: "o\x{309}"
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/text/missing-glyph-in-combining-character-sequence-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/fast/text/missing-glyph-in-combining-character-sequence-expected.png deleted file mode 100644 index 3389a24..0000000 --- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/text/missing-glyph-in-combining-character-sequence-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/fast/text/missing-glyph-in-combining-character-sequence-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/fast/text/missing-glyph-in-combining-character-sequence-expected.txt deleted file mode 100644 index 0055ba1..0000000 --- a/third_party/WebKit/LayoutTests/platform/win-xp/fast/text/missing-glyph-in-combining-character-sequence-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x572 - LayoutBlockFlow (anonymous) at (0,0) size 784x20 - LayoutText {#text} at (0,0) size 381x19 - text run at (0,0) width 381: "You should not see an empty rectangle above the black square." - LayoutBlockFlow {DIV} at (20,40) size 744x20 - LayoutText {#text} at (0,4) size 16x16 - text run at (0,4) width 16: "o\x{309}"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/missing-glyph-in-combining-character-sequence-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/missing-glyph-in-combining-character-sequence-expected.png deleted file mode 100644 index 428683e..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/fast/text/missing-glyph-in-combining-character-sequence-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/missing-glyph-in-combining-character-sequence-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/text/missing-glyph-in-combining-character-sequence-expected.txt deleted file mode 100644 index 0d97ebd0..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/fast/text/missing-glyph-in-combining-character-sequence-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x572 - LayoutBlockFlow (anonymous) at (0,0) size 784x18 - LayoutText {#text} at (0,0) size 403x17 - text run at (0,0) width 403: "You should not see an empty rectangle above the black square." - LayoutBlockFlow {DIV} at (20,38) size 744x25 - LayoutText {#text} at (0,5) size 16x16 - text run at (0,5) width 16: "o\x{309}"
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-receiver.html b/third_party/WebKit/LayoutTests/presentation/presentation-receiver.html new file mode 100644 index 0000000..3f593f9a --- /dev/null +++ b/third_party/WebKit/LayoutTests/presentation/presentation-receiver.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + +test(function() { + assert_true('receiver' in navigator.presentation); + assert_true('getConnection' in navigator.presentation.receiver); + assert_true('getConnections' in navigator.presentation.receiver); + assert_true('onconnectionavailable' in navigator.presentation.receiver); + + assert_true('PresentationReceiver' in window); +}, "Test that the Presentation Receiver API is present.") + +test(function() { + assert_equals(typeof(navigator.presentation.receiver), "object"); + assert_equals(typeof(navigator.presentation.receiver.getConnection), "function"); + assert_equals(typeof(navigator.presentation.receiver.getConnections), "function"); + assert_equals(typeof(navigator.presentation.receiver.onconnectionavailable), "object"); +}, "Test the Presentation Receiver API property types."); + +test(function() { + assert_true(navigator.presentation.receiver instanceof EventTarget); +}, "Test that navigator.presentation.receiver is an EventTarget."); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 2dfa4fb..40417875 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1481,6 +1481,10 @@ interface GamepadEvent getter gamepad method constructor +interface HMDVRDevice + method constructor + method getEyeParameters + method setFieldOfView interface HTMLAllCollection getter length method constructor @@ -3444,6 +3448,7 @@ method getBattery method getGamepads method getStorageUpdates + method getVRDevices method isProtocolHandlerRegistered method javaEnabled method registerProtocolHandler @@ -3745,8 +3750,14 @@ interface PopStateEvent getter state method constructor +interface PositionSensorVRDevice + method constructor + method getImmediateState + method getState + method resetSensor interface Presentation getter defaultRequest + getter receiver method constructor setter defaultRequest interface PresentationAvailability @@ -3769,6 +3780,12 @@ interface PresentationConnectionAvailableEvent getter connection method constructor +interface PresentationReceiver + getter onconnectionavailable + method constructor + method getConnection + method getConnections + setter onconnectionavailable interface PresentationRequest getter onconnectionavailable method constructor @@ -5576,6 +5593,38 @@ getter bytesWritten getter status method constructor +interface VRDevice + getter deviceId + getter deviceName + getter hardwareUnitId + method constructor +interface VREyeParameters + getter currentFieldOfView + getter eyeTranslation + getter maximumFieldOfView + getter minimumFieldOfView + getter recommendedFieldOfView + getter renderRect + method constructor +interface VRFieldOfView + getter downDegrees + getter leftDegrees + getter rightDegrees + getter upDegrees + method constructor + setter downDegrees + setter leftDegrees + setter rightDegrees + setter upDegrees +interface VRPositionState + getter angularAcceleration + getter angularVelocity + getter linearAcceleration + getter linearVelocity + getter orientation + getter position + getter timeStamp + method constructor interface VTTCue getter align getter line
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp index 237b48cd..e9ca24f 100644 --- a/third_party/WebKit/Source/core/layout/LayoutText.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -41,6 +41,7 @@ #include "core/layout/line/GlyphOverflow.h" #include "core/layout/line/InlineTextBox.h" #include "core/paint/PaintLayer.h" +#include "platform/LayoutTestSupport.h" #include "platform/fonts/Character.h" #include "platform/fonts/FontCache.h" #include "platform/geometry/FloatQuad.h" @@ -1832,8 +1833,10 @@ bool LayoutText::computeCanUseSimpleFontCodePath() const { - if (RuntimeEnabledFeatures::alwaysUseComplexTextEnabled()) + if (RuntimeEnabledFeatures::alwaysUseComplexTextEnabled() + || LayoutTestSupport::alwaysUseComplexTextForTest()) { return false; + } if (m_text.is8Bit()) return true; return Character::characterRangeCodePath(characters16(), length()) == SimplePath;
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp index 0a5bc59..3b07431 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp
@@ -20,6 +20,7 @@ #include "config.h" #include "core/layout/svg/SVGTextChunkBuilder.h" +#include "core/layout/api/LineLayoutSVGInlineText.h" #include "core/layout/svg/LayoutSVGInlineText.h" #include "core/layout/svg/line/SVGInlineTextBox.h" #include "core/svg/SVGLengthContext.h" @@ -160,7 +161,7 @@ void SVGTextPathChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxListConstIterator boxEnd) { - const ComputedStyle& style = (*boxStart)->layoutObject().styleRef(); + const ComputedStyle& style = (*boxStart)->lineLayoutItem().styleRef(); ChunkLengthAccumulator lengthAccumulator(!style.isHorizontalWritingMode()); lengthAccumulator.processRange(boxStart, boxEnd); @@ -188,13 +189,13 @@ { ASSERT(*boxStart); - const LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText((*boxStart)->layoutObject()); - const ComputedStyle& style = textLayoutObject.styleRef(); + const LineLayoutSVGInlineText textLineLayout = LineLayoutSVGInlineText((*boxStart)->lineLayoutItem()); + const ComputedStyle& style = textLineLayout.styleRef(); // Handle 'lengthAdjust' property. float desiredTextLength = 0; SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown; - if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromLayoutObject(textLayoutObject.parent())) { + if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromLayoutObject(textLineLayout.parent())) { lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumValue(); SVGLengthContext lengthContext(textContentElement);
diff --git a/third_party/WebKit/Source/modules/EventTargetModulesFactory.in b/third_party/WebKit/Source/modules/EventTargetModulesFactory.in index 304b5ab..56613921 100644 --- a/third_party/WebKit/Source/modules/EventTargetModulesFactory.in +++ b/third_party/WebKit/Source/modules/EventTargetModulesFactory.in
@@ -25,6 +25,7 @@ modules/permissions/PermissionStatus modules/presentation/PresentationAvailability modules/presentation/PresentationConnection +modules/presentation/PresentationReceiver modules/presentation/PresentationRequest modules/screen_orientation/ScreenOrientation modules/serviceworkers/ServiceWorker
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp index 66d3a5dbf..678e9acc 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp +++ b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp
@@ -31,6 +31,7 @@ #include "config.h" #include "modules/mediastream/MediaConstraintsImpl.h" +#include "modules/mediastream/MediaTrackConstraintSet.h" #include "bindings/core/v8/ArrayValue.h" #include "bindings/core/v8/Dictionary.h" @@ -44,13 +45,46 @@ namespace MediaConstraintsImpl { +static bool parseMandatoryConstraintsDictionary(const Dictionary& mandatoryConstraintsDictionary, WebVector<WebMediaConstraint>& mandatory) +{ + Vector<WebMediaConstraint> mandatoryConstraintsVector; + HashMap<String, String> mandatoryConstraintsHashMap; + bool ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(mandatoryConstraintsHashMap); + if (!ok) + return false; + + for (const auto& iter : mandatoryConstraintsHashMap) + mandatoryConstraintsVector.append(WebMediaConstraint(iter.key, iter.value)); + mandatory.assign(mandatoryConstraintsVector); + return true; +} + +static bool parseOptionalConstraintsVectorElement(const Dictionary& constraint, Vector<WebMediaConstraint>& optionalConstraintsVector) +{ + Vector<String> localNames; + bool ok = constraint.getPropertyNames(localNames); + if (!ok) + return false; + if (localNames.size() != 1) + return false; + const String& key = localNames[0]; + String value; + ok = DictionaryHelper::get(constraint, key, value); + if (!ok) + return false; + optionalConstraintsVector.append(WebMediaConstraint(key, value)); + return true; +} + static bool parse(const Dictionary& constraintsDictionary, WebVector<WebMediaConstraint>& optional, WebVector<WebMediaConstraint>& mandatory) { if (constraintsDictionary.isUndefinedOrNull()) return true; Vector<String> names; - constraintsDictionary.getPropertyNames(names); + bool ok = constraintsDictionary.getPropertyNames(names); + if (!ok) + return false; String mandatoryName("mandatory"); String optionalName("optional"); @@ -60,21 +94,14 @@ return false; } - Vector<WebMediaConstraint> mandatoryConstraintsVector; if (names.contains(mandatoryName)) { Dictionary mandatoryConstraintsDictionary; bool ok = constraintsDictionary.get(mandatoryName, mandatoryConstraintsDictionary); if (!ok || mandatoryConstraintsDictionary.isUndefinedOrNull()) return false; - - HashMap<String, String> mandatoryConstraintsHashMap; - ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(mandatoryConstraintsHashMap); + ok = parseMandatoryConstraintsDictionary(mandatoryConstraintsDictionary, mandatory); if (!ok) return false; - - HashMap<String, String>::const_iterator iter = mandatoryConstraintsHashMap.begin(); - for (; iter != mandatoryConstraintsHashMap.end(); ++iter) - mandatoryConstraintsVector.append(WebMediaConstraint(iter->key, iter->value)); } Vector<WebMediaConstraint> optionalConstraintsVector; @@ -94,21 +121,38 @@ ok = optionalConstraints.get(i, constraint); if (!ok || constraint.isUndefinedOrNull()) return false; - Vector<String> localNames; - constraint.getPropertyNames(localNames); - if (localNames.size() != 1) - return false; - String key = localNames[0]; - String value; - ok = DictionaryHelper::get(constraint, key, value); + ok = parseOptionalConstraintsVectorElement(constraint, optionalConstraintsVector); if (!ok) return false; - optionalConstraintsVector.append(WebMediaConstraint(key, value)); } + optional.assign(optionalConstraintsVector); } - optional.assign(optionalConstraintsVector); - mandatory.assign(mandatoryConstraintsVector); + return true; +} + +static bool parse(const MediaTrackConstraintSet& constraintsIn, WebVector<WebMediaConstraint>& optional, WebVector<WebMediaConstraint>& mandatory) +{ + Vector<WebMediaConstraint> mandatoryConstraintsVector; + if (constraintsIn.hasMandatory()) { + bool ok = parseMandatoryConstraintsDictionary(constraintsIn.mandatory(), mandatory); + if (!ok) + return false; + } + + Vector<WebMediaConstraint> optionalConstraintsVector; + if (constraintsIn.hasOptional()) { + const Vector<Dictionary>& optionalConstraints = constraintsIn.optional(); + + for (const auto& constraint : optionalConstraints) { + if (constraint.isUndefinedOrNull()) + return false; + bool ok = parseOptionalConstraintsVectorElement(constraint, optionalConstraintsVector); + if (!ok) + return false; + } + optional.assign(optionalConstraintsVector); + } return true; } @@ -127,6 +171,19 @@ return constraints; } +WebMediaConstraints create(const MediaTrackConstraintSet& constraintsIn, ExceptionState& exceptionState) +{ + WebVector<WebMediaConstraint> optional; + WebVector<WebMediaConstraint> mandatory; + if (!parse(constraintsIn, optional, mandatory)) { + exceptionState.throwTypeError("Malformed constraints object."); + return WebMediaConstraints(); + } + WebMediaConstraints constraints; + constraints.initialize(optional, mandatory); + return constraints; +} + WebMediaConstraints create() { WebMediaConstraints constraints;
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h index d162c8b..04d3572 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h +++ b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.h
@@ -37,11 +37,13 @@ class Dictionary; class ExceptionState; +class MediaTrackConstraintSet; namespace MediaConstraintsImpl { WebMediaConstraints create(); WebMediaConstraints create(const Dictionary&, ExceptionState&); +WebMediaConstraints create(const MediaTrackConstraintSet&, ExceptionState&); }
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaStreamConstraints.idl b/third_party/WebKit/Source/modules/mediastream/MediaStreamConstraints.idl index 4ccb4ab..b5a8fee4 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaStreamConstraints.idl +++ b/third_party/WebKit/Source/modules/mediastream/MediaStreamConstraints.idl
@@ -1,23 +1,10 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-MediaStreamConstraints dictionary MediaStreamConstraints { - (boolean or Dictionary) video = false; - (boolean or Dictionary) audio = false; + (boolean or MediaTrackConstraintSet) video; + (boolean or MediaTrackConstraintSet) audio; };
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaTrackConstraintSet.idl b/third_party/WebKit/Source/modules/mediastream/MediaTrackConstraintSet.idl new file mode 100644 index 0000000..9f7f157 --- /dev/null +++ b/third_party/WebKit/Source/modules/mediastream/MediaTrackConstraintSet.idl
@@ -0,0 +1,12 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-MediaTrackConstraintSet + +dictionary MediaTrackConstraintSet { + // The "mandatory" and "_optional" members are retained for conformance + // with https://www.w3.org/TR/2013/WD-mediacapture-streams-20130903/ + Dictionary mandatory; + sequence<Dictionary> _optional; +};
diff --git a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp index 1f61be3c4..e16cacc 100644 --- a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp +++ b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
@@ -43,20 +43,24 @@ #include "modules/mediastream/MediaConstraintsImpl.h" #include "modules/mediastream/MediaStream.h" #include "modules/mediastream/MediaStreamConstraints.h" +#include "modules/mediastream/MediaTrackConstraintSet.h" #include "modules/mediastream/UserMediaController.h" #include "platform/mediastream/MediaStreamCenter.h" #include "platform/mediastream/MediaStreamDescriptor.h" namespace blink { -static WebMediaConstraints parseOptions(const BooleanOrDictionary& options, ExceptionState& exceptionState) +static WebMediaConstraints parseOptions(const BooleanOrMediaTrackConstraintSet& options, ExceptionState& exceptionState) { WebMediaConstraints constraints; Dictionary constraintsDictionary; - if (options.isDictionary()) { - constraints = MediaConstraintsImpl::create(options.getAsDictionary(), exceptionState); + if (options.isNull()) { + // Do nothing. + } else if (options.isMediaTrackConstraintSet()) { + constraints = MediaConstraintsImpl::create(options.getAsMediaTrackConstraintSet(), exceptionState); } else { + ASSERT(options.isBoolean()); if (options.getAsBoolean()) { constraints = MediaConstraintsImpl::create(); }
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi index 0b211493..f72c738 100644 --- a/third_party/WebKit/Source/modules/modules.gypi +++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -158,6 +158,7 @@ 'presentation/PresentationAvailability.idl', 'presentation/PresentationConnection.idl', 'presentation/PresentationConnectionAvailableEvent.idl', + 'presentation/PresentationReceiver.idl', 'presentation/PresentationRequest.idl', 'push_messaging/PushEvent.idl', 'push_messaging/PushManager.idl', @@ -456,6 +457,7 @@ 'mediarecorder/BlobEventInit.idl', 'mediastream/MediaStreamConstraints.idl', 'mediastream/MediaStreamEventInit.idl', + 'mediastream/MediaTrackConstraintSet.idl', 'mediastream/RTCDTMFToneChangeEventInit.idl', 'mediastream/RTCIceCandidateInit.idl', 'mediastream/RTCSessionDescriptionInit.idl', @@ -571,6 +573,8 @@ '<(blink_modules_output_dir)/mediastream/MediaStreamConstraints.h', '<(blink_modules_output_dir)/mediastream/MediaStreamEventInit.cpp', '<(blink_modules_output_dir)/mediastream/MediaStreamEventInit.h', + '<(blink_modules_output_dir)/mediastream/MediaTrackConstraintSet.cpp', + '<(blink_modules_output_dir)/mediastream/MediaTrackConstraintSet.h', '<(blink_modules_output_dir)/mediastream/RTCDTMFToneChangeEventInit.cpp', '<(blink_modules_output_dir)/mediastream/RTCDTMFToneChangeEventInit.h', '<(blink_modules_output_dir)/mediastream/RTCIceCandidateInit.cpp', @@ -1269,6 +1273,8 @@ 'presentation/PresentationController.h', 'presentation/PresentationError.cpp', 'presentation/PresentationError.h', + 'presentation/PresentationReceiver.cpp', + 'presentation/PresentationReceiver.h', 'presentation/PresentationRequest.cpp', 'presentation/PresentationRequest.h', 'push_messaging/PushController.cpp',
diff --git a/third_party/WebKit/Source/modules/presentation/Presentation.cpp b/third_party/WebKit/Source/modules/presentation/Presentation.cpp index c3a7f85b..962a22e 100644 --- a/third_party/WebKit/Source/modules/presentation/Presentation.cpp +++ b/third_party/WebKit/Source/modules/presentation/Presentation.cpp
@@ -8,6 +8,7 @@ #include "core/dom/Document.h" #include "core/frame/LocalFrame.h" #include "modules/presentation/PresentationController.h" +#include "modules/presentation/PresentationReceiver.h" #include "modules/presentation/PresentationRequest.h" namespace blink { @@ -32,6 +33,7 @@ DEFINE_TRACE(Presentation) { visitor->trace(m_defaultRequest); + visitor->trace(m_receiver); DOMWindowProperty::trace(visitor); } @@ -53,4 +55,14 @@ controller->setDefaultRequestUrl(request ? request->url() : KURL()); } +PresentationReceiver* Presentation::receiver() +{ + // TODO(mlamouri): only return something if the Blink instance is running in + // presentation receiver mode. The flag PresentationReceiver could be used + // for that. + if (!m_receiver) + m_receiver = new PresentationReceiver(frame()); + return m_receiver; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/presentation/Presentation.h b/third_party/WebKit/Source/modules/presentation/Presentation.h index 5ab715f..8091cd9 100644 --- a/third_party/WebKit/Source/modules/presentation/Presentation.h +++ b/third_party/WebKit/Source/modules/presentation/Presentation.h
@@ -13,6 +13,7 @@ namespace blink { class LocalFrame; +class PresentationReceiver; class PresentationRequest; // Implements the main entry point of the Presentation API corresponding to the Presentation.idl @@ -36,11 +37,17 @@ PresentationRequest* defaultRequest() const; void setDefaultRequest(PresentationRequest*); + PresentationReceiver* receiver(); + private: explicit Presentation(LocalFrame*); // Default PresentationRequest used by the embedder. Member<PresentationRequest> m_defaultRequest; + + // PresentationReceiver instance. It will always be nullptr if the Blink + // instance is not running as a presentation receiver. + Member<PresentationReceiver> m_receiver; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/presentation/Presentation.idl b/third_party/WebKit/Source/modules/presentation/Presentation.idl index cf72de62..968abde 100644 --- a/third_party/WebKit/Source/modules/presentation/Presentation.idl +++ b/third_party/WebKit/Source/modules/presentation/Presentation.idl
@@ -11,6 +11,5 @@ [MeasureAs=PresentationDefaultRequest] attribute PresentationRequest? defaultRequest; // This API is available on the receiving browsing context. - // TODO(mlamouri): implement PresentationReceiver, see https://crbug.com/525660 - // [SameObject] readonly attribute PresentationReceiver? receiver; + [RuntimeEnabled=PresentationReceiver, SameObject] readonly attribute PresentationReceiver? receiver; };
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp new file mode 100644 index 0000000..da40396b --- /dev/null +++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.cpp
@@ -0,0 +1,47 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "modules/presentation/PresentationReceiver.h" + +#include "bindings/core/v8/ScriptPromise.h" +#include "core/dom/DOMException.h" +#include "core/dom/Document.h" +#include "core/dom/ExceptionCode.h" +#include "modules/EventTargetModules.h" + +namespace blink { + +PresentationReceiver::PresentationReceiver(LocalFrame* frame) + : DOMWindowProperty(frame) +{ +} + +const AtomicString& PresentationReceiver::interfaceName() const +{ + return EventTargetNames::PresentationReceiver; +} + +ExecutionContext* PresentationReceiver::executionContext() const +{ + return frame() ? frame()->document() : nullptr; +} + +ScriptPromise PresentationReceiver::getConnection(ScriptState* scriptState) +{ + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "PresentationReceiver::getConnection() is not implemented yet.")); +} + +ScriptPromise PresentationReceiver::getConnections(ScriptState* scriptState) +{ + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "PresentationReceiver::getConnections() is not implemented yet.")); +} + +DEFINE_TRACE(PresentationReceiver) +{ + RefCountedGarbageCollectedEventTargetWithInlineData<PresentationReceiver>::trace(visitor); + DOMWindowProperty::trace(visitor); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.h b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.h new file mode 100644 index 0000000..412f222b --- /dev/null +++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.h
@@ -0,0 +1,42 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PresentationReceiver_h +#define PresentationReceiver_h + +#include "bindings/core/v8/ScriptPromise.h" +#include "core/events/EventTarget.h" +#include "core/frame/DOMWindowProperty.h" +#include "platform/heap/Handle.h" +#include "platform/heap/Heap.h" + +namespace blink { + +// Implements the PresentationReceiver interface from the Presentation API from +// which websites can implement the receiving side of a presentation session. +class PresentationReceiver final + : public RefCountedGarbageCollectedEventTargetWithInlineData<PresentationReceiver> + , DOMWindowProperty { + REFCOUNTED_GARBAGE_COLLECTED_EVENT_TARGET(PresentationReceiver); + WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PresentationReceiver); + DEFINE_WRAPPERTYPEINFO(); +public: + PresentationReceiver(LocalFrame*); + ~PresentationReceiver() = default; + + // EventTarget implementation. + const AtomicString& interfaceName() const override; + ExecutionContext* executionContext() const override; + + ScriptPromise getConnection(ScriptState*); + ScriptPromise getConnections(ScriptState*); + + DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable); + + DECLARE_VIRTUAL_TRACE(); +}; + +} // namespace blink + +#endif // PresentationReceiver_h
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationReceiver.idl b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.idl new file mode 100644 index 0000000..4039cec --- /dev/null +++ b/third_party/WebKit/Source/modules/presentation/PresentationReceiver.idl
@@ -0,0 +1,15 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3c.github.io/presentation-api/#interface-presentation + +[ + GarbageCollected, + RuntimeEnabled=PresentationReceiver +] interface PresentationReceiver : EventTarget { + [CallWith=ScriptState] Promise<PresentationConnection> getConnection(); + [CallWith=ScriptState] Promise<sequence<PresentationConnection>> getConnections(); + + attribute EventHandler onconnectionavailable; +};
diff --git a/third_party/WebKit/Source/platform/LayoutTestSupport.cpp b/third_party/WebKit/Source/platform/LayoutTestSupport.cpp index 928de04..70eb860 100644 --- a/third_party/WebKit/Source/platform/LayoutTestSupport.cpp +++ b/third_party/WebKit/Source/platform/LayoutTestSupport.cpp
@@ -35,6 +35,7 @@ static bool s_isRunningLayoutTest = false; static bool s_isFontAntialiasingEnabled = false; +static bool s_alwaysUseComplexTextForTest = false; bool LayoutTestSupport::isRunningLayoutTest() { @@ -56,4 +57,14 @@ s_isFontAntialiasingEnabled = value; } +bool LayoutTestSupport::alwaysUseComplexTextForTest() +{ + return s_alwaysUseComplexTextForTest; +} + +void LayoutTestSupport::setAlwaysUseComplexTextForTest(bool value) +{ + s_alwaysUseComplexTextForTest = value; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/LayoutTestSupport.h b/third_party/WebKit/Source/platform/LayoutTestSupport.h index f3853a1..f953d84f 100644 --- a/third_party/WebKit/Source/platform/LayoutTestSupport.h +++ b/third_party/WebKit/Source/platform/LayoutTestSupport.h
@@ -41,6 +41,8 @@ PLATFORM_EXPORT static void setIsRunningLayoutTest(bool); PLATFORM_EXPORT static bool isFontAntialiasingEnabledForTest(); PLATFORM_EXPORT static void setFontAntialiasingEnabledForTest(bool); + PLATFORM_EXPORT static bool alwaysUseComplexTextForTest(); + PLATFORM_EXPORT static void setAlwaysUseComplexTextForTest(bool); }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/Logging.cpp b/third_party/WebKit/Source/platform/Logging.cpp index f10e5a6..ac945fd4 100644 --- a/third_party/WebKit/Source/platform/Logging.cpp +++ b/third_party/WebKit/Source/platform/Logging.cpp
@@ -70,6 +70,8 @@ WTFLogChannel LogScriptedAnimationController = { WTFLogChannelOff }; WTFLogChannel LogTimers = { WTFLogChannelOff }; +WTFLogChannel LogFonts = { WTFLogChannelOff }; + WTFLogChannel* getChannelFromName(const String& channelName) { if (!(channelName.length() >= 2)) @@ -156,6 +158,9 @@ if (equalIgnoringCase(channelName, String("Timers"))) return &LogTimers; + if (equalIgnoringCase(channelName, String("Fonts"))) + return &LogFonts; + return 0; }
diff --git a/third_party/WebKit/Source/platform/Logging.h b/third_party/WebKit/Source/platform/Logging.h index 55c8443..eca9c3df 100644 --- a/third_party/WebKit/Source/platform/Logging.h +++ b/third_party/WebKit/Source/platform/Logging.h
@@ -66,6 +66,7 @@ PLATFORM_EXPORT extern WTFLogChannel LogGamepad; PLATFORM_EXPORT extern WTFLogChannel LogScriptedAnimationController; PLATFORM_EXPORT extern WTFLogChannel LogTimers; +PLATFORM_EXPORT extern WTFLogChannel LogFonts; PLATFORM_EXPORT WTFLogChannel* getChannelFromName(const String& channelName);
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in index a015032f..ba96635 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -127,6 +127,7 @@ // See https://crbug.com/346236 for current status. PrefixedVideoFullscreen status=stable Presentation status=stable +PresentationReceiver status=test PromiseRejectionEvent status=experimental PushMessaging status=stable // Push messaging payloads are blocked on the Push API supporting encryption. @@ -185,7 +186,7 @@ WebGLDraftExtensions status=experimental WebGLImageChromium WebUSB status=experimental -WebVR depends_on=GeometryInterfaces +WebVR depends_on=GeometryInterfaces, status=test WebVTTRegions depends_on=Media, status=experimental V8IdleTasks XSLT status=stable
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi index e1adf80b..3bfd1fe3 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gypi +++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -393,12 +393,16 @@ 'fonts/GlyphPageTreeNode.cpp', 'fonts/GlyphPageTreeNode.h', 'fonts/Latin1TextIterator.h', + 'fonts/OrientationIterator.h', + 'fonts/OrientationIterator.cpp', 'fonts/ScriptRunIterator.h', 'fonts/ScriptRunIterator.cpp', 'fonts/SegmentedFontData.cpp', 'fonts/SegmentedFontData.h', 'fonts/SimpleFontData.cpp', 'fonts/SimpleFontData.h', + 'fonts/SmallCapsIterator.cpp', + 'fonts/SmallCapsIterator.h', 'fonts/TextBlob.h', 'fonts/UTF16TextIterator.cpp', 'fonts/UTF16TextIterator.h', @@ -423,6 +427,8 @@ 'fonts/shaping/HarfBuzzFace.h', 'fonts/shaping/HarfBuzzShaper.cpp', 'fonts/shaping/HarfBuzzShaper.h', + 'fonts/shaping/RunSegmenter.h', + 'fonts/shaping/RunSegmenter.cpp', 'fonts/shaping/ShapeCache.h', 'fonts/shaping/Shaper.cpp', 'fonts/shaping/Shaper.h', @@ -976,11 +982,14 @@ 'fonts/FontTest.cpp', 'fonts/GlyphBufferTest.cpp', 'fonts/GlyphPageTreeNodeTest.cpp', + 'fonts/OrientationIteratorTest.cpp', 'fonts/ScriptRunIteratorTest.cpp', + 'fonts/SmallCapsIteratorTest.cpp', 'fonts/android/FontCacheAndroidTest.cpp', 'fonts/mac/FontFamilyMatcherMacTest.mm', 'fonts/shaping/CachingWordShaperTest.cpp', 'fonts/shaping/HarfBuzzShaperTest.cpp', + 'fonts/shaping/RunSegmenterTest.cpp', 'fonts/win/FontFallbackWinTest.cpp', 'geometry/FloatBoxTest.cpp', 'geometry/FloatBoxTestHelpers.cpp',
diff --git a/third_party/WebKit/Source/platform/fonts/Font.cpp b/third_party/WebKit/Source/platform/fonts/Font.cpp index be6e9d4..77ab8d9 100644 --- a/third_party/WebKit/Source/platform/fonts/Font.cpp +++ b/third_party/WebKit/Source/platform/fonts/Font.cpp
@@ -25,6 +25,7 @@ #include "config.h" #include "platform/fonts/Font.h" +#include "platform/LayoutTestSupport.h" #include "platform/LayoutUnit.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/fonts/Character.h" @@ -310,8 +311,10 @@ CodePath Font::codePath(const TextRunPaintInfo& runInfo) const { - if (RuntimeEnabledFeatures::alwaysUseComplexTextEnabled()) + if (RuntimeEnabledFeatures::alwaysUseComplexTextEnabled() + || LayoutTestSupport::alwaysUseComplexTextForTest()) { return ComplexPath; + } const TextRun& run = runInfo.run;
diff --git a/third_party/WebKit/Source/platform/fonts/OrientationIterator.cpp b/third_party/WebKit/Source/platform/fonts/OrientationIterator.cpp new file mode 100644 index 0000000..1177b181 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/OrientationIterator.cpp
@@ -0,0 +1,44 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "OrientationIterator.h" + +namespace blink { + +OrientationIterator::OrientationIterator(const UChar* buffer, unsigned bufferSize, FontOrientation runOrientation) + : m_utf16Iterator(adoptPtr(new UTF16TextIterator(buffer, bufferSize))) + , m_bufferSize(bufferSize) + , m_nextUChar32(0) + , m_atEnd(bufferSize == 0) + , m_currentRenderOrientation(OrientationInvalid) +{ + // There's not much point in segmenting by isUprightInVertical if the text + // orientation is not "mixed". + ASSERT(runOrientation == FontOrientation::VerticalMixed); +} + +bool OrientationIterator::consume(unsigned *orientationLimit, RenderOrientation* renderOrientation) +{ + if (m_atEnd) + return false; + + while (m_utf16Iterator->consume(m_nextUChar32)) { + m_previousRenderOrientation = m_currentRenderOrientation; + m_currentRenderOrientation = Character::isUprightInMixedVertical(m_nextUChar32) ? OrientationKeep : OrientationRotateSideways; + + if (m_previousRenderOrientation != m_currentRenderOrientation && m_previousRenderOrientation != OrientationInvalid) { + *orientationLimit = m_utf16Iterator->offset(); + *renderOrientation = m_previousRenderOrientation; + return true; + } + m_utf16Iterator->advance(); + } + *orientationLimit = m_bufferSize; + *renderOrientation = m_currentRenderOrientation; + m_atEnd = true; + return true; +} + +}
diff --git a/third_party/WebKit/Source/platform/fonts/OrientationIterator.h b/third_party/WebKit/Source/platform/fonts/OrientationIterator.h new file mode 100644 index 0000000..aa87b80 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/OrientationIterator.h
@@ -0,0 +1,37 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OrientationIterator_h +#define OrientationIterator_h + +#include "platform/fonts/FontOrientation.h" +#include "platform/fonts/ScriptRunIterator.h" +#include "platform/fonts/UTF16TextIterator.h" + +namespace blink { + +class PLATFORM_EXPORT OrientationIterator { +public: + enum RenderOrientation { + OrientationKeep, + OrientationRotateSideways, + OrientationInvalid + }; + + OrientationIterator(const UChar* buffer, unsigned bufferSize, FontOrientation runOrientation); + + bool consume(unsigned* orientationLimit, RenderOrientation*); +private: + OwnPtr<UTF16TextIterator> m_utf16Iterator; + unsigned m_bufferSize; + UChar32 m_nextUChar32; + bool m_atEnd; + + RenderOrientation m_currentRenderOrientation; + RenderOrientation m_previousRenderOrientation; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/platform/fonts/OrientationIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/OrientationIteratorTest.cpp new file mode 100644 index 0000000..8d57a2b7 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/OrientationIteratorTest.cpp
@@ -0,0 +1,153 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "platform/fonts/OrientationIterator.h" + +#include "platform/Logging.h" + +#include <gtest/gtest.h> +#include <string> +#include <vector> + +namespace blink { + +struct TestRun { + std::string text; + OrientationIterator::RenderOrientation code; +}; + +struct ExpectedRun { + unsigned limit; + OrientationIterator::RenderOrientation renderOrientation; + + ExpectedRun(unsigned theLimit, OrientationIterator::RenderOrientation theRenderOrientation) + : limit(theLimit) + , renderOrientation(theRenderOrientation) + { + } +}; + +class OrientationIteratorTest : public testing::Test { +protected: +#if !LOG_DISABLED + static void SetUpTestCase() + { + LogFonts = { WTFLogChannelOn }; + } +#endif + + void CheckRuns(const std::vector<TestRun>& runs) + { + String text(String::make16BitFrom8BitSource(0, 0)); + std::vector<ExpectedRun> expect; + for (auto& run : runs) { + text.append(String::fromUTF8(run.text.c_str())); + expect.push_back(ExpectedRun(text.length(), run.code)); + } + OrientationIterator orientationIterator(text.characters16(), text.length(), FontOrientation::VerticalMixed); + VerifyRuns(&orientationIterator, expect); + } + + void VerifyRuns(OrientationIterator* orientationIterator, + const std::vector<ExpectedRun>& expect) + { + unsigned limit; + OrientationIterator::RenderOrientation renderOrientation; + unsigned long runCount = 0; + while (orientationIterator->consume(&limit, &renderOrientation)) { + ASSERT_LT(runCount, expect.size()); + ASSERT_EQ(expect[runCount].limit, limit); + ASSERT_EQ(expect[runCount].renderOrientation, renderOrientation); + ++runCount; + } + WTF_LOG(Fonts, "Expected %zu runs, got %lu ", expect.size(), runCount); + ASSERT_EQ(expect.size(), runCount); + } +}; + +// Some of our compilers cannot initialize a vector from an array yet. +#define DECLARE_RUNSVECTOR(...) \ + static const TestRun runsArray[] = __VA_ARGS__; \ + std::vector<TestRun> runs(runsArray, runsArray + sizeof(runsArray) / sizeof(*runsArray)); + +#define CHECK_RUNS(...) \ + DECLARE_RUNSVECTOR(__VA_ARGS__); \ + CheckRuns(runs); + + +TEST_F(OrientationIteratorTest, Empty) +{ + String empty(String::make16BitFrom8BitSource(0, 0)); + OrientationIterator orientationIterator(empty.characters16(), empty.length(), FontOrientation::VerticalMixed); + unsigned limit = 0; + OrientationIterator::RenderOrientation orientation = OrientationIterator::OrientationInvalid; + ASSERT(!orientationIterator.consume(&limit, &orientation)); + ASSERT_EQ(limit, 0u); + ASSERT_EQ(orientation, OrientationIterator::OrientationInvalid); +} + +TEST_F(OrientationIteratorTest, OneCharLatin) +{ + CHECK_RUNS({ { "A", OrientationIterator::OrientationRotateSideways } }); +} + +TEST_F(OrientationIteratorTest, OneAceOfSpades) +{ + CHECK_RUNS({ { "🂡", OrientationIterator::OrientationKeep } }); +} + +TEST_F(OrientationIteratorTest, OneEthiopicSyllable) +{ + CHECK_RUNS({ { "ጀ", OrientationIterator::OrientationRotateSideways } }); +} + +TEST_F(OrientationIteratorTest, JapaneseLetterlikeEnd) +{ + CHECK_RUNS({ { "いろは", OrientationIterator::OrientationKeep }, + { "ℐℒℐℒℐℒℐℒℐℒℐℒℐℒ", OrientationIterator::OrientationRotateSideways } }); +} + +TEST_F(OrientationIteratorTest, LetterlikeJapaneseEnd) +{ + CHECK_RUNS({ { "ℐ", OrientationIterator::OrientationRotateSideways }, + { "いろは", OrientationIterator::OrientationKeep } }); +} + +TEST_F(OrientationIteratorTest, OneCharJapanese) +{ + CHECK_RUNS({ { "い", OrientationIterator::OrientationKeep } }); +} + +TEST_F(OrientationIteratorTest, Japanese) +{ + CHECK_RUNS({ { "いろはにほへと", OrientationIterator::OrientationKeep } }); +} + +TEST_F(OrientationIteratorTest, JapaneseLatinMixedInside) +{ + CHECK_RUNS({ { "いろはに", OrientationIterator::OrientationKeep }, + { "Abc", OrientationIterator::OrientationRotateSideways }, + { "ほへと", OrientationIterator::OrientationKeep } }); +} + +TEST_F(OrientationIteratorTest, PunctuationJapanese) +{ + CHECK_RUNS({ { ".…¡", OrientationIterator::OrientationRotateSideways }, + { "ほへと", OrientationIterator::OrientationKeep } }); +} + +TEST_F(OrientationIteratorTest, JapaneseLatinMixedOutside) +{ + CHECK_RUNS({ { "Abc", OrientationIterator::OrientationRotateSideways }, + { "ほへと", OrientationIterator::OrientationKeep }, + { "Xyz", OrientationIterator::OrientationRotateSideways } }); +} + +TEST_F(OrientationIteratorTest, JapaneseMahjonggMixed) +{ + CHECK_RUNS({ { "いろはに🀤ほへと", OrientationIterator::OrientationKeep } }); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/SmallCapsIterator.cpp b/third_party/WebKit/Source/platform/fonts/SmallCapsIterator.cpp new file mode 100644 index 0000000..9819490 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/SmallCapsIterator.cpp
@@ -0,0 +1,51 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "SmallCapsIterator.h" + +#include <unicode/utypes.h> + +namespace blink { + +SmallCapsIterator::SmallCapsIterator(const UChar* buffer, unsigned bufferSize) + : m_utf16Iterator(adoptPtr(new UTF16TextIterator(buffer, bufferSize))) + , m_bufferSize(bufferSize) + , m_nextUChar32(0) + , m_atEnd(bufferSize == 0) + , m_currentSmallCapsBehavior(SmallCapsInvalid) +{ +} + +bool SmallCapsIterator::consume(unsigned *capsLimit, SmallCapsBehavior* smallCapsBehavior) +{ + if (m_atEnd) + return false; + + while (m_utf16Iterator->consume(m_nextUChar32)) { + m_previousSmallCapsBehavior = m_currentSmallCapsBehavior; + // Skipping over combining marks, as these combine with the small-caps + // uppercased text as well and we do not need to split by their + // individual case-ness. + if (!u_getCombiningClass(m_nextUChar32)) { + m_currentSmallCapsBehavior = u_hasBinaryProperty(m_nextUChar32, UCHAR_CHANGES_WHEN_UPPERCASED) + ? SmallCapsUppercaseNeeded + : SmallCapsSameCase; + } + + if (m_previousSmallCapsBehavior != m_currentSmallCapsBehavior + && m_previousSmallCapsBehavior != SmallCapsInvalid) { + *capsLimit = m_utf16Iterator->offset(); + *smallCapsBehavior = m_previousSmallCapsBehavior; + return true; + } + m_utf16Iterator->advance(); + } + *capsLimit = m_bufferSize; + *smallCapsBehavior = m_currentSmallCapsBehavior; + m_atEnd = true; + return true; +} + +}
diff --git a/third_party/WebKit/Source/platform/fonts/SmallCapsIterator.h b/third_party/WebKit/Source/platform/fonts/SmallCapsIterator.h new file mode 100644 index 0000000..ab58d621 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/SmallCapsIterator.h
@@ -0,0 +1,37 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SmallCapsIterator_h +#define SmallCapsIterator_h + +#include "platform/fonts/FontOrientation.h" +#include "platform/fonts/ScriptRunIterator.h" +#include "platform/fonts/UTF16TextIterator.h" + +namespace blink { + +class PLATFORM_EXPORT SmallCapsIterator { +public: + enum SmallCapsBehavior { + SmallCapsSameCase, + SmallCapsUppercaseNeeded, + SmallCapsInvalid + }; + + SmallCapsIterator(const UChar* buffer, unsigned bufferSize); + + bool consume(unsigned* capsLimit, SmallCapsBehavior*); +private: + OwnPtr<UTF16TextIterator> m_utf16Iterator; + unsigned m_bufferSize; + UChar32 m_nextUChar32; + bool m_atEnd; + + SmallCapsBehavior m_currentSmallCapsBehavior; + SmallCapsBehavior m_previousSmallCapsBehavior; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/platform/fonts/SmallCapsIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/SmallCapsIteratorTest.cpp new file mode 100644 index 0000000..d172899 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/SmallCapsIteratorTest.cpp
@@ -0,0 +1,141 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "platform/fonts/SmallCapsIterator.h" + +#include "platform/Logging.h" + +#include <gtest/gtest.h> +#include <string> +#include <vector> + +namespace blink { + +struct TestRun { + std::string text; + SmallCapsIterator::SmallCapsBehavior code; +}; + +struct ExpectedRun { + unsigned limit; + SmallCapsIterator::SmallCapsBehavior smallCapsBehavior; + + ExpectedRun(unsigned theLimit, SmallCapsIterator::SmallCapsBehavior theSmallCapsBehavior) + : limit(theLimit) + , smallCapsBehavior(theSmallCapsBehavior) + { + } +}; + +class SmallCapsIteratorTest : public testing::Test { +protected: +#if !LOG_DISABLED + static void SetUpTestCase() + { + LogFonts = { WTFLogChannelOn }; + } +#endif + + void CheckRuns(const std::vector<TestRun>& runs) + { + String text(String::make16BitFrom8BitSource(0, 0)); + std::vector<ExpectedRun> expect; + for (auto& run : runs) { + text.append(String::fromUTF8(run.text.c_str())); + expect.push_back(ExpectedRun(text.length(), run.code)); + } + SmallCapsIterator smallCapsIterator(text.characters16(), text.length()); + VerifyRuns(&smallCapsIterator, expect); + } + + void VerifyRuns(SmallCapsIterator* smallCapsIterator, + const std::vector<ExpectedRun>& expect) + { + unsigned limit; + SmallCapsIterator::SmallCapsBehavior smallCapsBehavior; + unsigned long runCount = 0; + while (smallCapsIterator->consume(&limit, &smallCapsBehavior)) { + ASSERT_LT(runCount, expect.size()); + ASSERT_EQ(expect[runCount].limit, limit); + ASSERT_EQ(expect[runCount].smallCapsBehavior, smallCapsBehavior); + ++runCount; + } + WTF_LOG(Fonts, "Expected %zu runs, got %lu ", expect.size(), runCount); + ASSERT_EQ(expect.size(), runCount); + } +}; + +// Some of our compilers cannot initialize a vector from an array yet. +#define DECLARE_RUNSVECTOR(...) \ + static const TestRun runsArray[] = __VA_ARGS__; \ + std::vector<TestRun> runs(runsArray, runsArray + sizeof(runsArray) / sizeof(*runsArray)); + +#define CHECK_RUNS(...) \ + DECLARE_RUNSVECTOR(__VA_ARGS__); \ + CheckRuns(runs); + + +TEST_F(SmallCapsIteratorTest, Empty) +{ + String empty(String::make16BitFrom8BitSource(0, 0)); + SmallCapsIterator smallCapsIterator(empty.characters16(), empty.length()); + unsigned limit = 0; + SmallCapsIterator::SmallCapsBehavior smallCapsBehavior = SmallCapsIterator::SmallCapsInvalid; + ASSERT(!smallCapsIterator.consume(&limit, &smallCapsBehavior)); + ASSERT_EQ(limit, 0u); + ASSERT_EQ(smallCapsBehavior, SmallCapsIterator::SmallCapsInvalid); +} + +TEST_F(SmallCapsIteratorTest, UppercaseA) +{ + CHECK_RUNS({ { "A", SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(SmallCapsIteratorTest, LowercaseA) +{ + CHECK_RUNS({ { "a", SmallCapsIterator::SmallCapsUppercaseNeeded } }); +} + +TEST_F(SmallCapsIteratorTest, UppercaseLowercaseA) +{ + CHECK_RUNS({ { "A", SmallCapsIterator::SmallCapsSameCase }, + { "a", SmallCapsIterator::SmallCapsUppercaseNeeded } }); +} + +TEST_F(SmallCapsIteratorTest, UppercasePunctuationMixed) +{ + CHECK_RUNS({ { "AAA??", SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(SmallCapsIteratorTest, LowercasePunctuationMixed) +{ + CHECK_RUNS({ { "aaa", SmallCapsIterator::SmallCapsUppercaseNeeded }, + { "===", SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(SmallCapsIteratorTest, LowercasePunctuationInterleaved) +{ + CHECK_RUNS({ { "aaa", SmallCapsIterator::SmallCapsUppercaseNeeded }, + { "===", SmallCapsIterator::SmallCapsSameCase }, + { "bbb", SmallCapsIterator::SmallCapsUppercaseNeeded } }); +} + +TEST_F(SmallCapsIteratorTest, Japanese) +{ + CHECK_RUNS({ { "ほへと", SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(SmallCapsIteratorTest, Armenian) +{ + CHECK_RUNS({ { "աբգդ", SmallCapsIterator::SmallCapsUppercaseNeeded }, + { "ԵԶԷԸ", SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(SmallCapsIteratorTest, CombiningCharacterSequence) +{ + CHECK_RUNS({ { "èü", SmallCapsIterator::SmallCapsUppercaseNeeded } }); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenter.cpp b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenter.cpp new file mode 100644 index 0000000..8cf7098 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenter.cpp
@@ -0,0 +1,94 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "platform/fonts/shaping/RunSegmenter.h" + +#include "platform/fonts/Character.h" +#include "platform/fonts/ScriptRunIterator.h" +#include "platform/fonts/SmallCapsIterator.h" +#include "platform/fonts/UTF16TextIterator.h" +#include "wtf/Assertions.h" + +namespace blink { + +RunSegmenter::RunSegmenter(const UChar* buffer, unsigned bufferSize, FontOrientation runOrientation, FontVariant variant) + : m_bufferSize(bufferSize) + , m_candidateRange({ 0, 0, USCRIPT_INVALID_CODE, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }) + , m_scriptRunIterator(adoptPtr(new ScriptRunIterator(buffer, bufferSize))) + , m_orientationIterator(runOrientation == FontOrientation::VerticalMixed ? adoptPtr(new OrientationIterator(buffer, bufferSize, runOrientation)) : nullptr) + , m_smallCapsIterator(variant == FontVariantSmallCaps ? adoptPtr(new SmallCapsIterator(buffer, bufferSize)) : nullptr) + , m_lastSplit(0) + , m_scriptRunIteratorPosition(0) + , m_orientationIteratorPosition(runOrientation == FontOrientation::VerticalMixed ? 0 : m_bufferSize) + , m_smallCapsIteratorPosition(variant == FontVariantSmallCaps ? 0 : m_bufferSize) + , m_atEnd(false) +{ +} + +void RunSegmenter::consumeScriptIteratorPastLastSplit() +{ + ASSERT(m_scriptRunIterator); + if (m_scriptRunIteratorPosition <= m_lastSplit && m_scriptRunIteratorPosition < m_bufferSize) { + while (m_scriptRunIterator->consume(m_scriptRunIteratorPosition, m_candidateRange.script)) { + if (m_scriptRunIteratorPosition > m_lastSplit) + return; + } + } +} + +void RunSegmenter::consumeOrientationIteratorPastLastSplit() +{ + if (m_orientationIterator && m_orientationIteratorPosition <= m_lastSplit && m_orientationIteratorPosition < m_bufferSize) { + while (m_orientationIterator->consume(&m_orientationIteratorPosition, &m_candidateRange.renderOrientation)) { + if (m_orientationIteratorPosition > m_lastSplit) + return; + } + } +} + +void RunSegmenter::consumeSmallCapsIteratorPastLastSplit() +{ + if (m_smallCapsIterator && m_smallCapsIteratorPosition <= m_lastSplit && m_smallCapsIteratorPosition < m_bufferSize) { + while (m_smallCapsIterator->consume(&m_smallCapsIteratorPosition, &m_candidateRange.smallCapsBehavior)) { + if (m_smallCapsIteratorPosition > m_lastSplit) + return; + } + } +} + +bool RunSegmenter::consume(RunSegmenterRange* nextRange) +{ + if (m_atEnd || !m_bufferSize) + return false; + + consumeScriptIteratorPastLastSplit(); + consumeOrientationIteratorPastLastSplit(); + consumeSmallCapsIteratorPastLastSplit(); + + if (m_scriptRunIteratorPosition <= m_orientationIteratorPosition + && m_scriptRunIteratorPosition <= m_smallCapsIteratorPosition) { + m_lastSplit = m_scriptRunIteratorPosition; + } + + if (m_orientationIteratorPosition <= m_scriptRunIteratorPosition + && m_orientationIteratorPosition <= m_smallCapsIteratorPosition) { + m_lastSplit = m_orientationIteratorPosition; + } + + if (m_smallCapsIteratorPosition <= m_scriptRunIteratorPosition + && m_smallCapsIteratorPosition <= m_orientationIteratorPosition) { + m_lastSplit = m_smallCapsIteratorPosition; + } + + m_candidateRange.start = m_candidateRange.end; + m_candidateRange.end = m_lastSplit; + *nextRange = m_candidateRange; + + m_atEnd = m_lastSplit == m_bufferSize; + return true; +} + + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenter.h b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenter.h new file mode 100644 index 0000000..76e025f --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenter.h
@@ -0,0 +1,59 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef RunSegmenter_h +#define RunSegmenter_h + +#include "platform/fonts/FontOrientation.h" +#include "platform/fonts/FontTraits.h" +#include "platform/fonts/OrientationIterator.h" +#include "platform/fonts/ScriptRunIterator.h" +#include "platform/fonts/SmallCapsIterator.h" +#include "platform/fonts/UTF16TextIterator.h" + +#include <unicode/uscript.h> + +namespace blink { + +// A tool for segmenting runs prior to shaping, combining ScriptIterator, +// OrientationIterator and SmallCapsIterator, depending on orientaton and +// font-variant of the text run. +class PLATFORM_EXPORT RunSegmenter { + +public: + + // Indices into the UTF-16 buffer that is passed in + struct RunSegmenterRange { + unsigned start; + unsigned end; + UScriptCode script; + OrientationIterator::RenderOrientation renderOrientation; + SmallCapsIterator::SmallCapsBehavior smallCapsBehavior; + }; + + RunSegmenter(const UChar* buffer, unsigned bufferSize, FontOrientation, FontVariant); + + bool consume(RunSegmenterRange*); + +private: + + void consumeOrientationIteratorPastLastSplit(); + void consumeSmallCapsIteratorPastLastSplit(); + void consumeScriptIteratorPastLastSplit(); + + unsigned m_bufferSize; + RunSegmenterRange m_candidateRange; + OwnPtr<ScriptRunIterator> m_scriptRunIterator; + OwnPtr<OrientationIterator> m_orientationIterator; + OwnPtr<SmallCapsIterator> m_smallCapsIterator; + unsigned m_lastSplit; + unsigned m_scriptRunIteratorPosition; + unsigned m_orientationIteratorPosition; + unsigned m_smallCapsIteratorPosition; + bool m_atEnd; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp new file mode 100644 index 0000000..d66c7f2 --- /dev/null +++ b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp
@@ -0,0 +1,206 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" +#include "platform/fonts/shaping/RunSegmenter.h" + +#include "platform/Logging.h" +#include "platform/fonts/OrientationIterator.h" +#include "wtf/Assertions.h" +#include "wtf/Threading.h" +#include "wtf/text/WTFString.h" + +#include <gtest/gtest.h> +#include <string> +#include <vector> + +namespace blink { + + +struct SegmenterTestRun { + std::string text; + UScriptCode script; + OrientationIterator::RenderOrientation renderOrientation; + SmallCapsIterator::SmallCapsBehavior smallCapsBehavior; +}; + +struct SegmenterExpectedRun { + unsigned start; + unsigned limit; + UScriptCode script; + OrientationIterator::RenderOrientation renderOrientation; + SmallCapsIterator::SmallCapsBehavior smallCapsBehavior; + + SegmenterExpectedRun(unsigned theStart, + unsigned theLimit, + UScriptCode theScript, + OrientationIterator::RenderOrientation theRenderOrientation, + SmallCapsIterator::SmallCapsBehavior theSmallCapsBehavior) + : start(theStart) + , limit(theLimit) + , script(theScript) + , renderOrientation(theRenderOrientation) + , smallCapsBehavior(theSmallCapsBehavior) + { + } +}; + +class RunSegmenterTest : public testing::Test { +protected: +#if !LOG_DISABLED + static void SetUpTestCase() + { + LogFonts = { WTFLogChannelOn }; + } +#endif + + void CheckRuns(const std::vector<SegmenterTestRun>& runs, FontOrientation orientation, FontVariant variant) + { + String text(String::make16BitFrom8BitSource(0, 0)); + std::vector<SegmenterExpectedRun> expect; + for (auto& run : runs) { + unsigned lengthBefore = text.length(); + text.append(String::fromUTF8(run.text.c_str())); + expect.push_back(SegmenterExpectedRun(lengthBefore, text.length(), run.script, run.renderOrientation, run.smallCapsBehavior)); + } + RunSegmenter runSegmenter(text.characters16(), text.length(), orientation, variant); + VerifyRuns(&runSegmenter, expect); + } + + void VerifyRuns(RunSegmenter* runSegmenter, + const std::vector<SegmenterExpectedRun>& expect) + { + RunSegmenter::RunSegmenterRange segmenterRange; + unsigned long runCount = 0; + while (runSegmenter->consume(&segmenterRange)) { + ASSERT_LT(runCount, expect.size()); + ASSERT_EQ(expect[runCount].start, segmenterRange.start); + ASSERT_EQ(expect[runCount].limit, segmenterRange.end); + ASSERT_EQ(expect[runCount].script, segmenterRange.script); + ASSERT_EQ(expect[runCount].renderOrientation, segmenterRange.renderOrientation); + ASSERT_EQ(expect[runCount].smallCapsBehavior, segmenterRange.smallCapsBehavior); + ++runCount; + } + ASSERT_EQ(expect.size(), runCount); + } +}; + +// Some of our compilers cannot initialize a vector from an array yet. +#define DECLARE_RUNSVECTOR(...) \ + static const SegmenterTestRun runsArray[] = __VA_ARGS__; \ + std::vector<SegmenterTestRun> runs(runsArray, runsArray + sizeof(runsArray) / sizeof(*runsArray)); + +#define CHECK_RUNS_MIXED_NORMAL(...) \ + DECLARE_RUNSVECTOR(__VA_ARGS__); \ + CheckRuns(runs, FontOrientation::VerticalMixed, FontVariantNormal); + +#define CHECK_RUNS_MIXED_SMALLCAPS(...) \ + DECLARE_RUNSVECTOR(__VA_ARGS__); \ + CheckRuns(runs, FontOrientation::VerticalMixed, FontVariantSmallCaps); + +#define CHECK_RUNS_HORIZONTAL_NORMAL(...) \ + DECLARE_RUNSVECTOR(__VA_ARGS__); \ + CheckRuns(runs, FontOrientation::Horizontal, FontVariantNormal); + +#define CHECK_RUNS_HORIZONTAL_SMALLCAPS(...) \ + DECLARE_RUNSVECTOR(__VA_ARGS__); \ + CheckRuns(runs, FontOrientation::Horizontal, FontVariantSmallCaps); + + +TEST_F(RunSegmenterTest, Empty) +{ + String empty(String::make16BitFrom8BitSource(0, 0)); + RunSegmenter::RunSegmenterRange segmenterRange = { 0, 0, USCRIPT_INVALID_CODE, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }; + RunSegmenter runSegmenter(empty.characters16(), empty.length(), FontOrientation::VerticalMixed, FontVariantNormal); + ASSERT(!runSegmenter.consume(&segmenterRange)); + ASSERT_EQ(segmenterRange.start, 0u); + ASSERT_EQ(segmenterRange.end, 0u); + ASSERT_EQ(segmenterRange.script, USCRIPT_INVALID_CODE); + ASSERT_EQ(segmenterRange.renderOrientation, OrientationIterator::OrientationKeep); + ASSERT_EQ(segmenterRange.smallCapsBehavior, SmallCapsIterator::SmallCapsSameCase); +} + +TEST_F(RunSegmenterTest, LatinPunctuationSideways) +{ + CHECK_RUNS_MIXED_NORMAL({ { "Abc.;?Xyz", USCRIPT_LATIN, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, OneSpace) +{ + CHECK_RUNS_MIXED_NORMAL({ { " ", USCRIPT_COMMON, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, ArabicHangul) +{ + CHECK_RUNS_MIXED_NORMAL({ { "نص", USCRIPT_ARABIC, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase }, + { "키스의", USCRIPT_HANGUL, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, JapaneseHindiEmojiMix) +{ + CHECK_RUNS_MIXED_NORMAL({ { "百家姓", USCRIPT_HAN, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }, + { "ऋषियों", USCRIPT_DEVANAGARI, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase }, + { "🌱🌲🌳🌴", USCRIPT_DEVANAGARI, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }, + { "百家姓🌱🌲", USCRIPT_HAN, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, HangulSpace) +{ + CHECK_RUNS_MIXED_NORMAL({ { "키스의", USCRIPT_HANGUL, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }, + { " ", USCRIPT_HANGUL, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase }, + { "고유조건은", USCRIPT_HANGUL, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, TechnicalCommonUpright) +{ + CHECK_RUNS_MIXED_NORMAL({ { "⌀⌁⌂", USCRIPT_COMMON, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, PunctuationCommonSideways) +{ + CHECK_RUNS_MIXED_NORMAL({ { ".…¡", USCRIPT_COMMON, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, JapanesePunctuationMixedInside) +{ + CHECK_RUNS_MIXED_NORMAL({ { "いろはに", USCRIPT_HIRAGANA, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }, + { ".…¡", USCRIPT_HIRAGANA, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase }, + { "ほへと", USCRIPT_HIRAGANA, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, JapanesePunctuationMixedInsideHorizontal) +{ + CHECK_RUNS_HORIZONTAL_NORMAL({ { "いろはに.…¡ほへと", USCRIPT_HIRAGANA, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }}); +} + +TEST_F(RunSegmenterTest, PunctuationDevanagariCombining) +{ + CHECK_RUNS_HORIZONTAL_NORMAL({ { "क+े", USCRIPT_DEVANAGARI, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }}); +} + +TEST_F(RunSegmenterTest, JapaneseLetterlikeEnd) +{ + CHECK_RUNS_MIXED_NORMAL({ { "いろは", USCRIPT_HIRAGANA, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }, + { "ℐℒℐℒℐℒℐℒℐℒℐℒℐℒ", USCRIPT_HIRAGANA, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase } }); +} + +TEST_F(RunSegmenterTest, JapaneseSmallCaps) +{ + CHECK_RUNS_MIXED_SMALLCAPS({ + { "いろは", USCRIPT_HIRAGANA, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }, + { "aa", USCRIPT_LATIN, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsUppercaseNeeded }, + { "AA", USCRIPT_LATIN, OrientationIterator::OrientationRotateSideways, SmallCapsIterator::SmallCapsSameCase }, + { "いろは", USCRIPT_HIRAGANA, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase }, + }); +} + +TEST_F(RunSegmenterTest, ArmenianCyrillicSmallCaps) +{ + CHECK_RUNS_HORIZONTAL_SMALLCAPS({ { "աբգ", USCRIPT_ARMENIAN, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsUppercaseNeeded }, + { "αβγ", USCRIPT_GREEK, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsUppercaseNeeded }, + { "ԱԲԳ", USCRIPT_ARMENIAN, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase } }); +} + + +} // namespace blink
diff --git a/third_party/WebKit/Source/web/WebKit.cpp b/third_party/WebKit/Source/web/WebKit.cpp index dca9111..1a0ef8b 100644 --- a/third_party/WebKit/Source/web/WebKit.cpp +++ b/third_party/WebKit/Source/web/WebKit.cpp
@@ -265,6 +265,16 @@ return LayoutTestSupport::isFontAntialiasingEnabledForTest(); } +void setAlwaysUseComplexTextForTest(bool value) +{ + LayoutTestSupport::setAlwaysUseComplexTextForTest(value); +} + +bool alwaysUseComplexTextForTest() +{ + return LayoutTestSupport::alwaysUseComplexTextForTest(); +} + void enableLogChannel(const char* name) { #if !LOG_DISABLED
diff --git a/third_party/WebKit/public/web/WebKit.h b/third_party/WebKit/public/web/WebKit.h index 47c4193c..5b9ea84 100644 --- a/third_party/WebKit/public/web/WebKit.h +++ b/third_party/WebKit/public/web/WebKit.h
@@ -78,6 +78,10 @@ BLINK_EXPORT void setFontAntialiasingEnabledForTest(bool); BLINK_EXPORT bool fontAntialiasingEnabledForTest(); +// Forces the use of the complex text path for layout tests. +BLINK_EXPORT void setAlwaysUseComplexTextForTest(bool); +BLINK_EXPORT bool alwaysUseComplexTextForTest(); + // Enables the named log channel. See WebCore/platform/Logging.h for details. BLINK_EXPORT void enableLogChannel(const char*);
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium index 9bd4fde..6ac2c94 100644 --- a/third_party/libjingle/README.chromium +++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@ Name: libjingle URL: http://code.google.com/p/webrtc/ Version: unknown -Revision: 10196 +Revision: 10255 License: BSD License File: source/talk/COPYING Security Critical: yes
diff --git a/third_party/mojo/src/mojo/edk/js/drain_data.cc b/third_party/mojo/src/mojo/edk/js/drain_data.cc index 137b76bf..407c5d2 100644 --- a/third_party/mojo/src/mojo/edk/js/drain_data.cc +++ b/third_party/mojo/src/mojo/edk/js/drain_data.cc
@@ -42,8 +42,11 @@ void DrainData::WaitForData() { wait_id_ = Environment::GetDefaultAsyncWaiter()->AsyncWait( - 2, handle_.get().value(), MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE, &DrainData::WaitCompleted, this); + handle_.get().value(), + MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE, + &DrainData::WaitCompleted, + this); } void DrainData::DataReady(MojoResult result) {
diff --git a/third_party/mojo/src/mojo/edk/js/waiting_callback.cc b/third_party/mojo/src/mojo/edk/js/waiting_callback.cc index 9f58ef5..0746dfb 100644 --- a/third_party/mojo/src/mojo/edk/js/waiting_callback.cc +++ b/third_party/mojo/src/mojo/edk/js/waiting_callback.cc
@@ -31,8 +31,11 @@ gin::Handle<WaitingCallback> waiting_callback = gin::CreateHandle( isolate, new WaitingCallback(isolate, callback, handle_wrapper)); waiting_callback->wait_id_ = Environment::GetDefaultAsyncWaiter()->AsyncWait( - 3, handle_wrapper->get().value(), signals, MOJO_DEADLINE_INDEFINITE, - &WaitingCallback::CallOnHandleReady, waiting_callback.get()); + handle_wrapper->get().value(), + signals, + MOJO_DEADLINE_INDEFINITE, + &WaitingCallback::CallOnHandleReady, + waiting_callback.get()); return waiting_callback; }
diff --git a/third_party/mojo/src/mojo/public/c/environment/async_waiter.h b/third_party/mojo/src/mojo/public/c/environment/async_waiter.h index bbb794be..b5a1f752 100644 --- a/third_party/mojo/src/mojo/public/c/environment/async_waiter.h +++ b/third_party/mojo/src/mojo/public/c/environment/async_waiter.h
@@ -43,11 +43,7 @@ // // Note that once the callback has been called, the returned |MojoAsyncWaitID| // becomes invalid. - // - // TODO(sky): id is for tracking http://crbug.com/534719, will remove once - // fixed. |id| is used to identify the caller. - MojoAsyncWaitID (*AsyncWait)(int id, - MojoHandle handle, + MojoAsyncWaitID (*AsyncWait)(MojoHandle handle, MojoHandleSignals signals, MojoDeadline deadline, MojoAsyncWaitCallback callback,
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/lib/connector.cc b/third_party/mojo/src/mojo/public/cpp/bindings/lib/connector.cc index 7c92ac3c..f9ffdd2 100644 --- a/third_party/mojo/src/mojo/public/cpp/bindings/lib/connector.cc +++ b/third_party/mojo/src/mojo/public/cpp/bindings/lib/connector.cc
@@ -150,9 +150,11 @@ void Connector::WaitToReadMore() { MOJO_CHECK(!async_wait_id_); - async_wait_id_ = waiter_->AsyncWait( - 4, message_pipe_.get().value(), MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE, &Connector::CallOnHandleReady, this); + async_wait_id_ = waiter_->AsyncWait(message_pipe_.get().value(), + MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE, + &Connector::CallOnHandleReady, + this); } bool Connector::ReadSingleMessage(MojoResult* read_result) {
diff --git a/third_party/mojo/src/mojo/public/cpp/environment/lib/async_waiter.cc b/third_party/mojo/src/mojo/public/cpp/environment/lib/async_waiter.cc index f72b01a9..599a649 100644 --- a/third_party/mojo/src/mojo/public/cpp/environment/lib/async_waiter.cc +++ b/third_party/mojo/src/mojo/public/cpp/environment/lib/async_waiter.cc
@@ -12,7 +12,7 @@ : waiter_(Environment::GetDefaultAsyncWaiter()), id_(0), callback_(callback) { - id_ = waiter_->AsyncWait(5, handle.value(), signals, MOJO_DEADLINE_INDEFINITE, + id_ = waiter_->AsyncWait(handle.value(), signals, MOJO_DEADLINE_INDEFINITE, &AsyncWaiter::WaitComplete, this); }
diff --git a/third_party/mojo/src/mojo/public/cpp/environment/lib/default_async_waiter.cc b/third_party/mojo/src/mojo/public/cpp/environment/lib/default_async_waiter.cc index 6a6038f9..4a588a99 100644 --- a/third_party/mojo/src/mojo/public/cpp/environment/lib/default_async_waiter.cc +++ b/third_party/mojo/src/mojo/public/cpp/environment/lib/default_async_waiter.cc
@@ -54,8 +54,7 @@ MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl); }; -MojoAsyncWaitID AsyncWait(int id, - MojoHandle handle, +MojoAsyncWaitID AsyncWait(MojoHandle handle, MojoHandleSignals signals, MojoDeadline deadline, MojoAsyncWaitCallback callback,
diff --git a/third_party/mojo/src/mojo/public/cpp/environment/tests/async_wait_unittest.cc b/third_party/mojo/src/mojo/public/cpp/environment/tests/async_wait_unittest.cc index 63766b88..83c5ca0 100644 --- a/third_party/mojo/src/mojo/public/cpp/environment/tests/async_wait_unittest.cc +++ b/third_party/mojo/src/mojo/public/cpp/environment/tests/async_wait_unittest.cc
@@ -42,8 +42,11 @@ MojoHandleSignals signals, TestAsyncWaitCallback* callback) { return Environment::GetDefaultAsyncWaiter()->AsyncWait( - 0, handle.value(), signals, MOJO_DEADLINE_INDEFINITE, - &TestAsyncWaitCallback::OnHandleReady, callback); + handle.value(), + signals, + MOJO_DEADLINE_INDEFINITE, + &TestAsyncWaitCallback::OnHandleReady, + callback); } void CallCancelWait(MojoAsyncWaitID wait_id) {
diff --git a/third_party/omaha/BUILD.gn b/third_party/omaha/BUILD.gn deleted file mode 100644 index fbed9fa..0000000 --- a/third_party/omaha/BUILD.gn +++ /dev/null
@@ -1,12 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("extractor") { - sources = [ - "src/omaha/base/extractor.cc", - "src/omaha/base/extractor.h", - ] - - include_dirs = [ "src" ] -}
diff --git a/third_party/omaha/LICENSE b/third_party/omaha/LICENSE deleted file mode 100644 index d645695..0000000 --- a/third_party/omaha/LICENSE +++ /dev/null
@@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.
diff --git a/third_party/omaha/OWNERS b/third_party/omaha/OWNERS deleted file mode 100644 index 1ecba6c9b..0000000 --- a/third_party/omaha/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -benwells@chromium.org -jackhou@chromium.org
diff --git a/third_party/omaha/README.chromium b/third_party/omaha/README.chromium deleted file mode 100644 index 88c836b..0000000 --- a/third_party/omaha/README.chromium +++ /dev/null
@@ -1,16 +0,0 @@ -Name: Omaha (Google Update) -Short Name: omaha -URL: https://code.google.com/p/omaha/ -Version: 0 -Date: 2013-09-16 -Revision: r147 -License: Apache 2.0 -License File: LICENSE -Security Critical: yes - -Description: -We use base/extractor from Omaha to extract tags from signed binaries. - -Local Modifications: -Checks for security: -https://chromium.googlesource.com/external/omaha.git.
diff --git a/third_party/omaha/omaha.gyp b/third_party/omaha/omaha.gyp deleted file mode 100644 index de513f7..0000000 --- a/third_party/omaha/omaha.gyp +++ /dev/null
@@ -1,21 +0,0 @@ -# Copyright 2014 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. - -{ - 'targets': [ - { - # GN version: //third_party/omaha:extractor - 'target_name': 'omaha_extractor', - 'type': 'static_library', - 'sources': [ - 'src/omaha/base/extractor.cc', - 'src/omaha/base/extractor.h', - ], - 'include_dirs': [ - '../..', - 'src', - ], - }, - ], -}
diff --git a/tools/licenses.py b/tools/licenses.py index 03c6f52..d8799e53 100755 --- a/tools/licenses.py +++ b/tools/licenses.py
@@ -125,7 +125,7 @@ }, os.path.join('sdch', 'open-vcdiff'): { "Name": "open-vcdiff", - "URL": "https://github.com.com/google/open-vcdiff", + "URL": "https://github.com/google/open-vcdiff", "License": "Apache 2.0, MIT, GPL v2 and custom licenses", "License Android Compatible": "yes", },
diff --git a/tools/perf/benchmarks/page_cycler.py b/tools/perf/benchmarks/page_cycler.py index 645962c1..826a6af 100644 --- a/tools/perf/benchmarks/page_cycler.py +++ b/tools/perf/benchmarks/page_cycler.py
@@ -35,6 +35,18 @@ report_speed_index = options.report_speed_index) +# This is an old page set, we intend to remove it after more modern benchmarks +# work on CrOS. +@benchmark.Enabled('chromeos') +class PageCyclerDhtml(_PageCycler): + """Benchmarks for various DHTML operations like simple animations.""" + page_set = page_sets.DhtmlPageSet + + @classmethod + def Name(cls): + return 'page_cycler.dhtml' + + class PageCyclerIntlArFaHe(_PageCycler): """Page load time for a variety of pages in Arabic, Farsi and Hebrew. @@ -162,7 +174,12 @@ return 'page_cycler.top_10_mobile' def CreateStorySet(self, options): - return page_sets.Top10MobilePageSet(run_no_page_interactions=True) + # Disable the taobao.com page since it's crashing. crbug.com/509690 + stories = page_sets.Top10MobilePageSet(run_no_page_interactions=True) + found = next((x for x in stories if 'taobao.com' in x.url), None) + if found: + stories.RemoveStory(found) + return stories @benchmark.Disabled class PageCyclerKeyMobileSites(_PageCycler):
diff --git a/tools/perf/measurements/page_cycler.js b/tools/perf/measurements/page_cycler.js index 207c70d..46708c6 100644 --- a/tools/perf/measurements/page_cycler.js +++ b/tools/perf/measurements/page_cycler.js
@@ -3,6 +3,22 @@ // found in the LICENSE file. (function() { +// The Mozilla DHTML performance tests need to explicitly call a function to +// trigger the next page visit, rather than directly using the onload handler. +// To meet needs of the DHTML performance tests without forking this head.js +// file, use a variable |__install_onload_handler| to indicate whether the +// |__onload| handler should be added to onload event listener. +// Install |__onload| by default if there is no pre-configuration. +if (typeof(__install_onload_handler) == 'undefined') + var __install_onload_handler = true; + +// This is the timeout used in setTimeout inside the DHTML tests. Chrome has +// a much more accurate timer resolution than other browsers do. This results +// in Chrome running these tests much faster than other browsers. In order to +// compare Chrome with other browsers on DHTML performance alone, set this +// value to ~15. +var __test_timeout = 0; + function __set_cookie(name, value) { document.cookie = name + "=" + value + "; path=/"; } @@ -15,7 +31,24 @@ } } +// The function |__onload| is used by the DHTML tests. +window.__onload = function() { + if (!__install_onload_handler && !performance.timing.loadEventEnd) + return; + + var unused = document.body.offsetHeight; // force layout + + window.__pc_load_time = window.performance.now(); +}; + +// The function |__eval_later| now is only used by the DHTML tests. +window.__eval_later = function(expression) { + setTimeout(expression, __test_timeout); +}; + if (window.parent == window) { // Ignore subframes. + window.__pc_load_time = null; + addEventListener("load", __onload); addEventListener("beforeunload", __onbeforeunload); } -})(); +})(); \ No newline at end of file
diff --git a/tools/perf/measurements/page_cycler.py b/tools/perf/measurements/page_cycler.py index 87f52b8..b9e47ed 100644 --- a/tools/perf/measurements/page_cycler.py +++ b/tools/perf/measurements/page_cycler.py
@@ -104,14 +104,14 @@ keychain_metric.KeychainMetric.CustomizeBrowserOptions(options) def ValidateAndMeasurePage(self, page, tab, results): - tab.WaitForDocumentReadyStateToBeComplete(60) + tab.WaitForJavaScriptExpression('__pc_load_time', 60) chart_name_prefix = ('cold_' if self.IsRunCold(page.url) else 'warm_') results.AddValue(scalar.ScalarValue( results.current_page, '%stimes.page_load_time' % chart_name_prefix, - 'ms', tab.EvaluateJavaScript('window.performance.now()'), + 'ms', tab.EvaluateJavaScript('__pc_load_time'), description='Average page load time. Measured from ' 'performance.timing.navigationStart until the completion ' 'time of a layout after the window.load event. Cold times '
diff --git a/tools/perf/measurements/page_cycler_unittest.py b/tools/perf/measurements/page_cycler_unittest.py index 32c6f04..d2a38d0 100644 --- a/tools/perf/measurements/page_cycler_unittest.py +++ b/tools/perf/measurements/page_cycler_unittest.py
@@ -65,8 +65,6 @@ self.navigated_urls.append(url) def WaitForJavaScriptExpression(self, _, __): pass - def WaitForDocumentReadyStateToBeComplete(self, _): - pass @property def browser(self): return FakeBrowser()
diff --git a/tools/perf/page_sets/data/credentials.json.sha1 b/tools/perf/page_sets/data/credentials.json.sha1 index e6596dd..41077589 100644 --- a/tools/perf/page_sets/data/credentials.json.sha1 +++ b/tools/perf/page_sets/data/credentials.json.sha1
@@ -1 +1 @@ -cfb2dbe089b211a44691e4b719d023d041d88713 \ No newline at end of file +bf4de6267c1908c2a3ac7ec30a12545a46b23e24 \ No newline at end of file
diff --git a/tools/perf/page_sets/page_cycler/dhtml.py b/tools/perf/page_sets/page_cycler/dhtml.py new file mode 100644 index 0000000..e14fdf4 --- /dev/null +++ b/tools/perf/page_sets/page_cycler/dhtml.py
@@ -0,0 +1,45 @@ +# Copyright 2014 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. +from telemetry.page import page as page_module +from telemetry import story + + +class DhtmlPage(page_module.Page): + + def __init__(self, url, page_set): + super(DhtmlPage, self).__init__(url=url, page_set=page_set) + + +class DhtmlPageSet(story.StorySet): + + """ DHTML page_cycler benchmark """ + + def __init__(self): + super(DhtmlPageSet, self).__init__( + # pylint: disable=C0301 + serving_dirs=set(['../../../../data/page_cycler/dhtml']), + cloud_storage_bucket=story.PARTNER_BUCKET) + + urls_list = [ + 'file://../../../../data/page_cycler/dhtml/colorfade/', + 'file://../../../../data/page_cycler/dhtml/diagball/', + 'file://../../../../data/page_cycler/dhtml/fadespacing/', + 'file://../../../../data/page_cycler/dhtml/imageslide/', + 'file://../../../../data/page_cycler/dhtml/layers1/', + 'file://../../../../data/page_cycler/dhtml/layers2/', + 'file://../../../../data/page_cycler/dhtml/layers4/', + 'file://../../../../data/page_cycler/dhtml/layers5/', + 'file://../../../../data/page_cycler/dhtml/layers6/', + 'file://../../../../data/page_cycler/dhtml/meter/', + 'file://../../../../data/page_cycler/dhtml/movingtext/', + 'file://../../../../data/page_cycler/dhtml/mozilla/', + 'file://../../../../data/page_cycler/dhtml/replaceimages/', + 'file://../../../../data/page_cycler/dhtml/scrolling/', + 'file://../../../../data/page_cycler/dhtml/slidein/', + 'file://../../../../data/page_cycler/dhtml/slidingballs/', + 'file://../../../../data/page_cycler/dhtml/zoom/' + ] + + for url in urls_list: + self.AddStory(DhtmlPage(url, self))
diff --git a/tools/telemetry/third_party/pyserial/README.chromium b/tools/telemetry/third_party/pyserial/README.chromium index efa3a74..b8e3bc9 100644 --- a/tools/telemetry/third_party/pyserial/README.chromium +++ b/tools/telemetry/third_party/pyserial/README.chromium
@@ -1,6 +1,6 @@ Name: pySerial Short Name: pySerial -URL: http://pyserial.sourceforge.net/ +URL: https://github.com/pyserial/pyserial Version: 2.7 Date: 2013-10-17 License: Python
diff --git a/ui/message_center/message_center_style.cc b/ui/message_center/message_center_style.cc index 33f8757..3c98bd4 100644 --- a/ui/message_center/message_center_style.cc +++ b/ui/message_center/message_center_style.cc
@@ -55,9 +55,9 @@ const int kAutocloseDefaultDelaySeconds = 8; const int kAutocloseHighPriorityDelaySeconds = 25; // Web notifications use a larger timeout for now, which improves re-engagement. -// TODO(johnme): Use Finch to experiment with different values for this, then -// consider replacing kAutocloseDefaultDelaySeconds with this. -const int kAutocloseWebNotificationDelaySeconds = 20; +// TODO(johnme): Use Finch to experiment with different values, then consider +// replacing kAutocloseDefaultDelaySeconds with this (https://crbug.com/530697). +const int kAutocloseWebPageDelaySeconds = 20; // Colors. const SkColor kBackgroundLightColor = SkColorSetRGB(0xf1, 0xf1, 0xf1);
diff --git a/ui/message_center/message_center_style.h b/ui/message_center/message_center_style.h index 6c1ac96..864c2894 100644 --- a/ui/message_center/message_center_style.h +++ b/ui/message_center/message_center_style.h
@@ -101,7 +101,7 @@ // Timing. extern const int kAutocloseDefaultDelaySeconds; extern const int kAutocloseHighPriorityDelaySeconds; -extern const int kAutocloseWebNotificationDelaySeconds; +extern const int kAutocloseWebPageDelaySeconds; // Buttons. const int kButtonHeight = 38; // In DIPs.
diff --git a/ui/message_center/notification.cc b/ui/message_center/notification.cc index a39f7c7..af35e57 100644 --- a/ui/message_center/notification.cc +++ b/ui/message_center/notification.cc
@@ -26,7 +26,6 @@ RichNotificationData::RichNotificationData() : priority(DEFAULT_PRIORITY), - is_web_notification(false), never_timeout(false), timestamp(base::Time::Now()), context_message(base::string16()), @@ -37,7 +36,6 @@ RichNotificationData::RichNotificationData(const RichNotificationData& other) : priority(other.priority), - is_web_notification(other.is_web_notification), never_timeout(other.never_timeout), timestamp(other.timestamp), context_message(other.context_message), @@ -141,7 +139,6 @@ is_read_ = base->is_read_; if (!delegate_.get()) delegate_ = base->delegate(); - optional_fields_.is_web_notification = base->is_web_notification(); optional_fields_.never_timeout = base->never_timeout(); }
diff --git a/ui/message_center/notification.h b/ui/message_center/notification.h index 41dfa21..f4dce7b 100644 --- a/ui/message_center/notification.h +++ b/ui/message_center/notification.h
@@ -41,7 +41,6 @@ ~RichNotificationData(); int priority; - bool is_web_notification; bool never_timeout; base::Time timestamp; base::string16 context_message; @@ -76,7 +75,7 @@ virtual ~Notification(); // Copies the internal on-memory state from |base|, i.e. shown_as_popup, - // is_read, is_web_notification and never_timeout. + // is_read and never_timeout. void CopyState(Notification* base); NotificationType type() const { return type_; } @@ -194,14 +193,6 @@ // The notification with lesser serial_number is considered 'older'. unsigned serial_number() { return serial_number_; } - // Gets and sets whether this was shown using the Web Notifications API. - bool is_web_notification() const { - return optional_fields_.is_web_notification; - } - void set_is_web_notification(bool is_web_notification) { - optional_fields_.is_web_notification = is_web_notification; - } - // Gets and sets whether the notifiction should remain onscreen permanently. bool never_timeout() const { return optional_fields_.never_timeout; } void set_never_timeout(bool never_timeout) {
diff --git a/ui/message_center/popup_timer.cc b/ui/message_center/popup_timer.cc index f2f9c5e0..dc27866b 100644 --- a/ui/message_center/popup_timer.cc +++ b/ui/message_center/popup_timer.cc
@@ -16,10 +16,10 @@ namespace { base::TimeDelta GetTimeoutForNotification(Notification* notification) { - if (notification->priority() > message_center::DEFAULT_PRIORITY) + if (notification->priority() > DEFAULT_PRIORITY) return base::TimeDelta::FromSeconds(kAutocloseHighPriorityDelaySeconds); - if (notification->is_web_notification()) - return base::TimeDelta::FromSeconds(kAutocloseWebNotificationDelaySeconds); + if (notification->notifier_id().type == NotifierId::WEB_PAGE) + return base::TimeDelta::FromSeconds(kAutocloseWebPageDelaySeconds); return base::TimeDelta::FromSeconds(kAutocloseDefaultDelaySeconds); }