DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (5b81998bb7ab)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/Hal.h"
#include "mozilla/HalWakeLock.h"
#include "mozilla/Services.h"
#include "nsObserverService.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"

using namespace mozilla::hal;

namespace mozilla {
namespace hal {

WakeLockState
ComputeWakeLockState(int aNumLocks, int aNumHidden)
{
  if (aNumLocks == 0) {
    return WAKE_LOCK_STATE_UNLOCKED;
  } else if (aNumLocks == aNumHidden) {
    return WAKE_LOCK_STATE_HIDDEN;
  } else {
    return WAKE_LOCK_STATE_VISIBLE;
  }
}

} // hal
} // mozilla

namespace mozilla {
namespace hal_impl {

namespace {
struct LockCount {
  uint32_t numLocks;
  uint32_t numHidden;
};
}

static int sActiveChildren = 0;
static nsAutoPtr<nsDataHashtable<nsStringHashKey, LockCount> > sLockTable;
static bool sInitialized = false;
static bool sIsShuttingDown = false;

namespace {
class ClearHashtableOnShutdown MOZ_FINAL : public nsIObserver {
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOBSERVER
};

NS_IMPL_ISUPPORTS1(ClearHashtableOnShutdown, nsIObserver)

NS_IMETHODIMP
ClearHashtableOnShutdown::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* data)
{
  MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"));

  sIsShuttingDown = true;
  sLockTable = nullptr;

  return NS_OK;
}
} // anonymous namespace

static void
Init()
{
  sLockTable = new nsDataHashtable<nsStringHashKey, LockCount>();
  sLockTable->Init();
  sInitialized = true;

  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
  if (obs) {
    obs->AddObserver(new ClearHashtableOnShutdown(), "xpcom-shutdown", false);
  }
}

void
EnableWakeLockNotifications()
{
  sActiveChildren++;
}

void
DisableWakeLockNotifications()
{
  sActiveChildren--;
}

void
ModifyWakeLock(const nsAString &aTopic,
               hal::WakeLockControl aLockAdjust,
               hal::WakeLockControl aHiddenAdjust)
{
  if (sIsShuttingDown) {
    return;
  }
  if (!sInitialized) {
    Init();
  }

  LockCount count;
  count.numLocks = 0;
  count.numHidden = 0;
  sLockTable->Get(aTopic, &count);
  MOZ_ASSERT(count.numLocks >= count.numHidden);
  MOZ_ASSERT(aLockAdjust >= 0 || count.numLocks > 0);
  MOZ_ASSERT(aHiddenAdjust >= 0 || count.numHidden > 0);

  WakeLockState oldState = ComputeWakeLockState(count.numLocks, count.numHidden);

  count.numLocks += aLockAdjust;
  count.numHidden += aHiddenAdjust;
  MOZ_ASSERT(count.numLocks >= count.numHidden);

  if (count.numLocks) {
    sLockTable->Put(aTopic, count);
  } else {
    sLockTable->Remove(aTopic);
  }

  WakeLockState newState = ComputeWakeLockState(count.numLocks, count.numHidden);

  if (sActiveChildren && oldState != newState) {
    WakeLockInformation info;
    info.numLocks() = count.numLocks;
    info.numHidden() = count.numHidden;
    info.topic() = aTopic;
    NotifyWakeLockChange(info);
  }
}

void
GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
{
  if (sIsShuttingDown) {
    NS_WARNING("You don't want to get wake lock information during xpcom-shutdown!");
    return;
  }
  if (!sInitialized) {
    Init();
  }

  LockCount count;
  count.numLocks = 0;
  count.numHidden = 0;
  sLockTable->Get(aTopic, &count);

  aWakeLockInfo->numLocks() = count.numLocks;
  aWakeLockInfo->numHidden() = count.numHidden;
  aWakeLockInfo->topic() = aTopic;
}

} // hal_impl
} // mozilla