Commit 9282f59b authored by pbond's avatar pbond Committed by Commit bot

arc: add enterprise_reporting.mojom interface.

This allows ARC to clear user data.

BUG=629574
TEST=manual

Review-Url: https://codereview.chromium.org/2165643004
Cr-Commit-Position: refs/heads/master@{#407771}
parent d03176d9
......@@ -208,7 +208,8 @@ void ArcAuthService::OnBridgeStopped(ArcBridgeService::StopReason reason) {
clear_required_ = false;
chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->RemoveArcData(
cryptohome::Identification(
multi_user_util::GetAccountIdFromProfile(profile_)));
multi_user_util::GetAccountIdFromProfile(profile_)),
chromeos::SessionManagerClient::ArcCallback());
}
std::string ArcAuthService::GetAndResetAuthCode() {
......
......@@ -175,6 +175,9 @@ class ArcAuthService : public ArcService,
void OnAndroidManagementChecked(
policy::AndroidManagementClient::Result result) override;
// Stops ARC without changing ArcEnabled preference.
void StopArc();
// Returns current page that has to be shown in OptIn UI.
UIPage ui_page() const { return ui_page_; }
......@@ -195,7 +198,6 @@ class ArcAuthService : public ArcService,
void StartAndroidManagementClient();
void CheckAndroidManagement(bool background_mode);
void StartArcIfSignedIn();
void StopArc();
// Unowned pointer. Keeps current profile.
Profile* profile_ = nullptr;
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/arc/arc_enterprise_reporting_service.h"
#include <utility>
#include "base/bind.h"
#include "base/logging.h"
#include "chrome/browser/chromeos/arc/arc_auth_service.h"
#include "components/arc/arc_service_manager.h"
#include "components/arc/user_data/arc_user_data_service.h"
namespace arc {
ArcEnterpriseReportingService::ArcEnterpriseReportingService(
ArcBridgeService* bridge_service)
: ArcService(bridge_service), binding_(this), weak_ptr_factory_(this) {
arc_bridge_service()->enterprise_reporting()->AddObserver(this);
}
ArcEnterpriseReportingService::~ArcEnterpriseReportingService() {
DCHECK(thread_checker_.CalledOnValidThread());
arc_bridge_service()->enterprise_reporting()->RemoveObserver(this);
}
void ArcEnterpriseReportingService::OnInstanceReady() {
DCHECK(thread_checker_.CalledOnValidThread());
arc_bridge_service()->enterprise_reporting()->instance()->Init(
binding_.CreateInterfacePtrAndBind());
}
void ArcEnterpriseReportingService::ReportManagementState(
mojom::ManagementState state) {
DCHECK(thread_checker_.CalledOnValidThread());
VLOG(1) << "ReportManagementState state=" << state;
if (state == mojom::ManagementState::MANAGED_DO_LOST) {
DCHECK(arc::ArcServiceManager::Get());
ArcServiceManager::Get()->arc_user_data_service()->RequireUserDataWiped(
base::Bind(&ArcEnterpriseReportingService::RestartArc,
weak_ptr_factory_.GetWeakPtr()));
ArcAuthService::Get()->StopArc();
}
}
void ArcEnterpriseReportingService::RestartArc(bool result) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!result)
LOG(ERROR) << "Required ARC user data wipe failed.";
// Restart ARC anyway. Let the enterprise reporting instance decide whether
// the ARC user data wipe is still required or not.
VLOG(1) << "Restart ARC";
ArcAuthService::Get()->EnableArc();
}
} // namespace arc
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_ARC_ARC_ENTERPRISE_REPORTING_SERVICE_H_
#define CHROME_BROWSER_CHROMEOS_ARC_ARC_ENTERPRISE_REPORTING_SERVICE_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_service.h"
#include "components/arc/instance_holder.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace arc {
// This class controls the ARC enterprise reporting.
class ArcEnterpriseReportingService
: public ArcService,
public InstanceHolder<mojom::EnterpriseReportingInstance>::Observer,
public mojom::EnterpriseReportingHost {
public:
explicit ArcEnterpriseReportingService(ArcBridgeService* arc_bridge_service);
~ArcEnterpriseReportingService() override;
// InstanceHolder<mojom::EnterpriseReportingInstance>::Observer overrides:
void OnInstanceReady() override;
// mojom::EnterpriseReportingHost overrides:
void ReportManagementState(mojom::ManagementState state) override;
private:
// DBus callback, restarts ARC after ARC user data wipe.
void RestartArc(bool success);
base::ThreadChecker thread_checker_;
mojo::Binding<mojom::EnterpriseReportingHost> binding_;
base::WeakPtrFactory<ArcEnterpriseReportingService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ArcEnterpriseReportingService);
};
} // namespace arc
#endif // CHROME_BROWSER_CHROMEOS_ARC_ARC_ENTERPRISE_REPORTING_SERVICE_H_
......@@ -9,6 +9,7 @@
#include "chrome/browser/chromeos/arc/arc_auth_service.h"
#include "chrome/browser/chromeos/arc/arc_boot_error_notification.h"
#include "chrome/browser/chromeos/arc/arc_downloads_watcher_service.h"
#include "chrome/browser/chromeos/arc/arc_enterprise_reporting_service.h"
#include "chrome/browser/chromeos/arc/arc_policy_bridge.h"
#include "chrome/browser/chromeos/arc/arc_process_service.h"
#include "chrome/browser/chromeos/arc/arc_settings_service.h"
......@@ -36,6 +37,9 @@ void ArcServiceLauncher::Initialize() {
arc_service_manager_->arc_bridge_service()));
arc_service_manager_->AddService(base::MakeUnique<ArcDownloadsWatcherService>(
arc_service_manager_->arc_bridge_service()));
arc_service_manager_->AddService(
base::MakeUnique<ArcEnterpriseReportingService>(
arc_service_manager_->arc_bridge_service()));
arc_service_manager_->AddService(base::MakeUnique<ArcIntentHelperBridge>(
arc_service_manager_->arc_bridge_service(),
arc_service_manager_->icon_loader(),
......
......@@ -193,7 +193,8 @@ void DeviceSettingsTestHelper::GetArcStartTime(
const GetArcStartTimeCallback& callback) {}
void DeviceSettingsTestHelper::RemoveArcData(
const cryptohome::Identification& cryptohome_id) {}
const cryptohome::Identification& cryptohome_id,
const ArcCallback& callback) {}
DeviceSettingsTestHelper::PolicyState::PolicyState()
: store_result_(true) {}
......
......@@ -124,7 +124,8 @@ class DeviceSettingsTestHelper : public SessionManagerClient {
const ArcCallback& callback) override;
void StopArcInstance(const ArcCallback& callback) override;
void GetArcStartTime(const GetArcStartTimeCallback& callback) override;
void RemoveArcData(const cryptohome::Identification& cryptohome_id) override;
void RemoveArcData(const cryptohome::Identification& cryptohome_id,
const ArcCallback& callback) override;
private:
struct PolicyState {
......
......@@ -70,6 +70,8 @@
'browser/chromeos/arc/arc_boot_error_notification.h',
'browser/chromeos/arc/arc_downloads_watcher_service.cc',
'browser/chromeos/arc/arc_downloads_watcher_service.h',
'browser/chromeos/arc/arc_enterprise_reporting_service.cc',
'browser/chromeos/arc/arc_enterprise_reporting_service.h',
'browser/chromeos/arc/arc_navigation_throttle.cc',
'browser/chromeos/arc/arc_navigation_throttle.h',
'browser/chromeos/arc/arc_service_launcher.cc',
......
......@@ -178,7 +178,13 @@ void FakeSessionManagerClient::GetArcStartTime(
}
void FakeSessionManagerClient::RemoveArcData(
const cryptohome::Identification& cryptohome_id) {}
const cryptohome::Identification& cryptohome_id,
const ArcCallback& callback) {
if (!callback.is_null()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(callback, arc_available_));
}
}
const std::string& FakeSessionManagerClient::device_policy() const {
return device_policy_;
......
......@@ -68,7 +68,8 @@ class FakeSessionManagerClient : public SessionManagerClient {
const ArcCallback& callback) override;
void StopArcInstance(const ArcCallback& callback) override;
void GetArcStartTime(const GetArcStartTimeCallback& callback) override;
void RemoveArcData(const cryptohome::Identification& cryptohome_id) override;
void RemoveArcData(const cryptohome::Identification& cryptohome_id,
const ArcCallback& callback) override;
const std::string& device_policy() const;
void set_device_policy(const std::string& policy_blob);
......
......@@ -64,7 +64,8 @@ class MockSessionManagerClient : public SessionManagerClient {
void(const cryptohome::Identification&, const ArcCallback&));
MOCK_METHOD1(StopArcInstance, void(const ArcCallback&));
MOCK_METHOD1(GetArcStartTime, void(const GetArcStartTimeCallback&));
MOCK_METHOD1(RemoveArcData, void(const cryptohome::Identification&));
MOCK_METHOD2(RemoveArcData,
void(const cryptohome::Identification&, const ArcCallback&));
};
} // namespace chromeos
......
......@@ -380,7 +380,8 @@ class SessionManagerClientImpl : public SessionManagerClient {
weak_ptr_factory_.GetWeakPtr(), callback));
}
void RemoveArcData(const cryptohome::Identification& cryptohome_id) override {
void RemoveArcData(const cryptohome::Identification& cryptohome_id,
const ArcCallback& callback) override {
dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
login_manager::kSessionManagerRemoveArcData);
dbus::MessageWriter writer(&method_call);
......@@ -389,7 +390,7 @@ class SessionManagerClientImpl : public SessionManagerClient {
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&SessionManagerClientImpl::OnArcMethod,
weak_ptr_factory_.GetWeakPtr(),
login_manager::kSessionManagerRemoveArcData, ArcCallback()));
login_manager::kSessionManagerRemoveArcData, callback));
}
protected:
......@@ -947,7 +948,10 @@ class SessionManagerClientStubImpl : public SessionManagerClient {
callback.Run(false, base::TimeTicks::Now());
}
void RemoveArcData(const cryptohome::Identification& cryptohome_id) override {
void RemoveArcData(const cryptohome::Identification& cryptohome_id,
const ArcCallback& callback) override {
if (!callback.is_null())
callback.Run(false);
}
private:
......
......@@ -237,9 +237,11 @@ class CHROMEOS_EXPORT SessionManagerClient : public DBusClient {
virtual void GetArcStartTime(const GetArcStartTimeCallback& callback) = 0;
// Asynchronously removes all ARC user data for the user whose cryptohome is
// located by |cryptohome_id|.
virtual void RemoveArcData(
const cryptohome::Identification& cryptohome_id) = 0;
// located by |cryptohome_id|. Upon completion, invokes |callback| with the
// result; true on success, false on failure (either session manager failed
// to remove user data or session manager can not be reached).
virtual void RemoveArcData(const cryptohome::Identification& cryptohome_id,
const ArcCallback& callback) = 0;
// Creates the instance.
static SessionManagerClient* Create(DBusClientImplementationType type);
......
......@@ -166,6 +166,7 @@
'arc/common/bluetooth.mojom',
'arc/common/clipboard.mojom',
'arc/common/crash_collector.mojom',
'arc/common/enterprise_reporting.mojom',
'arc/common/file_system.mojom',
'arc/common/ime.mojom',
'arc/common/intent_helper.mojom',
......
......@@ -136,6 +136,7 @@ mojom("arc_bindings") {
"common/bluetooth.mojom",
"common/clipboard.mojom",
"common/crash_collector.mojom",
"common/enterprise_reporting.mojom",
"common/file_system.mojom",
"common/ime.mojom",
"common/intent_helper.mojom",
......
......@@ -98,6 +98,9 @@ class ArcBridgeService {
InstanceHolder<mojom::CrashCollectorInstance>* crash_collector() {
return &crash_collector_;
}
InstanceHolder<mojom::EnterpriseReportingInstance>* enterprise_reporting() {
return &enterprise_reporting_;
}
InstanceHolder<mojom::FileSystemInstance>* file_system() {
return &file_system_;
}
......@@ -176,6 +179,7 @@ class ArcBridgeService {
InstanceHolder<mojom::BluetoothInstance> bluetooth_;
InstanceHolder<mojom::ClipboardInstance> clipboard_;
InstanceHolder<mojom::CrashCollectorInstance> crash_collector_;
InstanceHolder<mojom::EnterpriseReportingInstance> enterprise_reporting_;
InstanceHolder<mojom::FileSystemInstance> file_system_;
InstanceHolder<mojom::ImeInstance> ime_;
InstanceHolder<mojom::IntentHelperInstance> intent_helper_;
......
......@@ -230,6 +230,12 @@ void ArcBridgeServiceImpl::OnCrashCollectorInstanceReady(
crash_collector_.OnInstanceReady(std::move(crash_collector_ptr));
}
void ArcBridgeServiceImpl::OnEnterpriseReportingInstanceReady(
mojom::EnterpriseReportingInstancePtr enterprise_reporting_ptr) {
DCHECK(CalledOnValidThread());
enterprise_reporting_.OnInstanceReady(std::move(enterprise_reporting_ptr));
}
void ArcBridgeServiceImpl::OnFileSystemInstanceReady(
mojom::FileSystemInstancePtr file_system_ptr) {
DCHECK(CalledOnValidThread());
......
......@@ -52,6 +52,8 @@ class ArcBridgeServiceImpl : public ArcBridgeService,
mojom::ClipboardInstancePtr clipboard_ptr) override;
void OnCrashCollectorInstanceReady(
mojom::CrashCollectorInstancePtr crash_collector_ptr) override;
void OnEnterpriseReportingInstanceReady(
mojom::EnterpriseReportingInstancePtr enterprise_reporting_ptr) override;
void OnFileSystemInstanceReady(
mojom::FileSystemInstancePtr file_system_ptr) override;
void OnImeInstanceReady(mojom::ImeInstancePtr ime_ptr) override;
......
......@@ -100,8 +100,8 @@ void ArcServiceManager::OnPrimaryUserProfilePrepared(
std::unique_ptr<BooleanPrefMember> arc_enabled_pref) {
DCHECK(thread_checker_.CalledOnValidThread());
AddService(base::WrapUnique(new ArcUserDataService(
arc_bridge_service(), std::move(arc_enabled_pref), account_id)));
arc_user_data_service_.reset(new ArcUserDataService(arc_bridge_service(),
std::move(arc_enabled_pref), account_id));
AddService(base::WrapUnique(
new ArcNotificationManager(arc_bridge_service(), account_id)));
......@@ -110,6 +110,7 @@ void ArcServiceManager::OnPrimaryUserProfilePrepared(
void ArcServiceManager::Shutdown() {
icon_loader_ = nullptr;
activity_resolver_ = nullptr;
arc_user_data_service_ = nullptr;
services_.clear();
}
......
......@@ -21,6 +21,7 @@ namespace arc {
class ArcBridgeService;
class ArcService;
class ArcUserDataService;
// Manages creation and destruction of services that communicate with the ARC
// instance via the ArcBridgeService.
......@@ -66,6 +67,10 @@ class ArcServiceManager {
return activity_resolver_;
}
ArcUserDataService* arc_user_data_service() {
return arc_user_data_service_.get();
}
private:
base::ThreadChecker thread_checker_;
scoped_refptr<base::TaskRunner> blocking_task_runner_;
......@@ -74,6 +79,7 @@ class ArcServiceManager {
std::vector<std::unique_ptr<ArcService>> services_;
scoped_refptr<ActivityIconLoader> icon_loader_;
scoped_refptr<LocalActivityResolver> activity_resolver_;
std::unique_ptr<ArcUserDataService> arc_user_data_service_;
DISALLOW_COPY_AND_ASSIGN(ArcServiceManager);
};
......
......@@ -10,6 +10,7 @@ import "auth.mojom";
import "bluetooth.mojom";
import "clipboard.mojom";
import "crash_collector.mojom";
import "enterprise_reporting.mojom";
import "file_system.mojom";
import "ime.mojom";
import "intent_helper.mojom";
......@@ -23,9 +24,9 @@ import "process.mojom";
import "storage_manager.mojom";
import "video.mojom";
// Next MinVersion: 15
// Deprecated method IDs: 101, 105, 117
// Next method ID: 121
// Next MinVersion: 16
// Deprecated method IDs: 101, 105
// Next method ID: 123
interface ArcBridgeHost {
// Keep the entries alphabetical. In order to do so without breaking
// compatibility with the ARC instance, explicitly assign each interface a
......@@ -50,6 +51,10 @@ interface ArcBridgeHost {
[MinVersion=7] OnCrashCollectorInstanceReady@112(
CrashCollectorInstance instance_ptr);
// Notifies Chrome that the EnterpriseReportingInstance interface is ready.
[MinVersion=15] OnEnterpriseReportingInstanceReady@122(
EnterpriseReportingInstance instance_ptr);
// Notifies Chrome that the FileSystemInstance interface is ready.
[MinVersion=13] OnFileSystemInstanceReady@119(
FileSystemInstance instance_ptr);
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Next MinVersion: 1
module arc.mojom;
// Enumerates the states that management can be in for a user.
[Extensible]
enum ManagementState {
// The user is not managed.
UNMANAGED = 0,
// The user is managed and the management infrastructure is working correctly.
MANAGED_OK = 1,
// The user is managed but managing app lost its Device Owner status and
// cannot set policies.
MANAGED_DO_LOST = 2
};
// Next method ID: 1
interface EnterpriseReportingHost {
// Reports the management status for the user.
ReportManagementState@0(ManagementState state);
};
// Next method ID: 1
interface EnterpriseReportingInstance {
// Establishes full-duplex communication with the host.
Init@0(EnterpriseReportingHost host_ptr);
};
......@@ -10,7 +10,6 @@
#include "chromeos/chromeos_switches.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "components/prefs/pref_member.h"
#include "components/signin/core/account_id/account_id.h"
#include "components/user_manager/user_manager.h"
......@@ -31,7 +30,7 @@ ArcUserDataService::ArcUserDataService(
arc_enabled_pref_->GetPrefName(),
base::Bind(&ArcUserDataService::OnOptInPreferenceChanged,
weak_ptr_factory_.GetWeakPtr()));
ClearIfDisabled();
WipeIfRequired();
}
ArcUserDataService::~ArcUserDataService() {
......@@ -50,30 +49,38 @@ void ArcUserDataService::OnBridgeStopped(ArcBridgeService::StopReason reason) {
primary_user_account_id_ = EmptyAccountId();
return;
}
ClearIfDisabled();
WipeIfRequired();
}
void ArcUserDataService::ClearIfDisabled() {
void ArcUserDataService::RequireUserDataWiped(const ArcDataCallback& callback) {
VLOG(1) << "Require ARC user data to be wiped.";
arc_user_data_wipe_required_ = true;
callback_ = callback;
}
void ArcUserDataService::WipeIfRequired() {
DCHECK(thread_checker_.CalledOnValidThread());
if (!arc_bridge_service()->stopped()) {
LOG(ERROR) << "ARC instance not stopped, user data can't be cleared";
LOG(ERROR) << "ARC instance not stopped, user data can't be wiped";
return;
}
if ((arc_enabled_pref_->GetValue() && !arc_disabled_) ||
if ((arc_enabled_pref_->GetValue() && !arc_user_data_wipe_required_) ||
base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kDisableArcDataWipe)) {
return;
}
arc_disabled_ = false;
VLOG(1) << "Wipe ARC user data.";
arc_user_data_wipe_required_ = false;
const cryptohome::Identification cryptohome_id(primary_user_account_id_);
chromeos::SessionManagerClient* session_manager_client =
chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
session_manager_client->RemoveArcData(cryptohome_id);
session_manager_client->RemoveArcData(cryptohome_id, callback_);
callback_.Reset();
}
void ArcUserDataService::OnOptInPreferenceChanged() {
if (!arc_enabled_pref_->GetValue())
arc_disabled_ = true;
arc_user_data_wipe_required_ = true;
}
} // namespace arc
......@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "chromeos/dbus/session_manager_client.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_service.h"
#include "components/prefs/pref_change_registrar.h"
......@@ -31,19 +32,25 @@ class ArcUserDataService : public ArcService,
const AccountId& account_id);
~ArcUserDataService() override;
using ArcDataCallback = chromeos::SessionManagerClient::ArcCallback;
// ArcBridgeService::Observer:
// Called whenever the arc bridge is stopped to potentially remove data if
// the user has not opted in.
// Called whenever the arc bridge is stopped to potentially wipe data if
// the user has not opted in or it is required.
void OnBridgeStopped(ArcBridgeService::StopReason reason) override;
// Requires to wipe ARC user data after the next ARC bridge shutdown and call
// |callback| with an operation result.
void RequireUserDataWiped(const ArcDataCallback& callback);
private:
base::ThreadChecker thread_checker_;
// Checks if ARC is both stopped and disabled (not opt-in) and triggers
// removal of user data if both conditions are true.
void ClearIfDisabled();
// Checks if ARC is both stopped and disabled (not opt-in) or data wipe is
// required and triggers removal of user data.
void WipeIfRequired();
// Callback when the kArcEnabled preference changes. It watches for instances
// Callback when the kArcEnabled preference changes. It watches for instances
// where the preference is disabled and remembers this so that it can wipe
// user data once the bridge has stopped.
void OnOptInPreferenceChanged();
......@@ -56,10 +63,16 @@ class ArcUserDataService : public ArcService,
// Registrar used to monitor ARC enabled state.
PrefChangeRegistrar pref_change_registrar_;
// Set to true when kArcEnabled goes from true to false and set to false
// again after user data has been wiped. This ensures data is wiped even if
// the user tries to enable ARC before the bridge has shut down.
bool arc_disabled_ = false;
// Set to true when kArcEnabled goes from true to false or user data wipe is
// required and set to false again after user data has been wiped.
// This ensures data is wiped even if the user tries to enable ARC before the
// bridge has shut down.
bool arc_user_data_wipe_required_ = false;
// Callback object that is passed to RemoveArcData to be invoked with a
// result of ARC user data wipe.
// Set when ARC user data wipe is required by RequireUserDataWiped.
ArcDataCallback callback_;
base::WeakPtrFactory<ArcUserDataService> weak_ptr_factory_;
......
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