Home | History | Annotate | Download | only in libgtk2ui
      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