blob: 6d28b38d15fda5f52ae0ad37183e54f0140ad49b [file] [log] [blame]
// Copyright 2020 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 CHROMEOS_LACROS_LACROS_CHROME_SERVICE_IMPL_H_
#define CHROMEOS_LACROS_LACROS_CHROME_SERVICE_IMPL_H_
#include <memory>
#include "base/component_export.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "chromeos/crosapi/mojom/crosapi.mojom.h"
#include "chromeos/crosapi/mojom/keystore_service.mojom.h"
#include "chromeos/crosapi/mojom/message_center.mojom.h"
#include "chromeos/crosapi/mojom/screen_manager.mojom.h"
#include "chromeos/crosapi/mojom/select_file.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/hid.mojom.h"
namespace chromeos {
class LacrosChromeServiceDelegate;
// Forward declaration for class defined in .cc file that holds most of the
// business logic of this class.
class LacrosChromeServiceNeverBlockingState;
// This class is responsible for receiving and routing mojo messages from
// ash-chrome via the mojo::Receiver |sequenced_state_.receiver_|. This class is
// responsible for sending and routing messages to ash-chrome via the
// mojo::Remote |sequenced_state_.ash_chrome_service_|. Messages are sent and
// received on a dedicated, never-blocking sequence to avoid deadlocks.
//
// This object is constructed, destroyed, and mostly used on an "affine
// sequence". For most intents and purposes, this is the main/UI thread.
//
// This class is a singleton but is not thread safe. Each method is individually
// documented with threading requirements.
class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl {
public:
// The getter is safe to call from all threads.
//
// This method returns nullptr very early or late in the application
// lifecycle. We've chosen to have precise constructor/destructor timings
// rather than rely on a lazy initializer and no destructor to allow for
// more precise testing.
//
// If this is accessed on a thread other than the affine sequence, the caller
// must invalidate or destroy the pointer before shutdown. Attempting to use
// this pointer during shutdown can result in UaF.
static LacrosChromeServiceImpl* Get();
// This class is expected to be constructed and destroyed on the same
// sequence.
explicit LacrosChromeServiceImpl(
std::unique_ptr<LacrosChromeServiceDelegate> delegate);
~LacrosChromeServiceImpl();
// This can be called on any thread. This call allows LacrosChromeServiceImpl
// to start receiving messages from ash-chrome.
void BindReceiver(
mojo::PendingReceiver<crosapi::mojom::LacrosChromeService> receiver);
// This must be called on the affine sequence.
mojo::Remote<crosapi::mojom::MessageCenter>& message_center_remote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_);
return message_center_remote_;
}
// This must be called on the affine sequence. It exposes a remote that can
// be used to show a select-file dialog.
mojo::Remote<crosapi::mojom::SelectFile>& select_file_remote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_);
return select_file_remote_;
}
// This must be called on the affine sequence. It exposes a remote that can
// be used to query the system keystores.
mojo::Remote<crosapi::mojom::KeystoreService>& keystore_service_remote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_);
return keystore_service_remote_;
}
// This must be called on the affine sequence. It exposes a remote that can
// be used to support HID devices.
mojo::Remote<device::mojom::HidManager>& hid_manager_remote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_);
return hid_manager_remote_;
}
// This may be called on any thread.
void BindScreenManagerReceiver(
mojo::PendingReceiver<crosapi::mojom::ScreenManager> pending_receiver);
const crosapi::mojom::LacrosInitParams* init_params() const {
return init_params_.get();
}
private:
// LacrosChromeServiceNeverBlockingState is an implementation detail of this
// class.
friend class LacrosChromeServiceNeverBlockingState;
// Creates a new window on the affine sequence.
void NewWindowAffineSequence();
// Delegate instance to inject Chrome dependent code. Must only be used on the
// affine sequence.
std::unique_ptr<LacrosChromeServiceDelegate> delegate_;
// Parameters passed from ash-chrome.
crosapi::mojom::LacrosInitParamsPtr init_params_;
// This member allows lacros-chrome to use the SelectFile interface. This
// member is affine to the affine sequence. It is initialized in the
// constructor and it is immediately available for use.
mojo::Remote<crosapi::mojom::MessageCenter> message_center_remote_;
mojo::Remote<crosapi::mojom::SelectFile> select_file_remote_;
mojo::Remote<device::mojom::HidManager> hid_manager_remote_;
// This member allows lacros-chrome to use the KeystoreService interface. This
// member is affine to the affine sequence. It is initialized in the
// constructor and it is immediately available for use.
mojo::Remote<crosapi::mojom::KeystoreService> keystore_service_remote_;
// This member is instantiated on the affine sequence alongside the
// constructor. All subsequent invocations of this member, including
// destruction, happen on the |never_blocking_sequence_|.
std::unique_ptr<LacrosChromeServiceNeverBlockingState,
base::OnTaskRunnerDeleter>
sequenced_state_;
// This member is instantiated on the affine sequence, but only ever
// dereferenced on the |never_blocking_sequence_|.
base::WeakPtr<LacrosChromeServiceNeverBlockingState> weak_sequenced_state_;
// A sequence that is guaranteed to never block.
scoped_refptr<base::SequencedTaskRunner> never_blocking_sequence_;
// Checks that the method is called on the affine sequence.
SEQUENCE_CHECKER(affine_sequence_checker_);
base::WeakPtrFactory<LacrosChromeServiceImpl> weak_factory_{this};
};
} // namespace chromeos
#endif // CHROMEOS_LACROS_LACROS_CHROME_SERVICE_IMPL_H_