Commit 668c5c10 authored by tengs's avatar tengs Committed by Commit bot

Unload Easy Unlock app when ChromeOS suspends and reload on wake up.

When the system wakes up, it takes a few seconds for the correct
Bluetooth state to propogate to the app. A bad sync state allows
the lock screen to be unlocked even though the phone is not connected
in reality.

BUG=410082
TEST=manual

Review URL: https://codereview.chromium.org/528423002

Cr-Commit-Position: refs/heads/master@{#294104}
parent 227733e3
......@@ -26,12 +26,15 @@
#include "components/pref_registry/pref_registry_syncable.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/one_shot_event.h"
#include "grit/browser_resources.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager_client.h"
#include "components/user_manager/user_manager.h"
#endif
......@@ -106,6 +109,37 @@ class EasyUnlockService::BluetoothDetector
DISALLOW_COPY_AND_ASSIGN(BluetoothDetector);
};
#if defined(OS_CHROMEOS)
class EasyUnlockService::PowerMonitor :
public chromeos::PowerManagerClient::Observer {
public:
explicit PowerMonitor(EasyUnlockService* service) : service_(service) {
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
AddObserver(this);
}
virtual ~PowerMonitor() {
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
RemoveObserver(this);
}
private:
// chromeos::PowerManagerClient::Observer:
virtual void SuspendImminent() OVERRIDE {
service_->DisableApp();
service_->screenlock_state_handler_.reset();
}
virtual void SuspendDone(const base::TimeDelta& sleep_duration) OVERRIDE {
service_->LoadApp();
}
EasyUnlockService* service_;
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
};
#endif
EasyUnlockService::EasyUnlockService(Profile* profile)
: profile_(profile),
bluetooth_detector_(new BluetoothDetector(this)),
......@@ -319,26 +353,56 @@ void EasyUnlockService::LoadApp() {
if (!easy_unlock_path.empty()) {
extensions::ComponentLoader* loader = GetComponentLoader(profile_);
if (!loader->Exists(extension_misc::kEasyUnlockAppId))
if (!loader->Exists(extension_misc::kEasyUnlockAppId)) {
loader->Add(IDR_EASY_UNLOCK_MANIFEST, easy_unlock_path);
} else {
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(profile_);
// If the app is installed but disabled, then enable it.
if (registry->GetExtensionById(extension_misc::kEasyUnlockAppId,
extensions::ExtensionRegistry::DISABLED)) {
ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile_)->extension_service();
extension_service->EnableExtension(extension_misc::kEasyUnlockAppId);
}
}
}
#endif // defined(GOOGLE_CHROME_BUILD)
}
void EasyUnlockService::UnloadApp() {
void EasyUnlockService::DisableApp() {
extensions::ComponentLoader* loader = GetComponentLoader(profile_);
if (loader->Exists(extension_misc::kEasyUnlockAppId))
loader->Remove(extension_misc::kEasyUnlockAppId);
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(profile_);
if (loader->Exists(extension_misc::kEasyUnlockAppId) &&
registry->GetExtensionById(extension_misc::kEasyUnlockAppId,
extensions::ExtensionRegistry::ENABLED)) {
ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile_)->extension_service();
extension_service->DisableExtension(extension_misc::kEasyUnlockAppId,
extensions::Extension::DISABLE_RELOAD);
}
}
void EasyUnlockService::UpdateAppState() {
if (IsAllowed()) {
LoadApp();
#if defined(OS_CHROMEOS)
if (!power_monitor_)
power_monitor_.reset(new PowerMonitor(this));
#endif
} else {
UnloadApp();
DisableApp();
// Reset the screenlock state handler to make sure Screenlock state set
// by Easy Unlock app is reset.
screenlock_state_handler_.reset();
#if defined(OS_CHROMEOS)
power_monitor_.reset();
#endif
}
}
......
......@@ -84,11 +84,12 @@ class EasyUnlockService : public KeyedService {
// Initializes the service after ExtensionService is ready.
void Initialize();
// Loads the Easy unlock component app.
// Installs the Easy unlock component app if it isn't installed or enables
// the app if it is installed but disabled.
void LoadApp();
// Unloads the Easy unlock component app.
void UnloadApp();
// Disables the Easy unlock component app.
void DisableApp();
// Checks whether Easy unlock should be running and updates app state.
void UpdateAppState();
......@@ -115,6 +116,12 @@ class EasyUnlockService : public KeyedService {
scoped_ptr<EasyUnlockToggleFlow> turn_off_flow_;
ObserverList<EasyUnlockServiceObserver> observers_;
#if defined(OS_CHROMEOS)
// Monitors suspend and wake state of ChromeOS.
class PowerMonitor;
scoped_ptr<PowerMonitor> power_monitor_;
#endif
base::WeakPtrFactory<EasyUnlockService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(EasyUnlockService);
......
......@@ -345,7 +345,7 @@ cr.define('login', function() {
this.hideTooltip_(true);
this.iconElement.classList.add('faded');
this.hideTransitionListener_ = this.hide_.bind(this);
this.hideTransitionListener_ = this.hide.bind(this);
this.iconElement.addEventListener('webkitTransitionEnd',
this.hideTransitionListener_);
ensureTransitionEndEvent(this.iconElement, 200);
......@@ -467,9 +467,8 @@ cr.define('login', function() {
/**
* Hides the icon. Makes sure the tooltip is hidden and animation reset.
* @private
*/
hide_: function() {
hide: function() {
this.hideTooltip_(true);
this.hidden = true;
this.setAnimation(null);
......@@ -2358,7 +2357,8 @@ cr.define('login', function() {
return;
}
pod.customIconElement.fadeOut();
// TODO(tengs): Allow option for a fading transition.
pod.customIconElement.hide();
},
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment