Java tutorial
/******************************************************************************* * This file is part of BOINC. * http://boinc.berkeley.edu * Copyright (C) 2012 University of California * * BOINC is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. * * BOINC 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with BOINC. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package edu.berkeley.boinc; import edu.berkeley.boinc.utils.*; import edu.berkeley.boinc.attach.SelectionListActivity; import edu.berkeley.boinc.client.ClientStatus; import edu.berkeley.boinc.utils.BOINCDefs; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.AsyncTask; import android.os.Bundle; import android.os.RemoteException; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class StatusFragment extends Fragment { // keep computingStatus and suspend reason to only adapt layout when changes occur private Integer computingStatus = -1; private Integer computingSuspendReason = -1; private Integer networkSuspendReason = -1; private Integer setupStatus = -1; private BroadcastReceiver mClientStatusChangeRec = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (Logging.VERBOSE) Log.d(Logging.TAG, "StatusFragment ClientStatusChange - onReceive()"); loadLayout(false); } }; private IntentFilter ifcsc = new IntentFilter("edu.berkeley.boinc.clientstatuschange"); public void onResume() { //register noisy clientStatusChangeReceiver here, so only active when Activity is visible if (Logging.VERBOSE) Log.v(Logging.TAG, "StatusFragment register receiver"); getActivity().registerReceiver(mClientStatusChangeRec, ifcsc); //loadLayout(true); super.onResume(); } public void onPause() { //unregister receiver, so there are not multiple intents flying in if (Logging.VERBOSE) Log.v(Logging.TAG, "StatusFragment remove receiver"); getActivity().unregisterReceiver(mClientStatusChangeRec); super.onPause(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (Logging.VERBOSE) Log.v(Logging.TAG, "StatusFragment onCreateView"); // Inflate the layout for this fragment return inflater.inflate(R.layout.status_layout, container, false); } private void loadLayout(Boolean forceUpdate) { //load layout, if if ClientStatus can be accessed. //if this is not the case, the broadcast receiver will call "loadLayout" again try { int currentSetupStatus = BOINCActivity.monitor.getSetupStatus(); int currentComputingStatus = BOINCActivity.monitor.getComputingStatus(); int currentComputingSuspendReason = BOINCActivity.monitor.getComputingSuspendReason(); int currentNetworkSuspendReason = BOINCActivity.monitor.getNetworkSuspendReason(); // layout only if client RPC connection is established // otherwise BOINCActivity does not start Tabs if (currentSetupStatus == ClientStatus.SETUP_STATUS_AVAILABLE) { // return in cases nothing has changed if (forceUpdate || computingStatus != currentComputingStatus || currentComputingSuspendReason != computingSuspendReason || currentNetworkSuspendReason != networkSuspendReason) { // set layout and retrieve elements LinearLayout statusWrapper = (LinearLayout) getView().findViewById(R.id.status_wrapper); LinearLayout centerWrapper = (LinearLayout) getView().findViewById(R.id.center_wrapper); LinearLayout restartingWrapper = (LinearLayout) getView().findViewById(R.id.restarting_wrapper); TextView statusHeader = (TextView) getView().findViewById(R.id.status_header); ImageView statusImage = (ImageView) getView().findViewById(R.id.status_image); TextView statusDescriptor = (TextView) getView().findViewById(R.id.status_long); restartingWrapper.setVisibility(View.GONE); // adapt to specific computing status switch (currentComputingStatus) { case ClientStatus.COMPUTING_STATUS_NEVER: statusWrapper.setVisibility(View.VISIBLE); statusHeader.setText(BOINCActivity.monitor.getCurrentStatusTitle()); statusHeader.setVisibility(View.VISIBLE); statusImage.setImageResource(R.drawable.playb48); statusImage.setContentDescription(BOINCActivity.monitor.getCurrentStatusTitle()); statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); centerWrapper.setVisibility(View.VISIBLE); centerWrapper.setOnClickListener(runModeOnClickListener); break; case ClientStatus.COMPUTING_STATUS_SUSPENDED: statusWrapper.setVisibility(View.VISIBLE); statusHeader.setText(BOINCActivity.monitor.getCurrentStatusTitle()); statusHeader.setVisibility(View.VISIBLE); statusImage.setImageResource(R.drawable.pauseb48); statusImage.setContentDescription(BOINCActivity.monitor.getCurrentStatusTitle()); statusImage.setClickable(false); centerWrapper.setVisibility(View.VISIBLE); switch (currentComputingSuspendReason) { case BOINCDefs.SUSPEND_REASON_BATTERIES: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); statusImage.setImageResource(R.drawable.notconnectedb48); statusHeader.setVisibility(View.GONE); break; case BOINCDefs.SUSPEND_REASON_USER_ACTIVE: Boolean suspendDueToScreenOn = false; try { suspendDueToScreenOn = BOINCActivity.monitor.getSuspendWhenScreenOn(); } catch (RemoteException e) { } if (suspendDueToScreenOn) { statusImage.setImageResource(R.drawable.screen48b); statusHeader.setVisibility(View.GONE); } statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_USER_REQ: // state after user stops and restarts computation centerWrapper.setVisibility(View.GONE); restartingWrapper.setVisibility(View.VISIBLE); break; case BOINCDefs.SUSPEND_REASON_TIME_OF_DAY: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_BENCHMARKS: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); statusImage.setImageResource(R.drawable.watchb48); statusHeader.setVisibility(View.GONE); break; case BOINCDefs.SUSPEND_REASON_DISK_SIZE: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_CPU_THROTTLE: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_NO_RECENT_INPUT: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_INITIAL_DELAY: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_EXCLUSIVE_APP_RUNNING: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_CPU_USAGE: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_NETWORK_QUOTA_EXCEEDED: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_OS: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_WIFI_STATE: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case BOINCDefs.SUSPEND_REASON_BATTERY_CHARGING: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); statusImage.setImageResource(R.drawable.batteryb48); statusHeader.setVisibility(View.GONE); break; case BOINCDefs.SUSPEND_REASON_BATTERY_OVERHEATED: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); statusImage.setImageResource(R.drawable.batteryb48); statusHeader.setVisibility(View.GONE); break; default: statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; } break; case ClientStatus.COMPUTING_STATUS_IDLE: statusWrapper.setVisibility(View.VISIBLE); centerWrapper.setVisibility(View.VISIBLE); statusHeader.setText(BOINCActivity.monitor.getCurrentStatusTitle()); statusHeader.setVisibility(View.VISIBLE); statusImage.setImageResource(R.drawable.pauseb48); statusImage.setContentDescription(BOINCActivity.monitor.getCurrentStatusTitle()); statusImage.setClickable(false); statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusDescription()); break; case ClientStatus.COMPUTING_STATUS_COMPUTING: statusWrapper.setVisibility(View.GONE); break; } //save new computing status computingStatus = currentComputingStatus; computingSuspendReason = currentComputingSuspendReason; networkSuspendReason = currentNetworkSuspendReason; setupStatus = -1; // invalidate to force update next time no project } } else if (currentSetupStatus == ClientStatus.SETUP_STATUS_NOPROJECT) { if (setupStatus != ClientStatus.SETUP_STATUS_NOPROJECT) { // set layout and retrieve elements LinearLayout statusWrapper = (LinearLayout) getView().findViewById(R.id.status_wrapper); LinearLayout centerWrapper = (LinearLayout) getView().findViewById(R.id.center_wrapper); LinearLayout restartingWrapper = (LinearLayout) getView().findViewById(R.id.restarting_wrapper); TextView statusHeader = (TextView) getView().findViewById(R.id.status_header); ImageView statusImage = (ImageView) getView().findViewById(R.id.status_image); TextView statusDescriptor = (TextView) getView().findViewById(R.id.status_long); statusWrapper.setVisibility(View.VISIBLE); restartingWrapper.setVisibility(View.GONE); centerWrapper.setVisibility(View.VISIBLE); centerWrapper.setOnClickListener(addProjectOnClickListener); statusImage.setImageResource(R.drawable.projectsb48); statusHeader.setVisibility(View.GONE); statusDescriptor.setText(BOINCActivity.monitor.getCurrentStatusTitle()); setupStatus = ClientStatus.SETUP_STATUS_NOPROJECT; computingStatus = -1; } } else { // BOINC client is not available //invalid computingStatus, forces layout on next event setupStatus = -1; computingStatus = -1; } } catch (Exception e) { } } private OnClickListener runModeOnClickListener = new OnClickListener() { @Override public void onClick(View v) { new WriteClientRunModeAsync().execute(BOINCDefs.RUN_MODE_AUTO); } }; private OnClickListener addProjectOnClickListener = new OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(getActivity(), SelectionListActivity.class)); } }; private final class WriteClientRunModeAsync extends AsyncTask<Integer, Void, Boolean> { @Override protected Boolean doInBackground(Integer... params) { // setting provided mode for both, CPU computation and network. Boolean runMode; try { runMode = BOINCActivity.monitor.setRunMode(params[0]); } catch (RemoteException e) { runMode = false; } Boolean networkMode; try { networkMode = BOINCActivity.monitor.setNetworkMode(params[0]); } catch (RemoteException e) { networkMode = false; } return runMode && networkMode; } @Override protected void onPostExecute(Boolean success) { if (success) try { BOINCActivity.monitor.forceRefresh(); } catch (RemoteException e) { } else if (Logging.WARNING) Log.w(Logging.TAG, "StatusFragment: setting run mode failed"); } } }