<commit_before>package org.mozilla.mozstumbler;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.content.BroadcastReceiver;

class Reporter extends BroadcastReceiver {
    private static final String LOGTAG          = Reporter.class.getName();
    private static final String LOCATION_URL    = "https://location.services.mozilla.com/v1/submit";
    private static final String NICKNAME_HEADER = "X-Nickname";
    private static final String USER_AGENT_HEADER = "User-Agent";
    private static final int RECORD_BATCH_SIZE  = 100;
    private static final int REPORTER_WINDOW  = 3000; //ms

    private static String       MOZSTUMBLER_USER_AGENT_STRING;

    private final Context       mContext;
    private final Prefs         mPrefs;
    private JSONArray           mReports;
    private volatile long       mLastUploadTime;  //TODO why volatile

    private String mWifiData;
    private long   mWifiDataTime;

    private String mCellData;
    private long   mCellDataTime;

    private long   mGPSDataTime;
    private String mGPSData;

    private String mRadioType;
        
    Reporter(Context context, Prefs prefs) {
        mContext = context;
        mPrefs = prefs;

        MOZSTUMBLER_USER_AGENT_STRING = NetworkUtils.getUserAgentString(mContext);

        String storedReports = mPrefs.getReports();
        try {
            mReports = new JSONArray(storedReports);
        } catch (Exception e) {
            mReports = new JSONArray();
        }

        resetData();
        mContext.registerReceiver(this, new IntentFilter(ScannerService.MESSAGE_TOPIC));
    }

    private void resetData() {
        mWifiData = "";
        mCellData = "";
        mRadioType = "";
        mGPSData = "";
        mWifiDataTime = 0;
        mCellDataTime = 0;
        mGPSDataTime = 0;
    }

    void shutdown() {
        Log.d(LOGTAG, "shutdown");

        resetData();
        // Attempt to write out mReports
        mPrefs.setReports(mReports.toString());
        mContext.unregisterReceiver(this);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        
        if (!action.equals(ScannerService.MESSAGE_TOPIC)) {
            Log.e(LOGTAG, "Received an unknown intent");
            return;
        }

        long time = intent.getLongExtra("time", 0);
        String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
        String data = intent.getStringExtra("data");
        if (data!=null) Log.d(LOGTAG, "" + subject + " : " + data);

        if (mWifiDataTime - time > REPORTER_WINDOW) {
          mWifiData = "";
          mWifiDataTime = 0;
        }

        if (mCellDataTime - time > REPORTER_WINDOW) {
          mCellData = "";
          mCellDataTime = 0;
        }

        if (mGPSDataTime - time > REPORTER_WINDOW) {
          mGPSData = "";
          mGPSDataTime = 0;
        }

        if (subject.equals("WifiScanner")) {
            mWifiData = data;
            mWifiDataTime = time;
        } else if (subject.equals("CellScanner")) {
            mCellData = data;
            mRadioType = intent.getStringExtra("radioType");
            mCellDataTime = time;
        } else if (subject.equals("GPSScanner")) {
            mGPSData = data;
            mGPSDataTime = time;
        }
        else {
            Log.d(LOGTAG, "Intent ignored with Subject: " + subject);
            return; // Intent not aimed at the Reporter (it is possibly for UI instead)
        }

        // Record recent Wi-Fi and/or cell scan results for the current GPS position.
        Log.d(LOGTAG, "Reporter data: GPS: "+mGPSData.length()+", WiFi: "+mWifiData.length()+", Cell: "+mCellData.length()+" ("+mRadioType+")");
        if (mGPSData.length() > 0 && (mWifiData.length() > 0 || mCellData.length() > 0)) {
          reportLocation(mGPSData, mWifiData, mRadioType, mCellData);
          resetData();
        }
    }

