unity_service.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright 2013 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. #include "shell/browser/linux/unity_service.h"
  5. #include <dlfcn.h>
  6. #include <gtk/gtk.h>
  7. #include <memory>
  8. #include <string>
  9. #include "base/environment.h"
  10. #include "base/nix/xdg_util.h"
  11. // Unity data typedefs.
  12. typedef struct _UnityInspector UnityInspector;
  13. typedef UnityInspector* (*unity_inspector_get_default_func)();
  14. typedef gboolean (*unity_inspector_get_unity_running_func)(
  15. UnityInspector* self);
  16. typedef struct _UnityLauncherEntry UnityLauncherEntry;
  17. typedef UnityLauncherEntry* (*unity_launcher_entry_get_for_desktop_id_func)(
  18. const gchar* desktop_id);
  19. typedef void (*unity_launcher_entry_set_count_func)(UnityLauncherEntry* self,
  20. gint64 value);
  21. typedef void (*unity_launcher_entry_set_count_visible_func)(
  22. UnityLauncherEntry* self,
  23. gboolean value);
  24. typedef void (*unity_launcher_entry_set_progress_func)(UnityLauncherEntry* self,
  25. gdouble value);
  26. typedef void (*unity_launcher_entry_set_progress_visible_func)(
  27. UnityLauncherEntry* self,
  28. gboolean value);
  29. namespace {
  30. bool attempted_load = false;
  31. // Unity has a singleton object that we can ask whether the unity is running.
  32. UnityInspector* inspector = nullptr;
  33. // A link to the desktop entry in the panel.
  34. UnityLauncherEntry* chrome_entry = nullptr;
  35. // Retrieved functions from libunity.
  36. unity_inspector_get_unity_running_func get_unity_running = nullptr;
  37. unity_launcher_entry_set_count_func entry_set_count = nullptr;
  38. unity_launcher_entry_set_count_visible_func entry_set_count_visible = nullptr;
  39. unity_launcher_entry_set_progress_func entry_set_progress = nullptr;
  40. unity_launcher_entry_set_progress_visible_func entry_set_progress_visible =
  41. nullptr;
  42. void EnsureLibUnityLoaded() {
  43. using base::nix::GetDesktopEnvironment;
  44. if (attempted_load)
  45. return;
  46. attempted_load = true;
  47. auto env = base::Environment::Create();
  48. base::nix::DesktopEnvironment desktop_env = GetDesktopEnvironment(env.get());
  49. // The "icon-tasks" KDE task manager also honors Unity Launcher API.
  50. if (desktop_env != base::nix::DESKTOP_ENVIRONMENT_UNITY &&
  51. desktop_env != base::nix::DESKTOP_ENVIRONMENT_KDE4 &&
  52. desktop_env != base::nix::DESKTOP_ENVIRONMENT_KDE5)
  53. return;
  54. // Ubuntu still hasn't given us a nice libunity.so symlink.
  55. void* unity_lib = dlopen("libunity.so.4", RTLD_LAZY);
  56. if (!unity_lib)
  57. unity_lib = dlopen("libunity.so.6", RTLD_LAZY);
  58. if (!unity_lib)
  59. unity_lib = dlopen("libunity.so.9", RTLD_LAZY);
  60. if (!unity_lib)
  61. return;
  62. unity_inspector_get_default_func inspector_get_default =
  63. reinterpret_cast<unity_inspector_get_default_func>(
  64. dlsym(unity_lib, "unity_inspector_get_default"));
  65. if (inspector_get_default) {
  66. inspector = inspector_get_default();
  67. get_unity_running =
  68. reinterpret_cast<unity_inspector_get_unity_running_func>(
  69. dlsym(unity_lib, "unity_inspector_get_unity_running"));
  70. }
  71. unity_launcher_entry_get_for_desktop_id_func entry_get_for_desktop_id =
  72. reinterpret_cast<unity_launcher_entry_get_for_desktop_id_func>(
  73. dlsym(unity_lib, "unity_launcher_entry_get_for_desktop_id"));
  74. if (entry_get_for_desktop_id) {
  75. std::string desktop_id = getenv("CHROME_DESKTOP");
  76. chrome_entry = entry_get_for_desktop_id(desktop_id.c_str());
  77. entry_set_count = reinterpret_cast<unity_launcher_entry_set_count_func>(
  78. dlsym(unity_lib, "unity_launcher_entry_set_count"));
  79. entry_set_count_visible =
  80. reinterpret_cast<unity_launcher_entry_set_count_visible_func>(
  81. dlsym(unity_lib, "unity_launcher_entry_set_count_visible"));
  82. entry_set_progress =
  83. reinterpret_cast<unity_launcher_entry_set_progress_func>(
  84. dlsym(unity_lib, "unity_launcher_entry_set_progress"));
  85. entry_set_progress_visible =
  86. reinterpret_cast<unity_launcher_entry_set_progress_visible_func>(
  87. dlsym(unity_lib, "unity_launcher_entry_set_progress_visible"));
  88. }
  89. }
  90. } // namespace
  91. namespace unity {
  92. bool IsRunning() {
  93. EnsureLibUnityLoaded();
  94. if (inspector && get_unity_running)
  95. return get_unity_running(inspector);
  96. return false;
  97. }
  98. void SetDownloadCount(int count) {
  99. EnsureLibUnityLoaded();
  100. if (chrome_entry && entry_set_count && entry_set_count_visible) {
  101. entry_set_count(chrome_entry, count);
  102. entry_set_count_visible(chrome_entry, count != 0);
  103. }
  104. }
  105. void SetProgressFraction(float percentage) {
  106. EnsureLibUnityLoaded();
  107. if (chrome_entry && entry_set_progress && entry_set_progress_visible) {
  108. entry_set_progress(chrome_entry, percentage);
  109. entry_set_progress_visible(chrome_entry,
  110. percentage > 0.0 && percentage < 1.0);
  111. }
  112. }
  113. } // namespace unity