dom/system/gonk/nsVolumeMountLock.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 "nsVolumeMountLock.h"
     7 #include "mozilla/dom/ContentChild.h"
     8 #include "mozilla/Services.h"
    10 #include "nsIObserverService.h"
    11 #include "nsIPowerManagerService.h"
    12 #include "nsIVolume.h"
    13 #include "nsIVolumeService.h"
    14 #include "nsString.h"
    15 #include "nsXULAppAPI.h"
    17 #define VOLUME_MANAGER_LOG_TAG  "nsVolumeMountLock"
    18 #include "VolumeManagerLog.h"
    19 #include "nsServiceManagerUtils.h"
    20 #include "mozilla/dom/power/PowerManagerService.h"
    22 using namespace mozilla::dom;
    23 using namespace mozilla::services;
    25 namespace mozilla {
    26 namespace system {
    28 NS_IMPL_ISUPPORTS(nsVolumeMountLock, nsIVolumeMountLock,
    29                   nsIObserver, nsISupportsWeakReference)
    31 // static
    32 already_AddRefed<nsVolumeMountLock>
    33 nsVolumeMountLock::Create(const nsAString& aVolumeName)
    34 {
    35   DBG("nsVolumeMountLock::Create called");
    37   nsRefPtr<nsVolumeMountLock> mountLock = new nsVolumeMountLock(aVolumeName);
    38   nsresult rv = mountLock->Init();
    39   NS_ENSURE_SUCCESS(rv, nullptr);
    41   return mountLock.forget();
    42 }
    44 nsVolumeMountLock::nsVolumeMountLock(const nsAString& aVolumeName)
    45   : mVolumeName(aVolumeName),
    46     mVolumeGeneration(-1),
    47     mUnlocked(false)
    48 {
    49 }
    51 //virtual
    52 nsVolumeMountLock::~nsVolumeMountLock()
    53 {
    54   Unlock();
    55 }
    57 nsresult nsVolumeMountLock::Init()
    58 {
    59   LOG("nsVolumeMountLock created for '%s'",
    60       NS_LossyConvertUTF16toASCII(mVolumeName).get());
    62   // Add ourselves as an Observer. It's important that we use a weak
    63   // reference here. If we used a strong reference, then that reference
    64   // would prevent this object from being destructed.
    65   nsCOMPtr<nsIObserverService> obs = GetObserverService();
    66   obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, true /*weak*/);
    68   // Request the sdcard info, so we know the state/generation without having
    69   // to wait for a state change.
    70   if (XRE_GetProcessType() == GeckoProcessType_Content) {
    71     ContentChild::GetSingleton()->SendBroadcastVolume(mVolumeName);
    72     return NS_OK;
    73   }
    74   nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
    75   NS_ENSURE_TRUE(vs, NS_ERROR_FAILURE);
    77   vs->BroadcastVolume(mVolumeName);
    79   return NS_OK;
    80 }
    82 /* void unlock (); */
    83 NS_IMETHODIMP nsVolumeMountLock::Unlock()
    84 {
    85   LOG("nsVolumeMountLock released for '%s'",
    86       NS_LossyConvertUTF16toASCII(mVolumeName).get());
    88   mUnlocked = true;
    89   mWakeLock = nullptr;
    91   // While we don't really need to remove weak observers, we do so anyways
    92   // since it will reduce the number of times Observe gets called.
    93   nsCOMPtr<nsIObserverService> obs = GetObserverService();
    94   obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED);
    95   return NS_OK;
    96 }
    98 NS_IMETHODIMP nsVolumeMountLock::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
    99 {
   100   if (strcmp(aTopic, NS_VOLUME_STATE_CHANGED) != 0) {
   101     return NS_OK;
   102   }
   103   if (mUnlocked) {
   104     // We're not locked anymore, so we don't need to look at the notifications.
   105     return NS_OK;
   106   }
   108   nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
   109   if (!vol) {
   110     return NS_OK;
   111   }
   112   nsString volName;
   113   vol->GetName(volName);
   114   if (!volName.Equals(mVolumeName)) {
   115     return NS_OK;
   116   }
   117   int32_t state;
   118   nsresult rv = vol->GetState(&state);
   119   NS_ENSURE_SUCCESS(rv, rv);
   121   if (state != nsIVolume::STATE_MOUNTED) {
   122     mWakeLock = nullptr;
   123     mVolumeGeneration = -1;
   124     return NS_OK;
   125   }
   127   int32_t   mountGeneration;
   128   rv = vol->GetMountGeneration(&mountGeneration);
   129   NS_ENSURE_SUCCESS(rv, rv);
   131   DBG("nsVolumeMountLock::Observe mountGeneration = %d mVolumeGeneration = %d",
   132        mountGeneration, mVolumeGeneration);
   134   if (mVolumeGeneration == mountGeneration) {
   135     return NS_OK;
   136   }
   138   // The generation changed, which means that any wakelock we may have
   139   // been holding is now invalid. Grab a new wakelock for the new generation
   140   // number.
   142   mWakeLock = nullptr;
   143   mVolumeGeneration = mountGeneration;
   145   nsRefPtr<power::PowerManagerService> pmService =
   146     power::PowerManagerService::GetInstance();
   147   NS_ENSURE_TRUE(pmService, NS_ERROR_FAILURE);
   149   nsString mountLockName;
   150   vol->GetMountLockName(mountLockName);
   152   ErrorResult err;
   153   mWakeLock = pmService->NewWakeLock(mountLockName, nullptr, err);
   154   if (err.Failed()) {
   155     return err.ErrorCode();
   156   }
   158   LOG("nsVolumeMountLock acquired for '%s' gen %d",
   159       NS_LossyConvertUTF16toASCII(mVolumeName).get(), mVolumeGeneration);
   160   return NS_OK;
   161 }
   163 } // namespace system
   164 } // namespace mozilla

mercurial