dom/system/gonk/nsVolume.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 "nsVolume.h"
     7 #include "base/message_loop.h"
     8 #include "nsIPowerManagerService.h"
     9 #include "nsISupportsUtils.h"
    10 #include "nsIVolume.h"
    11 #include "nsServiceManagerUtils.h"
    12 #include "nsThreadUtils.h"
    13 #include "nsVolumeStat.h"
    14 #include "nsXULAppAPI.h"
    15 #include "Volume.h"
    16 #include "AutoMounter.h"
    17 #include "VolumeManager.h"
    19 #define VOLUME_MANAGER_LOG_TAG  "nsVolume"
    20 #include "VolumeManagerLog.h"
    22 namespace mozilla {
    23 namespace system {
    25 const char *
    26 NS_VolumeStateStr(int32_t aState)
    27 {
    28   switch (aState) {
    29     case nsIVolume::STATE_INIT:       return "Init";
    30     case nsIVolume::STATE_NOMEDIA:    return "NoMedia";
    31     case nsIVolume::STATE_IDLE:       return "Idle";
    32     case nsIVolume::STATE_PENDING:    return "Pending";
    33     case nsIVolume::STATE_CHECKING:   return "Checking";
    34     case nsIVolume::STATE_MOUNTED:    return "Mounted";
    35     case nsIVolume::STATE_UNMOUNTING: return "Unmounting";
    36     case nsIVolume::STATE_FORMATTING: return "Formatting";
    37     case nsIVolume::STATE_SHARED:     return "Shared";
    38     case nsIVolume::STATE_SHAREDMNT:  return "Shared-Mounted";
    39   }
    40   return "???";
    41 }
    43 // While nsVolumes can only be used on the main thread, in the
    44 // UpdateVolumeRunnable constructor (which is called from IOThread) we
    45 // allocate an nsVolume which is then passed to MainThread. Since we
    46 // have a situation where we allocate on one thread and free on another
    47 // we use a thread safe AddRef implementation.
    48 NS_IMPL_ISUPPORTS(nsVolume, nsIVolume)
    50 nsVolume::nsVolume(const Volume* aVolume)
    51   : mName(NS_ConvertUTF8toUTF16(aVolume->Name())),
    52     mMountPoint(NS_ConvertUTF8toUTF16(aVolume->MountPoint())),
    53     mState(aVolume->State()),
    54     mMountGeneration(aVolume->MountGeneration()),
    55     mMountLocked(aVolume->IsMountLocked()),
    56     mIsFake(false),
    57     mIsMediaPresent(aVolume->MediaPresent()),
    58     mIsSharing(aVolume->IsSharing()),
    59     mIsFormatting(aVolume->IsFormatting())
    60 {
    61 }
    63 bool nsVolume::Equals(nsIVolume* aVolume)
    64 {
    65   nsString volName;
    66   aVolume->GetName(volName);
    67   if (!mName.Equals(volName)) {
    68     return false;
    69   }
    71   nsString volMountPoint;
    72   aVolume->GetMountPoint(volMountPoint);
    73   if (!mMountPoint.Equals(volMountPoint)) {
    74     return false;
    75   }
    77   int32_t volState;
    78   aVolume->GetState(&volState);
    79   if (mState != volState){
    80     return false;
    81   }
    83   int32_t volMountGeneration;
    84   aVolume->GetMountGeneration(&volMountGeneration);
    85   if (mMountGeneration != volMountGeneration) {
    86     return false;
    87   }
    89   bool volIsMountLocked;
    90   aVolume->GetIsMountLocked(&volIsMountLocked);
    91   if (mMountLocked != volIsMountLocked) {
    92     return false;
    93   }
    95   bool isFake;
    96   aVolume->GetIsFake(&isFake);
    97   if (mIsFake != isFake) {
    98     return false;
    99   }
   101   bool isSharing;
   102   aVolume->GetIsSharing(&isSharing);
   103   if (mIsSharing != isSharing) {
   104     return false;
   105   }
   107   bool isFormatting;
   108   aVolume->GetIsFormatting(&isFormatting);
   109   if (mIsFormatting != isFormatting) {
   110     return false;
   111   }
   113   return true;
   114 }
   116 NS_IMETHODIMP nsVolume::GetIsMediaPresent(bool *aIsMediaPresent)
   117 {
   118   *aIsMediaPresent = mIsMediaPresent;
   119   return NS_OK;
   120 }
   122 NS_IMETHODIMP nsVolume::GetIsMountLocked(bool *aIsMountLocked)
   123 {
   124   *aIsMountLocked = mMountLocked;
   125   return NS_OK;
   126 }
   128 NS_IMETHODIMP nsVolume::GetIsSharing(bool *aIsSharing)
   129 {
   130   *aIsSharing = mIsSharing;
   131   return NS_OK;
   132 }
   134 NS_IMETHODIMP nsVolume::GetIsFormatting(bool *aIsFormatting)
   135 {
   136   *aIsFormatting = mIsFormatting;
   137   return NS_OK;
   138 }
   140 NS_IMETHODIMP nsVolume::GetName(nsAString& aName)
   141 {
   142   aName = mName;
   143   return NS_OK;
   144 }
   146 NS_IMETHODIMP nsVolume::GetMountGeneration(int32_t* aMountGeneration)
   147 {
   148   *aMountGeneration = mMountGeneration;
   149   return NS_OK;
   150 }
   152 NS_IMETHODIMP nsVolume::GetMountLockName(nsAString& aMountLockName)
   153 {
   154   aMountLockName = NS_LITERAL_STRING("volume-") + Name();
   155   aMountLockName.AppendPrintf("-%d", mMountGeneration);
   157   return NS_OK;
   158 }
   160 NS_IMETHODIMP nsVolume::GetMountPoint(nsAString& aMountPoint)
   161 {
   162   aMountPoint = mMountPoint;
   163   return NS_OK;
   164 }
   166 NS_IMETHODIMP nsVolume::GetState(int32_t* aState)
   167 {
   168   *aState = mState;
   169   return NS_OK;
   170 }
   172 NS_IMETHODIMP nsVolume::GetStats(nsIVolumeStat **aResult)
   173 {
   174   if (mState != STATE_MOUNTED) {
   175     return NS_ERROR_NOT_AVAILABLE;
   176   }
   178   NS_IF_ADDREF(*aResult = new nsVolumeStat(mMountPoint));
   179   return NS_OK;
   180 }
   182 NS_IMETHODIMP nsVolume::GetIsFake(bool *aIsFake)
   183 {
   184   *aIsFake = mIsFake;
   185   return NS_OK;
   186 }
   188 NS_IMETHODIMP nsVolume::Format()
   189 {
   190   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   192   XRE_GetIOMessageLoop()->PostTask(
   193       FROM_HERE,
   194       NewRunnableFunction(FormatVolumeIOThread, NameStr()));
   196   return NS_OK;
   197 }
   199 /* static */
   200 void nsVolume::FormatVolumeIOThread(const nsCString& aVolume)
   201 {
   202   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   204   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   205   if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
   206     return;
   207   }
   209   AutoMounterFormatVolume(aVolume);
   210 }
   212 NS_IMETHODIMP nsVolume::Mount()
   213 {
   214   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   216   XRE_GetIOMessageLoop()->PostTask(
   217       FROM_HERE,
   218       NewRunnableFunction(MountVolumeIOThread, NameStr()));
   220   return NS_OK;
   221 }
   223 /* static */
   224 void nsVolume::MountVolumeIOThread(const nsCString& aVolume)
   225 {
   226   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   228   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   229   if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
   230     return;
   231   }
   233   AutoMounterMountVolume(aVolume);
   234 }
   236 NS_IMETHODIMP nsVolume::Unmount()
   237 {
   238   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   240   XRE_GetIOMessageLoop()->PostTask(
   241       FROM_HERE,
   242       NewRunnableFunction(UnmountVolumeIOThread, NameStr()));
   244   return NS_OK;
   245 }
   247 /* static */
   248 void nsVolume::UnmountVolumeIOThread(const nsCString& aVolume)
   249 {
   250   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   252   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
   253   if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
   254     return;
   255   }
   257   AutoMounterUnmountVolume(aVolume);
   258 }
   260 void
   261 nsVolume::LogState() const
   262 {
   263   if (mState == nsIVolume::STATE_MOUNTED) {
   264     LOG("nsVolume: %s state %s @ '%s' gen %d locked %d fake %d "
   265         "media %d sharing %d formatting %d",
   266         NameStr().get(), StateStr(), MountPointStr().get(),
   267         MountGeneration(), (int)IsMountLocked(), (int)IsFake(),
   268         (int)IsMediaPresent(), (int)IsSharing(),
   269         (int)IsFormatting());
   270     return;
   271   }
   273   LOG("nsVolume: %s state %s", NameStr().get(), StateStr());
   274 }
   276 void nsVolume::Set(nsIVolume* aVolume)
   277 {
   278   MOZ_ASSERT(NS_IsMainThread());
   280   aVolume->GetName(mName);
   281   aVolume->GetMountPoint(mMountPoint);
   282   aVolume->GetState(&mState);
   283   aVolume->GetIsFake(&mIsFake);
   284   aVolume->GetIsMediaPresent(&mIsMediaPresent);
   285   aVolume->GetIsSharing(&mIsSharing);
   286   aVolume->GetIsFormatting(&mIsFormatting);
   288   int32_t volMountGeneration;
   289   aVolume->GetMountGeneration(&volMountGeneration);
   291   if (mState != nsIVolume::STATE_MOUNTED) {
   292     // Since we're not in the mounted state, we need to
   293     // forgot whatever mount generation we may have had.
   294     mMountGeneration = -1;
   295     return;
   296   }
   297   if (mMountGeneration == volMountGeneration) {
   298     // No change in mount generation, nothing else to do
   299     return;
   300   }
   302   mMountGeneration = volMountGeneration;
   304   if (XRE_GetProcessType() != GeckoProcessType_Default) {
   305     // Child processes just track the state, not maintain it.
   306     aVolume->GetIsMountLocked(&mMountLocked);
   307     return;
   308   }
   310   // Notify the Volume on IOThread whether the volume is locked or not.
   311   nsCOMPtr<nsIPowerManagerService> pmService =
   312     do_GetService(POWERMANAGERSERVICE_CONTRACTID);
   313   if (!pmService) {
   314     return;
   315   }
   316   nsString mountLockName;
   317   GetMountLockName(mountLockName);
   318   nsString mountLockState;
   319   pmService->GetWakeLockState(mountLockName, mountLockState);
   320   UpdateMountLock(mountLockState);
   321 }
   323 void
   324 nsVolume::UpdateMountLock(const nsAString& aMountLockState)
   325 {
   326   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   327   MOZ_ASSERT(NS_IsMainThread());
   329   // There are 3 states, unlocked, locked-background, and locked-foreground
   330   // I figured it was easier to use negtive logic and compare for unlocked.
   331   UpdateMountLock(!aMountLockState.EqualsLiteral("unlocked"));
   332 }
   334 void
   335 nsVolume::UpdateMountLock(bool aMountLocked)
   336 {
   337   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   338   MOZ_ASSERT(NS_IsMainThread());
   340   if (aMountLocked == mMountLocked) {
   341     return;
   342   }
   343   // The locked/unlocked state changed. Tell IOThread about it.
   344   mMountLocked = aMountLocked;
   345   LogState();
   346   XRE_GetIOMessageLoop()->PostTask(
   347      FROM_HERE,
   348      NewRunnableFunction(Volume::UpdateMountLock,
   349                          NS_LossyConvertUTF16toASCII(Name()),
   350                          MountGeneration(), aMountLocked));
   351 }
   353 void
   354 nsVolume::SetIsFake(bool aIsFake)
   355 {
   356   mIsFake = aIsFake;
   357   if (mIsFake) {
   358     // The media is always present for fake volumes.
   359     mIsMediaPresent = true;
   360     MOZ_ASSERT(!mIsSharing);
   361   }
   362 }
   364 void
   365 nsVolume::SetState(int32_t aState)
   366 {
   367   static int32_t sMountGeneration = 0;
   369   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
   370   MOZ_ASSERT(NS_IsMainThread());
   371   MOZ_ASSERT(IsFake());
   373   if (aState == mState) {
   374     return;
   375   }
   377   if (aState == nsIVolume::STATE_MOUNTED) {
   378     mMountGeneration = ++sMountGeneration;
   379   }
   381   mState = aState;
   382 }
   384 } // system
   385 } // mozilla

mercurial