Bug 799632 - Add a preference for controlling automatic update downloads on Android r=bnicholson
authorJames Willcox <jwillcox@mozilla.com>
Mon, 15 Oct 2012 09:56:42 -0400
changeset 110274 7009f7377d85f4a2c2ebd2cadbe5bff8a8cd9db1
parent 110273 a53a74e310ae6d3e5e189a37b59521f08dda0a9f
child 110275 2b96e74420878cd94b9afd8fe4095196af24e46f
push id23680
push useremorley@mozilla.com
push dateTue, 16 Oct 2012 08:09:24 +0000
treeherdermozilla-central@8f145599e4bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbnicholson
bugs799632
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 799632 - Add a preference for controlling automatic update downloads on Android r=bnicholson
mobile/android/app/mobile.js
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoPreferences.java
mobile/android/base/UpdateService.java
mobile/android/base/UpdateServiceHelper.java.in
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/resources/values/arrays.xml
mobile/android/base/resources/xml/preferences.xml.in
mobile/android/base/strings.xml.in
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -488,16 +488,20 @@ pref("browser.search.param.yahoo-fr", "m
 pref("browser.search.param.yahoo-fr-cjkt", "moz35");
 pref("browser.search.param.yahoo-fr-ja", "mozff");
 #endif
 
 /* prefs used by the update timer system (including blocklist pings) */
 pref("app.update.timerFirstInterval", 30000); // milliseconds
 pref("app.update.timerMinimumDelay", 30); // seconds
 
+// used by update service to decide whether or not to
+// automatically download an update
+pref("app.update.autodownload", "wifi");
+
 #ifdef MOZ_UPDATER
 /* prefs used specifically for updating the app */
 pref("app.update.enabled", false);
 pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
 
 // If you are looking for app.update.url, we no longer use it.
 // See mobile/android/base/UpdateServiceHelper.java.in
 #endif
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1727,17 +1727,21 @@ abstract public class GeckoApp
 
         mPromptService = new PromptService();
 
         mTextSelection = new TextSelection((TextSelectionHandle) findViewById(R.id.start_handle),
                                            (TextSelectionHandle) findViewById(R.id.middle_handle),
                                            (TextSelectionHandle) findViewById(R.id.end_handle),
                                            GeckoAppShell.getEventDispatcher());
 
-        UpdateServiceHelper.registerForUpdates(this);
+        PrefsHelper.getPref("app.update.autodownload", new PrefsHelper.PrefHandlerBase() {
+            @Override public void prefValue(String pref, String value) {
+                UpdateServiceHelper.registerForUpdates(GeckoApp.this, value);
+            }
+        });
 
         final GeckoApp self = this;
 
         // End of the startup of our Java App
         mJavaUiStartupTimer.stop();
 
         GeckoAppShell.getHandler().postDelayed(new Runnable() {
             public void run() {
--- a/mobile/android/base/GeckoPreferences.java
+++ b/mobile/android/base/GeckoPreferences.java
@@ -49,16 +49,17 @@ public class GeckoPreferences
     private PreferenceScreen mPreferenceScreen;
     private static boolean sIsCharEncodingEnabled = false;
     private static final String NON_PREF_PREFIX = "android.not_a_preference.";
 
     // These match keys in resources/xml/preferences.xml.in.
     public static String PREFS_MP_ENABLED         = "privacy.masterpassword.enabled";
     public static String PREFS_MENU_CHAR_ENCODING = "browser.menu.showCharacterEncoding";
     public static String PREFS_ANNOUNCEMENTS_ENABLED = NON_PREF_PREFIX + "privacy.announcements.enabled";
+    public static String PREFS_UPDATER_AUTODOWNLOAD  = "app.update.autodownload";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.preferences);
         registerEventListener("Sanitize:Finished");
     }
 
@@ -205,16 +206,18 @@ public class GeckoPreferences
             showDialog((Boolean) newValue ? DIALOG_CREATE_MASTER_PASSWORD : DIALOG_REMOVE_MASTER_PASSWORD);
             return false;
         } else if (prefName != null && prefName.equals(PREFS_MENU_CHAR_ENCODING)) {
             setCharEncodingState(((String) newValue).equals("true"));
         } else if (prefName != null && prefName.equals(PREFS_ANNOUNCEMENTS_ENABLED)) {
             // Send a broadcast intent to the product announcements service, either to start or
             // to stop the repeated background checks.
             broadcastAnnouncementsPref(GeckoApp.mAppContext, ((Boolean) newValue).booleanValue());
+        } else if (prefName != null && prefName.equals(PREFS_UPDATER_AUTODOWNLOAD)) {
+            org.mozilla.gecko.updater.UpdateServiceHelper.registerForUpdates(GeckoApp.mAppContext, (String)newValue);
         }
 
         if (!TextUtils.isEmpty(prefName)) {
             PrefsHelper.setPref(prefName, newValue);
         }
         if (preference instanceof ListPreference) {
             // We need to find the entry for the new value
             int newIndex = ((ListPreference)preference).findIndexOfValue((String) newValue);
--- a/mobile/android/base/UpdateService.java
+++ b/mobile/android/base/UpdateService.java
@@ -71,16 +71,17 @@ public class UpdateService extends Inten
     private static final int INTERVAL_SHORT = 14400000; // again, in milliseconds
     private static final int INTERVAL_RETRY = 3600000;
 
     private static final String PREFS_NAME = "UpdateService";
     private static final String KEY_LAST_BUILDID = "UpdateService.lastBuildID";
     private static final String KEY_LAST_HASH_FUNCTION = "UpdateService.lastHashFunction";
     private static final String KEY_LAST_HASH_VALUE = "UpdateService.lastHashValue";
     private static final String KEY_LAST_ATTEMPT_DATE = "UpdateService.lastAttemptDate";
+    private static final String KEY_AUTODOWNLOAD_POLICY = "UpdateService.autoDownloadPolicy";
 
     private SharedPreferences mPrefs;
 
     private NotificationManager mNotificationManager;
     private ConnectivityManager mConnectivityManager;
 
     private boolean mDownloading;
     private boolean mApplyImmediately;
@@ -113,16 +114,21 @@ public class UpdateService extends Inten
         }
 
         return Service.START_REDELIVER_INTENT;
     }
 
     @Override
     protected void onHandleIntent (Intent intent) {
         if (UpdateServiceHelper.ACTION_REGISTER_FOR_UPDATES.equals(intent.getAction())) {
+            int policy = intent.getIntExtra(UpdateServiceHelper.EXTRA_AUTODOWNLOAD_NAME, -1);
+            if (policy >= 0) {
+                setAutoDownloadPolicy(policy);
+            }
+
             registerForUpdates(false);
         } else if (UpdateServiceHelper.ACTION_CHECK_FOR_UPDATE.equals(intent.getAction())) {
             startUpdate(intent.getIntExtra(UpdateServiceHelper.EXTRA_UPDATE_FLAGS_NAME, 0));
         } else if (UpdateServiceHelper.ACTION_APPLY_UPDATE.equals(intent.getAction())) {
             applyUpdate(intent.getStringExtra(UpdateServiceHelper.EXTRA_PACKAGE_PATH_NAME));
         }
     }
 
