Bug 1252666 - Part 2: Use reflection to start PushService. r=margaret

The alternative is to define an interface and two conditional
implementations, and then build only one depending on MOZ_ANDROID_GCM.
That's what we did for Adjust, and it works; but it's awkward here
because the the PushService code is truly part of the browser, and the
conditional code is compiled very early (much earlier than the
browser).  (The Adjust library was built even earlier than the
existing conditional code, so this wasn't an issue.)  To work around
this, we'd want to add conditional code to the main browser, which
complicates the build.  This is expedient until we get to a proper
dependency injection scheme (for example, Dagger).

MozReview-Commit-ID: 18usWz8oC3B
This commit is contained in:
Nick Alexander 2016-03-07 14:37:57 -08:00
Родитель d8a65feef6
Коммит 5b9b896497
2 изменённых файлов: 41 добавлений и 17 удалений

Просмотреть файл

@ -4,8 +4,15 @@
package org.mozilla.gecko;
import org.mozilla.gecko.AdjustConstants;
import org.mozilla.gecko.AppConstants;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.SystemClock;
import android.util.Log;
import com.squareup.leakcanary.LeakCanary;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.db.LocalBrowserDB;
@ -17,16 +24,8 @@ import org.mozilla.gecko.util.Clipboard;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.ThreadUtils;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.SystemClock;
import android.util.Log;
import com.squareup.leakcanary.LeakCanary;
import java.io.File;
import java.lang.reflect.Method;
public class GeckoApplication extends Application
implements ContextGetter {
@ -165,6 +164,26 @@ public class GeckoApplication extends Application
super.onCreate();
if (AppConstants.MOZ_ANDROID_GCM) {
// TODO: only run in main process.
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
// It's fine to throw GCM initialization onto a background thread; the registration process requires
// network access, so is naturally asynchronous. This, of course, races against Gecko page load of
// content requiring GCM-backed services, like Web Push. There's nothing to be done here.
try {
final Class<?> clazz = Class.forName("org.mozilla.gecko.push.PushService");
final Method onCreate = clazz.getMethod("onCreate", Context.class);
onCreate.invoke(null, getApplicationContext()); // Method is static.
} catch (Exception e) {
Log.e(LOG_TAG, "Got exception during startup; ignoring.", e);
return;
}
}
});
}
if (AppConstants.MOZ_ANDROID_DOWNLOAD_CONTENT_SERVICE) {
DownloadContentService.startStudy(this);
}

Просмотреть файл

@ -17,6 +17,7 @@ import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoThread;
import org.mozilla.gecko.annotation.ReflectionTarget;
import org.mozilla.gecko.gcm.GcmTokenClient;
import org.mozilla.gecko.push.autopush.AutopushClientException;
import org.mozilla.gecko.util.BundleEventListener;
@ -34,6 +35,7 @@ import java.util.Map;
* <p/>
* It's worth noting that we allow the DOM push API in restricted profiles.
*/
@ReflectionTarget
public class PushService implements BundleEventListener {
private static final String LOG_TAG = "GeckoPushService";
@ -58,12 +60,15 @@ public class PushService implements BundleEventListener {
return sInstance;
}
public static synchronized PushService createInstance(Context context) {
@ReflectionTarget
public static synchronized void onCreate(Context context) {
if (sInstance != null) {
throw new IllegalStateException("PushService already created!");
}
sInstance = new PushService(context);
return sInstance;
sInstance.registerGeckoEventListener();
sInstance.onStartup();
}
protected final PushManager pushManager;
@ -180,14 +185,14 @@ public class PushService implements BundleEventListener {
}
}
public static void registerGeckoEventListener() {
protected void registerGeckoEventListener() {
Log.d(LOG_TAG, "Registered Gecko event listener.");
EventDispatcher.getInstance().registerBackgroundThreadListener(getInstance(), GECKO_EVENTS);
EventDispatcher.getInstance().registerBackgroundThreadListener(this, GECKO_EVENTS);
}
public static void unregisterGeckoEventListener() {
protected void unregisterGeckoEventListener() {
Log.d(LOG_TAG, "Unregistered Gecko event listener.");
EventDispatcher.getInstance().unregisterBackgroundThreadListener(getInstance(), GECKO_EVENTS);
EventDispatcher.getInstance().unregisterBackgroundThreadListener(this, GECKO_EVENTS);
}
@Override