summaryrefslogtreecommitdiffstats
path: root/xbmc/profiles/ProfileManager.h
blob: e39451893fc808f7aa44d9696e4363ae59df84ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*
 *  Copyright (C) 2013-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "profiles/Profile.h"
#include "settings/lib/ISettingCallback.h"
#include "settings/lib/ISettingsHandler.h"
#include "threads/CriticalSection.h"

#include <memory>
#include <stdint.h>
#include <vector>

class CEventLog;
class CEventLogManager;
class CSettings;
class TiXmlNode;

class CProfileManager : protected ISettingsHandler,
                         protected ISettingCallback
{
public:
  CProfileManager();
  CProfileManager(const CProfileManager&) = delete;
  CProfileManager& operator=(CProfileManager const&) = delete;
  ~CProfileManager() override;

  void Initialize(const std::shared_ptr<CSettings>& settings);
  void Uninitialize();

  void OnSettingsLoaded() override;
  void OnSettingsSaved() const override;
  void OnSettingsCleared() override;

  bool Load();
  /*! \brief Load the user profile information from disk
    Loads the profiles.xml file and creates the list of profiles.
    If no profiles exist, a master user is created. Should be called
    after special://masterprofile/ has been defined.
    \param file XML file to load.
    */

  bool Save() const;
  /*! \brief Save the user profile information to disk
    Saves the list of profiles to the profiles.xml file.
    \param file XML file to save.
    \return true on success, false on failure to save
    */

  void Clear();

  bool LoadProfile(unsigned int index);
  void LogOff();

  bool DeleteProfile(unsigned int index);

  void CreateProfileFolders();

  /*! \brief Retrieve the master profile
    \return const reference to the master profile
    */
  const CProfile& GetMasterProfile() const;

  /*! \brief Retrieve the current profile
    \return const reference to the current profile
    */
  const CProfile& GetCurrentProfile() const;

  /*! \brief Retrieve the profile from an index
    \param unsigned index of the profile to retrieve
    \return const pointer to the profile, NULL if the index is invalid
    */
  const CProfile* GetProfile(unsigned int index) const;

  /*! \brief Retrieve the profile from an index
    \param unsigned index of the profile to retrieve
    \return pointer to the profile, NULL if the index is invalid
    */
  CProfile* GetProfile(unsigned int index);

  /*! \brief Retrieve index of a particular profile by name
    \param name name of the profile index to retrieve
    \return index of this profile, -1 if invalid.
    */
  int GetProfileIndex(const std::string &name) const;

  /*! \brief Retrieve the number of profiles
    \return number of profiles
    */
  size_t GetNumberOfProfiles() const { return m_profiles.size(); }

  /*! \brief Add a new profile
    \param profile CProfile to add
    */
  void AddProfile(const CProfile &profile);

  /*! \brief Are we using the login screen?
    \return true if we're using the login screen, false otherwise
    */
  bool UsingLoginScreen() const { return m_usingLoginScreen; }

  /*! \brief Toggle login screen use on and off
    Toggles the login screen state
    */
  void ToggleLoginScreen()
  {
    m_usingLoginScreen = !m_usingLoginScreen;
    Save();
  }

  /*! \brief Are we the master user?
    \return true if the current profile is the master user, false otherwise
    */
  bool IsMasterProfile() const { return m_currentProfile == 0; }

  /*! \brief Update the date of the current profile
    */
  void UpdateCurrentProfileDate();

  /*! \brief Load the master user for the purposes of logging in
    Loads the master user.  Identical to LoadProfile(0) but doesn't
    update the last logged in details
    */
  void LoadMasterProfileForLogin();

  /*! \brief Retrieve the last used profile index
    \return the last used profile that logged in.  Does not count the
    master user during login.
    */
  uint32_t GetLastUsedProfileIndex() const { return m_lastUsedProfile; }

  /*! \brief Retrieve the current profile index
    \return the index of the currently logged in profile.
    */
  uint32_t GetCurrentProfileIndex() const { return m_currentProfile; }

  /*! \brief Retrieve the next id to use for a new profile
    \return the unique <id> to be used when creating a new profile
    */
  int GetNextProfileId() const { return m_nextProfileId; }

  int GetCurrentProfileId() const { return GetCurrentProfile().getId(); }

  /*! \brief Retrieve the autologin profile id
    Retrieves the autologin profile id. When set to -1, then the last
    used profile will be loaded
    \return the id to the autologin profile
    */
  int GetAutoLoginProfileId() const { return m_autoLoginProfile; }

  /*! \brief Retrieve the autologin profile id
    Retrieves the autologin profile id. When set to -1, then the last
    used profile will be loaded
    \return the id to the autologin profile
    */
  void SetAutoLoginProfileId(const int profileId)
  {
    m_autoLoginProfile = profileId;
    Save();
  }

  /*! \brief Retrieve the name of a particular profile by index
    \param profileId profile index for which to retrieve the name
    \param name will hold the name of the profile when a valid profile index has been provided
    \return false if profileId is an invalid index, true if the name parameter is set
    */
  bool GetProfileName(const unsigned int profileId, std::string& name) const;

  std::string GetUserDataFolder() const;
  std::string GetProfileUserDataFolder() const;
  std::string GetDatabaseFolder() const;
  std::string GetCDDBFolder() const;
  std::string GetThumbnailsFolder() const;
  std::string GetVideoThumbFolder() const;
  std::string GetBookmarksThumbFolder() const;
  std::string GetLibraryFolder() const;
  std::string GetSavestatesFolder() const;
  std::string GetSettingsFile() const;

  // uses HasSlashAtEnd to determine if a directory or file was meant
  std::string GetUserDataItem(const std::string& strFile) const;

  // Event log access
  CEventLog &GetEventLog();

protected:
  // implementation of ISettingCallback
  void OnSettingAction(const std::shared_ptr<const CSetting>& setting) override;

private:
  /*! \brief Set the current profile id and update the special://profile path
    \param profileId profile index
    */
  void SetCurrentProfileId(unsigned int profileId);

  void PrepareLoadProfile(unsigned int profileIndex);
  void FinalizeLoadProfile();

  // Construction parameters
  std::shared_ptr<CSettings> m_settings;

  std::vector<CProfile> m_profiles;
  bool m_usingLoginScreen = false;
  bool m_profileLoadedForLogin = false;
  bool m_previousProfileLoadedForLogin = false;
  int m_autoLoginProfile = -1;
  unsigned int m_lastUsedProfile = 0;
  unsigned int m_currentProfile =
      0; // do not modify directly, use SetCurrentProfileId() function instead
  int m_nextProfileId =
      0; // for tracking the next available id to give to a new profile to ensure id's are not re-used
  mutable CCriticalSection m_critical;

  // Event properties
  std::unique_ptr<CEventLogManager> m_eventLogs;
};