Skip to content

Commit

Permalink
Adding sample eligibility checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
mattspitz committed Dec 4, 2013
1 parent 19fd05a commit ceda810
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@
import android.os.Handler;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import co.nebulabs.phonehome.PhoneHomeConfig;
import co.nebulabs.phonehome.PhoneHomeLogger;

import com.example.phonehometest.example.ExampleEligibilityChecker;
import com.example.phonehometest.example.ExampleEligibilityChecker.EligibilityCallback;
import com.example.phonehometest.example.ExampleSink;
import com.example.phonehometest.example.Utils;
import com.example.phonehometest.example.Utils.AndroidInfo;

public class MainActivity extends Activity {
private static final PhoneHomeLogger Log = PhoneHomeLogger.forClass(MainActivity.class);
private ExampleEligibilityChecker eligibilityChecker;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


PhoneHomeConfig.getInstance()
// disable sending log flushing for now (toggled by the button in this activity)
.enabled(false)
Expand All @@ -33,22 +39,34 @@ protected void onCreate(Bundle savedInstanceState) {
// in production, only log INFO messages and above to logcat (everything is flushed to our sink)
.productionLogLevel(android.util.Log.INFO)
// the actual sink used when it's time to flush logs (required if you ever enable log flushing!)
.logSink(new ExampleSink());
.logSink(new ExampleSink(this));


eligibilityChecker = new ExampleEligibilityChecker(this);


AndroidInfo androidInfo = Utils.getAndroidInfo(this);
((TextView) findViewById(R.id.model)).setText("Model: " + androidInfo.model);
((TextView) findViewById(R.id.sdkVersion)).setText("SDK version: " + Integer.toString(androidInfo.sdkVersion));
((TextView) findViewById(R.id.appVersion)).setText("App version: " + Integer.toString(androidInfo.appVersion));


// queue up a handler to create logs
final Handler handler = new Handler();
handler.post(new Runnable() {
int counter = 0;
int debugCounter = 0;
int infoCounter = 0;

@Override
public void run() {
String text = "I've run " + ++counter + " times!";
((TextView) findViewById(R.id.counterText)).setText(text);

if (counter % 2 == 0)
Log.i(text);
Log.d(text);
debugCounter++;
Log.d("Debug event #" + debugCounter);

if (debugCounter % 2 == 0) {
infoCounter++;
Log.d("Info event #" + infoCounter);
}

((TextView) findViewById(R.id.counterText)).setText("Events: " + debugCounter + " debug, " + infoCounter + " info");

handler.postDelayed(this, 1000);
}
Expand All @@ -62,13 +80,23 @@ public boolean onCreateOptionsMenu(Menu menu) {
return true;
}

private boolean phoneHomeEnabled = false;
public void toggleFlushing(View view) {
phoneHomeEnabled = !phoneHomeEnabled;

PhoneHomeConfig.getInstance()
.enabled(phoneHomeEnabled);
public void checkEligibility(View view) {
eligibilityChecker.checkEligibility(
new EligibilityCallback() {
@Override
public void handleEligibilty(boolean isEligible) {
PhoneHomeConfig.getInstance()
.enabled(isEligible);

((Button) view).setText(phoneHomeEnabled ? "Disable" : "Enable");
String description;
if (isEligible) {
description = "Eligible to send logs! Make sure you're receiving them on the backend!";
} else {
description = "NOT eligible to receive logs. Are you sure that the android info above matches one of your logcat criteria?";
}

((TextView) findViewById(R.id.description)).setText(description);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.example.phonehometest.example;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

import android.content.Context;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;

public final class ExampleEligibilityChecker {
// matches with the example backend provided
private static final String HTTP_ENDPOINT = Utils.HTTP_BASE + "/eligibility";

private final Context context;
private final AndroidHttpClient httpClient = AndroidHttpClient.newInstance("PhoneHomeTest");

public ExampleEligibilityChecker(Context context) {
this.context = context;
}

public interface EligibilityCallback {
public void handleEligibilty(boolean isEligible);
}

public void checkEligibility(final EligibilityCallback eligibilityCallback) {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
HttpGet httpGet = new HttpGet(HTTP_ENDPOINT);
httpGet.setHeaders(Utils.getAndroidHeaders(context));

HttpResponse response;
try {
response = httpClient.execute(httpGet);
String json = EntityUtils.toString(response.getEntity(), "UTF-8");

JSONObject obj = new JSONObject(json);
return obj.getBoolean("is_eligible");

} catch (Exception ex) {
throw new RuntimeException(ex);
}
}

@Override
protected void onPostExecute(final Boolean isEligible) {
eligibilityCallback.handleEligibilty(isEligible);
}
}.execute();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.example.phonehometest;
package com.example.phonehometest.example;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.client.methods.HttpPost;
Expand All @@ -10,13 +8,22 @@
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import co.nebulabs.phonehome.PhoneHomeLogEvent;
import co.nebulabs.phonehome.PhoneHomeSink;

class ExampleSink implements PhoneHomeSink {
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("PhoneHomeTest");
public class ExampleSink implements PhoneHomeSink {
// matches with the example backend provided
private static final String HTTP_ENDPOINT = Utils.HTTP_BASE + "/logevents";

private final Context context;
private final AndroidHttpClient httpClient = AndroidHttpClient.newInstance("PhoneHomeTest");

public ExampleSink(Context context) {
this.context = context;
}

private String encodeLogEvents(final List<PhoneHomeLogEvent> logEvents) throws JSONException {
// JSON-encoded the hard way; you're better off using something nice like Jackson or Gson
Expand All @@ -40,27 +47,19 @@ public void flushLogs(final List<PhoneHomeLogEvent> logEvents) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
String postBody;
try {
postBody = encodeLogEvents(logEvents);
} catch (JSONException ex) {
throw new RuntimeException(ex);
}
String postBody = encodeLogEvents(logEvents);

StringEntity postEntity;
try {
postEntity = new StringEntity(postBody, "UTF-8");
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
postEntity.setContentType("application/json");
StringEntity postEntity = new StringEntity(postBody, "UTF-8");
postEntity.setContentType("application/json");

HttpPost httpPost = new HttpPost("http://example.com/api/logevents");
httpPost.setEntity(postEntity);
HttpPost httpPost = new HttpPost(HTTP_ENDPOINT);
httpPost.setEntity(postEntity);
httpPost.setHeaders(Utils.getAndroidHeaders(context));

try {
httpClient.execute(httpPost);
} catch (IOException ex) {

} catch (Exception ex) {
throw new RuntimeException(ex);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.example.phonehometest.example;

import org.apache.http.Header;
import org.apache.http.message.BasicHeader;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;

public final class Utils {
// this points at localhost on whatever machine the meulator's running on; obviously change this to suit your needs
static final String HTTP_BASE = "http://10.0.2.2";

private Utils() {}

public static class AndroidInfo {
public final String model;
public final int sdkVersion;
public final int appVersion;

private AndroidInfo(final String model, final int sdkVersion, final int appVersion) {
this.model = model;
this.sdkVersion = sdkVersion;
this.appVersion = appVersion;
}
}

public static AndroidInfo getAndroidInfo(Context context) {
int versionCode = -1;
try {
PackageManager manager = context.getPackageManager();
// FIXME point this at your own package!
PackageInfo info = manager.getPackageInfo("com.example.phonehometest", 0);
versionCode = info.versionCode;
} catch (NameNotFoundException nnf) {
throw new RuntimeException("Couldn't get package versionCode!", nnf);
}

return new AndroidInfo(Build.MODEL, Build.VERSION.SDK_INT, versionCode);
}

static Header[] getAndroidHeaders(Context context) {
// see backend example for how these are used to associate log events with users
AndroidInfo androidInfo = getAndroidInfo(context);
return new Header[] {
new BasicHeader("X-Android-Model", androidInfo.model),
new BasicHeader("X-Android-Sdk", Integer.toString(androidInfo.sdkVersion)),
new BasicHeader("X-Android-AppVersion", Integer.toString(androidInfo.appVersion))
};
}
}

0 comments on commit ceda810

Please sign in to comment.