Exemplo n.º 1
0
    bool PathProvider(int key, FilePath* result)
    {
        // 需要进行值的计算. 支持长于MAX_PATH的路径会更好, 但是系统函数设计的时候
        // 除了GetTempPath以外都不支持.
        wchar_t system_buffer[MAX_PATH] = { 0 };
        system_buffer[0] = 0;

        FilePath cur;
        switch(key)
        {
        case DIR_CURRENT:
            if(!FilePath::GetCurrentDirectory(cur))
            {
                return false;
            }
            break;
        case DIR_EXE:
            GetModuleFileNameW(NULL, system_buffer, MAX_PATH);
            cur = FilePath(system_buffer);
            cur.RemoveFileSpec();
            break;
        case DIR_MODULE:
            {
                // 代码调用的模块都有资源, 无论dll或exe.
                HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
                ::GetModuleFileNameW(this_module, system_buffer, MAX_PATH);
                cur = FilePath(system_buffer);
                cur.RemoveFileSpec();
                break;
            }
        case DIR_TEMP:
            if(!FilePath::GetTempDir(cur))
            {
                return false;
            }
            break;
        case FILE_EXE:
            GetModuleFileNameW(NULL, system_buffer, MAX_PATH);
            cur = FilePath(system_buffer);
            break;
        case FILE_MODULE:
            {
                // 代码调用的模块都有资源, 无论dll或exe.
                HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
                GetModuleFileNameW(this_module, system_buffer, MAX_PATH);
                cur = FilePath(system_buffer);
                break;
            }
        case DIR_WINDOWS:
            GetWindowsDirectoryW(system_buffer, MAX_PATH);
            cur = FilePath(system_buffer);
            break;
        case DIR_SYSTEM:
            GetSystemDirectoryW(system_buffer, MAX_PATH);
            cur = FilePath(system_buffer);
            break;
        case DIR_PROGRAM_FILES:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        case DIR_IE_INTERNET_CACHE:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_INTERNET_CACHE, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        case DIR_COMMON_START_MENU:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_COMMON_PROGRAMS, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        case DIR_START_MENU:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        case DIR_COMMON_APP_DATA:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        case DIR_APP_DATA:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        case DIR_PROFILE:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        case DIR_LOCAL_APP_DATA_LOW:
            if(GetWinVersion() < WINVERSION_VISTA)
            {
                return false;
            }
            // TODO: 应该使用SHGetKnownFolderPath替换. Bug 1281128.
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            cur.RemoveFileSpec();
            cur.Append(L"LocalLow");
            break;
        case DIR_LOCAL_APP_DATA:
            if(FAILED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL,
                SHGFP_TYPE_CURRENT, system_buffer)))
            {
                return false;
            }
            cur = FilePath(system_buffer);
            break;
        default:
            return false;
        }

        *result = cur;
        return true;
    }
