Bug 677166 - Part 7 - Network Information API: DOM implementation. r=sicking

This commit is contained in:
Mounir Lamouri 2012-01-16 18:14:56 +01:00
parent 15d460350a
commit 9888667efb
7 changed files with 203 additions and 11 deletions

View File

@ -175,7 +175,10 @@ Navigator::Invalidate()
}
#endif
mConnection = nsnull;
if (mConnection) {
mConnection->Shutdown();
mConnection = nsnull;
}
}
nsPIDOMWindow *
@ -1074,8 +1077,20 @@ Navigator::GetMozTelephony(nsIDOMTelephony** aTelephony)
NS_IMETHODIMP
Navigator::GetMozConnection(nsIDOMMozConnection** aConnection)
{
*aConnection = nsnull;
if (!mConnection) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(window);
NS_ENSURE_TRUE(sgo, NS_OK);
nsIScriptContext* scx = sgo->GetContext();
NS_ENSURE_TRUE(scx, NS_OK);
mConnection = new network::Connection();
mConnection->Init(window, scx);
}
NS_ADDREF(*aConnection = mConnection);

View File

@ -80,6 +80,10 @@ namespace sms {
class SmsManager;
} // namespace sms
namespace network {
class Connection;
} // namespace Connection;
class Navigator : public nsIDOMNavigator
, public nsIDOMClientInformation
, public nsIDOMNavigatorGeolocation
@ -136,7 +140,7 @@ private:
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsIDOMTelephony> mTelephony;
#endif
nsCOMPtr<nsIDOMMozConnection> mConnection;
nsRefPtr<network::Connection> mConnection;
nsWeakPtr mWindow;
};

View File

@ -36,8 +36,13 @@
#include "nsISupports.idl"
[scriptable, uuid(0bd0bcc8-ca92-43fa-97bd-aec8d79edb24)]
interface nsIDOMEventListener;
[scriptable, uuid(8c6b574d-1135-4387-a6e3-6d8ba38d79a1)]
interface nsIDOMMozConnection : nsISupports
{
readonly attribute double bandwidth;
readonly attribute boolean metered;
attribute nsIDOMEventListener onchange;
};

View File

