Bug 927961 - Add ums.status so that settings app can determine if files are open. r=gwagner
authorDave Hylands <dhylands@mozilla.com>
Thu, 17 Oct 2013 15:41:46 -0700
changeset 151141 d7862edf9e2b5a5581a4e1939cf604cbfad8311b
parent 151140 125d25e3662efcf6294acda25857e88c74a1478b
child 151142 0ed642aa646a5bfccdb8de702ac40da9f3256df4
push id1681
push userdhylands@mozilla.com
push dateThu, 17 Oct 2013 22:42:00 +0000
treeherderb2g-inbound@d7862edf9e2b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgwagner
bugs927961
milestone27.0a1
Bug 927961 - Add ums.status so that settings app can determine if files are open. r=gwagner
dom/system/gonk/AutoMounter.cpp
dom/system/gonk/AutoMounter.h
dom/system/gonk/AutoMounterSetting.cpp
dom/system/gonk/AutoMounterSetting.h
--- a/dom/system/gonk/AutoMounter.cpp
+++ b/dom/system/gonk/AutoMounter.cpp
@@ -83,16 +83,18 @@ using namespace mozilla::hal;
 #define DBG(args...)
 #endif
 
 namespace mozilla {
 namespace system {
 
 class AutoMounter;
 
+static void SetAutoMounterStatus(int32_t aStatus);
+
 /***************************************************************************/
 
 inline const char* SwitchStateStr(const SwitchEvent& aEvent)
 {
   return aEvent.status() == SWITCH_STATE_ON ? "plugged" : "unplugged";
 }
 
 /***************************************************************************/
@@ -371,16 +373,17 @@ AutoMounter::UpdateState()
       mMode = AUTOMOUNTER_DISABLE;
     }
   }
 
   bool tryToShare = (umsAvail && umsEnabled && enabled && usbCablePluggedIn);
   LOG("UpdateState: umsAvail:%d umsEnabled:%d mode:%d usbCablePluggedIn:%d tryToShare:%d",
       umsAvail, umsEnabled, mMode, usbCablePluggedIn, tryToShare);
 
+  bool filesOpen = false;
   VolumeArray::index_type volIndex;
   VolumeArray::size_type  numVolumes = VolumeManager::NumVolumes();
   for (volIndex = 0; volIndex < numVolumes; volIndex++) {
     RefPtr<Volume>  vol = VolumeManager::GetVolume(volIndex);
     Volume::STATE   volState = vol->State();
 
     if (vol->State() == nsIVolume::STATE_MOUNTED) {
       LOG("UpdateState: Volume %s is %s and %s @ %s gen %d locked %d sharing %c",
@@ -432,16 +435,17 @@ AutoMounter::UpdateState()
             // we're trying to share the volume, this implies that we're
             // plugged into the PC via USB and this in turn implies that the
             // battery is charging, so we don't need to be too concerned about
             // wasting battery here.
             MessageLoopForIO::current()->
               PostDelayedTask(FROM_HERE,
                               NewRunnableMethod(this, &AutoMounter::UpdateState),
                               5000);
+            filesOpen = true;
             break;
           }
 
           // Volume is mounted, we need to unmount before
           // we can share.
           LOG("UpdateState: Unmounting %s", vol->NameStr());
           vol->SetIsSharing(true);
           vol->StartUnmount(mResponseCallback);
@@ -476,16 +480,24 @@ AutoMounter::UpdateState()
         }
         default: {
           // Not in a state that we can do anything about.
           break;
         }
       }
     }
   }
