unity_service.cc 4.8 KB

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