<commit_before>package berlin.reiche.securitas.activies;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import berlin.reiche.securitas.Action;
import berlin.reiche.securitas.Client;
import berlin.reiche.securitas.ClientModel;
import berlin.reiche.securitas.ClientModel.State;
import berlin.reiche.securitas.Protocol;
import berlin.reiche.securitas.R;
import berlin.reiche.securitas.controller.ClientController;
import berlin.reiche.securitas.util.Settings;

import com.google.android.gcm.GCMRegistrar;

/**
 * Activity which is used to remote control the server and display snapshots.
 * This class implements the {@link Callback} interface in order to handle
 * requests sent from the controller.
 * 
 * @author <NAME>
 * 
 */
public class MainActivity extends Activity implements Callback {

	/**
	 * Tag for logging.
	 */
	private static String TAG = MainActivity.class.getSimpleName();

	/**
	 * This {@link ImageView} will display the latest snapshot or the snapshot
	 * that triggered an motion detection.
	 */
	public ImageView snapshot;

	/**
	 * The same button is used for starting and stopping the motion detection on
	 * the backend.
	 */
	public Button detectionToggle;

	/**
	 * A {@link TextView} to display some problems on the network layer.
	 */
	public TextView status;

	/**
	 * Separate layout for the layout.
	 */
	public RelativeLayout snapshotArea;

	/**
	 * Progress bar for displaying progress.
	 */
	public ProgressBar progress;

	/**
	 * Simply a headline.
	 */
	public TextView headline;

	/**
	 * Simply a subtitle to the headline.
	 */
	public TextView subtitle;

	/**
	 * Stores the settings used for building the connection.
	 */
	private SharedPreferences settings;

	/**
	 * The controller for handling user requests.
	 */
	private ClientController controller;

	/**
	 * The inbox handler takes requests and delegates them to the current
	 * controller state object.
	 */
	private Handler handler;

	/**
	 * Whether all components are initialized and can be referenced.
	 */
	private boolean initialized;

	/**
	 * This is an activity state variable used for saving and restoring the
	 * state without accessing the model.
	 */
	private boolean detecting;