    void sendReports(boolean force) {
        Log.d(LOGTAG, "sendReports: " + force);
        int count = mReports.length();
        if (count == 0) {
            Log.d(LOGTAG, "no reports to send");
            return;
        }

        if (count < RECORD_BATCH_SIZE && !force) {
            Log.d(LOGTAG, "batch count not reached, and !force");
            return;
        }

        if (!NetworkUtils.isNetworkAvailable(mContext)) {
            Log.d(LOGTAG, "Can't send reports without network connection");
            return;
        }

        JSONArray reports = mReports;
        mReports = new JSONArray();
<commit_msg>Upload the first measurement we take so we can show results right away<commit_after>package org.mozilla.mozstumbler;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.content.BroadcastReceiver;

class Reporter extends BroadcastReceiver {
    private static final String LOGTAG          = Reporter.class.getName();
    private static final String LOCATION_URL    = "https://location.services.mozilla.com/v1/submit";
    private static final String NICKNAME_HEADER = "X-Nickname";
    private static final String USER_AGENT_HEADER = "User-Agent";
    private static final int RECORD_BATCH_SIZE  = 100;
    private static final int REPORTER_WINDOW  = 3000; //ms

    private static String       MOZSTUMBLER_USER_AGENT_STRING;

    private final Context       mContext;
    private final Prefs         mPrefs;
    private JSONArray           mReports;
    private volatile long       mLastUploadTime;  //TODO why volatile

    private String mWifiData;
    private long   mWifiDataTime;

    private String mCellData;
    private long   mCellDataTime;

    private long   mGPSDataTime;
    private String mGPSData;

    private String mRadioType;
        
    Reporter(Context context, Prefs prefs) {
        mContext = context;
        mPrefs = prefs;

        MOZSTUMBLER_USER_AGENT_STRING = NetworkUtils.getUserAgentString(mContext);

        String storedReports = mPrefs.getReports();
        try {
            mReports = new JSONArray(storedReports);
        } catch (Exception e) {
            mReports = new JSONArray();
        }

        resetData();
        mContext.registerReceiver(this, new IntentFilter(ScannerService.MESSAGE_TOPIC));
    }

    private void resetData() {
        mWifiData = "";
        mCellData = "";
        mRadioType = "";
        mGPSData = "";
        mWifiDataTime = 0;
        mCellDataTime = 0;
        mGPSDataTime = 0;
    }

    void shutdown() {
        Log.d(LOGTAG, "shutdown");

        resetData();
        // Attempt to write out mReports
        mPrefs.setReports(mReports.toString());
        mContext.unregisterReceiver(this);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        
        if (!action.equals(ScannerService.MESSAGE_TOPIC)) {
            Log.e(LOGTAG, "Received an unknown intent");
            return;
        }

        long time = intent.getLongExtra("time", 0);
        String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
        String data = intent.getStringExtra("data");
        if (data!=null) Log.d(LOGTAG, "" + subject + " : " + data);

        if (mWifiDataTime - time > REPORTER_WINDOW) {
          mWifiData = "";
          mWifiDataTime = 0;
        }

        if (mCellDataTime - time > REPORTER_WINDOW) {
          mCellData = "";
          mCellDataTime = 0;
        }

        if (mGPSDataTime - time > REPORTER_WINDOW) {
          mGPSData = "";
          mGPSDataTime = 0;
        }

        if (subject.equals("WifiScanner")) {
            mWifiData = data;
            mWifiDataTime = time;
        } else if (subject.equals("CellScanner")) {
            mCellData = data;
            mRadioType = intent.getStringExtra("radioType");
            mCellDataTime = time;
        } else if (subject.equals("GPSScanner")) {
            mGPSData = data;
            mGPSDataTime = time;
        }
        else {
            Log.d(LOGTAG, "Intent ignored with Subject: " + subject);
            return; // Intent not aimed at the Reporter (it is possibly for UI instead)
        }

        // Record recent Wi-Fi and/or cell scan results for the current GPS position.
        Log.d(LOGTAG, "Reporter data: GPS: "+mGPSData.length()+", WiFi: "+mWifiData.length()+", Cell: "+mCellData.length()+" ("+mRadioType+")");
        if (mGPSData.length() > 0 && (mWifiData.length() > 0 || mCellData.length() > 0)) {
          reportLocation(mGPSData, mWifiData, mRadioType, mCellData);
          resetData();
        }
    }

    void sendReports(boolean force) {
        Log.d(LOGTAG, "sendReports: force=" + force);

        int count = mReports.length();
        if (count == 0) {
            Log.d(LOGTAG, "no reports to send");
            return;
        }

        if (count < RECORD_BATCH_SIZE && !force && mLastUploadTime > 0) {
            Log.d(LOGTAG, "batch count not reached, and !force");
            return;
        }

        if (!NetworkUtils.isNetworkAvailable(mContext)) {
            Log.d(LOGTAG, "Can't send reports without network connection");
            return;
        }

        JSONArray reports = mReports;
        mReports = new JSONArray();

{'fraction_non_alphanumeric': 0.1023802410118514, 'fraction_numerical': 0.003884075291305647, 'mean_word_length': 2.30982201713909, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 16, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1874677', 'n_tokens_mistral': 3025, 'n_tokens_neox': 2930, 'n_words': 707}