@ -35,9 +35,19 @@
*
* ***** END LICENSE BLOCK ***** */
#include <limits>
#include "mozilla/Hal.h"
#include "Connection.h"
#include "nsIDOMClassInfo.h"
#include "mozilla/Preferences.h"
#include "nsDOMEvent.h"
#include "Constants.h"
/**
* We have to use macros here because our leak analysis tool things we are
* leaking strings when we have |static const nsString|. Sad :(
*/
#define CHANGE_EVENT_NAME NS_LITERAL_STRING("change")
DOMCI_DATA(MozConnection, mozilla::dom::network::Connection)
@ -48,23 +58,121 @@ namespace network {
const char* Connection::sMeteredPrefName = "dom.network.metered";
const bool Connection::sMeteredDefaultValue = false;
NS_INTERFACE_MAP_BEGIN(Connection)
NS_INTERFACE_MAP_ENTRY(nsIDOMMozConnection)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozConnection)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_CLASS(Connection)
NS_IMPL_ADDREF(Connection)
NS_IMPL_RELEASE(Connection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Connection,
nsDOMEventTargetWrapperCache)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(change)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Connection,
nsDOMEventTargetWrapperCache)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(change)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Connection)
NS_INTERFACE_MAP_ENTRY(nsIDOMMozConnection)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozConnection)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozConnection)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
NS_IMPL_ADDREF_INHERITED(Connection, nsDOMEventTargetWrapperCache)
NS_IMPL_RELEASE_INHERITED(Connection, nsDOMEventTargetWrapperCache)
Connection::Connection()
: mCanBeMetered(kDefaultCanBeMetered)
, mBandwidth(kDefaultBandwidth)
{
}
void
Connection::Init(nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext)
{
// Those vars come from nsDOMEventTargetHelper.
mOwner = aWindow;
mScriptContext = aScriptContext;
hal::RegisterNetworkObserver(this);
hal::NetworkInformation networkInfo;
hal::GetCurrentNetworkInformation(&networkInfo);
UpdateFromNetworkInfo(networkInfo);
}
void
Connection::Shutdown()
{
hal::UnregisterNetworkObserver(this);
}
NS_IMETHODIMP
Connection::GetBandwidth(double* aBandwidth)
{
if (mBandwidth == kDefaultBandwidth) {
*aBandwidth = std::numeric_limits<double>::infinity();
return NS_OK;
}
*aBandwidth = mBandwidth;
return NS_OK;
}
NS_IMETHODIMP
Connection::GetMetered(bool* aMetered)
{
if (!mCanBeMetered) {
*aMetered = false;
return NS_OK;
}
*aMetered = Preferences::GetBool(sMeteredPrefName,
sMeteredDefaultValue);
return NS_OK;
}
NS_IMPL_EVENT_HANDLER(Connection, change)
nsresult
Connection::DispatchTrustedEventToSelf(const nsAString& aEventName)
{
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
nsresult rv = event->InitEvent(aEventName, false, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = event->SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
bool dummy;
rv = DispatchEvent(event, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
void
Connection::UpdateFromNetworkInfo(const hal::NetworkInformation& aNetworkInfo)
{
mBandwidth = aNetworkInfo.bandwidth();
mCanBeMetered = aNetworkInfo.canBeMetered();
}
void
Connection::Notify(const hal::NetworkInformation& aNetworkInfo)
{
double previousBandwidth = mBandwidth;
bool previousCanBeMetered = mCanBeMetered;
UpdateFromNetworkInfo(aNetworkInfo);
if (previousBandwidth == mBandwidth &&
previousCanBeMetered == mCanBeMetered) {
return;
}
DispatchTrustedEventToSelf(CHANGE_EVENT_NAME);
}
} // namespace network
} // namespace dom
} // namespace mozilla

View File

@ -39,18 +39,65 @@
#define mozilla_dom_network_Connection_h
#include "nsIDOMConnection.h"
#include "nsDOMEventTargetWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Observer.h"
#include "Types.h"
namespace mozilla {
namespace hal {
class NetworkInformation;
} // namespace hal
namespace dom {
namespace network {
class Connection : public nsIDOMMozConnection
class Connection : public nsDOMEventTargetWrapperCache
, public nsIDOMMozConnection
, public NetworkObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMOZCONNECTION
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetWrapperCache::)
Connection();
void Init(nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext);
void Shutdown();
// For IObserver
void Notify(const hal::NetworkInformation& aNetworkInfo);
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Connection,
nsDOMEventTargetWrapperCache)
private:
/**
* Dispatch a trusted non-cancellable and non-bubbling event to itself.
*/
nsresult DispatchTrustedEventToSelf(const nsAString& aEventName);
/**
* Update the connection information stored in the object using a
* NetworkInformation object.
*/
void UpdateFromNetworkInfo(const hal::NetworkInformation& aNetworkInfo);
/**
* If the connection is of a type that can be metered.
*/
bool mCanBeMetered;
/**
* The connection bandwidth.
*/
double mBandwidth;
NS_DECL_EVENT_HANDLER(change)
static const char* sMeteredPrefName;
static const bool sMeteredDefaultValue;
};

View File

@ -61,6 +61,9 @@ CPPSRCS = \
$(NULL)
LOCAL_INCLUDES = \
-I$(topsrcdir)/content/events/src \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk

View File

@ -28,6 +28,16 @@ ok(navigator.mozConnection instanceof MozConnection,
checkInterface("Connection");
ok('bandwidth' in navigator.mozConnection,
"bandwidth should be a Connection attribute");
is(navigator.mozConnection.bandwidth, Infinity,
"By default connection.bandwidth is equals to Infinity");
ok('metered' in navigator.mozConnection,
"metered should be a Connection attribute");
is(navigator.mozConnection.metered, false,
"By default the connection is not metered");
</script>
</pre>
</body>