Fixes error loading bootstrap data and adds signing configs and setting up shrinking of app to reduce app size.

This commit is contained in:
Brian Mwadime 2016-06-27 12:49:33 +03:00
Родитель 70b07b4d51
Коммит 775634770a
10 изменённых файлов: 85 добавлений и 99 удалений

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

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="jisort" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="jisort" external.system.module.version="1" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
@ -65,14 +65,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
@ -81,6 +73,14 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
@ -105,12 +105,18 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.firebase/firebase-core/9.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.firebase/firebase-iid/9.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
@ -120,27 +126,30 @@
</content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-v4-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="firebase-iid-9.0.0" level="project" />
<orderEntry type="library" exported="" name="design-23.4.0" level="project" />
<orderEntry type="library" exported="" name="basic-http-client-android-0.88" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="play-services-analytics-impl-9.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-analytics-9.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-basement-9.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-tasks-9.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-base-9.0.0" level="project" />
<orderEntry type="library" exported="" name="cardview-v7-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="support-annotations-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="firebase-analytics-impl-9.0.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
<orderEntry type="library" exported="" name="support-vector-drawable-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-23.4.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" />
<orderEntry type="library" exported="" name="android-simple-tooltip-0.1.1" level="project" />
<orderEntry type="library" exported="" name="otto-1.3.8" level="project" />
<orderEntry type="library" exported="" name="firebase-common-9.0.0" level="project" />
<orderEntry type="library" exported="" name="firebase-core-9.0.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="design-23.4.0" level="project" />
<orderEntry type="library" exported="" name="guava-18.0" level="project" />
<orderEntry type="library" exported="" name="play-services-analytics-impl-9.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-analytics-9.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-basement-9.0.0" level="project" />
<orderEntry type="library" exported="" name="gson-2.3" level="project" />
<orderEntry type="library" exported="" name="play-services-tasks-9.0.0" level="project" />
<orderEntry type="library" exported="" name="cardview-v7-24.0.0-alpha2" level="project" />
<orderEntry type="library" exported="" name="firebase-analytics-impl-9.0.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" />
<orderEntry type="library" exported="" name="android-simple-tooltip-0.1.1" level="project" />
<orderEntry type="library" exported="" name="firebase-analytics-9.0.0" level="project" />
</component>
</module>

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

