From d17669f131b52a9d6deace950c793522e08c1c2f Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 11 Apr 2017 14:53:03 +0100 Subject: [PATCH 01/22] Increase socket timeout for Tor sockets. --- .../bramble/api/plugin/TorConstants.java | 1 + .../briarproject/bramble/socks/SocksModule.java | 4 +++- .../briarproject/bramble/socks/SocksSocket.java | 16 +++++++++------- .../bramble/socks/SocksSocketFactory.java | 8 +++++--- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java index 5ab9594f8..639155ac4 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java @@ -8,6 +8,7 @@ public interface TorConstants { int CONTROL_PORT = 59051; int CONNECT_TO_PROXY_TIMEOUT = 5000; // Milliseconds + int EXTRA_SOCKET_TIMEOUT = 30000; // Milliseconds String PREF_TOR_NETWORK = "network"; String PREF_TOR_PORT = "port"; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java index 1fe9f31c6..be342f011 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java @@ -8,6 +8,7 @@ import dagger.Module; import dagger.Provides; import static org.briarproject.bramble.api.plugin.TorConstants.CONNECT_TO_PROXY_TIMEOUT; +import static org.briarproject.bramble.api.plugin.TorConstants.EXTRA_SOCKET_TIMEOUT; import static org.briarproject.bramble.api.plugin.TorConstants.SOCKS_PORT; @Module @@ -17,6 +18,7 @@ public class SocksModule { SocketFactory provideTorSocketFactory() { InetSocketAddress proxy = new InetSocketAddress("127.0.0.1", SOCKS_PORT); - return new SocksSocketFactory(proxy, CONNECT_TO_PROXY_TIMEOUT); + return new SocksSocketFactory(proxy, CONNECT_TO_PROXY_TIMEOUT, + EXTRA_SOCKET_TIMEOUT); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocket.java b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocket.java index 9494e6297..7f5cb0090 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocket.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocket.java @@ -29,11 +29,13 @@ class SocksSocket extends Socket { private static final byte[] UNSPECIFIED_ADDRESS = new byte[4]; private final SocketAddress proxy; - private final int connectToProxyTimeout; + private final int connectToProxyTimeout, extraSocketTimeout; - SocksSocket(SocketAddress proxy, int connectToProxyTimeout) { + SocksSocket(SocketAddress proxy, int connectToProxyTimeout, + int extraSocketTimeout) { this.proxy = proxy; this.connectToProxyTimeout = connectToProxyTimeout; + this.extraSocketTimeout = extraSocketTimeout; } @Override @@ -47,7 +49,7 @@ class SocksSocket extends Socket { InetAddress address = inet.getAddress(); if (address != null && !Arrays.equals(address.getAddress(), UNSPECIFIED_ADDRESS)) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException(); } String host = inet.getHostName(); if (host.length() > 255) throw new IllegalArgumentException(); @@ -62,16 +64,16 @@ class SocksSocket extends Socket { sendMethodRequest(out); receiveMethodResponse(in); - // Use the supplied timeout temporarily + // Use the supplied timeout temporarily, plus any configured extra int oldTimeout = getSoTimeout(); - setSoTimeout(timeout); + setSoTimeout(timeout + extraSocketTimeout); // Connect to the endpoint via the proxy sendConnectRequest(out, host, port); receiveConnectResponse(in); - // Restore the old timeout - setSoTimeout(oldTimeout); + // Restore the old timeout, plus any configured extra + setSoTimeout(oldTimeout + extraSocketTimeout); } private void sendMethodRequest(OutputStream out) throws IOException { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocketFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocketFactory.java index adc5265fb..fb0b1cd91 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocketFactory.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocketFactory.java @@ -11,16 +11,18 @@ import javax.net.SocketFactory; class SocksSocketFactory extends SocketFactory { private final SocketAddress proxy; - private final int connectToProxyTimeout; + private final int connectToProxyTimeout, extraSocketTimeout; - SocksSocketFactory(SocketAddress proxy, int connectToProxyTimeout) { + SocksSocketFactory(SocketAddress proxy, int connectToProxyTimeout, + int extraSocketTimeout) { this.proxy = proxy; this.connectToProxyTimeout = connectToProxyTimeout; + this.extraSocketTimeout = extraSocketTimeout; } @Override public Socket createSocket() { - return new SocksSocket(proxy, connectToProxyTimeout); + return new SocksSocket(proxy, connectToProxyTimeout, extraSocketTimeout); } @Override From 57d4d6546a8fabcbdcbb9747898be83516add434 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Wed, 12 Apr 2017 14:22:20 +0100 Subject: [PATCH 02/22] When checking for overlay apps, ignore Play Services. --- .../android/ScreenFilterMonitorImpl.java | 112 +++++++++++++----- 1 file changed, 81 insertions(+), 31 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java index cb195108a..8ec4b3508 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java @@ -6,10 +6,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.support.annotation.NonNull; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.Signature; import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.v7.preference.PreferenceManager; @@ -19,11 +19,16 @@ import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.system.AndroidExecutor; +import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.api.android.ScreenFilterMonitor; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.util.Collection; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.TreeSet; @@ -31,32 +36,57 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; +import static android.content.Intent.ACTION_PACKAGE_ADDED; +import static android.content.Intent.EXTRA_REPLACING; +import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; +import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; +import static android.content.pm.PackageManager.GET_PERMISSIONS; +import static android.content.pm.PackageManager.GET_SIGNATURES; +import static java.util.logging.Level.WARNING; @MethodsNotNullByDefault @ParametersNotNullByDefault public class ScreenFilterMonitorImpl extends BroadcastReceiver - implements Service, - ScreenFilterMonitor { + implements Service, ScreenFilterMonitor { private static final Logger LOG = Logger.getLogger(ScreenFilterMonitorImpl.class.getName()); private static final String PREF_SCREEN_FILTER_APPS = "shownScreenFilterApps"; + + /* + * Ignore Play Services if it uses this package name and public key - it's + * effectively a system app, but not flagged as such on older systems + */ + private static final String PLAY_SERVICES_PACKAGE = + "com.google.android.gms"; + private static final String PLAY_SERVICES_PUBLIC_KEY = + "30820120300D06092A864886F70D01010105000382010D0030820108" + + "0282010100AB562E00D83BA208AE0A966F124E29DA11F2AB56D08F58" + + "E2CCA91303E9B754D372F640A71B1DCB130967624E4656A7776A9219" + + "3DB2E5BFB724A91E77188B0E6A47A43B33D9609B77183145CCDF7B2E" + + "586674C9E1565B1F4C6A5955BFF251A63DABF9C55C27222252E875E4" + + "F8154A645F897168C0B1BFC612EABF785769BB34AA7984DC7E2EA276" + + "4CAE8307D8C17154D7EE5F64A51A44A602C249054157DC02CD5F5C0E" + + "55FBEF8519FBE327F0B1511692C5A06F19D18385F5C4DBC2D6B93F68" + + "CC2979C70E18AB93866B3BD5DB8999552A0E3B4C99DF58FB918BEDC1" + + "82BA35E003C1B4B10DD244A8EE24FFFD333872AB5221985EDAB0FC0D" + + "0B145B6AA192858E79020103"; + private final Context appContext; private final AndroidExecutor androidExecutor; - private final LinkedList appNames = new LinkedList<>(); private final PackageManager pm; private final SharedPreferences prefs; private final AtomicBoolean used = new AtomicBoolean(false); + + // The following must only be accessed on the UI thread private final Set apps = new HashSet<>(); private final Set shownApps; - // Used solely for the UiThread private boolean serviceStarted = false; @Inject @@ -75,7 +105,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver @Override public Void call() { IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addAction(ACTION_PACKAGE_ADDED); intentFilter.addDataScheme("package"); appContext.registerReceiver(ScreenFilterMonitorImpl.this, intentFilter); @@ -109,9 +139,8 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver } private Set getShownScreenFilterApps() { - // res must not be modified - Set s = - prefs.getStringSet(PREF_SCREEN_FILTER_APPS, null); + // Result must not be modified + Set s = prefs.getStringSet(PREF_SCREEN_FILTER_APPS, null); HashSet result = new HashSet<>(); if (s != null) { result.addAll(s); @@ -121,7 +150,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver @Override public void onReceive(Context context, Intent intent) { - if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { + if (!intent.getBooleanExtra(EXTRA_REPLACING, false)) { final String packageName = intent.getData().getEncodedSchemeSpecificPart(); androidExecutor.runOnUiThread(new Runnable() { @@ -155,7 +184,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver @Override @UiThread public void storeAppsAsShown(Collection s, boolean persistent) { - HashSet buf = new HashSet(s); + HashSet buf = new HashSet<>(s); shownApps.addAll(buf); if (persistent && !s.isEmpty()) { buf.addAll(getShownScreenFilterApps()); @@ -168,7 +197,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver private Set getInstalledScreenFilterApps() { HashSet screenFilterApps = new HashSet<>(); List packageInfos = - pm.getInstalledPackages(PackageManager.GET_PERMISSIONS); + pm.getInstalledPackages(GET_PERMISSIONS); for (PackageInfo packageInfo : packageInfos) { if (isOverlayApp(packageInfo)) { String name = pkgToString(packageInfo); @@ -180,25 +209,22 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver return screenFilterApps; } - // Checks if pkg uses the SYSTEM_ALERT_WINDOW permission and if so + // Checks if a package uses the SYSTEM_ALERT_WINDOW permission and if so // returns the app name. @Nullable private String isOverlayApp(String pkg) { try { - PackageInfo pkgInfo = - pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS); + PackageInfo pkgInfo = pm.getPackageInfo(pkg, GET_PERMISSIONS); if (isOverlayApp(pkgInfo)) { return pkgToString(pkgInfo); } - } catch (PackageManager.NameNotFoundException ignored) { - if (LOG.isLoggable(Level.WARNING)) { - LOG.warning("Package name not found: " + pkg); - } + } catch (NameNotFoundException e) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); } return null; } - // Fetch the application name for a given package. + // Fetches the application name for a given package. @Nullable private String pkgToString(PackageInfo pkgInfo) { CharSequence seq = pm.getApplicationLabel(pkgInfo.applicationInfo); @@ -208,25 +234,49 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver return null; } - // Checks if an installed pkg is a user app using the permission. + // Checks if an installed package is a user app using the permission. private boolean isOverlayApp(PackageInfo packageInfo) { - int mask = ApplicationInfo.FLAG_SYSTEM | - ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; + int mask = FLAG_SYSTEM | FLAG_UPDATED_SYSTEM_APP; // Ignore system apps if ((packageInfo.applicationInfo.flags & mask) != 0) { return false; } - //Get Permissions - String[] requestedPermissions = - packageInfo.requestedPermissions; + // Ignore Play Services, it's effectively a system app + if (isPlayServices(packageInfo.packageName)) { + return false; + } + // Get permissions + String[] requestedPermissions = packageInfo.requestedPermissions; if (requestedPermissions != null) { for (String requestedPermission : requestedPermissions) { - if (requestedPermission - .equals(SYSTEM_ALERT_WINDOW)) { + if (requestedPermission.equals(SYSTEM_ALERT_WINDOW)) { return true; } } } return false; } + + private boolean isPlayServices(String pkg) { + if (!PLAY_SERVICES_PACKAGE.equals(pkg)) return false; + try { + PackageInfo sigs = pm.getPackageInfo(pkg, GET_SIGNATURES); + // The genuine Play Services app should have a single signature + Signature[] signatures = sigs.signatures; + if (signatures == null || signatures.length != 1) return false; + // Extract the public key from the signature + CertificateFactory certFactory = + CertificateFactory.getInstance("X509"); + byte[] signatureBytes = signatures[0].toByteArray(); + InputStream in = new ByteArrayInputStream(signatureBytes); + X509Certificate cert = + (X509Certificate) certFactory.generateCertificate(in); + byte[] publicKeyBytes = cert.getPublicKey().getEncoded(); + String publicKey = StringUtils.toHexString(publicKeyBytes); + return PLAY_SERVICES_PUBLIC_KEY.equals(publicKey); + } catch (NameNotFoundException | CertificateException e) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + return false; + } + } } From 49ba66dee91f74db516cf7e8e4f995e6dae4f99c Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 13 Apr 2017 13:56:20 +0100 Subject: [PATCH 03/22] Don't use single top and clear top flags together. --- .../android/AndroidNotificationManagerImpl.java | 17 ++++++++--------- .../briar/android/BriarService.java | 4 +--- .../briar/android/blog/BlogFragment.java | 5 ++--- .../briar/android/forum/ForumActivity.java | 5 ++--- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java index c45608094..003c77ee7 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java @@ -59,7 +59,6 @@ import static android.app.Notification.DEFAULT_SOUND; import static android.app.Notification.DEFAULT_VIBRATE; import static android.content.Context.NOTIFICATION_SERVICE; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; -import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE; import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL; import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET; @@ -310,7 +309,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ContactId c = contactCounts.keySet().iterator().next(); i.putExtra(CONTACT_ID, c.getInt()); i.setData(Uri.parse(CONTACT_URI + "/" + c.getInt())); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(ConversationActivity.class); t.addNextIntent(i); @@ -319,7 +318,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, // Touching the notification shows the contact list Intent i = new Intent(appContext, NavDrawerActivity.class); i.putExtra(INTENT_CONTACTS, true); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i.setData(Uri.parse(CONTACT_URI)); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(NavDrawerActivity.class); @@ -415,7 +414,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, i.putExtra(GROUP_ID, g.getBytes()); String idHex = StringUtils.toHexString(g.getBytes()); i.setData(Uri.parse(GROUP_URI + "/" + idHex)); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(GroupActivity.class); t.addNextIntent(i); @@ -424,7 +423,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, // Touching the notification shows the group list Intent i = new Intent(appContext, NavDrawerActivity.class); i.putExtra(INTENT_GROUPS, true); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i.setData(Uri.parse(GROUP_URI)); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(NavDrawerActivity.class); @@ -507,7 +506,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, i.putExtra(GROUP_ID, g.getBytes()); String idHex = StringUtils.toHexString(g.getBytes()); i.setData(Uri.parse(FORUM_URI + "/" + idHex)); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(ForumActivity.class); t.addNextIntent(i); @@ -516,7 +515,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, // Touching the notification shows the forum list Intent i = new Intent(appContext, NavDrawerActivity.class); i.putExtra(INTENT_FORUMS, true); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i.setData(Uri.parse(FORUM_URI)); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(NavDrawerActivity.class); @@ -595,7 +594,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, // Touching the notification shows the combined blog feed Intent i = new Intent(appContext, NavDrawerActivity.class); i.putExtra(INTENT_BLOGS, true); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i.setData(Uri.parse(BLOG_URI)); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(NavDrawerActivity.class); @@ -651,7 +650,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, // Touching the notification shows the contact list Intent i = new Intent(appContext, NavDrawerActivity.class); i.putExtra(INTENT_CONTACTS, true); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i.setData(Uri.parse(CONTACT_URI)); TaskStackBuilder t = TaskStackBuilder.create(appContext); t.addParentStack(NavDrawerActivity.class); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java index e273d393d..9c12a7ace 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java @@ -28,7 +28,6 @@ import javax.inject.Inject; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; -import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE; import static android.support.v4.app.NotificationCompat.PRIORITY_MIN; import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET; @@ -83,8 +82,7 @@ public class BriarService extends Service { b.setWhen(0); // Don't show the time b.setOngoing(true); Intent i = new Intent(this, NavDrawerActivity.class); - i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | - FLAG_ACTIVITY_SINGLE_TOP); + i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP); b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0)); if (Build.VERSION.SDK_INT >= 21) { b.setCategory(CATEGORY_SERVICE); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java index e5cd225bc..c9305411d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java @@ -43,7 +43,6 @@ import javax.inject.Inject; import static android.app.Activity.RESULT_OK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; -import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; import static android.widget.Toast.LENGTH_SHORT; import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SHARE_BLOG; @@ -149,14 +148,14 @@ public class BlogFragment extends BaseFragment return true; case R.id.action_blog_share: Intent i2 = new Intent(getActivity(), ShareBlogActivity.class); - i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i2.putExtra(GROUP_ID, groupId.getBytes()); startActivityForResult(i2, REQUEST_SHARE_BLOG); return true; case R.id.action_blog_sharing_status: Intent i3 = new Intent(getActivity(), BlogSharingStatusActivity.class); - i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i3.putExtra(GROUP_ID, groupId.getBytes()); startActivity(i3); return true; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java index ee82e165b..19173ac7f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java @@ -34,7 +34,6 @@ import javax.annotation.Nullable; import javax.inject.Inject; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; -import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; import static android.widget.Toast.LENGTH_SHORT; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SHARE_FORUM; import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH; @@ -122,13 +121,13 @@ public class ForumActivity extends return true; case R.id.action_forum_share: Intent i2 = new Intent(this, ShareForumActivity.class); - i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i2.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i2.putExtra(GROUP_ID, groupId.getBytes()); startActivityForResult(i2, REQUEST_SHARE_FORUM); return true; case R.id.action_forum_sharing_status: Intent i3 = new Intent(this, ForumSharingStatusActivity.class); - i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP); + i3.setFlags(FLAG_ACTIVITY_CLEAR_TOP); i3.putExtra(GROUP_ID, groupId.getBytes()); startActivity(i3); return true; From 1b48d661e8f4e52e16214bf9a8ba3299ccca0073 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 13 Apr 2017 14:43:43 +0100 Subject: [PATCH 04/22] Use original timestamp for RSS posts, if available. --- .../java/org/briarproject/briar/feed/FeedManagerImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java index bb97bb0d4..735e220c6 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java @@ -467,7 +467,11 @@ class FeedManagerImpl implements FeedManager, Client, EventListener, // get other information for post GroupId groupId = feed.getBlogId(); - long time = clock.currentTimeMillis(); + long time; + Date date = entry.getUpdatedDate(); + if (date == null) date = entry.getPublishedDate(); + if (date == null) time = clock.currentTimeMillis(); + else time = date.getTime(); String body = getPostBody(b.toString()); try { // create and store post From 115d488bc3b2442f52c6341a7081131e2619f2b7 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 13 Apr 2017 16:21:00 +0100 Subject: [PATCH 05/22] Clamp the imported timestamp within reasonable limits. --- .../java/org/briarproject/briar/feed/FeedManagerImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java index 735e220c6..609166ad5 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java @@ -467,11 +467,11 @@ class FeedManagerImpl implements FeedManager, Client, EventListener, // get other information for post GroupId groupId = feed.getBlogId(); - long time; + long time, now = clock.currentTimeMillis(); Date date = entry.getUpdatedDate(); if (date == null) date = entry.getPublishedDate(); - if (date == null) time = clock.currentTimeMillis(); - else time = date.getTime(); + if (date == null) time = now; + else time = Math.max(0, Math.min(date.getTime(), now)); String body = getPostBody(b.toString()); try { // create and store post From 45e7af31fe97704465e60a929516243108fddd35 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 17 Apr 2017 16:14:26 -0300 Subject: [PATCH 06/22] Darken thread indicator --- briar-android/src/main/res/drawable/level_indicator_circle.xml | 2 +- briar-android/src/main/res/values/color.xml | 3 ++- briar-android/src/main/res/values/styles.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/briar-android/src/main/res/drawable/level_indicator_circle.xml b/briar-android/src/main/res/drawable/level_indicator_circle.xml index 22fc407d3..265ff997f 100644 --- a/briar-android/src/main/res/drawable/level_indicator_circle.xml +++ b/briar-android/src/main/res/drawable/level_indicator_circle.xml @@ -5,5 +5,5 @@ + android:color="@color/thread_indicator"/> \ No newline at end of file diff --git a/briar-android/src/main/res/values/color.xml b/briar-android/src/main/res/values/color.xml index daf3f8b3b..b116d1aad 100644 --- a/briar-android/src/main/res/values/color.xml +++ b/briar-android/src/main/res/values/color.xml @@ -33,11 +33,12 @@ @color/briar_accent + + #9e9e9e #c1c1c1 #ffffff #FFFFFF #61000000 - #cfd2d4 #ffffff \ No newline at end of file diff --git a/briar-android/src/main/res/values/styles.xml b/briar-android/src/main/res/values/styles.xml index f599ac189..c967fdb07 100644 --- a/briar-android/src/main/res/values/styles.xml +++ b/briar-android/src/main/res/values/styles.xml @@ -102,7 +102,7 @@