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

Side by Side Diff: chrome/browser/chromeos/lock_screen_apps/app_manager_impl.cc

Issue 2902293002: Introduce lock screen app manager (Closed)
Patch Set: . Created 3 years, 6 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
OLDNEW
(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/browser/install_flag.h"
24 #include "extensions/common/api/app_runtime.h"
25 #include "extensions/common/extension.h"
26 #include "extensions/common/extension_set.h"
27
28 namespace lock_screen_apps {
29
30 AppManagerImpl::AppManagerImpl() : extensions_observer_(this) {}
31
32 AppManagerImpl::~AppManagerImpl() = default;
33
34 void AppManagerImpl::Initialize(Profile* primary_profile,
35 Profile* lock_screen_profile) {
36 DCHECK_EQ(State::kNotInitialized, state_);
37 DCHECK(primary_profile);
38 DCHECK(lock_screen_profile);
39 DCHECK_NE(primary_profile, lock_screen_profile);
Devlin 2017/06/05 16:09:35 Is there any defined relation between primary and
tbarzic 2017/06/06 01:54:55 Not really. GetOriginalProfile would return the si
40
41 CHECK(!chromeos::ProfileHelper::Get()->GetUserByProfile(lock_screen_profile))
42 << "Lock screen profile should not be associated with any users.";
43
44 primary_profile_ = primary_profile;
45 lock_screen_profile_ = lock_screen_profile;
46 state_ = State::kInactive;
47
48 pref_change_registrar_.Init(primary_profile->GetPrefs());
49 pref_change_registrar_.Add(
50 prefs::kNoteTakingAppId,
51 base::Bind(&AppManagerImpl::OnNoteTakingExtensionChanged,
52 base::Unretained(this)));
53 pref_change_registrar_.Add(
54 prefs::kNoteTakingAppEnabledOnLockScreen,
55 base::Bind(&AppManagerImpl::OnNoteTakingExtensionChanged,
56 base::Unretained(this)));
57 }
58
59 void AppManagerImpl::Start(const base::Closure& note_taking_changed_callback) {
60 DCHECK_NE(State::kNotInitialized, state_);
61
62 note_taking_changed_callback_ = note_taking_changed_callback;
63 extensions_observer_.Add(
64 extensions::ExtensionRegistry::Get(primary_profile_));
65
66 if (state_ == State::kActive)
67 return;
68
69 lock_screen_app_id_.clear();
70 std::string app_id = FindLockScreenNoteTakingApp();
71 if (!app_id.empty() && AddAppToLockScreenProfile(app_id))
72 lock_screen_app_id_ = app_id;
73
74 state_ = State::kActive;
75 }
76
77 void AppManagerImpl::Stop() {
78 DCHECK_NE(State::kNotInitialized, state_);
79
80 note_taking_changed_callback_.Reset();
81 extensions_observer_.RemoveAll();
Devlin 2017/06/05 16:09:35 Is the ExtensionRegistry guaranteed to outlive thi
tbarzic 2017/06/06 01:54:55 yes, this is owned by StateController, which is de
82
83 if (state_ == State::kInactive)
84 return;
85
86 UnloadLockApp(lock_screen_app_id_);
87 lock_screen_app_id_.clear();
88 state_ = State::kInactive;
89 }
90
91 bool AppManagerImpl::IsNoteTakingAppAvailable() const {
92 return state_ == State::kActive && !lock_screen_app_id_.empty();
93 }
94
95 std::string AppManagerImpl::GetNoteTakingAppId() const {
96 if (!IsNoteTakingAppAvailable())
97 return std::string();
98 return lock_screen_app_id_;
99 }
100
101 bool AppManagerImpl::LaunchNoteTaking() {
102 if (!IsNoteTakingAppAvailable())
103 return false;
104
105 Profile* target_profile = lock_screen_profile_->GetOriginalProfile();
Devlin 2017/06/05 16:09:35 can we somewhere explain target, lockscreen, and p
tbarzic 2017/06/06 01:54:55 Documentation for AppManager::Initialize has some
106 const extensions::ExtensionRegistry* extension_registry =
107 extensions::ExtensionRegistry::Get(target_profile);
108 const extensions::Extension* app = extension_registry->GetExtensionById(
109 lock_screen_app_id_, extensions::ExtensionRegistry::ENABLED);
110 if (!app)
111 return false;
112
113 auto action_data =
114 base::MakeUnique<extensions::api::app_runtime::ActionData>();
115 action_data->action_type =
116 extensions::api::app_runtime::ActionType::ACTION_TYPE_NEW_NOTE;
117 apps::LaunchPlatformAppWithAction(target_profile, app, std::move(action_data),
118 base::FilePath());
119 return true;
120 }
121
122 void AppManagerImpl::OnExtensionLoaded(content::BrowserContext* browser_context,
123 const extensions::Extension* extension) {
124 if (extension->id() ==
125 primary_profile_->GetPrefs()->GetString(prefs::kNoteTakingAppId)) {
126 OnNoteTakingExtensionChanged();
127 }
128 }
129
130 void AppManagerImpl::OnExtensionUnloaded(
131 content::BrowserContext* browser_context,
132 const extensions::Extension* extension,
133 extensions::UnloadedExtensionReason reason) {
134 if (extension->id() == lock_screen_app_id_)
135 OnNoteTakingExtensionChanged();
136 }
137
138 void AppManagerImpl::OnNoteTakingExtensionChanged() {
139 if (state_ != State::kActive)
140 return;
141 std::string app_id = FindLockScreenNoteTakingApp();
142 if (app_id == lock_screen_app_id_)
143 return;
144
145 UnloadLockApp(lock_screen_app_id_);
146 lock_screen_app_id_.clear();
147
148 if (AddAppToLockScreenProfile(app_id))
149 lock_screen_app_id_ = app_id;
150
151 if (!note_taking_changed_callback_.is_null())
152 note_taking_changed_callback_.Run();
153 }
154
155 std::string AppManagerImpl::FindLockScreenNoteTakingApp() const {
156 // Note that lock screen does not currently support Android apps, so
157 // it's enough to only check the state of the preferred Chrome app.
158 std::unique_ptr<chromeos::NoteTakingAppInfo> note_taking_app =
159 chromeos::NoteTakingHelper::Get()->GetPreferredChromeAppInfo(
160 primary_profile_);
161
162 if (!note_taking_app ||
163 note_taking_app->lock_screen_support !=
164 chromeos::NoteTakingLockScreenSupport::kSelected) {
165 return std::string();
166 }
167
168 return note_taking_app->app_id;
169 }
170
171 bool AppManagerImpl::AddAppToLockScreenProfile(const std::string& app_id) {
172 extensions::ExtensionRegistry* primary_registry =
173 extensions::ExtensionRegistry::Get(primary_profile_);
174 const extensions::Extension* app =
175 primary_registry->enabled_extensions().GetByID(app_id);
176 if (!app)
177 return false;
178
179 ExtensionService* lock_screen_service =
180 extensions::ExtensionSystem::Get(lock_screen_profile_)
181 ->extension_service();
182
183 // If the app is already installed, remove it.
184 extensions::ExtensionRegistry* lock_screen_registry =
185 extensions::ExtensionRegistry::Get(lock_screen_profile_);
186 if (lock_screen_registry->GetExtensionById(
187 app_id, extensions::ExtensionRegistry::EVERYTHING)) {
188 ExtensionService::UninstallExtensionHelper(
Devlin 2017/06/05 16:09:35 nit: prefer just using ExtensionService::Uninstall
tbarzic 2017/06/06 01:54:55 Done.
189 lock_screen_service, app_id,
190 extensions::UNINSTALL_REASON_INTERNAL_MANAGEMENT);
191 }
192
193 // TODO(tbarzic): Instead of loading the app from user profile path, consider
194 // copying and installing the app to the target profile.
Devlin 2017/06/05 16:09:35 Yeah, this strikes me as very strange. What happe
tbarzic 2017/06/06 01:54:55 Yeah, I have not yet completely figured out the be
Devlin 2017/06/09 18:18:40 Out of curiosity, is there a reason to not write t
tbarzic 2017/06/09 19:01:45 One reason is time - I do plan to look more closel
Devlin 2017/06/12 18:31:45 I talked with kerrnel@ about this, and we both agr
rkc 2017/06/13 21:18:17 We've had this discussion in many different forms
195 std::string error;
196 scoped_refptr<extensions::Extension> lock_profile_app =
197 extensions::Extension::Create(app->path(), app->location(),
198 *app->manifest()->value()->CreateDeepCopy(),
199 app->creation_flags(), app->id(), &error);
200
201 if (!lock_profile_app)
202 return false;
203
204 lock_screen_service->OnExtensionInstalled(
205 lock_profile_app.get(), syncer::StringOrdinal(),
206 extensions::kInstallFlagInstallImmediately);
207 lock_screen_service->EnableExtension(lock_profile_app->id());
208 return true;
209 }
210
211 void AppManagerImpl::UnloadLockApp(const std::string& app_id) {
Devlin 2017/06/05 16:09:35 s/Lock/LockScreen?
tbarzic 2017/06/06 01:54:55 Done.
212 if (app_id.empty())
213 return;
214
215 extensions::ExtensionRegistry* lock_screen_registry =
216 extensions::ExtensionRegistry::Get(lock_screen_profile_);
217 if (!lock_screen_registry->GetExtensionById(
218 app_id, extensions::ExtensionRegistry::EVERYTHING)) {
219 return;
220 }
221
222 ExtensionService::UninstallExtensionHelper(
Devlin 2017/06/05 16:09:34 This is pretty strange in combination with using t
Devlin 2017/06/05 16:09:34 Do we unload it, or uninstall it? The two are not
tbarzic 2017/06/06 01:54:55 Closer to uninstall (though, the initial version o
223 extensions::ExtensionSystem::Get(lock_screen_profile_)
224 ->extension_service(),
225 app_id, extensions::UNINSTALL_REASON_INTERNAL_MANAGEMENT);
226 }
227
228 } // namespace lock_screen_apps
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698