package com.kedzie.vbox.machine; import java.io.IOException; import java.util.List; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.NetworkOnMainThreadException; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.actionbarsherlock.app.SherlockFragment; import com.kedzie.vbox.R; import com.kedzie.vbox.api.IMachine; import com.kedzie.vbox.api.INetworkAdapter; import com.kedzie.vbox.api.IStorageController; import com.kedzie.vbox.api.IVRDEServer; import com.kedzie.vbox.api.jaxb.CPUPropertyType; import com.kedzie.vbox.api.jaxb.DeviceType; import com.kedzie.vbox.api.jaxb.HWVirtExPropertyType; import com.kedzie.vbox.api.jaxb.IMediumAttachment; import com.kedzie.vbox.api.jaxb.MachineState; import com.kedzie.vbox.api.jaxb.NetworkAttachmentType; import com.kedzie.vbox.api.jaxb.StorageBus; import com.kedzie.vbox.api.jaxb.VBoxEventType; import com.kedzie.vbox.app.BundleBuilder; import com.kedzie.vbox.app.CollapsiblePanelView; import com.kedzie.vbox.app.Utils; import com.kedzie.vbox.machine.group.GroupInfoFragment.MachineInfo; import com.kedzie.vbox.task.ActionBarTask; import com.kedzie.vbox.task.MachineRunnable; /** * * @apiviz.stereotype fragment */ public class InfoFragment extends SherlockFragment { private static final String TAG = "InfoFragment"; class LoadInfoTask extends ActionBarTask<IMachine, MachineInfo> { public LoadInfoTask() { super(getSherlockActivity(), _machine.getAPI()); } @Override protected MachineInfo work(IMachine... m) throws Exception { //cache values Utils.cacheProperties(m[0]); fork(new MachineRunnable(m[0]) { public void run() { m.getMemorySize(); m.getCPUCount(); m.getVRAMSize(); m.getAccelerate2DVideoEnabled(); m.getAccelerate3DEnabled(); m.getDescription(); m.getGroups(); m.getHWVirtExProperty(HWVirtExPropertyType.NESTED_PAGING); m.getHWVirtExProperty(HWVirtExPropertyType.ENABLED); m.getCPUProperty(CPUPropertyType.PAE); } }); fork(new MachineRunnable(m[0]) { public void run() { //audio m.getAudioAdapter().getAudioController(); m.getAudioAdapter().getAudioDriver(); //boot order for(int i=1 ;i<=99; i++) if(m.getBootOrder(i).equals(DeviceType.NULL)) break; //Remote Desktop m.getVRDEServer().getVRDEProperty(IVRDEServer.PROPERTY_PORT); } }); fork(new MachineRunnable(m[0]) { public void run() { //storage controllers List<IStorageController> controllers = m.getStorageControllers(); for(IStorageController controller : controllers) { controller.getBus(); for(IMediumAttachment a : m.getMediumAttachmentsOfController(controller.getName())) { if(a.getMedium()!=null) { a.getMedium().getName(); a.getMedium().getBase().getName(); } } } } }); fork(new MachineRunnable(m[0]) { public void run() { //network adapters for(int i=0; i<4; i++) { INetworkAdapter adapter = m.getNetworkAdapter(i); adapter.getEnabled(); adapter.getAdapterType(); adapter.getAttachmentType(); adapter.getBridgedInterface(); adapter.getHostOnlyInterface(); adapter.getGenericDriver(); adapter.getInternalNetwork(); } } }); //screenshots int size = getResources().getDimensionPixelSize(R.dimen.screenshot_size); MachineInfo info = new MachineInfo(m[0], null); if(m[0].getState().equals(MachineState.SAVED)) { info.screenshot = _vmgr.readSavedScreenshot(m[0], 0); info.screenshot.scaleBitmap(size, size); } else if(m[0].getState().equals(MachineState.RUNNING)) { try { info.screenshot = m[0].getAPI().takeScreenshot(m[0], size, size); } catch(IOException e) { Log.e(TAG, "Exception taking screenshot", e); } } join(); return info; } @Override protected void onSuccess(MachineInfo result) { _machineInfo = result; populateViews(); } } // private VBoxSvc _vmgr; private IMachine _machine; private MachineInfo _machineInfo; private View _view; private TextView _nameText; private TextView _descriptionText; private TextView _groupText; private TextView _osTypeText; private TextView _baseMemoryText; private TextView _processorsText; private TextView _bootOrderText; private TextView _accelerationText; private TextView _videoMemoryText; private TextView _accelerationVideoText; private TextView _rdpPortText; private TextView _storageText; private TextView _networkText; private TextView _audioDriver; private TextView _audioController; private CollapsiblePanelView _previewPanel; private ImageView _preview; private LocalBroadcastManager lbm; /** Event-handling local broadcasts */ private BroadcastReceiver _receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(VBoxEventType.ON_MACHINE_STATE_CHANGED.name())) { IMachine m = BundleBuilder.getProxy(intent.getExtras(), IMachine.BUNDLE, IMachine.class); new LoadInfoTask().execute(m); } } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); if(savedInstanceState!=null) { _machineInfo = savedInstanceState.getParcelable("info"); } _machine = BundleBuilder.getProxy(getArguments(), IMachine.BUNDLE, IMachine.class); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { _view = inflater.inflate(R.layout.machine_info, null); _nameText = (TextView)_view.findViewById(R.id.name); _descriptionText = (TextView)_view.findViewById(R.id.description); _groupText = (TextView)_view.findViewById(R.id.groups); _osTypeText = (TextView)_view.findViewById(R.id.ostype); _baseMemoryText = (TextView)_view.findViewById(R.id.baseMemory); _processorsText = (TextView)_view.findViewById(R.id.processors); _bootOrderText = (TextView)_view.findViewById(R.id.bootOrder); _accelerationText = (TextView)_view.findViewById(R.id.acceleration); _videoMemoryText = (TextView)_view.findViewById(R.id.videoMemory); _accelerationVideoText = (TextView)_view.findViewById(R.id.accelerationVideo); _storageText = (TextView)_view.findViewById(R.id.storage); _networkText = (TextView)_view.findViewById(R.id.network); _audioDriver = (TextView)_view.findViewById(R.id.audio_driver); _audioController = (TextView)_view.findViewById(R.id.audio_controlller); _rdpPortText = (TextView)_view.findViewById(R.id.rdpPort); _preview = (ImageView)_view.findViewById(R.id.preview); _previewPanel =(CollapsiblePanelView)_view.findViewById(R.id.previewPanel); return _view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); lbm = LocalBroadcastManager.getInstance(getActivity().getApplicationContext()); } @Override public void onStart() { super.onStart(); lbm.registerReceiver(_receiver, Utils.createIntentFilter(VBoxEventType.ON_MACHINE_STATE_CHANGED.name())); if(_machineInfo!=null) safePopulate(); else new LoadInfoTask().execute(_machine); } @Override public void onStop() { lbm.unregisterReceiver(_receiver); super.onStop(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable("info", _machineInfo); } private void safePopulate() { try { populateViews(); } catch(NetworkOnMainThreadException e) { Log.e(TAG, "Populate error", e); new LoadInfoTask().execute(_machine); } } private void populateViews() { IMachine m = _machineInfo.machine; _nameText.setText( m.getName()); _osTypeText.setText( m.getOSTypeId() ); if(!Utils.isEmpty(m.getGroups())) _groupText.setText(m.getGroups().get(0)); else _groupText.setText("None"); _baseMemoryText.setText( m.getMemorySize()+"" ); _processorsText.setText( m.getCPUCount()+"" ); //boot order StringBuffer bootOrder = new StringBuffer(); for(int i=1; i<=99; i++) { DeviceType b = m.getBootOrder(i); if(b.equals(DeviceType.NULL)) break; Utils.appendWithComma(bootOrder, b.toString()); } _bootOrderText.setText( bootOrder.toString() ); StringBuffer acceleration = new StringBuffer(); if(m.getHWVirtExProperty(HWVirtExPropertyType.ENABLED)) Utils.appendWithComma(acceleration, "VT-x/AMD-V"); if(m.getHWVirtExProperty(HWVirtExPropertyType.NESTED_PAGING)) Utils.appendWithComma(acceleration, "Nested Paging"); if(m.getCPUProperty(CPUPropertyType.PAE)) Utils.appendWithComma(acceleration, "PAE/NX"); _accelerationText.setText(acceleration.toString()); //storage controllers StringBuffer storage = new StringBuffer(); List<IStorageController> controllers = m.getStorageControllers(); for(IStorageController controller : controllers) { storage.append("Controller: ").append(controller.getName()).append("\n"); if(controller.getBus().equals(StorageBus.SATA)) { for(IMediumAttachment a : m.getMediumAttachmentsOfController(controller.getName())) storage.append(String.format("SATA Port %1$d\t\t%2$s\n", a.getPort(), a.getMedium()==null ? "" : a.getMedium().getBase().getName())); } else if (controller.getBus().equals(StorageBus.IDE)){ for(IMediumAttachment a : m.getMediumAttachmentsOfController(controller.getName())) { storage.append(String.format("IDE %1$s %2$s\t\t%3$s\n", a.getPort()==0 ? "Primary" : "Secondary", a.getDevice()==0 ? "Master" : "Slave", a.getMedium()==null ? "" : a.getMedium().getBase().getName())); } } else { for(IMediumAttachment a : m.getMediumAttachmentsOfController(controller.getName())) storage.append(String.format("Port: %1$d Device: %2$d\t\t%3$s\n", a.getPort(), a.getDevice(), a.getMedium()==null ? "" : a.getMedium().getBase().getName())); } } _storageText.setText(storage.toString()); //audio devices _audioController.setText(m.getAudioAdapter().getAudioController().toString()); _audioDriver.setText(m.getAudioAdapter().getAudioDriver().toString()); //network devices StringBuffer networkText = new StringBuffer(); for(int i=0; i<4; i++) { INetworkAdapter adapter = m.getNetworkAdapter(i); if(!adapter.getEnabled()) continue; if(i>0) networkText.append("\n"); networkText.append("Adapter ").append(i+1).append(": ").append(adapter.getAdapterType()); NetworkAttachmentType type = adapter.getAttachmentType(); Log.v(TAG, "Adapter #" + (i+1) + " attachment Type: " + type); if(type.equals(NetworkAttachmentType.BRIDGED)) networkText.append(" (Bridged Adapter, ").append(adapter.getBridgedInterface()).append(")"); else if(type.equals(NetworkAttachmentType.BRIDGED)) networkText.append(" (Host-Only Adapter, ").append(adapter.getHostOnlyInterface()).append(")"); else if(type.equals(NetworkAttachmentType.GENERIC)) networkText.append(" (Generic-Driver Adapter, ").append(adapter.getGenericDriver()).append(")"); else if(type.equals(NetworkAttachmentType.INTERNAL)) networkText.append(" (Internal-Network Adapter, ").append(adapter.getInternalNetwork()).append(")"); } _networkText.setText(networkText.toString()); _videoMemoryText.setText( m.getVRAMSize()+" MB"); _accelerationVideoText.setText( (m.getAccelerate2DVideoEnabled() ? "2D" : "") + " " + (m.getAccelerate3DEnabled() ? "3D" : "") ); _rdpPortText.setText(m.getVRDEServer().getVRDEProperty(IVRDEServer.PROPERTY_PORT)); _descriptionText.setText( m.getDescription()+"" ); if(_machineInfo.screenshot!=null) { _preview.setImageBitmap(_machineInfo.screenshot.getBitmap()); _preview.setAdjustViewBounds(true); _preview.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); _previewPanel.expand(); } else _previewPanel.collapse(); } @Override public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) { switch(item.getItemId()) { case R.id.option_menu_refresh: Log.i(TAG, "Refreshing..."); new LoadInfoTask().execute(_machine); return true; } return false; } }