	/**
	 * Called when the activity is first created.
	 * 
	 * @param savedInstanceState
	 *            If the activity is being re-initialized after previously being
	 *            shut down then this Bundle contains the data it most recently
	 *            supplied in onSaveInstanceState(Bundle). <b>Note: Otherwise it
	 *            is null.</b>
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.i(TAG, "onCreate");
		setContentView(R.layout.main);

		Client.setModel(new ClientModel());
		Client.setController(new ClientController(Client.getModel()));

		controller = Client.getController();
		controller.addOutboxHandler(new Handler(this));
		handler = controller.getInboxHandler();

		initialize();
		updateSettings();

		if (getLastNonConfigurationInstance() != null) {
			Bitmap bitmap = (Bitmap) getLastNonConfigurationInstance();
			snapshot.setImageBitmap(bitmap);
		}

		if (savedInstanceState != null) {
			Log.i(TAG, "Restore saved instance state");
			String stateKey = getString(R.string.is_detection_active_key);
			String snapshotKey = getString(R.string.snapshot_key);

			detecting = savedInstanceState.getBoolean(stateKey);
			Bitmap bitmap = savedInstanceState.getParcelable(snapshotKey);
			snapshot.setImageBitmap(bitmap);
		} else if (getIntent().getExtras() == null) {
			// maybe the user hit the *Back* button with the motion detection
			// still activate on the server, hence restore the state
			lockInterface();
			handler.sendEmptyMessage(Protocol.RESTORE_CLIENT_STATE.code);
			handler.sendEmptyMessage(Protocol.DOWNLOAD_LATEST_SNAPSHOT.code);
		} else {
			lockInterface();
			handler.sendEmptyMessage(Protocol.RESTORE_CLIENT_STATE.code);
			int what = Protocol.DOWNLOAD_MOTION_SNAPSHOT.code;
			String filename = getIntent().getExtras().getString("filename");
			Message message = Message.obtain(handler, what, filename);
			handler.sendMessage(message);
		}

	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		super.onRetainNonConfigurationInstance();
		return ((BitmapDrawable) snapshot.getDrawable()).getBitmap();
	}

	@Override
	protected void onDestroy() {
		try {
			Client.getController().dispose();
		} catch (Throwable t) {
			Log.e(TAG, "Failed to destroy the controller", t);
		} finally {
			super.onDestroy();
		}
	}

	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
		super.onSaveInstanceState(savedInstanceState);
		String stateKey = getString(R.string.is_detection_active_key);
		String snapshotKey = getString(R.string.snapshot_key);

		savedInstanceState.putBoolean(stateKey, detecting);
		if (snapshot.getDrawable() != null) {
			savedInstanceState.putParcelable(snapshotKey,
					((BitmapDrawable) snapshot.getDrawable()).getBitmap());
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		Log.i(TAG, "onResume");
		updateSettings();

		int orientation = getResources().getConfiguration().orientation;
		if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
			getWindow().setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN);
			LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT);

			snapshotArea.setLayoutParams(params);
			headline.setVisibility(View.GONE);
			subtitle.setVisibility(View.GONE);
		}

		boolean notification = getIntent().getExtras() != null;
		if (detecting) {
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
			detectionToggle.setText(R.string.button_stop_detection);
			detecting = true;
			if (!notification) {
				handler.sendEmptyMessage(Protocol.DOWNLOAD_LATEST_SNAPSHOT.code);
			}
		}

		if (notification) {
			String filename = getIntent().getExtras().getString("filename");
			int what = Protocol.DOWNLOAD_MOTION_SNAPSHOT.code;
			Message message = Message.obtain(handler, what, filename);
			handler.sendMessage(message);
		}
	}

	public void initialize() {
		if (!initialized) {
			snapshot = (ImageView) findViewById(R.id.snapshot);
			detectionToggle = (Button) findViewById(R.id.detection_toggle);
			status = (TextView) findViewById(R.id.errors);
			progress = (ProgressBar) findViewById(R.id.progress_bar);
			snapshotArea = (RelativeLayout) findViewById(R.id.snapshot_area);
			headline = (TextView) findViewById(R.id.headline);
			subtitle = (TextView) findViewById(R.id.subtitle);
			initialized = true;
		}
	}

	private void updateSettings() {
		settings = PreferenceManager.getDefaultSharedPreferences(this);
		String host = settings.getString(SettingsActivity.HOST, null);
		String port = settings.getString(SettingsActivity.PORT, null);
		String username = settings.getString(SettingsActivity.USER, null);
		String password = settings.getString(SettingsActivity.PASSWORD, null);
		String gcmSenderId = settings.getString(SettingsActivity.GCM_SENDER_ID,
				null);

		if (!isConfigured()) {
			startSettingsActivity(true);
		} else {
			Client.endpoint = "http://" + host + ":" + port;
			Client.settings = new Settings(host, port, username, password,
					gcmSenderId);
			Log.i(TAG, "Updated endpoint to " + Client.endpoint);
			manageDeviceRegistration();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.settings:
			startSettingsActivity(false);
			break;
		}
		return true;
	}

	private void startSettingsActivity(boolean forceConfiguration) {
		Intent intent = new Intent(this, SettingsActivity.class);
		intent.putExtra(SettingsActivity.DISPLAY_INSTRUCTION,
				forceConfiguration);
		startActivity(intent);
	}

	private boolean isConfigured() {
		settings = PreferenceManager.getDefaultSharedPreferences(this);
		String host = settings.getString(SettingsActivity.HOST, "");
		String port = settings.getString(SettingsActivity.PORT, "");
		String username = settings.getString(SettingsActivity.USER, "");
		String password = settings.getString(SettingsActivity.PASSWORD, "");
		String gcmSenderId = settings.getString(SettingsActivity.GCM_SENDER_ID,
				"");

		boolean configured = !host.equals("") && !port.equals("")
				&& !username.equals("") && !password.equals("")
				&& !gcmSenderId.equals("");<commit_msg>Start refactoring main activity<commit_after>package berlin.reiche.securitas.activies;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import berlin.reiche.securitas.Action;
import berlin.reiche.securitas.Client;
import berlin.reiche.securitas.ClientModel;
import berlin.reiche.securitas.ClientModel.State;
import berlin.reiche.securitas.Protocol;
import berlin.reiche.securitas.R;
import berlin.reiche.securitas.controller.ClientController;
import berlin.reiche.securitas.util.Settings;

import com.google.android.gcm.GCMRegistrar;

/**
 * Activity which is used to remote control the server and display snapshots.
 * This class implements the {@link Callback} interface in order to handle
 * requests sent from the controller.
 * 
 * @author <NAME>
 * 
 */
public class MainActivity extends Activity implements Callback {

