at.alladin.rmbt.android.loopmode.LoopModeTestFragment.java Source code

Java tutorial

Introduction

Here is the source code for at.alladin.rmbt.android.loopmode.LoopModeTestFragment.java

Source

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

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import at.alladin.openrmbt.android.R;
import at.alladin.rmbt.android.loopmode.LoopModeResults.Status;
import at.alladin.rmbt.android.loopmode.info.AdditionalInfoFragment;
import at.alladin.rmbt.android.loopmode.info.DetailsInfoListAdapter;
import at.alladin.rmbt.android.loopmode.info.LoopModeTriggerItem;
import at.alladin.rmbt.android.loopmode.info.LoopModeTriggerItem.TriggerType;
import at.alladin.rmbt.android.loopmode.info.TrafficUsageItem;
import at.alladin.rmbt.android.loopmode.measurement.IpAddressItem;
import at.alladin.rmbt.android.loopmode.measurement.MeasurementDetailsFragment;
import at.alladin.rmbt.android.loopmode.measurement.ServerNameItem;
import at.alladin.rmbt.android.main.RMBTMainActivity;
import at.alladin.rmbt.android.test.RMBTLoopService;
import at.alladin.rmbt.android.test.RMBTLoopService.RMBTLoopBinder;
import at.alladin.rmbt.android.test.RMBTLoopService.RMBTLoopServiceConnection;
import at.alladin.rmbt.android.test.RMBTService;
import at.alladin.rmbt.android.test.RMBTService.RMBTBinder;
import at.alladin.rmbt.android.test.RMBTTestFragment;
import at.alladin.rmbt.android.util.InformationCollector;
import at.alladin.rmbt.client.helper.IntermediateResult;

public class LoopModeTestFragment extends Fragment implements ServiceConnection, RMBTLoopServiceConnection {

    public final static String TAG = "LoopModeStartFragment";

    public static final class LoopModeViewHolder {
        private class StringsHolder {
            String testRunningString;
            String loopModeString;
            String waiting;
            String finished;
        }

        DetailsInfoListAdapter unimportantListAdapter;

        TextView counterText;
        TextView lastTestText;
        MeasurementDetailsFragment measurementFragment;
        AdditionalInfoFragment infoFragment;
        ProgressBar progressBar;
        TextView progressText;
        ListView unimportantInfoList;
        Button cancelButton;
        final StringsHolder strings = new StringsHolder();
    }

