language_pack_manager.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef CHROMEOS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
  5. #define CHROMEOS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_
  6. #include <string>
  7. #include "base/callback.h"
  8. #include "base/no_destructor.h"
  9. #include "base/observer_list.h"
  10. #include "base/strings/strcat.h"
  11. #include "chromeos/dbus/dlcservice/dlcservice_client.h"
  12. namespace chromeos::language_packs {
  13. // All Language Pack IDs are listed here.
  14. constexpr char kHandwritingFeatureId[] = "LP_ID_HANDWRITING";
  15. constexpr char kTtsFeatureId[] = "LP_ID_TTS";
  16. // Status contains information about the status of a Language Pack operation.
  17. struct PackResult {
  18. // This string contains the error returns by DLC Service.
  19. std::string operation_error;
  20. enum StatusCode {
  21. UNKNOWN = 0,
  22. WRONG_ID,
  23. NOT_INSTALLED,
  24. IN_PROGRESS,
  25. INSTALLED
  26. };
  27. // The code that indicates the current state of the Pack.
  28. // INSTALLED means that the Pack is ready to be used.
  29. StatusCode pack_state;
  30. // The path where the Pack is available for users to use.
  31. std::string path;
  32. };
  33. // We define an internal type to identify a Language Pack.
  34. // It's a pair of featured_id and locale that is hashable.
  35. struct PackSpecPair {
  36. std::string feature_id;
  37. std::string locale;
  38. PackSpecPair(const std::string& feature_id, const std::string& locale)
  39. : feature_id(feature_id), locale(locale) {}
  40. bool operator==(const PackSpecPair& other) const {
  41. return (feature_id == other.feature_id && locale == other.locale);
  42. }
  43. bool operator!=(const PackSpecPair& other) const { return !(*this == other); }
  44. // Allows PackSpecPair to be used as a key in STL containers, like flat_map.
  45. bool operator<(const PackSpecPair& other) const {
  46. if (feature_id == other.feature_id)
  47. return locale < other.locale;
  48. return feature_id < other.feature_id;
  49. }
  50. // Simple hash function: XOR the string hash.
  51. struct HashFunction {
  52. size_t operator()(const PackSpecPair& obj) const {
  53. size_t first_hash = std::hash<std::string>()(obj.feature_id);
  54. size_t second_hash = std::hash<std::string>()(obj.locale) << 1;
  55. return first_hash ^ second_hash;
  56. }
  57. };
  58. };
  59. using OnInstallCompleteCallback =
  60. base::OnceCallback<void(const PackResult& pack_result)>;
  61. using GetPackStateCallback =
  62. base::OnceCallback<void(const PackResult& pack_result)>;
  63. using OnUninstallCompleteCallback =
  64. base::OnceCallback<void(const PackResult& pack_result)>;
  65. using OnInstallBasePackCompleteCallback =
  66. base::OnceCallback<void(const PackResult& pack_result)>;
  67. // This class manages all Language Packs and their dependencies (called Base
  68. // Packs) on the device.
  69. // This is a Singleton and needs to be accessed via Get().
  70. class LanguagePackManager : public DlcserviceClient::Observer {
  71. public:
  72. // Observer of Language Packs.
  73. // TODO(crbug.com/1194688): Make the Observers dependent on feature and
  74. // locale, so that clients don't get notified for things they are not
  75. // interested in.
  76. class Observer : public base::CheckedObserver {
  77. public:
  78. // Called whenever the state of a Language Pack changes, which includes
  79. // installation, download, removal or errors.
  80. virtual void OnPackStateChanged(const PackResult& pack_result) = 0;
  81. };
  82. // Disallow copy and assign.
  83. LanguagePackManager(const LanguagePackManager&) = delete;
  84. LanguagePackManager& operator=(const LanguagePackManager&) = delete;
  85. // Returns true if the given Language Pack exists and can be installed on
  86. // this device.
  87. // TODO(claudiomagni): Check per board.
  88. bool IsPackAvailable(const std::string& feature_id,
  89. const std::string& locale);
  90. // Installs the Language Pack.
  91. // It takes a callback that will be triggered once the operation is done.
  92. // A state is passed to the callback.
  93. void InstallPack(const std::string& feature_id,
  94. const std::string& locale,
  95. OnInstallCompleteCallback callback);
  96. // Checks the state of a Language Pack.
  97. // It takes a callback that will be triggered once the operation is done.
  98. // A state is passed to the callback.
  99. // If the state marks the Language Pack as ready, then there's no need to
  100. // call Install(), otherwise the client should call Install() and not call
  101. // this method a second time.
  102. void GetPackState(const std::string& feature_id,
  103. const std::string& locale,
  104. GetPackStateCallback callback);
  105. // Features should call this method to indicate that they do not intend to
  106. // use the Pack again, until they will call |InstallPack()|.
  107. // The Language Pack will be removed from disk, but no guarantee is given on
  108. // when that will happen.
  109. // TODO(claudiomagni): Allow callers to force immediate removal. Useful to
  110. // clear space on disk for another language.
  111. void RemovePack(const std::string& feature_id,
  112. const std::string& locale,
  113. OnUninstallCompleteCallback callback);
  114. // Explicitly installs the base pack for |feature_id|.
  115. void InstallBasePack(const std::string& feature_id,
  116. OnInstallBasePackCompleteCallback callback);
  117. // Adds an observer to the observer list.
  118. void AddObserver(Observer* observer);
  119. // Removes an observer from the observer list.
  120. void RemoveObserver(Observer* observer);
  121. // Must be called before using the class.
  122. void Initialize();
  123. // Testing only: called to free up resources since this object should never
  124. // be destroyed.
  125. void ResetForTesting();
  126. // Returns the global instance..
  127. static LanguagePackManager* GetInstance();
  128. private:
  129. friend base::NoDestructor<LanguagePackManager>;
  130. // This class should be accessed only via GetInstance();
  131. LanguagePackManager();
  132. ~LanguagePackManager() override;
  133. // DlcserviceClient::Observer overrides.
  134. void OnDlcStateChanged(const dlcservice::DlcState& dlc_state) override;
  135. // Notification method called upon change of DLCs state.
  136. void NotifyPackStateChanged(const dlcservice::DlcState& dlc_state);
  137. base::ObserverList<Observer> observers_;
  138. };
  139. } // namespace chromeos::language_packs
  140. #endif // CHROMEOS_LANGUAGE_LANGUAGE_PACKS_LANGUAGE_PACK_MANAGER_H_