diff --git a/.tx/config b/.tx/config index 44d0e0a4..e5c960f2 100644 --- a/.tx/config +++ b/.tx/config @@ -7,4 +7,17 @@ file_filter = res/values-/strings.xml host = https://www.transifex.com source_file = res/values/strings.xml source_lang = en +type = ANDROID +[orbot.description] +file_filter = description/.xlf +host = https://www.transifex.com +source_file = description/source.xlf +source_lang = en +type = XLIFF + +[orbot.olddescription] +file_filter = releases/assets/-description.txt +host = https://www.transifex.com +source_file = releases/assets/description.txt +source_lang = en diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 30249799..23f5e4e5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -56,13 +56,7 @@ - - - - + @@ -81,24 +75,27 @@ /> - - + - - - - - - - + + + + + + + + + + + +
+ Google places strick character limits on the various text fields in Google Play. The title is 30 characters, the short description is 80 characters, and the rest of the strings, which all go together in the description, are limited to 4000 characters. +
+ + + Orbot + This is limited by Google to 30 characters + + + Protect your privacy with this proxy with Tor + This is limited by Google to 80 characters + + + Orbot is a free proxy app that empowers other apps to use the internet more securely. Orbot uses Tor to encrypt your Internet traffic and then hides it by bouncing through a series of computers around the world. Tor is free software and an open network that helps you defend against a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, and state security known as traffic analysis. + + + Orbot is the only app that creates a truly private internet connection. As the New York Times writes, “when a communication arrives from Tor, you can never know where or whom it’s from.” Tor won the 2012 Electronic Frontier Foundation (EFF) Pioneer Award. + + + ACCEPT NO SUBSTITUTES: Orbot is the safest way to use the Internet on Android. Period. Orbot bounces your encrypted traffic several times through computers around the world, instead of connecting you directly like VPNs and proxies. This process takes a little longer, but the strongest privacy and identity protection available is worth the wait. + + + PRIVATE WEB SURFING: Use with Orweb, the most anonymous way to access any website, even if it’s normally blocked, monitored, or on the hidden web. Get Orweb: https://goo.gl/s3mLa + + + PRIVATE CHAT MESSAGING: Use Gibberbot with Orbot to chat confidentially with anyone, anywhere for free. Get Gibberbot: https://goo.gl/O3FfS + + + PRIVACY FOR APPS: Any installed app can use Tor if it has a proxy feature, using the settings found here: https://goo.gl/2OA1y Use Orbot with Twitter, or try private web searching with DuckDuckGo: https://goo.gl/lgh1p + + + PRIVACY FOR EVERYONE: Tor can help you confidentially research a competitor, get around the Facebook block at school, or circumvent a firewall to watch sports at work. +PRIVACY MADE EASY: Check out our fun, interactive walkthrough: https://guardianproject.info/howto/browsefreely +IT’S OFFICIAL: This is the official version of the Tor onion routing service for Android. + + + ***Expert Root Mode*** + + + UNIVERSAL MODE: Orbot can be configured to transparently proxy all of your Internet traffic through Tor. You can also choose which specific apps you want to use through Tor. + + + ★ WE SPEAK YOUR LANGUAGE: Orbot is available for friends who speak: + + + العربية, azərbaycanca, български, català, Čeština, dansk, Deutsch, Ελληνικά, English, español, eesti, euskara, فارسی, suomi, français, galego, hrvatski, magyar, עברית, íslenska, italiano, 日本語, 한국어, lietuvių, latviešu, Македонци, Bahasa Melayu, Nederlands, norsk, polski, português, Русский, slovenčina, slovenščina, српски, svenska, Türkçe, українська, Tagalog, Tiếng Việt, 中文(简体), 中文(台灣) + Do not translate the names of the languages, leave them just like this. + + + Don’t see your language? Join us and help translate the app: + + + https://www.transifex.com/projects/p/orbot + Do not translate this. + + + ***Learn More*** + + + ★ ABOUT US: Guardian Project is a group of developers that make secure mobile apps and open-source code for a better tomorrow + + + ★ OUR WEBSITE: https://GuardianProject.info + + + ★ ABOUT TOR: https://TorProject.org + + + ★ ON TWITTER: https://twitter.com/guardianproject + + + ★ FREE SOFTWARE: Orbot is free software. Take a look at our source code, or join the community to make it better: + + + https://gitweb.torproject.org/orbot.git + Do not translate this. + + + ★ MESSAGE US: Are we missing your favorite feature? Found an annoying bug? Please tell us! We’d love to hear from you. Send us an email: support@guardianproject.info or find us in our chat room https://guardianproject.info/contact + + +
+
\ No newline at end of file diff --git a/external/.tx/config b/external/.tx/config deleted file mode 100644 index 8f5c518d..00000000 --- a/external/.tx/config +++ /dev/null @@ -1,15 +0,0 @@ -[main] -host = https://www.transifex.com -lang_map = af_ZA: af-rZA, am_ET: am-rET, ar_AE: ar-rAE, ar_BH: ar-rBH, ar_DZ: ar-rDZ, ar_EG: ar-rEG, ar_IQ: ar-rIQ, ar_JO: ar-rJO, ar_KW: ar-rKW, ar_LB: ar-rLB, ar_LY: ar-rLY, ar_MA: ar-rMA, ar_OM: ar-rOM, ar_QA: ar-rQA, ar_SA: ar-rSA, ar_SY: ar-rSY, ar_TN: ar-rTN, ar_YE: ar-rYE, arn_CL: arn-rCL, as_IN: as-rIN, az_AZ: az-rAZ, ba_RU: ba-rRU, be_BY: be-rBY, bg_BG: bg-rBG, bn_BD: bn-rBD, bn_IN: bn-rIN, bo_CN: bo-rCN, br_FR: br-rFR, bs_BA: bs-rBA, ca_ES: ca-rES, co_FR: co-rFR, cs_CZ: cs-rCZ, cy_GB: cy-rGB, da_DK: da-rDK, de_AT: de-rAT, de_CH: de-rCH, de_DE: de-rDE, de_LI: de-rLI, de_LU: de-rLU, dsb_DE: dsb-rDE, dv_MV: dv-rMV, el_GR: el-rGR, en_AU: en-rAU, en_BZ: en-rBZ, en_CA: en-rCA, en_GB: en-rGB, en_IE: en-rIE, en_IN: en-rIN, en_JM: en-rJM, en_MY: en-rMY, en_NZ: en-rNZ, en_PH: en-rPH, en_SG: en-rSG, en_TT: en-rTT, en_US: en-rUS, en_ZA: en-rZA, en_ZW: en-rZW, es_AR: es-rAR, es_BO: es-rBO, es_CL: es-rCL, es_CO: es-rCO, es_CR: es-rCR, es_DO: es-rDO, es_EC: es-rEC, es_ES: es-rES, es_GT: es-rGT, es_HN: es-rHN, es_MX: es-rMX, es_NI: es-rNI, es_PA: es-rPA, es_PE: es-rPE, es_PR: es-rPR, es_PY: es-rPY, es_SV: es-rSV, es_US: es-rUS, es_UY: es-rUY, es_VE: es-rVE, et_EE: et-rEE, eu_ES: eu-rES, fa_IR: fa-rIR, fi_FI: fi-rFI, fil_PH: tl-rPH, fil: tl, fo_FO: fo-rFO, fr_BE: fr-rBE, fr_CA: fr-rCA, fr_CH: fr-rCH, fr_FR: fr-rFR, fr_LU: fr-rLU, fr_MC: fr-rMC, fy_NL: fy-rNL, ga_IE: ga-rIE, gd_GB: gd-rGB, gl_ES: gl-rES, gsw_FR: gsw-rFR, gu_IN: gu-rIN, ha_NG: ha-rNG, he_IL: he-rIL, hi_IN: hi-rIN, hr_BA: hr-rBA, hr_HR: hr-rHR, hsb_DE: hsb-rDE, hu_HU: hu-rHU, hy_AM: hy-rAM, id_ID: id-rID, ig_NG: ig-rNG, ii_CN: ii-rCN, is_IS: is-rIS, it_CH: it-rCH, it_IT: it-rIT, iu_CA: iu-rCA, ja_JP: ja-rJP, ka_GE: ka-rGE, kk_KZ: kk-rKZ, kl_GL: kl-rGL, km_KH: km-rKH, kn_IN: kn-rIN, ko_KR: ko-rKR, kok_IN: kok-rIN, ky_KG: ky-rKG, lb_LU: lb-rLU, lo_LA: lo-rLA, lt_LT: lt-rLT, lv_LV: lv-rLV, mi_NZ: mi-rNZ, mk_MK: mk-rMK, ml_IN: ml-rIN, mn_CN: mn-rCN, mn_MN: mn-rMN, moh_CA: moh-rCA, mr_IN: mr-rIN, ms_BN: ms-rBN, ms_MY: ms-rMY, mt_MT: mt-rMT, nb_NO: nb-rNO, ne_NP: ne-rNP, nl_BE: nl-rBE, nl_NL: nl-rNL, nn_NO: nn-rNO, nso_ZA: nso-rZA, oc_FR: oc-rFR, or_IN: or-rIN, pa_IN: pa-rIN, pl_PL: pl-rPL, prs_AF: prs-rAF, ps_AF: ps-rAF, pt_BR: pt-rBR, pt_PT: pt-rPT, qut_GT: qut-rGT, quz_BO: quz-rBO, quz_EC: quz-rEC, quz_PE: quz-rPE, rm_CH: rm-rCH, ro_RO: ro-rRO, ru_RU: ru-rRU, rw_RW: rw-rRW, sa_IN: sa-rIN, sah_RU: sah-rRU, se_FI: se-rFI, se_NO: se-rNO, se_SE: se-rSE, si_LK: si-rLK, sk_SK: sk-rSK, sl_SI: sl-rSI, sma_NO: sma-rNO, sma_SE: sma-rSE, smj_NO: smj-rNO, smj_SE: smj-rSE, smn_FI: smn-rFI, sms_FI: sms-rFI, sq_AL: sq-rAL, sr_BA: sr-rBA, sr_CS: sr-rCS, sr_ME: sr-rME, sr_RS: sr-rRS, sv_FI: sv-rFI, sv_SE: sv-rSE, sw_KE: sw-rKE, syr_SY: syr-rSY, ta_IN: ta-rIN, te_IN: te-rIN, tg_TJ: tg-rTJ, th_TH: th-rTH, tk_TM: tk-rTM, tn_ZA: tn-rZA, tr_TR: tr-rTR, tt_RU: tt-rRU, tzm_DZ: tzm-rDZ, ug_CN: ug-rCN, uk_UA: uk-rUA, ur_PK: ur-rPK, uz_UZ: uz-rUZ, vi_VN: vi-rVN, wo_SN: wo-rSN, xh_ZA: xh-rZA, yo_NG: yo-rNG, zh_CN: zh-rCN, zh_HK: zh-rHK, zh_MO: zh-rMO, zh_SG: zh-rSG, zh_TW: zh-rTW, zu_ZA: zu-rZA - -[orbot.stringsxml] -file_filter = ../res/values-/strings.xml -host = https://www.transifex.com -source_file = ../res/values/strings.xml -source_lang = en - -[orbot.description] -file_filter = ../releases/assets/-description.txt -host = https://www.transifex.com -source_file = ../releases/assets/description.txt -source_lang = en diff --git a/external/tor b/external/tor index 9ccf019b..d41ab972 160000 --- a/external/tor +++ b/external/tor @@ -1 +1 @@ -Subproject commit 9ccf019b168909ef6674c71aebda9f90516bb6a1 +Subproject commit d41ab97294ec69c748566f4cb610f899d9976572 diff --git a/res/layout/layout_main.xml b/res/layout/layout_main.xml index 1b46e551..a0fc1a66 100644 --- a/res/layout/layout_main.xml +++ b/res/layout/layout_main.xml @@ -4,6 +4,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/panel_background_main" + > - - + + - + + + + - - - - - - - - diff --git a/res/menu/orbot_main.xml b/res/menu/orbot_main.xml index cff67e90..f37373a8 100644 --- a/res/menu/orbot_main.xml +++ b/res/menu/orbot_main.xml @@ -57,8 +57,8 @@ --> - Orbot is starting… Connected to the Tor network Orbot is deactivated - Orbot is shutting down + TorService is shutting down Starting Tor client… complete. waiting. @@ -25,7 +25,7 @@ Start Stop About - Wizard + Get apps… Download Upload Help @@ -126,6 +126,8 @@ Entrance Nodes Fingerprints, nicks, countries and addresses for the first hop Enter Entrance Nodes + Allow Background Starts + Let any app tell Orbot to start Tor and related services Proxy All Proxy None diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index d910fee2..08eddfac 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -22,6 +22,11 @@ android:summary="@string/pref_use_expanded_notifications" android:enabled="true" android:title="@string/pref_use_expanded_notifications_title"/> + 0) { @@ -444,34 +407,21 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon } - - /** - * This is our attempt to REALLY exit Orbot, and stop the background service - * However, Android doesn't like people "quitting" apps, and/or our code may not - * be quite right b/c no matter what we do, it seems like the TorService still exists - **/ - private void doExit () - { - try { - - //one of the confusing things about all of this code is the multiple - //places where things like "stopTor" are called, both in the Activity and the Service - //not something to tackle in your first iteration, but i thin we can talk about fixing - //terminology but also making sure there are clear distinctions in control - stopTor(); - stopService (); - - - } catch (RemoteException e) { - Log.w(TAG, e); - } - - //Kill all the wizard activities - setResult(RESULT_CLOSE_ALL); - finish(); - - } - + + /** + * This is our attempt to REALLY exit Orbot, and stop the background service + * However, Android doesn't like people "quitting" apps, and/or our code may + * not be quite right b/c no matter what we do, it seems like the TorService + * still exists + **/ + private void doExit() { + stopTor(); + + // Kill all the wizard activities + setResult(RESULT_CLOSE_ALL); + finish(); + } + protected void onPause() { try { @@ -485,7 +435,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon //can happen on exit/shutdown } } - + private void doTorCheck () { @@ -517,13 +467,11 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon if (onionHostname == null || onionHostname.length() == 0) { - stopTor(); - startTor(); - + requestTorRereadConfig(); + new Thread () { - - - public void run () + + public void run () { String onionHostname = mPrefs.getString("pref_hs_hostname",""); @@ -557,8 +505,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon } } - - + private synchronized void handleIntents () { if (getIntent() == null) @@ -567,14 +514,14 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon // Get intent, action and MIME type Intent intent = getIntent(); String action = intent.getAction(); - Log.e(TAG, "handleIntents " + action); + Log.d(TAG, "handleIntents " + action); - String type = intent.getType(); + //String type = intent.getType(); if (action == null) return; - if (action.equals("org.torproject.android.REQUEST_HS_PORT")) + if (action.equals(INTENT_ACTION_REQUEST_HIDDEN_SERVICE)) { final int hiddenServicePortRequest = getIntent().getIntExtra("hs_port", -1); @@ -614,27 +561,25 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon return; //don't null the setIntent() as we need it later } - else if (action.equals("org.torproject.android.START_TOR")) + else if (action.equals(INTENT_ACTION_REQUEST_START_TOR)) { autoStartFromIntent = true; - try { - Log.i(TAG, "action equals org.torproject.android.START_TOR"); - startTor(); - - Intent resultIntent = new Intent(intent); - resultIntent.putExtra("socks_proxy", "socks://127.0.0.1:" + TorServiceConstants.PORT_SOCKS_DEFAULT); - resultIntent.putExtra("socks_proxy_host", "127.0.0.1"); - resultIntent.putExtra("socks_proxy_port", TorServiceConstants.PORT_SOCKS_DEFAULT); - resultIntent.putExtra("http_proxy", "http://127.0.0.1" + TorServiceConstants.PORT_HTTP); - resultIntent.putExtra("http_proxy_host", "127.0.0.1"); - resultIntent.putExtra("http_proxy_port", TorServiceConstants.PORT_HTTP); - setResult(RESULT_OK, resultIntent); - finish(); - } catch (RemoteException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + + startTor(); + if (Prefs.allowBackgroundStarts()) + { + Intent resultIntent; + if (lastStatusIntent == null) { + resultIntent = new Intent(intent); + } else { + resultIntent = lastStatusIntent; + } + resultIntent.putExtra(TorServiceConstants.EXTRA_STATUS, torStatus); + setResult(RESULT_OK, resultIntent); + finish(); + } + } else if (action.equals(Intent.ACTION_VIEW)) { @@ -653,28 +598,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon } } } - else - { - showWizard = mPrefs.getBoolean("show_wizard",showWizard); - - //let's not show the wizard now for new users - - if (showWizard) - { - Editor pEdit = mPrefs.edit(); - pEdit.putBoolean("show_wizard",false); - pEdit.commit(); - showWizard = false; - - - showAlert(getString(R.string.app_name),getString(R.string.wizard_final_msg),true); - - } - - } - - updateStatus(""); + updateStatus(null); setIntent(null); @@ -686,31 +611,15 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon showAlert(getString(R.string.bridges_updated),getString(R.string.restart_orbot_to_use_this_bridge_) + newBridgeValue,false); - Editor pEdit = mPrefs.edit(); - - pEdit.putString(OrbotConstants.PREF_BRIDGES_LIST,newBridgeValue); //set the string to a preference - pEdit.putBoolean(OrbotConstants.PREF_BRIDGES_ENABLED,true); - - pEdit.commit(); + Prefs.setBridgesList(newBridgeValue); //set the string to a preference + Prefs.putBridgesEnabled(true); setResult(RESULT_OK); mBtnBridges.setChecked(true); enableBridges(true); - } - - private boolean showWizard = true; - - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - // doLayout(); - //updateStatus(""); - } - + } /* * Launch the system activity for Uri viewing with the provided url @@ -718,7 +627,6 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon private void openBrowser(final String browserLaunchUrl,boolean forceExternal) { boolean isOrwebInstalled = appInstalledOrNot("info.guardianproject.browser"); - boolean isTransProxy = mPrefs.getBoolean("pref_transparent", false); if (mBtnVPN.isChecked()||forceExternal) { @@ -727,7 +635,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } - else if (isTransProxy) + else if (Prefs.useTransparentProxying()) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(browserLaunchUrl)); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); @@ -836,18 +744,14 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon } else if (torStatus == TorServiceConstants.STATUS_ON) { - updateSettings(); + updateTransProxy(); Toast.makeText(this, R.string.you_may_need_to_stop_and_start_orbot_for_settings_change_to_be_enabled_, Toast.LENGTH_SHORT).show(); } } else if (request == REQUEST_VPN && response == RESULT_OK) { - startService(TorServiceConstants.CMD_VPN); - - // if (torStatus == TorServiceConstants.STATUS_ON) - // restartTor (); - + sendIntentToService(TorServiceConstants.CMD_VPN); } IntentResult scanResult = IntentIntegrator.parseActivityResult(request, response, data); @@ -910,17 +814,17 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon break; case 3: //azure - mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"2").commit(); + Prefs.setBridgesList("2"); enableBridges(true); break; case 4: //amazon - mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"1").commit(); + Prefs.setBridgesList("1"); enableBridges(true); break; case 5: //google - mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"0").commit(); + Prefs.setBridgesList("0"); enableBridges(true); break; @@ -1017,54 +921,22 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon private void enableBridges (boolean enable) { + Prefs.putBridgesEnabled(enable); - Editor edit = mPrefs.edit(); - edit.putBoolean(OrbotConstants.PREF_BRIDGES_ENABLED, enable); - edit.commit(); - - updateSettings(); - if (torStatus == TorServiceConstants.STATUS_ON) { - String bridgeList = mPrefs.getString(OrbotConstants.PREF_BRIDGES_LIST,null); + String bridgeList = Prefs.getBridgesList(); if (bridgeList != null && bridgeList.length() > 0) { - restartTor (); + requestTorRereadConfig (); } - - } - - - } - - private void restartTor () - { - try - { - //do auto restart - stopTor (); - - mHandler.postDelayed(new Runnable () { - - public void run () - { - try - { - startTor(); - } - catch (Exception e) - { - Log.e(TAG,"can't start orbot",e); - } - } - }, 2000); - } - catch (Exception e) - { - Log.e(TAG,"can't stop orbot",e); } } - + + private void requestTorRereadConfig() { + sendIntentToService(TorServiceConstants.CMD_SIGNAL_HUP); + } + public void promptStartVpnService () { LayoutInflater li = LayoutInflater.from(this); @@ -1081,11 +953,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon @Override public void onClick(DialogInterface dialog, int which) { - - mPrefs.edit().putBoolean("pref_vpn", true).commit(); - + Prefs.putUseVpn(true); startVpnService(); - } @@ -1097,9 +966,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon public void onClick(DialogInterface dialog, int which) { mBtnVPN.setChecked(false); - } - }) .show(); @@ -1114,29 +981,24 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon } else { - startService(TorServiceConstants.CMD_VPN); - // if (torStatus == TorServiceConstants.STATUS_ON) - // restartTor (); - + sendIntentToService(TorServiceConstants.CMD_VPN); } } public void stopVpnService () { - startService(TorServiceConstants.CMD_VPN_CLEAR); - // restartTor (); + sendIntentToService(TorServiceConstants.CMD_VPN_CLEAR); } private boolean flushTransProxy () { - startService(TorServiceConstants.CMD_FLUSH); + sendIntentToService(TorServiceConstants.CMD_FLUSH); return true; } - private boolean updateSettings () + private boolean updateTransProxy () { - //todo send service command - startService(TorServiceConstants.CMD_UPDATE); + sendIntentToService(TorServiceConstants.CMD_UPDATE_TRANS_PROXY); return true; } @@ -1146,25 +1008,14 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon if (mPrefs != null) { - boolean useVPN = mPrefs.getBoolean("pref_vpn", false); - mBtnVPN.setChecked(useVPN); - - boolean useBridges = mPrefs.getBoolean("pref_bridges_enabled", false); - mBtnBridges.setChecked(useBridges); + mBtnVPN.setChecked(Prefs.useVpn()); + mBtnBridges.setChecked(Prefs.bridgesEnabled()); } - mHandler.postDelayed(new Runnable () - { - public void run () - { - - handleIntents(); + requestTorStatus(); - } - } - , 500); - - + updateStatus(null); + } AlertDialog aDialog = null; @@ -1202,198 +1053,155 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon aDialog.setCanceledOnTouchOutside(true); } - - private void updateStatus (String torServiceMsg) - { - - //now update the layout_main UI based on the status - if (imgStatus != null) - { - - if (torStatus == TorServiceConstants.STATUS_ON) - { - - imgStatus.setImageResource(R.drawable.toron); - - mBtnBrowser.setEnabled(true); - - if (mItemOnOff != null) - mItemOnOff.setTitle(R.string.menu_stop); - - if (lblStatus != null && torServiceMsg != null) - if (torServiceMsg.indexOf('%')!=-1) - lblStatus.setText(torServiceMsg); - else - lblStatus.setText(""); - - boolean showFirstTime = mPrefs.getBoolean("connect_first_time",true); - - if (showFirstTime) - { - - Editor pEdit = mPrefs.edit(); - - pEdit.putBoolean("connect_first_time",false); - - pEdit.commit(); - - showAlert(getString(R.string.status_activated),getString(R.string.connect_first_time),true); - - } - - if (autoStartFromIntent) - { - autoStartFromIntent = false; - finish(); - Log.e(TAG, "autoStartFromIntent finish"); - } - } - else if (torStatus == TorServiceConstants.STATUS_CONNECTING) - { - - imgStatus.setImageResource(R.drawable.torstarting); - - if (mItemOnOff != null) - mItemOnOff.setTitle(R.string.menu_stop); - - if (lblStatus != null && torServiceMsg != null) - if (torServiceMsg.indexOf('%')!=-1) - lblStatus.setText(torServiceMsg); - - - - } - else if (torStatus == TorServiceConstants.STATUS_OFF) - { - imgStatus.setImageResource(R.drawable.toroff); - lblStatus.setText(getString(R.string.press_to_start)); - mBtnBrowser.setEnabled(false); - - if (mItemOnOff != null) - mItemOnOff.setTitle(R.string.menu_start); - } - - if (torServiceMsg != null && torServiceMsg.length() > 0) - { - mTxtOrbotLog.append(torServiceMsg + '\n'); - } - } - - - } - - - - // guess what? this start's Tor! actually no it just requests via the local ITorService to the remote TorService instance - // to start Tor - private void startTor () throws RemoteException - { - - - startService (TorServiceConstants.CMD_START); - torStatus = TorServiceConstants.STATUS_CONNECTING; - - mTxtOrbotLog.setText(""); - - //here we update the UI which is a bit sloppy and mixed up code wise - //might be best to just call updateStatus() instead of directly manipulating UI in this method - yep makes sense - imgStatus.setImageResource(R.drawable.torstarting); - lblStatus.setText(getString(R.string.status_starting_up)); - - //we send a message here to the progressDialog i believe, but we can clarify that shortly - Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG); - msg.getData().putString(HANDLER_TOR_MSG, getString(R.string.status_starting_up)); - mHandler.sendMessage(msg); - - - } - - //now we stop Tor! amazing! - private void stopTor () throws RemoteException - { - - startService (TorServiceConstants.CMD_STOP); - torStatus = TorServiceConstants.STATUS_OFF; - Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG); - mHandler.sendMessage(msg); - - } - - /* - * (non-Javadoc) - * @see android.view.View.OnClickListener#onClick(android.view.View) + /** + * Update the layout_main UI based on the status of {@link TorService}. + * {@code torServiceMsg} must never be {@code null} */ - public boolean onLongClick(View view) { - - try - { - - if (torStatus == TorServiceConstants.STATUS_OFF) - { + private void updateStatus(String torServiceMsg) { - startTor(); - } - else - { - - stopTor(); - stopService (); - - } - - return true; - - } - catch (Exception e) + if (torStatus == null) + return; //UI not init'd yet + + if (torStatus == TorServiceConstants.STATUS_ON) { + + imgStatus.setImageResource(R.drawable.toron); + + mBtnBrowser.setEnabled(true); + + if (torServiceMsg != null) { - Log.d(TAG,"error onclick",e); + if (torServiceMsg.contains(TorServiceConstants.LOG_NOTICE_HEADER)) + lblStatus.setText(torServiceMsg); + } + else + lblStatus.setText(getString(R.string.status_activated)); + + + boolean showFirstTime = mPrefs.getBoolean("connect_first_time", true); + + if (showFirstTime) + { + Editor pEdit = mPrefs.edit(); + pEdit.putBoolean("connect_first_time", false); + pEdit.commit(); + showAlert(getString(R.string.status_activated), + getString(R.string.connect_first_time), true); + } + + if (autoStartFromIntent) + { + autoStartFromIntent = false; + Intent resultIntent = lastStatusIntent; + resultIntent.putExtra(TorServiceConstants.EXTRA_STATUS, torStatus); + setResult(RESULT_OK, resultIntent); + finish(); + Log.d(TAG, "autoStartFromIntent finish"); } - return false; - + + + } else if (torStatus == TorServiceConstants.STATUS_STARTING) { + + imgStatus.setImageResource(R.drawable.torstarting); + + if (torServiceMsg != null) + { + if (torServiceMsg.contains(TorServiceConstants.LOG_NOTICE_BOOTSTRAPPED)) + lblStatus.setText(torServiceMsg); + } + else + lblStatus.setText(getString(R.string.status_starting_up)); + + mBtnBrowser.setEnabled(false); + + } else if (torStatus == TorServiceConstants.STATUS_STOPPING) { + + if (torServiceMsg != null && torServiceMsg.contains(TorServiceConstants.LOG_NOTICE_HEADER)) + lblStatus.setText(torServiceMsg); + + imgStatus.setImageResource(R.drawable.torstarting); + lblStatus.setText(torServiceMsg); + mBtnBrowser.setEnabled(false); + + } else if (torStatus == TorServiceConstants.STATUS_OFF) { + + imgStatus.setImageResource(R.drawable.toroff); + lblStatus.setText(getString(R.string.press_to_start)); + mBtnBrowser.setEnabled(false); } + if (torServiceMsg != null && torServiceMsg.length() > 0) + { + mTxtOrbotLog.append(torServiceMsg + '\n'); + } + } + + /** + * Starts tor and related daemons by sending an + * {@link TorServiceConstants#ACTION_START} {@link Intent} to + * {@link TorService} + */ + private void startTor() { + sendIntentToService(TorServiceConstants.ACTION_START); + } + + /** + * Request tor status without starting it + * {@link TorServiceConstants#ACTION_START} {@link Intent} to + * {@link TorService} + */ + private void requestTorStatus() { + sendIntentToService(TorServiceConstants.ACTION_STATUS); + } + + public boolean onLongClick(View view) { + + if (torStatus == TorServiceConstants.STATUS_OFF) { + lblStatus.setText(getString(R.string.status_starting_up)); + startTor(); + } else { + lblStatus.setText(getString(R.string.status_shutting_down)); + + stopTor(); + } - - + return true; + + } // this is what takes messages or values from the callback threads or other non-mainUI threads //and passes them back into the main UI thread for display to the user - private Handler mHandler = new Handler() { - - private String lastServiceMsg = null; - - public void handleMessage(Message msg) { + private Handler mStatusUpdateHandler = new Handler() { + + @Override + public void handleMessage(final Message msg) { + + String newTorStatus = msg.getData().getString("status"); + String log = (String)msg.obj; + + if (torStatus == null && newTorStatus != null) //first time status + { + torStatus = newTorStatus; + findViewById(R.id.pbConnecting).setVisibility(View.GONE); + findViewById(R.id.frameMain).setVisibility(View.VISIBLE); + updateStatus(log); + + //now you can handle the intents properly + handleIntents(); + + } + else if (newTorStatus != null && !torStatus.equals(newTorStatus)) //status changed + { + torStatus = newTorStatus; + updateStatus(log); + } + else if (log != null) //it is just a log + updateStatus(log); + switch (msg.what) { - case TorServiceConstants.STATUS_MSG: - case TorServiceConstants.LOG_MSG: + case MESSAGE_TRAFFIC_COUNT: - String torServiceMsg = (String)msg.getData().getString(HANDLER_TOR_MSG); - - if (lastServiceMsg == null || !lastServiceMsg.equals(torServiceMsg)) - { - updateStatus(torServiceMsg); - - lastServiceMsg = torServiceMsg; - } - - break; - case TorServiceConstants.ENABLE_TOR_MSG: - - - updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG)); - - break; - case TorServiceConstants.DISABLE_TOR_MSG: - - updateStatus((String)msg.getData().getString(HANDLER_TOR_MSG)); - - break; - - - case TorServiceConstants.MESSAGE_TRAFFIC_COUNT : - Bundle data = msg.getData(); DataCount datacount = new DataCount(data.getLong("upload"),data.getLong("download")); @@ -1402,25 +1210,18 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon downloadText.setText(formatCount(datacount.Download) + " / " + formatTotal(totalRead)); uploadText.setText(formatCount(datacount.Upload) + " / " + formatTotal(totalWrite)); - - if (torStatus != TorServiceConstants.STATUS_ON) - { - updateStatus(""); - } - + + break; default: super.handleMessage(msg); } } - - - }; - @Override + @Override protected void onDestroy() { super.onDestroy(); - LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); + LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocalBroadcastReceiver); } @@ -1464,19 +1265,12 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon + getString(R.string.mb); } - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - - - } - private static final float ROTATE_FROM = 0.0f; private static final float ROTATE_TO = 360.0f*4f;// 3.141592654f * 32.0f; public void spinOrbot (float direction) { - startService (TorServiceConstants.CMD_NEWNYM); + sendIntentToService (TorServiceConstants.CMD_NEWNYM); Toast.makeText(this, R.string.newnym, Toast.LENGTH_SHORT).show(); diff --git a/src/org/torproject/android/Prefs.java b/src/org/torproject/android/Prefs.java new file mode 100644 index 00000000..fad04ba6 --- /dev/null +++ b/src/org/torproject/android/Prefs.java @@ -0,0 +1,121 @@ + +package org.torproject.android; + +import android.content.Context; +import android.content.SharedPreferences; +import org.torproject.android.service.TorServiceUtils; + +import java.util.Locale; + +public class Prefs { + private final static String PREF_BRIDGES_ENABLED = "pref_bridges_enabled"; + private final static String PREF_BRIDGES_LIST = "pref_bridges_list"; + private final static String PREF_DEFAULT_LOCALE = "pref_default_locale"; + private final static String PREF_ENABLE_LOGGING = "pref_enable_logging"; + private final static String PREF_EXPANDED_NOTIFICATIONS = "pref_expanded_notifications"; + private final static String PREF_HAS_ROOT = "has_root"; + private final static String PREF_PERSIST_NOTIFICATIONS = "pref_persistent_notifications"; + private final static String PREF_START_ON_BOOT = "pref_start_boot"; + private final static String PREF_ALLOW_BACKGROUND_STARTS = "pref_allow_background_starts"; + private final static String PREF_TRANSPARENT = "pref_transparent"; + private final static String PREF_TRANSPARENT_ALL = "pref_transparent_all"; + private final static String PREF_TRANSPARENT_TETHERING = "pref_transparent_tethering"; + private final static String PREF_TRANSPROXY_REFRESH = "pref_transproxy_refresh"; + private final static String PREF_USE_SYSTEM_IPTABLES = "pref_use_sys_iptables"; + private final static String PREF_USE_VPN = "pref_vpn"; + + private static SharedPreferences prefs; + + public static void setContext(Context context) { + if (prefs == null) + prefs = TorServiceUtils.getSharedPrefs(context); + } + + private static void putBoolean(String key, boolean value) { + prefs.edit().putBoolean(key, value).apply(); + } + + private static void putString(String key, String value) { + prefs.edit().putString(key, value).apply(); + } + + public static boolean bridgesEnabled() { + return prefs.getBoolean(PREF_BRIDGES_ENABLED, false); + } + + public static void putBridgesEnabled(boolean value) { + putBoolean(PREF_BRIDGES_ENABLED, value); + } + + public static String getBridgesList() { + return prefs.getString(PREF_BRIDGES_LIST, ""); + } + + public static void setBridgesList(String value) { + putString(PREF_BRIDGES_LIST, value); + } + + public static String getDefaultLocale() { + return prefs.getString(PREF_DEFAULT_LOCALE, Locale.getDefault().getLanguage()); + } + + public static void setDefaultLocale(String value) { + putString(PREF_DEFAULT_LOCALE, value); + } + + public static boolean useSystemIpTables() { + return prefs.getBoolean(PREF_USE_SYSTEM_IPTABLES, false); + } + + public static boolean useRoot() { + return prefs.getBoolean(PREF_HAS_ROOT, false); + } + + public static boolean useTransparentProxying() { + return prefs.getBoolean(PREF_TRANSPARENT, false); + } + + public static boolean transparentProxyAll() { + return prefs.getBoolean(PREF_TRANSPARENT_ALL, false); + } + + public static boolean transparentTethering() { + return prefs.getBoolean(PREF_TRANSPARENT_TETHERING, false); + } + + public static boolean transProxyNetworkRefresh() { + return prefs.getBoolean(PREF_TRANSPROXY_REFRESH, false); + } + + public static boolean expandedNotifications() { + return prefs.getBoolean(PREF_EXPANDED_NOTIFICATIONS, false); + } + + public static boolean useDebugLogging() { + return prefs.getBoolean(PREF_ENABLE_LOGGING, false); + } + + public static boolean persistNotifications() { + return prefs.getBoolean(PREF_PERSIST_NOTIFICATIONS, true); + } + + public static boolean allowBackgroundStarts() { + return prefs.getBoolean(PREF_ALLOW_BACKGROUND_STARTS, true); + } + + public static boolean useVpn() { + return prefs.getBoolean(PREF_USE_VPN, false); + } + + public static void putUseVpn(boolean value) { + putBoolean(PREF_USE_VPN, value); + } + + public static boolean startOnBoot() { + return prefs.getBoolean(PREF_START_ON_BOOT, true); + } + + public static void putStartOnBoot(boolean value) { + putBoolean(PREF_START_ON_BOOT, value); + } +} diff --git a/src/org/torproject/android/service/OnBootReceiver.java b/src/org/torproject/android/service/OnBootReceiver.java index a97091e1..2429c4d6 100644 --- a/src/org/torproject/android/service/OnBootReceiver.java +++ b/src/org/torproject/android/service/OnBootReceiver.java @@ -5,30 +5,22 @@ import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.net.VpnService; +import org.torproject.android.Prefs; + public class OnBootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(context.getApplicationContext()); - - boolean startOnBoot = prefs.getBoolean("pref_start_boot",true); - boolean useVPN = prefs.getBoolean("pref_vpn",true); - - if (startOnBoot) + Prefs.setContext(context); + if (Prefs.startOnBoot()) { - - startService(TorServiceConstants.CMD_INIT,context); - startService(TorServiceConstants.CMD_START,context); - - if (useVPN) - startVpnService(context); - - } + startService(TorServiceConstants.ACTION_START, context); + if (Prefs.useVpn()) + startVpnService(context); + } } @SuppressLint("NewApi") diff --git a/src/org/torproject/android/service/StartTorReceiver.java b/src/org/torproject/android/service/StartTorReceiver.java new file mode 100644 index 00000000..087b01f4 --- /dev/null +++ b/src/org/torproject/android/service/StartTorReceiver.java @@ -0,0 +1,36 @@ + +package org.torproject.android.service; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; + +import org.torproject.android.Prefs; + +public class StartTorReceiver extends BroadcastReceiver implements TorServiceConstants { + + @Override + public void onReceive(Context context, Intent intent) { + /* sanitize the Intent before forwarding it to TorService */ + Prefs.setContext(context); + String action = intent.getAction(); + if (TextUtils.equals(action, ACTION_START)) { + String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME); + if (Prefs.allowBackgroundStarts()) { + Intent startTorIntent = new Intent(context, TorService.class); + startTorIntent.setAction(action); + if (packageName != null) + startTorIntent.putExtra(EXTRA_PACKAGE_NAME, packageName); + context.startService(startTorIntent); + } else if (!TextUtils.isEmpty(packageName)) { + // let the requesting app know that the user has disabled + // starting via Intent + Intent startsDisabledIntent = new Intent(ACTION_STATUS); + startsDisabledIntent.putExtra(EXTRA_STATUS, STATUS_STARTS_DISABLED); + startsDisabledIntent.setPackage(packageName); + context.sendBroadcast(startsDisabledIntent); + } + } + } +} diff --git a/src/org/torproject/android/service/TorResourceInstaller.java b/src/org/torproject/android/service/TorResourceInstaller.java index 3d992258..648f7524 100644 --- a/src/org/torproject/android/service/TorResourceInstaller.java +++ b/src/org/torproject/android/service/TorResourceInstaller.java @@ -8,12 +8,10 @@ import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; -import java.io.PrintWriter; import java.io.StringBufferInputStream; import java.util.ArrayList; import java.util.concurrent.TimeoutException; @@ -96,11 +94,13 @@ public class TorResourceInstaller implements TorServiceConstants { outFile = new File(installFolder, OBFSCLIENT_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); + setExecutable(outFile); is = context.getResources().openRawResource(R.raw.meek); outFile = new File(installFolder, MEEK_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); + setExecutable(outFile); cpuPath = "armeabi"; } @@ -111,17 +111,19 @@ public class TorResourceInstaller implements TorServiceConstants { outFile = new File(installFolder, TOR_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); + setExecutable(outFile); is = context.getAssets().open(cpuPath + "/polipo.mp3"); outFile = new File(installFolder, POLIPO_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); + setExecutable(outFile); is = context.getAssets().open(cpuPath + "/xtables.mp3"); outFile = new File(installFolder, IPTABLES_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); - + setExecutable(outFile); return true; } @@ -359,4 +361,11 @@ public class TorResourceInstaller implements TorServiceConstants { }*/ + private void setExecutable(File fileBin) { + fileBin.setReadable(true); + fileBin.setExecutable(true); + fileBin.setWritable(false); + fileBin.setWritable(true, true); + } + } diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index 195fe98f..bf065c32 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -8,6 +8,46 @@ package org.torproject.android.service; +import android.annotation.SuppressLint; +import android.app.Application; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Build; +import android.os.IBinder; +import android.os.RemoteException; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationCompat.Builder; +import android.support.v4.content.LocalBroadcastManager; +import android.text.TextUtils; +import android.util.Log; +import android.widget.RemoteViews; + +import net.freehaven.tor.control.ConfigEntry; +import net.freehaven.tor.control.EventHandler; +import net.freehaven.tor.control.TorControlConnection; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.sufficientlysecure.rootcommands.Shell; +import org.sufficientlysecure.rootcommands.command.SimpleCommand; +import org.torproject.android.OrbotConstants; +import org.torproject.android.OrbotMainActivity; +import org.torproject.android.Prefs; +import org.torproject.android.R; +import org.torproject.android.settings.AppManager; +import org.torproject.android.settings.TorifiedApp; +import org.torproject.android.vpn.OrbotVpnService; + import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -41,50 +81,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeoutException; -import net.freehaven.tor.control.ConfigEntry; -import net.freehaven.tor.control.EventHandler; -import net.freehaven.tor.control.TorControlConnection; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.sufficientlysecure.rootcommands.Shell; -import org.sufficientlysecure.rootcommands.command.SimpleCommand; -import org.torproject.android.OrbotConstants; -import org.torproject.android.OrbotMainActivity; -import org.torproject.android.R; -import org.torproject.android.settings.AppManager; -import org.torproject.android.settings.TorifiedApp; -import org.torproject.android.vpn.OrbotVpnService; - -import android.annotation.SuppressLint; -import android.app.Application; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Build; -import android.os.IBinder; -import android.os.RemoteException; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.NotificationCompat.Builder; -import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; -import android.widget.RemoteViews; - public class TorService extends Service implements TorServiceConstants, OrbotConstants, EventHandler { - public static boolean ENABLE_DEBUG_LOG = true; - - private int mCurrentStatus = STATUS_OFF; + private String mCurrentStatus = STATUS_OFF; private final static int CONTROL_SOCKET_TIMEOUT = 0; @@ -93,16 +93,14 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon private int mLastProcessId = -1; - private int mPortHTTP = 8118; - private int mPortSOCKS = 9050; + private int mPortHTTP = HTTP_PROXY_PORT_DEFAULT; + private int mPortSOCKS = SOCKS_PROXY_PORT_DEFAULT; private static final int NOTIFY_ID = 1; private static final int TRANSPROXY_NOTIFY_ID = 2; private static final int ERROR_NOTIFY_ID = 3; private static final int HS_NOTIFY_ID = 4; - private boolean prefPersistNotifications = true; - private static final int MAX_START_TRIES = 3; private ArrayList configBuffer = null; @@ -134,26 +132,17 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon private NotificationManager mNotificationManager = null; private Builder mNotifyBuilder; private Notification mNotification; - private boolean mShowExpandedNotifications = false; private boolean mNotificationShowing = false; - - private boolean mHasRoot = false; - private boolean mEnableTransparentProxy = false; - private boolean mTransProxyAll = false; - private boolean mTransProxyTethering = false; - private boolean mTransProxyNetworkRefresh = false; - - private boolean mUseVPN = false; + boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - private ExecutorService mExecutor = Executors.newFixedThreadPool(1); private NumberFormat mNumberFormat = null; public void debug(String msg) { - if (ENABLE_DEBUG_LOG) + if (Prefs.useDebugLogging()) { Log.d(TAG,msg); sendCallbackLogMessage(msg); @@ -163,7 +152,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon public void logException(String msg, Exception e) { - if (ENABLE_DEBUG_LOG) + if (Prefs.useDebugLogging()) { Log.e(TAG,msg,e); ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -179,8 +168,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } - private boolean findExistingProc () - { + private boolean findExistingTorDaemon() { if (fileTor != null) { try @@ -191,10 +179,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon if (mLastProcessId != -1 && conn != null) { sendCallbackLogMessage (getString(R.string.found_existing_tor_process)); - - mCurrentStatus = STATUS_ON; - sendCallbackStatus(mCurrentStatus); - + sendCallbackStatus(STATUS_ON); return true; } @@ -210,7 +195,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon else return false; } - /* (non-Javadoc) * @see android.app.Service#onLowMemory() @@ -223,14 +207,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } - - public int getTorStatus () - { - - return mCurrentStatus; - - } - private void clearNotifications () { if (mNotificationManager != null) @@ -239,7 +215,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon hmBuiltNodes.clear(); mNotificationShowing = false; - } @SuppressLint("NewApi") @@ -279,32 +254,26 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon mNotifyBuilder.setTicker(null); } - mNotifyBuilder.setOngoing(prefPersistNotifications); + mNotifyBuilder.setOngoing(Prefs.persistNotifications()); mNotification = mNotifyBuilder.build(); - if (Build.VERSION.SDK_INT >= 16 && mShowExpandedNotifications) { - - + if (Build.VERSION.SDK_INT >= 16 && Prefs.expandedNotifications()) { // Create remote view that needs to be set as bigContentView for the notification. RemoteViews expandedView = new RemoteViews(this.getPackageName(), R.layout.layout_notification_expanded); StringBuffer sbInfo = new StringBuffer(); - if (notifyType == NOTIFY_ID) expandedView.setTextViewText(R.id.text, notifyMsg); else { expandedView.setTextViewText(R.id.info, notifyMsg); - } if (hmBuiltNodes.size() > 0) { - //sbInfo.append(getString(R.string.your_tor_public_ips_) + '\n '); - Set itBuiltNodes = hmBuiltNodes.keySet(); for (String key : itBuiltNodes) { @@ -334,7 +303,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon mNotification.bigContentView = expandedView; } - if (prefPersistNotifications && (!mNotificationShowing)) + if (Prefs.persistNotifications() && (!mNotificationShowing)) { startForeground(NOTIFY_ID, mNotification); logNotice("Set background service to FOREGROUND"); @@ -352,55 +321,50 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon * @see android.app.Service#onStart(android.content.Intent, int) */ public int onStartCommand(Intent intent, int flags, int startId) { + if (intent != null) + new Thread (new IncomingIntentRouter(intent)).start(); + else + Log.d(TAG, "Got null onStartCommand() intent"); - new Thread (new TorStarter(intent)).start(); - return Service.START_STICKY; - } - private class TorStarter implements Runnable + private class IncomingIntentRouter implements Runnable { Intent mIntent; - public TorStarter (Intent intent) + public IncomingIntentRouter (Intent intent) { mIntent = intent; } - public void run (){ - try{ - //if this is a start on boot launch turn tor on - if (mIntent != null){ - String action = mIntent.getAction(); - - if (action!=null){ - if(action.equals(Intent.ACTION_BOOT_COMPLETED)||action.equals(CMD_START)){ - setTorProfile(STATUS_ON); - }else if (action.equals(CMD_STOP)){ - setTorProfile(STATUS_OFF); - }else if (action.equals(CMD_INIT)){ - initialize(); - sendCallbackStatus(mCurrentStatus); - }else if (action.equals(CMD_NEWNYM)){ - newIdentity(); - }else if (action.equals(CMD_FLUSH)){ - flushTransparentProxyRules(); - }else if (action.equals(CMD_UPDATE)){ - processSettings(); - }else if (action.equals(CMD_VPN)){ - enableVpnProxy(); - } - else if (action.equals(CMD_VPN_CLEAR)){ - clearVpnProxy(); - } - } - }else{ - Log.d(TAG, "Got null onStartCommand() intent"); + public void run() { + String action = mIntent.getAction(); + + if (action != null) { + if (action.equals(ACTION_START)) { + replyWithStatus(mIntent); + startTor(); + // stopTor() is called when the Service is destroyed + } + else if (action.equals(ACTION_STATUS)) { + replyWithStatus(mIntent); + } + else if (action.equals(CMD_SIGNAL_HUP)) { + requestTorRereadConfig(); + } else if (action.equals(CMD_NEWNYM)) { + newIdentity(); + } else if (action.equals(CMD_FLUSH)) { + flushTransparentProxyRules(); + } else if (action.equals(CMD_UPDATE_TRANS_PROXY)) { + processTransparentProxying(); + } else if (action.equals(CMD_VPN)) { + enableVpnProxy(); + } else if (action.equals(CMD_VPN_CLEAR)) { + clearVpnProxy(); + } else { + Log.w(TAG, "unhandled TorService Intent: " + action); } - - }catch (Exception e){ - Log.e(TAG,"error onBind",e); } } } @@ -414,52 +378,34 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } @Override - public boolean stopService(Intent name) { - logNotice("TorService is being stopped: " + name); - return super.stopService(name); - } - - @Override - public void onDestroy () - { - String msg = ("TorService is being DESTROYED... shutting down!"); - Log.d(TAG, msg); - sendCallbackLogMessage(msg); + public void onDestroy() { + stopTor(); unregisterReceiver(mNetworkStateReceiver); - clearNotifications (); super.onDestroy(); } - private void stopTor () - { + private void stopTor() { + Log.i("TorService", "stopTor"); + try { + sendCallbackStatus(STATUS_STOPPING); + sendCallbackLogMessage(getString(R.string.status_shutting_down)); - try - { - Log.d(TAG,"Tor is stopping NOW"); - - shutdownTorProcess (); + killAllDaemons(); //stop the foreground priority and make sure to remove the persistant notification stopForeground(true); - mCurrentStatus = STATUS_OFF; - sendCallbackStatus(mCurrentStatus); - - if (mHasRoot && mEnableTransparentProxy) + if (Prefs.useRoot() && Prefs.useTransparentProxying()) { Shell shellRoot = Shell.startRootShell(); disableTransparentProxy(shellRoot); shellRoot.close(); } - clearNotifications(); - sendCallbackLogMessage(getString(R.string.status_disabled)); - } catch (CannotKillException e) { - Log.d(TAG, "An error occured stopping Tor", e); logNotice("An error occured stopping Tor: " + e.getMessage()); sendCallbackLogMessage(getString(R.string.unable_to_reset_tor)); showToolbarNotification(getString(R.string.unable_to_reset_tor), @@ -467,11 +413,11 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } catch (Exception e) { - Log.d(TAG, "An error occured stopping Tor",e); logNotice("An error occured stopping Tor: " + e.getMessage()); sendCallbackLogMessage(getString(R.string.something_bad_happened)); - } + clearNotifications(); + sendCallbackStatus(STATUS_OFF); } @@ -543,31 +489,49 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } - private void shutdownTorProcess () throws Exception - { - - if (conn != null) - { - + private void killAllDaemons() throws CannotKillException { + if (conn != null) { logNotice("Using control port to shutdown Tor"); - try { logNotice("sending HALT signal to Tor process"); conn.shutdownTor("HALT"); - } catch (Exception e) { - Log.d(TAG,"error shutting down Tor via connection",e); + } catch (IOException e) { + Log.d(TAG, "error shutting down Tor via connection", e); } conn = null; } - killProcess(fileTor); - - killProcess(filePolipo); - killProcess(fileObfsclient); - killProcess(fileMeekclient); + // try these separately in case one fails, then it can try the next + File cannotKillFile = null; + try { + killProcess(fileObfsclient); + } catch (IOException e) { + e.printStackTrace(); + cannotKillFile = fileObfsclient; + } + try { + killProcess(fileMeekclient); + } catch (IOException e) { + e.printStackTrace(); + cannotKillFile = fileMeekclient; + } + try { + killProcess(filePolipo); + } catch (IOException e) { + e.printStackTrace(); + cannotKillFile = filePolipo; + } + try { + killProcess(fileTor); + } catch (IOException e) { + e.printStackTrace(); + cannotKillFile = fileTor; + } + if (cannotKillFile != null) + throw new CannotKillException(cannotKillFile); } public class CannotKillException extends IllegalStateException { @@ -578,7 +542,28 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } } - private void killProcess(File fileProcBin) throws IOException { + private void requestTorRereadConfig() { + try { + conn.signal("HUP"); + return; + } catch (IOException e) { + e.printStackTrace(); + } + // if that fails, try again using native utils + try { + killProcess(fileTor, "-1"); // this is -HUP + } catch (CannotKillException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void killProcess(File fileProcBin) throws IOException, CannotKillException { + killProcess(fileProcBin, "-9"); // this is -KILL + } + + private void killProcess(File fileProcBin, String signal) throws IOException, CannotKillException { int procId = -1; int killAttempts = 0; @@ -592,16 +577,16 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon * uninstall/reinstall with different UID. */ Shell shell; - if (mHasRoot && killAttempts > 2) { + if (Prefs.useRoot() && killAttempts > 2) { shell = Shell.startRootShell(); Log.i(TAG, "using a root shell"); } else { shell = Shell.startShell(); } - shell.add(new SimpleCommand("busybox killall " + fileProcBin.getName())); - shell.add(new SimpleCommand("toolbox kill -9 " + pidString)); - shell.add(new SimpleCommand("busybox kill -9 " + pidString)); - shell.add(new SimpleCommand("kill -9 " + pidString)); + shell.add(new SimpleCommand("busybox killall " + signal + " " + fileProcBin.getName())); + shell.add(new SimpleCommand("toolbox kill " + signal + " " + pidString)); + shell.add(new SimpleCommand("busybox kill " + signal + " " + pidString)); + shell.add(new SimpleCommand("kill " + signal + " " + pidString)); try { Thread.sleep(1000); } catch (InterruptedException e) { @@ -617,7 +602,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon { if (msg != null && msg.trim().length() > 0) { - if (ENABLE_DEBUG_LOG) + if (Prefs.useDebugLogging()) Log.d(TAG, msg); sendCallbackLogMessage(msg); @@ -627,11 +612,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon @Override public void onCreate() { super.onCreate(); - initialize(); - } - - private void initialize() - { + try { mNumberFormat = NumberFormat.getInstance(Locale.getDefault()); //localized numbers! @@ -646,9 +627,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } - initBinariesAndDirectories(); - updateSettings(); new Thread(new Runnable () { @@ -656,7 +635,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon { try { - findExistingProc (); + findExistingTorDaemon(); } catch (Exception e) { @@ -692,17 +671,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon appCacheHome = getDir(DIRECTORY_TOR_DATA,Application.MODE_PRIVATE); fileTor= new File(appBinHome, TOR_ASSET_KEY); - filePolipo = new File(appBinHome, POLIPO_ASSET_KEY); - fileObfsclient = new File(appBinHome, OBFSCLIENT_ASSET_KEY); - fileMeekclient = new File(appBinHome, MEEK_ASSET_KEY); - fileTorRc = new File(appBinHome, TORRC_ASSET_KEY); - fileXtables = new File(appBinHome, IPTABLES_ASSET_KEY); - + SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); String version = prefs.getString(PREF_BINARY_TOR_VERSION_INSTALLED,null); @@ -721,8 +695,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } updateTorConfigFile (); - - } private boolean updateTorConfigFile () throws FileNotFoundException, IOException, TimeoutException @@ -737,7 +709,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon fileControlPort = new File(appBinHome,"control.txt"); extraLines.append(TORRC_CONTROLPORT_FILE_KEY).append(' ').append(fileControlPort.getCanonicalPath()).append('\n'); - if (mTransProxyTethering) + if (Prefs.transparentTethering()) { extraLines.append("TransListenAddress 0.0.0.0").append('\n'); extraLines.append("DNSListenAddress 0.0.0.0").append('\n'); @@ -780,78 +752,68 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon return success; } - - private boolean enableBinExec (File fileBin) throws Exception - { + + /** + * Send Orbot's status in reply to an + * {@link TorServiceConstants#ACTION_START} {@link Intent}, targeted only to + * the app that sent the initial request. + */ + private void replyWithStatus(Intent startRequest) { + String packageName = startRequest.getStringExtra(EXTRA_PACKAGE_NAME); + + Intent reply = new Intent(ACTION_STATUS); + reply.putExtra(EXTRA_STATUS, mCurrentStatus); + reply.putExtra(EXTRA_SOCKS_PROXY, "socks://127.0.0.1:" + mPortSOCKS); + reply.putExtra(EXTRA_SOCKS_PROXY_HOST, "127.0.0.1"); + reply.putExtra(EXTRA_SOCKS_PROXY_PORT, mPortSOCKS); + reply.putExtra(EXTRA_HTTP_PROXY, "http://127.0.0.1" + mPortHTTP); + reply.putExtra(EXTRA_HTTP_PROXY_HOST, "127.0.0.1"); + reply.putExtra(EXTRA_HTTP_PROXY_PORT, mPortHTTP); - logNotice(fileBin.getName() + ": PRE: Is binary exec? " + fileBin.canExecute()); - - if (!fileBin.canExecute()) + if (packageName != null) { - logNotice("(re)Setting permission on binary: " + fileBin.getCanonicalPath()); - - Shell shell = Shell.startShell(); - shell.add(new SimpleCommand("chmod " + CHMOD_EXE_VALUE + ' ' + fileBin.getCanonicalPath())).waitForFinish(); - - File fileTest = new File(fileBin.getCanonicalPath()); - logNotice(fileTest.getName() + ": POST: Is binary exec? " + fileTest.canExecute()); - - shell.close(); + reply.setPackage(packageName); + sendBroadcast(reply); } - - return fileBin.canExecute(); - } - - - private void updateSettings () throws TimeoutException, IOException - { - - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); + else + { + LocalBroadcastManager.getInstance(this).sendBroadcast(reply); - mHasRoot = prefs.getBoolean(PREF_HAS_ROOT,false); - - mEnableTransparentProxy = prefs.getBoolean("pref_transparent", false); - mTransProxyAll = prefs.getBoolean("pref_transparent_all", false); - mTransProxyTethering = prefs.getBoolean("pref_transparent_tethering", false); - mTransProxyNetworkRefresh = prefs.getBoolean("pref_transproxy_refresh", false); - - mShowExpandedNotifications = prefs.getBoolean("pref_expanded_notifications", false); - - ENABLE_DEBUG_LOG = prefs.getBoolean("pref_enable_logging",false); - Log.i(TAG,"debug logging:" + ENABLE_DEBUG_LOG); + } - prefPersistNotifications = prefs.getBoolean(OrbotConstants.PREF_PERSIST_NOTIFICATIONS, true); - - mUseVPN = prefs.getBoolean("pref_vpn", false); } - - private void startTor () throws Exception - { + + /** + * The entire process for starting tor and related services is run from this method. + */ + private void startTor() { + // STATUS_STARTING is set in onCreate() + if (mCurrentStatus == STATUS_STOPPING) { + // these states should probably be handled better + sendCallbackLogMessage("Ignoring start request, currently " + mCurrentStatus); + return; + } else if (mCurrentStatus == STATUS_ON && findExistingTorDaemon()) { - mCurrentStatus = STATUS_CONNECTING; - sendCallbackStatus(mCurrentStatus); + sendCallbackLogMessage("Ignoring start request, already started."); + + return; + } + // make sure there are no stray daemons running + killAllDaemons(); + + sendCallbackStatus(STATUS_STARTING); + sendCallbackLogMessage(getString(R.string.status_starting_up)); + logNotice(getString(R.string.status_starting_up)); + + try { if (fileTor == null) initBinariesAndDirectories(); - enableBinExec(fileTor); - enableBinExec(filePolipo); - enableBinExec(fileObfsclient); - enableBinExec(fileMeekclient); - enableBinExec(fileXtables); - - updateSettings (); - - logNotice(getString(R.string.status_starting_up)); - sendCallbackLogMessage(getString(R.string.status_starting_up)); - ArrayList customEnv = new ArrayList(); - - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); - boolean useBridges = prefs.getBoolean(OrbotConstants.PREF_BRIDGES_ENABLED, false); - if (useBridges) - if (mUseVPN && !mIsLollipop) + if (Prefs.bridgesEnabled()) + if (Prefs.useVpn() && !mIsLollipop) customEnv.add("TOR_PT_PROXY=socks5://127.0.0.1:" + OrbotVpnService.mSocksProxyPort); String baseDirectory = fileTor.getParent(); @@ -864,7 +826,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon if (mPortHTTP != -1) runPolipoShellCmd(shellUser); - if (mHasRoot && mEnableTransparentProxy) + if (Prefs.useRoot() && Prefs.useTransparentProxying()) { Shell shellRoot = Shell.startRootShell(); @@ -874,7 +836,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon shellRoot.close(); } - if (mUseVPN) //we need to turn on VPN here so the proxy is running + if (Prefs.useVpn()) //we need to turn on VPN here so the proxy is running { enableVpnProxy(); } @@ -885,24 +847,35 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon else { showToolbarNotification(getString(R.string.unable_to_start_tor), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); - } - shellUser.close(); + + } catch (CannotKillException e) { + logException(e.getMessage(), e); + showToolbarNotification(getString(R.string.unable_to_reset_tor), + ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); + stopTor(); + } catch (Exception e) { + logException("Unable to start Tor: " + e.toString(), e); + showToolbarNotification( + getString(R.string.unable_to_start_tor) + ": " + e.getMessage(), + ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); + stopTor(); + } } - private boolean flushTransparentProxyRules () throws Exception - { - - if (mHasRoot) + private boolean flushTransparentProxyRules () { + if (Prefs.useRoot()) { if (mTransProxy == null) - { mTransProxy = new TorTransProxy(this, fileXtables); - + + try { + mTransProxy.flushTransproxyRules(this); + } catch (Exception e) { + e.printStackTrace(); + return false; } - - mTransProxy.flushTransproxyRules(this); return true; } @@ -943,7 +916,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon int code = 0; // Default state is "okay" - if(mTransProxyAll) + if(Prefs.transparentProxyAll()) { code = mTransProxy.setTransparentProxyingAll(this, true, shell); @@ -960,7 +933,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon if (code == 0) { - if (mTransProxyTethering) + if (Prefs.transparentTethering()) { showToolbarNotification(getString(R.string.transproxy_enabled_for_tethering_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor); @@ -1119,7 +1092,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon logNotice(log.toString()); } - sendCallbackLogMessage(getString(R.string.privoxy_is_running_on_port_) + PORT_HTTP); + sendCallbackLogMessage(getString(R.string.privoxy_is_running_on_port_) + mPortHTTP); logNotice("Polipo process id=" + polipoProcId); @@ -1127,11 +1100,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon private int initControlConnection (int maxTries, boolean isReconnect) throws Exception, RuntimeException { - int i = 0; int controlPort = -1; - int attempt = 0; - logNotice( "Waiting for control port..."); @@ -1168,9 +1138,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon // logNotice("waiting..."); Thread.sleep(1000); } catch (Exception e){} - - - } if (conn != null) @@ -1204,9 +1171,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon conn.setConf("Log", "debug file " + fileLog2.getCanonicalPath()); }*/ - mCurrentStatus = STATUS_CONNECTING; - sendCallbackStatus(mCurrentStatus); - String confSocks = conn.getInfo("net/listeners/socks"); StringTokenizer st = new StringTokenizer(confSocks," "); @@ -1219,7 +1183,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); - String socksPortPref = prefs.getString(OrbotConstants.PREF_SOCKS, TorServiceConstants.PORT_SOCKS_DEFAULT); + String socksPortPref = prefs.getString(OrbotConstants.PREF_SOCKS, + String.valueOf(TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT)); if (socksPortPref.indexOf(':')!=-1) socksPortPref = socksPortPref.split(":")[1]; @@ -1352,45 +1317,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon return result; } - - /* - private void getTorStatus () throws IOException - { - try - { - - if (conn != null) - { - // get a single value. - - // get several values - - if (mCurrentStatus == STATUS_CONNECTING) - { - //Map vals = conn.getInfo(Arrays.asList(new String[]{ - // "status/bootstrap-phase", "status","version"})); - - String bsPhase = conn.getInfo("status/bootstrap-phase"); - Log.d(TAG, "bootstrap-phase: " + bsPhase); - - - } - else - { - // String status = conn.getInfo("status/circuit-established"); - // Log.d(TAG, "status/circuit-established=" + status); - } - } - } - catch (Exception e) - { - Log.d(TAG, "Unable to get Tor status from control port"); - mCurrentStatus = STATUS_UNAVAILABLE; - } - - }*/ - - + public void addEventHandler () throws Exception { // We extend NullEventHandler so that we don't need to provide empty @@ -1406,9 +1333,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon // "DEBUG", "INFO", "NOTICE", "WARN", "ERR"})); logNotice( "SUCCESS added control port event handler"); - - - } /** @@ -1425,78 +1349,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon public int getSOCKSPort() throws RemoteException { return mPortSOCKS; } - - - public void setTorProfile(int newState) { - - if (newState == STATUS_ON) - { - - if (mCurrentStatus == STATUS_OFF) - { - sendCallbackLogMessage (getString(R.string.status_starting_up)); - - - try - { - - boolean found = findExistingProc (); - - if (!found) - { - killProcess(fileTor); - killProcess(filePolipo); - - startTor(); - } - } - catch (CannotKillException e) - { - logException(e.getMessage(), e); - mCurrentStatus = STATUS_OFF; - sendCallbackStatus(mCurrentStatus); - showToolbarNotification(getString(R.string.unable_to_reset_tor), - ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); - stopTor(); - } - catch (Exception e) - { - - logException("Unable to start Tor: " + e.toString(),e); - mCurrentStatus = STATUS_OFF; - sendCallbackStatus(mCurrentStatus); - - showToolbarNotification(getString(R.string.unable_to_start_tor) + ": " + e.getMessage(), ERROR_NOTIFY_ID, R.drawable.ic_stat_notifyerr); - stopTor(); - } - - } - } - else if (newState == STATUS_OFF) - { - sendCallbackLogMessage (getString(R.string.status_shutting_down)); - - stopTor(); - - mCurrentStatus = STATUS_OFF; - sendCallbackStatus(mCurrentStatus); - - - } - } public void enableVpnProxy () { - debug ("enabling VPN Proxy"); - - mUseVPN = true; - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); - Editor ePrefs = prefs.edit(); - ePrefs.putBoolean("pref_vpn", true); - ePrefs.commit(); - - processSettings(); + Prefs.putUseVpn(true); + processTransparentProxying(); Intent intent = new Intent(TorService.this, OrbotVpnService.class); intent.setAction("start"); @@ -1540,51 +1398,26 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon public void clearVpnProxy () { debug ("clearing VPN Proxy"); - - mUseVPN = false; - - - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); - Editor ePrefs = prefs.edit(); - ePrefs.putBoolean("pref_vpn", false); - ePrefs.commit(); - - processSettings(); + Prefs.putUseVpn(false); + processTransparentProxying(); Intent intent = new Intent(TorService.this, OrbotVpnService.class); intent.setAction("stop"); startService(intent); } - - + @Override public void message(String severity, String msg) { - - logNotice(severity + ": " + msg); - - if (msg.indexOf(TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE)!=-1) - { - mCurrentStatus = STATUS_ON; - sendCallbackStatus(mCurrentStatus); - - - showToolbarNotification(getString(R.string.status_activated), NOTIFY_ID, R.drawable.ic_stat_tor); - } - - - } - + @Override public void newDescriptors(List orList) { - } - + @Override public void orConnStatus(String status, String orName) { - StringBuilder sb = new StringBuilder(); sb.append("orConnStatus ("); sb.append(parseNodeName(orName) ); @@ -1592,10 +1425,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon sb.append(status); debug(sb.toString()); - } - + @Override public void streamStatus(String status, String streamID, String target) { StringBuilder sb = new StringBuilder(); @@ -1605,10 +1437,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon sb.append(status); logNotice(sb.toString()); - } - + @Override public void unrecognized(String type, String msg) { StringBuilder sb = new StringBuilder(); @@ -1618,10 +1449,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon sb.append(msg); logNotice(sb.toString()); - - } - + + @Override public void bandwidthUsed(long read, long written) { if (read != lastRead || written != lastWritten) @@ -1638,20 +1468,17 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon if (read > 0 || written > 0) iconId = R.drawable.ic_stat_tor_xfer; - if (mConnectivity && prefPersistNotifications) + if (mConnectivity && Prefs.persistNotifications()) showToolbarNotification(sb.toString(), NOTIFY_ID, iconId); mTotalTrafficWritten += written; mTotalTrafficRead += read; - - } lastWritten = written; lastRead = read; - sendCallbackStatusMessage(lastWritten, lastRead, mTotalTrafficWritten, mTotalTrafficRead); - + sendCallbackBandwidth(lastWritten, lastRead, mTotalTrafficWritten, mTotalTrafficRead); } private String formatCount(long count) { @@ -1671,7 +1498,10 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon public void circuitStatus(String status, String circID, String path) { - + /* once the first circuit is complete, then announce that Orbot is on*/ + if (mCurrentStatus == STATUS_STARTING && TextUtils.equals(status, "BUILT")) + sendCallbackStatus(STATUS_ON); + StringBuilder sb = new StringBuilder(); sb.append("Circuit ("); sb.append((circID)); @@ -1713,27 +1543,14 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon sb.append (" > "); } - if (ENABLE_DEBUG_LOG) + if (Prefs.useDebugLogging()) debug(sb.toString()); else if(status.equals("BUILT")) - { - - if (mCurrentStatus == STATUS_CONNECTING) - mCurrentStatus = STATUS_ON; - - sendCallbackStatus(mCurrentStatus); - - logNotice(sb.toString()); - - } else if (status.equals("CLOSED")) - { logNotice(sb.toString()); - } - - if (mShowExpandedNotifications) + if (Prefs.expandedNotifications()) { //get IP from last nodename if(status.equals("BUILT")){ @@ -1789,7 +1606,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon Proxy proxy = null; - if (!mUseVPN) //if not on the VPN then we should proxy + if (!Prefs.useVpn()) //if not on the VPN then we should proxy { proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118)); conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy); @@ -1869,21 +1686,16 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon else return node; } - - - public void processSettings (){ + public void processTransparentProxying() { try{ - boolean hadEnableTransparentProxy = mEnableTransparentProxy; - updateSettings (); - if (mHasRoot) + if (Prefs.useRoot()) { Shell shell = Shell.startRootShell(); - if (hadEnableTransparentProxy){ - disableTransparentProxy(shell); - } - if (mEnableTransparentProxy){ + if (Prefs.useTransparentProxying()){ enableTransparentProxy(shell); + } else { + disableTransparentProxy(shell); } shell.close(); } @@ -2070,58 +1882,46 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } catch (Exception ioe) { - logException("Unable to update Tor configuration: " + ioe.getMessage(),ioe); - } return false; - } - - - - - private void sendCallbackStatusMessage (long upload, long download, long written, long read) - { - - - Intent intent = new Intent("log"); - // You can also include some extra data. - intent.putExtra("up",upload); - intent.putExtra("down",download); - intent.putExtra("written",written); - intent.putExtra("read",read); - - LocalBroadcastManager.getInstance(this).sendBroadcast(intent); + private void sendCallbackBandwidth(long upload, long download, long written, long read) { + Intent intent = new Intent(LOCAL_ACTION_BANDWIDTH); + intent.putExtra("up",upload); + intent.putExtra("down",download); + intent.putExtra("written",written); + intent.putExtra("read",read); + intent.putExtra(EXTRA_STATUS, mCurrentStatus); + + LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } - - // private ArrayList mLogBuffer = new ArrayList(); - + private void sendCallbackLogMessage (String logMessage) { - - Intent intent = new Intent("log"); + Intent intent = new Intent(LOCAL_ACTION_LOG); // You can also include some extra data. - intent.putExtra("log", logMessage); + intent.putExtra(LOCAL_EXTRA_LOG, logMessage); + intent.putExtra(EXTRA_STATUS, mCurrentStatus); + LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } - private void sendCallbackStatus (int currentStatus) - { - - - Intent intent = new Intent("status"); - // You can also include some extra data. - intent.putExtra("status", currentStatus); - LocalBroadcastManager.getInstance(this).sendBroadcast(intent); + private void sendCallbackStatus(String currentStatus) { + mCurrentStatus = currentStatus; + Intent intent = new Intent(ACTION_STATUS); + intent.putExtra(EXTRA_STATUS, currentStatus); + // send for Orbot internals, using secure local broadcast + LocalBroadcastManager.getInstance(this).sendBroadcast(intent); + // send for any apps that are interested + sendBroadcast(intent); } - /* * Another way to do this would be to use the Observer pattern by defining the @@ -2189,7 +1989,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon { if (mConnectivity) { - if (mHasRoot && mEnableTransparentProxy && mTransProxyNetworkRefresh) + if (Prefs.useRoot() && Prefs.useTransparentProxying() && Prefs.transProxyNetworkRefresh()) { Shell shell = Shell.startRootShell(); @@ -2199,7 +1999,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon shell.close(); } - else if (mUseVPN) //we need to turn on VPN here so the proxy is running + else if (Prefs.useVpn()) //we need to turn on VPN here so the proxy is running refreshVpnProxy(); } @@ -2233,7 +2033,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon enableTransProxyAndDNSPorts(transPort, dnsPort); */ - boolean useBridges = prefs.getBoolean(OrbotConstants.PREF_BRIDGES_ENABLED, false); + boolean useBridges = Prefs.bridgesEnabled(); boolean becomeRelay = prefs.getBoolean(OrbotConstants.PREF_OR, false); boolean ReachableAddresses = prefs.getBoolean(OrbotConstants.PREF_REACHABLE_ADDRESSES,false); @@ -2249,7 +2049,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon extraLines.append("UseBridges 0").append('\n'); - if (mUseVPN) //set the proxy here if we aren't using a bridge + if (Prefs.useVpn()) //set the proxy here if we aren't using a bridge { if (!mIsLollipop) @@ -2300,7 +2100,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon extraLines.append("UseBridges 1").append('\n'); - String bridgeList = new String(prefs.getString(OrbotConstants.PREF_BRIDGES_LIST,"").getBytes("ISO-8859-1")); + String bridgeList = new String(Prefs.getBridgesList().getBytes("ISO-8859-1")); if (bridgeList != null && bridgeList.length() > 1) //longer then 1 = some real values here { @@ -2499,8 +2299,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } - - if (mUseVPN) + if (Prefs.useVpn()) { extraLines.append("DNSListenAddress" + ' ' + "10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT).append('\n'); } @@ -2518,34 +2317,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon } return new String(out); } - - /* - private void enableSocks (String socks, boolean safeSocks) throws RemoteException - { - updateConfiguration("SOCKSPort", socks, false); - updateConfiguration("SafeSocks", safeSocks ? "1" : "0", false); - updateConfiguration("TestSocks", "1", false); - updateConfiguration("WarnUnsafeSocks", "1", false); - saveConfiguration(); - - } - - private void enableTransProxyAndDNSPorts (String transPort, String dnsPort) throws RemoteException - { - logMessage ("Transparent Proxying: enabling port..."); - - updateConfiguration("TransPort",transPort,false); - updateConfiguration("DNSPort",dnsPort,false); - updateConfiguration("VirtualAddrNetwork","10.192.0.0/10",false); - updateConfiguration("AutomapHostsOnResolve","1",false); - saveConfiguration(); - }*/ - - private void blockPlaintextPorts (String portList) throws RemoteException - { - updateConfiguration("RejectPlaintextPorts",portList,false); - } - + //using Google DNS for now as the public DNS server private String writeDNSFile () throws IOException { diff --git a/src/org/torproject/android/service/TorServiceConstants.java b/src/org/torproject/android/service/TorServiceConstants.java index 55ff6c3b..3d34deb5 100644 --- a/src/org/torproject/android/service/TorServiceConstants.java +++ b/src/org/torproject/android/service/TorServiceConstants.java @@ -1,7 +1,10 @@ /* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */ /* See LICENSE for licensing information */ + package org.torproject.android.service; +import android.content.Intent; + public interface TorServiceConstants { public final static String TOR_APP_USERNAME = "org.torproject.android"; @@ -46,46 +49,84 @@ public interface TorServiceConstants { public final static String CHMOD_EXE_VALUE = "770"; public final static int FILE_WRITE_BUFFER_SIZE = 1024; - - //HTTP Proxy server port - public static int PORT_HTTP = 8118; //just like Privoxy! - - //Socks port client connects to, server is the Tor binary - public static String PORT_SOCKS_DEFAULT = "9050"; - - - //what is says! + public final static String IP_LOCALHOST = "127.0.0.1"; public final static int UPDATE_TIMEOUT = 1000; public final static int TOR_TRANSPROXY_PORT_DEFAULT = 9040; public final static int STANDARD_DNS_PORT = 53; public final static int TOR_DNS_PORT_DEFAULT = 5400; - + public final static int CONTROL_PORT_DEFAULT = 9051; + public final static int HTTP_PROXY_PORT_DEFAULT = 8118; // like Privoxy! + public final static int SOCKS_PROXY_PORT_DEFAULT = 9050; + //path to check Tor against public final static String URL_TOR_CHECK = "https://check.torproject.org"; //control port public final static String TOR_CONTROL_PORT_MSG_BOOTSTRAP_DONE = "Bootstrapped 100%"; + public final static String LOG_NOTICE_HEADER = "NOTICE"; + public final static String LOG_NOTICE_BOOTSTRAPPED = "Bootstrapped"; - public final static int STATUS_OFF = 0; - public final static int STATUS_ON = 1; - public final static int STATUS_CONNECTING = 2; - - public static final int STATUS_MSG = 1; - public static final int ENABLE_TOR_MSG = 2; - public static final int DISABLE_TOR_MSG = 3; - public static final int LOG_MSG = 4; - - public static final String CMD_START = "start"; - public static final String CMD_STOP = "stop"; + /** + * A request to Orbot to transparently start Tor services + */ + public final static String ACTION_START = "org.torproject.android.intent.action.START"; + /** + * {@link Intent} send by Orbot with {@code ON/OFF/STARTING/STOPPING} status + */ + public final static String ACTION_STATUS = "org.torproject.android.intent.action.STATUS"; + /** + * {@code String} that contains a status constant: {@link #STATUS_ON}, + * {@link #STATUS_OFF}, {@link #STATUS_STARTING}, or + * {@link #STATUS_STOPPING} + */ + public final static String EXTRA_STATUS = "org.torproject.android.intent.extra.STATUS"; + /** + * A {@link String} {@code packageName} for Orbot to direct its status reply + * to, used in {@link #ACTION_START} {@link Intent}s sent to Orbot + */ + public final static String EXTRA_PACKAGE_NAME = "org.torproject.android.intent.extra.PACKAGE_NAME"; + /** + * The SOCKS proxy settings in URL form. + */ + public final static String EXTRA_SOCKS_PROXY = "org.torproject.android.intent.extra.SOCKS_PROXY"; + public final static String EXTRA_SOCKS_PROXY_HOST = "org.torproject.android.intent.extra.SOCKS_PROXY_HOST"; + public final static String EXTRA_SOCKS_PROXY_PORT = "org.torproject.android.intent.extra.SOCKS_PROXY_PORT"; + /** + * The HTTP proxy settings in URL form. + */ + public final static String EXTRA_HTTP_PROXY = "org.torproject.android.intent.extra.HTTP_PROXY"; + public final static String EXTRA_HTTP_PROXY_HOST = "org.torproject.android.intent.extra.HTTP_PROXY_HOST"; + public final static String EXTRA_HTTP_PROXY_PORT = "org.torproject.android.intent.extra.HTTP_PROXY_PORT"; + + public final static String LOCAL_ACTION_LOG = "log"; + public final static String LOCAL_ACTION_BANDWIDTH = "bandwidth"; + public final static String LOCAL_EXTRA_LOG = "log"; + + /** + * All tor-related services and daemons are stopped + */ + public final static String STATUS_OFF = "OFF"; + /** + * All tor-related services and daemons have completed starting + */ + public final static String STATUS_ON = "ON"; + public final static String STATUS_STARTING = "STARTING"; + public final static String STATUS_STOPPING = "STOPPING"; + /** + * The user has disabled the ability for background starts triggered by + * apps. Fallback to the old Intent that brings up Orbot. + */ + public final static String STATUS_STARTS_DISABLED = "STARTS_DISABLED"; + + // actions for internal command Intents + public static final String CMD_SIGNAL_HUP = "signal_hup"; public static final String CMD_FLUSH = "flush"; public static final String CMD_NEWNYM = "newnym"; - public static final String CMD_INIT = "init"; public static final String CMD_VPN = "vpn"; public static final String CMD_VPN_CLEAR = "vpnclear"; - public static final String CMD_UPDATE = "update"; - - + public static final String CMD_UPDATE_TRANS_PROXY = "update"; + public static final String BINARY_TOR_VERSION = "0.2.6.7"; public static final String PREF_BINARY_TOR_VERSION_INSTALLED = "BINARY_TOR_VERSION_INSTALLED"; @@ -93,15 +134,7 @@ public interface TorServiceConstants { public static final String OBFSCLIENT_ASSET_KEY = "obfs4proxy"; public static final String MEEK_ASSET_KEY = "meek-client"; - - - public static final int MESSAGE_TRAFFIC_COUNT = 5; - - //name of the iptables binary public final static String IPTABLES_ASSET_KEY = "xtables"; - - public final static int DEFAULT_CONTROL_PORT = 9051; - } diff --git a/src/org/torproject/android/service/TorTransProxy.java b/src/org/torproject/android/service/TorTransProxy.java index 89663fbc..f88e46b0 100644 --- a/src/org/torproject/android/service/TorTransProxy.java +++ b/src/org/torproject/android/service/TorTransProxy.java @@ -3,20 +3,17 @@ package org.torproject.android.service; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.concurrent.TimeoutException; - import org.sufficientlysecure.rootcommands.Shell; import org.sufficientlysecure.rootcommands.command.SimpleCommand; import org.torproject.android.OrbotConstants; +import org.torproject.android.Prefs; import org.torproject.android.settings.TorifiedApp; import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; public class TorTransProxy implements TorServiceConstants { - private boolean useSystemIpTables = false; private String mSysIptables = null; private TorService mTorService = null; private File mFileXtables = null; @@ -46,12 +43,8 @@ public class TorTransProxy implements TorServiceConstants { { String ipTablesPath = null; - - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(context); - useSystemIpTables = prefs.getBoolean(OrbotConstants.PREF_USE_SYSTEM_IPTABLES, false); - - if (useSystemIpTables) + if (Prefs.useSystemIpTables()) { ipTablesPath = findSystemIPTables(); } @@ -70,11 +63,7 @@ public class TorTransProxy implements TorServiceConstants { String ipTablesPath = null; - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(context); - - useSystemIpTables = prefs.getBoolean(OrbotConstants.PREF_USE_SYSTEM_IPTABLES, false); - - if (useSystemIpTables) + if (Prefs.useSystemIpTables()) { ipTablesPath = findSystemIP6Tables(); } @@ -335,7 +324,7 @@ public class TorTransProxy implements TorServiceConstants { return code; }*/ - public int setTransparentProxyingByApp(Context context, ArrayList apps, boolean enableRule, Shell shell) throws Exception + public int setTransparentProxyingByApp(Context context, ArrayList apps, boolean enableRule, Shell shell) { String ipTablesPath = getIpTablesPath(context); @@ -439,10 +428,13 @@ public class TorTransProxy implements TorServiceConstants { return lastExit; } - private int executeCommand (Shell shell, String cmdString) throws IOException, TimeoutException - { + private int executeCommand (Shell shell, String cmdString) { SimpleCommand cmd = new SimpleCommand(cmdString); - shell.add(cmd); + try { + shell.add(cmd); + } catch (IOException e) { + e.printStackTrace(); + } int exitCode = cmd.getExitCode(); String output = cmd.getOutput(); @@ -524,8 +516,7 @@ public class TorTransProxy implements TorServiceConstants { } - public int dropAllIPv6Traffic (Context context, int appUid, boolean enableDrop, Shell shell) throws Exception - { + public int dropAllIPv6Traffic (Context context, int appUid, boolean enableDrop, Shell shell) { String action = " -A "; String chain = "OUTPUT"; @@ -575,8 +566,7 @@ public class TorTransProxy implements TorServiceConstants { return lastExit; }*/ - public int flushTransproxyRules (Context context) throws Exception - { + public int flushTransproxyRules (Context context) throws IOException { int exit = -1; String ipTablesPath = getIpTablesPath(context); @@ -676,7 +666,7 @@ public class TorTransProxy implements TorServiceConstants { script = new StringBuilder(); - if (TorService.ENABLE_DEBUG_LOG) + if (Prefs.useDebugLogging()) { //XXX: Comment the following rules for non-debug builds script.append(ipTablesPath); diff --git a/src/org/torproject/android/ui/OrbotLogActivity.java b/src/org/torproject/android/ui/OrbotLogActivity.java deleted file mode 100644 index 4a24d3f1..00000000 --- a/src/org/torproject/android/ui/OrbotLogActivity.java +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - https://guardianproject.info */ -/* See LICENSE for licensing information */ - -package org.torproject.android.ui; - -import org.torproject.android.OrbotConstants; - -import android.app.Activity; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.support.v4.content.LocalBroadcastManager; - - -public class OrbotLogActivity extends Activity implements OrbotConstants -{ - - /** Called when the activity is first created. */ - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - doLayout(); - LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, - new IntentFilter("log")); - - - } - - // Our handler for received Intents. This will be called whenever an Intent - // with an action named "custom-event-name" is broadcasted. - private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { - - - - @Override - public void onReceive(Context context, Intent intent) { - // Get extra data included in the Intent - - if (intent.hasExtra("log")) - { - String log = intent.getStringExtra("log"); - updateStatus(log); - } - - - } - }; - - - - private void doLayout () - { - - - } - - - private void updateStatus(String log) - { - - } - - - @Override - protected void onDestroy() { - super.onDestroy(); - LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); - - } - - - -} diff --git a/src/org/torproject/android/ui/wizard/PromoAppsActivity.java b/src/org/torproject/android/ui/PromoAppsActivity.java similarity index 82% rename from src/org/torproject/android/ui/wizard/PromoAppsActivity.java rename to src/org/torproject/android/ui/PromoAppsActivity.java index 048528fd..5d120d31 100644 --- a/src/org/torproject/android/ui/wizard/PromoAppsActivity.java +++ b/src/org/torproject/android/ui/PromoAppsActivity.java @@ -1,4 +1,4 @@ -package org.torproject.android.ui.wizard; +package org.torproject.android.ui; import android.app.Activity; import android.content.Intent; @@ -10,14 +10,12 @@ import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; -import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import org.torproject.android.OrbotConstants; import org.torproject.android.R; - import java.util.List; public class PromoAppsActivity extends Activity implements OrbotConstants { @@ -42,7 +40,7 @@ public class PromoAppsActivity extends Activity implements OrbotConstants { protected void onStart() { super.onStart(); - setContentView(R.layout.layout_wizard_tips); + setContentView(R.layout.layout_promo_apps); stepFive(); @@ -169,43 +167,16 @@ public class PromoAppsActivity extends Activity implements OrbotConstants { } }); - - // Button back = ((Button)findViewById(R.id.btnWizard1)); Button next = ((Button)findViewById(R.id.btnWizard2)); - - /* - back.setOnClickListener(new View.OnClickListener() { - - public void onClick(View v) { - finish(); - startActivityForResult(new Intent(PromoAppsActivity.this, ChooseLocaleWizardActivity.class), 1); - } - });*/ - next.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - //showWizardFinal(); - finish(); } }); } - - - //Code to override the back button! - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if(keyCode == KeyEvent.KEYCODE_BACK){ - finish(); - startActivity(new Intent(getBaseContext(), ChooseLocaleWizardActivity.class)); - return true; - } - return false; - } - boolean isAppInstalled(PackageManager pm, String packageName) { try { pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); @@ -239,32 +210,4 @@ public class PromoAppsActivity extends Activity implements OrbotConstants { } return intent; } - - /* - private void showWizardFinal () - { - String title = null; - String msg = null; - - - title = context.getString(R.string.wizard_final); - msg = context.getString(R.string.wizard_final_msg); - - DialogInterface.OnClickListener ocListener = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - context.startActivity(new Intent(context, Orbot.class)); - - } - }; - - - new AlertDialog.Builder(context) - .setIcon(R.drawable.icon) - .setTitle(title) - .setPositiveButton(R.string.button_close, ocListener) - .setMessage(msg) - .show(); - }*/ } diff --git a/src/org/torproject/android/ui/wizard/ChooseLocaleWizardActivity.java b/src/org/torproject/android/ui/wizard/ChooseLocaleWizardActivity.java deleted file mode 100644 index a804f45c..00000000 --- a/src/org/torproject/android/ui/wizard/ChooseLocaleWizardActivity.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.torproject.android.ui.wizard; - -import android.app.Activity; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.ListView; -import android.widget.Toast; - -import info.guardianproject.util.Languages; - -import org.torproject.android.OrbotApp; -import org.torproject.android.OrbotConstants; -import org.torproject.android.R; -import org.torproject.android.service.TorServiceUtils; - -import java.util.Locale; - -public class ChooseLocaleWizardActivity extends Activity implements OrbotConstants { - - private ListView listLocales; - private String[] localeValues; - - protected void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - setContentView(R.layout.layout_wizard_locale); - - listLocales = (ListView)findViewById(R.id.wizard_locale_list); - Button next = ((Button)findViewById(R.id.btnWizard2)); - // next.setEnabled(false); - - Languages languages = OrbotApp.getLanguages(this); - localeValues = languages.getSupportedLocales(); - ArrayAdapter adapter = new ArrayAdapter(this, - android.R.layout.simple_list_item_1, android.R.id.text1, - languages.getAllNames()); - listLocales.setAdapter(adapter); - - listLocales.setSelection(0); - listLocales.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView arg0, View arg1, - int arg2, long arg3) { - - setLocalePref(arg2); - finish(); - startActivity(new Intent(ChooseLocaleWizardActivity.this, PromoAppsActivity.class)); - } - }); - - next.setOnClickListener(new View.OnClickListener() { - - public void onClick(View v) { - setLocalePref(0); - finish(); - startActivity(new Intent(ChooseLocaleWizardActivity.this, PromoAppsActivity.class)); - - } - }); - } - - private void setLocalePref(int selId) - { - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); - - Configuration config = getResources().getConfiguration(); - - String lang = localeValues[selId]; - - Editor pEdit = prefs.edit(); - pEdit.putString(PREF_DEFAULT_LOCALE, lang); - pEdit.commit(); - Locale locale = null; - - if (lang.equals("xx")) - { - locale = Locale.getDefault(); - - } - else - locale = new Locale(lang); - - Locale.setDefault(locale); - config.locale = locale; - getResources().updateConfiguration(config, getResources().getDisplayMetrics()); - } - - //Code to override the back button! - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if(keyCode == KeyEvent.KEYCODE_BACK){ - Toast.makeText(getApplicationContext(), R.string.wizard_exit_at_first_screen_toast, Toast.LENGTH_SHORT).show(); - return true; - } - return false; - } -} \ No newline at end of file diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java index 10969060..e2020781 100644 --- a/src/org/torproject/android/vpn/OrbotVpnService.java +++ b/src/org/torproject/android/vpn/OrbotVpnService.java @@ -241,7 +241,8 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { final String virtualGateway = "10.0.0.1"; final String virtualIP = "10.0.0.2"; final String virtualNetMask = "255.255.255.0"; - final String localSocks = "127.0.0.1:" + TorServiceConstants.PORT_SOCKS_DEFAULT; + final String localSocks = "127.0.0.1:" + + String.valueOf(TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT); final String localDNS = "10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT; Builder builder = new Builder();