/* * Copyright (C) 2013 - 2014 Alexander "Evisceration" Martinz * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.namelessrom.devicecontrol.views; import android.content.Context; import android.os.AsyncTask; import android.support.annotation.NonNull; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import org.namelessrom.devicecontrol.R; import org.namelessrom.devicecontrol.modules.cpu.CpuUtils; import org.namelessrom.devicecontrol.modules.cpu.monitors.CpuStateMonitor; import java.io.IOException; import java.util.ArrayList; import java.util.List; import timber.log.Timber; public class CpuStateView extends LinearLayout implements CpuUtils.StateListener { private LinearLayout mStatesView; private TextView mAdditionalStates; private TextView mTotalStateTime; private TextView mHeaderAdditionalStates; private TextView mHeaderTotalStateTime; private TextView mStatesWarning; private boolean mUpdatingData = false; public CpuStateView(final Context context) { this(context, null); } public CpuStateView(final Context context, final AttributeSet attrs) { this(context, attrs, 0); } public CpuStateView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); createViews(context); } public void onResume() { Timber.d("onResume"); } public void onPause() { Timber.d("onPause"); } public void onDestroy() { // nothing to be done yet } private void createViews(final Context context) { final View view = LayoutInflater.from(context).inflate(R.layout.widget_cpu_states, this); mStatesView = (LinearLayout) view.findViewById(R.id.ui_states_view); mAdditionalStates = (TextView) view.findViewById(R.id.ui_additional_states); mHeaderAdditionalStates = (TextView) view.findViewById(R.id.ui_header_additional_states); mHeaderTotalStateTime = (TextView) view.findViewById(R.id.ui_header_total_state_time); mStatesWarning = (TextView) view.findViewById(R.id.ui_states_warning); mTotalStateTime = (TextView) view.findViewById(R.id.ui_total_state_time); refreshData(); } public void refreshData() { new CpuStateUpdater().execute(); } private class CpuStateUpdater extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { if (!mUpdatingData) { mUpdatingData = true; try { CpuStateMonitor.getInstance().updateStates(CpuStateView.this); } catch (IOException e) { Timber.e(e, "updateStates()"); } } return null; } @Override protected void onPostExecute(Void aVoid) { mUpdatingData = false; } } private static String toString(final long tSec) { final long h = (long) Math.floor(tSec / (60 * 60)); final long m = (long) Math.floor((tSec - h * 60 * 60) / 60); final long s = tSec % 60; final StringBuilder sDur = new StringBuilder(); sDur.append(h).append(':'); if (m < 10) { sDur.append('0'); } sDur.append(m).append(':'); if (s < 10) { sDur.append('0'); } sDur.append(s); return sDur.toString(); } private View generateStateRow(final CpuStateMonitor.CpuState state, final ViewGroup parent, final long totalStateTime) { final LinearLayout view = (LinearLayout) inflate(getContext(), R.layout.row_state, null); int per = ((int) ((float) state.duration * 100 / totalStateTime)); if (per > 100) { per = 100; } else if (per < 0) { per = 0; } final String sFreq; if (state.freq == 0) { sFreq = getContext().getString(R.string.deep_sleep); } else { sFreq = state.freq / 1000 + " MHz"; } long tSec = state.duration / 100; final String sDur = toString(tSec); final TextView freqText = (TextView) view.findViewById(R.id.ui_freq_text); final TextView durText = (TextView) view.findViewById(R.id.ui_duration_text); final NumberProgressBar bar = (NumberProgressBar) view.findViewById(R.id.ui_bar); freqText.setText(sFreq); durText.setText(sDur); bar.setProgress(per); parent.addView(view); return view; } @Override public void onStates(@NonNull final CpuUtils.State states) { mStatesView.removeAllViews(); final List<String> extraStates = new ArrayList<>(); for (CpuStateMonitor.CpuState state : states.states) { if (state.duration > 0) { generateStateRow(state, mStatesView, states.totalTime); } else { if (state.freq == 0) { extraStates.add(getContext().getString(R.string.deep_sleep)); } else { extraStates.add(state.freq / 1000 + " MHz"); } } } if (states.states.size() == 0) { mStatesWarning.setVisibility(View.VISIBLE); mHeaderTotalStateTime.setVisibility(View.GONE); mTotalStateTime.setVisibility(View.GONE); mStatesView.setVisibility(View.GONE); } final long totTime = states.totalTime / 100; mTotalStateTime.setText(toString(totTime)); if (extraStates.size() > 0) { int n = 0; final StringBuilder sb = new StringBuilder(); for (final String s : extraStates) { if (n++ > 0) { sb.append(", "); } sb.append(s); } mAdditionalStates.setVisibility(View.VISIBLE); mHeaderAdditionalStates.setVisibility(View.VISIBLE); mAdditionalStates.setText(sb.toString()); } else { mAdditionalStates.setVisibility(View.GONE); mHeaderAdditionalStates.setVisibility(View.GONE); } } }