@@ -197,20 +203,23 @@ public class UpdateService extends Inten
         if (!haveUpdate) {
             Log.i(LOGTAG, "no update available");
             return;
         }
 
         Log.i(LOGTAG, "update available, buildID = " + info.buildID);
         
         int connectionType = netInfo.getType();
+        int autoDownloadPolicy = getAutoDownloadPolicy();
         if (!hasFlag(flags, UpdateServiceHelper.FLAG_FORCE_DOWNLOAD) &&
-            connectionType != ConnectivityManager.TYPE_WIFI &&
-            connectionType != ConnectivityManager.TYPE_ETHERNET) {
-            Log.i(LOGTAG, "not connected via wifi or ethernet");
+            autoDownloadPolicy != UpdateServiceHelper.AUTODOWNLOAD_ENABLED &&
+            (autoDownloadPolicy == UpdateServiceHelper.AUTODOWNLOAD_WIFI &&
+             connectionType != ConnectivityManager.TYPE_WIFI &&
+             connectionType != ConnectivityManager.TYPE_ETHERNET)) {
+            Log.i(LOGTAG, "not initiating automatic update download due to policy " + autoDownloadPolicy);
 
             // We aren't autodownloading here, so prompt to start the update
             Notification notification = new Notification(R.drawable.ic_status_logo, null, System.currentTimeMillis());
 
             Intent notificationIntent = new Intent(UpdateServiceHelper.ACTION_CHECK_FOR_UPDATE);
             notificationIntent.setClass(this, UpdateService.class);
             notificationIntent.putExtra(UpdateServiceHelper.EXTRA_UPDATE_FLAGS_NAME, UpdateServiceHelper.FLAG_FORCE_DOWNLOAD);
 
@@ -517,16 +526,26 @@ public class UpdateService extends Inten
     }
 
     private void setLastAttemptDate() {
         SharedPreferences.Editor editor = mPrefs.edit();
         editor.putLong(KEY_LAST_ATTEMPT_DATE, System.currentTimeMillis());
         editor.commit();
     }
 