Exemplo n.º 2
0
bool Root::init(FileString homeDirectory, FileString subprocessDirectory, unsigned int extra_argc, const char* extra_argv[] ) {

    new base::AtExitManager();

    FilePath subprocess;

    // convert extra arguments in a more useful form
    std::vector< std::string > extra_args;
    if( extra_argc > 0 )
    {
        for( unsigned int arg_idx = 0; arg_idx < extra_argc; ++arg_idx )
        {
            const char* raw_arg = extra_argv[ arg_idx ];
            assert( raw_arg );
            extra_args.push_back( raw_arg );
        }
    }


    {
// From <base/command_line.h>:
  // Initialize the current process CommandLine singleton.  On Windows,
  // ignores its arguments (we instead parse GetCommandLineW()
  // directly) because we don't trust the CRT's parsing of the command
  // line, but it still must be called to set up the command line.
// This means that on windows, we have to call ::Init with whatever we feel
// like (since this is the only way to create the static CommandLine instance),
// and then we have manually call ParseFromString.
// (InitFromArgv does not exist on OS_WIN!)
#if defined(OS_WIN)
    FilePath module_dir;
    if (subprocessDirectory.size()) {
        module_dir = FilePath(subprocessDirectory.get<FilePath::StringType>());
    } else {
        PathService::Get(base::DIR_MODULE, &module_dir);
    }
#ifdef _DEBUG
    subprocess = module_dir.Append(L"berkelium_d.exe");
#else
    subprocess = module_dir.Append(L"berkelium.exe");
#endif

	std::wstring subprocess_str = L"berkelium --enable-webgl --browser-subprocess-path=";
	subprocess_str += L"\"";
	subprocess_str += subprocess.value();
	subprocess_str += L"\"";

    // add extra arguments if any
    if( !extra_args.empty() )
    {
        for( unsigned int arg_idx = 0, arg_count = extra_args.size(); arg_idx < arg_count; ++arg_idx )
        {
            const std::string& str_arg = extra_args[ arg_idx ];
            std::wstring wstr_arg( str_arg.begin(), str_arg.end() );

            subprocess_str += L" " + wstr_arg;
        }
    }

    //std::wcout << "Berkelium subprocess_str : " << subprocess_str;

    CommandLine::Init(0, NULL);
    CommandLine::ForCurrentProcess()->ParseFromString(subprocess_str);
#elif defined(OS_MACOSX)
    FilePath app_contents;
    PathService::Get(base::FILE_EXE, &app_contents);
    FilePath module_dir;
    if (subprocessDirectory.size()) {
        module_dir = FilePath(subprocessDirectory.get<FilePath::StringType>());
    } else {
        module_dir = app_contents.DirName();
    }
    subprocess = module_dir.Append("berkelium");
    std::string subprocess_str = "--browser-subprocess-path=";
    subprocess_str += subprocess.value();

    std::vector<const char*> argv;
    argv.push_back( "berkelium" );
    argv.push_back( subprocess_str.c_str() );
    argv.push_back( "--enable-webgl" );

    for( std::vector<std::string>::iterator it = extra_args.begin(); it != extra_args.end(); ++it )
    {
        argv.push_back( it->c_str() );
    }

    //for( std::vector<const char*>::iterator it = argv.begin(); it != argv.end(); ++it )
    //    std::cout << "Berkelium arg : " << *it;

    CommandLine::Init( argv.size(), &argv[0] );
#elif defined(OS_POSIX)
    FilePath module_file;
    PathService::Get(base::FILE_EXE, &module_file);
    FilePath module_dir;
    if (subprocessDirectory.size()) {
        module_dir = FilePath(subprocessDirectory.get<FilePath::StringType>());
    } else {
        module_dir = module_file.DirName();
    }
    subprocess = module_dir.Append("berkelium");
    std::string subprocess_str = "--browser-subprocess-path=";
    subprocess_str += subprocess.value();
    std::vector<const char*> argv;
    argv.push_back( "berkelium" );
    argv.push_back( subprocess_str.c_str() );
    argv.push_back( "--enable-webgl" );

    for( std::vector<std::string>::iterator it = extra_args.begin(); it != extra_args.end(); ++it )
    {
        argv.push_back( it->c_str() );
    }
    //for( std::vector<const char*>::iterator it = argv.begin(); it != argv.end(); ++it )
    //    std::cout << "Berkelium arg : " << *it;

    CommandLine::Init( argv.size(), &argv[0]) ;
#endif
    }

    PathService::Override(base::FILE_EXE, subprocess);

#if !defined(OS_WIN)
/// Temporary SingletonLock fix:
// Do not do this for child processes--they should only be initialized.
// Children should never delete the lock.
    if (signal(SIGINT, handleINT) == SIG_IGN) {
        signal(SIGINT, SIG_IGN);
    }
    if (signal(SIGHUP, handleINT) == SIG_IGN) {
        signal(SIGHUP, SIG_IGN);
    }
    if (signal(SIGTERM, handleINT) == SIG_IGN) {
        signal(SIGTERM, SIG_IGN);
    }
#endif

    chrome::RegisterPathProvider();
    ui::RegisterPathProvider();
    FilePath homedirpath;

    if (homeDirectory.data() && homeDirectory.length()) {
        FilePath homeDirectoryPath(homeDirectory.get<FilePath::StringType>());
        PathService::Override(chrome::DIR_USER_DATA, homeDirectoryPath);
        PathService::Override(chrome::DIR_LOGS, homeDirectoryPath);
#if defined(OS_POSIX)
        PathService::Override(base::DIR_CACHE, homeDirectoryPath);
#endif
    } else {
        mTempProfileDir.reset(new ScopedTempDir());
        if (mTempProfileDir->CreateUniqueTempDir()) {
            PathService::Override(chrome::DIR_USER_DATA, mTempProfileDir->path());
            PathService::Override(chrome::DIR_LOGS, mTempProfileDir->path());
#if defined(OS_POSIX)
            PathService::Override(base::DIR_CACHE, mTempProfileDir->path());
#endif
        }
    }
    PathService::Get(chrome::DIR_USER_DATA,&homedirpath);
    bool SINGLE_PROCESS=false;
#if defined(OS_MACOSX)
    base::mac::SetOverrideAppBundlePath(chrome::GetFrameworkBundlePath());
    if (SINGLE_PROCESS) {
        InitWebCoreSystemInterface();
        //CGColorSpaceCreateDeviceRGB();
    }
#endif  // OS_MACOSX
    if (SINGLE_PROCESS) {
        RenderProcessHost::set_run_renderer_in_process(true);
    }
    mMessageLoop.reset(new MessageLoop(MessageLoop::TYPE_UI));
    mSysMon.reset(new ui::SystemMonitor);
    mTimerMgr.reset(new HighResolutionTimerManager);
    mUIThread.reset(new BrowserThread(BrowserThread::UI, mMessageLoop.get()));
    mErrorHandler = 0;

#if defined(OS_LINUX)
    if (!g_thread_supported ()) // the client application might have already setup glib
	{
		g_thread_init(NULL);
		// Glib type system initialization. Needed at least for gconf,
		// used in net/proxy/proxy_config_service_linux.cc. Most likely
		// this is superfluous as gtk_init() ought to do this. It's
		// definitely harmless, so retained as a reminder of this
		// requirement for gconf.
		g_type_init();
		// gtk_init() can change |argc| and |argv|.
		char argv0data[] = "[Berkelium]";
		char *argv0 = argv0data;
		char **argv = &argv0;
		int argc = 1;
		gtk_init(&argc, &argv);
    }
    SetUpGLibLogHandler();
#endif

    mProcessSingleton.reset(new ProcessSingleton(homedirpath));
    BrowserProcessImpl *browser_process;
    browser_process=new BrowserProcessImpl(*CommandLine::ForCurrentProcess());
    browser_process->local_state()->RegisterStringPref(prefs::kApplicationLocale, "");
    browser_process->local_state()->RegisterBooleanPref(prefs::kMetricsReportingEnabled, false);
    assert(g_browser_process == browser_process);

#ifdef OS_WIN
    logging::InitLogging(
        L"chrome.log",
        logging::LOG_NONE,
        logging::DONT_LOCK_LOG_FILE,
        logging::DELETE_OLD_LOG_FILE,
        logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS
        );
#else
    logging::InitLogging(
        "chrome.log",
        logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
        logging::DONT_LOCK_LOG_FILE,
        logging::DELETE_OLD_LOG_FILE,
        logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS
        );
#endif
    logging::InitChromeLogging(
        *CommandLine::ForCurrentProcess(),
        logging::DELETE_OLD_LOG_FILE);
    //APPEND_TO_OLD_LOG_FILE

  chrome::RegisterChromeSchemes(); // Required for "chrome-extension://" in InitExtensions
#if defined(OS_LINUX)
    const char* sandbox_binary = NULL;
    struct stat st;

    // In Chromium branded builds, developers can set an environment variable to
    // use the development sandbox. See
    // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
    if (stat("/proc/self/exe", &st) == 0 && st.st_uid == getuid())
      sandbox_binary = getenv("CHROME_DEVEL_SANDBOX");

    std::string sandbox_cmd;
    if (sandbox_binary && !CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox))
      sandbox_cmd = sandbox_binary;

    // Tickle the sandbox host and zygote host so they fork now.
    RenderSandboxHostLinux* shost = RenderSandboxHostLinux::GetInstance();
    shost->Init(sandbox_cmd);
    ZygoteHost* zhost = ZygoteHost::GetInstance();
    zhost->Init(sandbox_cmd);

    // We want to be sure to init NSPR on the main thread.
    base::EnsureNSPRInit();