+
+  int32_t status = AUTOMOUNTER_STATUS_DISABLED;
+  if (filesOpen) {
+    status = AUTOMOUNTER_STATUS_FILES_OPEN;
+  } else if (enabled) {
+    status = AUTOMOUNTER_STATUS_ENABLED;
+  }
+  SetAutoMounterStatus(status);
 }
 
 /***************************************************************************/
 
 static void
 InitAutoMounterIOThread()
 {
   MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
@@ -590,17 +602,17 @@ InitVolumeConfig()
   char line[255];
   char *command, *vol_name_cstr, *mount_point_cstr, *save_ptr;
   const char *filename = "/system/etc/volume.cfg";
   if (!(fp = fopen(filename, "r"))) {
     LOG("Unable to open volume configuration file '%s' - ignoring", filename);
     return;
   }
   while(fgets(line, sizeof(line), fp)) {
-    char *delim = " \t\n";
+    const char *delim = " \t\n";
     n++;
 
     if (line[0] == '#')
       continue;
     if (!(command = strtok_r(line, delim, &save_ptr))) {
       // Blank line - ignore
       continue;
     }
@@ -639,16 +651,34 @@ InitAutoMounter()
       NewRunnableFunction(InitAutoMounterIOThread));
 
   // Switch Observers need to run on the main thread, so we need to
   // start it here and have it send events to the AutoMounter running
   // on the IO Thread.
   sUsbCableObserver = new UsbCableObserver();
 }
 
+int32_t
+GetAutoMounterStatus()
+{
+  if (sAutoMounterSetting) {
+    return sAutoMounterSetting->GetStatus();
+  }
+  return AUTOMOUNTER_STATUS_DISABLED;
+}
+
+//static
+void
+SetAutoMounterStatus(int32_t aStatus)
+{
+  if (sAutoMounterSetting) {
+    sAutoMounterSetting->SetStatus(aStatus);
+  }
+}
+
 void
 SetAutoMounterMode(int32_t aMode)
 {
   XRE_GetIOMessageLoop()->PostTask(
       FROM_HERE,
       NewRunnableFunction(SetAutoMounterModeIOThread, aMode));
 }
 