	/**
	 * Tag for logging.
	 */
	private static String TAG = MainActivity.class.getSimpleName();

	/**
	 * This {@link ImageView} will display the latest snapshot or the snapshot
	 * that triggered an motion detection.
	 */
	public ImageView snapshot;

	/**
	 * The same button is used for starting and stopping the motion detection on
	 * the backend.
	 */
	public Button detectionToggle;

	/**
	 * A {@link TextView} to display some problems on the network layer.
	 */
	public TextView status;

	/**
	 * Separate layout for the layout.
	 */
	public RelativeLayout snapshotArea;

	/**
	 * Progress bar for displaying progress.
	 */
	public ProgressBar progress;

	/**
	 * Simply a headline.
	 */
	public TextView headline;

	/**
	 * Simply a subtitle to the headline.
	 */
	public TextView subtitle;

	/**
	 * The inbox handler takes requests and delegates them to the current
	 * controller state object.
	 */
	private Handler handler;

	/**
	 * Whether all components are initialized and can be referenced.
	 */
	private boolean initialized;

	/**
	 * This is an activity state variable used for saving and restoring the
	 * state without accessing the model.
	 */
	private boolean detecting;

	/**
	 * Called when the activity is first created.
	 * 
	 * @param savedInstanceState
	 *            If the activity is being re-initialized after previously being
	 *            shut down then this Bundle contains the data it most recently
	 *            supplied in onSaveInstanceState(Bundle). <b>Note: Otherwise it
	 *            is null.</b>
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.i(TAG, "onCreate");
		setContentView(R.layout.main);

		Client.setModel(new ClientModel());
		Client.setController(new ClientController(Client.getModel()));

		Client.getController().addOutboxHandler(new Handler(this));
		handler = Client.getController().getInboxHandler();

		initializeReferences();
		updateSettings();

		// restore image due to orientation change
		if (getLastNonConfigurationInstance() != null) {
			Bitmap bitmap = (Bitmap) getLastNonConfigurationInstance();
			snapshot.setImageBitmap(bitmap);
		}

		if (savedInstanceState != null) {
			// activity was put to the background, restore
			Log.i(TAG, "Restore saved instance state");
			String detectingKey = getString(R.string.is_detection_active_key);
			String snapshotKey = getString(R.string.snapshot_key);
			detecting = savedInstanceState.getBoolean(detectingKey);
			Bitmap bitmap = savedInstanceState.getParcelable(snapshotKey);
			snapshot.setImageBitmap(bitmap);
		} else if (getIntent().getExtras() == null) {
			// activity was destroyed, restore based on server state
			lockInterface();
			handler.sendEmptyMessage(Protocol.RESTORE_CLIENT_STATE.code);
			handler.sendEmptyMessage(Protocol.DOWNLOAD_LATEST_SNAPSHOT.code);
		} else {
			// activity was destroyed, activity started through notification
			lockInterface();
			handler.sendEmptyMessage(Protocol.RESTORE_CLIENT_STATE.code);
			int what = Protocol.DOWNLOAD_MOTION_SNAPSHOT.code;
			String filename = getIntent().getExtras().getString("filename");
			Message message = Message.obtain(handler, what, filename);
			handler.sendMessage(message);
		}
	}
	
	@Override
	public void onResume() {
		super.onResume();
		Log.i(TAG, "onResume");
		updateSettings();

		int orientation = getResources().getConfiguration().orientation;
		if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
			getWindow().setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN);
			LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT);

			snapshotArea.setLayoutParams(params);
			headline.setVisibility(View.GONE);
			subtitle.setVisibility(View.GONE);
		}

		boolean notification = getIntent().getExtras() != null;
		if (detecting) {
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
			detectionToggle.setText(R.string.button_stop_detection);
			detecting = true;
			if (!notification) {
				handler.sendEmptyMessage(Protocol.DOWNLOAD_LATEST_SNAPSHOT.code);
			}
		}

		if (notification) {
			String filename = getIntent().getExtras().getString("filename");
			int what = Protocol.DOWNLOAD_MOTION_SNAPSHOT.code;
			Message message = Message.obtain(handler, what, filename);
			handler.sendMessage(message);
		}
	}
	
	/**
	 * Disposes the controller so the handler looper is shut down. Makes sure
	 * that that this method does not fail and delegates to the super method.
	 * 
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	public void onDestroy() {
		try {
			Client.getController().dispose();
		} catch (Throwable t) {
			Log.e(TAG, "Failed to destroy the controller", t);
		} finally {
			super.onDestroy();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.settings:
			startSettingsActivity(false);
			break;
		}
		return true;
	}
	
	/**
	 * Saves all necessary information to restore the activity state.
	 * 
	 * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
	 */
	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
		super.onSaveInstanceState(savedInstanceState);
		String detectingKey = getString(R.string.is_detection_active_key);
		String snapshotKey = getString(R.string.snapshot_key);
		savedInstanceState.putBoolean(detectingKey, detecting);

