Bug 713687 - Part 4 - Network API Android backend: use enable/disable notifications to prevent listening when not needed. r=dougt
authorMounir Lamouri <mounir.lamouri@gmail.com>
Mon, 16 Jan 2012 15:01:07 +0100
changeset 84752 9f68bafdd6852e727f4af1a303ca20a9bab0466a
parent 84751 9ee757bbbcd0031fe56d1cf394e0e7d9bff9bcee
child 84753 7087bb2ced148327594d06b2bd89a6994db8c086
push id443
push usertim.taubert@gmx.de
push dateWed, 18 Jan 2012 12:23:22 +0000
treeherderfx-team@f93675b9e0ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougt
bugs713687
milestone12.0a1
Bug 713687 - Part 4 - Network API Android backend: use enable/disable notifications to prevent listening when not needed. r=dougt
embedding/android/GeckoAppShell.java
embedding/android/GeckoNetworkManager.java
hal/android/AndroidHal.cpp
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoNetworkManager.java
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -1775,9 +1775,17 @@ public class GeckoAppShell
             }
         }
         return false;
     }
 
     public static double[] getCurrentNetworkInformation() {
         return GeckoNetworkManager.getInstance().getCurrentInformation();
     }
+
+    public static void enableNetworkNotifications() {
+        GeckoNetworkManager.getInstance().enableNotifications();
+    }
+
+    public static void disableNetworkNotifications() {
+        GeckoNetworkManager.getInstance().disableNotifications();
+    }
 }
--- a/embedding/android/GeckoNetworkManager.java
+++ b/embedding/android/GeckoNetworkManager.java
@@ -127,16 +127,21 @@ public class GeckoNetworkManager
     NETWORK_3_5_G,  // 3.5G
     NETWORK_3_75_G, // 3.75G
     NETWORK_3_9_G,  // 3.9G
     NETWORK_UNKNOWN
   }
 
   private NetworkType  mNetworkType = NetworkType.NETWORK_NONE;
   private IntentFilter mNetworkFilter = new IntentFilter();
+  // Whether the manager should be listening to Network Information changes.
+  private boolean mShouldBeListening = false;
+  // Whether the manager should notify Gecko that a change in Network
+  // Information happened.
+  private boolean mShouldNotify      = false;
 
   public static GeckoNetworkManager getInstance() {
     return sInstance;
   }
 
   @Override
   public void onReceive(Context aContext, Intent aIntent) {
     updateNetworkType();
@@ -144,42 +149,76 @@ public class GeckoNetworkManager
 
   public void init() {
     mNetworkFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
 
     mNetworkType = getNetworkType();
   }
 
   public void start() {
+    mShouldBeListening = true;
     updateNetworkType();
 
+    if (mShouldNotify) {
+      startListening();
+    }
+  }
+
+  private void startListening() {
     GeckoApp.mAppContext.registerReceiver(sInstance, mNetworkFilter);
   }
 
   public void stop() {
+    mShouldBeListening = false;
+
+    if (mShouldNotify) {
+      stopListening();
+    }
+  }
+
+  private void stopListening() {
     GeckoApp.mAppContext.unregisterReceiver(sInstance);
   }
 
   private void updateNetworkType() {
     NetworkType previousNetworkType = mNetworkType;
     mNetworkType = getNetworkType();
 
-    if (mNetworkType == previousNetworkType) {
+    if (mNetworkType == previousNetworkType || !mShouldNotify) {
       return;
     }
 
     GeckoAppShell.sendEventToGecko(new GeckoEvent(getNetworkSpeed(mNetworkType),
                                                   isNetworkUsuallyMetered(mNetworkType)));
   }
 
   public double[] getCurrentInformation() {
     return new double[] { getNetworkSpeed(mNetworkType),
                           isNetworkUsuallyMetered(mNetworkType) ? 1.0 : 0.0 };
   }
 
+  public void enableNotifications() {
+    // We set mShouldNotify *after* calling updateNetworkType() to make sure we
+    // don't notify an eventual change in mNetworkType.
+    updateNetworkType();
+    mShouldNotify = true;
+
+    if (mShouldBeListening) {
+      startListening();
+    }
+  }
+
+  public void disableNotifications() {
+    mShouldNotify = false;
+
+    if (mShouldBeListening) {
+      stopListening();
+    }
+  }
+
   private static NetworkType getNetworkType() {
     ConnectivityManager cm =
       (ConnectivityManager)GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
 
     if (cm.getActiveNetworkInfo() == null) {
       return NetworkType.NETWORK_NONE;
     }
 
--- a/hal/android/AndroidHal.cpp
+++ b/hal/android/AndroidHal.cpp
@@ -137,21 +137,35 @@ GetScreenBrightness()
 }
 
 void
 SetScreenBrightness(double brightness)
 {}
 
 void
 EnableNetworkNotifications()
-{}
+{
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->EnableNetworkNotifications();
+}
 
 void
 DisableNetworkNotifications()
-{}
+{
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->DisableNetworkNotifications();
+}
 
 void
 GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo)
 {
   AndroidBridge* bridge = AndroidBridge::Bridge();
   if (!bridge) {
     return;
   }
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -1746,9 +1746,17 @@ public class GeckoAppShell
         if (mInputConnection != null && mInputConnection.isIMEEnabled()) {
             sendEventToGecko(new GeckoEvent("ScrollTo:FocusedInput", ""));
         }
     }
 
     public static double[] getCurrentNetworkInformation() {
         return GeckoNetworkManager.getInstance().getCurrentInformation();
     }
+
+    public static void enableNetworkNotifications() {
+        GeckoNetworkManager.getInstance().enableNotifications();
+    }
+
+    public static void disableNetworkNotifications() {
+        GeckoNetworkManager.getInstance().disableNotifications();
+    }
 }
