OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 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 "chrome/browser/chromeos/lock_screen_apps/app_manager_impl.h" | |
6 | |
7 #include <memory> | |
8 #include <utility> | |
9 #include <vector> | |
10 | |
11 #include "apps/launcher.h" | |
12 #include "base/bind.h" | |
13 #include "base/files/file_path.h" | |
14 #include "base/memory/ptr_util.h" | |
15 #include "base/memory/ref_counted.h" | |
16 #include "base/strings/string16.h" | |
17 #include "chrome/browser/chromeos/note_taking_helper.h" | |
18 #include "chrome/browser/chromeos/profiles/profile_helper.h" | |
19 #include "chrome/browser/extensions/extension_service.h" | |
20 #include "chrome/common/pref_names.h" | |
21 #include "extensions/browser/extension_registry.h" | |
22 #include "extensions/browser/extension_system.h" | |
23 #include "extensions/common/api/app_runtime.h" | |
24 #include "extensions/common/extension.h" | |
25 #include "extensions/common/extension_set.h" | |
26 | |
27 namespace lock_screen_apps { | |
28 | |
29 AppManagerImpl::AppManagerImpl() : extensions_observer_(this) {} | |
30 | |
31 AppManagerImpl::~AppManagerImpl() = default; | |
32 | |
33 void AppManagerImpl::Initialize(Profile* primary_profile, | |
34 Profile* lock_screen_profile) { | |
35 DCHECK_EQ(State::kNotInitialized, state_); | |
36 DCHECK(primary_profile); | |
37 DCHECK(lock_screen_profile); | |
38 DCHECK_NE(primary_profile, lock_screen_profile); | |
39 | |
40 CHECK(!chromeos::ProfileHelper::Get()->GetUserByProfile(lock_screen_profile)) | |
41 << "Lock screen profile should not be associated with any users."; | |
42 | |
43 primary_profile_ = primary_profile; | |
44 lock_screen_profile_ = lock_screen_profile; | |
45 state_ = State::kIdle; | |
46 | |
47 pref_change_registrar_.Init(primary_profile->GetPrefs()); | |
48 pref_change_registrar_.Add( | |
49 prefs::kNoteTakingAppId, | |
50 base::Bind(&AppManagerImpl::OnNoteTakingExtensionChanged, | |
51 base::Unretained(this))); | |
52 pref_change_registrar_.Add( | |
53 prefs::kNoteTakingAppEnabledOnLockScreen, | |
54 base::Bind(&AppManagerImpl::OnNoteTakingExtensionChanged, | |
55 base::Unretained(this))); | |
56 } | |
57 | |
58 void AppManagerImpl::Start(AppManager::Observer* observer) { | |
59 observer_ = observer; | |
60 extensions_observer_.Add( | |
61 extensions::ExtensionRegistry::Get(primary_profile_)); | |
62 | |
63 if (state_ == State::kStarted) | |
64 return; | |
65 | |
66 lock_screen_app_id_.clear(); | |
67 std::string app_id = FindLockScreenNoteTakingApp(); | |
68 if (!app_id.empty() && AddAppToLockScreenProfile(app_id)) | |
69 lock_screen_app_id_ = app_id; | |
70 | |
71 state_ = State::kStarted; | |
72 } | |
73 | |
74 void AppManagerImpl::Stop() { | |
75 observer_ = nullptr; | |
76 extensions_observer_.RemoveAll(); | |
77 | |
78 if (state_ == State::kIdle) | |
79 return; | |
80 | |
81 UnloadLockApp(lock_screen_app_id_); | |
jdufault
2017/05/26 19:15:52
what if state_ == State::kNotInitialized?
tbarzic
2017/05/26 19:34:14
Done.
| |
82 lock_screen_app_id_.clear(); | |
83 state_ = State::kIdle; | |
84 } | |
85 | |
86 bool AppManagerImpl::IsNoteTakingAppAvailable() const { | |
87 return state_ == State::kStarted && !lock_screen_app_id_.empty(); | |
88 } | |
89 | |
90 std::string AppManagerImpl::GetNoteTakingAppId() const { | |
91 if (!IsNoteTakingAppAvailable()) | |
92 return std::string(); | |
93 return lock_screen_app_id_; | |
94 } | |
95 | |
96 bool AppManagerImpl::LaunchNoteTaking() { | |
97 if (!IsNoteTakingAppAvailable()) | |
98 return false; | |
99 | |
100 Profile* target_profile = lock_screen_profile_->GetOriginalProfile(); | |
101 const extensions::ExtensionRegistry* extension_registry = | |
102 extensions::ExtensionRegistry::Get(target_profile); | |
103 const extensions::Extension* app = extension_registry->GetExtensionById( | |
104 lock_screen_app_id_, extensions::ExtensionRegistry::ENABLED); | |
105 if (!app) | |
106 return false; | |
107 | |
108 auto action_data = | |
109 base::MakeUnique<extensions::api::app_runtime::ActionData>(); | |
110 action_data->action_type = | |
111 extensions::api::app_runtime::ActionType::ACTION_TYPE_NEW_NOTE; | |
112 apps::LaunchPlatformAppWithAction(target_profile, app, std::move(action_data), | |
113 base::FilePath()); | |
114 return true; | |
115 } | |
116 | |
117 void AppManagerImpl::OnExtensionLoaded(content::BrowserContext* browser_context, | |
118 const extensions::Extension* extension) { | |
119 if (extension->id() == | |
120 primary_profile_->GetPrefs()->GetString(prefs::kNoteTakingAppId)) { | |
121 OnNoteTakingExtensionChanged(); | |
122 } | |
123 } | |
124 | |
125 void AppManagerImpl::OnExtensionUnloaded( | |
126 content::BrowserContext* browser_context, | |
127 const extensions::Extension* extension, | |
128 extensions::UnloadedExtensionReason reason) { | |
129 if (extension->id() == lock_screen_app_id_) | |
130 OnNoteTakingExtensionChanged(); | |
131 } | |
132 | |
133 void AppManagerImpl::OnNoteTakingExtensionChanged() { | |
134 if (state_ != State::kStarted) | |
135 return; | |
136 std::string app_id = FindLockScreenNoteTakingApp(); | |
137 if (app_id == lock_screen_app_id_) | |
138 return; | |
139 | |
140 UnloadLockApp(lock_screen_app_id_); | |
141 lock_screen_app_id_.clear(); | |
142 | |
143 if (AddAppToLockScreenProfile(app_id)) | |
144 lock_screen_app_id_ = app_id; | |
145 | |
146 observer_->OnNoteTakingAvailabilityChanged(); | |
147 } | |
148 | |
149 std::string AppManagerImpl::FindLockScreenNoteTakingApp() const { | |
150 std::unique_ptr<chromeos::NoteTakingAppInfo> note_taking_app = | |
151 chromeos::NoteTakingHelper::Get()->GetPreferredChromeAppInfo( | |
152 primary_profile_); | |
153 | |
154 if (!note_taking_app || | |
155 note_taking_app->lock_screen_support != | |
156 chromeos::NoteTakingLockScreenSupport::kSelected) { | |
157 return std::string(); | |
158 } | |
159 | |
160 return note_taking_app->app_id; | |
161 } | |
162 | |
163 bool AppManagerImpl::AddAppToLockScreenProfile(const std::string& app_id) { | |
164 extensions::ExtensionRegistry* primary_registry = | |
165 extensions::ExtensionRegistry::Get(primary_profile_); | |
166 const extensions::Extension* app = | |
167 primary_registry->enabled_extensions().GetByID(app_id); | |
168 if (!app) | |
169 return false; | |
170 | |
171 extensions::ExtensionRegistry* lock_screen_registry = | |
172 extensions::ExtensionRegistry::Get(lock_screen_profile_); | |
173 const extensions::Extension* lock_app = | |
174 lock_screen_registry->GetExtensionById( | |
175 app_id, extensions::ExtensionRegistry::EVERYTHING); | |
176 if (lock_app && !lock_app->runs_on_lock_screen()) { | |
177 LOG(ERROR) << "Non lock screen enabled app already installed in profile."; | |
178 return false; | |
179 } | |
180 | |
181 ExtensionService* lock_screen_service = | |
182 extensions::ExtensionSystem::Get(lock_screen_profile_) | |
183 ->extension_service(); | |
184 if (lock_app) { | |
185 lock_screen_service->UnloadExtension( | |
186 app_id, extensions::UnloadedExtensionReason::UNINSTALL); | |
187 } | |
188 | |
189 // TODO(tbarzic): Instead of loading the app from user profile path, consider | |
190 // copying and installing the app to the target profile. | |
191 std::string error; | |
192 scoped_refptr<extensions::Extension> lock_profile_app = | |
193 extensions::Extension::Create( | |
194 app->path(), app->location(), | |
195 *app->manifest()->value()->CreateDeepCopy(), | |
196 app->creation_flags() | extensions::Extension::RUNS_ON_LOCK_SCREEN, | |
197 app->id(), &error); | |
198 | |
199 if (!lock_profile_app) | |
200 return false; | |
201 | |
202 lock_screen_service->AddExtension(lock_profile_app.get()); | |
203 lock_screen_service->EnableExtension(lock_profile_app->id()); | |
204 return true; | |
205 } | |
206 | |
207 void AppManagerImpl::UnloadLockApp(const std::string& app_id) { | |
208 if (app_id.empty()) | |
209 return; | |
210 | |
211 extensions::ExtensionRegistry* lock_screen_registry = | |
212 extensions::ExtensionRegistry::Get(lock_screen_profile_); | |
213 const extensions::Extension* lock_app = | |
214 lock_screen_registry->GetExtensionById( | |
215 app_id, extensions::ExtensionRegistry::EVERYTHING); | |
216 if (!lock_app) | |
217 return; | |
218 | |
219 extensions::ExtensionSystem::Get(lock_screen_profile_) | |
220 ->extension_service() | |
221 ->UnloadExtension(app_id, extensions::UnloadedExtensionReason::UNINSTALL); | |
222 } | |
223 | |
224 } // namespace lock_screen_apps | |
OLD | NEW |