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