15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/common/service_process_util.h" 66d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sha1.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h" 236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/cloud_devices/common/cloud_devices_switches.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_paths.h" 256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "google_apis/gaia/gaia_switches.h" 266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "ui/base/ui_base_switches.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This should be more than enough to hold a version string assuming each part 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the version string is an int64. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint32 kMaxVersionStringLength = 256; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The structure that gets written to shared memory. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ServiceProcessSharedData { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char service_process_version[kMaxVersionStringLength]; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessId service_process_pid; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the name of the shared memory used by the service process to write its 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// version. The name is not versioned. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetServiceProcessSharedMemName() { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetServiceProcessScopedName("_service_shmem"); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ServiceProcessRunningState { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SERVICE_NOT_RUNNING, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SERVICE_OLDER_VERSION_RUNNING, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SERVICE_SAME_VERSION_RUNNING, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SERVICE_NEWER_VERSION_RUNNING, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceProcessRunningState GetServiceProcessRunningState( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* service_version_out, base::ProcessId* pid_out) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string version; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetServiceProcessData(&version, pid_out)) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_NOT_RUNNING; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only need to check for service running on POSIX because Windows cleans 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // up shared memory files when an app crashes, so there isn't a chance of 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // us reading bogus data from shared memory for an app that has died. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CheckServiceProcessReady()) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_NOT_RUNNING; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_POSIX) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this time we have a version string. Set the out param if it exists. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service_version_out) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *service_version_out = version; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version service_version(version); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the version string is invalid, treat it like an older version. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!service_version.IsValid()) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_OLDER_VERSION_RUNNING; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the version of the currently *running* instance of Chrome. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::VersionInfo version_info; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!version_info.is_valid()) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Failed to get current file version"; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our own version is invalid. This is an error case. Pretend that we 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are out of date. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_NEWER_VERSION_RUNNING; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version running_version(version_info.Version()); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!running_version.IsValid()) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Failed to parse version info"; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our own version is invalid. This is an error case. Pretend that we 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are out of date. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_NEWER_VERSION_RUNNING; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (running_version.CompareTo(service_version) > 0) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_OLDER_VERSION_RUNNING; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (service_version.CompareTo(running_version) > 0) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_NEWER_VERSION_RUNNING; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SERVICE_SAME_VERSION_RUNNING; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return a name that is scoped to this instance of the service process. We 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// use the hash of the user-data-dir as a scoping prefix. We can't use 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the user-data-dir itself as we have limits on the size of the lock names. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetServiceProcessScopedName(const std::string& append_str) { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath user_data_dir; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string user_data_dir_path = base::WideToUTF8(user_data_dir.value()); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string user_data_dir_path = user_data_dir.value(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_WIN) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string hash = base::SHA1HashString(user_data_dir_path); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string hex_hash = base::HexEncode(hash.c_str(), hash.length()); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hex_hash + "." + append_str; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return a name that is scoped to this instance of the service process. We 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// use the user-data-dir and the version as a scoping prefix. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetServiceProcessScopedVersionedName( 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& append_str) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string versioned_str; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::VersionInfo version_info; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(version_info.is_valid()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) versioned_str.append(version_info.Version()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) versioned_str.append(append_str); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetServiceProcessScopedName(versioned_str); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reads the named shared memory to get the shared data. Returns false if no 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// matching shared memory was found. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetServiceProcessData(std::string* version, base::ProcessId* pid) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::SharedMemory> shared_mem_service_data; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data.reset(new base::SharedMemory()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceProcessSharedData* service_data = NULL; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shared_mem_service_data.get() && 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data->Open(GetServiceProcessSharedMemName(), true) && 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data->Map(sizeof(ServiceProcessSharedData))) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_data = reinterpret_cast<ServiceProcessSharedData*>( 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data->memory()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the version in shared memory is null-terminated. If it is not, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // treat it as invalid. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version && memchr(service_data->service_process_version, '\0', 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(service_data->service_process_version))) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *version = service_data->service_process_version; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pid) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pid = service_data->service_process_pid; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !OS_MACOSX 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)scoped_ptr<base::CommandLine> CreateServiceProcessCommandLine() { 1596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::FilePath exe_path; 1606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) PathService::Get(content::CHILD_PROCESS_EXE, &exe_path); 1616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(!exe_path.empty()) << "Unable to get service process binary name."; 1626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<base::CommandLine> command_line(new base::CommandLine(exe_path)); 1636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) command_line->AppendSwitchASCII(switches::kProcessType, 1646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kServiceProcess); 1656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) static const char* const kSwitchesToCopy[] = { 1666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kCloudPrintSetupProxy, 1676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kCloudPrintURL, 1686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kCloudPrintXmppEndpoint, 1696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_WIN) 1706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kEnableCloudPrintXps, 1716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif 1726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kEnableLogging, 1736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kIgnoreUrlFetcherCertRequests, 1746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kLang, 1756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kLoggingLevel, 1766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kLsoUrl, 1776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kNoServiceAutorun, 1786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kUserDataDir, 1796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kV, 1806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kVModule, 1816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switches::kWaitForDebugger, 1826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) }; 1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(), 1856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) kSwitchesToCopy, 1866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) arraysize(kSwitchesToCopy)); 1876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return command_line.Pass(); 1886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 1896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceProcessState::ServiceProcessState() : state_(NULL) { 1916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) autorun_command_line_ = CreateServiceProcessCommandLine(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateState(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceProcessState::~ServiceProcessState() { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shared_mem_service_data_.get()) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data_->Delete(GetServiceProcessSharedMemName()); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !OS_MACOSX 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TearDownState(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServiceProcessState::SignalStopped() { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TearDownState(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data_.reset(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ServiceProcessState::Initialize() { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!TakeSingletonLock()) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now that we have the singleton, take care of killing an older version, if 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it exists. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HandleOtherVersion()) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the version we are using to shared memory. This can be used by a 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // newer service to signal us to exit. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateSharedData(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ServiceProcessState::HandleOtherVersion() { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string running_version; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessId process_id = 0; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceProcessRunningState state = 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetServiceProcessRunningState(&running_version, &process_id); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SERVICE_SAME_VERSION_RUNNING: 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SERVICE_NEWER_VERSION_RUNNING: 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SERVICE_OLDER_VERSION_RUNNING: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If an older version is running, kill it. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForceServiceProcessShutdown(running_version, process_id); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SERVICE_NOT_RUNNING: 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ServiceProcessState::CreateSharedData() { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::VersionInfo version_info; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!version_info.is_valid()) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Failed to get current file version"; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version_info.Version().length() >= kMaxVersionStringLength) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Version string length is << " << 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_info.Version().length() << "which is longer than" << 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMaxVersionStringLength; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::SharedMemory> shared_mem_service_data( 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new base::SharedMemory()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shared_mem_service_data.get()) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 alloc_size = sizeof(ServiceProcessSharedData); 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(viettrungluu): Named shared memory is deprecated (crbug.com/345734). 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!shared_mem_service_data->CreateNamedDeprecated 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (GetServiceProcessSharedMemName(), true, alloc_size)) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shared_mem_service_data->Map(alloc_size)) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(shared_mem_service_data->memory(), 0, alloc_size); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceProcessSharedData* shared_data = 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<ServiceProcessSharedData*>( 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data->memory()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(shared_data->service_process_version, version_info.Version().c_str(), 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_info.Version().length()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_data->service_process_pid = base::GetCurrentProcId(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_mem_service_data_.reset(shared_mem_service_data.release()); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC::ChannelHandle ServiceProcessState::GetServiceProcessChannel() { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::GetServiceProcessChannel(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !OS_MACOSX 286