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

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/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::kInactive;
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 DCHECK_NE(State::kNotInitialized, state_);
60
61 observer_ = observer;
62 extensions_observer_.Add(
63 extensions::ExtensionRegistry::Get(primary_profile_));
64
65 if (state_ == State::kActive)
66 return;
67
68 lock_screen_app_id_.clear();
69 std::string app_id = FindLockScreenNoteTakingApp();
70 if (!app_id.empty() && AddAppToLockScreenProfile(app_id))
71 lock_screen_app_id_ = app_id;
72
73 state_ = State::kActive;
74 }
75
76 void AppManagerImpl::Stop() {
77 DCHECK_NE(State::kNotInitialized, state_);
78
79 observer_ = nullptr;
80 extensions_observer_.RemoveAll();
81
82 if (state_ == State::kInactive)
83 return;
84
85 UnloadLockApp(lock_screen_app_id_);
86 lock_screen_app_id_.clear();
87 state_ = State::kInactive;
88 }
89
90 bool AppManagerImpl::IsNoteTakingAppAvailable() const {
91 return state_ == State::kActive && !lock_screen_app_id_.empty();
92 }
93
94 std::string AppManagerImpl::GetNoteTakingAppId() const {
95 if (!IsNoteTakingAppAvailable())
96 return std::string();
97 return lock_screen_app_id_;
98 }
99
100 bool AppManagerImpl::LaunchNoteTaking() {
101 if (!IsNoteTakingAppAvailable())
102 return false;
103
104 Profile* target_profile = lock_screen_profile_->GetOriginalProfile();
105 const extensions::ExtensionRegistry* extension_registry =
106 extensions::ExtensionRegistry::Get(target_profile);
107 const extensions::Extension* app = extension_registry->GetExtensionById(
108 lock_screen_app_id_, extensions::ExtensionRegistry::ENABLED);
109 if (!app)
110 return false;
111
112 auto action_data =
113 base::MakeUnique<extensions::api::app_runtime::ActionData>();
114 action_data->action_type =
115 extensions::api::app_runtime::ActionType::ACTION_TYPE_NEW_NOTE;
116 apps::LaunchPlatformAppWithAction(target_profile, app, std::move(action_data),
117 base::FilePath());
118 return true;
119 }
120
121 void AppManagerImpl::OnExtensionLoaded(content::BrowserContext* browser_context,
122 const extensions::Extension* extension) {
123 if (extension->id() ==
124 primary_profile_->GetPrefs()->GetString(prefs::kNoteTakingAppId)) {
125 OnNoteTakingExtensionChanged();
126 }
127 }
128
129 void AppManagerImpl::OnExtensionUnloaded(
130 content::BrowserContext* browser_context,
131 const extensions::Extension* extension,
132 extensions::UnloadedExtensionReason reason) {
133 if (extension->id() == lock_screen_app_id_)
134 OnNoteTakingExtensionChanged();
135 }
136
137 void AppManagerImpl::OnNoteTakingExtensionChanged() {
138 if (state_ != State::kActive)
139 return;
140 std::string app_id = FindLockScreenNoteTakingApp();
141 if (app_id == lock_screen_app_id_)
142 return;
143
144 UnloadLockApp(lock_screen_app_id_);
145 lock_screen_app_id_.clear();
146
147 if (AddAppToLockScreenProfile(app_id))
148 lock_screen_app_id_ = app_id;
149
150 observer_->OnNoteTakingAvailabilityChanged();
151 }
152
153 std::string AppManagerImpl::FindLockScreenNoteTakingApp() const {
154 // Note that lock screen does not currently support Android apps, so
155 // it's enough to only check the state of the preferred Chrome app.
156 std::unique_ptr<chromeos::NoteTakingAppInfo> note_taking_app =
157 chromeos::NoteTakingHelper::Get()->GetPreferredChromeAppInfo(
158 primary_profile_);
159
160 if (!note_taking_app ||
161 note_taking_app->lock_screen_support !=
162 chromeos::NoteTakingLockScreenSupport::kSelected) {
163 return std::string();
164 }
165
166 return note_taking_app->app_id;
167 }
168
169 bool AppManagerImpl::AddAppToLockScreenProfile(const std::string& app_id) {
170 extensions::ExtensionRegistry* primary_registry =
171 extensions::ExtensionRegistry::Get(primary_profile_);
172 const extensions::Extension* app =
173 primary_registry->enabled_extensions().GetByID(app_id);
174 if (!app)
175 return false;
176
177 extensions::ExtensionRegistry* lock_screen_registry =
178 extensions::ExtensionRegistry::Get(lock_screen_profile_);
179 const extensions::Extension* lock_app =
180 lock_screen_registry->GetExtensionById(
181 app_id, extensions::ExtensionRegistry::EVERYTHING);
182 if (lock_app && !lock_app->runs_on_lock_screen()) {
183 LOG(ERROR) << "Non lock screen enabled app already installed in profile.";
184 return false;
185 }
186
187 ExtensionService* lock_screen_service =
188 extensions::ExtensionSystem::Get(lock_screen_profile_)
189 ->extension_service();
190 if (lock_app) {
191 lock_screen_service->UnloadExtension(
192 app_id, extensions::UnloadedExtensionReason::UNINSTALL);
193 }
194
195 // TODO(tbarzic): Instead of loading the app from user profile path, consider
196 // copying and installing the app to the target profile.
197 std::string error;
198 scoped_refptr<extensions::Extension> lock_profile_app =
199 extensions::Extension::Create(
200 app->path(), app->location(),
201 *app->manifest()->value()->CreateDeepCopy(),
202 app->creation_flags() | extensions::Extension::RUNS_ON_LOCK_SCREEN,
203 app->id(), &error);
204
205 if (!lock_profile_app)
206 return false;
207
208 lock_screen_service->AddExtension(lock_profile_app.get());
209 lock_screen_service->EnableExtension(lock_profile_app->id());
210 return true;
211 }
212
213 void AppManagerImpl::UnloadLockApp(const std::string& app_id) {
214 if (app_id.empty())
215 return;
216
217 extensions::ExtensionRegistry* lock_screen_registry =
218 extensions::ExtensionRegistry::Get(lock_screen_profile_);
219 const extensions::Extension* lock_app =
220 lock_screen_registry->GetExtensionById(
221 app_id, extensions::ExtensionRegistry::EVERYTHING);
222 if (!lock_app)
223 return;
224
225 extensions::ExtensionSystem::Get(lock_screen_profile_)
226 ->extension_service()
227 ->UnloadExtension(app_id, extensions::UnloadedExtensionReason::UNINSTALL);
228 }
229
230 } // namespace lock_screen_apps
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698