diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/APIEditorActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/APIEditorActivity.java index ed58cbc3f..4a01d25dd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/APIEditorActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/APIEditorActivity.java @@ -37,6 +37,7 @@ import android.widget.Toast; import org.mariotaku.twidere.R; import org.mariotaku.twidere.model.ParcelableCredentials; import org.mariotaku.twidere.provider.TwidereDataStore.Accounts; +import org.mariotaku.twidere.util.TwitterAPIFactory; import static org.mariotaku.twidere.util.ParseUtils.parseString; import static org.mariotaku.twidere.util.Utils.getNonEmptyString; @@ -75,7 +76,11 @@ public class APIEditorActivity extends BaseSupportDialogActivity implements OnCh public void onClick(final View v) { switch (v.getId()) { case R.id.save: { - saveAndFinish(); + if (checkApiUrl()) { + saveAndFinish(); + } else { + mEditAPIUrlFormat.setError(getString(R.string.wrong_url_format)); + } break; } case R.id.api_url_format_help: { @@ -85,6 +90,10 @@ public class APIEditorActivity extends BaseSupportDialogActivity implements OnCh } } + private boolean checkApiUrl() { + return TwitterAPIFactory.verifyApiFormat(String.valueOf(mEditAPIUrlFormat.getText())); + } + @Override public void onContentChanged() { super.onContentChanged(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java index e3087d662..a054adf22 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java @@ -943,8 +943,12 @@ public final class TwidereDataProvider extends ContentProvider implements Consta builder.setNumber(statusesCount); builder.setColor(pref.getNotificationLightColor()); setNotificationPreferences(builder, pref, pref.getHomeTimelineNotificationType()); - nm.notify("home_" + accountId, NOTIFICATION_ID_HOME_TIMELINE, builder.build()); - Utils.sendPebbleNotification(context, notificationContent); + try { + nm.notify("home_" + accountId, NOTIFICATION_ID_HOME_TIMELINE, builder.build()); + Utils.sendPebbleNotification(context, notificationContent); + } catch (SecurityException e) { + // Silently ignore + } } finally { statusCursor.close(); userCursor.close(); @@ -1043,9 +1047,13 @@ public final class TwidereDataProvider extends ContentProvider implements Consta builder.setStyle(style); builder.setColor(pref.getNotificationLightColor()); setNotificationPreferences(builder, pref, pref.getMentionsNotificationType()); - nm.notify("mentions_" + accountId, NOTIFICATION_ID_MENTIONS_TIMELINE, - builder.build()); - Utils.sendPebbleNotification(context, notificationContent); + try { + nm.notify("mentions_" + accountId, NOTIFICATION_ID_MENTIONS_TIMELINE, + builder.build()); + Utils.sendPebbleNotification(context, notificationContent); + } catch (SecurityException e) { + // Silently ignore + } } finally { statusCursor.close(); userCursor.close(); @@ -1238,8 +1246,12 @@ public final class TwidereDataProvider extends ContentProvider implements Consta builder.setStyle(style); builder.setColor(pref.getNotificationLightColor()); setNotificationPreferences(builder, pref, pref.getDirectMessagesNotificationType()); - nm.notify("messages_" + accountId, NOTIFICATION_ID_DIRECT_MESSAGES, builder.build()); - Utils.sendPebbleNotification(context, notificationContent); + try { + nm.notify("messages_" + accountId, NOTIFICATION_ID_DIRECT_MESSAGES, builder.build()); + Utils.sendPebbleNotification(context, notificationContent); + } catch (SecurityException e) { + // Silently ignore + } } finally { messageCursor.close(); userCursor.close(); diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java index 1cda87f38..a83820ee5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterAPIFactory.java @@ -9,7 +9,9 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Pair; +import android.webkit.URLUtil; +import com.squareup.okhttp.HttpUrl; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.internal.Internal; @@ -59,7 +61,6 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import static android.text.TextUtils.isEmpty; @@ -175,7 +176,7 @@ public class TwitterAPIFactory implements TwidereConstants { return TwitterAPIFactory.getInstance(context, getEndpoint(credentials, cls), credentials, cls); } - public static Endpoint getEndpoint(ParcelableCredentials credentials, Class cls) { + public static Endpoint getEndpoint(ParcelableCredentials credentials, Class cls) throws APIFormatException { final String apiUrlFormat; final boolean sameOAuthSigningUrl = credentials.same_oauth_signing_url; final boolean noVersionSuffix = credentials.no_version_suffix; @@ -202,6 +203,8 @@ public class TwitterAPIFactory implements TwidereConstants { } final String endpointUrl; endpointUrl = getApiUrl(apiUrlFormat, domain, versionSuffix); + if (endpointUrl == null || HttpUrl.parse(endpointUrl) == null) + throw new APIFormatException(apiUrlFormat); if (credentials.auth_type == ParcelableCredentials.AUTH_TYPE_XAUTH || credentials.auth_type == ParcelableCredentials.AUTH_TYPE_OAUTH) { final String signEndpointUrl; if (!sameOAuthSigningUrl) { @@ -209,6 +212,8 @@ public class TwitterAPIFactory implements TwidereConstants { } else { signEndpointUrl = endpointUrl; } + if (signEndpointUrl == null || HttpUrl.parse(signEndpointUrl) == null) + throw new APIFormatException(apiUrlFormat); return new OAuthEndpoint(endpointUrl, signEndpointUrl); } return new Endpoint(endpointUrl); @@ -246,9 +251,13 @@ public class TwitterAPIFactory implements TwidereConstants { params.add(Pair.create(name, typedData)); } + public static boolean verifyApiFormat(String format) { + return URLUtil.isValidUrl(getApiBaseUrl(format, "test")); + } + public static String getApiBaseUrl(String format, final String domain) { if (format == null) return null; - final Matcher matcher = Pattern.compile("\\[(\\.?)DOMAIN(\\.?)\\]").matcher(format); + final Matcher matcher = Pattern.compile("\\[(\\.?)DOMAIN(\\.?)\\]", Pattern.CASE_INSENSITIVE).matcher(format); if (!matcher.find()) { // For backward compatibility format = substituteLegacyApiBaseUrl(format, domain); @@ -398,4 +407,10 @@ public class TwitterAPIFactory implements TwidereConstants { return te; } } + + public static class APIFormatException extends RuntimeException { + public APIFormatException(String format) { + super("Wrong api format " + format); + } + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/net/NetworkUsageUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/net/NetworkUsageUtils.java index 3b37334e0..6a959fa32 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/net/NetworkUsageUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/net/NetworkUsageUtils.java @@ -22,6 +22,7 @@ package org.mariotaku.twidere.util.net; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; +import android.util.Log; import com.squareup.okhttp.Interceptor; import com.squareup.okhttp.OkHttpClient; @@ -30,6 +31,7 @@ import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.Response; import com.squareup.okhttp.ResponseBody; +import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.model.RequestType; import org.mariotaku.twidere.provider.TwidereDataStore.NetworkUsages; import org.mariotaku.twidere.util.Utils; @@ -39,7 +41,7 @@ import java.io.IOException; /** * Created by mariotaku on 15/6/24. */ -public class NetworkUsageUtils { +public class NetworkUsageUtils implements Constants { public static void initForHttpClient(Context context, OkHttpClient client) { client.networkInterceptors().add(new NetworkUsageInterceptor(context)); } @@ -71,7 +73,11 @@ public class NetworkUsageUtils { final Response response = chain.proceed(request); values.put(NetworkUsages.KILOBYTES_RECEIVED, getBodyLength(response.body()) / 1024.0); final ContentResolver cr = context.getContentResolver(); - cr.insert(NetworkUsages.CONTENT_URI, values); + try { + cr.insert(NetworkUsages.CONTENT_URI, values); + } catch (IllegalStateException e) { + Log.e(LOGTAG, "Unable to log network usage", e); + } return response; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/net/OkHttpRestClient.java b/twidere/src/main/java/org/mariotaku/twidere/util/net/OkHttpRestClient.java index 4678b4271..6f13c0ca8 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/net/OkHttpRestClient.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/net/OkHttpRestClient.java @@ -264,4 +264,5 @@ public class OkHttpRestClient implements RestHttpClient { } } } + }