OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "apps/app_shim/app_shim_host.h" | |
6 | |
7 #include "apps/app_shim/app_shim_messages.h" | |
8 #include "base/bind.h" | |
9 #include "base/files/file_path.h" | |
10 #include "base/logging.h" | |
11 #include "chrome/browser/browser_process.h" | |
12 #include "chrome/browser/extensions/extension_host.h" | |
13 #include "chrome/browser/extensions/extension_service.h" | |
14 #include "chrome/browser/extensions/extension_system.h" | |
15 #include "chrome/browser/extensions/shell_window_registry.h" | |
16 #include "chrome/browser/profiles/profile_manager.h" | |
17 #include "chrome/browser/ui/extensions/application_launch.h" | |
18 #include "chrome/common/extensions/extension_constants.h" | |
19 #include "ipc/ipc_channel_proxy.h" | |
20 | |
21 AppShimHost::AppShimHost() | |
22 : channel_(NULL), profile_(NULL) { | |
23 } | |
24 | |
25 AppShimHost::~AppShimHost() { | |
26 DCHECK(CalledOnValidThread()); | |
27 if (channel_) | |
28 delete channel_; | |
koz (OOO until 15th September)
2013/03/14 23:51:05
scoped_ptr<> to hold channel_?
jeremya
2013/03/15 02:24:14
Done.
| |
29 } | |
30 | |
31 void AppShimHost::ServeChannel(const IPC::ChannelHandle& handle) { | |
32 DCHECK(CalledOnValidThread()); | |
33 channel_ = new IPC::ChannelProxy(handle, IPC::Channel::MODE_SERVER, this, | |
koz (OOO until 15th September)
2013/03/14 23:51:05
Is this method intended to be called multiple time
jeremya
2013/03/15 02:24:14
Nope. Done.
| |
34 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); | |
35 } | |
36 | |
37 bool AppShimHost::OnMessageReceived(const IPC::Message& message) { | |
38 DCHECK(CalledOnValidThread()); | |
39 bool handled = true; | |
40 IPC_BEGIN_MESSAGE_MAP(AppShimHost, message) | |
41 IPC_MESSAGE_HANDLER(AppShimHostMsg_LaunchApp, OnLaunchApp) | |
42 IPC_MESSAGE_UNHANDLED(handled = false) | |
43 IPC_END_MESSAGE_MAP() | |
44 | |
45 return handled; | |
46 } | |
47 | |
48 bool AppShimHost::Send(IPC::Message* message) { | |
49 DCHECK(channel_); | |
50 return channel_->Send(message); | |
51 } | |
52 | |
53 void AppShimHost::OnLaunchApp(std::string profile_dir, std::string app_id) { | |
54 DCHECK(CalledOnValidThread()); | |
55 bool success = LaunchAppImpl(profile_dir, app_id); | |
56 Send(new AppShimMsg_LaunchApp_Done(success)); | |
palmer
2013/03/14 19:05:04
Please pardon my ignorance: How is this new object
jeremya
2013/03/14 23:33:01
From ipc/ipc_sender.h:
// Sends the given IPC me
| |
57 } | |
58 | |
59 bool AppShimHost::LaunchAppImpl(const std::string& profile_dir, | |
60 const std::string& app_id) { | |
61 DCHECK(CalledOnValidThread()); | |
62 if (profile_) { | |
63 // Only one app launch message per channel. | |
64 return false; | |
65 } | |
66 if (!extensions::Extension::IdIsValid(app_id)) { | |
67 LOG(ERROR) << "Bad app ID from app shim launch message."; | |
68 return false; | |
69 } | |
70 Profile* profile = FetchProfileForDirectory(profile_dir); | |
71 if (!profile) | |
72 return false; | |
73 | |
74 if (!LaunchApp(profile, app_id)) | |
75 return false; | |
76 | |
77 profile_ = profile; | |
78 app_id_ = app_id; | |
79 | |
80 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | |
81 content::Source<Profile>(profile_)); | |
82 return true; | |
83 } | |
84 | |
85 Profile* AppShimHost::FetchProfileForDirectory(const std::string& profile_dir) { | |
86 ProfileManager* profileManager = g_browser_process->profile_manager(); | |
87 base::FilePath path(profile_dir); | |
palmer
2013/03/14 19:05:04
Can we therefore have |pfile_dir| originate as a F
jeremya
2013/03/14 23:33:01
Not sure if base::FilePaths can be serialized over
| |
88 path = profileManager->user_data_dir().Append(path); | |
89 ProfileInfoCache& cache = profileManager->GetProfileInfoCache(); | |
90 if (cache.GetIndexOfProfileWithPath(path) == std::string::npos) { | |
palmer
2013/03/14 19:05:04
So this line is the true security check? Is it wor
jeremya
2013/03/14 23:33:01
Done.
| |
91 LOG(ERROR) << "Requested directory is not a known profile."; | |
92 return NULL; | |
93 } | |
94 Profile* profile = profileManager->GetProfile(path); | |
palmer
2013/03/14 19:05:04
Is this kind of the same thing, effectively, as th
jeremya
2013/03/14 23:33:01
The ProfileInfoCache stores info about the profile
| |
95 if (!profile) { | |
96 LOG(ERROR) << "Couldn't get profile for directory '" << profile_dir << "'."; | |
97 return NULL; | |
98 } | |
99 return profile; | |
100 } | |
101 | |
102 bool AppShimHost::LaunchApp(Profile* profile, const std::string& app_id) { | |
103 extensions::ExtensionSystem* extension_system = | |
104 extensions::ExtensionSystem::Get(profile); | |
105 ExtensionServiceInterface* extension_service = | |
106 extension_system->extension_service(); | |
107 const extensions::Extension* extension = | |
108 extension_service->GetExtensionById( | |
109 app_id, false); | |
110 if (!extension) { | |
111 LOG(ERROR) << "Attempted to launch nonexistent app with id '" | |
112 << app_id << "'."; | |
113 return false; | |
114 } | |
115 // TODO(jeremya): Handle the case that launching the app fails. Probably we | |
116 // need to watch for 'app successfully launched' or at least 'background page | |
117 // exists/was created' and time out with failure if we don't see that sign of | |
118 // life within a certain window. | |
119 chrome::AppLaunchParams params(profile, | |
120 extension, | |
121 extension_misc::LAUNCH_NONE, | |
122 NEW_WINDOW); | |
123 chrome::OpenApplication(params); | |
124 return true; | |
125 } | |
126 | |
127 void AppShimHost::Observe(int type, | |
128 const content::NotificationSource& source, | |
129 const content::NotificationDetails& details) { | |
130 DCHECK(CalledOnValidThread()); | |
131 DCHECK(content::Source<Profile>(source).ptr() == profile_); | |
132 switch (type) { | |
133 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { | |
134 extensions::ExtensionHost* extension_host = | |
135 content::Details<extensions::ExtensionHost>(details).ptr(); | |
136 if (app_id_ == extension_host->extension_id()) | |
137 Close(); | |
138 break; | |
139 } | |
140 default: | |
141 NOTREACHED() << "Unexpected notification sent."; | |
142 break; | |
143 } | |
144 } | |
145 | |
146 void AppShimHost::Close() { | |
147 DCHECK(CalledOnValidThread()); | |
148 delete this; | |
149 } | |
OLD | NEW |