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. 19typedef struct _UnityInspector UnityInspector; 20typedef UnityInspector* (*unity_inspector_get_default_func)(void); 21typedef gboolean (*unity_inspector_get_unity_running_func) 22 (UnityInspector* self); 23 24typedef struct _UnityLauncherEntry UnityLauncherEntry; 25typedef UnityLauncherEntry* (*unity_launcher_entry_get_for_desktop_id_func) 26 (const gchar* desktop_id); 27typedef void (*unity_launcher_entry_set_count_func)(UnityLauncherEntry* self, 28 gint64 value); 29typedef void (*unity_launcher_entry_set_count_visible_func) 30 (UnityLauncherEntry* self, gboolean value); 31typedef void (*unity_launcher_entry_set_progress_func)(UnityLauncherEntry* self, 32 gdouble value); 33typedef void (*unity_launcher_entry_set_progress_visible_func) 34 (UnityLauncherEntry* self, gboolean value); 35 36 37namespace { 38 39bool attempted_load = false; 40 41// Unity has a singleton object that we can ask whether the unity is running. 42UnityInspector* inspector = NULL; 43 44// A link to the desktop entry in the panel. 45UnityLauncherEntry* chrome_entry = NULL; 46 47// Retrieved functions from libunity. 48unity_inspector_get_unity_running_func get_unity_running = NULL; 49unity_launcher_entry_set_count_func entry_set_count = NULL; 50unity_launcher_entry_set_count_visible_func entry_set_count_visible = NULL; 51unity_launcher_entry_set_progress_func entry_set_progress = NULL; 52unity_launcher_entry_set_progress_visible_func entry_set_progress_visible = 53 NULL; 54 55void 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 114namespace unity { 115 116bool IsRunning() { 117 EnsureMethodsLoaded(); 118 if (inspector && get_unity_running) 119 return get_unity_running(inspector); 120 121 return false; 122} 123 124void 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 132void 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