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 if (GetDesktopEnvironment(env.get()) != base::nix::DESKTOP_ENVIRONMENT_UNITY) 64 return; 65 66 // Ubuntu still hasn't given us a nice libunity.so symlink. 67 void* unity_lib = dlopen("libunity.so.4", RTLD_LAZY); 68 if (!unity_lib) 69 unity_lib = dlopen("libunity.so.6", RTLD_LAZY); 70 if (!unity_lib) 71 unity_lib = dlopen("libunity.so.9", RTLD_LAZY); 72 if (!unity_lib) 73 return; 74 75 unity_inspector_get_default_func inspector_get_default = 76 reinterpret_cast<unity_inspector_get_default_func>( 77 dlsym(unity_lib, "unity_inspector_get_default")); 78 if (inspector_get_default) { 79 inspector = inspector_get_default(); 80 81 get_unity_running = 82 reinterpret_cast<unity_inspector_get_unity_running_func>( 83 dlsym(unity_lib, "unity_inspector_get_unity_running")); 84 } 85 86 unity_launcher_entry_get_for_desktop_id_func entry_get_for_desktop_id = 87 reinterpret_cast<unity_launcher_entry_get_for_desktop_id_func>( 88 dlsym(unity_lib, "unity_launcher_entry_get_for_desktop_id")); 89 if (entry_get_for_desktop_id) { 90 std::string desktop_id = libgtk2ui::GetDesktopName(env.get()); 91 chrome_entry = entry_get_for_desktop_id(desktop_id.c_str()); 92 93 entry_set_count = 94 reinterpret_cast<unity_launcher_entry_set_count_func>( 95 dlsym(unity_lib, "unity_launcher_entry_set_count")); 96 97 entry_set_count_visible = 98 reinterpret_cast<unity_launcher_entry_set_count_visible_func>( 99 dlsym(unity_lib, "unity_launcher_entry_set_count_visible")); 100 101 entry_set_progress = 102 reinterpret_cast<unity_launcher_entry_set_progress_func>( 103 dlsym(unity_lib, "unity_launcher_entry_set_progress")); 104 105 entry_set_progress_visible = 106 reinterpret_cast<unity_launcher_entry_set_progress_visible_func>( 107 dlsym(unity_lib, "unity_launcher_entry_set_progress_visible")); 108 } 109 } 110 111 } // namespace 112 113 114 namespace unity { 115 116 bool IsRunning() { 117 EnsureMethodsLoaded(); 118 if (inspector && get_unity_running) 119 return get_unity_running(inspector); 120 121 return false; 122 } 123 124 void SetDownloadCount(int count) { 125 EnsureMethodsLoaded(); 126 if (chrome_entry && entry_set_count && entry_set_count_visible) { 127 entry_set_count(chrome_entry, count); 128 entry_set_count_visible(chrome_entry, count != 0); 129 } 130 } 131 132 void SetProgressFraction(float percentage) { 133 EnsureMethodsLoaded(); 134 if (chrome_entry && entry_set_progress && entry_set_progress_visible) { 135 entry_set_progress(chrome_entry, percentage); 136 entry_set_progress_visible(chrome_entry, 137 percentage > 0.0 && percentage < 1.0); 138 } 139 } 140 141 } // namespace unity 142