mobisocial.metrics.UsageMetrics.java Source code

Java tutorial

Introduction

Here is the source code for mobisocial.metrics.UsageMetrics.java

Source

/*
 * Copyright 2012 The Stanford MobiSocial Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package mobisocial.metrics;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import mobisocial.musubi.App;
import mobisocial.musubi.ui.MusubiBaseActivity;
import mobisocial.socialkit.User;

import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

/**
 * Record user events, supporting anonymous and non-anonymous reporting.
 */
public class UsageMetrics {
    public static final String CHIRP_REPORTING_ENDPOINT = null;//"https://chirp.yourserver.com";
    public static final String CHIRP_VERSIONING_ENDPOINT = null;//"https://chirp.yoursever.com/version/latest.json";

    public enum ReportingLevel {
        ANONYMOUS, NON_ANONYMOUS, DISABLED
    };

    static ReportingThread mReportingThread;

    private final Context mContext;
    private final User mUser;
    private ReportingLevel mLevel = ReportingLevel.ANONYMOUS;

    /**
     * Creates a UserMetrics for tracking wholly anonymous statistics.
    */
    public UsageMetrics(Context context) {
        mContext = context.getApplicationContext();
        mUser = null;
        init();
    }

    public void setReportingLevel(ReportingLevel level) {
        mLevel = level;
    }

    /**
     * Creates a UserMetrics with stats linked against the given Musubi user.
    */
    public UsageMetrics(Context context, User user) {
        mContext = context.getApplicationContext();
        mUser = user;
        mLevel = ReportingLevel.NON_ANONYMOUS;
        init();
    }

    private void init() {
        if (mReportingThread == null) {
            mReportingThread = new ReportingThread();
            mReportingThread.start();
            synchronized (mReportingThread) {
                while (!mReportingThread.isStarted) {
                    try {
                        mReportingThread.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }

    private static UsageMetrics sUsageMetrics;

    public static UsageMetrics getUsageMetrics(Context c) {
        synchronized (UsageMetrics.class) {
            if (sUsageMetrics == null) {
                if (MusubiBaseActivity.isDeveloperModeEnabled(c)) {
                    sUsageMetrics = new UsageMetrics(c, App.getMusubi(c).userForLocalDevice(null));
                } else {
                    sUsageMetrics = new UsageMetrics(c);
                }
            }
            return sUsageMetrics;
        }
    }

    public void report(Throwable exception) {
        if (mLevel == ReportingLevel.DISABLED || UsageMetrics.CHIRP_REPORTING_ENDPOINT == null) {
            return;
        }
        Message msg = mReportingThread.mHandler.obtainMessage(ReportingHandler.HTTP_REQUEST);
        HttpPost post = new HttpPost(UsageMetrics.CHIRP_REPORTING_ENDPOINT);
        List<NameValuePair> data = new ArrayList<NameValuePair>();
        JSONObject json = MusubiExceptionHandler.jsonForException(mContext, exception, true);
        data.add(new BasicNameValuePair("json", json.toString()));
        try {
            post.setEntity(new UrlEncodedFormEntity(data, HTTP.UTF_8));
            msg.obj = post;
            mReportingThread.mHandler.sendMessage(msg);
        } catch (IOException e) {
        }
    }

    public void report(String feature) {
        if (mLevel == ReportingLevel.DISABLED || UsageMetrics.CHIRP_REPORTING_ENDPOINT == null) {
            return;
        }
        Message msg = mReportingThread.mHandler.obtainMessage(ReportingHandler.HTTP_REQUEST);
        HttpPost post = new HttpPost(UsageMetrics.CHIRP_REPORTING_ENDPOINT);
        List<NameValuePair> data = new ArrayList<NameValuePair>();
        JSONObject json = jsonForReport(feature);
        try {
            json.put("feature", feature);
        } catch (JSONException e) {
        }
        data.add(new BasicNameValuePair("json", json.toString()));
        try {
            post.setEntity(new UrlEncodedFormEntity(data, HTTP.UTF_8));
            msg.obj = post;
            mReportingThread.mHandler.sendMessage(msg);
        } catch (IOException e) {
        }
    }

    public void report(String feature, String value) {
        if (mLevel == ReportingLevel.DISABLED || UsageMetrics.CHIRP_REPORTING_ENDPOINT == null) {
            return;
        }
        Message msg = mReportingThread.mHandler.obtainMessage(ReportingHandler.HTTP_REQUEST);
        HttpPost post = new HttpPost(UsageMetrics.CHIRP_REPORTING_ENDPOINT);
        List<NameValuePair> data = new ArrayList<NameValuePair>();
        JSONObject json = jsonForReport(feature);
        try {
            json.put("feature", feature);
            json.put("value", value);
        } catch (JSONException e) {
        }
        data.add(new BasicNameValuePair("json", json.toString()));
        try {
            post.setEntity(new UrlEncodedFormEntity(data, HTTP.UTF_8));
            msg.obj = post;
            mReportingThread.mHandler.sendMessage(msg);
        } catch (IOException e) {
        }
    }

    private JSONObject jsonForReport(String feature) {
        JSONObject json = new JSONObject();
        try {
            json.put("type", "feature");
            json.put("timestamp", Long.toString(new Date().getTime()));
            json.put("feature", feature);
            if (mUser != null && mLevel == ReportingLevel.NON_ANONYMOUS) {
                json.put("user", mUser.getId());
            }
        } catch (JSONException e) {
        }
        return json;
    }

    class ReportingThread extends Thread {
        public Handler mHandler;
        public boolean isStarted = false;

        public void run() {
            Looper.prepare();
            mHandler = new ReportingHandler();
            isStarted = true;
            synchronized (this) {
                notify();
            }
            Looper.loop();
        }
    }

    class ReportingHandler extends Handler {
        static final int HTTP_REQUEST = 1;

        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case HTTP_REQUEST:
                HttpClient http = MusubiExceptionHandler.getHttpClient(mContext);
                HttpUriRequest request = (HttpUriRequest) msg.obj;
                try {
                    http.execute(request);
                } catch (IOException e) {
                }
                break;
            }
        }
    }
}