blob: d19053c2c06dfb7425c2ab9385af1dd403c84af1 [file] [log] [blame]
// Copyright (C) 2012 The Android Open Source Project
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
#include <memory>
#include <string>
#include <vector>
#include <base/files/file_path.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include "shill/event_dispatcher.h"
#include "shill/property_store.h"
#include "shill/refptr_types.h"
namespace shill {
class ControlInterface;
class Error;
class Manager;
class Metrics;
class ProfileAdaptorInterface;
class StoreInterface;
#if !defined(DISABLE_WIFI)
class WiFiProvider;
#endif // DISABLE_WIFI
class Profile : public base::RefCounted<Profile> {
enum InitStorageOption {
struct Identifier {
Identifier() {}
explicit Identifier(const std::string& i) : identifier(i) {}
Identifier(const std::string& u, const std::string& i)
: user(u),
identifier(i) {
std::string user; // Empty for global.
std::string identifier;
std::string user_hash;
// Path to the cached list of inserted user profiles to be loaded at
// startup.
static const char kUserProfileListPathname[];
Profile(ControlInterface* control_interface,
Metrics* metrics,
Manager* manager,
const Identifier& name,
const base::FilePath& storage_directory,
bool connect_to_rpc);
virtual ~Profile();
// Set up persistent storage for this Profile.
bool InitStorage(InitStorageOption storage_option,
Error* error);
// Set up stub storage for this Profile. The data will NOT be
// persisted. In most cases, you should prefer InitStorage.
void InitStubStorage();
// Remove the persistent storage for this Profile. It is an error to
// do so while the underlying storage is open via InitStorage() or
// SetStorageForTest().
bool RemoveStorage(Error* error);
virtual std::string GetFriendlyName() const;
virtual std::string GetRpcIdentifier() const;
PropertyStore* mutable_store() { return &store_; }
const PropertyStore& store() const { return store_; }
// Set the storage inteface. This is used for testing purposes.
void SetStorageForTest(std::unique_ptr<StoreInterface> storage);
// Begin managing the persistence of |service|.
// Returns true if |service| is new to this profile and was added,
// false if the |service| already existed.
virtual bool AdoptService(const ServiceRefPtr& service);
// Cease managing the persistence of the Service |service|.
// Returns true if |service| was found and abandoned, or not found.
// Returns false if can't be abandoned.
virtual bool AbandonService(const ServiceRefPtr& service);
// Clobbers persisted notion of |service| with data from |service|.
// Returns true if |service| was found and updated, false if not found.
virtual bool UpdateService(const ServiceRefPtr& service);
// Ask |service| if it can configure itself from the profile. If it can,
// ask |service| to perform the configuration and return true. If not,
// return false.
virtual bool LoadService(const ServiceRefPtr& service);
// Perform LoadService() on |service|. If this succeeds, change
// the service to point at this profile and return true. If not, return
// false.
virtual bool ConfigureService(const ServiceRefPtr& service);
// Allow the device to configure itself from this profile. Returns
// true if the device succeeded in finding its configuration. If not,
// return false.
virtual bool ConfigureDevice(const DeviceRefPtr& device);
// Remove a named entry from the profile. This includes detaching
// any service that uses this profile entry.
virtual void DeleteEntry(const std::string& entry_name, Error* error);
// Return a service configured from the given profile entry.
// Callers must not register the returned service with the Manager or connect
// it since it might not be in the provider's service list.
virtual ServiceRefPtr GetServiceFromEntry(const std::string& entry_name,
Error* error);
// Return whether |service| can configure itself from the profile.
bool ContainsService(const ServiceConstRefPtr& service);
std::vector<std::string> EnumerateAvailableServices(Error* error);
std::vector<std::string> EnumerateEntries(Error* error);
// Clobbers persisted notion of |device| with data from |device|. Returns true
// if |device| was found and updated, false otherwise. The base implementation
// always returns false -- currently devices are persisted only in
// DefaultProfile.
virtual bool UpdateDevice(const DeviceRefPtr& device);
#if !defined(DISABLE_WIFI)
// Clobbers persisted notion of |wifi_provider| with data from
// |wifi_provider|. Returns true if |wifi_provider| was found and updated,
// false otherwise. The base implementation always returns false -- currently
// wifi_provider is persisted only in DefaultProfile.
virtual bool UpdateWiFiProvider(const WiFiProvider& wifi_provider);
#endif // DISABLE_WIFI
// Write all in-memory state to disk via |storage_|.
virtual bool Save();
// Parses a profile identifier. There're two acceptable forms of the |raw|
// identifier: "identifier" and "~user/identifier". Both "user" and
// "identifier" must be suitable for use in a D-Bus object path. Returns true
// on success.
static bool ParseIdentifier(const std::string& raw, Identifier* parsed);
// Returns the composite string identifier for a profile, as would have
// been used in an argument to Manager::PushProfile() in creating this
// profile. It returns a string in the form "identifier", or
// "~user/identifier" depending on whether this profile has a user
// component.
static std::string IdentifierToString(const Identifier& name);
// Load a list of user profile identifiers from a cache file |path|.
// The profiles themselves are not loaded.
static std::vector<Identifier> LoadUserProfileList(
const base::FilePath& path);
// Save a list of user profile identifiers |profiles| to a cache file |path|.
// Returns true if successful, false otherwise.
static bool SaveUserProfileList(const base::FilePath& path,
const std::vector<ProfileRefPtr>& profiles);
// Returns whether |name| matches this Profile's |name_|.
virtual bool MatchesIdentifier(const Identifier& name) const;
// Returns the username component of the profile identifier.
const std::string& GetUser() const { return name_.user; }
// Returns the user_hash component of the profile identifier.
const std::string& GetUserHash() const { return name_.user_hash; }
virtual StoreInterface* GetStorage() {
return storage_.get();
// Returns a read-only copy of the backing storage of the profile.
virtual const StoreInterface* GetConstStorage() const {
return storage_.get();
virtual bool IsDefault() const { return false; }
// Returns the persistent store file path for a Profile with the
// given |storage_dir| and |profile_name|. Provided as a static
// method, so that tests can use this logic without having to
// instantiate a Profile.
static base::FilePath GetFinalStoragePath(
const base::FilePath& storage_dir,
const Identifier& profile_name);
Metrics* metrics() const { return metrics_; }
Manager* manager() const { return manager_; }
StoreInterface* storage() { return storage_.get(); }
const base::FilePath& persistent_profile_path() {
return persistent_profile_path_;
void set_persistent_profile_path(const base::FilePath& path) {
persistent_profile_path_ = path;
friend class ManagerTest;
friend class ProfileAdaptorInterface;
FRIEND_TEST(ManagerTest, CreateDuplicateProfileWithMissingKeyfile);
FRIEND_TEST(ManagerTest, RemoveProfile);
FRIEND_TEST(ProfileTest, DeleteEntry);
FRIEND_TEST(ProfileTest, GetStoragePath);
FRIEND_TEST(ProfileTest, IsValidIdentifierToken);
FRIEND_TEST(ProfileTest, GetServiceFromEntry);
static bool IsValidIdentifierToken(const std::string& token);
void HelpRegisterConstDerivedStrings(
const std::string& name,
Strings(Profile::*get)(Error* error));
// Data members shared with subclasses via getter/setters above in the
// protected: section
Metrics* metrics_;
Manager* manager_;
ControlInterface* control_interface_;
base::FilePath persistent_profile_path_;
// Shared with |adaptor_| via public getter.
PropertyStore store_;
// Properties to be gotten via PropertyStore calls.
Identifier name_;
// Allows this profile to be backed with on-disk storage.
std::unique_ptr<StoreInterface> storage_;
std::unique_ptr<ProfileAdaptorInterface> adaptor_;
} // namespace shill
#endif // SHILL_PROFILE_H_