package org.ovirt.mobile.movirt.ui.vms; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.support.v4.widget.SwipeRefreshLayout; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Click; import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.InstanceState; import org.androidannotations.annotations.ViewById; import org.ovirt.mobile.movirt.R; import org.ovirt.mobile.movirt.facade.ConsoleFacade; import org.ovirt.mobile.movirt.facade.HostFacade; import org.ovirt.mobile.movirt.facade.SnapshotFacade; import org.ovirt.mobile.movirt.facade.VmFacade; import org.ovirt.mobile.movirt.model.Cluster; import org.ovirt.mobile.movirt.model.Console; import org.ovirt.mobile.movirt.model.DataCenter; import org.ovirt.mobile.movirt.model.Host; import org.ovirt.mobile.movirt.model.Snapshot; import org.ovirt.mobile.movirt.model.Vm; import org.ovirt.mobile.movirt.model.enums.ConsoleProtocol; import org.ovirt.mobile.movirt.model.mapping.EntityMapper; import org.ovirt.mobile.movirt.provider.OVirtContract; import org.ovirt.mobile.movirt.provider.ProviderFacade; import org.ovirt.mobile.movirt.ui.ProgressBarResponse; import org.ovirt.mobile.movirt.ui.RefreshableLoaderFragment; import org.ovirt.mobile.movirt.util.usage.MemorySize; import org.springframework.util.StringUtils; import java.util.Iterator; import java.util.List; import java.util.SortedSet; @EFragment(R.layout.fragment_vm_detail_general) public class VmDetailGeneralFragment extends RefreshableLoaderFragment implements LoaderManager.LoaderCallbacks<Cursor> { private static final String TAG = VmDetailGeneralFragment.class.getSimpleName(); private static final int VMS_LOADER = 0; private static final int CLUSTER_LOADER = 1; private static final int DATA_CENTER_LOADER = 2; private static final int HOST_LOADER = 3; private static final int CONSOLES_LOADER = 4; private static final String VM_URI = "vm_uri"; private String vmId = null; @ViewById TextView statusView; @ViewById TextView cpuView; @ViewById TextView memView; @ViewById TextView memoryView; @ViewById TextView socketView; @ViewById TextView coreView; @ViewById TextView osView; @ViewById TextView displayView; @ViewById TextView displayLabel; @ViewById TextView clusterView; @ViewById TextView dataCenterView; @ViewById TextView hostLabel; @ViewById Button hostButton; Bundle args; @Bean ProviderFacade provider; @Bean VmFacade vmFacade; @Bean HostFacade hostFacade; @Bean SnapshotFacade snapshotFacade; @Bean ConsoleFacade consoleFacade; @InstanceState boolean isSnapshot; private Vm vm; private Host host; private Cluster cluster; private DataCenter dataCenter; @ViewById SwipeRefreshLayout swipeGeneralContainer; @AfterViews void initLoader() { hideProgressBar(); Uri vmUri = getActivity().getIntent().getData(); args = new Bundle(); args.putParcelable(VM_URI, vmUri); vmId = vmUri.getLastPathSegment(); renderSnapshotVm(); getLoaderManager().initLoader(VMS_LOADER, args, this); if (!isSnapshot) { renderDisplayView(""); getLoaderManager().initLoader(CONSOLES_LOADER, args, this); } } @Override public void restartLoader() { getLoaderManager().restartLoader(VMS_LOADER, args, this); if (!isSnapshot) { getLoaderManager().restartLoader(CONSOLES_LOADER, args, this); } } @Override public void destroyLoader() { getLoaderManager().destroyLoader(VMS_LOADER); getLoaderManager().destroyLoader(CLUSTER_LOADER); getLoaderManager().destroyLoader(DATA_CENTER_LOADER); if (!isSnapshot) { getLoaderManager().destroyLoader(HOST_LOADER); getLoaderManager().destroyLoader(CONSOLES_LOADER); } } @Override protected SwipeRefreshLayout getSwipeRefreshLayout() { return swipeGeneralContainer; } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Loader<Cursor> loader = null; switch (id) { case VMS_LOADER: String vmId = args.<Uri>getParcelable(VM_URI).getLastPathSegment(); loader = provider.query(Vm.class).id(vmId).asLoader(); break; case CLUSTER_LOADER: if (vm != null) { loader = provider.query(Cluster.class).id(vm.getClusterId()).asLoader(); } break; case DATA_CENTER_LOADER: if (cluster != null) { loader = provider.query(DataCenter.class).id(cluster.getDataCenterId()).asLoader(); } break; case HOST_LOADER: if (vm != null) { loader = provider.query(Host.class).id(vm.getHostId()).asLoader(); } break; case CONSOLES_LOADER: vmId = args.<Uri>getParcelable(VM_URI).getLastPathSegment(); loader = provider.query(Console.class).where(OVirtContract.Console.VM_ID, vmId).asLoader(); break; default: break; } return loader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (!data.moveToNext()) { if (loader.getId() == HOST_LOADER) { host = null; renderHost(host); } else { Log.e(TAG, "Error loading data: id=" + loader.getId()); } return; } switch (loader.getId()) { case VMS_LOADER: vm = vmFacade.mapFromCursor(data); renderVm(vm); if (getLoaderManager().getLoader(CLUSTER_LOADER) == null) { getLoaderManager().initLoader(CLUSTER_LOADER, null, this); } if (!isSnapshot && getLoaderManager().getLoader(HOST_LOADER) != null) { getLoaderManager().restartLoader(HOST_LOADER, null, this); } break; case CLUSTER_LOADER: cluster = EntityMapper.forEntity(Cluster.class).fromCursor(data); renderCluster(cluster); if (getLoaderManager().getLoader(DATA_CENTER_LOADER) == null) { getLoaderManager().initLoader(DATA_CENTER_LOADER, null, this); } break; case DATA_CENTER_LOADER: dataCenter = EntityMapper.forEntity(DataCenter.class).fromCursor(data); renderDataCenter(dataCenter); if (!isSnapshot && getLoaderManager().getLoader(HOST_LOADER) == null) { getLoaderManager().initLoader(HOST_LOADER, null, this); } break; case HOST_LOADER: host = hostFacade.mapFromCursor(data); renderHost(host); break; case CONSOLES_LOADER: // no consoles for snapshots, because they have different id SortedSet<ConsoleProtocol> protocols = ConsoleProtocol.getProtocolTypes(consoleFacade.mapAllFromCursor(data)); Iterator<ConsoleProtocol> it = protocols.iterator(); String displayTypes = ""; while (it.hasNext()) { displayTypes += it.next(); if (it.hasNext()) { displayTypes += " + "; } } renderDisplayView(displayTypes); break; default: break; } } @Override public void onLoaderReset(Loader<Cursor> loader) { // do nothing } public void setIsSnapshot(boolean isSnapshot) { this.isSnapshot = isSnapshot; } public void renderVm(Vm vm) { statusView.setText(vm.getStatus().toString().toLowerCase()); cpuView.setText(getString(R.string.percentage, vm.getCpuUsage())); memView.setText(getString(R.string.percentage, vm.getMemoryUsage())); long memory = vm.getMemorySize(); memoryView.setText((memory == -1) ? getString(R.string.NA) : new MemorySize(memory).toString()); socketView.setText(String.valueOf(vm.getSockets())); coreView.setText(String.valueOf(vm.getCoresPerSocket())); osView.setText(vm.getOsType()); } public void renderSnapshotVm() { if (isSnapshot) { displayView.setVisibility(View.GONE); displayLabel.setVisibility(View.GONE); hostButton.setVisibility(View.GONE); hostLabel.setVisibility(View.GONE); } } public void renderDisplayView(String displayTypes) { displayView.setText(StringUtils.isEmpty(displayTypes) ? getString(R.string.NA) : displayTypes); } public void renderHost(Host host) { if (host != null) { hostButton.setText(host.getName()); hostButton.setEnabled(true); } else { hostButton.setText(getString(R.string.NA)); hostButton.setEnabled(false); } } public void renderCluster(Cluster cluster) { clusterView.setText(getString(R.string.two_separated_strings, cluster.getName(), cluster.getVersion())); } public void renderDataCenter(DataCenter dataCenter) { dataCenterView.setText(getString(R.string.two_separated_strings, dataCenter.getName(), dataCenter.getVersion())); } @Click(R.id.hostButton) void btnHost() { if (host != null) { startActivity(hostFacade.getDetailIntent(host, getActivity())); } } @Override @Background public void onRefresh() { // a hack because of https://bugzilla.redhat.com/1348138 - e.g. if we don't know the // type we don't know if to show this details. But better than completely disable this feature it // is better to show the tab always and just don't fail on NPE here. if (vm == null) { hideProgressBar(); return; } if (vm.isSnapshotEmbedded()) { String snapshotId = vm.getSnapshotId(); String vmId = provider.query(Snapshot.class).id(snapshotId).first().getVmId(); snapshotFacade.syncOne(new ProgressBarResponse<Snapshot>(this), snapshotId, vmId); } else { vmFacade.syncOne(new ProgressBarResponse<Vm>(this), vmId); consoleFacade.syncAll(new ProgressBarResponse<List<Console>>(this), vmId); } } }