| // Copyright 2014 The Chromium OS 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 BUFFET_DEVICE_REGISTRATION_INFO_H_ |
| #define BUFFET_DEVICE_REGISTRATION_INFO_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include <base/callback.h> |
| #include <base/macros.h> |
| #include <base/time/time.h> |
| #include <chromeos/data_encoding.h> |
| #include <chromeos/errors/error.h> |
| #include <chromeos/http/http_transport.h> |
| |
| #include "buffet/storage_interface.h" |
| |
| namespace base { |
| class Value; |
| } // namespace base |
| |
| namespace chromeos { |
| class KeyValueStore; |
| } // namespace chromeos |
| |
| namespace buffet { |
| |
| class CommandManager; |
| class StateManager; |
| |
| extern const char kErrorDomainOAuth2[]; |
| extern const char kErrorDomainGCD[]; |
| extern const char kErrorDomainGCDServer[]; |
| |
| // The DeviceRegistrationInfo class represents device registration information. |
| class DeviceRegistrationInfo { |
| public: |
| // This is a helper class for unit testing. |
| class TestHelper; |
| |
| DeviceRegistrationInfo( |
| const std::shared_ptr<CommandManager>& command_manager, |
| const std::shared_ptr<StateManager>& state_manager, |
| std::unique_ptr<chromeos::KeyValueStore> config_store, |
| const std::shared_ptr<chromeos::http::Transport>& transport, |
| const std::shared_ptr<StorageInterface>& state_store); |
| |
| ~DeviceRegistrationInfo(); |
| |
| // Returns the authorization HTTP header that can be used to talk |
| // to GCD server for authenticated device communication. |
| // Make sure ValidateAndRefreshAccessToken() is called before this call. |
| std::pair<std::string, std::string> GetAuthorizationHeader() const; |
| |
| // Returns the GCD service request URL. If |subpath| is specified, it is |
| // appended to the base URL which is normally |
| // https://www.googleapis.com/clouddevices/v1/". |
| // If |params| are specified, each key-value pair is formatted using |
| // chromeos::data_encoding::WebParamsEncode() and appended to URL as a query |
| // string. |
| // So, calling: |
| // GetServiceURL("ticket", {{"key","apiKey"}}) |
| // will return something like: |
| // https://www.googleapis.com/clouddevices/v1/ticket?key=apiKey |
| std::string GetServiceURL( |
| const std::string& subpath = {}, |
| const chromeos::data_encoding::WebParamList& params = {}) const; |
| |
| // Returns a service URL to access the registered device on GCD server. |
| // The base URL used to construct the full URL looks like this: |
| // https://www.googleapis.com/clouddevices/v1/devices/<device_id>/ |
| std::string GetDeviceURL( |
| const std::string& subpath = {}, |
| const chromeos::data_encoding::WebParamList& params = {}) const; |
| |
| // Similar to GetServiceURL, GetOAuthURL() returns a URL of OAuth 2.0 server. |
| // The base URL used is https://accounts.google.com/o/oauth2/. |
| std::string GetOAuthURL( |
| const std::string& subpath = {}, |
| const chromeos::data_encoding::WebParamList& params = {}) const; |
| |
| // Returns the registered device ID (GUID) or empty string if failed |
| std::string GetDeviceId(chromeos::ErrorPtr* error); |
| |
| // Loads the device registration information from cache. |
| bool Load(); |
| |
| // Checks for the valid device registration as well as refreshes |
| // the device access token, if available. |
| bool CheckRegistration(chromeos::ErrorPtr* error); |
| |
| // Gets the full device description JSON object, or nullptr if |
| // the device is not registered or communication failure. |
| std::unique_ptr<base::Value> GetDeviceInfo(chromeos::ErrorPtr* error); |
| |
| // Registers the device. |
| // |
| // |params| are a list of key-value pairs of device information, |
| // such as client_id, client_secret, and so on. If a particular key-value pair |
| // is omitted, a default value is used when possible. |
| // Returns a device ID on success. |
| // The values are all strings for now. |
| std::string RegisterDevice( |
| const std::map<std::string, std::string>& params, |
| chromeos::ErrorPtr* error); |
| |
| // Starts device execution. |
| // Device will do required start up chores and then start to listen |
| // to new commands. |
| // TODO(antonm): Consider moving into some other class. |
| void StartDevice(chromeos::ErrorPtr* error); |
| |
| // Updates a command. |
| // TODO(antonm): Should solve the issues with async vs. sync. |
| // TODO(antonm): Consider moving some other class. |
| void UpdateCommand(const std::string& command_id, |
| const base::DictionaryValue& command_patch); |
| |
| private: |
| // Saves the device registration to cache. |
| bool Save() const; |
| |
| // Makes sure the access token is available and up-to-date. |
| bool ValidateAndRefreshAccessToken(chromeos::ErrorPtr* error); |
| |
| using CloudRequestCallback = |
| base::Callback<void(const base::DictionaryValue&)>; |
| using CloudRequestErrorCallback = |
| base::Callback<void(const chromeos::Error* error)>; |
| |
| // Do a HTTPS request to cloud services. |
| // Handles many cases like reauthorization, 5xx HTTP response codes |
| // and device removal. It is a recommended way to do cloud API |
| // requests. |
| // TODO(antonm): Consider moving into some other class. |
| void DoCloudRequest( |
| const std::string& method, |
| const std::string& url, |
| const base::DictionaryValue* body, |
| const CloudRequestCallback& success_callback, |
| const CloudRequestErrorCallback& error_callback); |
| |
| void UpdateDeviceResource(base::Closure callback); |
| |
| void FetchCommands(base::Callback<void(const base::ListValue&)> callback); |
| |
| void AbortLimboCommands(base::Closure callback, |
| const base::ListValue& commands); |
| |
| void PeriodicallyPollCommands(); |
| |
| void PublishCommands(const base::ListValue& commands); |
| |
| void PublishStateUpdates(); |
| |
| // Looks up the value for parameter with name |param_name| in |
| // |params|, supplying a default value if one is available and |
| // |params| doesn't have a value for |param_name|. The value will be |
| // returned in |param_value|. Returns |true| if a value was set |
| // (either from |params| or a default), |false| otherwise and |
| // |error| will be set. |
| bool GetParamValue( |
| const std::map<std::string, std::string>& params, |
| const std::string& param_name, |
| std::string* param_value, |
| chromeos::ErrorPtr* error); |
| |
| // Builds Cloud API devices collection REST resouce which matches |
| // current state of the device including command definitions |
| // for all supported commands and current device state. |
| std::unique_ptr<base::DictionaryValue> BuildDeviceResource( |
| chromeos::ErrorPtr* error); |
| |
| std::string client_id_; |
| std::string client_secret_; |
| std::string api_key_; |
| std::string refresh_token_; |
| std::string device_id_; |
| std::string device_robot_account_; |
| std::string oauth_url_; |
| std::string service_url_; |
| |
| // Transient data |
| std::string access_token_; |
| base::Time access_token_expiration_; |
| std::string ticket_id_; |
| std::string device_kind_; |
| std::string name_; |
| std::string display_name_; |
| std::string description_; |
| std::string location_; |
| |
| // HTTP transport used for communications. |
| std::shared_ptr<chromeos::http::Transport> transport_; |
| // Serialization interface to save and load device registration info. |
| std::shared_ptr<StorageInterface> storage_; |
| // Global command manager. |
| std::shared_ptr<CommandManager> command_manager_; |
| // Device state manager. |
| std::shared_ptr<StateManager> state_manager_; |
| |
| // Buffet configuration. |
| std::unique_ptr<chromeos::KeyValueStore> config_store_; |
| |
| friend class TestHelper; |
| DISALLOW_COPY_AND_ASSIGN(DeviceRegistrationInfo); |
| }; |
| |
| } // namespace buffet |
| |
| #endif // BUFFET_DEVICE_REGISTRATION_INFO_H_ |