@ -19,7 +19,7 @@ android {
signingConfigs {
debug {
storeFile file("../android/debug.keystore")
storeFile file("~/.android/debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
@ -36,13 +36,15 @@ android {
buildTypes {
debug {
debuggable true
minifyEnabled false
minifyEnabled true
shrinkResources true
signingConfig signingConfigs.debug
buildConfigField("boolean", "ENABLE_DEBUG_TOOLS", "true")
}
qualityassurance {
debuggable true
minifyEnabled true
shrinkResources true
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), file('proguard-project.txt')
buildConfigField("boolean", "ENABLE_DEBUG_TOOLS", "true")
@ -50,6 +52,7 @@ android {
release {
debuggable false
minifyEnabled true
shrinkResources true
// No signing config as we do this separately.
proguardFiles getDefaultProguardFile('proguard-android.txt'), file('proguard-project.txt')
}

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

@ -52,20 +52,20 @@ public class IconsFragment extends Fragment {
private List<Topic> getTopics() {
List<Topic> list = new ArrayList<Topic>();
list.add(get("wifi", R.drawable.ic_wifi_tethering_black_48dp));
list.add(get("phone", R.drawable.ic_phone_black_48dp));
list.add(get("app", R.drawable.ic_get_app_black_48dp));
list.add(get("account", R.drawable.ic_account_box_black_48dp));
list.add(get("calendar", R.drawable.ic_perm_contact_calendar_black_48dp));
list.add(get("alarm", R.drawable.ic_alarm_black_48dp));
list.add(get("settings", R.drawable.ic_settings_applications_black_48dp));
list.add(get("search", R.drawable.ic_search_black_48dp));
list.add(get("wifi", "wifi", R.drawable.ic_wifi_tethering_black_48dp));
list.add(get("phone", "phone", R.drawable.ic_phone_black_48dp));
list.add(get("app","app", R.drawable.ic_get_app_black_48dp));
list.add(get("account", "account", R.drawable.ic_account_box_black_48dp));
list.add(get("calendar", "calendar", R.drawable.ic_perm_contact_calendar_black_48dp));
list.add(get("alarm", "alarm", R.drawable.ic_alarm_black_48dp));
list.add(get("settings", "settings", R.drawable.ic_settings_applications_black_48dp));
list.add(get("search", "search", R.drawable.ic_search_black_48dp));
return list;
}
private Topic get(String s, int i) {
return new Topic(s, i);
private Topic get(String t, String s, int i) {
return new Topic(t, s, i);
}

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

@ -12,6 +12,7 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.mozilla.hackathon.kiboko.models.Tutorial;
import com.mozilla.hackathon.kiboko.provider.DsoContract;
import com.mozilla.hackathon.kiboko.provider.DsoContract.Tutorials;
import com.mozilla.hackathon.kiboko.provider.DsoContractHelper;
import com.mozilla.hackathon.kiboko.provider.DsoDatabase;
import com.mozilla.hackathon.kiboko.utilities.TimeUtils;
@ -26,7 +27,7 @@ import static com.mozilla.hackathon.kiboko.utilities.LogUtils.LOGW;
import static com.mozilla.hackathon.kiboko.utilities.LogUtils.makeLogTag;
/**
* Created by Audrey on 25/06/2016.
* Created by Brian Mwadime on 25/06/2016.
*/
public class TutorialsHandler extends JSONHandler {
private static final String TAG = makeLogTag(TutorialsHandler.class);
@ -123,8 +124,8 @@ public class TutorialsHandler extends JSONHandler {
HashMap<String, String> hashcodeMap = new HashMap<String, String>();
if (cursor.moveToFirst()) {
do {
String tutorialId = cursor.getString(tutorialHashcodeQuery.Tutorial_ID);
String hashcode = cursor.getString(tutorialHashcodeQuery.Tutorial_IMPORT_HASHCODE);
String tutorialId = cursor.getString(tutorialHashcodeQuery.TUTORIAL_ID);
String hashcode = cursor.getString(tutorialHashcodeQuery.TUTORIAL_IMPORT_HASHCODE);
hashcodeMap.put(tutorialId, hashcode == null ? "" : hashcode);
} while (cursor.moveToNext());
}
@ -143,9 +144,9 @@ public class TutorialsHandler extends JSONHandler {
Tutorial tutorial, ArrayList<ContentProviderOperation> list) {
ContentProviderOperation.Builder builder;
Uri alltutorialsUri = DsoContractHelper
.setUriAsCalledFromSyncAdapter(DsoContract.Tutorials.CONTENT_URI);
.setUriAsCalledFromSyncAdapter(Tutorials.CONTENT_URI);
Uri thistutorialUri = DsoContractHelper
.setUriAsCalledFromSyncAdapter(DsoContract.Tutorials.buildtutorialUri(
.setUriAsCalledFromSyncAdapter(Tutorials.buildTutorialUri(
tutorial.id));
if (isInsert) {
@ -182,11 +183,11 @@ public class TutorialsHandler extends JSONHandler {
// }
builder.withValue(DsoContract.SyncColumns.UPDATED, System.currentTimeMillis())
.withValue(DsoContract.Tutorials.Tutorial_ID, tutorial.id)
.withValue(DsoContract.Tutorials.Tutorial_LEVEL, null) // Not available
.withValue(DsoContract.Tutorials.Tutorial_TITLE, tutorial.title)
.withValue(DsoContract.Tutorials.Tutorial_ABSTRACT, tutorial.description)
.withValue(DsoContract.Tutorials.Tutorial_HASHTAG, tutorial.hashtag)
.withValue(Tutorials.TUTORIAL_ID, tutorial.id)
.withValue(Tutorials.TUTORIAL_TAGS, null) // Not available
.withValue(Tutorials.TUTORIAL_HEADER, tutorial.header)
.withValue(Tutorials.TUTORIAL_STEPS, tutorial.steps)
.withValue(Tutorials.TUTORIAL_TAGS, tutorial.tag)
// Note: we store this comma-separated list of tags IN ADDITION
// to storing the tags in proper relational format (in the tutorials_tags
@ -197,26 +198,8 @@ public class TutorialsHandler extends JSONHandler {
// with the tutorials_speakers relationship table) so that we can
// display it easily in lists without having to make an additional DB query
// (or another join) for each record.
.withValue(DsoContract.Tutorials.Tutorial_KEYWORDS, null) // Not available
.withValue(DsoContract.Tutorials.Tutorial_URL, tutorial.url)
.withValue(DsoContract.Tutorials.Tutorial_LIVESTREAM_ID,
tutorial.isLivestream ? tutorial.youtubeUrl : null)
.withValue(DsoContract.Tutorials.Tutorial_MODERATOR_URL, null) // Not available
.withValue(DsoContract.Tutorials.Tutorial_REQUIREMENTS, null) // Not available
.withValue(DsoContract.Tutorials.Tutorial_YOUTUBE_URL,
tutorial.isLivestream ? null : tutorial.youtubeUrl)
.withValue(DsoContract.Tutorials.Tutorial_PDF_URL, null) // Not available
.withValue(DsoContract.Tutorials.Tutorial_NOTES_URL, null) // Not available
.withValue(DsoContract.Tutorials.ROOM_ID, tutorial.room)
.withValue(DsoContract.Tutorials.Tutorial_GROUPING_ORDER, tutorial.groupingOrder)
.withValue(DsoContract.Tutorials.Tutorial_IMPORT_HASHCODE,
tutorial.getImportHashCode())
.withValue(DsoContract.Tutorials.Tutorial_MAIN_TAG, tutorial.mainTag)
.withValue(DsoContract.Tutorials.Tutorial_CAPTIONS_URL, tutorial.captionsUrl)
.withValue(DsoContract.Tutorials.Tutorial_PHOTO_URL, tutorial.photoUrl)
// Disabled since this isn't being used by this app.
// .withValue(DsoContract.Tutorials.Tutorial_RELATED_CONTENT, tutorial.relatedContent)
.withValue(DsoContract.Tutorials.Tutorial_COLOR, color);
.withValue(DsoContract.Tutorials.TUTORIAL_PHOTO_URL, tutorial.photoUrl);
list.add(builder.build());
}
@ -234,11 +217,11 @@ public class TutorialsHandler extends JSONHandler {
private interface tutorialHashcodeQuery {
String[] PROJECTION = {
BaseColumns._ID,
DsoContract.Tutorials.Tutorial_ID,
DsoContract.Tutorials.Tutorial_IMPORT_HASHCODE
Tutorials.TUTORIAL_ID,
Tutorials.TUTORIAL_IMPORT_HASHCODE
};
int _ID = 0;
int tutorial_ID = 1;
int tutorial_IMPORT_HASHCODE = 2;
int TUTORIAL_ID = 1;
int TUTORIAL_IMPORT_HASHCODE = 2;
};
}

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

@ -46,6 +46,8 @@ public final class DsoContract {
String TUTORIAL_PHOTO_URL = "tutorial_photo_url";
/** The Tutorials's steps. */
String TUTORIAL_STEPS = "tutorial_steps";
/** The hashcode of the data used to create this record. */
String TUTORIAL_IMPORT_HASHCODE = "tutorial_import_hashcode";
}

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

@ -1,6 +1,5 @@
package com.mozilla.hackathon.kiboko.provider;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
@ -8,17 +7,13 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
import com.google.common.collect.Tables;
import com.mozilla.hackathon.kiboko.Config;
import com.mozilla.hackathon.kiboko.settings.SettingsUtils;
import com.mozilla.hackathon.kiboko.provider.DsoContract.Tutorials;
import com.mozilla.hackathon.kiboko.provider.DsoDatabase.Tables;
import com.mozilla.hackathon.kiboko.utilities.SelectionBuilder;
import java.io.FileDescriptor;
@ -26,10 +21,7 @@ import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.mozilla.hackathon.kiboko.utilities.LogUtils.LOGD;
import static com.mozilla.hackathon.kiboko.utilities.LogUtils.LOGV;
import static com.mozilla.hackathon.kiboko.utilities.LogUtils.makeLogTag;
/**
@ -176,6 +168,8 @@ public class DsoProvider extends ContentProvider {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
DsoUriEnum matchingUriEnum = mUriMatcher.matchUri(uri);
final SelectionBuilder builder = buildSimpleSelection(uri);
int retVal = builder.where(selection, selectionArgs).update(db, values);
notifyChange(uri);
return retVal;
@ -206,10 +200,8 @@ public class DsoProvider extends ContentProvider {
* <p/>
* We only notify changes if the uri wasn't called by the sync adapter, to avoid issuing a large
* amount of notifications while doing a sync. The
* {@link com.google.samples.apps.iosched.sync.ConferenceDataHandler} notifies all top level
* conference paths once the conference data sync is done, and the
* {@link com.google.samples.apps.iosched.sync.userdata.AbstractUserDataSyncHelper} notifies all
* user data related paths once the user data sync is done.
* {@link com.mozilla.hackathon.kiboko.sync.DsoDataHandler} notifies all top level
* tutorials paths once the tutorial data sync is done.
*/
private void notifyChange(Uri uri) {
if (!DsoContractHelper.isUriCalledFromSyncAdapter(uri)) {
@ -259,7 +251,10 @@ public class DsoProvider extends ContentProvider {
case TUTORIALS_ID: {
final String tutorialId = DsoContract.Tutorials.getTutorialId(uri);
return builder.table(Tables.TUTORIALS)
.where(TUTORIALS.TUTORIAL_ID + "=?", tutorialId);
.where(Tutorials.TUTORIAL_ID + "=?", tutorialId);
}
default: {
throw new UnsupportedOperationException("Unknown uri for " + uri);
}
}
@ -278,16 +273,7 @@ public class DsoProvider extends ContentProvider {
}
switch (matchingUriEnum) {
case TUTORIALS: {
// We query sessions on the joined table of sessions with rooms and tags.
// Since there may be more than one tag per session, we GROUP BY session ID.
// The starred sessions ("my schedule") are associated with a user, so we
// use the current user to select them properly
return builder
.table(Tables.SESSIONS_JOIN_ROOMS_TAGS, getCurrentAccountName(uri, true))
.mapToTable(DsoContract.Tutorials._ID, Tables.TUTORIALS)
.mapToTable(DsoContract.Tutorials.TUTORIAL_ID, Tables.TUTORIALS)
.map(DsoContract.Tutorials.SESSION_IN_MY_SCHEDULE, "IFNULL(in_schedule, 0)")
.groupBy(Qualified.TUTORIALS_TUTORIAL_ID);
return builder.table(Tables.TUTORIALS);
}
default: {
throw new UnsupportedOperationException("Unknown uri: " + uri);

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

@ -22,8 +22,8 @@ import static com.mozilla.hackathon.kiboko.utilities.LogUtils.LOGW;
/**
* An {@code IntentService} that performs the one-time data bootstrap. It takes the prepackaged
* conference data from the R.raw.bootstrap_data resource, and populates the database. This data
* contains the sessions, speakers, etc.
* mozilla dso data from the R.raw.bootstrap_data resource, and populates the database. This data
* contains the turtorials.
*/
public class DataBootstrapService extends IntentService {
@ -85,7 +85,7 @@ public class DataBootstrapService extends IntentService {
LOGE(TAG, "*** ERROR DURING BOOTSTRAP! Problem in bootstrap data?", ex);
LOGE(TAG,
"Applying fallback -- marking boostrap as done; sync might fix problem.");
SettingsUtils.markDataBootstrapDone(appContext);
// SettingsUtils.markDataBootstrapDone(appContext);
} finally {
// Request a manual sync immediately after the bootstrapping process, in case we
// have an active connection. Otherwise, the scheduled sync could take a while.

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

@ -121,7 +121,7 @@ public class SyncHelper {
* @return Whether or not data was changed.
* @throws IOException if there is a problem downloading or importing the data.
*/
private boolean doConferenceDataSync() throws IOException {
private boolean doDsoDataSync() throws IOException {
if (!isOnline()) {
LOGD(TAG, "Not attempting remote sync because device is OFFLINE");
return false;

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

@ -15,6 +15,9 @@ import com.mozilla.hackathon.kiboko.io.JSONHandler;
import com.mozilla.hackathon.kiboko.io.TutorialsHandler;
import com.mozilla.hackathon.kiboko.provider.DsoContract;
import com.mozilla.hackathon.kiboko.services.SyncHelper;
import com.turbomanage.httpclient.ConsoleRequestLogger;
import com.turbomanage.httpclient.HttpResponse;
import com.turbomanage.httpclient.RequestLogger;
import java.io.File;
import java.io.FileInputStream;

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

@ -43,12 +43,12 @@ staging_api_manifest_endpoint = http://storage.googleapis.com/io2015-data.appspo
production_api_manifest_endpoint = http://storage.googleapis.com/io2015-data.appspot.com/manifest_v1.json
# GCM server endpoints to checkin with.
staging_gcm_server_endpoint = https://io2015-data.appspot.com/gcm
production_gcm_server_endpoint = https://io2015-data.appspot.com/gcm
staging_gcm_server_endpoint = UNDEFINED
production_gcm_server_endpoint = UNDEFINED
# Website hostname
staging_website_host_name = googleio-staging.appspot.com
production_website_host_name = events.google.com
staging_website_host_name = UNDEFINED
production_website_host_name = UNDEFINED
#API key for GCM
## TODO: Supply GCM API key and sender ID for your project