org.comixwall.pffw.InfoQueues.java Source code

Java tutorial

Introduction

Here is the source code for org.comixwall.pffw.InfoQueues.java

Source

/*
 * Copyright (C) 2017-2018 Soner Tari
 *
 * This file is part of PFFW.
 *
 * PFFW is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PFFW is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PFFW.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.comixwall.pffw;

import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.comixwall.pffw.MainActivity.cache;
import static org.comixwall.pffw.MainActivity.controller;
import static org.comixwall.pffw.MainActivity.fragment;
import static org.comixwall.pffw.MainActivity.logger;
import static org.comixwall.pffw.Utils.processException;
import static org.comixwall.pffw.Utils.showMessage;

public class InfoQueues extends Fragment
        implements SwipeRefreshLayout.OnRefreshListener, RefreshTimer.OnTimeoutListener,
        RecyclerTouchListener.OnItemClickListener, ControllerTask.ControllerTaskListener {

    private InfoQueuesCache mModuleCache;

    private RefreshTimer mTimer;
    private int mRefreshTimeout = 10;

    private SwipeRefreshLayout swipeRefresh;

    private JSONArray mQueuesJsonArray;
    private final List<Queue> mQueuesList = new ArrayList<>();
    private QueueRecyclerAdapter mQueuesAdapter;

    private String mLastError;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.info_queues, container, false);

        swipeRefresh = view.findViewById(R.id.swipeRefresh);
        swipeRefresh.setOnRefreshListener(this);

        RecyclerView rvQueues = view.findViewById(R.id.recyclerViewQueues);

        rvQueues.setLayoutManager(new LinearLayoutManager(getActivity()));
        rvQueues.setItemAnimator(new DefaultItemAnimator());
        rvQueues.addItemDecoration(new RecyclerDivider(getActivity(), LinearLayoutManager.VERTICAL));
        mQueuesAdapter = new QueueRecyclerAdapter(mQueuesList);
        rvQueues.setAdapter(mQueuesAdapter);
        rvQueues.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), this));

        if (cache.infoQueues == null) {
            cache.infoQueues = new InfoQueuesCache();
        }
        mModuleCache = cache.infoQueues;

        return view;
    }

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

        mModuleCache.mQueuesJsonArray = mQueuesJsonArray;

        // ATTENTION: It is very important to cancel the timer
        mTimer.cancel();
    }

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

        fragment = this;

        mQueuesJsonArray = mModuleCache.mQueuesJsonArray;

        if (mQueuesJsonArray == null) {
            getInfo();
        } else {
            updateInfo();
        }

        mTimer = new RefreshTimer((MainActivity) getActivity(), this);
        mTimer.start(mRefreshTimeout);
    }

    @Override
    public void onTimeout() {
        getInfo();
    }

    @Override
    public void executePreTask() {
    }

    @Override
    public void preExecute() {
        swipeRefresh.setRefreshing(true);
    }

    @Override
    public boolean executeTask() {
        Boolean retval = true;
        try {
            String output = controller.execute("pf", "GetPfQueueInfo");

            JSONArray jsonArray = new JSONArray(output);
            mQueuesJsonArray = new JSONArray(jsonArray.get(0).toString());

            output = controller.execute("pf", "GetReloadRate");

            int timeout = Integer.parseInt(new JSONArray(output).get(0).toString());
            mRefreshTimeout = timeout < 10 ? 10 : timeout;

        } catch (Exception e) {
            mLastError = processException(e);
            retval = false;
        }
        return retval;
    }

    @Override
    public void postExecute(boolean result) {
        if (result) {
            updateInfo();
        } else {
            showMessage(this, "Error: " + mLastError);
        }

        swipeRefresh.setRefreshing(false);
    }

    @Override
    public void executeOnCancelled() {
        swipeRefresh.setRefreshing(false);
    }

    private void getInfo() {
        ControllerTask.run(this, this);
    }

    private void updateInfo() {
        updateQueueList(mQueuesJsonArray, mQueuesList);
        mQueuesAdapter.notifyDataSetChanged();
    }

    private void updateQueueList(JSONArray jsonArray, List<Queue> list) {
        try {
            list.clear();

            int i = 0;
            while (i < jsonArray.length()) {
                list.add(Queue.newInstance(jsonArray.getJSONObject(i), i + 1));
                i++;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.warning("updateQueueList exception: " + e.toString());
        }
    }

    @Override
    public void onRefresh() {
        getInfo();
    }

    @Override
    public void onItemClick(View view) {

        TextView tvPacketsBytes = view.findViewById(R.id.packetsBytes);
        TextView tvDropped = view.findViewById(R.id.dropped);

        int lines = 10;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            if (tvPacketsBytes.getMaxLines() != 1) {
                lines = 1;
            }
        }

        tvPacketsBytes.setMaxLines(lines);
        tvDropped.setMaxLines(lines);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.menuRefresh) {
            getInfo();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

class Queue {
    String num;
    public String name;
    String pkts;
    String bytes;
    String droppedPkts;
    String droppedBytes;
    String len;

    static Queue newInstance(JSONObject qEntry, int line) {
        Queue queue = new Queue();
        try {
            queue.num = Integer.toString(line);
            queue.name = qEntry.getString("name");
            queue.pkts = qEntry.getString("pkts");
            queue.bytes = qEntry.getString("bytes");
            queue.droppedPkts = qEntry.getString("droppedPkts");
            queue.droppedBytes = qEntry.getString("droppedBytes");
            queue.len = qEntry.getString("length");
        } catch (Exception e) {
            e.printStackTrace();
            logger.warning("Queue newInstance exception: " + e.toString());
        }
        return queue;
    }
}

class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdapter.QueueViewHolder> {

    private final List<Queue> queueList;

    class QueueViewHolder extends RecyclerView.ViewHolder {
        final TextView name;
        final TextView packetsBytes;
        final TextView dropped;
        final TextView number;
        final TextView len;
        final TextView image;

        QueueViewHolder(View view) {
            super(view);
            name = view.findViewById(R.id.name);
            packetsBytes = view.findViewById(R.id.packetsBytes);
            dropped = view.findViewById(R.id.dropped);
            number = view.findViewById(R.id.number);
            len = view.findViewById(R.id.len);
            image = view.findViewById(R.id.image);
        }
    }

    QueueRecyclerAdapter(List<Queue> list) {
        this.queueList = list;
    }

    @Override
    public QueueViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.queue, parent, false);

        return new QueueViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(QueueViewHolder holder, int position) {

        Queue queue = queueList.get(position);

        holder.name.setText(queue.name);
        holder.packetsBytes.setText(String.format(
                holder.packetsBytes.getResources().getString(R.string.packets_bytes), queue.pkts, queue.bytes));
        holder.number.setText(queue.num);
        holder.dropped
                .setText(String.format(holder.dropped.getResources().getString(R.string.dropped_packets_bytes),
                        queue.droppedPkts, queue.droppedBytes));
        holder.len.setText(String.format(holder.len.getResources().getString(R.string.length), queue.len));

        // 0/50
        float used = 0f;
        float len = 1f;
        Pattern p = Pattern.compile("(\\d+)\\s*/\\s*(\\d+)");
        Matcher m = p.matcher(queue.len);
        if (m.matches()) {
            used = Float.parseFloat(m.group(1));
            len = Float.parseFloat(m.group(2));
        }

        float ratio = used / len;

        int image;
        String caption;

        if (ratio > 0.66f) {
            image = R.drawable.block;
            caption = "H";
        } else if (ratio > 0.33f) {
            image = R.drawable.pass;
            caption = "M";
        } else {
            image = R.drawable.match;
            caption = "L";
        }

        holder.image.setBackgroundResource(image);
        holder.image.setText(caption);
    }

    @Override
    public int getItemCount() {
        return queueList.size();
    }
}

class InfoQueuesCache {
    JSONArray mQueuesJsonArray;
}