Merge remote-tracking branch 'origin/121212_sb_gcm'

pull/14/head
Sam Bosley 13 years ago
commit b3625f4c63

@ -66,16 +66,16 @@ public class DateUtilities {
} }
/** Represents a single hour */ /** Represents a single hour */
public static long ONE_HOUR = 3600000L; public static final long ONE_HOUR = 3600000L;
/** Represents a single day */ /** Represents a single day */
public static long ONE_DAY = 24 * ONE_HOUR; public static final long ONE_DAY = 24 * ONE_HOUR;
/** Represents a single week */ /** Represents a single week */
public static long ONE_WEEK = 7 * ONE_DAY; public static final long ONE_WEEK = 7 * ONE_DAY;
/** Represents a single minute */ /** Represents a single minute */
public static long ONE_MINUTE = 60000L; public static final long ONE_MINUTE = 60000L;
/* ====================================================================== /* ======================================================================
* =========================================================== formatters * =========================================================== formatters

@ -31,5 +31,6 @@
<classpathentry kind="lib" path="libs/crittercism_v2_1_2.jar"/> <classpathentry kind="lib" path="libs/crittercism_v2_1_2.jar"/>
<classpathentry kind="lib" path="libs/findbugs-annotations.jar"/> <classpathentry kind="lib" path="libs/findbugs-annotations.jar"/>
<classpathentry kind="lib" path="libs/CWAC-SackOfViewsAdapter.jar"/> <classpathentry kind="lib" path="libs/CWAC-SackOfViewsAdapter.jar"/>
<classpathentry kind="lib" path="libs/gcm.jar" sourcepath="libs/gcm-src.jar"/>
<classpathentry kind="output" path="bin/classes"/> <classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>

@ -46,6 +46,9 @@
<!-- required for in-app billing of premium subscriptions --> <!-- required for in-app billing of premium subscriptions -->
<uses-permission android:name="com.android.vending.BILLING"/> <uses-permission android:name="com.android.vending.BILLING"/>
<!-- Required for GCM - keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- ============================================== Exported Permissions = --> <!-- ============================================== Exported Permissions = -->
<!-- for v2 tasks provider --> <!-- for v2 tasks provider -->
@ -409,19 +412,17 @@
android:theme="@style/Theme.Dialog"/> android:theme="@style/Theme.Dialog"/>
<activity android:name="com.todoroo.astrid.actfm.CommentsActivity" <activity android:name="com.todoroo.astrid.actfm.CommentsActivity"
android:windowSoftInputMode="stateHidden"/> android:windowSoftInputMode="stateHidden"/>
<receiver android:name="com.timsu.astrid.C2DMReceiver" permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message --> <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter> <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.timsu.astrid" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.timsu.astrid" /> <category android:name="com.timsu.astrid" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service android:name=".GCMIntentService" />
<!-- gtasks --> <!-- gtasks -->
<activity android:name="com.todoroo.astrid.gtasks.GtasksListFragment" <activity android:name="com.todoroo.astrid.gtasks.GtasksListFragment"
android:windowSoftInputMode="stateHidden|adjustResize" android:windowSoftInputMode="stateHidden|adjustResize"

Binary file not shown.

Binary file not shown.

@ -1,8 +1,3 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.timsu.astrid; package com.timsu.astrid;
import java.io.IOException; import java.io.IOException;
@ -12,7 +7,6 @@ import org.json.JSONObject;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
@ -20,6 +14,8 @@ import android.provider.Settings.Secure;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
@ -55,36 +51,18 @@ import com.todoroo.astrid.tags.TagFilterExposer;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
@SuppressWarnings("nls") @SuppressWarnings("nls")
public class C2DMReceiver extends BroadcastReceiver { public class GCMIntentService extends GCMBaseIntentService {
public static final String C2DM_SENDER = "c2dm@astrid.com"; //$NON-NLS-1$ public static final String SENDER_ID = "1003855277730"; //$NON-NLS-1$
public static final String PREF_REGISTRATION = "gcm_id";
public static final String PREF_NEEDS_REGISTRATION = "gcm_needs_reg";
private static final String PREF_REGISTRATION = "c2dm_key"; private static final String PREF_LAST_GCM = "c2dm_last";
private static final String PREF_LAST_C2DM = "c2dm_last"; public static final String PREF_C2DM_REGISTRATION = "c2dm_key";
private static final long MIN_MILLIS_BETWEEN_FULL_SYNCS = DateUtilities.ONE_HOUR; public static String getDeviceID() {
@Autowired TaskService taskService;
@Autowired TagDataService tagDataService;
@Autowired UpdateDao updateDao;
@Autowired ActFmPreferenceService actFmPreferenceService;
@Autowired ActFmSyncService actFmSyncService;
static {
AstridDependencyInjector.initialize();
}
private final SyncResultCallbackAdapter refreshOnlyCallback = new SyncResultCallbackAdapter() {
@Override
public void finished() {
ContextManager.getContext().sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
}
};
private static String getDeviceID() {
String id = Secure.getString(ContextManager.getContext().getContentResolver(), Secure.ANDROID_ID);; String id = Secure.getString(ContextManager.getContext().getContentResolver(), Secure.ANDROID_ID);;
if(AndroidUtilities.getSdkVersion() > 8) { //Gingerbread and above if(AndroidUtilities.getSdkVersion() > 8) { //Gingerbread and above
//the following uses relection to get android.os.Build.SERIAL to avoid having to build with Gingerbread //the following uses relection to get android.os.Build.SERIAL to avoid having to build with Gingerbread
try { try {
if(!Build.UNKNOWN.equals(Build.SERIAL)) if(!Build.UNKNOWN.equals(Build.SERIAL))
@ -101,16 +79,44 @@ public class C2DMReceiver extends BroadcastReceiver {
return id; return id;
} }
@Override static {
public void onReceive(Context context, final Intent intent) { AstridDependencyInjector.initialize();
ContextManager.setContext(context); }
@Autowired
private ActFmSyncService actFmSyncService;
@Autowired
private ActFmPreferenceService actFmPreferenceService;
@Autowired
private TaskService taskService;
@Autowired
private TagDataService tagDataService;
@Autowired
private UpdateDao updateDao;
public GCMIntentService() {
super();
DependencyInjectionService.getInstance().inject(this); DependencyInjectionService.getInstance().inject(this);
if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) { }
handleRegistration(intent);
} else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
new Thread(new Runnable() { // ===================== Messaging =================== //
private final SyncResultCallbackAdapter refreshOnlyCallback = new SyncResultCallbackAdapter() {
@Override @Override
public void run() { public void finished() {
ContextManager.getContext().sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
}
};
private static final long MIN_MILLIS_BETWEEN_FULL_SYNCS = DateUtilities.ONE_HOUR;
@Override
protected void onMessage(Context context, Intent intent) {
if (actFmPreferenceService.isLoggedIn()) { if (actFmPreferenceService.isLoggedIn()) {
if(intent.hasExtra("web_update")) if(intent.hasExtra("web_update"))
if (DateUtilities.now() - actFmPreferenceService.getLastSyncDate() > MIN_MILLIS_BETWEEN_FULL_SYNCS && !actFmPreferenceService.isOngoing()) if (DateUtilities.now() - actFmPreferenceService.getLastSyncDate() > MIN_MILLIS_BETWEEN_FULL_SYNCS && !actFmPreferenceService.isOngoing())
@ -121,11 +127,6 @@ public class C2DMReceiver extends BroadcastReceiver {
handleMessage(intent); handleMessage(intent);
} }
} }
}).start();
}
}
// --- web update handling
/** Handle web task or list changed */ /** Handle web task or list changed */
protected void handleWebUpdate(Intent intent) { protected void handleWebUpdate(Intent intent) {
@ -192,10 +193,10 @@ public class C2DMReceiver extends BroadcastReceiver {
if(TextUtils.isEmpty(message)) if(TextUtils.isEmpty(message))
return; return;
long lastNotification = Preferences.getLong(PREF_LAST_C2DM, 0); long lastNotification = Preferences.getLong(PREF_LAST_GCM, 0);
if(DateUtilities.now() - lastNotification < 5000L) if(DateUtilities.now() - lastNotification < 5000L)
return; return;
Preferences.setLong(PREF_LAST_C2DM, DateUtilities.now()); Preferences.setLong(PREF_LAST_GCM, DateUtilities.now());
Intent notifyIntent = null; Intent notifyIntent = null;
int notifId; int notifId;
@ -419,56 +420,67 @@ public class C2DMReceiver extends BroadcastReceiver {
return true; return true;
} }
private void handleRegistration(Intent intent) { // ==================== Registration ============== //
final String registration = intent.getStringExtra("registration_id");
if (intent.getStringExtra("error") != null) { public static final void register(Context context) {
Log.w("astrid-actfm", "error-c2dm: " + intent.getStringExtra("error"));
} else if (intent.getStringExtra("unregistered") != null) {
// un-registration done
} else if (registration != null) {
DependencyInjectionService.getInstance().inject(this);
new Thread() {
@Override
public void run() {
try { try {
String deviceId = getDeviceID(); if (AndroidUtilities.getSdkVersion() >= 8) {
if (deviceId != null) GCMRegistrar.checkDevice(context);
actFmSyncService.invoke("user_set_c2dm", "c2dm", registration, "device_id", deviceId); GCMRegistrar.checkManifest(context);
else final String regId = GCMRegistrar.getRegistrationId(context);
actFmSyncService.invoke("user_set_c2dm", "c2dm", registration); if ("".equals(regId)) {
Preferences.setString(PREF_REGISTRATION, registration); GCMRegistrar.register(context, GCMIntentService.SENDER_ID);
} catch (IOException e) { } else {
Log.e("astrid-actfm", "error-c2dm-transfer", e); // TODO: Already registered--do something?
} }
} }
}.start(); } catch (Exception e) {
// phone may not support gcm
Log.e("actfm-sync", "gcm-register", e);
} }
} }
/** try to request registration from c2dm service */ public static final void unregister(Context context) {
public static void register() { try {
if(Preferences.getStringValue(PREF_REGISTRATION) != null) if (AndroidUtilities.getSdkVersion() >= 8) {
return; GCMRegistrar.unregister(context);
}
} catch (Exception e) {
Log.e("actfm-sync", "gcm-unregister", e);
}
}
new Thread() {
@Override @Override
public void run() { protected void onRegistered(Context context, String registrationId) {
Context context = ContextManager.getContext(); actFmSyncService.setGCMRegistration(registrationId);
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
registrationIntent.putExtra("app", PendingIntent.getBroadcast(context, 0, new Intent(), 0)); // boilerplate
registrationIntent.putExtra("sender", C2DM_SENDER);
context.startService(registrationIntent);
} }
}.start();
@Override
protected void onUnregistered(Context context, String registrationId) {
// Server can unregister automatically next time it tries to send a message
} }
/** unregister with c2dm service */
public static void unregister() { @Override
Preferences.setString(PREF_REGISTRATION, null); protected void onError(Context context, String intent) {
Context context = ContextManager.getContext(); // Unrecoverable
Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER"); }
unregIntent.putExtra("app", PendingIntent.getBroadcast(context, 0, new Intent(), 0));
context.startService(unregIntent); // =========== Migration ============= //
public static class GCMMigration {
@Autowired
private ActFmPreferenceService actFmPreferenceService;
public GCMMigration() {
DependencyInjectionService.getInstance().inject(this);
}
public void performMigration(Context context) {
if (actFmPreferenceService.isLoggedIn()) {
GCMIntentService.register(context);
}
}
} }
} }

@ -50,7 +50,7 @@ import com.facebook.android.LoginButton;
import com.facebook.android.Util; import com.facebook.android.Util;
import com.google.android.googlelogin.GoogleLoginServiceConstants; import com.google.android.googlelogin.GoogleLoginServiceConstants;
import com.google.android.googlelogin.GoogleLoginServiceHelper; import com.google.android.googlelogin.GoogleLoginServiceHelper;
import com.timsu.astrid.C2DMReceiver; import com.timsu.astrid.GCMIntentService;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
@ -572,12 +572,7 @@ public class ActFmLoginActivity extends FragmentActivity implements AuthListener
setResult(RESULT_OK); setResult(RESULT_OK);
finish(); finish();
try { GCMIntentService.register(this);
C2DMReceiver.register();
} catch (Exception e) {
// phone may not support c2dm
exceptionService.reportError("error-c2dm-register", e);
}
} }
@SuppressWarnings("nls") @SuppressWarnings("nls")

