Home | History | Annotate | Download | only in fileapi
      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/media_galleries/fileapi/picasa_finder.h"
      6 
      7 #if defined(OS_WIN)
      8 #include <windows.h>
      9 #endif
     10 
     11 #include "base/base_paths.h"
     12 #include "base/bind.h"
     13 #include "base/file_util.h"
     14 #include "base/path_service.h"
     15 #include "base/strings/string16.h"
     16 #include "chrome/common/media_galleries/picasa_types.h"
     17 #include "components/storage_monitor/storage_info.h"
     18 #include "content/public/browser/browser_thread.h"
     19 
     20 #if defined(OS_WIN)
     21 #include "base/win/registry.h"
     22 #endif
     23 
     24 namespace picasa {
     25 
     26 #if defined(OS_WIN)
     27 const wchar_t kPicasaRegistryPath[] =
     28     L"Software\\Google\\Picasa\\Picasa2\\Preferences";
     29 const wchar_t kPicasaRegistryAppDataPathKey[] = L"AppLocalDataPath";
     30 #endif
     31 
     32 namespace {
     33 
     34 #if defined(OS_WIN)
     35 base::FilePath GetCustomPicasaAppDataPathFromWinRegistry() {
     36   base::win::RegKey key;
     37   if (key.Open(HKEY_CURRENT_USER, kPicasaRegistryPath, KEY_READ) !=
     38           ERROR_SUCCESS || !key.Valid()) {
     39     return base::FilePath();
     40   }
     41 
     42   base::string16 value;
     43   if (key.ReadValue(kPicasaRegistryAppDataPathKey, &value) != ERROR_SUCCESS)
     44     return base::FilePath();
     45   if (value.empty())
     46     return base::FilePath();
     47 
     48   return base::FilePath(value);
     49 }
     50 
     51 base::FilePath GetPicasaDatabasePath() {
     52   base::FilePath path = GetCustomPicasaAppDataPathFromWinRegistry();
     53   if (path.empty() && !PathService::Get(base::DIR_LOCAL_APP_DATA, &path))
     54     return base::FilePath();
     55   return MakePicasaDatabasePath(path);
     56 }
     57 #endif  // OS_WIN
     58 
     59 #if defined(OS_MACOSX)
     60 base::FilePath GetPicasaDatabasePath() {
     61   base::FilePath path = GetCustomPicasaAppDataPathFromMacPreferences();
     62   if (path.empty() && !PathService::Get(base::DIR_APP_DATA, &path))
     63     return base::FilePath();
     64   return MakePicasaDatabasePath(path);
     65 }
     66 #endif  // OS_MACOSX
     67 
     68 // Returns path of Picasa's DB3 database directory. May only be called on
     69 // threads that allow for disk IO, like the FILE thread or MediaTaskRunner.
     70 base::FilePath FindPicasaDatabaseOnFileThread() {
     71   DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
     72 
     73 #if defined(OS_WIN) || defined(OS_MACOSX)
     74    base::FilePath path = GetPicasaDatabasePath();
     75    // Verify actual existence
     76    if (!base::DirectoryExists(path))
     77      path.clear();
     78 
     79    return path;
     80 #else
     81    return base::FilePath();
     82 #endif
     83 }
     84 
     85 void FinishOnOriginalThread(const DeviceIDCallback& callback,
     86                             const base::FilePath& database_path) {
     87   std::string device_id;
     88   if (!database_path.empty()) {
     89     device_id = storage_monitor::StorageInfo::MakeDeviceId(
     90         storage_monitor::StorageInfo::PICASA, database_path.AsUTF8Unsafe());
     91   }
     92   callback.Run(device_id);
     93 }
     94 
     95 }  // namespace
     96 
     97 void FindPicasaDatabase(const DeviceIDCallback& callback) {
     98   content::BrowserThread::PostTaskAndReplyWithResult(
     99       content::BrowserThread::FILE,
    100       FROM_HERE,
    101       base::Bind(&FindPicasaDatabaseOnFileThread),
    102       base::Bind(&FinishOnOriginalThread, callback));
    103 }
    104 
    105 base::FilePath MakePicasaDatabasePath(
    106     const base::FilePath& picasa_app_data_path) {
    107 #if defined(OS_WIN)
    108   return picasa_app_data_path.AppendASCII("Google").AppendASCII("Picasa2")
    109       .AppendASCII(kPicasaDatabaseDirName);
    110 #elif defined(OS_MACOSX)
    111   return picasa_app_data_path.AppendASCII("Google").AppendASCII("Picasa3")
    112       .AppendASCII(kPicasaDatabaseDirName);
    113 #else
    114   return base::FilePath();
    115 #endif
    116 }
    117 
    118 }  // namespace picasa
    119