#endif  // defined(OS_LINUX)

  SandboxInitWrapper sandbox_wrapper;
#if defined(OS_WIN)
  // Get the interface pointer to the BrokerServices or TargetServices,
  // depending who we are.
  sandbox::SandboxInterfaceInfo sandbox_info = {0};
  sandbox_info.broker_services = sandbox::BrokerServicesBase::GetInstance();
  sandbox::InitBrokerServices(sandbox_info.broker_services);
  if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox)) {
    bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kDisableAltWinstation);
    // Precreate the desktop and window station used by the renderers.
    sandbox::TargetPolicy* policy = sandbox_info.broker_services->CreatePolicy();
    sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta);
    CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
    policy->Release();
  }
  sandbox_wrapper.SetServices(&sandbox_info);
#endif
  sandbox_wrapper.InitializeSandbox(*CommandLine::ForCurrentProcess(), "");

  bool icu_result = icu_util::Initialize();
  CHECK(icu_result);

    mRenderViewHostFactory.reset(new MemoryRenderViewHostFactory);

//    mNotificationService=new NotificationService();
//    ChildProcess* coreProcess=new ChildProcess;
//    coreProcess->set_main_thread(new ChildThread);
    g_browser_process->SetApplicationLocale("en-US");
    ResourceBundle::InitSharedInstance("en-US");// FIXME: lookup locale
    // We only load the theme dll in the browser process.
    net::CookieMonster::EnableFileScheme();

    browser_process->profile_manager();
    browser_process->db_thread();
    browser_process->file_thread();
    browser_process->process_launcher_thread();
    browser_process->cache_thread();
    browser_process->io_thread();

    // Initialize histogram synchronizer system. This is a singleton and is used
    // for posting tasks via NewRunnableMethod. Its deleted when it goes out of
    // scope. Even though NewRunnableMethod does AddRef and Release, the object
    // will not be deleted after the Task is executed.
    mHistogramSynchronizer= (new HistogramSynchronizer());

    browser::RegisterLocalState(g_browser_process->local_state());

    ProfileManager* profile_manager = browser_process->profile_manager();
    homedirpath = homedirpath.Append(profile_manager->GetCurrentProfileDir());
    {
        //std::cout << "Profile path: " << homedirpath.value() << std::endl;
        FilePath prefs_path (ProfileManager::GetProfilePrefsPath(homedirpath));
        FILE *fp = file_util::OpenFile(prefs_path, "a");
        file_util::CloseFile(fp);
        FilePath history_path (homedirpath);
        history_path = history_path.Append(chrome::kHistoryFilename);
        //std::cout << "  Profile exists: " << ProfileManager::IsProfile(homedirpath) << std::endl;
    }
    mProf = profile_manager->GetProfile(homedirpath, false);
    if (!mProf) {
        mProcessSingleton.reset();
        return false;
    }
    mProf->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, false);
    mProf->GetPrefs()->RegisterStringPref(prefs::kSafeBrowsingClientKey, "");
    mProf->GetPrefs()->RegisterStringPref(prefs::kSafeBrowsingWrappedKey, "");
    mProf->InitExtensions();

    PrefService* user_prefs = mProf->GetPrefs();
    DCHECK(user_prefs);