@ -32,6 +32,7 @@ import android.os.ConditionVariable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.timsu.astrid.GCMIntentService;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.DatabaseDao; import com.todoroo.andlib.data.DatabaseDao;
@ -1232,6 +1233,31 @@ public final class ActFmSyncService {
} }
} }
public void setGCMRegistration(String regId) {
try {
String deviceId = GCMIntentService.getDeviceID();
String existingC2DM = Preferences.getStringValue(GCMIntentService.PREF_C2DM_REGISTRATION);
ArrayList<Object> params = new ArrayList<Object>();
params.add("gcm"); params.add(regId);
if (!TextUtils.isEmpty(deviceId)) {
params.add("device_id"); params.add(deviceId);
}
if (!TextUtils.isEmpty(existingC2DM)) { // Unregisters C2DM with the server for migration purposes
params.add("c2dm"); params.add(existingC2DM);
}
invoke("user_set_gcm", params.toArray(new Object[params.size()]));
Preferences.setString(GCMIntentService.PREF_REGISTRATION, regId);
Preferences.setString(GCMIntentService.PREF_C2DM_REGISTRATION, null);
Preferences.setString(GCMIntentService.PREF_NEEDS_REGISTRATION, null);
} catch (IOException e) {
Preferences.setString(GCMIntentService.PREF_NEEDS_REGISTRATION, regId);
Log.e("gcm", "error-gcm-register", e);
}
}
private void pushQueuedUpdatesForTag(TagData tagData) { private void pushQueuedUpdatesForTag(TagData tagData) {
Criterion criterion = null; Criterion criterion = null;
if (tagData.getValue(TagData.REMOTE_ID) < 1) { if (tagData.getValue(TagData.REMOTE_ID) < 1) {

@ -14,7 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import com.timsu.astrid.C2DMReceiver; import com.timsu.astrid.GCMIntentService;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
@ -147,7 +147,7 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
actFmPreferenceService.setToken(null); actFmPreferenceService.setToken(null);
actFmPreferenceService.clearLastSyncDate(); actFmPreferenceService.clearLastSyncDate();
ActFmPreferenceService.premiumLogout(); ActFmPreferenceService.premiumLogout();
C2DMReceiver.unregister(); GCMIntentService.unregister(ContextManager.getContext());
} }
@Override @Override
@ -196,6 +196,10 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
/** fetch user status hash*/ /** fetch user status hash*/
@SuppressWarnings("nls") @SuppressWarnings("nls")
public void updateUserStatus() { public void updateUserStatus() {
if (Preferences.getStringValue(GCMIntentService.PREF_NEEDS_REGISTRATION) != null) {
actFmSyncService.setGCMRegistration(Preferences.getStringValue(GCMIntentService.PREF_NEEDS_REGISTRATION));
}
if (Preferences.getBoolean(BillingConstants.PREF_NEEDS_SERVER_UPDATE, false)) { if (Preferences.getBoolean(BillingConstants.PREF_NEEDS_SERVER_UPDATE, false)) {
actFmSyncService.updateUserSubscriptionStatus(null, null, null); actFmSyncService.updateUserSubscriptionStatus(null, null, null);
} }

@ -17,6 +17,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.os.Bundle; import android.os.Bundle;
import com.timsu.astrid.GCMIntentService;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty; import com.todoroo.andlib.data.Property.StringProperty;
@ -50,6 +51,7 @@ import com.todoroo.astrid.utility.Constants;
public final class UpgradeService { public final class UpgradeService {
public static final int V4_5_1 = 292;
public static final int V4_5_0 = 291; public static final int V4_5_0 = 291;
public static final int V4_4_4_1 = 290; public static final int V4_4_4_1 = 290;
public static final int V4_4_4 = 289; public static final int V4_4_4 = 289;
@ -176,7 +178,7 @@ public final class UpgradeService {
// long running tasks: pop up a progress dialog // long running tasks: pop up a progress dialog
final ProgressDialog dialog; final ProgressDialog dialog;
int maxWithUpgrade = V4_4_2; // The last version that required a migration int maxWithUpgrade = V4_5_1; // The last version that required a migration
final String lastSetVersionName = AstridPreferences.getCurrentVersionName(); final String lastSetVersionName = AstridPreferences.getCurrentVersionName();
@ -228,6 +230,9 @@ public final class UpgradeService {
if (from < V4_4_2) if (from < V4_4_2)
new SubtasksMetadataMigration().performMigration(); new SubtasksMetadataMigration().performMigration();
if (from < V4_5_1)
new GCMIntentService.GCMMigration().performMigration(UpgradeActivity.this);
} finally { } finally {
finished = true; finished = true;
DialogUtilities.dismissDialog(UpgradeActivity.this, dialog); DialogUtilities.dismissDialog(UpgradeActivity.this, dialog);

Loading…
Cancel
Save