diff options
Diffstat (limited to 'chromium/components/policy/core/common/remote_commands/remote_command_job.h')
-rw-r--r-- | chromium/components/policy/core/common/remote_commands/remote_command_job.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/chromium/components/policy/core/common/remote_commands/remote_command_job.h b/chromium/components/policy/core/common/remote_commands/remote_command_job.h new file mode 100644 index 00000000000..ffa7f9769b5 --- /dev/null +++ b/chromium/components/policy/core/common/remote_commands/remote_command_job.h @@ -0,0 +1,184 @@ +// Copyright 2015 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 COMPONENTS_POLICY_CORE_COMMON_REMOTE_COMMANDS_REMOTE_COMMAND_JOB_H_ +#define COMPONENTS_POLICY_CORE_COMMON_REMOTE_COMMANDS_REMOTE_COMMAND_JOB_H_ + +#include <stdint.h> + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "components/policy/policy_export.h" +#include "components/policy/proto/device_management_backend.pb.h" + +namespace policy { + +// This class manages the execution of a remote command job. It's a base class +// and actual implementations are expected to inherit from this class. +class POLICY_EXPORT RemoteCommandJob { + public: + using UniqueIDType = int64_t; + + // Status of this job. + // This enum is used to define the buckets for an enumerated UMA histogram. + // Hence, + // (a) existing enumerated constants should never be deleted or reordered + // (b) new constants should only be appended at the end of the enumeration + // (update RemoteCommandExecutuionStatus in + // tools/metrics/histograms/enums.xml as well). + enum Status { + NOT_INITIALIZED = 0, // The job is not initialized yet. + INVALID = 1, // The job was initialized from a malformed protobuf. + EXPIRED = 2, // The job is expired and won't be executed. + NOT_STARTED = 3, // The job is initialized and ready to be started. + RUNNING = 4, // The job was started and is running now. + SUCCEEDED = 5, // The job finished running successfully. + FAILED = 6, // The job finished running with failure. + TERMINATED = 7, // The job was terminated before finishing by itself. + STATUS_TYPE_SIZE // Used by UMA histograms. Shall be the last. + }; + + using FinishedCallback = base::OnceClosure; + + RemoteCommandJob(const RemoteCommandJob&) = delete; + RemoteCommandJob& operator=(const RemoteCommandJob&) = delete; + + virtual ~RemoteCommandJob(); + + // Initialize from a RemoteCommand protobuf definition, must be called before + // calling Run(). Returns true if the initialization is successful. + // |now| is the current time which will be used to estimate the command issued + // time. It must be consistent to the same parameter passed to Run() below. + // In order to minimize the error while estimating the command issued time, + // this method must be called immediately after the command is received from + // the server. |signed_command| contains the entire remote command and its + // signature, the way it was received from the server. + bool Init(base::TimeTicks now, + const enterprise_management::RemoteCommand& command, + const enterprise_management::SignedData& signed_command); + + // Run the command asynchronously. |now| is the time used for marking the + // execution start. |now_ticks| is the time which will be used for command + // expiration checking. + // |finished_callback| will be called once the command finishes running, + // regardless of whether the command is successful, fails or is terminated + // prematurely. + // Returns true if the task is posted and the command marked as running. + // Returns false otherwise, for example if the command is invalid or expired. + // Subclasses should implement RunImpl() for actual work. + bool Run(base::Time now, + base::TimeTicks now_ticks, + FinishedCallback finished_callback); + + // Attempts to terminate the running tasks associated with this command. Does + // nothing if the task is already terminated or finished. It's guaranteed that + // after calling this method, |finished_callback_| will never be called. + // Asynchronous tasks might still be running and subclasses that wish to + // actually terminate the tasks should implement TerminateImpl(). + // This method is also intended to be used to handle timeout of command + // execution. + void Terminate(); + + // Returns the remote command type that this class is able to handle. + virtual enterprise_management::RemoteCommand_Type GetType() const = 0; + + // Returns the remote command timeout. If the command takes longer than the + // returned time interval to execute, the command queue will kill it. + virtual base::TimeDelta GetCommandTimeout() const; + + // Helpful accessors. + UniqueIDType unique_id() const { return unique_id_; } + base::TimeTicks issued_time() const { return issued_time_; } + base::Time execution_started_time() const { return execution_started_time_; } + Status status() const { return status_; } + + // Returns whether execution of this command is finished. + bool IsExecutionFinished() const; + + // Generate the result payload which will be sent back to the server. + // This method will only be called for successfully executed commands. + std::unique_ptr<std::string> GetResultPayload() const; + + protected: + class ResultPayload { + public: + virtual ~ResultPayload() {} + + virtual std::unique_ptr<std::string> Serialize() = 0; + }; + + using CallbackWithResult = + base::OnceCallback<void(std::unique_ptr<ResultPayload>)>; + + RemoteCommandJob(); + + // The server can provide additional arguments for a command, + // serialized into a |command_payload| string. This method will be + // called with the payload sent by the server (or an empty string + // if there is no payload). Subclasses that expect command + // arguments should override this method and deserialize the + // |command_payload| string. The default implementation ignores any + // payload. + virtual bool ParseCommandPayload(const std::string& command_payload); + + // Subclasses may use this method for customized command expiration + // checking. |now| is the current time obtained from a clock. Implementations + // are usually expected to compare |now| to the issued_time(), which is the + // timestamp when the command was issued on the server. + virtual bool IsExpired(base::TimeTicks now); + + // Subclasses should implement this method for actual command execution logic. + // Implementations should execute commands asynchronously, possibly on a + // background thread. Execution should end by invoking either + // |succeeded_callback| or |failed_callback| on the thread that this method + // was called. + // Also see comments regarding Run(). + virtual void RunImpl(CallbackWithResult succeed_callback, + CallbackWithResult failed_callback) = 0; + + // Subclasses should implement this method for actual command execution + // termination. Be cautious that tasks might be running on another thread or + // even already be terminated. Implementations should expect destruction of + // the class soon. Also see comments regarding Terminate(). + // The default implementation does nothing. + virtual void TerminateImpl(); + + const enterprise_management::SignedData& signed_command() const { + return signed_command_; + } + + private: + // Posted tasks are expected to call this method. + void OnCommandExecutionFinishedWithResult( + bool succeeded, + std::unique_ptr<ResultPayload> result); + + Status status_; + + UniqueIDType unique_id_; + // The estimated time when the command was issued. + base::TimeTicks issued_time_; + // The time when the command started running. + base::Time execution_started_time_; + + // Serialized command inside policy data proto with signature. + enterprise_management::SignedData signed_command_; + + std::unique_ptr<ResultPayload> result_payload_; + + FinishedCallback finished_callback_; + + base::ThreadChecker thread_checker_; + + base::WeakPtrFactory<RemoteCommandJob> weak_factory_{this}; +}; + +} // namespace policy + +#endif // COMPONENTS_POLICY_CORE_COMMON_REMOTE_COMMANDS_REMOTE_COMMAND_JOB_H_ |