MainActivity.java 18 KB

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