+    private int getAutoDownloadPolicy() {
+        return mPrefs.getInt(KEY_AUTODOWNLOAD_POLICY, UpdateServiceHelper.AUTODOWNLOAD_WIFI);
+    }
+
+    private void setAutoDownloadPolicy(int policy) {
+        SharedPreferences.Editor editor = mPrefs.edit();
+        editor.putInt(KEY_AUTODOWNLOAD_POLICY, policy);
+        editor.commit();
+    }
+
     private void saveUpdateInfo(UpdateInfo info) {
         SharedPreferences.Editor editor = mPrefs.edit();
         editor.putString(KEY_LAST_BUILDID, info.buildID);
         editor.putString(KEY_LAST_HASH_FUNCTION, info.hashFunction);
         editor.putString(KEY_LAST_HASH_VALUE, info.hashValue);
         editor.commit();
     }
 
--- a/mobile/android/base/UpdateServiceHelper.java.in
+++ b/mobile/android/base/UpdateServiceHelper.java.in
@@ -29,16 +29,24 @@ public class UpdateServiceHelper {
     public static final String ACTION_APPLY_UPDATE = "@ANDROID_PACKAGE_NAME@.APPLY_UPDATE";
 
     // Flags for ACTION_CHECK_FOR_UPDATE
     public static final int FLAG_FORCE_DOWNLOAD = 1;
     public static final int FLAG_OVERWRITE_EXISTING = 1 << 1;
     public static final int FLAG_REINSTALL = 1 << 2;
     public static final int FLAG_RETRY = 1 << 3;
 
+    // Name of the Intent extra for the autodownload policy, used with ACTION_REGISTER_FOR_UPDATES
+    public static final String EXTRA_AUTODOWNLOAD_NAME = "autodownload";
+
+    // Values for EXTRA_AUTODOWNLOAD_NAME
+    public static final int AUTODOWNLOAD_WIFI = 0;
+    public static final int AUTODOWNLOAD_DISABLED = 1;
+    public static final int AUTODOWNLOAD_ENABLED = 2;
+
     // Name of the Intent extra that holds the flags for ACTION_CHECK_FOR_UPDATE
     public static final String EXTRA_UPDATE_FLAGS_NAME = "updateFlags";
 
     // Name of the Intent extra that holds the APK path, used with ACTION_APPLY_UPDATE
     public static final String EXTRA_PACKAGE_PATH_NAME = "packagePath";
 
     public static final String UPDATE_CHANNEL = "@MOZ_UPDATE_CHANNEL@";
 
@@ -87,15 +95,38 @@ public class UpdateServiceHelper {
     public static boolean isUpdaterEnabled() {
 #ifdef MOZ_UPDATER
         return true;
 #else
         return false;
 #endif
     }
 
-    public static void registerForUpdates(Context context) {
+    public static void registerForUpdates(Context context, String policy) {
+        if (policy == null)
+            return;
+
+        int intPolicy;
+        if (policy.equals("wifi")) {
+            intPolicy = AUTODOWNLOAD_WIFI;
+        } else if (policy.equals("disabled")) {
+            intPolicy = AUTODOWNLOAD_DISABLED;
+        } else if (policy.equals("enabled")) {
+            intPolicy = AUTODOWNLOAD_ENABLED;
+        } else {
+            Log.w(LOGTAG, "Unhandled autoupdate policy: " + policy);
+            return;
+        }
+
+        registerForUpdates(context, intPolicy);
+    }
+
+    // 'policy' should one of AUTODOWNLOAD_WIFI, AUTODOWNLOAD_DISABLED, AUTODOWNLOAD_ENABLED
+    public static void registerForUpdates(Context context, int policy) {
         if (!isUpdaterEnabled())
             return;
 
-        context.startService(new Intent(UpdateServiceHelper.ACTION_REGISTER_FOR_UPDATES, null, context, UpdateService.class));
+        Intent intent = new Intent(UpdateServiceHelper.ACTION_REGISTER_FOR_UPDATES, null, context, UpdateService.class);
+        intent.putExtra(EXTRA_AUTODOWNLOAD_NAME, policy);
+
+        context.startService(intent);
     }
 }
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -107,16 +107,21 @@ size. -->
 <!ENTITY pref_private_data_history "Browsing &amp; download history">
 <!ENTITY pref_private_data_formdata "Form &amp; search history">
 <!ENTITY pref_private_data_cookies2 "Cookies &amp; active logins">
 <!ENTITY pref_private_data_passwords "Saved passwords">
 <!ENTITY pref_private_data_cache "Cache">
 <!ENTITY pref_private_data_offlineApps "Offline website data">
 <!ENTITY pref_private_data_siteSettings "Site preferences">
 
+<!ENTITY pref_update_autodownload "Automatic updates">
+<!ENTITY pref_update_autodownload_wifi "Only over Wi-Fi">
+<!ENTITY pref_update_autodownload_disabled "Disabled">
+<!ENTITY pref_update_autodownload_enabled "Enabled">
+
 <!ENTITY quit "Quit">
 
 <!ENTITY addons "Add-ons">
 <!ENTITY downloads "Downloads">
 <!ENTITY apps "Apps">
 <!ENTITY char_encoding "Character Encoding">
 
 <!ENTITY share "Share">
--- a/mobile/android/base/resources/values/arrays.xml
+++ b/mobile/android/base/resources/values/arrays.xml
@@ -71,9 +71,19 @@
         <item>private.data.history_downloads</item>
         <item>private.data.formdata</item>
         <item>private.data.cookies_sessions</item>
         <item>private.data.passwords</item>
         <item>private.data.cache</item>
         <item>private.data.offlineApps</item>
         <item>private.data.siteSettings</item>
     </string-array>
+    <string-array name="pref_update_autodownload_entries">
+        <item>@string/pref_update_autodownload_wifi</item>
+        <item>@string/pref_update_autodownload_disabled</item>
+        <item>@string/pref_update_autodownload_enabled</item>
+    </string-array>
+    <string-array name="pref_update_autodownload_values">
+        <item>wifi</item>
+        <item>disabled</item>
+        <item>enabled</item>
+    </string-array>
 </resources>
--- a/mobile/android/base/resources/xml/preferences.xml.in
+++ b/mobile/android/base/resources/xml/preferences.xml.in
@@ -11,16 +11,24 @@
 
     <PreferenceCategory android:title="@string/pref_category_general">
         <org.mozilla.gecko.LinkPreference android:title="@string/pref_about_firefox"
                                           url="about:" />
 
         <org.mozilla.gecko.SyncPreference android:title="@string/pref_sync"
                                           android:persistent="false" />
 
+#ifdef MOZ_UPDATER
+        <ListPreference android:key="app.update.autodownload"
+                        android:title="@string/pref_update_autodownload"
+                        android:entries="@array/pref_update_autodownload_entries"
+                        android:entryValues="@array/pref_update_autodownload_values"
+                        android:persistent="false" />
+#endif
+
     </PreferenceCategory>
 
     <PreferenceCategory android:title="@string/pref_category_content">
 
         <ListPreference android:key="browser.menu.showCharacterEncoding"
                         android:title="@string/pref_char_encoding"
                         android:entries="@array/pref_char_encoding_entries"
                         android:entryValues="@array/pref_char_encoding_values"
@@ -104,10 +112,9 @@
           gecko:entryKeys="@array/pref_import_android_keys"
           gecko:initialValues="@array/pref_import_android_values"
           android:title="@string/pref_import_android"
           android:positiveButtonText="@string/bookmarkhistory_button_import"
           android:negativeButtonText="@string/button_cancel"
           android:persistent="false" />
 
     </PreferenceCategory>
-
 </PreferenceScreen>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -102,16 +102,20 @@
   <string name="pref_private_data_history">&pref_private_data_history;</string>
   <string name="pref_private_data_formdata">&pref_private_data_formdata;</string>
   <string name="pref_private_data_cookies2">&pref_private_data_cookies2;</string>
   <string name="pref_private_data_passwords">&pref_private_data_passwords;</string>
   <string name="pref_private_data_cache">&pref_private_data_cache;</string>
   <string name="pref_private_data_offlineApps">&pref_private_data_offlineApps;</string>
   <string name="pref_private_data_siteSettings">&pref_private_data_siteSettings;</string>
   <string name="pref_import_android">&pref_import_android;</string>
+  <string name="pref_update_autodownload">&pref_update_autodownload;</string>
+  <string name="pref_update_autodownload_wifi">&pref_update_autodownload_wifi;</string>
+  <string name="pref_update_autodownload_disabled">&pref_update_autodownload_disabled;</string>
+  <string name="pref_update_autodownload_enabled">&pref_update_autodownload_enabled;</string>
 
   <string name="go">&go;</string>
   <string name="search">&search;</string>
   <string name="reload">&reload;</string>
   <string name="forward">&forward;</string>
   <string name="menu">&menu;</string>
   <string name="back">&back;</string>
   <string name="stop">&stop;</string>