--- a/dom/system/gonk/AutoMounter.h
+++ b/dom/system/gonk/AutoMounter.h
@@ -12,16 +12,21 @@ class nsCString;
 namespace mozilla {
 namespace system {
 
 // AutoMounter modes
 #define AUTOMOUNTER_DISABLE                 0
 #define AUTOMOUNTER_ENABLE                  1
 #define AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED  2
 
+// Automounter statuses
+#define AUTOMOUNTER_STATUS_DISABLED         0
+#define AUTOMOUNTER_STATUS_ENABLED          1
+#define AUTOMOUNTER_STATUS_FILES_OPEN       2
+
 /**
  * Initialize the automounter. This causes some of the phone's
  * directories to show up on the host when the phone is plugged
  * into the host via USB.
  *
  * When the AutoMounter starts, it will poll the current state
  * of affairs (usb cable plugged in, automounter enabled, etc)
  * and try to make the state of the volumes match.
@@ -34,16 +39,22 @@ InitAutoMounter();
  *
  * This will in turn cause the automounter to re-evaluate
  * whether it should mount/unmount/share/unshare volumes.
  */
 void
 SetAutoMounterMode(int32_t aMode);
 
 /**
+ * Reports the status of the automounter.
+ */
+int32_t
+GetAutoMounterStatus();
+
+/**
  * Sets the sharing mode of an individual volume.
  *
  * If a volume is enabled for sharing, and the autmounter
  * is in a state to share, then the volume will be shared
  * with the PC.
  */
 void
 SetAutoMounterSharingMode(const nsCString& aVolumeName, bool aAllowSharing);
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -21,16 +21,17 @@
 #include "xpcpublic.h"
 #include "mozilla/Attributes.h"
 
 #undef LOG
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "AutoMounterSetting" , ## args)
 #define ERR(args...)  __android_log_print(ANDROID_LOG_ERROR, "AutoMounterSetting" , ## args)
 
 #define UMS_MODE                  "ums.mode"
+#define UMS_STATUS                "ums.status"
 #define UMS_VOLUME_ENABLED_PREFIX "ums.volume."
 #define UMS_VOLUME_ENABLED_SUFFIX ".enabled"
 #define MOZSETTINGS_CHANGED       "mozsettings-changed"
 
 namespace mozilla {
 namespace system {
 
 class SettingsServiceCallback MOZ_FINAL : public nsISettingsServiceCallback
@@ -82,17 +83,20 @@ public:
   }
 private:
   nsCString mVolumeName;
 };
 
 NS_IMPL_ISUPPORTS1(CheckVolumeSettingsCallback, nsISettingsServiceCallback)
 
 AutoMounterSetting::AutoMounterSetting()
+  : mStatus(AUTOMOUNTER_STATUS_DISABLED)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   // Setup an observer to watch changes to the setting
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   if (!observerService) {
     ERR("GetObserverService failed");
     return;
   }
   nsresult rv;
@@ -111,29 +115,41 @@ AutoMounterSetting::AutoMounterSetting()
   if (!settingsService) {
     ERR("Failed to get settingsLock service!");
     return;
   }
   nsCOMPtr<nsISettingsServiceLock> lock;
   settingsService->CreateLock(getter_AddRefs(lock));
   nsCOMPtr<nsISettingsServiceCallback> callback = new SettingsServiceCallback();
   lock->Set(UMS_MODE, INT_TO_JSVAL(AUTOMOUNTER_DISABLE), callback, nullptr);
+  lock->Set(UMS_STATUS, INT_TO_JSVAL(mStatus), nullptr, nullptr);
 }
 
 AutoMounterSetting::~AutoMounterSetting()
 {
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   if (observerService) {
     observerService->RemoveObserver(this, MOZSETTINGS_CHANGED);
   }
 }
 
 NS_IMPL_ISUPPORTS1(AutoMounterSetting, nsIObserver)
 
+const char *
+AutoMounterSetting::StatusStr(int32_t aStatus)
+{
+  switch (aStatus) {
+    case AUTOMOUNTER_STATUS_DISABLED:   return "Disabled";
+    case AUTOMOUNTER_STATUS_ENABLED:    return "Enabled";
+    case AUTOMOUNTER_STATUS_FILES_OPEN: return "FilesOpen";
+  }
+  return "??? Unknown ???";
+}
+
 class CheckVolumeSettingsRunnable : public nsRunnable
 {
 public:
   CheckVolumeSettingsRunnable(const nsACString& aVolumeName)
     : mVolumeName(aVolumeName) {}
 
   NS_IMETHOD Run()
   {
@@ -157,16 +173,49 @@ private:
 
 //static
 void
 AutoMounterSetting::CheckVolumeSettings(const nsACString& aVolumeName)
 {
   NS_DispatchToMainThread(new CheckVolumeSettingsRunnable(aVolumeName));
 }
 
+class SetStatusRunnable : public nsRunnable
+{
+public:
+  SetStatusRunnable(int32_t aStatus) : mStatus(aStatus) {}
+
+  NS_IMETHOD Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    nsCOMPtr<nsISettingsService> settingsService =
+      do_GetService("@mozilla.org/settingsService;1");
+    NS_ENSURE_TRUE(settingsService, NS_ERROR_FAILURE);
+    nsCOMPtr<nsISettingsServiceLock> lock;
+    settingsService->CreateLock(getter_AddRefs(lock));
+    lock->Set(UMS_STATUS, INT_TO_JSVAL(mStatus), nullptr, nullptr);
+    return NS_OK;
+  }
+
+private:
+  int32_t mStatus;
+};
+
+//static
+void
+AutoMounterSetting::SetStatus(int32_t aStatus)
+{
+  if (aStatus != mStatus) {
+    LOG("Changing status from '%s' to '%s'",
+        StatusStr(mStatus), StatusStr(aStatus));
+    mStatus = aStatus;
+    NS_DispatchToMainThread(new SetStatusRunnable(aStatus));
+  }
+}
+
 NS_IMETHODIMP
 AutoMounterSetting::Observe(nsISupports* aSubject,
                             const char* aTopic,
                             const PRUnichar* aData)
 {
   if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) {
     return NS_OK;
   }
--- a/dom/system/gonk/AutoMounterSetting.h
+++ b/dom/system/gonk/AutoMounterSetting.h
@@ -17,15 +17,22 @@ class AutoMounterSetting : public nsIObs
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   AutoMounterSetting();
   virtual ~AutoMounterSetting();
 
   static void CheckVolumeSettings(const nsACString& aVolumeName);
+
+  int32_t GetStatus() { return mStatus; }
+  void SetStatus(int32_t aStatus);
+  const char *StatusStr(int32_t aStatus);
+
+private:
+  int32_t mStatus;
 };
 
 }   // namespace system
 }   // namespace mozilla
 
 #endif  // mozilla_system_automountersetting_h__