		if (snapshot.getDrawable() != null) {
			savedInstanceState.putParcelable(snapshotKey,
					((BitmapDrawable) snapshot.getDrawable()).getBitmap());
		}
	}
	
	/**
	 * Called when the screen orientation changes and stores the image so it
	 * does not need to be retrieved once more.
	 * 
	 * @see android.app.Activity#onRetainNonConfigurationInstance()
	 */
	@Override
	public Object onRetainNonConfigurationInstance() {
		super.onRetainNonConfigurationInstance();
		return ((BitmapDrawable) snapshot.getDrawable()).getBitmap();
	}


	/**
	 * For a fast access of the components this method initializes all the
	 * references by finding their view elements through their IDs.
	 */
	public void initializeReferences() {
		if (!initialized) {
			snapshot = (ImageView) findViewById(R.id.snapshot);
			detectionToggle = (Button) findViewById(R.id.detection_toggle);
			status = (TextView) findViewById(R.id.errors);
			progress = (ProgressBar) findViewById(R.id.progress_bar);
			snapshotArea = (RelativeLayout) findViewById(R.id.snapshot_area);
			headline = (TextView) findViewById(R.id.headline);
			subtitle = (TextView) findViewById(R.id.subtitle);
			initialized = true;
		}
	}

	private void updateSettings() {
		SharedPreferences settings = PreferenceManager
				.getDefaultSharedPreferences(this);
		String host = settings.getString(SettingsActivity.HOST, null);
		String port = settings.getString(SettingsActivity.PORT, null);
		String username = settings.getString(SettingsActivity.USER, null);
		String password = settings.getString(SettingsActivity.PASSWORD, null);
		String gcmSenderId = settings.getString(SettingsActivity.GCM_SENDER_ID,
				null);

		if (!isConfigured()) {
			startSettingsActivity(true);
		} else {
			Client.endpoint = "http://" + host + ":" + port;
			Client.settings = new Settings(host, port, username, password,
					gcmSenderId);
			Log.i(TAG, "Updated endpoint to " + Client.endpoint);
			manageDeviceRegistration();
		}
	}

	private void startSettingsActivity(boolean forceConfiguration) {
		Intent intent = new Intent(this, SettingsActivity.class);
		intent.putExtra(SettingsActivity.DISPLAY_INSTRUCTION,
				forceConfiguration);
		startActivity(intent);
	}

	private boolean isConfigured() {
		SharedPreferences settings = PreferenceManager
				.getDefaultSharedPreferences(this);
		String host = settings.getString(SettingsActivity.HOST, "");
		String port = settings.getString(SettingsActivity.PORT, "");
		String username = settings.getString(SettingsActivity.USER, "");
		String password = settings.getString(SettingsActivity.PASSWORD, "");
		String gcmSenderId = settings.getString(SettingsActivity.GCM_SENDER_ID,
				"");

		boolean configured = !host.equals("") && !port.equals("")
				&& !username.equals("") && !password.equals("")
				&& !gcmSenderId.equals("");
{'fraction_non_alphanumeric': 0.10698812375758193, 'fraction_numerical': 0.0, 'mean_word_length': 4.6639722863741335, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '983435', 'n_tokens_mistral': 6122, 'n_tokens_neox': 5478, 'n_words': 1347}