//    browser_process->local_state()->SetString(prefs::kApplicationLocale,std::wstring());
    mProcessSingleton->Create();

    mDNSPrefetch.reset(new chrome_browser_net::PredictorInit(
      user_prefs,
      browser_process->local_state(),
      CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePreconnect)));

    BrowserURLHandler::InitURLHandlers();

    // From chrome/browser/browser_main.cc
  // Register our global network handler for chrome:// and
  // chrome-extension:// URLs.
  ChromeURLDataManagerBackend::Register();
/*
  RegisterExtensionProtocols();
  RegisterMetadataURLRequestHandler();
  RegisterBlobURLRequestJobFactory();
  RegisterFileSystemURLRequestJobFactory();
*/


    {
        FilePath plugindata = homedirpath.AppendASCII("plugin_");
        if (!file_util::CreateDirectory(plugindata)) {
            return false;
        }
        PluginService::GetInstance()->SetChromePluginDataDir(plugindata);
    }
    PluginService::GetInstance()->LoadChromePlugins(
        g_browser_process->resource_dispatcher_host());

    mDefaultRequestContext=mProf->GetRequestContext();

    if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kRemoteDebuggingPort)) {
        std::string debugging_port_str =
            CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kRemoteDebuggingPort);
        int64 debugging_port = -1;
        bool has_debugging_port = base::StringToInt64(debugging_port_str, &debugging_port);
        if (has_debugging_port && debugging_port > 0 && debugging_port < 65535) {
            devtools_http_handler_ =
                Berkelium::DevToolsHttpProtocolHandler::Start(
                    "127.0.0.1",
                    static_cast<int>(debugging_port),
                    ""
                );
        }
    }

    return true;
}