--- a/mobile/android/base/GeckoNetworkManager.java
+++ b/mobile/android/base/GeckoNetworkManager.java
@@ -127,16 +127,21 @@ public class GeckoNetworkManager
     NETWORK_3_5_G,  // 3.5G
     NETWORK_3_75_G, // 3.75G
     NETWORK_3_9_G,  // 3.9G
     NETWORK_UNKNOWN
   }
 
   private NetworkType  mNetworkType = NetworkType.NETWORK_NONE;
   private IntentFilter mNetworkFilter = new IntentFilter();
+  // Whether the manager should be listening to Network Information changes.
+  private boolean mShouldBeListening = false;
+  // Whether the manager should notify Gecko that a change in Network
+  // Information happened.
+  private boolean mShouldNotify      = false;
 
   public static GeckoNetworkManager getInstance() {
     return sInstance;
   }
 
   @Override
   public void onReceive(Context aContext, Intent aIntent) {
     updateNetworkType();
@@ -144,42 +149,76 @@ public class GeckoNetworkManager
 
   public void init() {
     mNetworkFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
 
     mNetworkType = getNetworkType();
   }
 
   public void start() {
+    mShouldBeListening = true;
     updateNetworkType();
 
+    if (mShouldNotify) {
+      startListening();
+    }
+  }
+
+  private void startListening() {
     GeckoApp.mAppContext.registerReceiver(sInstance, mNetworkFilter);
   }
 
   public void stop() {
+    mShouldBeListening = false;
+
+    if (mShouldNotify) {
+      stopListening();
+    }
+  }
+
+  private void stopListening() {
     GeckoApp.mAppContext.unregisterReceiver(sInstance);
   }
 
   private void updateNetworkType() {
     NetworkType previousNetworkType = mNetworkType;
     mNetworkType = getNetworkType();
 
-    if (mNetworkType == previousNetworkType) {
+    if (mNetworkType == previousNetworkType || !mShouldNotify) {
       return;
     }
 
     GeckoAppShell.sendEventToGecko(new GeckoEvent(getNetworkSpeed(mNetworkType),
                                                   isNetworkUsuallyMetered(mNetworkType)));
   }
 
   public double[] getCurrentInformation() {
     return new double[] { getNetworkSpeed(mNetworkType),
                           isNetworkUsuallyMetered(mNetworkType) ? 1.0 : 0.0 };
   }
 
+  public void enableNotifications() {
+    // We set mShouldNotify *after* calling updateNetworkType() to make sure we
+    // don't notify an eventual change in mNetworkType.
+    updateNetworkType();
+    mShouldNotify = true;
+
+    if (mShouldBeListening) {
+      startListening();
+    }
+  }
+
+  public void disableNotifications() {
+    mShouldNotify = false;
+
+    if (mShouldBeListening) {
+      stopListening();
+    }
+  }
+
   private static NetworkType getNetworkType() {
     ConnectivityManager cm =
       (ConnectivityManager)GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
 
     if (cm.getActiveNetworkInfo() == null) {
       return NetworkType.NETWORK_NONE;
     }
 
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -172,16 +172,18 @@ AndroidBridge::Init(JNIEnv *jEnv,
     jSaveSentMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "saveSentMessage", "(Ljava/lang/String;Ljava/lang/String;J)I");
     jGetMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMessage", "(IIJ)V");
     jDeleteMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "deleteMessage", "(IIJ)V");
     jCreateMessageList = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "createMessageList", "(JJ[Ljava/lang/String;IIZIJ)V");
     jGetNextMessageinList = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getNextMessageInList", "(IIJ)V");
     jClearMessageList = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "clearMessageList", "(I)V");
 
     jGetCurrentNetworkInformation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getCurrentNetworkInformation", "()[D");
+    jEnableNetworkNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableNetworkNotifications", "()V");
+    jDisableNetworkNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "disableNetworkNotifications", "()V");
 
     jEGLContextClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGLContext"));
     jEGL10Class = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGL10"));
     jEGLSurfaceImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLSurfaceImpl"));
     jEGLContextImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLContextImpl"));
     jEGLConfigImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLConfigImpl"));
     jEGLDisplayImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLDisplayImpl"));
 
