Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(649)

Side by Side Diff: apps/app_shim/app_shim_host_manager_mac.mm

Issue 66043003: Put app shim IPC socket in a temporary directory. (Mac) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use PathService(DIR_TEMP) instead of "/tmp" Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "apps/app_shim/app_shim_host_manager_mac.h" 5 #include "apps/app_shim/app_shim_host_manager_mac.h"
6 6
7 #include <unistd.h>
8
7 #include "apps/app_shim/app_shim_handler_mac.h" 9 #include "apps/app_shim/app_shim_handler_mac.h"
8 #include "apps/app_shim/app_shim_host_mac.h" 10 #include "apps/app_shim/app_shim_host_mac.h"
11 #include "base/base64.h"
9 #include "base/bind.h" 12 #include "base/bind.h"
10 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/file_util.h"
11 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
12 #include "base/logging.h" 16 #include "base/logging.h"
13 #include "base/path_service.h" 17 #include "base/path_service.h"
18 #include "base/sha1.h"
19 #include "base/strings/string_util.h"
14 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/browser_process.h"
15 #include "chrome/common/chrome_paths.h" 21 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/chrome_switches.h" 22 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/mac/app_mode_common.h" 23 #include "chrome/common/mac/app_mode_common.h"
18 #include "ipc/unix_domain_socket_util.h"
19 24
20 using content::BrowserThread; 25 using content::BrowserThread;
21 26
22 namespace { 27 namespace {
23 28
24 void CreateAppShimHost(const IPC::ChannelHandle& handle) { 29 void CreateAppShimHost(const IPC::ChannelHandle& handle) {
25 // AppShimHost takes ownership of itself. 30 // AppShimHost takes ownership of itself.
26 (new AppShimHost)->ServeChannel(handle); 31 (new AppShimHost)->ServeChannel(handle);
27 } 32 }
28 33
34 base::FilePath GetDirectoryInTmpTemplate(const base::FilePath& user_data_dir) {
35 base::FilePath temp_dir;
36 DCHECK(PathService::Get(base::DIR_TEMP, &temp_dir));
tapted 2014/01/31 07:04:12 DCHECK->CHECK
jackhou1 2014/01/31 07:19:21 Done.
37 // Check that it's shorter than the IPC socket length (104) minus the
38 // intermediate folder ("/XXXXXX/") and kAppShimSocketShortName.
39 DCHECK(temp_dir.value().length() < 90);
tapted 2014/01/31 07:04:12 nit: DCHECK_GT(90, ..) might be the preferred way
jackhou1 2014/01/31 07:19:21 Done.
40 return temp_dir.Append("XXXXXX");
tapted 2014/01/31 07:04:12 How many characters are spare with the lengths we'
jackhou1 2014/01/31 07:19:21 Done. There's around 40 spare characters.
41 }
42
43 void DeleteSocketFiles(const base::FilePath& directory_in_tmp,
44 const base::FilePath& symlink_path) {
45 if (!directory_in_tmp.empty())
46 base::DeleteFile(directory_in_tmp, true);
47 if (!symlink_path.empty())
48 base::DeleteFile(symlink_path, false);
49 }
50
29 } // namespace 51 } // namespace
30 52
31 const base::FilePath* AppShimHostManager::g_override_user_data_dir_ = NULL;
32
33 AppShimHostManager::AppShimHostManager() {} 53 AppShimHostManager::AppShimHostManager() {}
34 54
35 void AppShimHostManager::Init() { 55 void AppShimHostManager::Init() {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
37 apps::AppShimHandler::SetDefaultHandler(&extension_app_shim_handler_); 57 apps::AppShimHandler::SetDefaultHandler(&extension_app_shim_handler_);
38 BrowserThread::PostTask( 58 BrowserThread::PostTask(
39 BrowserThread::FILE, FROM_HERE, 59 BrowserThread::FILE, FROM_HERE,
40 base::Bind(&AppShimHostManager::InitOnFileThread, this)); 60 base::Bind(&AppShimHostManager::InitOnFileThread, this));
41 } 61 }
42 62
43 AppShimHostManager::~AppShimHostManager() { 63 AppShimHostManager::~AppShimHostManager() {
44 apps::AppShimHandler::SetDefaultHandler(NULL); 64 apps::AppShimHandler::SetDefaultHandler(NULL);
65 factory_.reset();
66 base::FilePath symlink_path;
67 if (PathService::Get(chrome::DIR_USER_DATA, &symlink_path))
68 symlink_path = symlink_path.Append(app_mode::kAppShimSocketSymlinkName);
69 BrowserThread::PostTask(
70 BrowserThread::FILE, FROM_HERE,
71 base::Bind(&DeleteSocketFiles, directory_in_tmp_, symlink_path));
45 } 72 }
46 73
47 void AppShimHostManager::InitOnFileThread() { 74 void AppShimHostManager::InitOnFileThread() {
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
49 base::FilePath user_data_dir; 76 base::FilePath user_data_dir;
50 if (g_override_user_data_dir_) { 77 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
51 user_data_dir = *g_override_user_data_dir_; 78 return;
52 } else if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { 79
53 LOG(ERROR) << "Couldn't get user data directory while creating App Shim " 80 // The socket path must be shorter than 104 chars (IPC::kMaxSocketNameLength).
54 << "Host manager."; 81 // To accommodate this, we use a short path in /tmp/ that is generated from a
82 // hash of the user data dir.
83 std::string directory_string =
84 GetDirectoryInTmpTemplate(user_data_dir).value();
85
86 // mkdtemp() replaces trailing X's randomly and creates the directory.
87 if (!mkdtemp(&directory_string[0])) {
88 PLOG(ERROR) << directory_string;
55 return; 89 return;
56 } 90 }
57 91
58 base::FilePath socket_path = 92 directory_in_tmp_ = base::FilePath(directory_string);
59 user_data_dir.Append(app_mode::kAppShimSocketName); 93 // Check that the directory was created with the correct permissions.
60 // This mirrors a check in unix_domain_socket_util.cc which will guarantee 94 int dir_mode = 0;
61 // failure and spam log files on bots because they have deeply nested paths to 95 if (!base::GetPosixFilePermissions(directory_in_tmp_, &dir_mode) ||
62 // |user_data_dir| when swarming. See http://crbug.com/240554. Shim tests that 96 dir_mode != base::FILE_PERMISSION_USER_MASK) {
63 // run on the bots must override the path using AppShimHostManagerTestApi. 97 NOTREACHED();
64 if (socket_path.value().length() >= IPC::kMaxSocketNameLength &&
65 CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) {
66 return; 98 return;
67 } 99 }
68 100
101 // IPC::ChannelFactory creates the socket immediately.
102 base::FilePath socket_path =
103 directory_in_tmp_.Append(app_mode::kAppShimSocketShortName);
69 factory_.reset(new IPC::ChannelFactory(socket_path, this)); 104 factory_.reset(new IPC::ChannelFactory(socket_path, this));
105
106 // Create a symlink to the socket in the user data dir. This lets the shim
107 // process started from Finder find the actual socket path by following the
108 // symlink with ::readlink().
109 base::FilePath symlink_path =
110 user_data_dir.Append(app_mode::kAppShimSocketSymlinkName);
111 base::DeleteFile(symlink_path, false);
112 base::CreateSymbolicLink(socket_path, symlink_path);
113
70 BrowserThread::PostTask( 114 BrowserThread::PostTask(
71 BrowserThread::IO, FROM_HERE, 115 BrowserThread::IO, FROM_HERE,
72 base::Bind(&AppShimHostManager::ListenOnIOThread, this)); 116 base::Bind(&AppShimHostManager::ListenOnIOThread, this));
73 } 117 }
74 118
75 void AppShimHostManager::ListenOnIOThread() { 119 void AppShimHostManager::ListenOnIOThread() {
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
77 if (!factory_->Listen()) { 121 if (!factory_->Listen()) {
78 BrowserThread::PostTask( 122 BrowserThread::PostTask(
79 BrowserThread::UI, FROM_HERE, 123 BrowserThread::UI, FROM_HERE,
80 base::Bind(&AppShimHostManager::OnListenError, this)); 124 base::Bind(&AppShimHostManager::OnListenError, this));
81 } 125 }
82 } 126 }
83 127
84 void AppShimHostManager::OnClientConnected( 128 void AppShimHostManager::OnClientConnected(
85 const IPC::ChannelHandle& handle) { 129 const IPC::ChannelHandle& handle) {
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
87 BrowserThread::PostTask( 131 BrowserThread::PostTask(
88 BrowserThread::UI, FROM_HERE, 132 BrowserThread::UI, FROM_HERE,
89 base::Bind(&CreateAppShimHost, handle)); 133 base::Bind(&CreateAppShimHost, handle));
90 } 134 }
91 135
92 void AppShimHostManager::OnListenError() { 136 void AppShimHostManager::OnListenError() {
93 // TODO(tapted): Set a timeout and attempt to reconstruct the channel. Until 137 // TODO(tapted): Set a timeout and attempt to reconstruct the channel. Until
94 // cases where the error could occur are better known, just reset the factory 138 // cases where the error could occur are better known, just reset the factory
95 // to allow failure to be communicated via the test API. 139 // to allow failure to be communicated via the test API.
96 factory_.reset(); 140 factory_.reset();
97 } 141 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698