package com.samknows.ui2.activity;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import org.json.JSONException;
import org.json.JSONObject;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Pair;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.samknows.libcore.SKPorting;
import com.samknows.libcore.R;
import com.samknows.libcore.SKTypeface;
import com.samknows.measurement.CachingStorage;
import com.samknows.measurement.MainService;
import com.samknows.measurement.TestRunner.ManualTestRunner;
import com.samknows.measurement.SK2AppSettings;
import com.samknows.measurement.SKApplication;
import com.samknows.measurement.SKApplication.eNetworkTypeResults;
import com.samknows.measurement.TestRunner.SKTestRunner;
import com.samknows.measurement.environment.NetworkDataCollector;
import com.samknows.measurement.environment.QueryWlanCarrier;
import com.samknows.measurement.schedule.ScheduleConfig;
import com.samknows.measurement.schedule.TestDescription.*;
import com.samknows.measurement.storage.StorageTestResult;
import com.samknows.measurement.storage.StorageTestResult.*;
import com.samknows.tests.HttpTest;
/**
* This fragment is responsible for running the tests and managing the home screen.
* <p/>
* All rights reserved SamKnows
*
* @author pablo@samknows.com
*/
public class FragmentRunTest extends Fragment {
static final String TAG = FragmentRunTest.class.getSimpleName();
// *** CONSTANTS *** //
private final static String C_TAG_FRAGMENT_SPEED_TEST = "Fragment SpeedTest"; // Tag for this fragment
private final static int C_UPDATE_INTERVAL_IN_MS = 250; // Time threshold in milliseconds to refresh the UI data
// *** VARIABLES *** //
private int numberOfTestsToBePerformed; // Number of tests to be performed (minimum 1, maximum 3)
private int heightInPixels; // Height in pixels
private eNetworkTypeResults connectivityType = eNetworkTypeResults.eNetworkTypeResults_WiFi;
private int results_Layout_Position_Y; // Position in the Y axis of the results layout
private float testProgressDownload, testProgressUpload, // Variables to control the background progress bar
testProgressLatencyPacketLossJitter, progressPercent;
private float screenDensity; // Screen density. This allows us to calculate density points to pixels
private long lastTimeMillisCurrentSpeed = 0; // Last the the current speed was updated
private long lastTimeMillisProgressBar = 0; // Last time progress bar was updated
private long testTime;
private boolean testsRunning = false; // If true, the tests are been performed
// Whether a test was selected to perform or not
private boolean test_selected_download = true;
private boolean test_selected_upload = true;
private boolean test_selected_latency_and_packet_loss_and_jitter = true;
private boolean gaugeVisible = true; // Whether the gauge is visible or not
private boolean executingLatencyTest = false;
// UI elements
private RelativeLayout layout_layout_Shining_Labels;
private LinearLayout layout_ll_Speed_Test_Layout, layout_ll_Main_Progress_Bar;
private LinearLayout layout_ll_passive_metrics, layout_ll_results, layout_ll_passive_metrics_divider_sim_and_network_operators, layout_ll_passive_metrics_divider_signal, layout_ll_passive_metrics_divider_location;
private FrameLayout run_results_panel_frame_to_animate;
// Text views showing warnings
private TextView mUnitText;
private TextView mMeasurementText;
private TextView mOptionalWlanCarrierNameText;
private View initial_warning_text;
// Text views showing the test result labels
private TextView tv_Label_Loss, tv_Label_Jitter;
private TextView tv_TopTextNetworkType;
// Text views showing the test result information
private TextView tv_Result_Download, tv_Result_Upload, tv_Result_Latency, tv_Result_Packet_Loss, tv_Result_Jitter;
private TextView tv_DownloadUnits, tv_UploadUnits;
private TextView tv_Result_DateDay;
private TextView tv_Result_DateTime;
// Text views showing the passive metric headers
private TextView pm_tv_header_label_sim_and_network_operators, pm_tv_header_label_signal, pm_tv_header_label_device, pm_tv_header_label_location;
// Text views showing the passive metric labels
private TextView tv_label_sim_operator, tv_label_sim_operator_code, tv_label_network_operator, tv_label_network_operator_code, tv_label_roaming_status,
tv_label_cell_tower_ID, tv_label_cell_tower_area_location_code, tv_label_signal_strength, tv_label_bearer,
tv_label_manufacturer, tv_label_model, tv_label_OS, tv_label_OS_version, tv_label_phone_type, tv_label_latitude, tv_label_longitude,
tv_label_accuracy, tv_label_provider;
// Text views that show the passive metric results
private TextView tv_result_sim_operator, tv_result_sim_operator_code, tv_result_network_operator, tv_result_network_operator_code, tv_result_roaming_status,
tv_result_cell_tower_ID, tv_result_cell_tower_area_location_code, tv_result_signal_strength, tv_result_bearer,
tv_result_manufacturer, tv_result_model, tv_result_OS, tv_result_OS_version, tv_result_phone_type, tv_result_latitude, tv_result_longitude,
tv_result_accuracy, tv_result_provider;
// Text views showing another additional information
private TextView tv_Gauge_TextView_PsuedoButton;
private TextView tv_Advice_Message, tv_Status_Label_1, tv_Status_Label_2;
private ImageView iv_Result_NetworkType; // Image showing the network type icon (Mobile or WiFi)
private Typeface typeface_Din_Condensed_Cyrillic, typeface_Roboto_Light, typeface_Roboto_Thin; // Type faces to be used in this fragment UI
private Typeface typeface_Roboto_Bold;
private MenuItem menuItem_SelectTests = null;
private MenuItem menuItem_ShareResult = null;
// Other class objects
private RelativeLayout gaugeViewContainer;
private GaugeView gaugeView;
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
// Background tasks
private Thread threadRunningTests; // Thread that run the tests
private ManualTestRunner manualTest; // Object containing the ManualTestRunner class object
private ScheduleConfig config;
private TextView publicIp;
private TextView submissionId;
private TextView networkType;
private TextView target;
// *** FRAGMENT LIFECYCLE METHODS *** //
// Called to have the fragment instantiate its user interface view.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_run_container, container, false);
// Bind and initialise the resources
setUpResources(view);
//SKLogger.sAssert("Hello!", false);
//SKLogger.sAssert(false);
// Inflate the layout for this fragment
return view;
}
// Called immediately after onCreateView but before any saved state has been restored in to the view
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
// Called when the fragment is visible to the user and actively running
@Override
public void onResume() {
// Restore any previously saved data...
restoreWhichTestsToRun();
// Register back button handler...
registerBackButtonHandler();
// Register the broadcast receiver to listen for connectivity changes from the system
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Context context = SKApplication.getAppInstance().getApplicationContext();
context.registerReceiver(broadcastReceiverConnectivityChanges, mIntentFilter);
// Start the periodic timer!
startTimer();
// Add the listener to the telephonyManager to listen for changes in the data connectivity
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
}
super.onResume();
View view = getView();
SKTypeface.sChangeChildrenToDefaultFontTypeface(view);
// Other labels
SKTypeface.sSetTypefaceForTextView(tv_TopTextNetworkType, typeface_Roboto_Bold);
SKTypeface.sSetTypefaceForTextView(tv_Gauge_TextView_PsuedoButton, typeface_Din_Condensed_Cyrillic);
SKTypeface.sSetTypefaceForTextView(tv_Advice_Message, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(mUnitText, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(mMeasurementText, typeface_Roboto_Light);
// Initialise the type face of the shining labels
SKTypeface.sSetTypefaceForTextView(tv_Status_Label_1, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_Status_Label_2, typeface_Roboto_Light);
// Assign fonts
// Passive metrics headers
SKTypeface.sSetTypefaceForTextView(pm_tv_header_label_sim_and_network_operators, typeface_Roboto_Thin);
SKTypeface.sSetTypefaceForTextView(pm_tv_header_label_signal, typeface_Roboto_Thin);
SKTypeface.sSetTypefaceForTextView(pm_tv_header_label_device, typeface_Roboto_Thin);
SKTypeface.sSetTypefaceForTextView(pm_tv_header_label_location, typeface_Roboto_Thin);
// Passive metrics labels
SKTypeface.sSetTypefaceForTextView(tv_label_sim_operator, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_sim_operator_code, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_network_operator, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_network_operator_code, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_roaming_status, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_cell_tower_ID, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_cell_tower_area_location_code, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_signal_strength, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_bearer, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_manufacturer, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_model, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_OS, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_OS_version, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_phone_type, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_latitude, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_longitude, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_accuracy, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_label_provider, typeface_Roboto_Light);
// Passive metrics results
SKTypeface.sSetTypefaceForTextView(tv_result_sim_operator, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_sim_operator_code, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_network_operator, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_network_operator_code, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_roaming_status, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_cell_tower_ID, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_cell_tower_area_location_code, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_signal_strength, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_bearer, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_manufacturer, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_model, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_OS, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_OS_version, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_phone_type, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_latitude, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_longitude, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_accuracy, typeface_Roboto_Light);
SKTypeface.sSetTypefaceForTextView(tv_result_provider, typeface_Roboto_Light);
// // Test result fields
// tv_Result_Download, typeface_Din_Condensed_Cyrillic);
// tv_Result_Upload, typeface_Din_Condensed_Cyrillic);
// tv_Result_Latency, typeface_Din_Condensed_Cyrillic);
// tv_Result_Packet_Loss, typeface_Din_Condensed_Cyrillic);
// tv_Result_Jitter, typeface_Din_Condensed_Cyrillic);
//
// // Test result labels
// tv_Label_Loss, typeface_Roboto_Light);
// tv_Label_Jitter, typeface_Roboto_Light);
// tv_Label_Mbps_1, typeface_Roboto_Thin);
// tv_Label_Mbps_2, typeface_Roboto_Thin);
// tv_Result_Date, typeface_Roboto_Light);
}
// Called when the fragment is no longer resumed
@Override
public void onPause() {
super.onPause();
// Unregister the broadcast receiver listener. The listener listen for connectivity changes
Context context = SKApplication.getAppInstance().getApplicationContext();
context.unregisterReceiver(broadcastReceiverConnectivityChanges);
// Stop the periodic timer!
stopTimer();
//Remove the telephonyManager listener
if (telephonyManager != null) {
try {
telephonyManager.listen(null, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
} catch (NullPointerException e) {
SKPorting.sAssert(false);
}
}
}
/// *** BROADCASTER RECEIVERS **** ///
// Broadcast receiver listening for connectivity changes to make the application connectivity aware.
private final BroadcastReceiver broadcastReceiverConnectivityChanges = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// On connectivity changes the data cap message might be modified because this message is only shown on mobile connectivity (3G, Edge, HSPA...)
checkOutDataCap();
// Check out connectivity status
checkConnectivity(intent);
}
};
final Handler mHandler = new Handler();
Timer myTimer = null;
private void stopTimer() {
if (myTimer != null) {
myTimer.cancel();
myTimer = null;
}
}
static double lastPolledSpeedValueMbps = 0;
private final Random mRandom = new Random();
private void startTimer() {
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
// For each timer "tick", *IF* the tests are running, we must see if the
// measured speed has changed since last time... and if so, update the UI.
// Otherwise, do nothing!
if (testsRunning) {
mHandler.post(new Runnable() {
@Override
public void run() {
// Defend against "java.lang.IllegalStateException: Fragment FragmentRunTest{...} not attached to Activity"
// http://stackoverflow.com/questions/10919240/fragment-myfragment-not-attached-to-activity
if (isAdded() == false) {
SKPorting.sAssert(getClass(), false);
return;
}
if (getActivity() == null) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
return;
}
Pair<Double, String> value = com.samknows.tests.HttpTest.sGetLatestSpeedForExternalMonitorAsMbps();
//Log.d("MPCMPCMPC", "gotResult for timer, =" + value.first + " Mbps (" + value.second + ")");
double showValueMbps = value.first;
if (showValueMbps == lastPolledSpeedValueMbps) {
// When running the upload test, the value might not have changed since last time; this
// is because the (behind the scenes) write to the socket via OutputStream can *block* from
// time to time, especially on a very slow network connection.
// In this case, show a random variation, in order to keep the UI active and show the user
// that the app is still running properly.
if (mRandom.nextBoolean()) {
showValueMbps *= (1.00 + mRandom.nextDouble() * 0.02);
} else {
showValueMbps *= (1.00 - mRandom.nextDouble() * 0.02);
}
}
if (showValueMbps != lastPolledSpeedValueMbps) {
switch (value.second) {
case HttpTest.cReasonUploadEnd:
// Nothing to do...?!
break;
case HttpTest.cReasonResetUpload:
case HttpTest.cReasonResetDownload:
// Don't display the first "0" for the download/upload test reset...
String workingString = getString(R.string.result_working);
tv_Gauge_TextView_PsuedoButton.setText(workingString);
break;
default:
//String message = String.valueOf(value);
// Update the current result meter for download/upload
updateCurrentTestSpeedMbps(showValueMbps);
// Update the gauge colour indicator (in Megabytes)
gaugeView.setAngleByValue(showValueMbps);
break;
}
lastPolledSpeedValueMbps = value.first;
lastTimeMillisCurrentSpeed = System.currentTimeMillis(); // Register the time of the last UI update
}
}
});
}
}
}, 0, C_UPDATE_INTERVAL_IN_MS);
}
// *** INNER CLASSES *** //
/**
* Just when the button is clicked it checks if we have real internet connection before start the tests.
*/
private class InitTestAsyncTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPreExecute() {
changeFadingTextViewValue(tv_Gauge_TextView_PsuedoButton, getString(R.string.gauge_message_starting), 0); // Set the gauge main text to STARTING
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Void... params) {
return isInternetAvailable();
}
@Override
protected void onPostExecute(Boolean result) {
if (getActivity() == null) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
} else {
if (/*haha*/result) {
testsRunning = true; // Make it notice that tests are running
resetValueFields(); // Set the value fields to a initial state
if (menuItem_SelectTests != null) {
menuItem_SelectTests.setVisible(false);
}
changeFadingTextViewValue(tv_Gauge_TextView_PsuedoButton, getString(R.string.gauge_message_starting), 0); // Set the gauge main text to STARTING
changeAdviceMessageTo(getString(R.string.advice_message_running)); // Change the advice message to "Running tests"
fadeInProgressBar(); // Initiate the progress bar to let the user know the progress of the tests
launchTests(); // Launch tests
layout_ll_results.animate().setDuration(300).alpha(1.0f); // Make the results layout visible
setTestTime(); // Set the time of the current test
//setTestConnectivity(); // Set the connectivity of the current test
layout_ll_results.setClickable(false); // The results layout is not clickable from here
} else {
changeFadingTextViewValue(tv_Gauge_TextView_PsuedoButton, getString(R.string.gauge_message_start), 0); // Set the gauge main text to START
Context context = SKApplication.getAppInstance().getApplicationContext();
Toast.makeText(context, getString(R.string.no_internet_connection), Toast.LENGTH_LONG).show();
}
}
super.onPostExecute(result);
}
}
// *** CUSTOM METHODS *** //
/**
* Bind the resources of the layout with the elements in this class and set up them
*
* @param pView
*/
private void setUpResources(View pView) {
// Passive metrics fields
// Header labels
pm_tv_header_label_sim_and_network_operators = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_sim_and_network_operators);
pm_tv_header_label_signal = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_signal);
pm_tv_header_label_device = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_device);
pm_tv_header_label_location = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_location);
//Dividers
layout_ll_passive_metrics_divider_sim_and_network_operators = (LinearLayout) pView.findViewById(R.id.fragment_passive_metrics_divider_sim_and_network_operators);
layout_ll_passive_metrics_divider_signal = (LinearLayout) pView.findViewById(R.id.fragment_passive_metrics_divider_signal);
layout_ll_passive_metrics_divider_location = (LinearLayout) pView.findViewById(R.id.fragment_passive_metrics_divider_location);
// Labels
tv_label_sim_operator = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_sim_operator);
tv_label_sim_operator_code = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_sim_operator_code);
tv_label_network_operator = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_network_operator);
tv_label_network_operator_code = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_network_operator_code);
tv_label_roaming_status = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_roaming_status);
tv_label_cell_tower_ID = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_cell_tower_ID);
tv_label_cell_tower_area_location_code = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_cell_tower_area_location_code);
tv_label_signal_strength = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_signal_strength);
tv_label_bearer = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_bearer);
tv_label_manufacturer = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_manufacturer);
tv_label_model = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_model);
tv_label_OS = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_OS);
tv_label_OS_version = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_OS_version);
tv_label_phone_type = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_phone_type);
tv_label_latitude = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_latitude);
tv_label_longitude = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_longitude);
tv_label_accuracy = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_accuracy);
tv_label_provider = (TextView) pView.findViewById(R.id.fragment_passive_metrics_label_location_provider);
// Results
tv_result_sim_operator = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_sim_operator_name);
tv_result_sim_operator_code = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_sim_operator_code);
tv_result_network_operator = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_network_operator_name);
tv_result_network_operator_code = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_network_operator_code);
tv_result_roaming_status = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_roaming_status);
tv_result_cell_tower_ID = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_cell_tower_id);
tv_result_cell_tower_area_location_code = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_cell_tower_area_location_code);
tv_result_signal_strength = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_signal_strength);
tv_result_bearer = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_bearer);
tv_result_manufacturer = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_manufacturer);
tv_result_model = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_detail_model);
tv_result_OS = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_detail_OS);
tv_result_OS_version = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_OS_version);
tv_result_phone_type = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_phone_type);
tv_result_latitude = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_latitude);
tv_result_longitude = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_longitude);
tv_result_accuracy = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_accuracy);
tv_result_provider = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_location_provider);
publicIp = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_your_ip_value);
submissionId = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_reference_number_value);
networkType = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_network_type);
target = (TextView) pView.findViewById(R.id.fragment_passive_metrics_result_target);
SKPorting.sAssert(getClass(), publicIp != null);
SKPorting.sAssert(getClass(), submissionId != null);
SKPorting.sAssert(getClass(), networkType != null);
SKPorting.sAssert(getClass(), target != null);
publicIp.setText("");
submissionId.setText("");
networkType.setText("");
target.setText("");
// Identify and hide the passive metrics layout
layout_ll_passive_metrics = (LinearLayout) pView.findViewById(R.id.fragment_passive_metrics_ll);
layout_ll_passive_metrics.setVisibility(View.GONE);
layout_ll_passive_metrics.setAlpha(0.0f);
// Now - what items to show?
LinearLayout ip_and_reference_metrics = (LinearLayout) pView.findViewById(R.id.ip_and_reference_metrics);
LinearLayout fragment_passive_metrics_ll_divider_sim_and_network_operators = (LinearLayout) pView.findViewById(R.id.network_operator_metrics);
LinearLayout signal_metrics = (LinearLayout) pView.findViewById(R.id.signal_metrics);
LinearLayout device_metrics = (LinearLayout) pView.findViewById(R.id.device_metrics);
LinearLayout location_metrics = (LinearLayout) pView.findViewById(R.id.location_metrics);
if (SKApplication.getAppInstance().getPassiveMetricsJustDisplayPublicIpAndSubmissionId() == true) {
fragment_passive_metrics_ll_divider_sim_and_network_operators.setVisibility(View.GONE);
signal_metrics.setVisibility(View.GONE);
device_metrics.setVisibility(View.GONE);
location_metrics.setVisibility(View.GONE);
} else {
ip_and_reference_metrics.setVisibility(View.GONE);
}
// Get the screen density. This is use to transform from dips to pixels
Context context = SKApplication.getAppInstance().getApplicationContext();
screenDensity = context.getResources().getDisplayMetrics().density;
// Initialise the telephony manager
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Set up the listener for the mobile connectivity changes
phoneStateListener = new PhoneStateListener() {
public void onDataConnectionStateChanged(int state, int networkType) {
// We have changed protocols, for example we have gone from HSDPA to GPRS
// HSDPA is an example of a 3G connection, GPRS is an example of a 2G connection
checkConnectivityStatus();
}
public void onCellLocationChanged(CellLocation location) {
// We have changed to a different Tower/Cell
}
};
// Report that this fragment would like to participate in populating the options menu by receiving a call to onCreateOptionsMenu(Menu, MenuInflater) and related methods.
setHasOptionsMenu(true);
// Gauge view container
gaugeViewContainer = (RelativeLayout) pView.findViewById(R.id.fragment_speed_gauge_container);
// Gauge view
gaugeView = (GaugeView) pView.findViewById(R.id.fragment_speed_gauge_view);
// Experiment: force turn-off of any hardware acceleration, on a per-view basis:
//gaugeView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
//SKLogger.sAssert(getClass(), gaugeView.getLayerType() == View.LAYER_TYPE_SOFTWARE);
// Text view showing the measurement values
tv_Gauge_TextView_PsuedoButton = (TextView) pView.findViewById(R.id.fragment_speed_test_gauge_textview_pseudobutton);
tv_Gauge_TextView_PsuedoButton.setText(getString(R.string.gauge_message_start));
// Initialise and hide the results layout
layout_ll_results = (LinearLayout) pView.findViewById(R.id.fragment_speed_test_results_ll2);
layout_ll_results.setAlpha(0.0f);
run_results_panel_frame_to_animate = (FrameLayout) pView.findViewById(R.id.run_results_panel_frame_to_animate);
// Get the position of the header row when it's already drawn
run_results_panel_frame_to_animate.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (run_results_panel_frame_to_animate != null) {
results_Layout_Position_Y = run_results_panel_frame_to_animate.getTop();
ViewTreeObserver observer = run_results_panel_frame_to_animate.getViewTreeObserver();
if (observer != null) {
// http://stackoverflow.com/questions/15162821/why-does-removeongloballayoutlistener-throw-a-nosuchmethoderror
try {
if (Build.VERSION.SDK_INT >= 16) {
observer.removeOnGlobalLayoutListener(this);
}
} catch (NoSuchMethodError x) {
observer.removeGlobalOnLayoutListener(this);
}
}
}
}
});
if (SKApplication.getAppInstance().getRevealMetricsOnMainScreen()) {
// Set a listener to the results layout to move it to the top and show the passive metrics
layout_ll_results.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (gaugeVisible) {
// If the gauge elements are visible, hide them and show the passive metrics.
hideGaugeShowPassiveMetricsPanel();
} else {
// The gauge elements are invisible - show them and hide the passive metrics.
showGaugeHidePassiveMetricsPanel();
}
}
});
// Now: immediately disable clicking on the panel, until the first result has arrived (in onDidDetectTestCompleted() ...)
layout_ll_results.setClickable(false);
}
// Elements in the results layout
tv_Result_Download = (TextView) pView.findViewById(R.id.archiveResultsListItemDownload);
tv_DownloadUnits = (TextView) pView.findViewById(R.id.mbps_label_1);
tv_Result_Download.setText(R.string.slash);
tv_Result_Upload = (TextView) pView.findViewById(R.id.archiveResultsListItemUpload);
tv_UploadUnits = (TextView) pView.findViewById(R.id.mbps_label_2);
tv_Result_Upload.setText(R.string.slash);
tv_Result_Latency = (TextView) pView.findViewById(R.id.archiveResultsListItemLatency);
tv_Result_Latency.setText(R.string.slash);
tv_Result_Packet_Loss = (TextView) pView.findViewById(R.id.archiveResultsListItemPacketLoss);
tv_Result_Packet_Loss.setText(R.string.slash);
tv_Result_Jitter = (TextView) pView.findViewById(R.id.archiveResultsListItemJitter);
tv_Result_Jitter.setText(R.string.slash);
tv_Label_Loss = (TextView) pView.findViewById(R.id.loss_label);
tv_Label_Jitter = (TextView) pView.findViewById(R.id.jitter_label);
//tv_Label_Mbps_1 = (TextView)pView.findViewById(R.id.mbps_label_1);
//tv_Label_Mbps_2 = (TextView)pView.findViewById(R.id.mbps_label_2);
tv_Result_DateDay = (TextView) pView.findViewById(R.id.archiveResultsListItemDateDay);
tv_Result_DateTime = (TextView) pView.findViewById(R.id.archiveResultsListItemDateTime);
tv_TopTextNetworkType = (TextView) pView.findViewById(R.id.top_text_network_type_label);
tv_TopTextNetworkType.setText(""); // Clear this immediately, until we know what the network type is!
iv_Result_NetworkType = (ImageView) pView.findViewById(R.id.archiveResultsListItemNetworkType);
// Layouts that contains the shining labels
layout_layout_Shining_Labels = (RelativeLayout) pView.findViewById(R.id.status_label_layout_1);
// Label showing the closest server
mUnitText = (TextView) pView.findViewById(R.id.unit_text_label);
mUnitText.setTextColor(getResources().getColor(R.color.MainColourDialUnitText));
mUnitText.setText("");
mMeasurementText = (TextView) pView.findViewById(R.id.measurement_text_label);
mMeasurementText.setTextColor(getResources().getColor(R.color.MainColourDialUnitText));
mMeasurementText.setText("");
mOptionalWlanCarrierNameText = (TextView) pView.findViewById(R.id.optional_wlan_carrier_name_text);
mOptionalWlanCarrierNameText.setTextColor(getResources().getColor(R.color.MainColourDialUnitText));
mOptionalWlanCarrierNameText.setText("");
initial_warning_text = pView.findViewById(R.id.initial_warning_text);
// Text views in the shining labels
tv_Status_Label_1 = (TextView) pView.findViewById(R.id.status_label_1);
tv_Status_Label_2 = (TextView) pView.findViewById(R.id.status_label_2);
// Initialise the first text in the shining labels
tv_Status_Label_1.setText(getString(R.string.label_message_ready_to_run));
tv_Status_Label_2.setText(getString(R.string.label_message_ready_to_run));
// Starts the "shining animation" of the shining labels
startShiningLabelsAnimation();
// Label showing an information/advice text
tv_Advice_Message = (TextView) pView.findViewById(R.id.press_the_start_button_label);
// Initialise fonts
typeface_Din_Condensed_Cyrillic = SKTypeface.sGetTypefaceWithPathInAssets("fonts/roboto_condensed_regular.ttf");
typeface_Roboto_Light = SKTypeface.sGetTypefaceWithPathInAssets("fonts/roboto_light.ttf");
typeface_Roboto_Thin = SKTypeface.sGetTypefaceWithPathInAssets("fonts/roboto_thin.ttf");
typeface_Roboto_Bold = SKTypeface.sGetTypefaceWithPathInAssets("fonts/roboto_bold.ttf");
if (SKApplication.getAppInstance().hideJitter()) {
tv_Label_Jitter.setVisibility(View.GONE);
pView.findViewById(R.id.jitter_panel).setVisibility(View.GONE);
}
if (SKApplication.getAppInstance().hideLoss()) {
tv_Label_Loss.setVisibility(View.GONE);
pView.findViewById(R.id.loss_panel).setVisibility(View.GONE);
}
// Layout containing the main screen
layout_ll_Speed_Test_Layout = (LinearLayout) pView.findViewById(R.id.new_speed_test_layout);
// Set the message label about the current network
setNetworkTypeInformation();
// Get the layout height in pixels just after the layout is drawn
final ViewTreeObserver observer = layout_ll_Speed_Test_Layout.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
heightInPixels = layout_ll_Speed_Test_Layout.getHeight();
ViewTreeObserver observer = layout_ll_Speed_Test_Layout.getViewTreeObserver();
if (observer != null) {
// http://stackoverflow.com/questions/15162821/why-does-removeongloballayoutlistener-throw-a-nosuchmethoderror
try {
if (Build.VERSION.SDK_INT >= 16) {
observer.removeOnGlobalLayoutListener(this);
}
} catch (NoSuchMethodError x) {
observer.removeGlobalOnLayoutListener(this);
}
}
}
});
// Background layout showing a progress animation
layout_ll_Main_Progress_Bar = (LinearLayout) getActivity().findViewById(R.id.main_Fragment_Progress_Bar);
// Define the behaviour when the tests are started
tv_Gauge_TextView_PsuedoButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onStartButtonPressed();
}
});
config = CachingStorage.getInstance().loadScheduleConfig();
if (config == null) {
config = new ScheduleConfig();
}
}
private void handleTheMessage(JSONObject message_JSON) {
if (isAdded() == false) {
// This fragment is NOT attached to the activity.
// Don't do anything with the message, or we're likely to crash!
SKPorting.sAssert(getClass(), false);
return;
}
FormattedValues formattedValues = new FormattedValues();
int success, statusComplete;
int testNameAsInt = 0;
String value;
try {
String messageType = message_JSON.getString(StorageTestResult.JSON_TYPE_ID);
// Tests are on progress
if (messageType.equals("test")) {
statusComplete = message_JSON.getInt(StorageTestResult.JSON_STATUS_COMPLETE);
testNameAsInt = message_JSON.getInt(StorageTestResult.JSON_TESTNUMBER);
value = message_JSON.getString(StorageTestResult.JSON_HRRESULT);
if (statusComplete == 100) {
if (value.length() == 0) {
// MPC - we're not *really* complete...
// we're never complete until we have a result, whatever
// the progress report might claim!
statusComplete = 99;
}
}
boolean bFailed = false;
if (statusComplete == 100 && message_JSON.has(StorageTestResult.JSON_SUCCESS)) {
success = message_JSON.getInt(StorageTestResult.JSON_SUCCESS);
if (success == 0) {
bFailed = true;
value = getString(R.string.failed);
//value = getString(R.string.failed_0MBPS);
}
}
Pair<Float, String> valueUnits = null;
DETAIL_TEST_ID testId = DETAIL_TEST_ID.sGetTestIdForInt(testNameAsInt);
switch (testId) {
// Case download test
case DOWNLOAD_TEST_ID:
// Download test results are processed
updateProgressBar(statusComplete, 0);
changeLabelText(getString(R.string.label_message_download_test));
gaugeView.setKindOfTest(0);
changeUnitsInformationLabel(getString(R.string.units_Mbps), getString(R.string.download));
valueUnits = FormattedValues.getFormattedSpeedValue(value);
if (valueUnits.second.length() > 0) {
Log.d(getClass().getName(), "gotResult for Download test ... at the end of the test - TODO - do this at the start!");
tv_DownloadUnits.setText(valueUnits.second);
}
if (statusComplete == 100) {
// Clear the central button test, ready for the first value to come through from the next test.
//tv_Gauge_TextView_PsuedoButton.setText("");
String workingString = getString(R.string.result_working);
tv_Gauge_TextView_PsuedoButton.setText(workingString);
//updateCurrentTestSpeedMbps(0.0);
gaugeView.setAngleByValue(0.0);
if (bFailed == true) {
changeFadingTextViewValue(tv_Result_Download, getString(R.string.failed), 0);
} else if (valueUnits.first <= 0.01F) {
changeFadingTextViewValue(tv_Result_Download, getString(R.string.failed_0MBPS), 0);
} else {
changeFadingTextViewValue(tv_Result_Download, String.valueOf(FormattedValues.sGet3DigitsNumber(valueUnits.first)), 0);
}
}
break;
// Case upload test
case UPLOAD_TEST_ID:
// Upload test results are processed
updateProgressBar(statusComplete, 1);
changeLabelText(getString(R.string.label_message_upload_test));
gaugeView.setKindOfTest(1);
changeUnitsInformationLabel(getString(R.string.units_Mbps), getString(R.string.upload));
valueUnits = FormattedValues.getFormattedSpeedValue(value);
if (valueUnits.second.length() > 0) {
Log.d(getClass().getName(), "gotResult for Upload test ... at the end of the test - TODO - do this at the start!");
tv_UploadUnits.setText(valueUnits.second);
}
if (statusComplete == 100) {
// Clear the central button test, ready for the first value to come through from the next test.
tv_Gauge_TextView_PsuedoButton.setText("");
//tv_Gauge_TextView_PsuedoButton.setText(R.string.result_working);
//updateCurrentTestSpeedMbps(0.0);
gaugeView.setAngleByValue(0.0);
if (bFailed == true) {
changeFadingTextViewValue(tv_Result_Upload, getString(R.string.failed), 0);
} else if (valueUnits.first <= 0.01F) {
changeFadingTextViewValue(tv_Result_Upload, getString(R.string.failed_0MBPS), 0);
} else {
changeFadingTextViewValue(tv_Result_Upload, String.valueOf(FormattedValues.sGet3DigitsNumber(valueUnits.first)), 0);
}
}
break;
// Case latency test
case LATENCY_TEST_ID:
// Latency test results are processed
executingLatencyTest = true;
updateProgressBar(statusComplete, 2);
changeLabelText(getString(R.string.label_message_latency_loss_jitter_test));
gaugeView.setKindOfTest(2);
changeUnitsInformationLabel(getString(R.string.units_ms), getString(R.string.latency));
if (statusComplete == 100) {
Pair<String, String> theResult = FormattedValues.sGetFormattedLatencyValue(value);
// Clear the central button test, ready for the first value to come through from the next test.
tv_Gauge_TextView_PsuedoButton.setText("");
//updateCurrentLatencyValue("0");
gaugeView.setAngleByValue(0.0);
//changeFadingTextViewValue(tv_Result_Latency, theResult.first, 0);
if (bFailed == true) {
changeFadingTextViewValue(tv_Result_Upload, value, 0);
} else {
changeFadingTextViewValue(tv_Result_Latency, String.valueOf(theResult.first) + " " + theResult.second, 0);
}
executingLatencyTest = false;
}
break;
// Case packet loss test
case PACKETLOSS_TEST_ID:
// Loss test results are processed
if (statusComplete == 100) {
// Clear the central button test, ready for the first value to come through from the next test.
tv_Gauge_TextView_PsuedoButton.setText("");
if (bFailed == true) {
changeFadingTextViewValue(tv_Result_Upload, value, 0);
} else {
// Display as Integer % (rather than Float %)
Pair<Integer, String> theResult = FormattedValues.sGetFormattedPacketLossValue(value);
changeFadingTextViewValue(tv_Result_Packet_Loss, String.valueOf(theResult.first) + " " + theResult.second, 0);
}
}
break;
case JITTER_TEST_ID:
// Jitter test results are processed
if (statusComplete == 100) {
// Clear the central button test, ready for the first value to come through from the next test.
tv_Gauge_TextView_PsuedoButton.setText("");
if (bFailed == true) {
changeFadingTextViewValue(tv_Result_Upload, value, 0);
} else {
// Display as Integer % in the correct format
Pair<Integer, String> theResult = FormattedValues.sGetFormattedJitter(value);
changeFadingTextViewValue(tv_Result_Jitter, String.valueOf(theResult.first) + " " + theResult.second, 0);
}
}
}
}
// Passive metric data process
else if (messageType.equals("passivemetric")) {
String metricString = message_JSON.getString("metricString");
value = message_JSON.getString("value");
if (!metricString.equals("invisible")) {
switch (metricString) {
case "simoperatorname":
tv_result_sim_operator.setText(value);
break;
case "simoperatorcode":
tv_result_sim_operator_code.setText(value);
break;
case "networkoperatorname":
tv_result_network_operator.setText(value);
break;
case "networkoperatorcode":
tv_result_network_operator_code.setText(value);
break;
case "roamingstatus":
tv_result_roaming_status.setText(value);
break;
case "gsmcelltowerid":
tv_result_cell_tower_ID.setText(value);
break;
case "gsmlocationareacode":
tv_result_cell_tower_area_location_code.setText(value);
break;
case "gsmsignalstrength":
tv_result_signal_strength.setText(value);
break;
case "manufactor":
tv_result_manufacturer.setText(value);
break;
case "networktype":
tv_result_bearer.setText(value);
break;
case "model":
tv_result_model.setText(value);
break;
case "ostype":
tv_result_OS.setText(value);
break;
case "osversion":
tv_result_OS_version.setText(value);
break;
case "osversionandroid":
tv_result_OS_version.setText(value);
// TODO - WIFI_SSID and other new stuff!
// wifi_ssid
// municipality
// country_name
// android os version string
break;
case "phonetype":
tv_result_phone_type.setText(value);
break;
case "latitude":
tv_result_latitude.setText(value);
break;
case "longitude":
tv_result_longitude.setText(value);
break;
case "accuracy":
tv_result_accuracy.setText(value);
break;
case "locationprovider":
tv_result_provider.setText(value);
break;
case "public_ip":
if (publicIp != null) {
publicIp.setText(value);
}
break;
case "submission_id":
if (submissionId != null) {
submissionId.setText(value);
}
break;
case "activenetworktype":
if (value.equals("WiFi")) {
setTestConnectivity(eNetworkTypeResults.eNetworkTypeResults_WiFi);
//testResult.setNetworkType(eNetworkTypeResults.eNetworkTypeResults_WiFi);
} else if (value.equals("mobile")) {
setTestConnectivity(eNetworkTypeResults.eNetworkTypeResults_Mobile);
//testResult.setNetworkType(eNetworkTypeResults.eNetworkTypeResults_Mobile);
} else {
SKPorting.sAssert(getClass(), false);
}
break;
default:
//SKLogger.sAssert(getClass(), false);
break;
}
}
}
} catch (JSONException e) {
Log.e(C_TAG_FRAGMENT_SPEED_TEST, "There was an error within the handler. " + e.getMessage());
}
}
private void safeRunOnUiThread(Runnable runnable) {
if (getActivity() == null) {
SKPorting.sAssert(getClass(), false);
return;
}
getActivity().runOnUiThread(runnable);
}
/**
* Update the UI current speed indicator (in Megabytes)
*
* @param pCurrentSpeed
*/
private void updateCurrentTestSpeedMbps(final double pCurrentSpeed) {
final DecimalFormat df;
final double showSpeed = pCurrentSpeed;
// The following can be used for testing, to help verify that the values are displayed properly for different value ranges.
//final double showSpeed = pCurrentSpeed + 5.0;
//final double showSpeed = pCurrentSpeed + 100.0;
if (showSpeed < 10) {
df = new DecimalFormat("0.00");
} else {
df = new DecimalFormat("00.0");
}
if (getActivity() == null) {
SKPorting.sAssert(getClass(), false);
return;
}
safeRunOnUiThread(new Runnable() {
@Override
public void run() {
String value = String.valueOf(df.format(showSpeed));
//SKLogger.sAssert(value.equals("0") == false);
tv_Gauge_TextView_PsuedoButton.setText(value);
}
});
}
/**
* Update the UI current latency indicator (in milliseconds)
*
* @param pLatencyValueMilli
*/
private void updateCurrentLatencyValue(long pLatencyValueMilli) {
final double formattedValue = pLatencyValueMilli;
final DecimalFormat df = new DecimalFormat("#.##");
safeRunOnUiThread(new Runnable() {
@Override
public void run() {
tv_Gauge_TextView_PsuedoButton.setText(String.valueOf(df.format(formattedValue)));
}
});
}
/**
* Make the progress bar visible. It is made invisible when it reaches the top in the fadeOutProgressBar method
*/
private void fadeInProgressBar() {
layout_ll_Main_Progress_Bar.setAlpha(0.3f);
layout_ll_Main_Progress_Bar.setVisibility(View.VISIBLE);
}
/**
* Update the UI progress bar. The bar goes up while performing the tests
*
* @param pProgress
* @param pNumOfTest
*/
private void updateProgressBar(int pProgress, int pNumOfTest) {
// Update the UI data only few times a second or when the progress is 100%
if ((System.currentTimeMillis() - lastTimeMillisProgressBar > C_UPDATE_INTERVAL_IN_MS) || pProgress == 100) {
switch (pNumOfTest) {
// Case the update comes from download test
case 0:
testProgressDownload = pProgress;
break;
// Case the update comes from upload test
case 1:
testProgressUpload = pProgress;
break;
// Case the update comes from latency test
case 2:
testProgressLatencyPacketLossJitter = pProgress;
break;
// Default case
default:
break;
}
// Update the total progress
progressPercent = (testProgressDownload + testProgressUpload + testProgressLatencyPacketLossJitter) / numberOfTestsToBePerformed;
// Modify the progress layout height
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_ll_Main_Progress_Bar.getLayoutParams();
layoutParams.height = (int) (progressPercent * heightInPixels / 100);
layout_ll_Main_Progress_Bar.setLayoutParams(layoutParams);
lastTimeMillisProgressBar = System.currentTimeMillis(); // Register the time of the last UI update
}
}
/**
* Restore the progress bat to the initial state. It's called when the bar reaches the top and the tests are finished
*/
private void resetProgressBar() {
// Set the height of the progress layout to 0. This performs an animation because we have set the animations to true in this layout
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout_ll_Main_Progress_Bar.getLayoutParams();
layoutParams.height = 0;
layout_ll_Main_Progress_Bar.setLayoutParams(layoutParams);
testProgressDownload = 0;
testProgressUpload = 0;
testProgressLatencyPacketLossJitter = 0;
progressPercent = 0;
}
private boolean getNetworkTypeIsWiFi() {
Context context = SKApplication.getAppInstance().getApplicationContext();
String networkType = Connectivity.getConnectionType(context);
return networkType != null && networkType.equals(SKApplication.getAppInstance().getApplicationContext().getString(R.string.network_type_wifi));
}
private void queryForWlanCarrierIfAppSupportsIt() {
FragmentRunTest.this.mOptionalWlanCarrierNameText.setText("");
if (SKApplication.getAppInstance().getShouldDisplayWlanCarrierNameInRunTestScreen() == false) {
return;
}
// Query for WlanCarrier!
final QueryWlanCarrier queryWlanCarrier = new QueryWlanCarrier() {
public void doHandleGotWlanCarrier(String wlanCarrier) {
//Log.d("MPC", "Main thread got wlanCarrier=" + wlanCarrier);
final String theWlanCarrier = wlanCarrier;
mHandler.post(new Runnable() {
@Override
public void run() {
// Defend against "java.lang.IllegalStateException: Fragment FragmentRunTest{...} not attached to Activity"
// http://stackoverflow.com/questions/10919240/fragment-myfragment-not-attached-to-activity
if (isAdded() == false) {
SKPorting.sAssert(getClass(), false);
return;
}
if (getActivity() == null) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
return;
}
FragmentRunTest.this.mOptionalWlanCarrierNameText.setText(theWlanCarrier);
}
});
}
};
new Thread() {
@Override
public void run() {
queryWlanCarrier.doPerformQuery();
}
}.start();
}
/**
* Create the test and launches it
*/
public void launchTests() {
// AT THIS POINT - query for WLan!
queryForWlanCarrierIfAppSupportsIt();
createManualTest(); // Create the manual test object storing which tests will be performed
threadRunningTests = new Thread(manualTest); // Create the thread with the Manual Test Object (Runnable Object)
changeLabelText(getString(R.string.label_message_starting_tests));
threadRunningTests.start(); // Run the thread
}
/**
* Start the shining effect on the labels. We have 4 text views and we play with the alpha value of them
*/
private void startShiningLabelsAnimation() {
// Animation to make the label invisible
tv_Status_Label_2.animate().alpha(0.0f).setDuration(1500).setListener(new AnimatorListenerAdapter() {
// When the animation ends, we call another method to make this labels visible again
@Override
public void onAnimationEnd(Animator animation) {
fadeInLabelAnimation();
}
});
}
/**
* Makes the labels visible after making them invisible in the startShiningLabelsAnimation. This is called when the startShiningLabelsAnimation methods ends.
*/
private void fadeInLabelAnimation() {
tv_Status_Label_2.animate().alpha(1.0f).setDuration(1500).setListener(new AnimatorListenerAdapter() {
// When the animation ends, we call another method to make this labels invisible again
@Override
public void onAnimationEnd(Animator animation) {
startShiningLabelsAnimation();
}
});
}
/**
* Change the text in the labels with a subtle animation (cross fading)
*
* @param pLabelText
*/
private void changeLabelText(final String pLabelText) {
tv_Status_Label_1.setText(pLabelText);
tv_Status_Label_2.setText(pLabelText);
}
/**
* Change the text in the advice message with a transition animation
*
* @param pAdviceMessageRunning
*/
private void changeAdviceMessageTo(final String pAdviceMessageRunning) {
tv_Advice_Message.setText(pAdviceMessageRunning);
}
/**
* Restores all selected tests from storage.
*/
private void restoreWhichTestsToRun() {
if ((getActivity() == null) || (isAdded() == false)) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
return;
}
Context context = SKApplication.getAppInstance().getApplicationContext();
SharedPreferences prefs = context.getSharedPreferences(getString(R.string.sharedPreferencesIdentifier), Context.MODE_PRIVATE);
if (SKApplication.getAppInstance().allowUserToSelectTestToRun() == false) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("downloadTestState", true);
editor.putBoolean("uploadTestState", true);
editor.putBoolean("latencyAndLossTestState", true);
editor.commit();
// User is not allowed to specify which tests to run.
test_selected_download = true;
test_selected_upload = true;
test_selected_latency_and_packet_loss_and_jitter = true;
} else {
// Get the selected tests from shared preferences
test_selected_download = prefs.getBoolean("downloadTestState", false);
test_selected_upload = prefs.getBoolean("uploadTestState", false);
test_selected_latency_and_packet_loss_and_jitter = prefs.getBoolean("latencyAndLossTestState", false);
}
}
/**
* Checks if at least one test is selected. True if so, false if any test is selected
*
* @return true or false
*/
private boolean atLeastOneTestSelected() {
restoreWhichTestsToRun();
return test_selected_download || test_selected_upload || test_selected_latency_and_packet_loss_and_jitter;
}
/**
* Create the ManualTestRunner object depending on which tests are selected
*/
private void createManualTest() {
List<SCHEDULE_TEST_ID> testIDs;
StringBuilder errorDescription = new StringBuilder();
testIDs = findOutTestIDs();
if (getActivity() == null) {
SKPorting.sAssert(getClass(), false);
return;
}
SKTestRunner.SKTestRunnerObserver observer = new SKTestRunner.SKTestRunnerObserver() {
@Override
public void onTestProgress(JSONObject pm) {
FragmentRunTest.this.handleTheMessage(pm);
}
@Override
public void onTestResult(JSONObject pm) {
FragmentRunTest.this.handleTheMessage(pm);
}
@Override
public void onPassiveMetric(JSONObject o) {
FragmentRunTest.this.handleTheMessage(o);
}
@Override
public void OnChangedStateTo(SKTestRunner.TestRunnerState state) {
if (state == SKTestRunner.TestRunnerState.STOPPED) {
onDidDetectTestCompleted();
}
}
@Override
public void OnUDPFailedSkipTests() {
}
@Override
public void OnClosestTargetSelected(String closestTarget) {
// http://stackoverflow.com/questions/28672883/java-lang-illegalstateexception-fragment-not-attached-to-activity
if ((isAdded() == false) || (FragmentRunTest.this.getActivity() == null)) {
// Not attached to Activity!
SKPorting.sAssert(false);
return;
}
String hostUrl = closestTarget;
if (hostUrl.length() != 0) {
String nameOfTheServer = config.hosts.get(hostUrl);
if (nameOfTheServer == null) {
nameOfTheServer = hostUrl;
}
// Set the server name in the optional detailed pop-up results...
target.setText(nameOfTheServer);
changeFadingTextViewValue(mUnitText, nameOfTheServer, getResources().getColor(R.color.MainColourDialUnitText)); // Update the current result closest target
changeFadingTextViewValue(mMeasurementText, nameOfTheServer, getResources().getColor(R.color.MainColourDialUnitText)); // Update the current result closest target
if (SKApplication.getAppInstance().getDoesAppDisplayClosestTargetInfo()) {
// Show "Best Target - myserver" as the text.
changeAdviceMessageTo(getString(R.string.running_test_closest_target) + nameOfTheServer);
} else {
// Show "Running Test"
changeAdviceMessageTo(getString(R.string.running_test));
}
}
}
@Override
public void OnCurrentLatencyCalculated(long latencyMilli) {
if (testsRunning) {
// Update the UI data only few times a second
if (executingLatencyTest && System.currentTimeMillis() - lastTimeMillisCurrentSpeed > C_UPDATE_INTERVAL_IN_MS) {
updateCurrentLatencyValue(latencyMilli); // Update the current result meter for latency
gaugeView.setAngleByValue((double) latencyMilli); // Update the gauge colour indicator
lastTimeMillisCurrentSpeed = System.currentTimeMillis(); // Register the time of the last UI update
}
}
}
};
if (testIDs.contains(SCHEDULE_TEST_ID.ALL_TESTS) == false) {
// Perform the selected tests
manualTest = ManualTestRunner.create(observer, testIDs, errorDescription);
}
else {
// Perform all tests
manualTest = ManualTestRunner.create(observer, errorDescription);
if (manualTest == null) {
if (errorDescription.toString().contains(getString(R.string.manual_test_create_failed_3))) {
showAlertCannotRunTestAsBackgroundTaskIsRunning();
} else {
showAlertForTestWithMessageBody(getString(R.string.unexpected_error));
}
}
}
}
// Shown when the background test is already running, so we cannot run the manual
// test at the moment...
void showAlertCannotRunTestAsBackgroundTaskIsRunning() {
// The App is busy
showAlertForTestWithMessageBody(getString(R.string.manual_test_error)); // Unable to launch test, a background task is running. Please retry shortly.
}
void showAlertForTestWithMessageBody(String bodyMessage) {
if (getActivity() == null) {
SKPorting.sAssert(getClass(), false);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.tests_running_title); // The app is busy
builder.setMessage(bodyMessage)
.setCancelable(false)
.setPositiveButton(R.string.ok_dialog, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
builder.create().show();
}
/**
* Checks which tests are selected
*
* @return a list of tests
*/
private List<SCHEDULE_TEST_ID> findOutTestIDs() {
// Get the selected tests from shared preferences
restoreWhichTestsToRun();
List<SCHEDULE_TEST_ID> testIDs = new ArrayList<>();
// Create the list of tests to be performed
// All tests
if (test_selected_download && test_selected_upload && test_selected_latency_and_packet_loss_and_jitter) {
testIDs.add(SCHEDULE_TEST_ID.CLOSEST_TARGET_TEST);
testIDs.add(SCHEDULE_TEST_ID.ALL_TESTS);
numberOfTestsToBePerformed = 3;
return testIDs;
}
// Just Download test
if (test_selected_download && !test_selected_upload && !test_selected_latency_and_packet_loss_and_jitter) {
testIDs.add(SCHEDULE_TEST_ID.DOWNLOAD_TEST);
numberOfTestsToBePerformed = 1;
return testIDs;
}
// Just Upload test
if (!test_selected_download && test_selected_upload && !test_selected_latency_and_packet_loss_and_jitter) {
testIDs.add(SCHEDULE_TEST_ID.UPLOAD_TEST);
numberOfTestsToBePerformed = 1;
return testIDs;
}
// Just latency and loss
if (!test_selected_download && !test_selected_upload && test_selected_latency_and_packet_loss_and_jitter) {
testIDs.add(SCHEDULE_TEST_ID.LATENCY_TEST);
numberOfTestsToBePerformed = 1;
return testIDs;
}
// Download and upload
if (test_selected_download && test_selected_upload && !test_selected_latency_and_packet_loss_and_jitter) {
testIDs.add(SCHEDULE_TEST_ID.DOWNLOAD_TEST);
testIDs.add(SCHEDULE_TEST_ID.UPLOAD_TEST);
numberOfTestsToBePerformed = 2;
return testIDs;
}
// Download and latency and loss
if (test_selected_download && !test_selected_upload && test_selected_latency_and_packet_loss_and_jitter) {
testIDs.add(SCHEDULE_TEST_ID.DOWNLOAD_TEST);
testIDs.add(SCHEDULE_TEST_ID.LATENCY_TEST);
numberOfTestsToBePerformed = 2;
return testIDs;
}
// Upload and latency and loss
if (!test_selected_download && test_selected_upload && test_selected_latency_and_packet_loss_and_jitter) {
testIDs.add(SCHEDULE_TEST_ID.UPLOAD_TEST);
testIDs.add(SCHEDULE_TEST_ID.LATENCY_TEST);
numberOfTestsToBePerformed = 2;
return testIDs;
}
// Default case
testIDs.add(SCHEDULE_TEST_ID.ALL_TESTS);
numberOfTestsToBePerformed = 3;
return testIDs;
}
/**
* Checks if the data cap has been or might be exceeded
*/
private void checkOutDataCap() {
if ((getActivity() == null) || (isAdded() == false)) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
return;
}
// If the data cap is enabled
if (SKApplication.getAppInstance().getIsDataCapEnabled() == true) {
String warningMessage = "";
// If the data cap was already reached, set the message that was already exceeded
if (SK2AppSettings.getSK2AppSettingsInstance().isDataCapAlreadyReached()) {
warningMessage = getString(R.string.data_cap_warning_already_exceeded);
} else // If the data cap wasn't reached, check if could be reached in the next run
{
createManualTest();
if (manualTest != null && SK2AppSettings.getSK2AppSettingsInstance().isDataCapLikelyToBeReached(manualTest.getNetUsage())) {
warningMessage = getString(R.string.data_cap_warning_might_be_exceeded);
}
}
// If the data cap was already reached or could be reached in the next run, show a message warning the user
if (warningMessage.length() > 0) {
Context context = SKApplication.getAppInstance().getApplicationContext();
Toast.makeText(context, warningMessage, Toast.LENGTH_LONG).show();
} else // If the data cap wasn't reached and won't be reached in the next run, hide the warning (maybe is not showed anyway)
{
}
}
}
/**
* Set the time of the test in an specific format
*/
private void setTestTime() {
testTime = System.currentTimeMillis();
//SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
//String currentDateandTime = sdf.format(new Date());
// String currentDateandTimeDay = new FormattedValues().getDate(testTime, "dd/MM/yyyy");
// if (tv_Result_Jitter.getVisibility() != View.GONE) {
String currentDateandTimeDay = new FormattedValues().getDate(testTime, "dd/MM/yy");
// }
String currentDateandTimeTime = new FormattedValues().getDate(testTime, "HH:mm:ss");
//tv_Result_Date.setText(currentDateandTime);
tv_Result_DateDay.setText(currentDateandTimeDay); // Set the gauge main text to STARTING
tv_Result_DateTime.setText(currentDateandTimeTime); // Set the gauge main text to STARTING
}
/**
* Set the connectivity icon depending on the connectivity (which comes from the passive metrics!)
*/
private void setTestConnectivity(eNetworkTypeResults pNetworkType) {
//if (Connectivity.isConnectedWifi(getActivity()))
if (pNetworkType == eNetworkTypeResults.eNetworkTypeResults_WiFi) {
iv_Result_NetworkType.setImageResource(R.drawable.ic_swifi);
connectivityType = eNetworkTypeResults.eNetworkTypeResults_WiFi;
// Set the network type string in the optional detailed pop-up results...
networkType.setText(R.string.network_type_wifi);
} else {
iv_Result_NetworkType.setImageResource(R.drawable.ic_sgsm);
connectivityType = eNetworkTypeResults.eNetworkTypeResults_Mobile;
// Set the network type string in the optional detailed pop-up results...
networkType.setText(R.string.network_type_mobile);
}
}
/**
* Check connectivity status to show or hide the warning messages (no connectivity, slow connectivity)
*
* @param pIntent
*/
private void checkConnectivity(Intent pIntent) {
// Set the network type information to update the changes in the network
setNetworkTypeInformation();
final Context context = SKApplication.getAppInstance().getApplicationContext();
// Show connectivity warning if there's no connectivity
if (pIntent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) {
safeRunOnUiThread(new Runnable() {
@Override
public void run() {
if (testsRunning == false) {
Toast.makeText(context, getString(R.string.no_connectivity), Toast.LENGTH_LONG).show();
}
}
});
}
// Show slow connection warning if we are on slow connectivity
else if (!Connectivity.isConnectedFast(context)) {
safeRunOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, getString(R.string.slow_connectivity), Toast.LENGTH_LONG).show();
}
});
}
}
/**
* Check which is the current connectivity status: whether is connected or not, is fast or not.
*/
private void checkConnectivityStatus() {
// Set the network type information to update the changes in the network
setNetworkTypeInformation();
final Context context = SKApplication.getAppInstance().getApplicationContext();
if (Connectivity.sGetIsConnected(context) == false) {
// No connectivity!
safeRunOnUiThread(new Runnable() {
@Override
public void run() {
if (testsRunning == false) {
Toast.makeText(context, getString(R.string.no_connectivity), Toast.LENGTH_LONG).show();
}
}
});
} else if (Connectivity.isConnectedFast(context) == false) {
// Slow connectivity!
safeRunOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, getString(R.string.slow_connectivity), Toast.LENGTH_LONG).show();
}
});
} else {
// Good connectivity!
}
}
/**
* @return true if we have internet conection, false otherwise
*/
private boolean isInternetAvailable() {
try {
URL url = new URL("http://www.google.com/");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("User-Agent", "test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1000); // mTimeout is in seconds
urlc.connect();
if (urlc.getResponseCode() == 200) {
return true;
} else {
return false;
}
} catch (Exception e) {
Log.i("warning", "Error checking internet connection", e);
SKPorting.sAssert(false);
return false;
}
}
static private String sCurrentWifiSSID() {
return NetworkDataCollector.sCurrentWifiSSIDNullIfNotFound();
}
private String getWiFiStringForUIWithSSIDIfAvailable() {
String wifiString = SKApplication.getAppInstance().getApplicationContext().getString(R.string.network_type_wifi);
String currentSSID = sCurrentWifiSSID();
if (currentSSID != null && currentSSID.length() > 0) {
return wifiString + "\n(" + currentSSID + ")";
}
return wifiString;
}
/**
* Get the type of network and set it on the information label
*/
private void setNetworkTypeInformation() {
if (!testsRunning) {
final Context context = SKApplication.getAppInstance().getApplicationContext();
String networkType = Connectivity.getConnectionType(context);
if (networkType == null) {
// Unexpected, but defend against it.
networkType = SKApplication.getAppInstance().getApplicationContext().getString(R.string.unknown);
SKPorting.sAssert(getClass(), false);
}
if (networkType.equals(SKApplication.getAppInstance().getApplicationContext().getString(R.string.network_type_wifi))) {
networkType = getWiFiStringForUIWithSSIDIfAvailable();
}
tv_TopTextNetworkType.setText(networkType);
tv_TopTextNetworkType.setVisibility(gaugeVisible ? View.VISIBLE : View.INVISIBLE);
}
}
/**
* Set the contextual information label with an animation
*
* @param unitsLabel
* @param testLabel
*/
private void changeUnitsInformationLabel(final String unitsLabel, final String testLabel) {
if ((testsRunning == false) &&
(unitsLabel.length() > 0)
) {
// Do NOT update the unit text etc. to non-empty string, if the test isn't running!
} else {
mUnitText.setText(unitsLabel);
mMeasurementText.setText(testLabel);
}
}
/**
* Send message to the other fragments to refresh the UI data
*/
private void sendRefreshUIMessage() {
final Context context = SKApplication.getAppInstance().getApplicationContext();
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("refreshUIMessage"));
}
/**
* Set the result fields value with an animation
*
* @param pTextView
* @param pValue
*/
private void changeFadingTextViewValue(final TextView pTextView, final String pValue, final int pColor) {
if (!pTextView.getText().toString().equals(pValue)) {
pTextView.animate().setDuration(300).alpha(0.0f).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (pColor != 0) {
pTextView.setTextColor(pColor);
}
pTextView.setText(pValue);
pTextView.animate().setDuration(300).alpha(1.0f);
pTextView.animate().setListener(null); // Set animation listener to null to avoid side effects
}
});
}
}
/**
* Convert dips to pixels
*
* @param pDP
* @return
*/
private int dpToPx(int pDP) {
return Math.round((float) pDP * screenDensity);
}
/**
* Show or hide the visibility of the passive metrics related to mobile network
*
* @param pNetworkType
*/
private void setUpPassiveMetricsLayout(eNetworkTypeResults pNetworkType) {
int visibility;
/*
if (pNetworkType == eNetworkTypeResults.eNetworkTypeResults_WiFi) {
visibility = View.GONE;
} else {
visibility = View.VISIBLE;
}
// Header labels
pm_tv_header_label_sim_and_network_operators.setVisibility(visibility);
pm_tv_header_label_signal.setVisibility(visibility);
//Dividers
layout_ll_passive_metrics_divider_sim_and_network_operators.setVisibility(visibility);
layout_ll_passive_metrics_divider_signal.setVisibility(visibility);
// Labels
tv_label_sim_operator.setVisibility(visibility);
tv_label_sim_operator_code.setVisibility(visibility);
tv_label_network_operator.setVisibility(visibility);
tv_label_network_operator_code.setVisibility(visibility);
tv_label_roaming_status.setVisibility(visibility);
tv_label_cell_tower_ID.setVisibility(visibility);
tv_label_cell_tower_area_location_code.setVisibility(visibility);
tv_label_signal_strength.setVisibility(visibility);
tv_label_bearer.setVisibility(visibility);
// Results
tv_result_sim_operator.setVisibility(visibility);
tv_result_sim_operator_code.setVisibility(visibility);
tv_result_network_operator.setVisibility(visibility);
tv_result_network_operator_code.setVisibility(visibility);
tv_result_roaming_status.setVisibility(visibility);
tv_result_cell_tower_ID.setVisibility(visibility);
tv_result_cell_tower_area_location_code.setVisibility(visibility);
tv_result_signal_strength.setVisibility(visibility);
tv_result_bearer.setVisibility(visibility);
// If the location metrics are not available, just hide those labels
int visibilityOfLocation = tv_result_longitude.getText().equals("") ? View.GONE : View.VISIBLE;
pm_tv_header_label_location.setVisibility(visibilityOfLocation);
layout_ll_passive_metrics_divider_location.setVisibility(visibilityOfLocation);
tv_label_latitude.setVisibility(visibilityOfLocation);
tv_label_longitude.setVisibility(visibilityOfLocation);
tv_label_accuracy.setVisibility(visibilityOfLocation);
tv_label_provider.setVisibility(visibilityOfLocation);
tv_result_latitude.setVisibility(visibilityOfLocation);
tv_result_longitude.setVisibility(visibilityOfLocation);
tv_result_accuracy.setVisibility(visibilityOfLocation);
tv_result_provider.setVisibility(visibilityOfLocation);
*/
}
/**
* Set the value fields to a initial position
*/
private void resetValueFields() {
changeFadingTextViewValue(tv_Result_Download, getString(R.string.slash), 0);
changeFadingTextViewValue(tv_Result_Upload, getString(R.string.slash), 0);
changeFadingTextViewValue(tv_Result_Latency, getString(R.string.slash), 0);
changeFadingTextViewValue(tv_Result_Packet_Loss, getString(R.string.slash), 0);
changeFadingTextViewValue(tv_Result_Jitter, getString(R.string.slash), 0);
tv_Result_DateDay.setText(getString(R.string.slash));
tv_Result_DateTime.setText(getString(R.string.slash));
}
// *** MENUS *** //
// Initialise the contents of the Activity's standard options menu.
// You should place your menu items in to menu. For this method to be called, you must have first called setHasOptionsMenu(boolean).
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_fragment_run_test, menu);
menuItem_SelectTests = menu.findItem(R.id.menu_item_fragment_run_test_select_tests);
menuItem_ShareResult = menu.findItem(R.id.menu_item_fragment_run_test_share_result);
menuItem_ShareResult.setVisible((!gaugeVisible) && (connectivityType == eNetworkTypeResults.eNetworkTypeResults_Mobile));
if (SKApplication.getAppInstance().isSocialMediaExportSupported() == false) {
menuItem_ShareResult.setVisible(false);
}
if (menuItem_SelectTests != null) {
menuItem_SelectTests.setVisible(SKApplication.getAppInstance().allowUserToSelectTestToRun());
}
}
// This hook is called whenever an item in your options menu is selected.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.menu_item_fragment_run_test_select_tests) {
if (SKApplication.getAppInstance().allowUserToSelectTestToRun() == false) {
if (menuItem_SelectTests != null) {
menuItem_SelectTests.setVisible(SKApplication.getAppInstance().allowUserToSelectTestToRun());
}
SKPorting.sAssert(getClass(), false);
return true;
}
// Case select tests
Intent intent_select_tests = new Intent(getActivity(), ActivitySelectTests.class);
startActivity(intent_select_tests);
return true;
}
if (itemId == R.id.menu_item_fragment_run_test_share_result) {
if (connectivityType == eNetworkTypeResults.eNetworkTypeResults_WiFi) {
SKPorting.sAssert(getClass(), false);
if (menuItem_ShareResult != null) {
menuItem_ShareResult.setVisible((!gaugeVisible) && (connectivityType == eNetworkTypeResults.eNetworkTypeResults_Mobile));
}
} else {
FormattedValues formattedValues = new FormattedValues();
try {
Intent intent_share_result_activity = new Intent(getActivity(), ActivityShareResult.class);
intent_share_result_activity.putExtra("downloadResult", tv_Result_Download.getText() + " " + tv_DownloadUnits.getText());
intent_share_result_activity.putExtra("uploadResult", tv_Result_Upload.getText() + " " + tv_UploadUnits.getText());
intent_share_result_activity.putExtra("latencyResult", String.valueOf(FormattedValues.sGetFormattedLatencyValue(tv_Result_Latency.getText().toString()).first));
intent_share_result_activity.putExtra("packetLossResult", String.valueOf(FormattedValues.sGetFormattedPacketLossValue(tv_Result_Packet_Loss.getText().toString()).first));
intent_share_result_activity.putExtra("jitterResult", String.valueOf(FormattedValues.sGetFormattedJitter(tv_Result_Jitter.getText().toString()).first));
intent_share_result_activity.putExtra("networkType", 2); // 2 mobile
intent_share_result_activity.putExtra("dateResult", testTime);
startActivity(intent_share_result_activity);
} catch (Exception e) {
// Don't let this crash the app!
SKPorting.sAssert(getClass(), false);
}
}
return true;
}
return true;
}
//
// This method is called when the activity detects that the running test has completed.
//
private void onDidDetectTestCompleted() {
checkOutDataCap(); // Check out if we have reach the data cap to show the warning
testsRunning = false; // Indicate that we are not running tests
// Prevent our getting bombarded with more info from the test!
HttpTest.sLatestSpeedReset();
manualTest = null;
threadRunningTests = null;
if ((getActivity() == null) || (isAdded() == false)) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
return;
}
if (menuItem_SelectTests != null) {
menuItem_SelectTests.setVisible(SKApplication.getAppInstance().allowUserToSelectTestToRun());
}
changeAdviceMessageTo(getString(R.string.advice_message_press_the_button_run_again));
resetProgressBar();
changeLabelText(getString(R.string.label_message_tests_executed));
changeFadingTextViewValue(tv_Gauge_TextView_PsuedoButton, getString(R.string.gauge_message_start), 0);
// tv_Gauge_Message.setText(getString(R.string.gauge_message_start));
gaugeView.setKindOfTest(-1);
setNetworkTypeInformation();
sendRefreshUIMessage();
if (SKApplication.getAppInstance().getRevealMetricsOnMainScreen()) {
layout_ll_results.setClickable(true);
}
setUpPassiveMetricsLayout(connectivityType);
//changeFadingTextViewValue(tv_Closest_Server, getString(R.string.TEST_Label_Finding_Best_Target), getResources().getColor(R.color.grey_light));
mUnitText.setText("");
mMeasurementText.setText("");
}
private void registerBackButtonHandler() {
View view = getView();
if (view == null) {
SKPorting.sAssert(false);
return;
}
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// TODO - should we handle this ourselves, or not?!
if (gaugeVisible == true) {
// Don't handle it...
return false;
}
// Handle the back button event directly.
// The gauge elements are invisible - show them and hide the passive metrics.
showGaugeHidePassiveMetricsPanel();
return true;
} else {
// Don't handle it...
return false;
}
}
});
}
private void hideGaugeShowPassiveMetricsPanel() {
// Find the public_ip and submission_id!
publicIp.setText(SKApplication.getAppInstance().mLastPublicIp);
submissionId.setText(SKApplication.getAppInstance().mLastSubmissionId);
tv_Advice_Message.animate().setDuration(300).alpha(0.0f);
tv_TopTextNetworkType.setVisibility(View.INVISIBLE);
tv_Gauge_TextView_PsuedoButton.animate().setDuration(300).alpha(0.0f);
layout_layout_Shining_Labels.animate().setDuration(300).alpha(0.0f);
mUnitText.animate().setDuration(300).alpha(0.0f);
mMeasurementText.animate().setDuration(300).alpha(0.0f);
gaugeViewContainer.animate().setDuration(300).alpha(0.0f).setListener(new AnimatorListenerAdapter() {
// Executed at the end of the animation
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
gaugeViewContainer.animate().setListener(null); // Remove listener to avoid side effects
// Hide all the gauge elements
//tv_Advice_Message.setVisibility(View.GONE);
tv_TopTextNetworkType.setVisibility(View.INVISIBLE);
tv_Gauge_TextView_PsuedoButton.setVisibility(View.GONE);
layout_layout_Shining_Labels.setVisibility(View.GONE);
gaugeViewContainer.setVisibility(View.GONE);
mUnitText.setVisibility(View.GONE);
mMeasurementText.setVisibility(View.GONE);
gaugeVisible = false;
if (menuItem_ShareResult != null) {
menuItem_ShareResult.setVisible((!gaugeVisible) && (connectivityType == eNetworkTypeResults.eNetworkTypeResults_Mobile));
}
// Move the results layout to the top of the screen
run_results_panel_frame_to_animate.animate().setDuration(300).y(dpToPx(8)).setInterpolator(new OvershootInterpolator(1.2f));
// Make the passive metrics layout visible
layout_ll_passive_metrics.animate().setDuration(300).alpha(1.0f);
layout_ll_passive_metrics.setVisibility(View.VISIBLE);
}
});
}
private void showGaugeHidePassiveMetricsPanel() {
layout_ll_passive_metrics.animate().setDuration(300).alpha(0.0f).setListener(new AnimatorListenerAdapter() {
// Executed at the end of the animation
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
layout_ll_passive_metrics.animate().setListener(null); // Remove listeners to avoid side effects
// Move the results layout to the default position
run_results_panel_frame_to_animate.animate().setDuration(300).y(results_Layout_Position_Y).setInterpolator(new OvershootInterpolator(1.2f)).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// Executed at the end of the animation
super.onAnimationEnd(animation);
run_results_panel_frame_to_animate.animate().setListener(null); // Remove listeners to avoid side effects
// Make gauge elements visible
tv_Advice_Message.setVisibility(View.VISIBLE);
tv_TopTextNetworkType.setVisibility(View.VISIBLE);
tv_Gauge_TextView_PsuedoButton.setVisibility(View.VISIBLE);
layout_layout_Shining_Labels.setVisibility(View.VISIBLE);
gaugeViewContainer.setVisibility(View.VISIBLE);
mUnitText.setVisibility(View.VISIBLE);
mMeasurementText.setVisibility(View.VISIBLE);
gaugeViewContainer.animate().setDuration(300).alpha(1.0f);
tv_Advice_Message.animate().setDuration(300).alpha(1.0f);
//tv_TopTextNetworkType.animate().setDuration(300).alpha(1.0f);
tv_Gauge_TextView_PsuedoButton.animate().setDuration(300).alpha(1.0f);
layout_layout_Shining_Labels.animate().setDuration(300).alpha(1.0f);
mUnitText.animate().setDuration(300).alpha(1.0f);
mMeasurementText.animate().setDuration(300).alpha(1.0f);
layout_ll_passive_metrics.setVisibility(View.GONE);
gaugeVisible = true;
if (menuItem_ShareResult != null) {
menuItem_ShareResult.setVisible(false);
}
}
});
}
});
}
private void testRunningAskUserIfTheyWantToCancelIt() {
//
// Tests are running - stop the tests, if the user agrees!
//
if ((getActivity() == null) || (isAdded() == false)) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.tests_running_title);
builder.setMessage(R.string.tests_running_message)
.setCancelable(false)
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
})
.setPositiveButton(R.string.ok_dialog, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
// Note that if the test has auto-stopped since we started asking
// the user, the manualTest value will be null; so, we need to defend
// against that.
if (manualTest != null) {
changeAdviceMessageTo(getString(R.string.advice_message_stopping));
manualTest.stopTestRunning();
}
}
});
builder.create().show();
}
private void onStartButtonPressed() {
if (MainService.isExecuting()) {
showAlertCannotRunTestAsBackgroundTaskIsRunning();
return;
}
if (testsRunning == true) {
if (manualTest == null) {
SKPorting.sAssert(getClass(), false);
// Should not happen - force a tidy-up!
onDidDetectTestCompleted();
} else if (threadRunningTests == null) {
SKPorting.sAssert(getClass(), false);
// Should not happen - force a tidy-up!
onDidDetectTestCompleted();
} else {
//
// Tests are running - stop the tests, if the user agrees!
//
testRunningAskUserIfTheyWantToCancelIt();
}
return;
}
//
// Tests are not running - start the test?
//
if (Connectivity.sGetIsConnected(getActivity()) == false) {
// Can't do anything, if we're not connected!
Toast.makeText(getActivity(), getString(R.string.no_connectivity), Toast.LENGTH_LONG).show();
return;
}
String showWithMessage = "";
// IF we're on mobile network (i.e. not on WiFi network...) do a datacap check!
if (Connectivity.isConnectedMobile(getActivity())) {
if (SKApplication.getAppInstance().getIsDataCapEnabled() == true) {
if (SK2AppSettings.getSK2AppSettingsInstance().isDataCapReached()) {
Log.d(TAG, "Data cap exceeded");
showWithMessage = getString(R.string.data_cap_exceeded);
} else {
if (manualTest != null) {
if (SK2AppSettings.getSK2AppSettingsInstance().isDataCapLikelyToBeReached(manualTest.getNetUsage())) {
// Data cap exceeded - but only ask the user if they want to continue, if the app is configured
// to work like that...
showWithMessage = getString(R.string.data_cap_might_be_exceeded);
}
}
}
}
}
if (showWithMessage.length() > 0) {
// Data cap exceeded limit hit, or will be hit!
Log.d(TAG, "Data cap exceeded");
new AlertDialog.Builder(getActivity())
.setMessage(showWithMessage)
.setPositiveButton(R.string.ok_dialog,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
doRunTestAfterAllPreStartChecksCompleted();
}
})
.setNegativeButton(R.string.no_dialog,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
} else {
doRunTestAfterAllPreStartChecksCompleted();
}
}
private void doRunTestAfterAllPreStartChecksCompleted() {
// If at least one test is selected
if (atLeastOneTestSelected()) {
initial_warning_text.setVisibility(View.GONE);
SKApplication.getAppInstance().mLastPublicIp = "";
SKApplication.getAppInstance().mLastSubmissionId = "";
publicIp.setText(SKApplication.getAppInstance().mLastPublicIp);
submissionId.setText(SKApplication.getAppInstance().mLastSubmissionId);
// Make sure that we display the correct image (for now!) in the Test results panel.
// This will be overridden by incoming passive metric data.
final Context context = SKApplication.getAppInstance().getApplicationContext();
if (Connectivity.isConnectedWifi(context)) {
setTestConnectivity(eNetworkTypeResults.eNetworkTypeResults_WiFi);
} else {
setTestConnectivity(eNetworkTypeResults.eNetworkTypeResults_Mobile);
}
if (SKApplication.getAppInstance().getDoesAppDisplayClosestTargetInfo()) {
mUnitText.setText(R.string.TEST_Label_Finding_Best_Target);
mMeasurementText.setText("");
}
new InitTestAsyncTask().execute();
} else {
// No tests are selected: show the activity to select tests
if ((getActivity() == null) || (isAdded() == false)) {
// e.g. test completes, after fragment detatched
SKPorting.sAssert(false);
return;
}
Intent intent_select_tests = new Intent(getActivity(), ActivitySelectTests.class);
startActivity(intent_select_tests);
}
}
}