@@ -1449,16 +1451,30 @@ AndroidBridge::GetCurrentNetworkInformat
     jdouble* info = mJNIEnv->GetDoubleArrayElements(arr, 0);
 
     aNetworkInfo->bandwidth() = info[0];
     aNetworkInfo->canBeMetered() = info[1] == 1.0f;
 
     mJNIEnv->ReleaseDoubleArrayElements(arr, info, 0);
 }
 
+void
+AndroidBridge::EnableNetworkNotifications()
+{
+    ALOG_BRIDGE("AndroidBridge::EnableNetworkNotifications");
+    mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jEnableNetworkNotifications);
+}
+
+void
+AndroidBridge::DisableNetworkNotifications()
+{
+    ALOG_BRIDGE("AndroidBridge::DisableNetworkNotifications");
+    mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jDisableNetworkNotifications);
+}
+
 void *
 AndroidBridge::LockBitmap(jobject bitmap)
 {
     int err;
     void *buf;
 
     if ((err = AndroidBitmap_lockPixels(JNI(), bitmap, &buf)) != 0) {
         ALOG_BRIDGE("AndroidBitmap_lockPixels failed! (error %d)", err);
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -348,16 +348,18 @@ public:
     void DeleteMessage(PRInt32 aMessageId, PRInt32 aRequestId, PRUint64 aProcessId);
     void CreateMessageList(const dom::sms::SmsFilterData& aFilter, bool aReverse, PRInt32 aRequestId, PRUint64 aProcessId);
     void GetNextMessageInList(PRInt32 aListId, PRInt32 aRequestId, PRUint64 aProcessId);
     void ClearMessageList(PRInt32 aListId);
 
     bool IsTablet();
 
     void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
+    void EnableNetworkNotifications();
+    void DisableNetworkNotifications();
 
 protected:
     static AndroidBridge *sBridge;
 
     // the global JavaVM
     JavaVM *mJavaVM;
 
     // the JNIEnv for the main thread
@@ -444,16 +446,18 @@ protected:
     jmethodID jSaveSentMessage;
     jmethodID jGetMessage;
     jmethodID jDeleteMessage;
     jmethodID jCreateMessageList;
     jmethodID jGetNextMessageinList;
     jmethodID jClearMessageList;
 
     jmethodID jGetCurrentNetworkInformation;
+    jmethodID jEnableNetworkNotifications;
+    jmethodID jDisableNetworkNotifications;
 
     // stuff we need for CallEglCreateWindowSurface
     jclass jEGLSurfaceImplClass;
     jclass jEGLContextImplClass;
     jclass jEGLConfigImplClass;
     jclass jEGLDisplayImplClass;
     jclass jEGLContextClass;
     jclass jEGL10Class;