package org.ovirt.mobile.movirt.ui.snapshots; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.support.annotation.NonNull; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.ProgressBar; import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.InstanceState; import org.androidannotations.annotations.OptionsItem; import org.androidannotations.annotations.OptionsMenu; import org.androidannotations.annotations.OptionsMenuItem; import org.androidannotations.annotations.Receiver; import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.res.StringArrayRes; import org.androidannotations.annotations.res.StringRes; import org.ovirt.mobile.movirt.Broadcasts; import org.ovirt.mobile.movirt.R; import org.ovirt.mobile.movirt.facade.SnapshotFacade; import org.ovirt.mobile.movirt.facade.VmFacade; import org.ovirt.mobile.movirt.model.Snapshot; import org.ovirt.mobile.movirt.model.Vm; import org.ovirt.mobile.movirt.provider.OVirtContract; import org.ovirt.mobile.movirt.provider.ProviderFacade; import org.ovirt.mobile.movirt.rest.SimpleResponse; import org.ovirt.mobile.movirt.rest.client.OVirtClient; import org.ovirt.mobile.movirt.rest.dto.SnapshotAction; import org.ovirt.mobile.movirt.ui.BooleanListener; import org.ovirt.mobile.movirt.ui.FragmentListPagerAdapter; import org.ovirt.mobile.movirt.ui.HasProgressBar; import org.ovirt.mobile.movirt.ui.MovirtActivity; import org.ovirt.mobile.movirt.ui.dialogs.ConfirmDialogFragment; import org.ovirt.mobile.movirt.ui.dialogs.PreviewRestoreSnapshotDialogFragment; import org.ovirt.mobile.movirt.ui.vms.VmDetailGeneralFragment; import org.ovirt.mobile.movirt.ui.vms.VmDetailGeneralFragment_; import java.util.Collection; import static org.springframework.util.StringUtils.isEmpty; @EActivity(R.layout.activity_snapshot_detail) @OptionsMenu(R.menu.snapshot) public class SnapshotDetailActivity extends MovirtActivity implements HasProgressBar, LoaderManager.LoaderCallbacks<Cursor>, ConfirmDialogFragment.ConfirmDialogListener, BooleanListener { private static final String TAG = SnapshotDetailActivity.class.getSimpleName(); private static final int DELETE_ACTION = 0; private static final int PREVIEW_ACTION = 1; private static final int RESTORE_ACTION = 2; private static final int SNAPSHOT_LOADER = 1; // 0 in MovirtActivity private static final int SNAPSHOTS_LOADER = 2; private static final int VMS_LOADER = 3; @ViewById ViewPager viewPager; @ViewById PagerTabStrip pagerTabStrip; @StringArrayRes(R.array.snapshot_detail_pager_titles) String[] PAGER_TITLES; @ViewById ProgressBar progress; @StringRes(R.string.details_for_snapshot) String SNAPSHOT_DETAILS; @Bean ProviderFacade provider; @Bean VmFacade vmFacade; @Bean SnapshotFacade snapshotFacade; @Bean OVirtClient client; @OptionsMenuItem(R.id.action_delete) MenuItem menuDelete; @OptionsMenuItem(R.id.action_preview) MenuItem menuPreview; @OptionsMenuItem(R.id.action_restore) MenuItem menuRestore; @OptionsMenuItem(R.id.action_commit) MenuItem menuCommit; @OptionsMenuItem(R.id.action_undo) MenuItem menuUndo; @InstanceState protected String snapshotId; @InstanceState protected String vmId; private Snapshot currentSnapshot; private Vm vm; private Collection<Snapshot> snapshots; @AfterViews public void init() { if (isEmpty(snapshotId) && isEmpty(vmId)) { Intent intent = getIntent(); Uri snapshotUri = intent.getData(); snapshotId = snapshotUri.getLastPathSegment(); vmId = intent.getExtras().getString(OVirtContract.HasVm.VM_ID); // for vm fragment Uri vmUri = OVirtContract.Vm.CONTENT_URI.buildUpon().appendPath(vmId + snapshotId).build(); intent.setData(vmUri); } initLoaders(); initPagers(); setProgressBar(progress); } private void initLoaders() { getSupportLoaderManager().initLoader(SNAPSHOT_LOADER, null, this); getSupportLoaderManager().initLoader(SNAPSHOTS_LOADER, null, this); getSupportLoaderManager().initLoader(VMS_LOADER, null, this); } @Override public void restartLoader() { super.restartLoader(); getSupportLoaderManager().restartLoader(SNAPSHOT_LOADER, null, this); getSupportLoaderManager().restartLoader(SNAPSHOTS_LOADER, null, this); getSupportLoaderManager().restartLoader(VMS_LOADER, null, this); } @Override public void destroyLoader() { super.destroyLoader(); getSupportLoaderManager().destroyLoader(SNAPSHOT_LOADER); getSupportLoaderManager().destroyLoader(SNAPSHOTS_LOADER); getSupportLoaderManager().destroyLoader(VMS_LOADER); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Loader<Cursor> loader = null; switch (id) { case SNAPSHOT_LOADER: loader = provider.query(Snapshot.class).id(snapshotId).asLoader(); break; case SNAPSHOTS_LOADER: loader = provider.query(Snapshot.class).where(OVirtContract.Snapshot.VM_ID, vmId).asLoader(); break; case VMS_LOADER: loader = provider.query(Vm.class).id(vmId).asLoader(); break; } return loader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (!data.moveToNext()) { Log.e(TAG, "Error loading Snapshot"); return; } switch (loader.getId()) { case SNAPSHOT_LOADER: currentSnapshot = snapshotFacade.mapFromCursor(data); setTitle(String.format(SNAPSHOT_DETAILS, currentSnapshot.getName())); break; case SNAPSHOTS_LOADER: snapshots = snapshotFacade.mapAllFromCursor(data); break; case VMS_LOADER: vm = vmFacade.mapFromCursor(data); break; } invalidateOptionsMenu(); } @Override public void onLoaderReset(Loader<Cursor> loader) { // do nothing } private void initPagers() { VmDetailGeneralFragment vmDetailFragment = new VmDetailGeneralFragment_(); SnapshotDisksFragment diskList = new SnapshotDisksFragment_(); SnapshotNicsFragment nicList = new SnapshotNicsFragment_(); vmDetailFragment.setIsSnapshot(true); diskList.setVmId(vmId); diskList.setSnapshotId(snapshotId); nicList.setVmId(vmId); nicList.setSnapshotId(snapshotId); FragmentListPagerAdapter pagerAdapter = new FragmentListPagerAdapter( getSupportFragmentManager(), PAGER_TITLES, vmDetailFragment, diskList, nicList ); viewPager.setAdapter(pagerAdapter); pagerTabStrip.setTabIndicatorColorResource(R.color.material_deep_teal_200); } @Override public boolean onPrepareOptionsMenu(Menu menu) { if (currentSnapshot != null && snapshots != null) { boolean allOk = !Snapshot.containsOneOfStatuses(snapshots, Snapshot.SnapshotStatus.LOCKED, Snapshot.SnapshotStatus.IN_PREVIEW); if (vm != null && Vm.Command.NOT_RUNNING.canExecute(vm.getStatus())) { boolean commitUndoVisible = Snapshot.SnapshotStatus.IN_PREVIEW.equals(currentSnapshot.getSnapshotStatus()); menuPreview.setVisible(allOk); menuRestore.setVisible(allOk); menuCommit.setVisible(commitUndoVisible); menuUndo.setVisible(commitUndoVisible); } menuDelete.setVisible(allOk); } return super.onPrepareOptionsMenu(menu); } @OptionsItem(R.id.action_delete) void delete() { ConfirmDialogFragment confirmDialog = ConfirmDialogFragment .newInstance(DELETE_ACTION, getString(R.string.dialog_action_delete_snapshot)); confirmDialog.show(getFragmentManager(), "confirmDeleteSnapshot"); } @OptionsItem(R.id.action_preview) public void preview() { if (currentSnapshot.getPersistMemorystate()) { PreviewRestoreSnapshotDialogFragment dialog = PreviewRestoreSnapshotDialogFragment .newInstance(PREVIEW_ACTION, getString(R.string.preview)); dialog.show(getFragmentManager(), "previewSnapshot"); } else { doPreviewSnapshot(false); } } @OptionsItem(R.id.action_restore) public void restore() { if (currentSnapshot.getPersistMemorystate()) { PreviewRestoreSnapshotDialogFragment dialog = PreviewRestoreSnapshotDialogFragment .newInstance(RESTORE_ACTION, getString(R.string.restore)); dialog.show(getFragmentManager(), "restoreSnapshot"); } else { doRestoreSnapshot(false); } } @OptionsItem(R.id.action_commit) @Background public void doCommit() { client.commitSnapshot(vmId, getSyncSnapshotsResponse()); } @OptionsItem(R.id.action_undo) @Background public void doUndo() { client.undoSnapshot(vmId, getSyncSnapshotsResponse()); } @Override public void onDialogResult(int dialogButton, int actionId) { if (actionId == DELETE_ACTION && dialogButton == DialogInterface.BUTTON_POSITIVE) { doDelete(); } } @Override public void onDialogResult(int actionId, boolean restoreMemory) { switch (actionId) { case PREVIEW_ACTION: doPreviewSnapshot(restoreMemory); break; case RESTORE_ACTION: doRestoreSnapshot(restoreMemory); break; } } @Background public void doDelete() { client.deleteSnapshot(vmId, snapshotId, new SimpleResponse<Void>() { @Override public void onResponse(Void aVoid) throws RemoteException { snapshotFacade.syncAll(vmId); if (vm != null) { startActivity(vmFacade.getDetailIntent(vm, getApplicationContext())); } } }); } @Background public void doPreviewSnapshot(boolean restoreMemory) { SnapshotAction action = new SnapshotAction(snapshotId, restoreMemory); client.previewSnapshot(action, vmId, getSyncSnapshotsResponse()); } @Background public void doRestoreSnapshot(boolean restoreMemory) { SnapshotAction action = new SnapshotAction(snapshotId, restoreMemory); client.restoreSnapshot(action, vmId, getSyncSnapshotsResponse()); } @Background @Receiver(actions = Broadcasts.IN_SYNC, registerAt = Receiver.RegisterAt.OnResumeOnPause) public void syncing(@Receiver.Extra(Broadcasts.Extras.SYNCING) boolean syncing) { if (syncing) { syncSnapshots(); } } @NonNull private SimpleResponse<Void> getSyncSnapshotsResponse() { return new SimpleResponse<Void>() { @Override public void onResponse(Void aVoid) throws RemoteException { syncSnapshots(); } }; } private void syncSnapshots() { snapshotFacade.syncAll(vmId); } }