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