Merge branch 'master' into desktop-capture-api
This commit is contained in:
commit
04f7ceab73
464 changed files with 18563 additions and 4629 deletions
86
chromium_src/chrome/browser/chrome_process_finder_win.cc
Normal file
86
chromium_src/chrome/browser/chrome_process_finder_win.cc
Normal file
|
@ -0,0 +1,86 @@
|
|||
// 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.
|
||||
|
||||
#include "chrome/browser/chrome_process_finder_win.h"
|
||||
|
||||
#include <shellapi.h>
|
||||
#include <string>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/process/process.h"
|
||||
#include "base/process/process_info.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/win/message_window.h"
|
||||
#include "base/win/scoped_handle.h"
|
||||
#include "base/win/win_util.h"
|
||||
#include "base/win/windows_version.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
int timeout_in_milliseconds = 20 * 1000;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chrome {
|
||||
|
||||
HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
|
||||
return base::win::MessageWindow::FindWindow(user_data_dir.value());
|
||||
}
|
||||
|
||||
NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window,
|
||||
bool fast_start) {
|
||||
DCHECK(remote_window);
|
||||
DWORD process_id = 0;
|
||||
DWORD thread_id = GetWindowThreadProcessId(remote_window, &process_id);
|
||||
if (!thread_id || !process_id)
|
||||
return NOTIFY_FAILED;
|
||||
|
||||
// Send the command line to the remote chrome window.
|
||||
// Format is "START\0<<<current directory>>>\0<<<commandline>>>".
|
||||
std::wstring to_send(L"START\0", 6); // want the NULL in the string.
|
||||
base::FilePath cur_dir;
|
||||
if (!base::GetCurrentDirectory(&cur_dir))
|
||||
return NOTIFY_FAILED;
|
||||
to_send.append(cur_dir.value());
|
||||
to_send.append(L"\0", 1); // Null separator.
|
||||
to_send.append(::GetCommandLineW());
|
||||
to_send.append(L"\0", 1); // Null separator.
|
||||
|
||||
// Allow the current running browser window to make itself the foreground
|
||||
// window (otherwise it will just flash in the taskbar).
|
||||
::AllowSetForegroundWindow(process_id);
|
||||
|
||||
COPYDATASTRUCT cds;
|
||||
cds.dwData = 0;
|
||||
cds.cbData = static_cast<DWORD>((to_send.length() + 1) * sizeof(wchar_t));
|
||||
cds.lpData = const_cast<wchar_t*>(to_send.c_str());
|
||||
DWORD_PTR result = 0;
|
||||
if (::SendMessageTimeout(remote_window, WM_COPYDATA, NULL,
|
||||
reinterpret_cast<LPARAM>(&cds), SMTO_ABORTIFHUNG,
|
||||
timeout_in_milliseconds, &result)) {
|
||||
return result ? NOTIFY_SUCCESS : NOTIFY_FAILED;
|
||||
}
|
||||
|
||||
// It is possible that the process owning this window may have died by now.
|
||||
if (!::IsWindow(remote_window))
|
||||
return NOTIFY_FAILED;
|
||||
|
||||
// If the window couldn't be notified but still exists, assume it is hung.
|
||||
return NOTIFY_WINDOW_HUNG;
|
||||
}
|
||||
|
||||
base::TimeDelta SetNotificationTimeoutForTesting(base::TimeDelta new_timeout) {
|
||||
base::TimeDelta old_timeout =
|
||||
base::TimeDelta::FromMilliseconds(timeout_in_milliseconds);
|
||||
timeout_in_milliseconds = new_timeout.InMilliseconds();
|
||||
return old_timeout;
|
||||
}
|
||||
|
||||
} // namespace chrome
|
39
chromium_src/chrome/browser/chrome_process_finder_win.h
Normal file
39
chromium_src/chrome/browser/chrome_process_finder_win.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
// 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.
|
||||
|
||||
#ifndef CHROME_BROWSER_CHROME_PROCESS_FINDER_WIN_H_
|
||||
#define CHROME_BROWSER_CHROME_PROCESS_FINDER_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/time/time.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace chrome {
|
||||
|
||||
enum NotifyChromeResult {
|
||||
NOTIFY_SUCCESS,
|
||||
NOTIFY_FAILED,
|
||||
NOTIFY_WINDOW_HUNG,
|
||||
};
|
||||
|
||||
// Finds an already running Chrome window if it exists.
|
||||
HWND FindRunningChromeWindow(const base::FilePath& user_data_dir);
|
||||
|
||||
// Attempts to send the current command line to an already running instance of
|
||||
// Chrome via a WM_COPYDATA message.
|
||||
// Returns true if a running Chrome is found and successfully notified.
|
||||
// |fast_start| is true when this is being called on the window fast start path.
|
||||
NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window,
|
||||
bool fast_start);
|
||||
|
||||
// Changes the notification timeout to |new_timeout|, returns the old timeout.
|
||||
base::TimeDelta SetNotificationTimeoutForTesting(base::TimeDelta new_timeout);
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_BROWSER_CHROME_PROCESS_FINDER_WIN_H_
|
|
@ -410,7 +410,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
|||
// be CPU bound, the page overly complex/large or the system just
|
||||
// memory-bound.
|
||||
static const int kPrinterSettingsTimeout = 60000;
|
||||
base::OneShotTimer<base::MessageLoop> quit_timer;
|
||||
base::OneShotTimer quit_timer;
|
||||
quit_timer.Start(FROM_HERE,
|
||||
TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
|
||||
base::MessageLoop::current(), &base::MessageLoop::Quit);
|
||||
|
|
182
chromium_src/chrome/browser/process_singleton.h
Normal file
182
chromium_src/chrome/browser/process_singleton.h
Normal file
|
@ -0,0 +1,182 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_BROWSER_PROCESS_SINGLETON_H_
|
||||
#define CHROME_BROWSER_PROCESS_SINGLETON_H_
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/process/process.h"
|
||||
#include "base/threading/non_thread_safe.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
|
||||
#if defined(OS_POSIX) && !defined(OS_ANDROID)
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/message_window.h"
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
namespace base {
|
||||
class CommandLine;
|
||||
}
|
||||
|
||||
// ProcessSingleton ----------------------------------------------------------
|
||||
//
|
||||
// This class allows different browser processes to communicate with
|
||||
// each other. It is named according to the user data directory, so
|
||||
// we can be sure that no more than one copy of the application can be
|
||||
// running at once with a given data directory.
|
||||
//
|
||||
// Implementation notes:
|
||||
// - the Windows implementation uses an invisible global message window;
|
||||
// - the Linux implementation uses a Unix domain socket in the user data dir.
|
||||
|
||||
class ProcessSingleton : public base::NonThreadSafe {
|
||||
public:
|
||||
enum NotifyResult {
|
||||
PROCESS_NONE,
|
||||
PROCESS_NOTIFIED,
|
||||
PROFILE_IN_USE,
|
||||
LOCK_ERROR,
|
||||
};
|
||||
|
||||
// Implement this callback to handle notifications from other processes. The
|
||||
// callback will receive the command line and directory with which the other
|
||||
// Chrome process was launched. Return true if the command line will be
|
||||
// handled within the current browser instance or false if the remote process
|
||||
// should handle it (i.e., because the current process is shutting down).
|
||||
using NotificationCallback =
|
||||
base::Callback<bool(const base::CommandLine::StringVector& command_line,
|
||||
const base::FilePath& current_directory)>;
|
||||
|
||||
ProcessSingleton(const base::FilePath& user_data_dir,
|
||||
const NotificationCallback& notification_callback);
|
||||
~ProcessSingleton();
|
||||
|
||||
// Notify another process, if available. Otherwise sets ourselves as the
|
||||
// singleton instance. Returns PROCESS_NONE if we became the singleton
|
||||
// instance. Callers are guaranteed to either have notified an existing
|
||||
// process or have grabbed the singleton (unless the profile is locked by an
|
||||
// unreachable process).
|
||||
// TODO(brettw): Make the implementation of this method non-platform-specific
|
||||
// by making Linux re-use the Windows implementation.
|
||||
NotifyResult NotifyOtherProcessOrCreate();
|
||||
|
||||
// Sets ourself up as the singleton instance. Returns true on success. If
|
||||
// false is returned, we are not the singleton instance and the caller must
|
||||
// exit.
|
||||
// NOTE: Most callers should generally prefer NotifyOtherProcessOrCreate() to
|
||||
// this method, only callers for whom failure is preferred to notifying
|
||||
// another process should call this directly.
|
||||
bool Create();
|
||||
|
||||
// Clear any lock state during shutdown.
|
||||
void Cleanup();
|
||||
|
||||
#if defined(OS_POSIX) && !defined(OS_ANDROID)
|
||||
static void DisablePromptForTesting();
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
// Called to query whether to kill a hung browser process that has visible
|
||||
// windows. Return true to allow killing the hung process.
|
||||
using ShouldKillRemoteProcessCallback = base::Callback<bool()>;
|
||||
void OverrideShouldKillRemoteProcessCallbackForTesting(
|
||||
const ShouldKillRemoteProcessCallback& display_dialog_callback);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// Notify another process, if available.
|
||||
// Returns true if another process was found and notified, false if we should
|
||||
// continue with the current process.
|
||||
// On Windows, Create() has to be called before this.
|
||||
NotifyResult NotifyOtherProcess();
|
||||
|
||||
#if defined(OS_POSIX) && !defined(OS_ANDROID)
|
||||
// Exposed for testing. We use a timeout on Linux, and in tests we want
|
||||
// this timeout to be short.
|
||||
NotifyResult NotifyOtherProcessWithTimeout(
|
||||
const base::CommandLine& command_line,
|
||||
int retry_attempts,
|
||||
const base::TimeDelta& timeout,
|
||||
bool kill_unresponsive);
|
||||
NotifyResult NotifyOtherProcessWithTimeoutOrCreate(
|
||||
const base::CommandLine& command_line,
|
||||
int retry_attempts,
|
||||
const base::TimeDelta& timeout);
|
||||
void OverrideCurrentPidForTesting(base::ProcessId pid);
|
||||
void OverrideKillCallbackForTesting(
|
||||
const base::Callback<void(int)>& callback);
|
||||
#endif
|
||||
|
||||
private:
|
||||
NotificationCallback notification_callback_; // Handler for notifications.
|
||||
|
||||
#if defined(OS_WIN)
|
||||
HWND remote_window_; // The HWND_MESSAGE of another browser.
|
||||
base::win::MessageWindow window_; // The message-only window.
|
||||
bool is_virtualized_; // Stuck inside Microsoft Softricity VM environment.
|
||||
HANDLE lock_file_;
|
||||
base::FilePath user_data_dir_;
|
||||
ShouldKillRemoteProcessCallback should_kill_remote_process_callback_;
|
||||
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
|
||||
// Start listening to the socket.
|
||||
void StartListening(int sock);
|
||||
|
||||
// Return true if the given pid is one of our child processes.
|
||||
// Assumes that the current pid is the root of all pids of the current
|
||||
// instance.
|
||||
bool IsSameChromeInstance(pid_t pid);
|
||||
|
||||
// Extract the process's pid from a symbol link path and if it is on
|
||||
// the same host, kill the process, unlink the lock file and return true.
|
||||
// If the process is part of the same chrome instance, unlink the lock file
|
||||
// and return true without killing it.
|
||||
// If the process is on a different host, return false.
|
||||
bool KillProcessByLockPath();
|
||||
|
||||
// Default function to kill a process, overridable by tests.
|
||||
void KillProcess(int pid);
|
||||
|
||||
// Allow overriding for tests.
|
||||
base::ProcessId current_pid_;
|
||||
|
||||
// Function to call when the other process is hung and needs to be killed.
|
||||
// Allows overriding for tests.
|
||||
base::Callback<void(int)> kill_callback_;
|
||||
|
||||
// Path in file system to the socket.
|
||||
base::FilePath socket_path_;
|
||||
|
||||
// Path in file system to the lock.
|
||||
base::FilePath lock_path_;
|
||||
|
||||
// Path in file system to the cookie file.
|
||||
base::FilePath cookie_path_;
|
||||
|
||||
// Temporary directory to hold the socket.
|
||||
base::ScopedTempDir socket_dir_;
|
||||
|
||||
// Helper class for linux specific messages. LinuxWatcher is ref counted
|
||||
// because it posts messages between threads.
|
||||
class LinuxWatcher;
|
||||
scoped_refptr<LinuxWatcher> watcher_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ProcessSingleton);
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_PROCESS_SINGLETON_H_
|
1061
chromium_src/chrome/browser/process_singleton_posix.cc
Normal file
1061
chromium_src/chrome/browser/process_singleton_posix.cc
Normal file
File diff suppressed because it is too large
Load diff
328
chromium_src/chrome/browser/process_singleton_win.cc
Normal file
328
chromium_src/chrome/browser/process_singleton_win.cc
Normal file
|
@ -0,0 +1,328 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/browser/process_singleton.h"
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "base/base_paths.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/process/process.h"
|
||||
#include "base/process/process_info.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/win/metro.h"
|
||||
#include "base/win/registry.h"
|
||||
#include "base/win/scoped_handle.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "chrome/browser/chrome_process_finder_win.h"
|
||||
#include "content/public/common/result_codes.h"
|
||||
#include "net/base/escape.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/gfx/win/hwnd_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const char kLockfile[] = "lockfile";
|
||||
|
||||
// A helper class that acquires the given |mutex| while the AutoLockMutex is in
|
||||
// scope.
|
||||
class AutoLockMutex {
|
||||
public:
|
||||
explicit AutoLockMutex(HANDLE mutex) : mutex_(mutex) {
|
||||
DWORD result = ::WaitForSingleObject(mutex_, INFINITE);
|
||||
DPCHECK(result == WAIT_OBJECT_0) << "Result = " << result;
|
||||
}
|
||||
|
||||
~AutoLockMutex() {
|
||||
BOOL released = ::ReleaseMutex(mutex_);
|
||||
DPCHECK(released);
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE mutex_;
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoLockMutex);
|
||||
};
|
||||
|
||||
// A helper class that releases the given |mutex| while the AutoUnlockMutex is
|
||||
// in scope and immediately re-acquires it when going out of scope.
|
||||
class AutoUnlockMutex {
|
||||
public:
|
||||
explicit AutoUnlockMutex(HANDLE mutex) : mutex_(mutex) {
|
||||
BOOL released = ::ReleaseMutex(mutex_);
|
||||
DPCHECK(released);
|
||||
}
|
||||
|
||||
~AutoUnlockMutex() {
|
||||
DWORD result = ::WaitForSingleObject(mutex_, INFINITE);
|
||||
DPCHECK(result == WAIT_OBJECT_0) << "Result = " << result;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE mutex_;
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUnlockMutex);
|
||||
};
|
||||
|
||||
// Checks the visibility of the enumerated window and signals once a visible
|
||||
// window has been found.
|
||||
BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
|
||||
bool* result = reinterpret_cast<bool*>(param);
|
||||
*result = ::IsWindowVisible(window) != 0;
|
||||
// Stops enumeration if a visible window has been found.
|
||||
return !*result;
|
||||
}
|
||||
|
||||
// Convert Command line string to argv.
|
||||
base::CommandLine::StringVector CommandLineStringToArgv(
|
||||
const std::wstring& command_line_string) {
|
||||
int num_args = 0;
|
||||
wchar_t** args = NULL;
|
||||
args = ::CommandLineToArgvW(command_line_string.c_str(), &num_args);
|
||||
base::CommandLine::StringVector argv;
|
||||
for (int i = 0; i < num_args; ++i)
|
||||
argv.push_back(std::wstring(args[i]));
|
||||
LocalFree(args);
|
||||
return argv;
|
||||
}
|
||||
|
||||
bool ParseCommandLine(const COPYDATASTRUCT* cds,
|
||||
base::CommandLine::StringVector* parsed_command_line,
|
||||
base::FilePath* current_directory) {
|
||||
// We should have enough room for the shortest command (min_message_size)
|
||||
// and also be a multiple of wchar_t bytes. The shortest command
|
||||
// possible is L"START\0\0" (empty current directory and command line).
|
||||
static const int min_message_size = 7;
|
||||
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
|
||||
cds->cbData % sizeof(wchar_t) != 0) {
|
||||
LOG(WARNING) << "Invalid WM_COPYDATA, length = " << cds->cbData;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We split the string into 4 parts on NULLs.
|
||||
DCHECK(cds->lpData);
|
||||
const std::wstring msg(static_cast<wchar_t*>(cds->lpData),
|
||||
cds->cbData / sizeof(wchar_t));
|
||||
const std::wstring::size_type first_null = msg.find_first_of(L'\0');
|
||||
if (first_null == 0 || first_null == std::wstring::npos) {
|
||||
// no NULL byte, don't know what to do
|
||||
LOG(WARNING) << "Invalid WM_COPYDATA, length = " << msg.length() <<
|
||||
", first null = " << first_null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decode the command, which is everything until the first NULL.
|
||||
if (msg.substr(0, first_null) == L"START") {
|
||||
// Another instance is starting parse the command line & do what it would
|
||||
// have done.
|
||||
VLOG(1) << "Handling STARTUP request from another process";
|
||||
const std::wstring::size_type second_null =
|
||||
msg.find_first_of(L'\0', first_null + 1);
|
||||
if (second_null == std::wstring::npos ||
|
||||
first_null == msg.length() - 1 || second_null == msg.length()) {
|
||||
LOG(WARNING) << "Invalid format for start command, we need a string in 4 "
|
||||
"parts separated by NULLs";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get current directory.
|
||||
*current_directory = base::FilePath(msg.substr(first_null + 1,
|
||||
second_null - first_null));
|
||||
|
||||
const std::wstring::size_type third_null =
|
||||
msg.find_first_of(L'\0', second_null + 1);
|
||||
if (third_null == std::wstring::npos ||
|
||||
third_null == msg.length()) {
|
||||
LOG(WARNING) << "Invalid format for start command, we need a string in 4 "
|
||||
"parts separated by NULLs";
|
||||
}
|
||||
|
||||
// Get command line.
|
||||
const std::wstring cmd_line =
|
||||
msg.substr(second_null + 1, third_null - second_null);
|
||||
*parsed_command_line = CommandLineStringToArgv(cmd_line);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProcessLaunchNotification(
|
||||
const ProcessSingleton::NotificationCallback& notification_callback,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam,
|
||||
LRESULT* result) {
|
||||
if (message != WM_COPYDATA)
|
||||
return false;
|
||||
|
||||
// Handle the WM_COPYDATA message from another process.
|
||||
const COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT*>(lparam);
|
||||
|
||||
base::CommandLine::StringVector parsed_command_line;
|
||||
base::FilePath current_directory;
|
||||
if (!ParseCommandLine(cds, &parsed_command_line, ¤t_directory)) {
|
||||
*result = TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
*result = notification_callback.Run(parsed_command_line, current_directory) ?
|
||||
TRUE : FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TerminateAppWithError() {
|
||||
// TODO: This is called when the secondary process can't ping the primary
|
||||
// process. Need to find out what to do here.
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ProcessSingleton::ProcessSingleton(
|
||||
const base::FilePath& user_data_dir,
|
||||
const NotificationCallback& notification_callback)
|
||||
: notification_callback_(notification_callback),
|
||||
is_virtualized_(false),
|
||||
lock_file_(INVALID_HANDLE_VALUE),
|
||||
user_data_dir_(user_data_dir),
|
||||
should_kill_remote_process_callback_(
|
||||
base::Bind(&TerminateAppWithError)) {
|
||||
}
|
||||
|
||||
ProcessSingleton::~ProcessSingleton() {
|
||||
if (lock_file_ != INVALID_HANDLE_VALUE)
|
||||
::CloseHandle(lock_file_);
|
||||
}
|
||||
|
||||
// Code roughly based on Mozilla.
|
||||
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
|
||||
if (is_virtualized_)
|
||||
return PROCESS_NOTIFIED; // We already spawned the process in this case.
|
||||
if (lock_file_ == INVALID_HANDLE_VALUE && !remote_window_) {
|
||||
return LOCK_ERROR;
|
||||
} else if (!remote_window_) {
|
||||
return PROCESS_NONE;
|
||||
}
|
||||
|
||||
switch (chrome::AttemptToNotifyRunningChrome(remote_window_, false)) {
|
||||
case chrome::NOTIFY_SUCCESS:
|
||||
return PROCESS_NOTIFIED;
|
||||
case chrome::NOTIFY_FAILED:
|
||||
remote_window_ = NULL;
|
||||
return PROCESS_NONE;
|
||||
case chrome::NOTIFY_WINDOW_HUNG:
|
||||
// Fall through and potentially terminate the hung browser.
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD process_id = 0;
|
||||
DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id);
|
||||
if (!thread_id || !process_id) {
|
||||
remote_window_ = NULL;
|
||||
return PROCESS_NONE;
|
||||
}
|
||||
base::Process process = base::Process::Open(process_id);
|
||||
|
||||
// The window is hung. Scan for every window to find a visible one.
|
||||
bool visible_window = false;
|
||||
::EnumThreadWindows(thread_id,
|
||||
&BrowserWindowEnumeration,
|
||||
reinterpret_cast<LPARAM>(&visible_window));
|
||||
|
||||
// If there is a visible browser window, ask the user before killing it.
|
||||
if (visible_window && !should_kill_remote_process_callback_.Run()) {
|
||||
// The user denied. Quit silently.
|
||||
return PROCESS_NOTIFIED;
|
||||
}
|
||||
|
||||
// Time to take action. Kill the browser process.
|
||||
process.Terminate(content::RESULT_CODE_HUNG, true);
|
||||
remote_window_ = NULL;
|
||||
return PROCESS_NONE;
|
||||
}
|
||||
|
||||
ProcessSingleton::NotifyResult
|
||||
ProcessSingleton::NotifyOtherProcessOrCreate() {
|
||||
ProcessSingleton::NotifyResult result = PROCESS_NONE;
|
||||
if (!Create()) {
|
||||
result = NotifyOtherProcess();
|
||||
if (result == PROCESS_NONE)
|
||||
result = PROFILE_IN_USE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Look for a Chrome instance that uses the same profile directory. If there
|
||||
// isn't one, create a message window with its title set to the profile
|
||||
// directory path.
|
||||
bool ProcessSingleton::Create() {
|
||||
static const wchar_t kMutexName[] = L"Local\\AtomProcessSingletonStartup!";
|
||||
|
||||
remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_);
|
||||
if (!remote_window_) {
|
||||
// Make sure we will be the one and only process creating the window.
|
||||
// We use a named Mutex since we are protecting against multi-process
|
||||
// access. As documented, it's clearer to NOT request ownership on creation
|
||||
// since it isn't guaranteed we will get it. It is better to create it
|
||||
// without ownership and explicitly get the ownership afterward.
|
||||
base::win::ScopedHandle only_me(::CreateMutex(NULL, FALSE, kMutexName));
|
||||
if (!only_me.IsValid()) {
|
||||
DPLOG(FATAL) << "CreateMutex failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoLockMutex auto_lock_only_me(only_me.Get());
|
||||
|
||||
// We now own the mutex so we are the only process that can create the
|
||||
// window at this time, but we must still check if someone created it
|
||||
// between the time where we looked for it above and the time the mutex
|
||||
// was given to us.
|
||||
remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_);
|
||||
if (!remote_window_) {
|
||||
// We have to make sure there is no Chrome instance running on another
|
||||
// machine that uses the same profile.
|
||||
base::FilePath lock_file_path = user_data_dir_.AppendASCII(kLockfile);
|
||||
lock_file_ = ::CreateFile(lock_file_path.value().c_str(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL |
|
||||
FILE_FLAG_DELETE_ON_CLOSE,
|
||||
NULL);
|
||||
DWORD error = ::GetLastError();
|
||||
LOG_IF(WARNING, lock_file_ != INVALID_HANDLE_VALUE &&
|
||||
error == ERROR_ALREADY_EXISTS) << "Lock file exists but is writable.";
|
||||
LOG_IF(ERROR, lock_file_ == INVALID_HANDLE_VALUE)
|
||||
<< "Lock file can not be created! Error code: " << error;
|
||||
|
||||
if (lock_file_ != INVALID_HANDLE_VALUE) {
|
||||
// Set the window's title to the path of our user data directory so
|
||||
// other Chrome instances can decide if they should forward to us.
|
||||
bool result = window_.CreateNamed(
|
||||
base::Bind(&ProcessLaunchNotification, notification_callback_),
|
||||
user_data_dir_.value());
|
||||
|
||||
// NB: Ensure that if the primary app gets started as elevated
|
||||
// admin inadvertently, secondary windows running not as elevated
|
||||
// will still be able to send messages
|
||||
::ChangeWindowMessageFilterEx(window_.hwnd(), WM_COPYDATA, MSGFLT_ALLOW, NULL);
|
||||
CHECK(result && window_.hwnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return window_.hwnd() != NULL;
|
||||
}
|
||||
|
||||
void ProcessSingleton::Cleanup() {
|
||||
}
|
||||
|
||||
void ProcessSingleton::OverrideShouldKillRemoteProcessCallbackForTesting(
|
||||
const ShouldKillRemoteProcessCallback& display_dialog_callback) {
|
||||
should_kill_remote_process_callback_ = display_dialog_callback;
|
||||
}
|
|
@ -111,7 +111,7 @@ TtsController* TtsController::GetInstance() {
|
|||
|
||||
// static
|
||||
TtsControllerImpl* TtsControllerImpl::GetInstance() {
|
||||
return Singleton<TtsControllerImpl>::get();
|
||||
return base::Singleton<TtsControllerImpl>::get();
|
||||
}
|
||||
|
||||
TtsControllerImpl::TtsControllerImpl()
|
||||
|
|
|
@ -77,7 +77,7 @@ class TtsControllerImpl : public TtsController {
|
|||
int GetMatchingVoice(const Utterance* utterance,
|
||||
std::vector<VoiceData>& voices);
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsControllerImpl>;
|
||||
friend struct base::DefaultSingletonTraits<TtsControllerImpl>;
|
||||
|
||||
// The current utterance being spoken.
|
||||
Utterance* current_utterance_;
|
||||
|
@ -101,4 +101,4 @@ class TtsControllerImpl : public TtsController {
|
|||
DISALLOW_COPY_AND_ASSIGN(TtsControllerImpl);
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_SPEECH_TTS_CONTROLLER_IMPL_H_
|
||||
#endif // CHROME_BROWSER_SPEECH_TTS_CONTROLLER_IMPL_H_
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "base/synchronization/lock.h"
|
||||
#include "chrome/browser/speech/tts_platform.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
|
||||
#include "library_loaders/libspeechd.h"
|
||||
|
||||
|
@ -32,18 +33,17 @@ struct SPDChromeVoice {
|
|||
|
||||
class TtsPlatformImplLinux : public TtsPlatformImpl {
|
||||
public:
|
||||
virtual bool PlatformImplAvailable() override;
|
||||
virtual bool Speak(
|
||||
int utterance_id,
|
||||
const std::string& utterance,
|
||||
const std::string& lang,
|
||||
const VoiceData& voice,
|
||||
const UtteranceContinuousParameters& params) override;
|
||||
virtual bool StopSpeaking() override;
|
||||
virtual void Pause() override;
|
||||
virtual void Resume() override;
|
||||
virtual bool IsSpeaking() override;
|
||||
virtual void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
bool PlatformImplAvailable() override;
|
||||
bool Speak(int utterance_id,
|
||||
const std::string& utterance,
|
||||
const std::string& lang,
|
||||
const VoiceData& voice,
|
||||
const UtteranceContinuousParameters& params) override;
|
||||
bool StopSpeaking() override;
|
||||
void Pause() override;
|
||||
void Resume() override;
|
||||
bool IsSpeaking() override;
|
||||
void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
|
||||
void OnSpeechEvent(SPDNotificationType type);
|
||||
|
||||
|
@ -52,7 +52,7 @@ class TtsPlatformImplLinux : public TtsPlatformImpl {
|
|||
|
||||
private:
|
||||
TtsPlatformImplLinux();
|
||||
virtual ~TtsPlatformImplLinux();
|
||||
~TtsPlatformImplLinux() override;
|
||||
|
||||
// Initiate the connection with the speech dispatcher.
|
||||
void Initialize();
|
||||
|
@ -83,7 +83,7 @@ class TtsPlatformImplLinux : public TtsPlatformImpl {
|
|||
// uniquely identify a voice across all available modules.
|
||||
scoped_ptr<std::map<std::string, SPDChromeVoice> > all_native_voices_;
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsPlatformImplLinux>;
|
||||
friend struct base::DefaultSingletonTraits<TtsPlatformImplLinux>;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplLinux);
|
||||
};
|
||||
|
@ -94,6 +94,11 @@ SPDNotificationType TtsPlatformImplLinux::current_notification_ =
|
|||
|
||||
TtsPlatformImplLinux::TtsPlatformImplLinux()
|
||||
: utterance_id_(0) {
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
if (!command_line.HasSwitch(switches::kEnableSpeechDispatcher))
|
||||
return;
|
||||
|
||||
BrowserThread::PostTask(BrowserThread::FILE,
|
||||
FROM_HERE,
|
||||
base::Bind(&TtsPlatformImplLinux::Initialize,
|
||||
|
@ -111,7 +116,7 @@ void TtsPlatformImplLinux::Initialize() {
|
|||
// http://crbug.com/317360
|
||||
ANNOTATE_SCOPED_MEMORY_LEAK;
|
||||
conn_ = libspeechd_loader_.spd_open(
|
||||
"chrome", "extension_api", NULL, SPD_MODE_SINGLE);
|
||||
"chrome", "extension_api", NULL, SPD_MODE_THREADED);
|
||||
}
|
||||
if (!conn_)
|
||||
return;
|
||||
|
@ -146,7 +151,7 @@ void TtsPlatformImplLinux::Reset() {
|
|||
if (conn_)
|
||||
libspeechd_loader_.spd_close(conn_);
|
||||
conn_ = libspeechd_loader_.spd_open(
|
||||
"chrome", "extension_api", NULL, SPD_MODE_SINGLE);
|
||||
"chrome", "extension_api", NULL, SPD_MODE_THREADED);
|
||||
}
|
||||
|
||||
bool TtsPlatformImplLinux::PlatformImplAvailable() {
|
||||
|
@ -187,6 +192,10 @@ bool TtsPlatformImplLinux::Speak(
|
|||
libspeechd_loader_.spd_set_voice_rate(conn_, 100 * log10(rate) / log10(3));
|
||||
libspeechd_loader_.spd_set_voice_pitch(conn_, 100 * log10(pitch) / log10(3));
|
||||
|
||||
// Support languages other than the default
|
||||
if (!lang.empty())
|
||||
libspeechd_loader_.spd_set_language(conn_, lang.c_str());
|
||||
|
||||
utterance_ = utterance;
|
||||
utterance_id_ = utterance_id;
|
||||
|
||||
|
@ -337,8 +346,9 @@ void TtsPlatformImplLinux::IndexMarkCallback(size_t msg_id,
|
|||
|
||||
// static
|
||||
TtsPlatformImplLinux* TtsPlatformImplLinux::GetInstance() {
|
||||
return Singleton<TtsPlatformImplLinux,
|
||||
LeakySingletonTraits<TtsPlatformImplLinux> >::get();
|
||||
return base::Singleton<
|
||||
TtsPlatformImplLinux,
|
||||
base::LeakySingletonTraits<TtsPlatformImplLinux>>::get();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -91,7 +91,7 @@ class TtsPlatformImplMac : public TtsPlatformImpl {
|
|||
int last_char_index_;
|
||||
bool paused_;
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsPlatformImplMac>;
|
||||
friend struct base::DefaultSingletonTraits<TtsPlatformImplMac>;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplMac);
|
||||
};
|
||||
|
@ -291,7 +291,7 @@ TtsPlatformImplMac::~TtsPlatformImplMac() {
|
|||
|
||||
// static
|
||||
TtsPlatformImplMac* TtsPlatformImplMac::GetInstance() {
|
||||
return Singleton<TtsPlatformImplMac>::get();
|
||||
return base::Singleton<TtsPlatformImplMac>::get();
|
||||
}
|
||||
|
||||
@implementation ChromeTtsDelegate
|
||||
|
|
|
@ -15,26 +15,26 @@
|
|||
|
||||
class TtsPlatformImplWin : public TtsPlatformImpl {
|
||||
public:
|
||||
virtual bool PlatformImplAvailable() {
|
||||
bool PlatformImplAvailable() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool Speak(
|
||||
bool Speak(
|
||||
int utterance_id,
|
||||
const std::string& utterance,
|
||||
const std::string& lang,
|
||||
const VoiceData& voice,
|
||||
const UtteranceContinuousParameters& params);
|
||||
const UtteranceContinuousParameters& params) override;
|
||||
|
||||
virtual bool StopSpeaking();
|
||||
bool StopSpeaking() override;
|
||||
|
||||
virtual void Pause();
|
||||
void Pause() override;
|
||||
|
||||
virtual void Resume();
|
||||
void Resume() override;
|
||||
|
||||
virtual bool IsSpeaking();
|
||||
bool IsSpeaking() override;
|
||||
|
||||
virtual void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
void GetVoices(std::vector<VoiceData>* out_voices) override;
|
||||
|
||||
// Get the single instance of this class.
|
||||
static TtsPlatformImplWin* GetInstance();
|
||||
|
@ -43,7 +43,7 @@ class TtsPlatformImplWin : public TtsPlatformImpl {
|
|||
|
||||
private:
|
||||
TtsPlatformImplWin();
|
||||
virtual ~TtsPlatformImplWin() {}
|
||||
~TtsPlatformImplWin() override {}
|
||||
|
||||
void OnSpeechEvent();
|
||||
|
||||
|
@ -57,7 +57,7 @@ class TtsPlatformImplWin : public TtsPlatformImpl {
|
|||
int char_position_;
|
||||
bool paused_;
|
||||
|
||||
friend struct DefaultSingletonTraits<TtsPlatformImplWin>;
|
||||
friend struct base::DefaultSingletonTraits<TtsPlatformImplWin>;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin);
|
||||
};
|
||||
|
@ -220,6 +220,8 @@ void TtsPlatformImplWin::OnSpeechEvent() {
|
|||
utterance_id_, TTS_EVENT_SENTENCE, char_position_,
|
||||
std::string());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,12 +248,12 @@ TtsPlatformImplWin::TtsPlatformImplWin()
|
|||
|
||||
// static
|
||||
TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() {
|
||||
return Singleton<TtsPlatformImplWin,
|
||||
LeakySingletonTraits<TtsPlatformImplWin> >::get();
|
||||
return base::Singleton<TtsPlatformImplWin,
|
||||
base::LeakySingletonTraits<TtsPlatformImplWin>>::get();
|
||||
}
|
||||
|
||||
// static
|
||||
void TtsPlatformImplWin::SpeechEventCallback(
|
||||
WPARAM w_param, LPARAM l_param) {
|
||||
GetInstance()->OnSpeechEvent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ const char kAppMenuRegistrarPath[] = "/com/canonical/AppMenu/Registrar";
|
|||
|
||||
// static
|
||||
GlobalMenuBarRegistrarX11* GlobalMenuBarRegistrarX11::GetInstance() {
|
||||
return Singleton<GlobalMenuBarRegistrarX11>::get();
|
||||
return base::Singleton<GlobalMenuBarRegistrarX11>::get();
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::OnWindowMapped(unsigned long xid) {
|
||||
|
@ -39,7 +39,7 @@ void GlobalMenuBarRegistrarX11::OnWindowUnmapped(unsigned long xid) {
|
|||
}
|
||||
|
||||
GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11()
|
||||
: registrar_proxy_(NULL) {
|
||||
: registrar_proxy_(nullptr) {
|
||||
// libdbusmenu uses the gio version of dbus; I tried using the code in dbus/,
|
||||
// but it looks like that's isn't sharing the bus name with the gio version,
|
||||
// even when |connection_type| is set to SHARED.
|
||||
|
@ -49,11 +49,11 @@ GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11()
|
|||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
|
||||
NULL,
|
||||
nullptr,
|
||||
kAppMenuRegistrarName,
|
||||
kAppMenuRegistrarPath,
|
||||
kAppMenuRegistrarName,
|
||||
NULL, // TODO: Probalby want a real cancelable.
|
||||
nullptr, // TODO: Probalby want a real cancelable.
|
||||
static_cast<GAsyncReadyCallback>(OnProxyCreatedThunk),
|
||||
this);
|
||||
}
|
||||
|
@ -84,9 +84,9 @@ void GlobalMenuBarRegistrarX11::RegisterXID(unsigned long xid) {
|
|||
"RegisterWindow",
|
||||
g_variant_new("(uo)", xid, path.c_str()),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) {
|
||||
|
@ -105,14 +105,14 @@ void GlobalMenuBarRegistrarX11::UnregisterXID(unsigned long xid) {
|
|||
"UnregisterWindow",
|
||||
g_variant_new("(u)", xid),
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source,
|
||||
GAsyncResult* result) {
|
||||
GError* error = NULL;
|
||||
GError* error = nullptr;
|
||||
GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
|
||||
if (error) {
|
||||
g_error_free(error);
|
||||
|
@ -128,7 +128,7 @@ void GlobalMenuBarRegistrarX11::OnProxyCreated(GObject* source,
|
|||
g_signal_connect(registrar_proxy_, "notify::g-name-owner",
|
||||
G_CALLBACK(OnNameOwnerChangedThunk), this);
|
||||
|
||||
OnNameOwnerChanged(NULL, NULL);
|
||||
OnNameOwnerChanged(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */,
|
||||
|
|
|
@ -28,7 +28,7 @@ class GlobalMenuBarRegistrarX11 {
|
|||
void OnWindowUnmapped(unsigned long xid);
|
||||
|
||||
private:
|
||||
friend struct DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
|
||||
friend struct base::DefaultSingletonTraits<GlobalMenuBarRegistrarX11>;
|
||||
|
||||
GlobalMenuBarRegistrarX11();
|
||||
~GlobalMenuBarRegistrarX11();
|
||||
|
|
74
chromium_src/chrome/common/chrome_constants.cc
Normal file
74
chromium_src/chrome/common/chrome_constants.cc
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
|
||||
#define FPL FILE_PATH_LITERAL
|
||||
|
||||
namespace chrome {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
const base::FilePath::CharType kFrameworkName[] =
|
||||
FPL(ATOM_PRODUCT_NAME " Framework.framework");
|
||||
#endif // OS_MACOSX
|
||||
|
||||
// filenames
|
||||
const base::FilePath::CharType kCacheDirname[] = FPL("Cache");
|
||||
const base::FilePath::CharType kChannelIDFilename[] = FPL("Origin Bound Certs");
|
||||
const base::FilePath::CharType kCookieFilename[] = FPL("Cookies");
|
||||
const base::FilePath::CharType kCRLSetFilename[] =
|
||||
FPL("Certificate Revocation Lists");
|
||||
const base::FilePath::CharType kCustomDictionaryFileName[] =
|
||||
FPL("Custom Dictionary.txt");
|
||||
const base::FilePath::CharType kExtensionActivityLogFilename[] =
|
||||
FPL("Extension Activity");
|
||||
const base::FilePath::CharType kExtensionsCookieFilename[] =
|
||||
FPL("Extension Cookies");
|
||||
const base::FilePath::CharType kFirstRunSentinel[] = FPL("First Run");
|
||||
const base::FilePath::CharType kGCMStoreDirname[] = FPL("GCM Store");
|
||||
const base::FilePath::CharType kLocalStateFilename[] = FPL("Local State");
|
||||
const base::FilePath::CharType kLocalStorePoolName[] = FPL("LocalStorePool");
|
||||
const base::FilePath::CharType kMediaCacheDirname[] = FPL("Media Cache");
|
||||
const base::FilePath::CharType kNetworkPersistentStateFilename[] =
|
||||
FPL("Network Persistent State");
|
||||
const base::FilePath::CharType kOfflinePageArchviesDirname[] =
|
||||
FPL("Offline Pages/archives");
|
||||
const base::FilePath::CharType kOfflinePageMetadataDirname[] =
|
||||
FPL("Offline Pages/metadata");
|
||||
const base::FilePath::CharType kPreferencesFilename[] = FPL("Preferences");
|
||||
const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[] =
|
||||
FPL("Protected Preferences");
|
||||
const base::FilePath::CharType kReadmeFilename[] = FPL("README");
|
||||
const base::FilePath::CharType kResetPromptMementoFilename[] =
|
||||
FPL("Reset Prompt Memento");
|
||||
const base::FilePath::CharType kSafeBrowsingBaseFilename[] =
|
||||
FPL("Safe Browsing");
|
||||
const base::FilePath::CharType kSecurePreferencesFilename[] =
|
||||
FPL("Secure Preferences");
|
||||
const base::FilePath::CharType kServiceStateFileName[] = FPL("Service State");
|
||||
const base::FilePath::CharType kSingletonCookieFilename[] =
|
||||
FPL("SingletonCookie");
|
||||
const base::FilePath::CharType kSingletonLockFilename[] = FPL("SingletonLock");
|
||||
const base::FilePath::CharType kSingletonSocketFilename[] =
|
||||
FPL("SingletonSocket");
|
||||
const base::FilePath::CharType kSupervisedUserSettingsFilename[] =
|
||||
FPL("Managed Mode Settings");
|
||||
const base::FilePath::CharType kThemePackFilename[] = FPL("Cached Theme.pak");
|
||||
const base::FilePath::CharType kThemePackMaterialDesignFilename[] =
|
||||
FPL("Cached Theme Material Design.pak");
|
||||
const base::FilePath::CharType kWebAppDirname[] = FPL("Web Applications");
|
||||
|
||||
// File name of the Pepper Flash plugin on different platforms.
|
||||
const base::FilePath::CharType kPepperFlashPluginFilename[] =
|
||||
#if defined(OS_MACOSX)
|
||||
FPL("PepperFlashPlayer.plugin");
|
||||
#elif defined(OS_WIN)
|
||||
FPL("pepflashplayer.dll");
|
||||
#else // OS_LINUX, etc.
|
||||
FPL("libpepflashplayer.so");
|
||||
#endif
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#undef FPL
|
58
chromium_src/chrome/common/chrome_constants.h
Normal file
58
chromium_src/chrome/common/chrome_constants.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// A handful of resource-like constants related to the Chrome application.
|
||||
|
||||
#ifndef CHROME_COMMON_CHROME_CONSTANTS_H_
|
||||
#define CHROME_COMMON_CHROME_CONSTANTS_H_
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
namespace chrome {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// NOTE: if you change the value of kFrameworkName, please don't forget to
|
||||
// update components/test/run_all_unittests.cc as well.
|
||||
// TODO(tfarina): Remove the comment above, when you fix components to use plist
|
||||
// on Mac.
|
||||
extern const base::FilePath::CharType kFrameworkName[];
|
||||
#endif // OS_MACOSX
|
||||
|
||||
// filenames
|
||||
extern const base::FilePath::CharType kCacheDirname[];
|
||||
extern const base::FilePath::CharType kChannelIDFilename[];
|
||||
extern const base::FilePath::CharType kCookieFilename[];
|
||||
extern const base::FilePath::CharType kCRLSetFilename[];
|
||||
extern const base::FilePath::CharType kCustomDictionaryFileName[];
|
||||
extern const base::FilePath::CharType kExtensionActivityLogFilename[];
|
||||
extern const base::FilePath::CharType kExtensionsCookieFilename[];
|
||||
extern const base::FilePath::CharType kFirstRunSentinel[];
|
||||
extern const base::FilePath::CharType kGCMStoreDirname[];
|
||||
extern const base::FilePath::CharType kLocalStateFilename[];
|
||||
extern const base::FilePath::CharType kLocalStorePoolName[];
|
||||
extern const base::FilePath::CharType kMediaCacheDirname[];
|
||||
extern const base::FilePath::CharType kNetworkPersistentStateFilename[];
|
||||
extern const base::FilePath::CharType kOfflinePageArchviesDirname[];
|
||||
extern const base::FilePath::CharType kOfflinePageMetadataDirname[];
|
||||
extern const base::FilePath::CharType kPreferencesFilename[];
|
||||
extern const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[];
|
||||
extern const base::FilePath::CharType kReadmeFilename[];
|
||||
extern const base::FilePath::CharType kResetPromptMementoFilename[];
|
||||
extern const base::FilePath::CharType kSafeBrowsingBaseFilename[];
|
||||
extern const base::FilePath::CharType kSecurePreferencesFilename[];
|
||||
extern const base::FilePath::CharType kServiceStateFileName[];
|
||||
extern const base::FilePath::CharType kSingletonCookieFilename[];
|
||||
extern const base::FilePath::CharType kSingletonLockFilename[];
|
||||
extern const base::FilePath::CharType kSingletonSocketFilename[];
|
||||
extern const base::FilePath::CharType kSupervisedUserSettingsFilename[];
|
||||
extern const base::FilePath::CharType kThemePackFilename[];
|
||||
extern const base::FilePath::CharType kThemePackMaterialDesignFilename[];
|
||||
extern const base::FilePath::CharType kWebAppDirname[];
|
||||
|
||||
// File name of the Pepper Flash plugin on different platforms.
|
||||
extern const base::FilePath::CharType kPepperFlashPluginFilename[];
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_COMMON_CHROME_CONSTANTS_H_
|
610
chromium_src/chrome/common/chrome_paths.cc
Normal file
610
chromium_src/chrome/common/chrome_paths.cc
Normal file
|
@ -0,0 +1,610 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/sys_info.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "base/version.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
#include "chrome/common/chrome_paths_internal.h"
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
#include "base/android/path_utils.h"
|
||||
#include "base/base_paths_android.h"
|
||||
// ui/base must only be used on Android. See BUILD.gn for dependency info.
|
||||
#include "ui/base/ui_base_paths.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "base/mac/foundation_util.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/registry.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// The Pepper Flash plugins are in a directory with this name.
|
||||
const base::FilePath::CharType kPepperFlashBaseDirectory[] =
|
||||
FILE_PATH_LITERAL("PepperFlash");
|
||||
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] =
|
||||
FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer");
|
||||
const base::FilePath::CharType kFlashSystemBaseDirectory[] =
|
||||
FILE_PATH_LITERAL("Internet Plug-Ins");
|
||||
const base::FilePath::CharType kFlashSystemPluginName[] =
|
||||
FILE_PATH_LITERAL("Flash Player.plugin");
|
||||
#endif
|
||||
|
||||
const base::FilePath::CharType kInternalNaClPluginFileName[] =
|
||||
FILE_PATH_LITERAL("internal-nacl-plugin");
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// The path to the external extension <id>.json files.
|
||||
// /usr/share seems like a good choice, see: http://www.pathname.com/fhs/
|
||||
const base::FilePath::CharType kFilepathSinglePrefExtensions[] =
|
||||
#if defined(GOOGLE_CHROME_BUILD)
|
||||
FILE_PATH_LITERAL("/usr/share/google-chrome/extensions");
|
||||
#else
|
||||
FILE_PATH_LITERAL("/usr/share/chromium/extensions");
|
||||
#endif // defined(GOOGLE_CHROME_BUILD)
|
||||
|
||||
// The path to the hint file that tells the pepper plugin loader
|
||||
// where it can find the latest component updated flash.
|
||||
const base::FilePath::CharType kComponentUpdatedFlashHint[] =
|
||||
FILE_PATH_LITERAL("latest-component-updated-flash");
|
||||
#endif // defined(OS_LINUX)
|
||||
|
||||
static base::LazyInstance<base::FilePath>
|
||||
g_invalid_specified_user_data_dir = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
// Gets the path for internal plugins.
|
||||
bool GetInternalPluginsDirectory(base::FilePath* result) {
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
// If called from Chrome, get internal plugins from a subdirectory of the
|
||||
// framework.
|
||||
if (base::mac::AmIBundled()) {
|
||||
*result = chrome::GetFrameworkBundlePath();
|
||||
DCHECK(!result->empty());
|
||||
*result = result->Append("Internet Plug-Ins");
|
||||
return true;
|
||||
}
|
||||
// In tests, just look in the module directory (below).
|
||||
#endif
|
||||
|
||||
// The rest of the world expects plugins in the module directory.
|
||||
return PathService::Get(base::DIR_MODULE, result);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Gets the Flash path if installed on the system. |is_npapi| determines whether
|
||||
// to return the NPAPI of the PPAPI version of the system plugin.
|
||||
bool GetSystemFlashFilename(base::FilePath* out_path, bool is_npapi) {
|
||||
const wchar_t kNpapiFlashRegistryRoot[] =
|
||||
L"SOFTWARE\\Macromedia\\FlashPlayerPlugin";
|
||||
const wchar_t kPepperFlashRegistryRoot[] =
|
||||
L"SOFTWARE\\Macromedia\\FlashPlayerPepper";
|
||||
const wchar_t kFlashPlayerPathValueName[] = L"PlayerPath";
|
||||
|
||||
base::win::RegKey path_key(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
is_npapi ? kNpapiFlashRegistryRoot : kPepperFlashRegistryRoot, KEY_READ);
|
||||
base::string16 path_str;
|
||||
if (FAILED(path_key.ReadValue(kFlashPlayerPathValueName, &path_str)))
|
||||
return false;
|
||||
|
||||
*out_path = base::FilePath(path_str);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chrome {
|
||||
|
||||
bool PathProvider(int key, base::FilePath* result) {
|
||||
// Some keys are just aliases...
|
||||
switch (key) {
|
||||
case chrome::DIR_APP:
|
||||
return PathService::Get(base::DIR_MODULE, result);
|
||||
case chrome::DIR_LOGS:
|
||||
#ifdef NDEBUG
|
||||
// Release builds write to the data dir
|
||||
return PathService::Get(chrome::DIR_USER_DATA, result);
|
||||
#else
|
||||
// Debug builds write next to the binary (in the build tree)
|
||||
#if defined(OS_MACOSX)
|
||||
if (!PathService::Get(base::DIR_EXE, result))
|
||||
return false;
|
||||
if (base::mac::AmIBundled()) {
|
||||
// If we're called from chrome, dump it beside the app (outside the
|
||||
// app bundle), if we're called from a unittest, we'll already
|
||||
// outside the bundle so use the exe dir.
|
||||
// exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
|
||||
*result = result->DirName();
|
||||
*result = result->DirName();
|
||||
*result = result->DirName();
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return PathService::Get(base::DIR_EXE, result);
|
||||
#endif // defined(OS_MACOSX)
|
||||
#endif // NDEBUG
|
||||
case chrome::FILE_RESOURCE_MODULE:
|
||||
return PathService::Get(base::FILE_MODULE, result);
|
||||
}
|
||||
|
||||
// Assume that we will not need to create the directory if it does not exist.
|
||||
// This flag can be set to true for the cases where we want to create it.
|
||||
bool create_dir = false;
|
||||
|
||||
base::FilePath cur;
|
||||
switch (key) {
|
||||
case chrome::DIR_USER_DATA:
|
||||
if (!GetDefaultUserDataDirectory(&cur)) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
create_dir = true;
|
||||
break;
|
||||
case chrome::DIR_USER_DOCUMENTS:
|
||||
if (!GetUserDocumentsDirectory(&cur))
|
||||
return false;
|
||||
create_dir = true;
|
||||
break;
|
||||
case chrome::DIR_USER_MUSIC:
|
||||
if (!GetUserMusicDirectory(&cur))
|
||||
return false;
|
||||
break;
|
||||
case chrome::DIR_USER_PICTURES:
|
||||
if (!GetUserPicturesDirectory(&cur))
|
||||
return false;
|
||||
break;
|
||||
case chrome::DIR_USER_VIDEOS:
|
||||
if (!GetUserVideosDirectory(&cur))
|
||||
return false;
|
||||
break;
|
||||
case chrome::DIR_DEFAULT_DOWNLOADS_SAFE:
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
if (!GetUserDownloadsDirectorySafe(&cur))
|
||||
return false;
|
||||
break;
|
||||
#else
|
||||
// Fall through for all other platforms.
|
||||
#endif
|
||||
case chrome::DIR_DEFAULT_DOWNLOADS:
|
||||
#if defined(OS_ANDROID)
|
||||
if (!base::android::GetDownloadsDirectory(&cur))
|
||||
return false;
|
||||
#else
|
||||
if (!GetUserDownloadsDirectory(&cur))
|
||||
return false;
|
||||
// Do not create the download directory here, we have done it twice now
|
||||
// and annoyed a lot of users.
|
||||
#endif
|
||||
break;
|
||||
case chrome::DIR_CRASH_DUMPS:
|
||||
#if defined(OS_CHROMEOS)
|
||||
// ChromeOS uses a separate directory. See http://crosbug.com/25089
|
||||
cur = base::FilePath("/var/log/chrome");
|
||||
#elif defined(OS_ANDROID)
|
||||
if (!base::android::GetCacheDirectory(&cur))
|
||||
return false;
|
||||
#else
|
||||
// The crash reports are always stored relative to the default user data
|
||||
// directory. This avoids the problem of having to re-initialize the
|
||||
// exception handler after parsing command line options, which may
|
||||
// override the location of the app's profile directory.
|
||||
if (!GetDefaultUserDataDirectory(&cur))
|
||||
return false;
|
||||
#endif
|
||||
#if defined(OS_MACOSX)
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
|
||||
#else
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
|
||||
#endif
|
||||
create_dir = true;
|
||||
break;
|
||||
#if defined(OS_WIN)
|
||||
case chrome::DIR_WATCHER_DATA:
|
||||
// The watcher data is always stored relative to the default user data
|
||||
// directory. This allows the watcher to be initialized before
|
||||
// command-line options have been parsed.
|
||||
if (!GetDefaultUserDataDirectory(&cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Diagnostics"));
|
||||
break;
|
||||
#endif
|
||||
case chrome::DIR_RESOURCES:
|
||||
#if defined(OS_MACOSX)
|
||||
cur = base::mac::FrameworkBundlePath();
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Resources"));
|
||||
#else
|
||||
if (!PathService::Get(chrome::DIR_APP, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("resources"));
|
||||
#endif
|
||||
break;
|
||||
case chrome::DIR_INSPECTOR:
|
||||
if (!PathService::Get(chrome::DIR_RESOURCES, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("inspector"));
|
||||
break;
|
||||
case chrome::DIR_APP_DICTIONARIES:
|
||||
#if defined(OS_POSIX)
|
||||
// We can't write into the EXE dir on Linux, so keep dictionaries
|
||||
// alongside the safe browsing database in the user data dir.
|
||||
// And we don't want to write into the bundle on the Mac, so push
|
||||
// it to the user data dir there also.
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
#else
|
||||
if (!PathService::Get(base::DIR_EXE, &cur))
|
||||
return false;
|
||||
#endif
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Dictionaries"));
|
||||
create_dir = true;
|
||||
break;
|
||||
case chrome::DIR_INTERNAL_PLUGINS:
|
||||
if (!GetInternalPluginsDirectory(&cur))
|
||||
return false;
|
||||
break;
|
||||
case chrome::DIR_PEPPER_FLASH_PLUGIN:
|
||||
if (!GetInternalPluginsDirectory(&cur))
|
||||
return false;
|
||||
cur = cur.Append(kPepperFlashBaseDirectory);
|
||||
break;
|
||||
case chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(kPepperFlashBaseDirectory);
|
||||
break;
|
||||
case chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN:
|
||||
#if defined(OS_WIN)
|
||||
if (!GetSystemFlashFilename(&cur, false))
|
||||
return false;
|
||||
#elif defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
if (!GetLocalLibraryDirectory(&cur))
|
||||
return false;
|
||||
cur = cur.Append(kPepperFlashSystemBaseDirectory);
|
||||
cur = cur.Append(chrome::kPepperFlashPluginFilename);
|
||||
#else
|
||||
// Chrome on iOS does not supports PPAPI binaries, return false.
|
||||
// TODO(wfh): If Adobe release PPAPI binaries for Linux, add support here.
|
||||
return false;
|
||||
#endif
|
||||
break;
|
||||
case chrome::FILE_FLASH_SYSTEM_PLUGIN:
|
||||
#if defined(OS_WIN)
|
||||
if (!GetSystemFlashFilename(&cur, true))
|
||||
return false;
|
||||
#elif defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
if (!GetLocalLibraryDirectory(&cur))
|
||||
return false;
|
||||
cur = cur.Append(kFlashSystemBaseDirectory);
|
||||
cur = cur.Append(kFlashSystemPluginName);
|
||||
#else
|
||||
// Chrome on other platforms does not supports system NPAPI binaries.
|
||||
return false;
|
||||
#endif
|
||||
break;
|
||||
case chrome::FILE_LOCAL_STATE:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(chrome::kLocalStateFilename);
|
||||
break;
|
||||
case chrome::FILE_RECORDED_SCRIPT:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("script.log"));
|
||||
break;
|
||||
case chrome::FILE_PEPPER_FLASH_PLUGIN:
|
||||
if (!PathService::Get(chrome::DIR_PEPPER_FLASH_PLUGIN, &cur))
|
||||
return false;
|
||||
cur = cur.Append(chrome::kPepperFlashPluginFilename);
|
||||
break;
|
||||
// TODO(teravest): Remove this case once the internal NaCl plugin is gone.
|
||||
// We currently need a path here to look up whether the plugin is disabled
|
||||
// and what its permissions are.
|
||||
case chrome::FILE_NACL_PLUGIN:
|
||||
if (!GetInternalPluginsDirectory(&cur))
|
||||
return false;
|
||||
cur = cur.Append(kInternalNaClPluginFileName);
|
||||
break;
|
||||
// PNaCl is currenly installable via the component updater or by being
|
||||
// simply built-in. DIR_PNACL_BASE is used as the base directory for
|
||||
// installation via component updater. DIR_PNACL_COMPONENT will be
|
||||
// the final location of pnacl, which is a subdir of DIR_PNACL_BASE.
|
||||
case chrome::DIR_PNACL_BASE:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
|
||||
break;
|
||||
// Where PNaCl files are ultimately located. The default finds the files
|
||||
// inside the InternalPluginsDirectory / build directory, as if it
|
||||
// was shipped along with chrome. The value can be overridden
|
||||
// if it is installed via component updater.
|
||||
case chrome::DIR_PNACL_COMPONENT:
|
||||
#if defined(OS_MACOSX)
|
||||
// PNaCl really belongs in the InternalPluginsDirectory but actually
|
||||
// copying it there would result in the files also being shipped, which
|
||||
// we don't want yet. So for now, just find them in the directory where
|
||||
// they get built.
|
||||
if (!PathService::Get(base::DIR_EXE, &cur))
|
||||
return false;
|
||||
if (base::mac::AmIBundled()) {
|
||||
// If we're called from chrome, it's beside the app (outside the
|
||||
// app bundle), if we're called from a unittest, we'll already be
|
||||
// outside the bundle so use the exe dir.
|
||||
// exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
|
||||
cur = cur.DirName();
|
||||
cur = cur.DirName();
|
||||
cur = cur.DirName();
|
||||
}
|
||||
#else
|
||||
if (!GetInternalPluginsDirectory(&cur))
|
||||
return false;
|
||||
#endif
|
||||
cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
|
||||
break;
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
#if defined(WIDEVINE_CDM_IS_COMPONENT)
|
||||
case chrome::DIR_COMPONENT_WIDEVINE_CDM:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("WidevineCDM"));
|
||||
break;
|
||||
#endif // defined(WIDEVINE_CDM_IS_COMPONENT)
|
||||
// TODO(xhwang): FILE_WIDEVINE_CDM_ADAPTER has different meanings.
|
||||
// In the component case, this is the source adapter. Otherwise, it is the
|
||||
// actual Pepper module that gets loaded.
|
||||
case chrome::FILE_WIDEVINE_CDM_ADAPTER:
|
||||
if (!GetInternalPluginsDirectory(&cur))
|
||||
return false;
|
||||
cur = cur.AppendASCII(kWidevineCdmAdapterFileName);
|
||||
break;
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
case chrome::FILE_RESOURCES_PACK:
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
if (base::mac::AmIBundled()) {
|
||||
cur = base::mac::FrameworkBundlePath();
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Resources"))
|
||||
.Append(FILE_PATH_LITERAL("resources.pak"));
|
||||
break;
|
||||
}
|
||||
#elif defined(OS_ANDROID)
|
||||
if (!PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &cur))
|
||||
return false;
|
||||
#else
|
||||
// If we're not bundled on mac or Android, resources.pak should be next
|
||||
// to the binary (e.g., for unit tests).
|
||||
if (!PathService::Get(base::DIR_MODULE, &cur))
|
||||
return false;
|
||||
#endif
|
||||
cur = cur.Append(FILE_PATH_LITERAL("resources.pak"));
|
||||
break;
|
||||
case chrome::DIR_RESOURCES_EXTENSION:
|
||||
if (!PathService::Get(base::DIR_MODULE, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("resources"))
|
||||
.Append(FILE_PATH_LITERAL("extension"));
|
||||
break;
|
||||
#if defined(OS_CHROMEOS)
|
||||
case chrome::DIR_CHROMEOS_WALLPAPERS:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("wallpapers"));
|
||||
break;
|
||||
case chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("wallpaper_thumbnails"));
|
||||
break;
|
||||
case chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("custom_wallpapers"));
|
||||
break;
|
||||
#endif
|
||||
#if defined(ENABLE_SUPERVISED_USERS)
|
||||
#if defined(OS_LINUX)
|
||||
case chrome::DIR_SUPERVISED_USERS_DEFAULT_APPS:
|
||||
if (!PathService::Get(chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("managed_users"));
|
||||
break;
|
||||
#endif
|
||||
case chrome::DIR_SUPERVISED_USER_INSTALLED_WHITELISTS:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("SupervisedUserInstalledWhitelists"));
|
||||
break;
|
||||
#endif
|
||||
// The following are only valid in the development environment, and
|
||||
// will fail if executed from an installed executable (because the
|
||||
// generated path won't exist).
|
||||
case chrome::DIR_GEN_TEST_DATA:
|
||||
#if defined(OS_ANDROID)
|
||||
// On Android, our tests don't have permission to write to DIR_MODULE.
|
||||
// gtest/test_runner.py pushes data to external storage.
|
||||
if (!PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &cur))
|
||||
return false;
|
||||
#else
|
||||
if (!PathService::Get(base::DIR_MODULE, &cur))
|
||||
return false;
|
||||
#endif
|
||||
cur = cur.Append(FILE_PATH_LITERAL("test_data"));
|
||||
if (!base::PathExists(cur)) // We don't want to create this.
|
||||
return false;
|
||||
break;
|
||||
case chrome::DIR_TEST_DATA:
|
||||
if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("chrome"));
|
||||
cur = cur.Append(FILE_PATH_LITERAL("test"));
|
||||
cur = cur.Append(FILE_PATH_LITERAL("data"));
|
||||
if (!base::PathExists(cur)) // We don't want to create this.
|
||||
return false;
|
||||
break;
|
||||
case chrome::DIR_TEST_TOOLS:
|
||||
if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("chrome"));
|
||||
cur = cur.Append(FILE_PATH_LITERAL("tools"));
|
||||
cur = cur.Append(FILE_PATH_LITERAL("test"));
|
||||
if (!base::PathExists(cur)) // We don't want to create this
|
||||
return false;
|
||||
break;
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
|
||||
case chrome::DIR_POLICY_FILES: {
|
||||
#if defined(GOOGLE_CHROME_BUILD)
|
||||
cur = base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies"));
|
||||
#else
|
||||
cur = base::FilePath(FILE_PATH_LITERAL("/etc/chromium/policies"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
case chrome::DIR_USER_LIBRARY: {
|
||||
if (!GetUserLibraryDirectory(&cur))
|
||||
return false;
|
||||
if (!base::PathExists(cur)) // We don't want to create this.
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case chrome::DIR_USER_APPLICATIONS: {
|
||||
if (!GetUserApplicationsDirectory(&cur))
|
||||
return false;
|
||||
if (!base::PathExists(cur)) // We don't want to create this.
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \
|
||||
(defined(OS_MACOSX) && !defined(OS_IOS))
|
||||
case chrome::DIR_USER_EXTERNAL_EXTENSIONS: {
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("External Extensions"));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(OS_LINUX)
|
||||
case chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS: {
|
||||
cur = base::FilePath(kFilepathSinglePrefExtensions);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case chrome::DIR_EXTERNAL_EXTENSIONS:
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
if (!chrome::GetGlobalApplicationSupportDirectory(&cur))
|
||||
return false;
|
||||
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Google"))
|
||||
.Append(FILE_PATH_LITERAL("Chrome"))
|
||||
.Append(FILE_PATH_LITERAL("External Extensions"));
|
||||
create_dir = false;
|
||||
#else
|
||||
if (!PathService::Get(base::DIR_MODULE, &cur))
|
||||
return false;
|
||||
|
||||
cur = cur.Append(FILE_PATH_LITERAL("extensions"));
|
||||
create_dir = true;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case chrome::DIR_DEFAULT_APPS:
|
||||
#if defined(OS_MACOSX)
|
||||
cur = base::mac::FrameworkBundlePath();
|
||||
cur = cur.Append(FILE_PATH_LITERAL("Default Apps"));
|
||||
#else
|
||||
if (!PathService::Get(chrome::DIR_APP, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("default_apps"));
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS))
|
||||
case chrome::DIR_NATIVE_MESSAGING:
|
||||
#if defined(OS_MACOSX)
|
||||
#if defined(GOOGLE_CHROME_BUILD)
|
||||
cur = base::FilePath(FILE_PATH_LITERAL(
|
||||
"/Library/Google/Chrome/NativeMessagingHosts"));
|
||||
#else
|
||||
cur = base::FilePath(FILE_PATH_LITERAL(
|
||||
"/Library/Application Support/Chromium/NativeMessagingHosts"));
|
||||
#endif
|
||||
#else // defined(OS_MACOSX)
|
||||
#if defined(GOOGLE_CHROME_BUILD)
|
||||
cur = base::FilePath(FILE_PATH_LITERAL(
|
||||
"/etc/opt/chrome/native-messaging-hosts"));
|
||||
#else
|
||||
cur = base::FilePath(FILE_PATH_LITERAL(
|
||||
"/etc/chromium/native-messaging-hosts"));
|
||||
#endif
|
||||
#endif // !defined(OS_MACOSX)
|
||||
break;
|
||||
|
||||
case chrome::DIR_USER_NATIVE_MESSAGING:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(FILE_PATH_LITERAL("NativeMessagingHosts"));
|
||||
break;
|
||||
#endif // defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS))
|
||||
#if !defined(OS_ANDROID)
|
||||
case chrome::DIR_GLOBAL_GCM_STORE:
|
||||
if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
|
||||
return false;
|
||||
cur = cur.Append(kGCMStoreDirname);
|
||||
break;
|
||||
#endif // !defined(OS_ANDROID)
|
||||
#if defined(OS_LINUX)
|
||||
case chrome::FILE_COMPONENT_FLASH_HINT:
|
||||
if (!PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN,
|
||||
&cur)) {
|
||||
return false;
|
||||
}
|
||||
cur = cur.Append(kComponentUpdatedFlashHint);
|
||||
break;
|
||||
#endif // defined(OS_LINUX)
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(bauerb): http://crbug.com/259796
|
||||
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
||||
if (create_dir && !base::PathExists(cur) &&
|
||||
!base::CreateDirectory(cur))
|
||||
return false;
|
||||
|
||||
*result = cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
// This cannot be done as a static initializer sadly since Visual Studio will
|
||||
// eliminate this object file if there is no direct entry point into it.
|
||||
void RegisterPathProvider() {
|
||||
PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
|
||||
}
|
||||
|
||||
void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir) {
|
||||
g_invalid_specified_user_data_dir.Get() = user_data_dir;
|
||||
}
|
||||
|
||||
const base::FilePath& GetInvalidSpecifiedUserDataDir() {
|
||||
return g_invalid_specified_user_data_dir.Get();
|
||||
}
|
||||
|
||||
} // namespace chrome
|
152
chromium_src/chrome/common/chrome_paths.h
Normal file
152
chromium_src/chrome/common/chrome_paths.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_COMMON_CHROME_PATHS_H__
|
||||
#define CHROME_COMMON_CHROME_PATHS_H__
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
// This file declares path keys for the chrome module. These can be used with
|
||||
// the PathService to access various special directories and files.
|
||||
|
||||
namespace chrome {
|
||||
|
||||
enum {
|
||||
PATH_START = 1000,
|
||||
|
||||
DIR_APP = PATH_START, // Directory where dlls and data reside.
|
||||
DIR_LOGS, // Directory where logs should be written.
|
||||
DIR_USER_DATA, // Directory where user data can be written.
|
||||
DIR_CRASH_DUMPS, // Directory where crash dumps are written.
|
||||
#if defined(OS_WIN)
|
||||
DIR_WATCHER_DATA, // Directory where the Chrome watcher stores
|
||||
// data.
|
||||
#endif
|
||||
DIR_RESOURCES, // Directory containing separate file resources
|
||||
// used by Chrome at runtime.
|
||||
DIR_INSPECTOR, // Directory where web inspector is located.
|
||||
DIR_APP_DICTIONARIES, // Directory where the global dictionaries are.
|
||||
DIR_USER_DOCUMENTS, // Directory for a user's "My Documents".
|
||||
DIR_USER_MUSIC, // Directory for a user's music.
|
||||
DIR_USER_PICTURES, // Directory for a user's pictures.
|
||||
DIR_USER_VIDEOS, // Directory for a user's videos.
|
||||
DIR_DEFAULT_DOWNLOADS_SAFE, // Directory for a user's
|
||||
// "My Documents/Downloads", (Windows) or
|
||||
// "Downloads". (Linux)
|
||||
DIR_DEFAULT_DOWNLOADS, // Directory for a user's downloads.
|
||||
DIR_INTERNAL_PLUGINS, // Directory where internal plugins reside.
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
DIR_POLICY_FILES, // Directory for system-wide read-only
|
||||
// policy files that allow sys-admins
|
||||
// to set policies for chrome. This directory
|
||||
// contains subdirectories.
|
||||
#endif
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
DIR_USER_APPLICATIONS, // ~/Applications
|
||||
DIR_USER_LIBRARY, // ~/Library
|
||||
#endif
|
||||
#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \
|
||||
(defined(OS_MACOSX) && !defined(OS_IOS))
|
||||
DIR_USER_EXTERNAL_EXTENSIONS, // Directory for per-user external extensions
|
||||
// on Chrome Mac and Chromium Linux.
|
||||
// On Chrome OS, this path is used for OEM
|
||||
// customization. Getting this path does not
|
||||
// create it.
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
DIR_STANDALONE_EXTERNAL_EXTENSIONS, // Directory for 'per-extension'
|
||||
// definition manifest files that
|
||||
// describe extensions which are to be
|
||||
// installed when chrome is run.
|
||||
#endif
|
||||
DIR_EXTERNAL_EXTENSIONS, // Directory where installer places .crx files.
|
||||
|
||||
DIR_DEFAULT_APPS, // Directory where installer places .crx files
|
||||
// to be installed when chrome is first run.
|
||||
DIR_PEPPER_FLASH_PLUGIN, // Directory to the bundled Pepper Flash plugin,
|
||||
// containing the plugin and the manifest.
|
||||
DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, // Base directory of the Pepper
|
||||
// Flash plugins downloaded by the
|
||||
// component updater.
|
||||
FILE_RESOURCE_MODULE, // Full path and filename of the module that
|
||||
// contains embedded resources (version,
|
||||
// strings, images, etc.).
|
||||
FILE_LOCAL_STATE, // Path and filename to the file in which
|
||||
// machine/installation-specific state is saved.
|
||||
FILE_RECORDED_SCRIPT, // Full path to the script.log file that
|
||||
// contains recorded browser events for
|
||||
// playback.
|
||||
FILE_PEPPER_FLASH_PLUGIN, // Full path to the bundled Pepper Flash plugin
|
||||
// file.
|
||||
FILE_PEPPER_FLASH_SYSTEM_PLUGIN, // Full path to the system version of the
|
||||
// Pepper Flash plugin, downloadable from
|
||||
// Adobe website. Querying this path might
|
||||
// succeed no matter the file exists or not.
|
||||
FILE_FLASH_SYSTEM_PLUGIN, // Full path to the system version of NPAPI
|
||||
// Flash plugin, downloadable from Adobe
|
||||
// website. Querying this path might succeed no
|
||||
// matter the file exists or not.
|
||||
FILE_NACL_PLUGIN, // Full path to the internal NaCl plugin file.
|
||||
DIR_PNACL_BASE, // Full path to the base dir for PNaCl.
|
||||
DIR_PNACL_COMPONENT, // Full path to the latest PNaCl version
|
||||
// (subdir of DIR_PNACL_BASE).
|
||||
DIR_COMPONENT_WIDEVINE_CDM, // Directory that contains component-updated
|
||||
// Widevine CDM files.
|
||||
FILE_WIDEVINE_CDM_ADAPTER, // Full path to the Widevine CDM adapter file.
|
||||
FILE_RESOURCES_PACK, // Full path to the .pak file containing
|
||||
// binary data (e.g., html files and images
|
||||
// used by internal pages).
|
||||
DIR_RESOURCES_EXTENSION, // Full path to extension resources.
|
||||
#if defined(OS_CHROMEOS)
|
||||
DIR_CHROMEOS_WALLPAPERS, // Directory where downloaded chromeos
|
||||
// wallpapers reside.
|
||||
DIR_CHROMEOS_WALLPAPER_THUMBNAILS, // Directory where downloaded chromeos
|
||||
// wallpaper thumbnails reside.
|
||||
DIR_CHROMEOS_CUSTOM_WALLPAPERS, // Directory where custom wallpapers
|
||||
// reside.
|
||||
#endif
|
||||
DIR_SUPERVISED_USERS_DEFAULT_APPS, // Directory where installer places .crx
|
||||
// files to be installed when managed user
|
||||
// session starts.
|
||||
DIR_SUPERVISED_USER_INSTALLED_WHITELISTS, // Directory where sanitized
|
||||
// supervised user whitelists are
|
||||
// installed.
|
||||
#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS))
|
||||
DIR_NATIVE_MESSAGING, // System directory where native messaging host
|
||||
// manifest files are stored.
|
||||
DIR_USER_NATIVE_MESSAGING, // Directory with Native Messaging Hosts
|
||||
// installed per-user.
|
||||
#endif
|
||||
#if !defined(OS_ANDROID)
|
||||
DIR_GLOBAL_GCM_STORE, // Directory where the global GCM instance
|
||||
// stores its data.
|
||||
#endif
|
||||
|
||||
// Valid only in development environment; TODO(darin): move these
|
||||
DIR_GEN_TEST_DATA, // Directory where generated test data resides.
|
||||
DIR_TEST_DATA, // Directory where unit test data resides.
|
||||
DIR_TEST_TOOLS, // Directory where unit test tools reside.
|
||||
#if defined(OS_LINUX)
|
||||
FILE_COMPONENT_FLASH_HINT, // A file in a known location that points to
|
||||
// the component updated flash plugin.
|
||||
#endif // defined(OS_LINUX)
|
||||
|
||||
PATH_END
|
||||
};
|
||||
|
||||
// Call once to register the provider for the path keys defined above.
|
||||
void RegisterPathProvider();
|
||||
|
||||
// Get or set the invalid user data dir that was originally specified.
|
||||
void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir);
|
||||
const base::FilePath& GetInvalidSpecifiedUserDataDir();
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_COMMON_CHROME_PATHS_H__
|
112
chromium_src/chrome/common/chrome_paths_internal.h
Normal file
112
chromium_src/chrome/common/chrome_paths_internal.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CHROME_COMMON_CHROME_PATHS_INTERNAL_H_
|
||||
#define CHROME_COMMON_CHROME_PATHS_INTERNAL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#if defined(__OBJC__)
|
||||
@class NSBundle;
|
||||
#else
|
||||
class NSBundle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace chrome {
|
||||
|
||||
// Get the path to the user's data directory, regardless of whether
|
||||
// DIR_USER_DATA has been overridden by a command-line option.
|
||||
bool GetDefaultUserDataDirectory(base::FilePath* result);
|
||||
|
||||
// Get the path to the user's cache directory. This is normally the
|
||||
// same as the profile directory, but on Linux it can also be
|
||||
// $XDG_CACHE_HOME and on Mac it can be under ~/Library/Caches.
|
||||
// Note that the Chrome cache directories are actually subdirectories
|
||||
// of this directory, with names like "Cache" and "Media Cache".
|
||||
// This will always fill in |result| with a directory, sometimes
|
||||
// just |profile_dir|.
|
||||
void GetUserCacheDirectory(const base::FilePath& profile_dir, base::FilePath* result);
|
||||
|
||||
// Get the path to the user's documents directory.
|
||||
bool GetUserDocumentsDirectory(base::FilePath* result);
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
// Gets the path to a safe default download directory for a user.
|
||||
bool GetUserDownloadsDirectorySafe(base::FilePath* result);
|
||||
#endif
|
||||
|
||||
// Get the path to the user's downloads directory.
|
||||
bool GetUserDownloadsDirectory(base::FilePath* result);
|
||||
|
||||
// Gets the path to the user's music directory.
|
||||
bool GetUserMusicDirectory(base::FilePath* result);
|
||||
|
||||
// Gets the path to the user's pictures directory.
|
||||
bool GetUserPicturesDirectory(base::FilePath* result);
|
||||
|
||||
// Gets the path to the user's videos directory.
|
||||
bool GetUserVideosDirectory(base::FilePath* result);
|
||||
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
// The "versioned directory" is a directory in the browser .app bundle. It
|
||||
// contains the bulk of the application, except for the things that the system
|
||||
// requires be located at spepcific locations. The versioned directory is
|
||||
// in the .app at Contents/Versions/w.x.y.z.
|
||||
base::FilePath GetVersionedDirectory();
|
||||
|
||||
// This overrides the directory returned by |GetVersionedDirectory()|, to be
|
||||
// used when |GetVersionedDirectory()| can't automatically determine the proper
|
||||
// location. This is the case when the browser didn't load itself but by, e.g.,
|
||||
// the app mode loader. This should be called before |ChromeMain()|. This takes
|
||||
// ownership of the object |path| and the caller must not delete it.
|
||||
void SetOverrideVersionedDirectory(const base::FilePath* path);
|
||||
|
||||
// Most of the application is further contained within the framework. The
|
||||
// framework bundle is located within the versioned directory at a specific
|
||||
// path. The only components in the versioned directory not included in the
|
||||
// framework are things that also depend on the framework, such as the helper
|
||||
// app bundle.
|
||||
base::FilePath GetFrameworkBundlePath();
|
||||
|
||||
// Get the local library directory.
|
||||
bool GetLocalLibraryDirectory(base::FilePath* result);
|
||||
|
||||
// Get the user library directory.
|
||||
bool GetUserLibraryDirectory(base::FilePath* result);
|
||||
|
||||
// Get the user applications directory.
|
||||
bool GetUserApplicationsDirectory(base::FilePath* result);
|
||||
|
||||
// Get the global Application Support directory (under /Library/).
|
||||
bool GetGlobalApplicationSupportDirectory(base::FilePath* result);
|
||||
|
||||
// Returns the NSBundle for the outer browser application, even when running
|
||||
// inside the helper. In unbundled applications, such as tests, returns nil.
|
||||
NSBundle* OuterAppBundle();
|
||||
|
||||
// Get the user data directory for the Chrome browser bundle at |bundle|.
|
||||
// |bundle| should be the same value that would be returned from +[NSBundle
|
||||
// mainBundle] if Chrome were launched normaly. This is used by app shims,
|
||||
// which run from a bundle which isn't Chrome itself, but which need access to
|
||||
// the user data directory to connect to a UNIX-domain socket therein.
|
||||
// Returns false if there was a problem fetching the app data directory.
|
||||
bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle,
|
||||
base::FilePath* result);
|
||||
|
||||
#endif // OS_MACOSX && !OS_IOS
|
||||
|
||||
// Checks if the |process_type| has the rights to access the profile.
|
||||
bool ProcessNeedsProfileDir(const std::string& process_type);
|
||||
|
||||
} // namespace chrome
|
||||
|
||||
#endif // CHROME_COMMON_CHROME_PATHS_INTERNAL_H_
|
145
chromium_src/chrome/common/chrome_paths_linux.cc
Normal file
145
chromium_src/chrome/common/chrome_paths_linux.cc
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/common/chrome_paths_internal.h"
|
||||
|
||||
#include "base/base_paths.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/nix/xdg_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
|
||||
namespace chrome {
|
||||
|
||||
using base::nix::GetXDGDirectory;
|
||||
using base::nix::GetXDGUserDirectory;
|
||||
using base::nix::kDotConfigDir;
|
||||
using base::nix::kXdgConfigHomeEnvVar;
|
||||
|
||||
namespace {
|
||||
|
||||
const char kDownloadsDir[] = "Downloads";
|
||||
const char kMusicDir[] = "Music";
|
||||
const char kPicturesDir[] = "Pictures";
|
||||
const char kVideosDir[] = "Videos";
|
||||
|
||||
// Generic function for GetUser{Music,Pictures,Video}Directory.
|
||||
bool GetUserMediaDirectory(const std::string& xdg_name,
|
||||
const std::string& fallback_name,
|
||||
base::FilePath* result) {
|
||||
#if defined(OS_CHROMEOS)
|
||||
// No local media directories on CrOS.
|
||||
return false;
|
||||
#else
|
||||
*result = GetXDGUserDirectory(xdg_name.c_str(), fallback_name.c_str());
|
||||
|
||||
base::FilePath home;
|
||||
PathService::Get(base::DIR_HOME, &home);
|
||||
if (*result != home) {
|
||||
base::FilePath desktop;
|
||||
if (!PathService::Get(base::DIR_USER_DESKTOP, &desktop))
|
||||
return false;
|
||||
if (*result != desktop) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*result = home.Append(fallback_name);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
// for a spec on where config files go. The net effect for most
|
||||
// systems is we use ~/.config/chromium/ for Chromium and
|
||||
// ~/.config/google-chrome/ for official builds.
|
||||
// (This also helps us sidestep issues with other apps grabbing ~/.chromium .)
|
||||
bool GetDefaultUserDataDirectory(base::FilePath* result) {
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
base::FilePath config_dir(GetXDGDirectory(env.get(),
|
||||
kXdgConfigHomeEnvVar,
|
||||
kDotConfigDir));
|
||||
#if defined(GOOGLE_CHROME_BUILD)
|
||||
*result = config_dir.Append("google-chrome");
|
||||
#else
|
||||
*result = config_dir.Append("chromium");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetUserCacheDirectory(const base::FilePath& profile_dir,
|
||||
base::FilePath* result) {
|
||||
// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
// for a spec on where cache files go. Our rule is:
|
||||
// - if the user-data-dir in the standard place,
|
||||
// use same subdirectory of the cache directory.
|
||||
// (this maps ~/.config/google-chrome to ~/.cache/google-chrome as well
|
||||
// as the same thing for ~/.config/chromium)
|
||||
// - otherwise, use the profile dir directly.
|
||||
|
||||
// Default value in cases where any of the following fails.
|
||||
*result = profile_dir;
|
||||
|
||||
scoped_ptr<base::Environment> env(base::Environment::Create());
|
||||
|
||||
base::FilePath cache_dir;
|
||||
if (!PathService::Get(base::DIR_CACHE, &cache_dir))
|
||||
return;
|
||||
base::FilePath config_dir(GetXDGDirectory(env.get(),
|
||||
kXdgConfigHomeEnvVar,
|
||||
kDotConfigDir));
|
||||
|
||||
if (!config_dir.AppendRelativePath(profile_dir, &cache_dir))
|
||||
return;
|
||||
|
||||
*result = cache_dir;
|
||||
}
|
||||
|
||||
bool GetUserDocumentsDirectory(base::FilePath* result) {
|
||||
*result = GetXDGUserDirectory("DOCUMENTS", "Documents");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetUserDownloadsDirectorySafe(base::FilePath* result) {
|
||||
base::FilePath home;
|
||||
PathService::Get(base::DIR_HOME, &home);
|
||||
*result = home.Append(kDownloadsDir);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetUserDownloadsDirectory(base::FilePath* result) {
|
||||
*result = GetXDGUserDirectory("DOWNLOAD", kDownloadsDir);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We respect the user's preferred pictures location, unless it is
|
||||
// ~ or their desktop directory, in which case we default to ~/Music.
|
||||
bool GetUserMusicDirectory(base::FilePath* result) {
|
||||
return GetUserMediaDirectory("MUSIC", kMusicDir, result);
|
||||
}
|
||||
|
||||
// We respect the user's preferred pictures location, unless it is
|
||||
// ~ or their desktop directory, in which case we default to ~/Pictures.
|
||||
bool GetUserPicturesDirectory(base::FilePath* result) {
|
||||
return GetUserMediaDirectory("PICTURES", kPicturesDir, result);
|
||||
}
|
||||
|
||||
// We respect the user's preferred pictures location, unless it is
|
||||
// ~ or their desktop directory, in which case we default to ~/Videos.
|
||||
bool GetUserVideosDirectory(base::FilePath* result) {
|
||||
return GetUserMediaDirectory("VIDEOS", kVideosDir, result);
|
||||
}
|
||||
|
||||
bool ProcessNeedsProfileDir(const std::string& process_type) {
|
||||
// For now we have no reason to forbid this on Linux as we don't
|
||||
// have the roaming profile troubles there. Moreover the Linux breakpad needs
|
||||
// profile dir access in all process if enabled on Linux.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace chrome
|
251
chromium_src/chrome/common/chrome_paths_mac.mm
Normal file
251
chromium_src/chrome/common/chrome_paths_mac.mm
Normal file
|
@ -0,0 +1,251 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/common/chrome_paths_internal.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/base_paths.h"
|
||||
#include "base/logging.h"
|
||||
#import "base/mac/foundation_util.h"
|
||||
#import "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/path_service.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#if !defined(OS_IOS)
|
||||
const base::FilePath* g_override_versioned_directory = NULL;
|
||||
|
||||
// Return a retained (NOT autoreleased) NSBundle* as the internal
|
||||
// implementation of chrome::OuterAppBundle(), which should be the only
|
||||
// caller.
|
||||
NSBundle* OuterAppBundleInternal() {
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
|
||||
if (!base::mac::AmIBundled()) {
|
||||
// If unbundled (as in a test), there's no app bundle.
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!base::mac::IsBackgroundOnlyProcess()) {
|
||||
// Shortcut: in the browser process, just return the main app bundle.
|
||||
return [[NSBundle mainBundle] retain];
|
||||
}
|
||||
|
||||
// From C.app/Contents/Versions/1.2.3.4, go up three steps to get to C.app.
|
||||
base::FilePath versioned_dir = chrome::GetVersionedDirectory();
|
||||
base::FilePath outer_app_dir = versioned_dir.DirName().DirName().DirName();
|
||||
const char* outer_app_dir_c = outer_app_dir.value().c_str();
|
||||
NSString* outer_app_dir_ns = [NSString stringWithUTF8String:outer_app_dir_c];
|
||||
|
||||
return [[NSBundle bundleWithPath:outer_app_dir_ns] retain];
|
||||
}
|
||||
#endif // !defined(OS_IOS)
|
||||
|
||||
char* ProductDirNameForBundle(NSBundle* chrome_bundle) {
|
||||
const char* product_dir_name = NULL;
|
||||
#if !defined(OS_IOS)
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
|
||||
NSString* product_dir_name_ns =
|
||||
[chrome_bundle objectForInfoDictionaryKey:@"CrProductDirName"];
|
||||
product_dir_name = [product_dir_name_ns fileSystemRepresentation];
|
||||
#else
|
||||
DCHECK(!chrome_bundle);
|
||||
#endif
|
||||
|
||||
if (!product_dir_name) {
|
||||
#if defined(GOOGLE_CHROME_BUILD)
|
||||
product_dir_name = "Google/Chrome";
|
||||
#else
|
||||
product_dir_name = "Chromium";
|
||||
#endif
|
||||
}
|
||||
|
||||
// Leaked, but the only caller initializes a static with this result, so it
|
||||
// only happens once, and that's OK.
|
||||
return strdup(product_dir_name);
|
||||
}
|
||||
|
||||
// ProductDirName returns the name of the directory inside
|
||||
// ~/Library/Application Support that should hold the product application
|
||||
// data. This can be overridden by setting the CrProductDirName key in the
|
||||
// outer browser .app's Info.plist. The default is "Google/Chrome" for
|
||||
// officially-branded builds, and "Chromium" for unbranded builds. For the
|
||||
// official canary channel, the Info.plist will have CrProductDirName set
|
||||
// to "Google/Chrome Canary".
|
||||
std::string ProductDirName() {
|
||||
#if defined(OS_IOS)
|
||||
static const char* product_dir_name = ProductDirNameForBundle(nil);
|
||||
#else
|
||||
// Use OuterAppBundle() to get the main app's bundle. This key needs to live
|
||||
// in the main app's bundle because it will be set differently on the canary
|
||||
// channel, and the autoupdate system dictates that there can be no
|
||||
// differences between channels within the versioned directory. This would
|
||||
// normally use base::mac::FrameworkBundle(), but that references the
|
||||
// framework bundle within the versioned directory. Ordinarily, the profile
|
||||
// should not be accessed from non-browser processes, but those processes do
|
||||
// attempt to get the profile directory, so direct them to look in the outer
|
||||
// browser .app's Info.plist for the CrProductDirName key.
|
||||
static const char* product_dir_name =
|
||||
ProductDirNameForBundle(chrome::OuterAppBundle());
|
||||
#endif
|
||||
return std::string(product_dir_name);
|
||||
}
|
||||
|
||||
bool GetDefaultUserDataDirectoryForProduct(const std::string& product_dir,
|
||||
base::FilePath* result) {
|
||||
bool success = false;
|
||||
if (result && PathService::Get(base::DIR_APP_DATA, result)) {
|
||||
*result = result->Append(product_dir);
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chrome {
|
||||
|
||||
bool GetDefaultUserDataDirectory(base::FilePath* result) {
|
||||
return GetDefaultUserDataDirectoryForProduct(ProductDirName(), result);
|
||||
}
|
||||
|
||||
bool GetUserDocumentsDirectory(base::FilePath* result) {
|
||||
return base::mac::GetUserDirectory(NSDocumentDirectory, result);
|
||||
}
|
||||
|
||||
void GetUserCacheDirectory(const base::FilePath& profile_dir,
|
||||
base::FilePath* result) {
|
||||
// If the profile directory is under ~/Library/Application Support,
|
||||
// use a suitable cache directory under ~/Library/Caches. For
|
||||
// example, a profile directory of ~/Library/Application
|
||||
// Support/Google/Chrome/MyProfileName would use the cache directory
|
||||
// ~/Library/Caches/Google/Chrome/MyProfileName.
|
||||
|
||||
// Default value in cases where any of the following fails.
|
||||
*result = profile_dir;
|
||||
|
||||
base::FilePath app_data_dir;
|
||||
if (!PathService::Get(base::DIR_APP_DATA, &app_data_dir))
|
||||
return;
|
||||
base::FilePath cache_dir;
|
||||
if (!PathService::Get(base::DIR_CACHE, &cache_dir))
|
||||
return;
|
||||
if (!app_data_dir.AppendRelativePath(profile_dir, &cache_dir))
|
||||
return;
|
||||
|
||||
*result = cache_dir;
|
||||
}
|
||||
|
||||
bool GetUserDownloadsDirectory(base::FilePath* result) {
|
||||
return base::mac::GetUserDirectory(NSDownloadsDirectory, result);
|
||||
}
|
||||
|
||||
bool GetUserMusicDirectory(base::FilePath* result) {
|
||||
return base::mac::GetUserDirectory(NSMusicDirectory, result);
|
||||
}
|
||||
|
||||
bool GetUserPicturesDirectory(base::FilePath* result) {
|
||||
return base::mac::GetUserDirectory(NSPicturesDirectory, result);
|
||||
}
|
||||
|
||||
bool GetUserVideosDirectory(base::FilePath* result) {
|
||||
return base::mac::GetUserDirectory(NSMoviesDirectory, result);
|
||||
}
|
||||
|
||||
#if !defined(OS_IOS)
|
||||
|
||||
base::FilePath GetVersionedDirectory() {
|
||||
if (g_override_versioned_directory)
|
||||
return *g_override_versioned_directory;
|
||||
|
||||
// Start out with the path to the running executable.
|
||||
base::FilePath path;
|
||||
PathService::Get(base::FILE_EXE, &path);
|
||||
|
||||
// One step up to MacOS, another to Contents.
|
||||
path = path.DirName().DirName();
|
||||
DCHECK_EQ(path.BaseName().value(), "Contents");
|
||||
|
||||
if (base::mac::IsBackgroundOnlyProcess()) {
|
||||
// path identifies the helper .app's Contents directory in the browser
|
||||
// .app's versioned directory. Go up two steps to get to the browser
|
||||
// .app's versioned directory.
|
||||
path = path.DirName().DirName();
|
||||
} else {
|
||||
// Go into the versioned directory.
|
||||
path = path.Append("Frameworks");
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void SetOverrideVersionedDirectory(const base::FilePath* path) {
|
||||
if (path != g_override_versioned_directory) {
|
||||
delete g_override_versioned_directory;
|
||||
g_override_versioned_directory = path;
|
||||
}
|
||||
}
|
||||
|
||||
base::FilePath GetFrameworkBundlePath() {
|
||||
// It's tempting to use +[NSBundle bundleWithIdentifier:], but it's really
|
||||
// slow (about 30ms on 10.5 and 10.6), despite Apple's documentation stating
|
||||
// that it may be more efficient than +bundleForClass:. +bundleForClass:
|
||||
// itself takes 1-2ms. Getting an NSBundle from a path, on the other hand,
|
||||
// essentially takes no time at all, at least when the bundle has already
|
||||
// been loaded as it will have been in this case. The FilePath operations
|
||||
// needed to compute the framework's path are also effectively free, so that
|
||||
// is the approach that is used here. NSBundle is also documented as being
|
||||
// not thread-safe, and thread safety may be a concern here.
|
||||
|
||||
// The framework bundle is at a known path and name from the browser .app's
|
||||
// versioned directory.
|
||||
return GetVersionedDirectory().Append(kFrameworkName);
|
||||
}
|
||||
|
||||
bool GetLocalLibraryDirectory(base::FilePath* result) {
|
||||
return base::mac::GetLocalDirectory(NSLibraryDirectory, result);
|
||||
}
|
||||
|
||||
bool GetUserLibraryDirectory(base::FilePath* result) {
|
||||
return base::mac::GetUserDirectory(NSLibraryDirectory, result);
|
||||
}
|
||||
|
||||
bool GetUserApplicationsDirectory(base::FilePath* result) {
|
||||
return base::mac::GetUserDirectory(NSApplicationDirectory, result);
|
||||
}
|
||||
|
||||
bool GetGlobalApplicationSupportDirectory(base::FilePath* result) {
|
||||
return base::mac::GetLocalDirectory(NSApplicationSupportDirectory, result);
|
||||
}
|
||||
|
||||
NSBundle* OuterAppBundle() {
|
||||
// Cache this. Foundation leaks it anyway, and this should be the only call
|
||||
// to OuterAppBundleInternal().
|
||||
static NSBundle* bundle = OuterAppBundleInternal();
|
||||
return bundle;
|
||||
}
|
||||
|
||||
bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle,
|
||||
base::FilePath* result) {
|
||||
scoped_ptr<char, base::FreeDeleter>
|
||||
product_dir_name(ProductDirNameForBundle(bundle));
|
||||
return GetDefaultUserDataDirectoryForProduct(product_dir_name.get(), result);
|
||||
}
|
||||
|
||||
#endif // !defined(OS_IOS)
|
||||
|
||||
bool ProcessNeedsProfileDir(const std::string& process_type) {
|
||||
// For now we have no reason to forbid this on other MacOS as we don't
|
||||
// have the roaming profile troubles there.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace chrome
|
107
chromium_src/chrome/common/chrome_paths_win.cc
Normal file
107
chromium_src/chrome/common/chrome_paths_win.cc
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "chrome/common/chrome_paths_internal.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <knownfolders.h>
|
||||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <shobjidl.h>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/win/metro.h"
|
||||
#include "base/win/scoped_co_mem.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
|
||||
namespace chrome {
|
||||
|
||||
namespace {
|
||||
|
||||
// Generic function to call SHGetFolderPath().
|
||||
bool GetUserDirectory(int csidl_folder, base::FilePath* result) {
|
||||
// We need to go compute the value. It would be nice to support paths
|
||||
// with names longer than MAX_PATH, but the system functions don't seem
|
||||
// to be designed for it either, with the exception of GetTempPath
|
||||
// (but other things will surely break if the temp path is too long,
|
||||
// so we don't bother handling it.
|
||||
wchar_t path_buf[MAX_PATH];
|
||||
path_buf[0] = 0;
|
||||
if (FAILED(SHGetFolderPath(NULL, csidl_folder, NULL,
|
||||
SHGFP_TYPE_CURRENT, path_buf))) {
|
||||
return false;
|
||||
}
|
||||
*result = base::FilePath(path_buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool GetDefaultUserDataDirectory(base::FilePath* result) {
|
||||
return PathService::Get(base::DIR_LOCAL_APP_DATA, result);
|
||||
}
|
||||
|
||||
void GetUserCacheDirectory(const base::FilePath& profile_dir,
|
||||
base::FilePath* result) {
|
||||
// This function does more complicated things on Mac/Linux.
|
||||
*result = profile_dir;
|
||||
}
|
||||
|
||||
bool GetUserDocumentsDirectory(base::FilePath* result) {
|
||||
return GetUserDirectory(CSIDL_MYDOCUMENTS, result);
|
||||
}
|
||||
|
||||
// Return a default path for downloads that is safe.
|
||||
// We just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing
|
||||
// 'downloads' is not a good idea because Chrome's UI language
|
||||
// can be changed.
|
||||
bool GetUserDownloadsDirectorySafe(base::FilePath* result) {
|
||||
if (!GetUserDocumentsDirectory(result))
|
||||
return false;
|
||||
|
||||
*result = result->Append(L"Downloads");
|
||||
return true;
|
||||
}
|
||||
|
||||
// On Vista and higher, use the downloads known folder. Since it can be
|
||||
// relocated to point to a "dangerous" folder, callers should validate that the
|
||||
// returned path is not dangerous before using it.
|
||||
bool GetUserDownloadsDirectory(base::FilePath* result) {
|
||||
typedef HRESULT (WINAPI *GetKnownFolderPath)(
|
||||
REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);
|
||||
GetKnownFolderPath f = reinterpret_cast<GetKnownFolderPath>(
|
||||
GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetKnownFolderPath"));
|
||||
base::win::ScopedCoMem<wchar_t> path_buf;
|
||||
if (f && SUCCEEDED(f(FOLDERID_Downloads, 0, NULL, &path_buf))) {
|
||||
*result = base::FilePath(std::wstring(path_buf));
|
||||
return true;
|
||||
}
|
||||
return GetUserDownloadsDirectorySafe(result);
|
||||
}
|
||||
|
||||
bool GetUserMusicDirectory(base::FilePath* result) {
|
||||
return GetUserDirectory(CSIDL_MYMUSIC, result);
|
||||
}
|
||||
|
||||
bool GetUserPicturesDirectory(base::FilePath* result) {
|
||||
return GetUserDirectory(CSIDL_MYPICTURES, result);
|
||||
}
|
||||
|
||||
bool GetUserVideosDirectory(base::FilePath* result) {
|
||||
return GetUserDirectory(CSIDL_MYVIDEO, result);
|
||||
}
|
||||
|
||||
bool ProcessNeedsProfileDir(const std::string& process_type) {
|
||||
// On windows we don't want subprocesses other than the browser process and
|
||||
// service processes to be able to use the profile directory because if it
|
||||
// lies on a network share the sandbox will prevent us from accessing it.
|
||||
|
||||
if (process_type.empty())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace chrome
|
|
@ -29,7 +29,6 @@
|
|||
#include "third_party/skia/include/core/SkMatrix.h"
|
||||
#include "third_party/skia/include/core/SkPaint.h"
|
||||
#include "third_party/skia/include/core/SkPoint.h"
|
||||
#include "third_party/skia/include/core/SkTemplates.h"
|
||||
#include "third_party/skia/include/core/SkTypeface.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "url/gurl.h"
|
||||
|
@ -315,7 +314,7 @@ int32_t PepperFlashRendererHost::OnNavigate(
|
|||
bool rejected = false;
|
||||
while (header_iter.GetNext()) {
|
||||
std::string lower_case_header_name =
|
||||
base::StringToLowerASCII(header_iter.name());
|
||||
base::ToLowerASCII(header_iter.name());
|
||||
if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
|
||||
rejected = true;
|
||||
|
||||
|
|
|
@ -544,7 +544,6 @@ void PrepareFrameAndViewForPrint::CopySelection(
|
|||
// on the page).
|
||||
WebPreferences prefs = preferences;
|
||||
prefs.javascript_enabled = false;
|
||||
prefs.java_enabled = false;
|
||||
|
||||
blink::WebView* web_view = blink::WebView::create(this);
|
||||
owns_web_view_ = true;
|
||||
|
|
|
@ -135,7 +135,8 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame,
|
|||
printed_page_params.page_size = page_size_in_dpi[i];
|
||||
printed_page_params.content_area = content_area_in_dpi[i];
|
||||
Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params));
|
||||
printed_page_params.metafile_data_handle = INVALID_HANDLE_VALUE;
|
||||
// Send the rest of the pages with an invalid metafile handle.
|
||||
printed_page_params.metafile_data_handle = base::SharedMemoryHandle();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue