Bug 1216834 - Don't override android wallpaper at first run r=sgiles
authorFabrice Desré <fabrice@mozilla.com>
Mon, 26 Oct 2015 09:42:30 -0700
changeset 304734 26a280477b42e3aaf0cdfdde2404efbd88b5df95
parent 304733 96bd799bae28f709ac3d422b3f1ba74a95100f3f
child 304735 26b6cdfc8b36410d403e43980b9553387cd63222
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssgiles
bugs1216834
milestone44.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 1216834 - Don't override android wallpaper at first run r=sgiles
b2g/chrome/content/settings.js
mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/SettingsMapper.java
mobile/android/b2gdroid/components/Setup.js
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -116,17 +116,25 @@ SettingsListener.observe('language.curre
   if (!((new RegExp('^' + value + '[^a-z-_] *[,;]?', 'i')).test(intl))) {
     value = value + ', ' + intl;
   } else {
     value = intl;
   }
   Services.prefs.setCharPref(prefName, value);
 
   if (shell.hasStarted() == false) {
-    shell.bootstrap();
+    // On b2gdroid at first run we need to synchronize our wallpaper with
+    // Android one's before bootstrapping.
+    if (AppConstants.MOZ_B2GDROID) {
+      Cc["@mozilla.org/b2g/b2gdroid-setup;1"]
+        .getService().wrappedJSObject.setWallpaper()
+        .then(() => { shell.bootstrap(); });
+    } else {
+      shell.bootstrap();
+    }
   }
 });
 
 // =================== RIL ====================
 (function RILSettingsToPrefs() {
   // DSDS default service IDs
   ['mms', 'sms', 'telephony', 'voicemail'].forEach(function(key) {
     SettingsListener.observe('ril.' + key + '.defaultServiceId', 0,
--- a/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/SettingsMapper.java
+++ b/mobile/android/b2gdroid/app/src/main/java/org/mozilla/b2gdroid/SettingsMapper.java
@@ -1,25 +1,29 @@
 /* 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/. */
 
 package org.mozilla.b2gdroid;
 
+import java.io.ByteArrayOutputStream;
 import java.util.Hashtable;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Handler;
 import android.provider.Settings.System;
 import android.telephony.TelephonyManager;
 import android.util.Base64;
 import android.util.Log;
 
 import org.mozilla.gecko.EventDispatcher;
@@ -161,17 +165,18 @@ class SettingsMapper extends ContentObse
     }
 
     SettingsMapper(Context context, Handler handler) {
         super(handler);
         mContext = context;
         EventDispatcher.getInstance()
                        .registerGeckoThreadListener(this,
                                                     "Settings:Change",
-                                                    "Android:GetIMEI");
+                                                    "Android:GetIMEI",
+                                                    "Android:GetWallpaper");
 
         mContext.getContentResolver()
                 .registerContentObserver(System.CONTENT_URI,
                                          true,
                                          this);
 
         mGeckoSettings = new Hashtable<String, BaseMapping>();
         mAndroidSettings = new Hashtable<String, BaseMapping>();
@@ -192,17 +197,18 @@ class SettingsMapper extends ContentObse
             mAndroidSettings.put(props[i], mapping);
         }
     }
 
     void destroy() {
         EventDispatcher.getInstance()
                        .unregisterGeckoThreadListener(this,
                                                       "Settings:Change",
-                                                      "Android:GetIMEI");
+                                                      "Android:GetIMEI",
+                                                      "Android:GetWallpaper");
         mGeckoSettings.clear();
         mGeckoSettings = null;
         mAndroidSettings.clear();
         mAndroidSettings = null;
         mContext.getContentResolver().unregisterContentObserver(this);
     }
 
     public void handleMessage(String event, JSONObject message) {
@@ -227,16 +233,53 @@ class SettingsMapper extends ContentObse
             JSONObject ret = new JSONObject();
             Log.d(LOGTAG, "Getting IMEI: " + telManager.getDeviceId());
             try {
                 ret.put("imei", telManager.getDeviceId());
             } catch(Exception jsonEx) {
                 Log.wtf(LOGTAG, "Error getting IMEI", jsonEx);
             }
             EventDispatcher.sendResponse(message, ret);
+        } else if ("Android:GetWallpaper".equals(event)) {
+            WallpaperManager wpManager = WallpaperManager.getInstance(mContext);
+            Drawable drawable = wpManager.getDrawable();
+
+            // Convert the drawable to a base64 url, using a bitmap.
+            Bitmap bitmap = null;
+
+            if (drawable instanceof BitmapDrawable) {
+                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+                if(bitmapDrawable.getBitmap() != null) {
+                    bitmap = bitmapDrawable.getBitmap();
+                }
+            }
+
+            if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
+                bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
+            } else {
+                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
+                                             drawable.getIntrinsicHeight(),
+                                             Bitmap.Config.ARGB_8888);
+            }
+
+            Canvas canvas = new Canvas(bitmap);
+            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+            drawable.draw(canvas);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
+            byte b [] = baos.toByteArray();
+            final String uri = "data:image/png;base64," + Base64.encodeToString(b, Base64.NO_WRAP);
+
+            JSONObject ret = new JSONObject();
+            try {
+                ret.put("wallpaper", uri);
+            } catch(Exception jsonEx) {
+                Log.wtf(LOGTAG, "Error getting Wallpaper", jsonEx);
+            }
+            EventDispatcher.sendResponse(message, ret);
         }
     }
 
     // ContentObserver, see
     // http://developer.android.com/reference/android/database/ContentObserver.html
     @Override
     public boolean deliverSelfNotifications() {
         return false;
--- a/mobile/android/b2gdroid/components/Setup.js
+++ b/mobile/android/b2gdroid/components/Setup.js
@@ -13,27 +13,51 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/MessagesBridge.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AppsUtils",
                                   "resource://gre/modules/AppsUtils.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "settings",
+                                   "@mozilla.org/settingsService;1",
+                                   "nsISettingsService");
+
 function debug() {
   dump("-*- B2GDroidSetup " + Array.slice(arguments) + "\n");
 }
 
-function B2GDroidSetup() { }
+function B2GDroidSetup() {
+  this.wrappedJSObject = this;
+  this.isFirstRun = true;
+}
 
 B2GDroidSetup.prototype = {
   classID:         Components.ID('{8bc88ef2-3aab-4e94-a40c-e2c80added2c}'),
   QueryInterface:  XPCOMUtils.generateQI([Ci.nsIObserver,
                                           Ci.nsISupportsWeakReference]),
 
+  // Returns a promise that resolves once we have set the wallpaper.image
+  // setting in sync with Android's wallpaper.
+  setWallpaper: function() {
+    if (!this.isFirstRun) {
+      return Promise.resolve();
+    }
+
+    debug("Getting wallpaper");
+
+    Cu.import("resource://gre/modules/Messaging.jsm");
+    return Messaging.sendRequestForResult({ type: "Android:GetWallpaper" })
+      .then(aData => {
+        settings.createLock().set("wallpaper.image", aData.wallpaper, null);
+        return Promise.resolve();
+      });
+  },
+
   getApk: function() {
     let registry = Cc["@mozilla.org/chrome/chrome-registry;1"]
                      .getService(Ci.nsIChromeRegistry);
     let url = registry.convertChromeURL(
       Services.io.newURI("chrome://b2g/content/shell.html", null, null)).spec;
     // url is something like jar:jar:file:///data/app/org.mozilla.fennec_fabrice-1.apk!/assets/omni.ja!/chrome/chrome/content/shell.html
     // and we just need the apk file path.
     let path = url.substring(url.indexOf("///") + 2, url.indexOf(".apk") + 4);
@@ -220,16 +244,17 @@ B2GDroidSetup.prototype = {
     if (aTopic !== "profile-after-change") {
       return;
     }
 
     // At first run of after updates, unpack gaia.
     let branch = Services.prefs.getBranch("b2gdroid");
     if (!AppsUtils.isFirstRun(branch)) {
       debug("No need to unpack gaia again.");
+      this.isFirstRun = false;
       return;
     }
 
     let profile = Services.dirsvc.get("DefRt", Ci.nsIFile);
     debug("profile directory is " + profile.path);
 
     let webapps = profile.clone();
     webapps.append("webapps");