dom/system/gonk/AutoMounterSetting.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "AutoMounter.h"
     6 #include "AutoMounterSetting.h"
     8 #include "base/message_loop.h"
     9 #include "jsapi.h"
    10 #include "mozilla/Services.h"
    11 #include "nsCOMPtr.h"
    12 #include "nsDebug.h"
    13 #include "nsIObserverService.h"
    14 #include "nsCxPusher.h"
    15 #include "nsISettingsService.h"
    16 #include "nsJSUtils.h"
    17 #include "nsPrintfCString.h"
    18 #include "nsServiceManagerUtils.h"
    19 #include "nsString.h"
    20 #include "nsThreadUtils.h"
    21 #include "xpcpublic.h"
    22 #include "mozilla/Attributes.h"
    24 #undef LOG
    25 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "AutoMounterSetting" , ## args)
    26 #define ERR(args...)  __android_log_print(ANDROID_LOG_ERROR, "AutoMounterSetting" , ## args)
    28 #define UMS_MODE                  "ums.mode"
    29 #define UMS_STATUS                "ums.status"
    30 #define UMS_VOLUME_ENABLED_PREFIX "ums.volume."
    31 #define UMS_VOLUME_ENABLED_SUFFIX ".enabled"
    32 #define MOZSETTINGS_CHANGED       "mozsettings-changed"
    34 namespace mozilla {
    35 namespace system {
    37 class SettingsServiceCallback MOZ_FINAL : public nsISettingsServiceCallback
    38 {
    39 public:
    40   NS_DECL_THREADSAFE_ISUPPORTS
    42   SettingsServiceCallback() {}
    44   NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
    45   {
    46     if (JSVAL_IS_INT(aResult)) {
    47       int32_t mode = JSVAL_TO_INT(aResult);
    48       SetAutoMounterMode(mode);
    49     }
    50     return NS_OK;
    51   }
    53   NS_IMETHOD HandleError(const nsAString& aName)
    54   {
    55     ERR("SettingsCallback::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get());
    56     return NS_OK;
    57   }
    58 };
    60 NS_IMPL_ISUPPORTS(SettingsServiceCallback, nsISettingsServiceCallback)
    62 class CheckVolumeSettingsCallback MOZ_FINAL : public nsISettingsServiceCallback
    63 {
    64 public:
    65   NS_DECL_THREADSAFE_ISUPPORTS
    67   CheckVolumeSettingsCallback(const nsACString& aVolumeName)
    68   : mVolumeName(aVolumeName) {}
    70   NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
    71   {
    72     if (JSVAL_IS_BOOLEAN(aResult)) {
    73       bool isSharingEnabled = JSVAL_TO_BOOLEAN(aResult);
    74       SetAutoMounterSharingMode(mVolumeName, isSharingEnabled);
    75     }
    76     return NS_OK;
    77   }
    79   NS_IMETHOD HandleError(const nsAString& aName)
    80   {
    81     ERR("CheckVolumeSettingsCallback::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get());
    82     return NS_OK;
    83   }
    84 private:
    85   nsCString mVolumeName;
    86 };
    88 NS_IMPL_ISUPPORTS(CheckVolumeSettingsCallback, nsISettingsServiceCallback)
    90 AutoMounterSetting::AutoMounterSetting()
    91   : mStatus(AUTOMOUNTER_STATUS_DISABLED)
    92 {
    93   MOZ_ASSERT(NS_IsMainThread());
    95   // Setup an observer to watch changes to the setting
    96   nsCOMPtr<nsIObserverService> observerService =
    97     mozilla::services::GetObserverService();
    98   if (!observerService) {
    99     ERR("GetObserverService failed");
   100     return;
   101   }
   102   nsresult rv;
   103   rv = observerService->AddObserver(this, MOZSETTINGS_CHANGED, false);
   104   if (NS_FAILED(rv)) {
   105     ERR("AddObserver failed");
   106     return;
   107   }
   109   // Force ums.mode to be 0 initially. We do this because settings are persisted.
   110   // We don't want UMS to be enabled until such time as the phone is unlocked,
   111   // and gaia/apps/system/js/storage.js takes care of detecting when the phone
   112   // becomes unlocked and changes ums.mode appropriately.
   113   nsCOMPtr<nsISettingsService> settingsService =
   114     do_GetService("@mozilla.org/settingsService;1");
   115   if (!settingsService) {
   116     ERR("Failed to get settingsLock service!");
   117     return;
   118   }
   119   nsCOMPtr<nsISettingsServiceLock> lock;
   120   settingsService->CreateLock(nullptr, getter_AddRefs(lock));
   121   nsCOMPtr<nsISettingsServiceCallback> callback = new SettingsServiceCallback();
   122   mozilla::AutoSafeJSContext cx;
   123   JS::Rooted<JS::Value> value(cx);
   124   value.setInt32(AUTOMOUNTER_DISABLE);
   125   lock->Set(UMS_MODE, value, callback, nullptr);
   126   value.setInt32(mStatus);
   127   lock->Set(UMS_STATUS, value, nullptr, nullptr);
   128 }
   130 AutoMounterSetting::~AutoMounterSetting()
   131 {
   132   nsCOMPtr<nsIObserverService> observerService =
   133     mozilla::services::GetObserverService();
   134   if (observerService) {
   135     observerService->RemoveObserver(this, MOZSETTINGS_CHANGED);
   136   }
   137 }
   139 NS_IMPL_ISUPPORTS(AutoMounterSetting, nsIObserver)
   141 const char *
   142 AutoMounterSetting::StatusStr(int32_t aStatus)
   143 {
   144   switch (aStatus) {
   145     case AUTOMOUNTER_STATUS_DISABLED:   return "Disabled";
   146     case AUTOMOUNTER_STATUS_ENABLED:    return "Enabled";
   147     case AUTOMOUNTER_STATUS_FILES_OPEN: return "FilesOpen";
   148   }
   149   return "??? Unknown ???";
   150 }
   152 class CheckVolumeSettingsRunnable : public nsRunnable
   153 {
   154 public:
   155   CheckVolumeSettingsRunnable(const nsACString& aVolumeName)
   156     : mVolumeName(aVolumeName) {}
   158   NS_IMETHOD Run()
   159   {
   160     MOZ_ASSERT(NS_IsMainThread());
   161     nsCOMPtr<nsISettingsService> settingsService =
   162       do_GetService("@mozilla.org/settingsService;1");
   163     NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
   164     nsCOMPtr<nsISettingsServiceLock> lock;
   165     settingsService->CreateLock(nullptr, getter_AddRefs(lock));
   166     nsCOMPtr<nsISettingsServiceCallback> callback =
   167       new CheckVolumeSettingsCallback(mVolumeName);
   168     nsPrintfCString setting(UMS_VOLUME_ENABLED_PREFIX "%s" UMS_VOLUME_ENABLED_SUFFIX,
   169                             mVolumeName.get());
   170     lock->Get(setting.get(), callback);
   171     return NS_OK;
   172   }
   174 private:
   175   nsCString mVolumeName;
   176 };
   178 //static
   179 void
   180 AutoMounterSetting::CheckVolumeSettings(const nsACString& aVolumeName)
   181 {
   182   NS_DispatchToMainThread(new CheckVolumeSettingsRunnable(aVolumeName));
   183 }
   185 class SetStatusRunnable : public nsRunnable
   186 {
   187 public:
   188   SetStatusRunnable(int32_t aStatus) : mStatus(aStatus) {}
   190   NS_IMETHOD Run()
   191   {
   192     MOZ_ASSERT(NS_IsMainThread());
   193     nsCOMPtr<nsISettingsService> settingsService =
   194       do_GetService("@mozilla.org/settingsService;1");
   195     NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
   196     nsCOMPtr<nsISettingsServiceLock> lock;
   197     settingsService->CreateLock(nullptr, getter_AddRefs(lock));
   198     // lock may be null if this gets called during shutdown.
   199     if (lock) {
   200       mozilla::AutoSafeJSContext cx;
   201       JS::Rooted<JS::Value> value(cx, JS::Int32Value(mStatus));
   202       lock->Set(UMS_STATUS, value, nullptr, nullptr);
   203     }
   204     return NS_OK;
   205   }
   207 private:
   208   int32_t mStatus;
   209 };
   211 //static
   212 void
   213 AutoMounterSetting::SetStatus(int32_t aStatus)
   214 {
   215   if (aStatus != mStatus) {
   216     LOG("Changing status from '%s' to '%s'",
   217         StatusStr(mStatus), StatusStr(aStatus));
   218     mStatus = aStatus;
   219     NS_DispatchToMainThread(new SetStatusRunnable(aStatus));
   220   }
   221 }
   223 NS_IMETHODIMP
   224 AutoMounterSetting::Observe(nsISupports* aSubject,
   225                             const char* aTopic,
   226                             const char16_t* aData)
   227 {
   228   if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) {
   229     return NS_OK;
   230   }
   232   // Note that this function gets called for any and all settings changes,
   233   // so we need to carefully check if we have the one we're interested in.
   234   //
   235   // The string that we're interested in will be a JSON string that looks like:
   236   //  {"key":"ums.autoMount","value":true}
   238   mozilla::AutoSafeJSContext cx;
   239   nsDependentString dataStr(aData);
   240   JS::Rooted<JS::Value> val(cx);
   241   if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val) ||
   242       !val.isObject()) {
   243     return NS_OK;
   244   }
   245   JS::Rooted<JSObject*> obj(cx, &val.toObject());
   246   JS::Rooted<JS::Value> key(cx);
   247   if (!JS_GetProperty(cx, obj, "key", &key) ||
   248       !key.isString()) {
   249     return NS_OK;
   250   }
   252   JSString *jsKey = JS::ToString(cx, key);
   253   nsDependentJSString keyStr;
   254   if (!keyStr.init(cx, jsKey)) {
   255     return NS_OK;
   256   }
   258   JS::Rooted<JS::Value> value(cx);
   259   if (!JS_GetProperty(cx, obj, "value", &value)) {
   260     return NS_OK;
   261   }
   263   // Check for ums.mode changes
   264   if (keyStr.EqualsLiteral(UMS_MODE)) {
   265     if (!value.isInt32()) {
   266       return NS_OK;
   267     }
   268     int32_t mode = value.toInt32();
   269     SetAutoMounterMode(mode);
   270     return NS_OK;
   271   }
   273   // Check for ums.volume.NAME.enabled
   274   if (StringBeginsWith(keyStr, NS_LITERAL_STRING(UMS_VOLUME_ENABLED_PREFIX)) &&
   275       StringEndsWith(keyStr, NS_LITERAL_STRING(UMS_VOLUME_ENABLED_SUFFIX))) {
   276     if (!value.isBoolean()) {
   277       return NS_OK;
   278     }
   279     const size_t prefixLen = sizeof(UMS_VOLUME_ENABLED_PREFIX) - 1;
   280     const size_t suffixLen = sizeof(UMS_VOLUME_ENABLED_SUFFIX) - 1;
   281     nsDependentSubstring volumeName =
   282       Substring(keyStr, prefixLen, keyStr.Length() - prefixLen - suffixLen);
   283     bool isSharingEnabled = value.toBoolean();
   284     SetAutoMounterSharingMode(NS_LossyConvertUTF16toASCII(volumeName), isSharingEnabled);
   285     return NS_OK;
   286   }
   288   return NS_OK;
   289 }
   291 }   // namespace system
   292 }   // namespace mozilla

mercurial