package edu.berkeley.cs.amplab.carat.android.fragments;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import edu.berkeley.cs.amplab.carat.android.CaratApplication;
import edu.berkeley.cs.amplab.carat.android.Constants;
import edu.berkeley.cs.amplab.carat.android.MainActivity;
import edu.berkeley.cs.amplab.carat.android.R;
import edu.berkeley.cs.amplab.carat.android.sampling.SamplingLibrary;
import edu.berkeley.cs.amplab.carat.android.subscreens.AppDetailsFragment;
import edu.berkeley.cs.amplab.carat.android.subscreens.ProcessListFragment;
/**
*
* @author Eemil Lagerspetz
*
*/
public class MyDeviceFragment extends ExtendedTitleFragment {
private final MainActivity mMainActivity = CaratApplication.getMainActivity();
long[] lastPoint = null; // related to the CPU usage bar
AppDetailsFragment detailsFragment;
// private final String TAG = "mydeviceFragment"; // for logging (debugging)
/**
* Set up fragment and sub-screens. Transformations from Fragment
* to another should be handled at a higher level.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.mydevice, container, false);
handleClicks(rootView);
return rootView;
}
@Override
public void onResume() {
setTextViews();
setMemoryBars();
super.onResume();
}
/**
* Handle user clicks on different views (TextViews, little arrow ImageViews,
* and the memory and CPU usage bars)
* @param rootView The current fragment's view (inflated using a layout inflater)
*/
private void handleClicks(View rootView) {
handleJscoreClick(rootView);
handleBatteryLifeClick(rootView);
handleCaratIdClick(rootView);
handleMemoryInfoClick(rootView);
handleOsClick(rootView);
handleDeviceClick(rootView);
handleProcessesButtonClick(rootView);
}
private void setTextViews() {
setModelAndVersion();
setJscoreTextView();
setLastUpdateTimeTextView();
setCaratIdTextView();
setBatteryLifeTextView();
setCondensedFontForBatteryLife();
}
/**
* copy Carat ID when Carat ID is tapped
* @param rootView the current fragment's view (inflated using a layout inflater)
*/
private void handleCaratIdClick(View rootView) {
rootView.findViewById(R.id.carat_id).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
copyCaratId();
}
});
}
/**
* Show the list of currently running processes
* when the "view processes" button is clicked
* @param rootView the current fragment's view (inflated using a layout inflater)
*/
private void handleProcessesButtonClick(View rootView) {
rootView.findViewById(R.id.view_processes_button).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
ProcessListFragment fragment = ProcessListFragment.getInstance();
CaratApplication.getMainActivity().replaceFragment(fragment, getString(R.string.processlist), false);
}
});
}
/**
* show battery consumptions statistics of the current OS version
* (average battery consumption [expected value])
* @param rootView the current fragment's view (inflated using a layout inflater)
*/
private void handleOsClick(View rootView) {
rootView.findViewById(R.id.os_info).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
showOsInfo();
}
});
rootView.findViewById(R.id.os_version).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
showOsInfo();
}
});
}
/**
* show device energy stats (average battery lifetime) the views pertaining to the device are tapped
* @param rootView the current fragment's view (inflated using a layout inflater)
*/
private void handleDeviceClick(View rootView) {
rootView.findViewById(R.id.device_info).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
showDeviceInfo();
}
});
rootView.findViewById(R.id.device).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
showDeviceInfo();
}
});
}
/**
* display memory explanation info
* @param root the current fragment's view (inflated using a layout inflater)
*/
private void handleMemoryInfoClick(View root) {
Subscreen lis = new Subscreen("memoryinfo", getString(R.string.memoryinfo));
root.findViewById(R.id.memory_info).setOnClickListener(lis);
root.findViewById(R.id.memory_used_bar).setOnClickListener(lis);
root.findViewById(R.id.memory_active_bar).setOnClickListener(lis);
}
/**
* display battery life explanation info
* @param root the current fragment's view (inflated using a layout inflater)
*/
private void handleBatteryLifeClick(View root) {
Subscreen lis = new Subscreen("batterylifeinfo", getString(R.string.batterylifeinfo));
root.findViewById(R.id.battery_life_legend).setOnClickListener(lis);
root.findViewById(R.id.battery_life).setOnClickListener(lis);
root.findViewById(R.id.battery_life_info).setOnClickListener(lis);
}
/**
* display jscore explanation info
* @param root the current fragment's view (inflated using a layout inflater)
*/
private void handleJscoreClick(View root) {
Subscreen lis = new Subscreen("jscoreinfo", getString(R.string.jscoreinfo));
root.findViewById(R.id.jscore_info).setOnClickListener(lis);
root.findViewById(R.id.jscore).setOnClickListener(lis);
root.findViewById(R.id.jscore_legend).setOnClickListener(lis);
}
private class Subscreen implements OnClickListener{
private String screenName = null;
private String title = null;
public Subscreen(String screenName, String title) {
this.screenName = screenName;
this.title = title;
}
@Override
public void onClick(View v) {
mMainActivity.showHTMLFile(screenName, title, false);
}
}
private void setJscoreTextView() {
TextView jscoreValue = (TextView) getView().findViewById(R.id.jscore);
int jscore = CaratApplication.getJscore();
if (jscore == -1 || jscore == 0)
jscoreValue.setText("N/A");
else
jscoreValue.setText(Integer.toString(jscore));
}
private void setLastUpdateTimeTextView() {
long lastUpdateTime = CaratApplication.myDeviceData.getLastReportsTimeMillis();
long min = CaratApplication.myDeviceData.getFreshnessMinutes();
long hour = CaratApplication.myDeviceData.getFreshnessHours();
TextView lastUpdateTimeView = (TextView) getView().findViewById(R.id.updated);
Activity mainActivity = getActivity();
if (lastUpdateTime <= 0)
lastUpdateTimeView.setText(mainActivity.getString(R.string.neverupdated));
else if (min == 0)
lastUpdateTimeView.setText(mainActivity.getString(R.string.updatedjustnow));
else
lastUpdateTimeView.setText(mainActivity.getString(R.string.updated)
+ " " + hour + "h " + min + "m " + mainActivity.getString(R.string.ago));
}
private void setCaratIdTextView() {
String caratId = CaratApplication.myDeviceData.getCaratId();
TextView caratIdView = (TextView) getView().findViewById(R.id.carat_id);
caratIdView.setText(caratId);
}
private void setBatteryLifeTextView() {
String batteryLife = CaratApplication.myDeviceData.getBatteryLife();
TextView batteryLifeView = (TextView) getView().findViewById(R.id.battery_life);
batteryLifeView.setText(batteryLife);
}
/**
* show battery consumptions statistics of the current OS (and OS version) (average battery consumption [expected value])
*/
public void showOsInfo() {
detailsFragment = AppDetailsFragment.getInstance(Constants.Type.OS, null, false);
CaratApplication.getMainActivity().replaceFragment(detailsFragment, getString(R.string.osinfo), false);
}
/**
* show battery consumptions statistics of the current device (average battery consumption [expected value])
*/
public void showDeviceInfo() {
detailsFragment = AppDetailsFragment.getInstance(Constants.Type.MODEL, null, false);
CaratApplication.getMainActivity().replaceFragment(detailsFragment, getString(R.string.deviceinfo), false);
}
/**
* Set the device model and OS version text views
* @param root
*/
private void setModelAndVersion() {
// Device model
String model = SamplingLibrary.getModel();
// Android version
String version = SamplingLibrary.getOsVersion();
// The info icon needs to change from dark to light.
TextView mText = (TextView) getView().findViewById(R.id.device);
mText.setText(model);
mText = (TextView) getView().findViewById(R.id.os_version);
mText.setText(version);
}
/**
* Set memory values to the progress bar
*/
private void setMemoryBars() {
final Activity a = getActivity();
ProgressBar mText = (ProgressBar) a.findViewById(R.id.memory_used_bar);
int[] totalAndUsed = SamplingLibrary.readMeminfo();
mText.setMax(totalAndUsed[0] + totalAndUsed[1]);
mText.setProgress(totalAndUsed[0]);
mText = (ProgressBar) a.findViewById(R.id.memory_active_bar);
if (totalAndUsed.length > 2) {
mText.setMax(totalAndUsed[2] + totalAndUsed[3]);
mText.setProgress(totalAndUsed[2]);
}
getActivity().runOnUiThread(new Runnable() {
public void run() {
long[] currentPoint = SamplingLibrary.readUsagePoint();
double cpu = 0;
if (lastPoint == null)
lastPoint = currentPoint;
else
cpu = SamplingLibrary.getUsage(lastPoint, currentPoint);
/* CPU usage */
ProgressBar mText = (ProgressBar) a.findViewById(R.id.cpu_bar);
mText.setMax(100);
mText.setProgress((int) (cpu * 100));
}
});
}
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
public void copyCaratId() {
TextView tv = (TextView) getView().findViewById(R.id.carat_id);
String caratId = tv.getText().toString();
int sdk = android.os.Build.VERSION.SDK_INT;
// for Android API lower than 11
if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
android.text.ClipboardManager clipboard =
(android.text.ClipboardManager) getActivity()
.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(caratId);
} else {
// for Android API 11 and above
android.content.ClipboardManager clipboard =
(android.content.ClipboardManager) getActivity()
.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData
.newPlainText("Carat ID", caratId);
clipboard.setPrimaryClip(clip);
}
Toast.makeText(getActivity(), getString(R.string.copied) + " " + caratId,
Toast.LENGTH_LONG).show();
}
private void setCondensedFontForBatteryLife() {
Typeface face = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Roboto-Condensed.ttf");
TextView tv = (TextView) getActivity().findViewById(R.id.battery_life);
tv.setTypeface(face);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
}