    private class RMBTServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            final RMBTBinder binder = (RMBTBinder) service;
            Log.d(TAG, "connect RMBT Service");
            rmbtService = binder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "disconnect RMBT Service");
            rmbtService = null;
        }

    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (RMBTService.BROADCAST_TEST_FINISHED.equals(intent.getAction())) {

            }
        }
    };

    Handler handler;

    RMBTLoopService loopService;

    RMBTService rmbtService;
    RMBTServiceConnection rmbtServiceConnection = new RMBTServiceConnection();

    LoopModeViewHolder holder;

    IntermediateResult intermediateResult;

    InformationCollector infoCollector;

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);

        handler = new Handler();
        infoCollector = new InformationCollector(getActivity(), false, false);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View v = inflater.inflate(R.layout.loop_mode_test_fragment, container, false);

        holder = new LoopModeViewHolder();
        holder.counterText = (TextView) v.findViewById(R.id.loop_test_counter);
        holder.lastTestText = (TextView) v.findViewById(R.id.loop_test_last_test_status);
        holder.progressBar = (ProgressBar) v.findViewById(R.id.loop_test_progress_bar);
        holder.progressText = (TextView) v.findViewById(R.id.loop_test_progress_bar_text);
        holder.unimportantInfoList = (ListView) v.findViewById(R.id.loop_test_unimportant_info_list);
        holder.cancelButton = (Button) v.findViewById(R.id.loop_test_close_button);
        holder.cancelButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                getActivity().onBackPressed();
            }
        });

        holder.strings.testRunningString = getResources().getString(R.string.loop_test_progress_test_running);
        holder.strings.loopModeString = getResources().getString(R.string.loop_test_progress_test_not_running);
        holder.strings.waiting = getResources().getString(R.string.loop_test_progress_test_waiting);
        holder.strings.finished = getResources().getString(R.string.loop_test_progress_test_finished);

        holder.infoFragment = AdditionalInfoFragment.newInstance();
        getChildFragmentManager().beginTransaction()
                .add(R.id.loop_test_details_holder, holder.infoFragment, "lm_additional_info").commit();

        holder.measurementFragment = MeasurementDetailsFragment.newInstance();
        getChildFragmentManager().beginTransaction()
                .add(R.id.loop_test_measurement_holder, holder.measurementFragment, "lm_measurement").commit();
        return v;
    }

    @Override
    public void onStop() {
        super.onStop();

        handler.removeCallbacks(updateTask);

        getActivity().unregisterReceiver(receiver);
        getActivity().unbindService(this);
        getActivity().unbindService(rmbtServiceConnection);

        Log.d(TAG, "UNBIND LOOP MODE SERVICES");

        getActivity().getActionBar().show();
        ((RMBTMainActivity) getActivity()).setLockNavigationDrawer(false);

        //getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (infoCollector != null) {
            infoCollector.unload();
        }
    }

    @Override
    public void onStart() {
        super.onStart();

        if (infoCollector != null) {
            infoCollector.init();
        }

        getActivity().getActionBar().hide();
        ((RMBTMainActivity) getActivity()).setLockNavigationDrawer(true);

        // Bind to RMBTLoopService
        final Intent loopServiceIntent = new Intent(getActivity(), RMBTLoopService.class);
        getActivity().bindService(loopServiceIntent, this, 0);

        final Intent rmbtServiceIntent = new Intent(getActivity(), RMBTService.class);
        getActivity().bindService(rmbtServiceIntent, rmbtServiceConnection, Context.BIND_AUTO_CREATE);

        final IntentFilter actionFilter = new IntentFilter(RMBTService.BROADCAST_TEST_FINISHED);
        getActivity().registerReceiver(receiver, actionFilter);

        Log.d(TAG, "BIND LOOP MODE SERVICES");

        handler.post(updateTask);

        //getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    @Override
    public void onServiceConnected(final ComponentName name, final IBinder service) {
        Log.d(TAG, "loopService connected");
        final RMBTLoopBinder binder = (RMBTLoopBinder) service;
        loopService = binder.getService();
    }

    @Override
    public void onServiceDisconnected(final ComponentName name) {
        Log.d(TAG, "loopService disconnected");
        loopService = null;
    }

    public final Runnable updateTask = new Runnable() {

        @Override
        public void run() {
            updateUi();
            handler.postDelayed(updateTask, 250);
        }
    };

    public void updateUi() {
        if (holder != null && loopService != null) {
            LoopModeResults loopModeResults = loopService.getLoopModeResults();
            holder.counterText.setText(holder.strings.loopModeString + ": " + loopModeResults.getNumberOfTests()
                    + "/" + loopModeResults.getMaxTests()
                    + (Status.RUNNING.equals(loopModeResults.getStatus()) ? ""
                            : " (" + (loopService.isActive() ? holder.strings.waiting : holder.strings.finished)
                                    + ")"));

            if (Status.RUNNING.equals(loopModeResults.getStatus())) {
                loopModeResults = loopService.updateLoopModeResults(true);

                if (holder.lastTestText.getVisibility() == View.VISIBLE) {
                    //loop mode just switched from idle/waiting state to test mode
                    holder.lastTestText.setVisibility(View.GONE);
                    holder.unimportantListAdapter = null;
                }

                if (holder.progressBar.getVisibility() == View.GONE) {
                    holder.progressBar.setVisibility(View.VISIBLE);
                    holder.progressText.setVisibility(View.VISIBLE);
                }
            } else {
                if (holder.lastTestText.getVisibility() != View.VISIBLE) {
                    //loop mode just switched from test mode to idle/waiting state
                    holder.unimportantListAdapter = null;
                    holder.lastTestText.setVisibility(View.VISIBLE);
                }

                if (holder.progressBar.getVisibility() == View.VISIBLE) {
                    holder.progressBar.setVisibility(View.GONE);
                    holder.progressText.setVisibility(View.GONE);
                }
            }

            //update or initialize the "not so important list" (reason why it's at the bottom of the view)
            if (holder.unimportantListAdapter != null) {
                holder.unimportantListAdapter.notifyDataSetChanged();
            } else {
                //different "not so important lists", depending on current test status (running/idle)
                if (Status.RUNNING.equals(loopModeResults.getStatus())) {
                    //during test mode, show current test server and client's ip
                    final List<DetailsListItem> list = new ArrayList<DetailsListItem>();
                    list.add(new ServerNameItem(getActivity(), loopModeResults));
                    list.add(new IpAddressItem(getActivity(), loopModeResults));
                    holder.unimportantListAdapter = new DetailsInfoListAdapter(getActivity(), list);
                    holder.unimportantInfoList.setAdapter(holder.unimportantListAdapter);
                } else {
                    //during idle mode, show current data usage, and both loop mode trigger statuses
                    final List<DetailsListItem> list = new ArrayList<DetailsListItem>();
                    list.add(new TrafficUsageItem(getActivity(), loopModeResults));
                    list.add(new LoopModeTriggerItem(getActivity(), loopModeResults, TriggerType.MOVEMENT));
                    list.add(new LoopModeTriggerItem(getActivity(), loopModeResults, TriggerType.TIME));
                    holder.unimportantListAdapter = new DetailsInfoListAdapter(getActivity(), list);
                    holder.unimportantInfoList.setAdapter(holder.unimportantListAdapter);
                }
            }

            //update last test status
            if (holder.lastTestText != null && holder.lastTestText.getVisibility() == View.VISIBLE) {
                String lastTestResult = "";
                if (loopModeResults != null && loopModeResults.getLastTestResults() != null) {
                    final Date d = new Date(loopModeResults.getLastTestResults().getLocalStartTimeStamp());
                    final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT,
                            Locale.getDefault());
                    switch (loopModeResults.getLastTestResults().getStatus()) {
                    case OK:
                        lastTestResult = getString(R.string.loop_test_last_status_ok);
                        break;
                    case REJECTED:
                        lastTestResult = getString(R.string.loop_test_last_status_rejected);
                        break;
                    default:
                        lastTestResult = getString(R.string.loop_test_last_status_error);
                    }
                    lastTestResult += " (" + df.format(d) + ")";
                }
                holder.lastTestText.setText(lastTestResult);
            }

            //update measurement list (up/down/ping/qos: last/current test + median values)
            if (holder.measurementFragment != null) {
                if (!holder.measurementFragment.hasResults()) {
                    holder.measurementFragment.initList(loopService.getLoopModeResults());
                } else {
                    holder.measurementFragment.updateList();
                }
            }

            //update info list (location, network, etc...)
            if (holder.infoFragment != null) {
                if (!holder.infoFragment.hasResults()) {
                    holder.infoFragment.initList(infoCollector);
                } else {
                    holder.infoFragment.updateList();
                }
            }

            //loop service is active (= at least one test still has to be run or finished) 
            if (loopService.isActive()) {
                int progress = 0;
                String progressText = "";
                int maxProgress = 100;

                if (rmbtService != null) {
                    if (Status.RUNNING.equals(loopModeResults.getStatus())) {
                        //test currently running, test mode:
                        intermediateResult = rmbtService.getIntermediateResult(intermediateResult);
                        if (intermediateResult != null) {
                            progress = (int) (RMBTTestFragment.calculateProgress(intermediateResult,
                                    rmbtService.getQoSTestProgress(), rmbtService.getQoSTestSize()) * 100d);
                            progressText = holder.strings.testRunningString + ": " + progress + "%";
                            maxProgress = 100;
                        } else if (rmbtService.isConnectionError()) {

                        } else {

                        }
                    } else {
                        //no test running, waiting mode:
                        progress = loopModeResults.getNumberOfTests();
                        progressText = holder.strings.loopModeString + ": " + loopModeResults.getNumberOfTests()
                                + "/" + loopModeResults.getMaxTests();
                        maxProgress = loopModeResults.getMaxTests();
                    }

                    holder.progressBar.setMax(maxProgress);
                    holder.progressBar.setProgress(progress);
                    holder.progressText.setText(progressText);
                } else {
                    //connecting?
                }
            } else {
                holder.cancelButton.setText(R.string.loop_test_quit);
            }
        } else if (holder != null) {
            //service (still) not bound...
        }
    }

    public boolean onBackPressed() {
        if (loopService == null) {
            return false;
        }

        else if (loopService.isRunning() || (loopService.getLoopModeResults().getMaxTests() > loopService
                .getLoopModeResults().getNumberOfTests())) {

            AlertDialog stopDialog = new AlertDialog.Builder(getActivity())
                    .setTitle(R.string.test_dialog_abort_title).setMessage(R.string.loop_mode_test_dialog_abort)
                    .setPositiveButton(android.R.string.yes, new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            stopLoopService();
                            ((RMBTMainActivity) getActivity()).popBackStackFull();
                        }
                    }).setNegativeButton(android.R.string.no, new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    }).create();

            stopDialog.setCancelable(false);
            stopDialog.show();
        } else if (loopService.getLoopModeResults().getMaxTests() <= loopService.getLoopModeResults()
                .getNumberOfTests()) {
            //if max tests is reached simply remove this fragment without alert dialog
            stopLoopService();
            return false;
        }

        return true;
    }

    private void stopLoopService() {
        if (rmbtService != null) {
            rmbtService.stopTest(RMBTService.BROADCAST_TEST_ABORTED);
        } else {
            // to be sure test is stopped:
            final Intent service = new Intent(RMBTService.ACTION_ABORT_TEST, null, getActivity(),
                    RMBTService.class);
            getActivity().startService(service);
        }

        ((RMBTMainActivity) getActivity()).stopLoopService();
    }

    @Override
    public RMBTLoopService getRMBTLoopService() {
        return loopService;
    }
}