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