MainActivity.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. package de.tudarmstadt.informatik.hostage.ui.activity;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import android.app.ActionBar;
  6. import android.app.Activity;
  7. import android.app.ActivityManager;
  8. import android.app.Fragment;
  9. import android.app.FragmentManager;
  10. import android.app.FragmentTransaction;
  11. import android.content.BroadcastReceiver;
  12. import android.content.ComponentName;
  13. import android.content.Context;
  14. import android.content.Intent;
  15. import android.content.IntentFilter;
  16. import android.content.ServiceConnection;
  17. import android.content.pm.ActivityInfo;
  18. import android.content.res.Configuration;
  19. import android.content.res.TypedArray;
  20. import android.os.Bundle;
  21. import android.os.IBinder;
  22. import android.support.v4.app.ActionBarDrawerToggle;
  23. import android.support.v4.content.LocalBroadcastManager;
  24. import android.support.v4.widget.DrawerLayout;
  25. import android.util.Log;
  26. import android.view.Gravity;
  27. import android.view.KeyEvent;
  28. import android.view.MenuItem;
  29. import android.view.View;
  30. import android.widget.AdapterView;
  31. import android.widget.ListView;
  32. import android.widget.Toast;
  33. import de.tudarmstadt.informatik.hostage.Hostage;
  34. import de.tudarmstadt.informatik.hostage.R;
  35. import de.tudarmstadt.informatik.hostage.model.Profile;
  36. import de.tudarmstadt.informatik.hostage.persistence.ProfileManager;
  37. import de.tudarmstadt.informatik.hostage.ui.LogFilter;
  38. import de.tudarmstadt.informatik.hostage.ui.adapter.DrawerListAdapter;
  39. import de.tudarmstadt.informatik.hostage.ui.fragment.AboutFragment;
  40. import de.tudarmstadt.informatik.hostage.ui.fragment.HomeFragment;
  41. import de.tudarmstadt.informatik.hostage.ui.fragment.ProfileManagerFragment;
  42. import de.tudarmstadt.informatik.hostage.ui.fragment.RecordOverviewFragment;
  43. import de.tudarmstadt.informatik.hostage.ui.fragment.ServicesFragment;
  44. import de.tudarmstadt.informatik.hostage.ui.fragment.SettingsFragment;
  45. import de.tudarmstadt.informatik.hostage.ui.fragment.StatisticsFragment;
  46. import de.tudarmstadt.informatik.hostage.ui.fragment.ThreatMapFragment;
  47. import de.tudarmstadt.informatik.hostage.ui.fragment.UpNavigatibleFragment;
  48. import de.tudarmstadt.informatik.hostage.ui.fragment.opengl.ThreatIndicatorGLRenderer;
  49. import de.tudarmstadt.informatik.hostage.ui.model.DrawerListItem;
  50. /**
  51. * @author Alexander Brakowski
  52. * @created 12.01.14 23:24
  53. */
  54. public class MainActivity extends Activity {
  55. public static volatile Context context;
  56. /** singleton instance of the MainActivity **/
  57. private static MainActivity sInstance = null;
  58. public Fragment mDisplayedFragment;
  59. public Hostage mHoneyService;
  60. private DrawerLayout mDrawerLayout;
  61. private ListView mDrawerList;
  62. private ActionBarDrawerToggle mDrawerToggle;
  63. private CharSequence mDrawerTitle;
  64. private CharSequence mTitle;
  65. private MainMenuItem mSelectedMenuItem = null;
  66. private ArrayList<DrawerListItem> mDrawerItems;
  67. private boolean mServiceBound = false;
  68. private ProfileManager mProfileManager;
  69. private Fragment rootFragment;
  70. /**
  71. * Connection to bind the background service
  72. *
  73. * @see de.tudarmstadt.informatik.hostage.Hostage
  74. */
  75. private ServiceConnection mConnection = new ServiceConnection() {
  76. /**
  77. * After the service is bound, check which has been clicked and start
  78. * it.
  79. *
  80. * @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName,
  81. * android.os.IBinder)
  82. */
  83. @Override
  84. public void onServiceConnected(ComponentName name, IBinder service) {
  85. mHoneyService = ((Hostage.LocalBinder) service).getService();
  86. mServiceBound = true;
  87. }
  88. /**
  89. * After the service is unbound, delete reference.
  90. *
  91. * @see android.content.ServiceConnection#onServiceDisconnected(android.content.ComponentName)
  92. */
  93. @Override
  94. public void onServiceDisconnected(ComponentName name) {
  95. mHoneyService = null;
  96. mServiceBound = false;
  97. }
  98. };
  99. private HashMap<String, Boolean> mAttacksOnProtocol = new HashMap<String, Boolean>();
  100. private boolean mCloseWarning = false;
  101. /**
  102. * Retrieve the singleton latest instance of the activity
  103. *
  104. * @return MainActivity - the singleton instance
  105. */
  106. public static MainActivity getInstance() {
  107. assert (sInstance != null);
  108. return sInstance;
  109. }
  110. public static Context getContext() {
  111. return MainActivity.context;
  112. }
  113. @Override
  114. public void onStart() {
  115. super.onStart();
  116. registerReceiver();
  117. if (isServiceRunning()) {
  118. this.bindService();
  119. }
  120. }
  121. @Override
  122. public void onStop() {
  123. this.unbindService();
  124. super.onStop();
  125. }
  126. @Override
  127. protected void onCreate(Bundle savedInstanceState) {
  128. super.onCreate(savedInstanceState);
  129. sInstance = this;
  130. MainActivity.context = getApplicationContext();
  131. setContentView(R.layout.activity_drawer_main);
  132. mProfileManager = ProfileManager.getInstance();
  133. ThreatIndicatorGLRenderer.assets = getAssets();
  134. ThreatIndicatorGLRenderer.setThreatLevel(ThreatIndicatorGLRenderer.ThreatLevel.NOT_MONITORING);
  135. // set background color
  136. TypedArray arr = getTheme().obtainStyledAttributes(new int[] { android.R.color.background_light });
  137. ThreatIndicatorGLRenderer.setBackgroundColor(arr.getColor(0, 0xFFFFFF));
  138. arr.recycle();
  139. ActionBar actionBar = getActionBar();
  140. actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP);
  141. mTitle = mDrawerTitle = getTitle();
  142. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
  143. mDrawerList = (ListView) findViewById(R.id.left_drawer);
  144. mDrawerItems = new ArrayList<DrawerListItem>();
  145. mDrawerItems.add(new DrawerListItem(R.string.drawer_overview, R.drawable.ic_menu_home));
  146. mDrawerItems.add(new DrawerListItem(R.string.drawer_threat_map, R.drawable.ic_menu_mapmode));
  147. mDrawerItems.add(new DrawerListItem(R.string.drawer_records, R.drawable.ic_menu_records));
  148. mDrawerItems.add(new DrawerListItem(R.string.drawer_statistics, R.drawable.ic_menu_stats));
  149. mDrawerItems.add(new DrawerListItem(R.string.drawer_services, R.drawable.ic_menu_set_as));
  150. mDrawerItems.add(new DrawerListItem(R.string.drawer_profile_manager, R.drawable.ic_menu_allfriends));
  151. mDrawerItems.add(new DrawerListItem(R.string.drawer_settings, R.drawable.ic_menu_preferences));
  152. mDrawerItems.add(new DrawerListItem(R.string.drawer_app_info, R.drawable.ic_menu_info_details));
  153. DrawerListAdapter listAdapter = new DrawerListAdapter(this, mDrawerItems);
  154. mDrawerList.setAdapter(listAdapter);
  155. mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
  156. getActionBar().setDisplayHomeAsUpEnabled(true);
  157. getActionBar().setHomeButtonEnabled(true);
  158. getActionBar().setDisplayShowHomeEnabled(true);
  159. mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
  160. mDrawerLayout, /* DrawerLayout object */
  161. R.drawable.ic_navigation_drawer, /*
  162. * nav drawer image to replace 'Up'
  163. * caret
  164. */
  165. R.string.drawer_open, /* "open drawer" description for accessibility */
  166. R.string.drawer_close /* "close drawer" description for accessibility */
  167. ) {
  168. public void onDrawerClosed(View view) {
  169. getActionBar().setTitle(mTitle);
  170. invalidateOptionsMenu(); // creates call to
  171. // onPrepareOptionsMenu()
  172. }
  173. public void onDrawerOpened(View drawerView) {
  174. getActionBar().setTitle(mDrawerTitle);
  175. invalidateOptionsMenu(); // creates call to
  176. // onPrepareOptionsMenu()
  177. }
  178. };
  179. mDrawerLayout.setDrawerListener(mDrawerToggle);
  180. startAndBind();
  181. if (savedInstanceState == null) {
  182. // on first time display view for first nav item
  183. displayView(0);
  184. }
  185. }
  186. private void registerReceiver() {
  187. LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(getString(R.string.broadcast)));
  188. }
  189. private void unregisterReceiver() {
  190. LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
  191. }
  192. private BroadcastReceiver mReceiver = new BroadcastReceiver() {
  193. @Override
  194. public void onReceive(Context context, Intent intent) {
  195. Bundle extras = intent.getExtras();
  196. String sender = extras.getString("SENDER");
  197. String[] values = extras.getStringArray("VALUES");
  198. if (sender.equals(Hostage.class.getName()) && values[0].equals(getString(R.string.broadcast_started))) {
  199. mAttacksOnProtocol.put(values[1], true);
  200. }
  201. }
  202. };
  203. public boolean hasProtocolAttacks(String protocol) {
  204. if (!mAttacksOnProtocol.containsKey(protocol))
  205. return false;
  206. return mAttacksOnProtocol.get(protocol);
  207. }
  208. public void startAndBind() {
  209. if (!isServiceRunning()) {
  210. startService(getServiceIntent());
  211. }
  212. bindService();
  213. }
  214. public void stopAndUnbind() {
  215. if (mHoneyService != null) {
  216. unbindService();
  217. }
  218. stopService(getServiceIntent());
  219. }
  220. public void unbindService() {
  221. try {
  222. unbindService(mConnection);
  223. } catch (IllegalArgumentException ex) {
  224. // somehow already unbound.
  225. }
  226. }
  227. public void bindService() {
  228. mAttacksOnProtocol.clear();
  229. bindService(getServiceIntent(), mConnection, BIND_AUTO_CREATE);
  230. // mServiceBound = true;
  231. }
  232. @Override
  233. protected void onDestroy() {
  234. super.onDestroy();
  235. // Unregister Broadcast Receiver
  236. unregisterReceiver();
  237. // Unbind running service
  238. if (!mHoneyService.hasRunningListeners()) {
  239. stopAndUnbind();
  240. }
  241. }
  242. @Override
  243. protected void onResume() {
  244. super.onResume();
  245. String action = getIntent().getAction();
  246. if (action != null && action.equals("SHOW_HOME")) {
  247. /*if (this.mDisplayedFragment != null && !this.mDisplayedFragment.getClass().equals(HomeFragment.class)) {
  248. getFragmentManager().popBackStackImmediate(HomeFragment.class.getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
  249. displayView(MainMenuItem.HOME.getValue());
  250. getIntent().setAction(null);
  251. }*/
  252. }
  253. }
  254. @Override
  255. public boolean onOptionsItemSelected(MenuItem item) {
  256. // toggle nav drawer on selecting action bar app icon/title
  257. if (mDrawerToggle.onOptionsItemSelected(item)) {
  258. return true;
  259. }
  260. if (item.getItemId() == android.R.id.home) {
  261. if (!mDrawerToggle.isDrawerIndicatorEnabled()) {
  262. navigateBack();
  263. }
  264. }
  265. return super.onOptionsItemSelected(item);
  266. }
  267. public void navigateBack(){
  268. if (!(this.mDisplayedFragment instanceof UpNavigatibleFragment)) {
  269. mDrawerToggle.setDrawerIndicatorEnabled(true);
  270. return;
  271. }
  272. UpNavigatibleFragment upNav = (UpNavigatibleFragment) this.mDisplayedFragment;
  273. getFragmentManager().popBackStackImmediate(upNav.getUpFragment().getName(), 0);
  274. this.mDisplayedFragment = getFragmentManager().findFragmentById(R.id.content_frame);
  275. configureFragment();
  276. if (!(this.mDisplayedFragment instanceof UpNavigatibleFragment) || !((UpNavigatibleFragment) this.mDisplayedFragment).isUpNavigatible()) {
  277. mDrawerToggle.setDrawerIndicatorEnabled(true);
  278. } else {
  279. mDrawerToggle.setDrawerIndicatorEnabled(false);
  280. }
  281. }
  282. @Override
  283. public void setTitle(CharSequence title) {
  284. mTitle = title;
  285. getActionBar().setTitle(mTitle);
  286. }
  287. /**
  288. * When using the ActionBarDrawerToggle, you must call it during
  289. * onPostCreate() and onConfigurationChanged()...
  290. */
  291. @Override
  292. protected void onPostCreate(Bundle savedInstanceState) {
  293. super.onPostCreate(savedInstanceState);
  294. // Sync the toggle state after onRestoreInstanceState has occurred.
  295. mDrawerToggle.syncState();
  296. }
  297. @Override
  298. public void onConfigurationChanged(Configuration newConfig) {
  299. super.onConfigurationChanged(newConfig);
  300. // Pass any configuration change to the drawer toggls
  301. mDrawerToggle.onConfigurationChanged(newConfig);
  302. }
  303. public Fragment getCurrentFragment() {
  304. return this.mDisplayedFragment;
  305. }
  306. public void setDrawerIndicatorEnabled(boolean val) {
  307. mDrawerToggle.setDrawerIndicatorEnabled(val);
  308. }
  309. public void displayView(int position) {
  310. MainMenuItem menuItemPosition = MainMenuItem.create(position);
  311. if (this.mDisplayedFragment != null && this.mDisplayedFragment.getClass() == menuItemPosition.getKlass()) {
  312. mDrawerLayout.closeDrawer(mDrawerList);
  313. return;
  314. }
  315. Fragment fragment = null;
  316. try {
  317. fragment = (Fragment) menuItemPosition.getKlass().newInstance();
  318. } catch (InstantiationException e) {
  319. Log.i(menuItemPosition.getKlass().toString(), "Could not create new instance of fragment");
  320. } catch (IllegalAccessException e) {
  321. Log.i(menuItemPosition.getKlass().toString(), "Could not create new instance of fragment");
  322. }
  323. if (fragment != null) {
  324. if(position == 0 && rootFragment == null){
  325. rootFragment = fragment;
  326. }
  327. boolean isFirst = getFragmentManager().getBackStackEntryCount() == 0;
  328. //getFragmentManager().popBackStackImmediate(HomeFragment.class.getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
  329. // update selected item and title, then close the drawer if needed
  330. //if(!(fragment instanceof HomeFragment) || isFirst) {
  331. injectFragment(fragment);// , false, menuItemPosition);
  332. //} else {
  333. // injectFragment(rootFragment);
  334. //}
  335. mDrawerList.setItemChecked(position, true);
  336. mDrawerList.setSelection(position);
  337. setTitle(mDrawerItems.get(position).text);
  338. }
  339. mDrawerLayout.closeDrawer(mDrawerList);
  340. }
  341. public void injectFragment(Fragment fragment, boolean enableBack) {
  342. injectFragment(fragment);
  343. }
  344. public void injectFragment(Fragment fragment) {
  345. this.mCloseWarning = false;
  346. // set orientation fixed to portrait in home fragment
  347. if (fragment instanceof UpNavigatibleFragment) {
  348. UpNavigatibleFragment upFrag = (UpNavigatibleFragment) fragment;
  349. if (upFrag.getUpFragment() == null) {
  350. upFrag.setUpFragment(this.mDisplayedFragment.getClass());
  351. }
  352. if (upFrag.isUpNavigatible()) {
  353. mDrawerToggle.setDrawerIndicatorEnabled(false);
  354. }
  355. }
  356. configureFragment(fragment);
  357. FragmentManager fragmentManager = getFragmentManager();
  358. FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
  359. fragmentTransaction.replace(R.id.content_frame, fragment, fragment.getClass().getName());
  360. fragmentTransaction.addToBackStack(fragment.getClass().getName());
  361. fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
  362. fragmentTransaction.commit();
  363. this.mDisplayedFragment = fragment;
  364. }
  365. private void configureFragment() {
  366. configureFragment(this.mDisplayedFragment);
  367. }
  368. private void configureFragment(Fragment fragment) {
  369. if (fragment == null)
  370. return;
  371. if (fragment instanceof HomeFragment || fragment instanceof AboutFragment) {
  372. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT | ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
  373. } else {
  374. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
  375. }
  376. if (fragment instanceof StatisticsFragment || fragment instanceof RecordOverviewFragment) {
  377. Intent intent = this.getIntent();
  378. intent.removeExtra(LogFilter.LOG_FILTER_INTENT_KEY);
  379. }
  380. }
  381. @Override
  382. public void onBackPressed() {
  383. if (mDisplayedFragment instanceof HomeFragment) {
  384. if (this.mCloseWarning) {
  385. MainActivity.getInstance().getHostageService().stopListeners();
  386. MainActivity.getInstance().stopAndUnbind();
  387. this.mCloseWarning = false;
  388. finish();
  389. } else {
  390. Toast.makeText(this, "Press the back button again to close HosTaGe", Toast.LENGTH_SHORT).show();
  391. this.mCloseWarning = true;
  392. }
  393. //}
  394. } else {
  395. super.onBackPressed();
  396. this.mDisplayedFragment = getFragmentManager().findFragmentById(R.id.content_frame);
  397. configureFragment();
  398. if (!(this.mDisplayedFragment instanceof UpNavigatibleFragment) || !((UpNavigatibleFragment) this.mDisplayedFragment).isUpNavigatible()) {
  399. mDrawerToggle.setDrawerIndicatorEnabled(true);
  400. } else {
  401. mDrawerToggle.setDrawerIndicatorEnabled(false);
  402. }
  403. }
  404. }
  405. @Override
  406. public boolean onKeyDown(int keycode, KeyEvent e) {
  407. switch (keycode) {
  408. case KeyEvent.KEYCODE_MENU:
  409. if (this.mDrawerToggle.isDrawerIndicatorEnabled()) {
  410. if (this.mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
  411. this.mDrawerLayout.closeDrawer(Gravity.LEFT);
  412. return true;
  413. }
  414. this.mDrawerLayout.openDrawer(Gravity.LEFT);
  415. }
  416. return true;
  417. }
  418. return super.onKeyDown(keycode, e);
  419. }
  420. public Intent getServiceIntent() {
  421. return new Intent(this, Hostage.class);
  422. }
  423. public Fragment getDisplayedFragment() {
  424. return this.mDisplayedFragment;
  425. }
  426. public Hostage getHostageService() {
  427. return this.mHoneyService;
  428. }
  429. public boolean isServiceBound() {
  430. return this.mServiceBound;
  431. }
  432. public boolean isServiceRunning() {
  433. ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
  434. for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
  435. if (service.service.getClassName().equals(Hostage.class.getName())) {
  436. return true;
  437. }
  438. }
  439. return false;
  440. }
  441. public void startMonitorServices(List<String> protocols){
  442. for(String protocol: protocols){
  443. if(protocol.equals("GHOST")){
  444. if(mProfileManager.getCurrentActivatedProfile() != null){
  445. Profile profile = mProfileManager.getCurrentActivatedProfile();
  446. if(profile.mGhostActive){
  447. for(int port: profile.getGhostPorts()){
  448. if(!getHostageService().isRunning(protocol, port)) getHostageService().startListener(protocol, port);
  449. }
  450. }
  451. }
  452. } else {
  453. if(!getHostageService().isRunning(protocol)) getHostageService().startListener(protocol);
  454. }
  455. }
  456. }
  457. public enum MainMenuItem {
  458. HOME(0, HomeFragment.class),
  459. THREAT_MAP(1, ThreatMapFragment.class),
  460. RECORDS(2, RecordOverviewFragment.class),
  461. STATISTICS(3, StatisticsFragment.class),
  462. SERVICES(4, ServicesFragment.class),
  463. PROFILE_MANAGER(5, ProfileManagerFragment.class),
  464. SETTINGS(6, SettingsFragment.class),
  465. APPLICATION_INFO(7, AboutFragment.class);
  466. private int value;
  467. private Class<?> klass;
  468. private MainMenuItem(int value, Class<?> klass) {
  469. this.value = value;
  470. this.klass = klass;
  471. }
  472. static public MainMenuItem create(int value) {
  473. if (value < 0 || value >= MainMenuItem.values().length)
  474. return MainMenuItem.HOME;
  475. return MainMenuItem.values()[value];
  476. }
  477. public static boolean hasClass(Class<?> klass){
  478. for(MainMenuItem m: MainMenuItem.values()){
  479. if(m.getKlass().equals(klass)) return true;
  480. }
  481. return false;
  482. }
  483. public int getValue() {
  484. return value;
  485. }
  486. public Class<?> getKlass() {
  487. return this.klass;
  488. }
  489. }
  490. private class DrawerItemClickListener implements ListView.OnItemClickListener {
  491. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  492. displayView(position);
  493. }
  494. }
  495. }