diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml index 476229541dce9930b1f0b791d91df133d86c4b6c..ac262a3c2067cc6abebc478b0e2b751b87305546 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -7,6 +7,9 @@ <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="22" + + xmlns:tools="http://schemas.android.com/tools" + tools:overrideLibrary="android.support.v14.preference" /> <uses-feature android:name="android.hardware.bluetooth" /> @@ -188,5 +191,22 @@ android:name=".android.StartupFailureActivity" android:label="@string/startup_failed_activity_title" > </activity> + <activity + android:name=".android.panic.PanicPreferencesActivity" + android:label="@string/panic_setting" > + </activity> + <activity + android:name=".android.panic.PanicResponderActivity" + android:noHistory="true" + android:theme="@android:style/Theme.NoDisplay"> + <!-- this can never have launchMode singleTask or singleInstance! --> + <intent-filter> + <action android:name="info.guardianproject.panic.action.TRIGGER" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <activity + android:name=".android.panic.ExitActivity" + android:theme="@android:style/Theme.NoDisplay" /> </application> </manifest> diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 756b2da587dbdff195733d15cbb150513597e413..4c3835102e719748bff27bcce6c47a1eab04dc03 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -1,4 +1,9 @@ apply plugin: 'com.android.application' +apply plugin: 'witness' + +repositories { + jcenter() +} dependencies { compile fileTree(dir: '../briar-api/libs', include: '*.jar') @@ -8,7 +13,23 @@ dependencies { compile fileTree(dir: 'libs', include: '*.jar') compile "com.android.support:support-v4:23.1.1" compile "com.android.support:appcompat-v7:23.1.1" + compile "com.android.support:preference-v7:23.1.1" + compile "com.android.support:preference-v14:23.1.1" compile "com.android.support:design:23.1.1" + compile "info.guardianproject.panic:panic:0.5" +} + +dependencyVerification { + verify = [ + 'com.android.support:support-v4:5c7dceb6c824089fe80f502e5206264048ef8bffa4e8ddeab180b81723e79b7f', + 'com.android.support:appcompat-v7:0a8762214382b7e8d4b989b4ac10b5c846b957d767ccb7bccbc6be5afa885a82', + 'com.android.support:preference-v7:4b6dabaa4400cbed885c7edc885aa6372468f48d628cc0d4a04b9ccd128ed324', + 'com.android.support:preference-v14:a69906c2b29b315ac3c1fdf01537a7557660a65b8ea1cf891baa8665e1197459', + 'com.android.support:design:41a9cd75ca78f25df5f573db7cedf8bb66beae00c330943923ba9f3e2051736d', + 'com.android.support:support-annotations:f347a35b9748a4103b39a6714a77e2100f488d623fd6268e259c177b200e9d82', + 'com.android.support:recyclerview-v7:7606373da0931a1e62588335465a0e390cd676c98117edab29220317495faefd', + 'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2', + ] } android { diff --git a/briar-android/res/layout/activity_panic_preferences.xml b/briar-android/res/layout/activity_panic_preferences.xml new file mode 100644 index 0000000000000000000000000000000000000000..78aaeb88da79937717e5f8c0b9b2404e97add599 --- /dev/null +++ b/briar-android/res/layout/activity_panic_preferences.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <fragment + android:id="@+id/fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:name="org.briarproject.android.panic.PanicPreferencesFragment"/> +</FrameLayout> \ No newline at end of file diff --git a/briar-android/res/values-v14/styles.xml b/briar-android/res/values-v14/styles.xml index 898a9e4e00922099b9c011de41d77c77cb61b1f3..ff39392ac4ea2678d97248a19b2a470c17450569 100644 --- a/briar-android/res/values-v14/styles.xml +++ b/briar-android/res/values-v14/styles.xml @@ -1,5 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <resources> + + <style name="BriarTheme" parent="BriarBaseTheme"> + <!-- This fixes a UI bug in the support preference library --> + <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> + </style> + <style name="BriarButton.Default"> <item name="android:textAllCaps">true</item> </style> diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml index 28cddbd4f2ce28ce41d4cc2ba7230485bba44135..fc0ea39777f88fcf3c7a538fa03c2afca4f3f34e 100644 --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -16,10 +16,14 @@ <color name="briar_primary">#2D3E50</color> <color name="briar_primary_dark">#0f1720</color> + <color name="briar_accent">#2D3E50</color> <color name="briar_text_link">#75ab0d</color> <color name="briar_green_light">#95d220</color> <color name="briar_green_dark">#75ab0d</color> <color name="briar_text_primary">#333333</color> <color name="briar_text_primary_inverse">#ffffff</color> + + <!-- this is needed as preference_category_material layout uses this color as the text color --> + <color name="preference_fallback_accent_color">@color/briar_accent</color> </resources> \ No newline at end of file diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index 4934dceabe03d48d78932a90e66a513251550e4b..25aa173bc40e091440a0b226e0487ee90648ffcc 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -106,6 +106,9 @@ <string name="tor_wifi_setting">Connect via Tor</string> <string name="tor_wifi_setting_enabled">Only when using Wi-Fi</string> <string name="tor_wifi_setting_disabled">When using Wi-Fi or mobile data</string> + <string name="panic_setting">Panic Button Setup</string> + <string name="panic_setting_title">Panic Button</string> + <string name="panic_setting_hint">Configure how Briar will react when you use a Panic Button app</string> <string name="notification_settings_title">NOTIFICATIONS</string> <string name="notify_private_messages_setting">Show alerts for private messages</string> <string name="notify_forum_posts_setting">Show alerts for forum posts</string> @@ -114,6 +117,13 @@ <string name="notify_sound_setting_default">Default ringtone</string> <string name="notify_sound_setting_disabled">None</string> <string name="choose_ringtone_title">Choose ringtone</string> + <string name="panic_app_setting_title">Accept from App</string> + <string name="panic_app_setting_summary">No app set, don\'t do destructive actions</string> + <string name="panic_app_setting_none">None</string> + <string name="lock_setting_title">Lock Briar</string> + <string name="lock_setting_summary">Signs you out and require password to access data</string> + <string name="purge_setting_title">Delete Data</string> + <string name="purge_setting_summary">Caution: This irrevocably deletes your contacts and all other data</string> <string name="step">Step %1$d/%2$d</string> <string name="online">Online</string> <string name="offline">Offline</string> @@ -122,11 +132,14 @@ <string name="transport_tor">Internet</string> <string name="transport_bt">Bluetooth</string> <string name="transport_lan">Wi-Fi</string> + <string name="no_data">No data</string> + <string name="unknown_app">an unknown App</string> <!-- Dialogs --> <string name="dialog_title_lost_password">Lost password</string> <string name="dialog_message_lost_password">Password recovery is not possible. Do you wish to delete your user, all contacts, and re-register ?</string> <string name="dialog_title_delete_contact">Confirm Contact Deletion</string> <string name="dialog_message_delete_contact">Are you sure that you want to remove this contact and all messages exchanged with this contact?</string> - <string name="no_data">No data</string> + <string name="dialog_title_connect_panic_app">Confirm Panic App</string> + <string name="dialog_message_connect_panic_app">Are you sure that you want to allow %1$s to trigger destructive panic actions?</string> </resources> diff --git a/briar-android/res/values/styles.xml b/briar-android/res/values/styles.xml index 8a706c0a22d527e09817bbfc076f9550259ec798..7a869c9051cf36783ee71cde92ad5d8157f2bfa5 100644 --- a/briar-android/res/values/styles.xml +++ b/briar-android/res/values/styles.xml @@ -1,17 +1,20 @@ <?xml version="1.0" encoding="utf-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android"> - <style name="BriarTheme" parent="Theme.AppCompat.Light.DarkActionBar"> + <style name="BriarBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="actionBarStyle">@style/BriarActionBar</item> <item name="colorPrimary">@color/briar_primary</item> <item name="colorPrimaryDark">@color/briar_primary_dark</item> - <item name="colorAccent">@color/briar_primary</item> + <item name="colorAccent">@color/briar_accent</item> <item name="android:textColorPrimary">@color/briar_text_primary</item> <item name="android:textColorPrimaryInverse">@color/briar_text_primary_inverse</item> <item name="android:textColorSecondary">@color/briar_text_primary</item> <item name="android:textColorLink">@color/briar_text_link</item> + </style> - <!-- The rest of your attributes --> + <style name="BriarTheme" parent="BriarBaseTheme"> + <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> + <item name="android:listSeparatorTextViewStyle">@style/BriarTheme.ListSeparatorTextView</item> </style> <style name="BriarActionBar" parent="Base.Widget.AppCompat.Light.ActionBar.Solid"> @@ -43,4 +46,14 @@ <item name="android:layout_width">match_parent</item> <item name="android:layout_height">1px</item> </style> + + <!-- This fixes a UI bug in the support preference library --> + <style name="BriarTheme.ListSeparatorTextView"> + <item name="android:textSize">14sp</item> + <item name="android:textStyle">bold</item> + <item name="android:textColor">@color/briar_accent</item> + <item name="android:paddingTop">16dp</item> + <item name="android:layout_marginBottom">16dp</item> + </style> + </resources> \ No newline at end of file diff --git a/briar-android/res/xml/panic_preferences.xml b/briar-android/res/xml/panic_preferences.xml new file mode 100644 index 0000000000000000000000000000000000000000..3b40f0e3dfed14616a4015f1374e60ae436493a0 --- /dev/null +++ b/briar-android/res/xml/panic_preferences.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen + xmlns:android="http://schemas.android.com/apk/res/android"> + + <CheckBoxPreference + android:key="pref_key_lock" + android:title="@string/lock_setting_title" + android:summary="@string/lock_setting_summary" + android:defaultValue="true"/> + +</PreferenceScreen> \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/BriarActivity.java b/briar-android/src/org/briarproject/android/BriarActivity.java index 5442839acb2534211ad3d59b17bea27d6465b95b..fcc4ab604db3cb354b3c386d5e4b1e71d1148873 100644 --- a/briar-android/src/org/briarproject/android/BriarActivity.java +++ b/briar-android/src/org/briarproject/android/BriarActivity.java @@ -2,11 +2,13 @@ package org.briarproject.android; import android.annotation.SuppressLint; import android.content.Intent; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import org.briarproject.android.BriarService.BriarBinder; import org.briarproject.android.BriarService.BriarServiceConnection; +import org.briarproject.android.panic.ExitActivity; import org.briarproject.api.db.DatabaseConfig; import org.briarproject.api.db.DatabaseExecutor; import org.briarproject.api.lifecycle.LifecycleManager; @@ -78,7 +80,7 @@ public class BriarActivity extends BaseActivity { if (bound) unbindService(serviceConnection); } - protected void signOut() { + protected void signOut(final boolean removeFromRecentApps) { new Thread() { @Override public void run() { @@ -95,15 +97,28 @@ public class BriarActivity extends BaseActivity { LOG.warning("Interrupted while waiting for service"); Thread.currentThread().interrupt(); } - finishAndExit(); + + if(removeFromRecentApps){ + ExitActivity.exitAndRemoveFromRecentApps(BriarActivity.this); + } else { + finishAndExit(); + } } }.start(); } + protected void signOut() { + signOut(false); + } + private void finishAndExit() { runOnUiThread(new Runnable() { public void run() { - finish(); + if (Build.VERSION.SDK_INT >= 21) { + finishAndRemoveTask(); + } else { + finish(); + } LOG.info("Exiting"); System.exit(0); } diff --git a/briar-android/src/org/briarproject/android/SettingsActivity.java b/briar-android/src/org/briarproject/android/SettingsActivity.java index e2f2d233a07d6d92e4cfdd056f803eed15391b00..7c48355a99bc0feae8d25947f4f2cf52320ee991 100644 --- a/briar-android/src/org/briarproject/android/SettingsActivity.java +++ b/briar-android/src/org/briarproject/android/SettingsActivity.java @@ -16,6 +16,7 @@ import android.widget.ScrollView; import android.widget.TextView; import org.briarproject.R; +import org.briarproject.android.panic.PanicPreferencesActivity; import org.briarproject.android.util.FixedVerticalSpace; import org.briarproject.android.util.HorizontalBorder; import org.briarproject.android.util.LayoutUtils; @@ -68,6 +69,7 @@ OnClickListener { private CheckBox notifyPrivateMessages = null, notifyForumPosts = null; private CheckBox notifyVibration = null; private TextView torOverWifi = null, torOverWifiHint = null; + private TextView panicSettings = null, panicSettingsHint = null; private TextView notifySound = null, notifySoundHint = null; private ListLoadingProgressBar progress = null; private ImageButton testingButton = null; @@ -141,6 +143,30 @@ OnClickListener { torOverWifiHint.setOnClickListener(this); settings.addView(torOverWifiHint); + TextView panicTitle = new TextView(this); + panicTitle.setPadding(pad, 0, pad, 0); + panicTitle.setTypeface(DEFAULT_BOLD); + panicTitle.setTextColor(titleText); + panicTitle.setText(R.string.panic_setting_title); + settings.addView(panicTitle); + + underline = new HorizontalBorder(this); + underline.setBackgroundColor(titleUnderline); + settings.addView(underline); + + panicSettings = new TextView(this); + panicSettings.setPadding(pad, pad, pad, 0); + panicSettings.setTextSize(18); + panicSettings.setText(R.string.panic_setting); + panicSettings.setOnClickListener(this); + settings.addView(panicSettings); + + panicSettingsHint = new TextView(this); + panicSettingsHint.setText(R.string.panic_setting_hint); + panicSettingsHint.setPadding(pad, 0, pad, pad); + panicSettingsHint.setOnClickListener(this); + settings.addView(panicSettingsHint); + TextView notificationsTitle = new TextView(this); notificationsTitle.setPadding(pad, 0, pad, 0); notificationsTitle.setTypeface(DEFAULT_BOLD); @@ -317,6 +343,8 @@ OnClickListener { s.putBoolean("notifyPrivateMessages", notifyPrivateMessages.isChecked()); storeSettings(s); + } else if (view == panicSettings || view == panicSettingsHint) { + startActivity(new Intent(this, PanicPreferencesActivity.class)); } else if (view == notifyForumPosts) { Settings s = new Settings(); s.putBoolean("notifyForumPosts", notifyForumPosts.isChecked()); diff --git a/briar-android/src/org/briarproject/android/SplashScreenActivity.java b/briar-android/src/org/briarproject/android/SplashScreenActivity.java index 60712a583945be2bcce0a33c0e2fd37d7b819598..e74056341b6a4e6ca75d5a3d24af6a7cc18118bd 100644 --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -7,6 +7,7 @@ import android.os.Bundle; import android.os.StrictMode; import android.os.StrictMode.ThreadPolicy; import android.os.StrictMode.VmPolicy; +import android.support.v7.preference.PreferenceManager; import android.widget.ImageView; import android.widget.LinearLayout; @@ -64,6 +65,9 @@ public class SplashScreenActivity extends RoboSplashActivity { logo.setImageResource(R.drawable.briar_logo_large); layout.addView(logo); + PreferenceManager + .setDefaultValues(this, R.xml.panic_preferences, false); + setContentView(layout); } diff --git a/briar-android/src/org/briarproject/android/panic/ExitActivity.java b/briar-android/src/org/briarproject/android/panic/ExitActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..68bef09ec217624ed748dcb3a5e36bc60cff00e3 --- /dev/null +++ b/briar-android/src/org/briarproject/android/panic/ExitActivity.java @@ -0,0 +1,40 @@ +package org.briarproject.android.panic; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; + +import org.briarproject.android.BaseActivity; + +public class ExitActivity extends BaseActivity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (Build.VERSION.SDK_INT >= 21) { + finishAndRemoveTask(); + } else { + finish(); + } + + System.exit(0); + } + + public static void exitAndRemoveFromRecentApps(final BaseActivity activity) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + Intent intent = new Intent(activity, ExitActivity.class); + + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS + | Intent.FLAG_ACTIVITY_CLEAR_TASK + | Intent.FLAG_ACTIVITY_NO_ANIMATION); + + activity.startActivity(intent); + } + }); + + } +} \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/panic/PanicPreferencesActivity.java b/briar-android/src/org/briarproject/android/panic/PanicPreferencesActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..13556f838d941dda1366279614833d93fe064133 --- /dev/null +++ b/briar-android/src/org/briarproject/android/panic/PanicPreferencesActivity.java @@ -0,0 +1,33 @@ +package org.briarproject.android.panic; + +import android.os.Bundle; +import android.support.v7.app.ActionBar; +import android.view.MenuItem; + +import org.briarproject.R; +import org.briarproject.android.BriarActivity; + +public class PanicPreferencesActivity extends BriarActivity { + + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setHomeButtonEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(true); + } + + setContentView(R.layout.activity_panic_preferences); + } + + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } + return false; + } + +} diff --git a/briar-android/src/org/briarproject/android/panic/PanicPreferencesFragment.java b/briar-android/src/org/briarproject/android/panic/PanicPreferencesFragment.java new file mode 100644 index 0000000000000000000000000000000000000000..7fd096213c379dc4f1efeb28502a46d746092da0 --- /dev/null +++ b/briar-android/src/org/briarproject/android/panic/PanicPreferencesFragment.java @@ -0,0 +1,14 @@ +package org.briarproject.android.panic; + +import android.os.Bundle; +import android.support.v7.preference.PreferenceFragmentCompat; + +import org.briarproject.R; + +public class PanicPreferencesFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + addPreferencesFromResource(R.xml.panic_preferences); + } +} diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..df758e295e1065ce0bd3ae2566a1c13e04a6ccd5 --- /dev/null +++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java @@ -0,0 +1,37 @@ +package org.briarproject.android.panic; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.support.v7.preference.PreferenceManager; + +import org.briarproject.android.BriarActivity; + +import java.util.logging.Logger; + +public class PanicResponderActivity extends BriarActivity { + + private static final Logger LOG = + Logger.getLogger(PanicResponderActivity.class.getName()); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + SharedPreferences sharedPref = PreferenceManager + .getDefaultSharedPreferences(this); + + Intent intent = getIntent(); + if (intent != null && sharedPref.getBoolean("pref_key_lock", true)) { + LOG.info("Signing out..."); + signOut(true); + } + + if (Build.VERSION.SDK_INT >= 21) { + finishAndRemoveTask(); + } else { + finish(); + } + } +} \ No newline at end of file diff --git a/briar-core/libs/gradle-witness.jar b/briar-core/libs/gradle-witness.jar new file mode 100644 index 0000000000000000000000000000000000000000..561041d3661895d48bd396b342d9c043ecd741ae Binary files /dev/null and b/briar-core/libs/gradle-witness.jar differ diff --git a/build.gradle b/build.gradle index ec8b633f83f3470eee55367047228ec9d551f928..98a1101ba91104e5cd0ef505f80d8f4c5a67007c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,5 +5,6 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:1.5.0' + classpath files('briar-core/libs/gradle-witness.jar') } -} +} \ No newline at end of file