using json string during aidl call for better compatibility
added option to fail directly for network issues
This commit is contained in:
parent
dce1b65915
commit
43af801b6c
|
@ -18,16 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package org.mariotaku.twidere;
|
package org.mariotaku.twidere;
|
||||||
|
|
||||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
|
||||||
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
|
||||||
import org.mariotaku.twidere.model.StatusShortenResult;
|
|
||||||
|
|
||||||
interface IStatusShortener {
|
interface IStatusShortener {
|
||||||
|
|
||||||
StatusShortenResult shorten(in ParcelableStatusUpdate status,in ParcelableAccount currentAccount,
|
String shorten(String statusJson, long currentAccountId, String overrideStatusText);
|
||||||
String overrideStatusText);
|
|
||||||
|
|
||||||
boolean callback(in StatusShortenResult result, in ParcelableStatus status);
|
boolean callback(String resultJson, String statusJson);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,8 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
|
||||||
String METADATA_KEY_EXTENSION_SETTINGS = "org.mariotaku.twidere.extension.settings";
|
String METADATA_KEY_EXTENSION_SETTINGS = "org.mariotaku.twidere.extension.settings";
|
||||||
String METADATA_KEY_EXTENSION_ICON = "org.mariotaku.twidere.extension.icon";
|
String METADATA_KEY_EXTENSION_ICON = "org.mariotaku.twidere.extension.icon";
|
||||||
String METADATA_KEY_EXTENSION_USE_JSON = "org.mariotaku.twidere.extension.use_json";
|
String METADATA_KEY_EXTENSION_USE_JSON = "org.mariotaku.twidere.extension.use_json";
|
||||||
|
String METADATA_KEY_EXTENSION_VERSION_STATUS_SHORTENER = "org.mariotaku.twidere.extension.version.status_shortener";
|
||||||
|
String METADATA_KEY_EXTENSION_VERSION_MEDIA_UPLOADER = "org.mariotaku.twidere.extension.version.media_uploader";
|
||||||
|
|
||||||
char SEPARATOR_PERMISSION = '|';
|
char SEPARATOR_PERMISSION = '|';
|
||||||
String SEPARATOR_PERMISSION_REGEX = "\\" + SEPARATOR_PERMISSION;
|
String SEPARATOR_PERMISSION_REGEX = "\\" + SEPARATOR_PERMISSION;
|
||||||
|
|
|
@ -302,6 +302,8 @@ public interface SharedPreferenceConstants {
|
||||||
String KEY_API_LAST_CHANGE = "api_last_change";
|
String KEY_API_LAST_CHANGE = "api_last_change";
|
||||||
@Preference(type = LONG, exportable = false)
|
@Preference(type = LONG, exportable = false)
|
||||||
String KEY_DEFAULT_ACCOUNT_ID = "default_account_id";
|
String KEY_DEFAULT_ACCOUNT_ID = "default_account_id";
|
||||||
|
@Preference(type = BOOLEAN, exportable = true, defaultBoolean = true)
|
||||||
|
String KEY_RETRY_ON_NETWORK_ISSUE = "retry_on_network_issue";
|
||||||
|
|
||||||
|
|
||||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="status_shortener_service_interface_version">2</string>
|
||||||
|
<string name="media_uploader_service_interface_version">2</string>
|
||||||
|
</resources>
|
|
@ -39,7 +39,7 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
apt 'com.bluelinelabs:logansquare-compiler:1.3.4'
|
apt 'com.bluelinelabs:logansquare-compiler:1.3.4'
|
||||||
compile 'com.github.mariotaku.RestFu:urlconnection:0.9.23'
|
compile 'com.github.mariotaku.RestFu:urlconnection:0.9.24'
|
||||||
compile project(':twidere.library.extension')
|
compile project(':twidere.library.extension')
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,11 @@
|
||||||
<service
|
<service
|
||||||
android:name=".GistStatusShortenerService"
|
android:name=".GistStatusShortenerService"
|
||||||
android:permission="org.mariotaku.twidere.permission.SHORTEN_STATUS">
|
android:permission="org.mariotaku.twidere.permission.SHORTEN_STATUS">
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="org.mariotaku.twidere.extension.version.status_shortener"
|
||||||
|
android:value="@string/status_shortener_service_interface_version"/>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.mariotaku.twidere.EXTENSION_SHORTEN_STATUS"/>
|
<action android:name="org.mariotaku.twidere.EXTENSION_SHORTEN_STATUS"/>
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import org.mariotaku.twidere.service.StatusShortenerService;
|
||||||
public class GistStatusShortenerService extends StatusShortenerService {
|
public class GistStatusShortenerService extends StatusShortenerService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected StatusShortenResult shorten(ParcelableStatusUpdate status, ParcelableAccount currentAccount, String overrideStatusText) {
|
protected StatusShortenResult shorten(ParcelableStatusUpdate status, long currentAccountId, String overrideStatusText) {
|
||||||
final Github github = GithubFactory.getInstance(getApiKey());
|
final Github github = GithubFactory.getInstance(getApiKey());
|
||||||
final NewGist newGist = new NewGist();
|
final NewGist newGist = new NewGist();
|
||||||
newGist.setDescription("long tweet");
|
newGist.setDescription("long tweet");
|
||||||
|
|
|
@ -38,7 +38,7 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
apt 'com.bluelinelabs:logansquare-compiler:1.3.4'
|
apt 'com.bluelinelabs:logansquare-compiler:1.3.4'
|
||||||
compile 'com.github.mariotaku.RestFu:urlconnection:0.9.23'
|
compile 'com.github.mariotaku.RestFu:urlconnection:0.9.24'
|
||||||
compile project(':twidere.library.extension')
|
compile project(':twidere.library.extension')
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,11 @@
|
||||||
<service
|
<service
|
||||||
android:name=".TwitLongerStatusShortenerService"
|
android:name=".TwitLongerStatusShortenerService"
|
||||||
android:permission="org.mariotaku.twidere.permission.SHORTEN_STATUS">
|
android:permission="org.mariotaku.twidere.permission.SHORTEN_STATUS">
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="org.mariotaku.twidere.extension.version.status_shortener"
|
||||||
|
android:value="@string/status_shortener_service_interface_version"/>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.mariotaku.twidere.EXTENSION_SHORTEN_STATUS"/>
|
<action android:name="org.mariotaku.twidere.EXTENSION_SHORTEN_STATUS"/>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.mariotaku.twidere.Twidere;
|
import org.mariotaku.twidere.Twidere;
|
||||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
|
||||||
import org.mariotaku.twidere.model.ParcelableCredentials;
|
import org.mariotaku.twidere.model.ParcelableCredentials;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
||||||
|
@ -31,7 +30,7 @@ public class TwitLongerStatusShortenerService extends StatusShortenerService imp
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected StatusShortenResult shorten(final ParcelableStatusUpdate status,
|
protected StatusShortenResult shorten(final ParcelableStatusUpdate status,
|
||||||
final ParcelableAccount currentAccount,
|
final long currentAccountId,
|
||||||
final String overrideStatusText) {
|
final String overrideStatusText) {
|
||||||
final int granted = Twidere.isPermissionGranted(this);
|
final int granted = Twidere.isPermissionGranted(this);
|
||||||
if (granted == Twidere.Permission.DENIED) {
|
if (granted == Twidere.Permission.DENIED) {
|
||||||
|
@ -57,7 +56,7 @@ public class TwitLongerStatusShortenerService extends StatusShortenerService imp
|
||||||
}
|
}
|
||||||
final ParcelableCredentials credentials;
|
final ParcelableCredentials credentials;
|
||||||
try {
|
try {
|
||||||
credentials = getOAuthCredentials(currentAccount.account_id);
|
credentials = getOAuthCredentials(currentAccountId);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Log.w(LOGTAG, e);
|
Log.w(LOGTAG, e);
|
||||||
|
|
|
@ -2,15 +2,17 @@ package org.mariotaku.twidere.service;
|
||||||
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
||||||
import org.mariotaku.twidere.IStatusShortener;
|
import org.mariotaku.twidere.IStatusShortener;
|
||||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
||||||
import org.mariotaku.twidere.model.StatusShortenResult;
|
import org.mariotaku.twidere.model.StatusShortenResult;
|
||||||
|
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,7 +26,7 @@ public abstract class StatusShortenerService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract StatusShortenResult shorten(ParcelableStatusUpdate status,
|
protected abstract StatusShortenResult shorten(ParcelableStatusUpdate status,
|
||||||
ParcelableAccount currentAccount,
|
long currentAccountId,
|
||||||
String overrideStatusText);
|
String overrideStatusText);
|
||||||
|
|
||||||
protected abstract boolean callback(StatusShortenResult result, ParcelableStatus status);
|
protected abstract boolean callback(StatusShortenResult result, ParcelableStatus status);
|
||||||
|
@ -43,16 +45,38 @@ public abstract class StatusShortenerService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusShortenResult shorten(final ParcelableStatusUpdate status,
|
public String shorten(final String statusJson, final long currentAccountId,
|
||||||
final ParcelableAccount currentAccount,
|
final String overrideStatusText)
|
||||||
final String overrideStatusText)
|
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
return mService.get().shorten(status, currentAccount, overrideStatusText);
|
try {
|
||||||
|
final ParcelableStatusUpdate statusUpdate = LoganSquareMapperFinder.mapperFor(ParcelableStatusUpdate.class)
|
||||||
|
.parse(statusJson);
|
||||||
|
final StatusShortenResult shorten = mService.get().shorten(statusUpdate, currentAccountId, overrideStatusText);
|
||||||
|
return LoganSquareMapperFinder.mapperFor(StatusShortenResult.class).serialize(shorten);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||||
|
throw new RemoteException(e.getMessage());
|
||||||
|
} else {
|
||||||
|
throw new RemoteException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean callback(StatusShortenResult result, ParcelableStatus status) throws RemoteException {
|
public boolean callback(String resultJson, String statusJson) throws RemoteException {
|
||||||
return mService.get().callback(result, status);
|
try {
|
||||||
|
final StatusShortenResult result = LoganSquareMapperFinder.mapperFor(StatusShortenResult.class)
|
||||||
|
.parse(resultJson);
|
||||||
|
final ParcelableStatus status = LoganSquareMapperFinder.mapperFor(ParcelableStatus.class)
|
||||||
|
.parse(statusJson);
|
||||||
|
return mService.get().callback(result, status);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||||
|
throw new RemoteException(e.getMessage());
|
||||||
|
} else {
|
||||||
|
throw new RemoteException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,17 +212,19 @@ public class TwidereApplication extends MultiDexApplication implements Constants
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KEY_ENABLE_PROXY:
|
case KEY_ENABLE_PROXY:
|
||||||
case KEY_CONNECTION_TIMEOUT:
|
|
||||||
case KEY_PROXY_HOST:
|
case KEY_PROXY_HOST:
|
||||||
case KEY_PROXY_PORT:
|
case KEY_PROXY_PORT:
|
||||||
case KEY_PROXY_TYPE:
|
case KEY_PROXY_TYPE:
|
||||||
case KEY_PROXY_USERNAME:
|
case KEY_PROXY_USERNAME:
|
||||||
case KEY_PROXY_PASSWORD: {
|
case KEY_PROXY_PASSWORD:
|
||||||
|
case KEY_CONNECTION_TIMEOUT:
|
||||||
|
case KEY_RETRY_ON_NETWORK_ISSUE: {
|
||||||
HttpClientFactory.reloadConnectivitySettings(this);
|
HttpClientFactory.reloadConnectivitySettings(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KEY_DNS_SERVER:
|
case KEY_DNS_SERVER:
|
||||||
case KEY_TCP_DNS_QUERY: {
|
case KEY_TCP_DNS_QUERY:
|
||||||
|
case KEY_BUILTIN_DNS_RESOLVER: {
|
||||||
reloadDnsSettings();
|
reloadDnsSettings();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,11 @@ import android.content.pm.PackageManager;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationCompat.Builder;
|
import android.support.v4.app.NotificationCompat.Builder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
@ -84,6 +86,7 @@ import org.mariotaku.twidere.preference.ServicePickerPreference;
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags;
|
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags;
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
|
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
|
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
|
||||||
|
import org.mariotaku.twidere.util.AbsServiceInterface;
|
||||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||||
import org.mariotaku.twidere.util.BitmapUtils;
|
import org.mariotaku.twidere.util.BitmapUtils;
|
||||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||||
|
@ -519,6 +522,23 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||||
if (!ServicePickerPreference.isNoneValue(shortenerComponent)) {
|
if (!ServicePickerPreference.isNoneValue(shortenerComponent)) {
|
||||||
shortener = StatusShortenerInterface.getInstance(app, shortenerComponent);
|
shortener = StatusShortenerInterface.getInstance(app, shortenerComponent);
|
||||||
if (shortener == null) throw new ShortenerNotFoundException(this);
|
if (shortener == null) throw new ShortenerNotFoundException(this);
|
||||||
|
try {
|
||||||
|
shortener.checkService(new AbsServiceInterface.CheckServiceAction() {
|
||||||
|
@Override
|
||||||
|
public void check(@Nullable Bundle metaData) throws AbsServiceInterface.CheckServiceException {
|
||||||
|
if (metaData == null) throw new ExtensionVersionMismatchException();
|
||||||
|
final String extensionVersion = metaData.getString(METADATA_KEY_EXTENSION_VERSION_STATUS_SHORTENER);
|
||||||
|
if (!TextUtils.equals(extensionVersion, getString(R.string.status_shortener_service_interface_version))) {
|
||||||
|
throw new ExtensionVersionMismatchException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (AbsServiceInterface.CheckServiceException e) {
|
||||||
|
if (e instanceof ExtensionVersionMismatchException) {
|
||||||
|
throw new ShortenException(getString(R.string.shortener_version_incompatible));
|
||||||
|
}
|
||||||
|
throw new ShortenException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean hasMedia = statusUpdate.media != null && statusUpdate.media.length > 0;
|
final boolean hasMedia = statusUpdate.media != null && statusUpdate.media.length > 0;
|
||||||
|
@ -581,7 +601,8 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||||
StatusShortenResult shortenedResult = null;
|
StatusShortenResult shortenedResult = null;
|
||||||
if (shouldShorten && shortener != null) {
|
if (shouldShorten && shortener != null) {
|
||||||
try {
|
try {
|
||||||
shortenedResult = shortener.shorten(statusUpdate, account, statusText);
|
shortenedResult = shortener.shorten(statusUpdate, account.account_id,
|
||||||
|
statusText);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new ShortenException(getString(R.string.error_message_tweet_shorten_failed), e);
|
throw new ShortenException(getString(R.string.error_message_tweet_shorten_failed), e);
|
||||||
}
|
}
|
||||||
|
@ -910,4 +931,8 @@ public class BackgroundOperationService extends IntentService implements Constan
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class ExtensionVersionMismatchException extends AbsServiceInterface.CheckServiceException {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,10 @@ import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.IInterface;
|
import android.os.IInterface;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
|
@ -37,6 +39,8 @@ public abstract class AbsServiceInterface<I extends IInterface> implements Const
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final String mShortenerName;
|
private final String mShortenerName;
|
||||||
|
@Nullable
|
||||||
|
private final Bundle mMetaData;
|
||||||
private I mIInterface;
|
private I mIInterface;
|
||||||
|
|
||||||
private ServiceToken mToken;
|
private ServiceToken mToken;
|
||||||
|
@ -56,9 +60,10 @@ public abstract class AbsServiceInterface<I extends IInterface> implements Const
|
||||||
|
|
||||||
protected abstract I onServiceConnected(ComponentName service, IBinder obj);
|
protected abstract I onServiceConnected(ComponentName service, IBinder obj);
|
||||||
|
|
||||||
protected AbsServiceInterface(final Context context, final String shortenerName) {
|
protected AbsServiceInterface(final Context context, final String componentName, @Nullable final Bundle metaData) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mShortenerName = shortenerName;
|
mShortenerName = componentName;
|
||||||
|
mMetaData = metaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final I getInterface() {
|
public final I getInterface() {
|
||||||
|
@ -89,4 +94,15 @@ public abstract class AbsServiceInterface<I extends IInterface> implements Const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void checkService(CheckServiceAction action) throws CheckServiceException {
|
||||||
|
action.check(mMetaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface CheckServiceAction {
|
||||||
|
void check(@Nullable Bundle metaData) throws CheckServiceException;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CheckServiceException extends Exception {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.mariotaku.twidere.util;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
@ -10,9 +9,11 @@ import org.mariotaku.restfu.http.RestHttpClient;
|
||||||
import org.mariotaku.restfu.okhttp3.OkHttpRestClient;
|
import org.mariotaku.restfu.okhttp3.OkHttpRestClient;
|
||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.util.dagger.DependencyHolder;
|
import org.mariotaku.twidere.util.dagger.DependencyHolder;
|
||||||
|
import org.mariotaku.twidere.util.net.TwidereDns;
|
||||||
import org.mariotaku.twidere.util.net.TwidereProxySelector;
|
import org.mariotaku.twidere.util.net.TwidereProxySelector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -33,14 +34,14 @@ import static android.text.TextUtils.isEmpty;
|
||||||
public class HttpClientFactory implements Constants {
|
public class HttpClientFactory implements Constants {
|
||||||
|
|
||||||
public static RestHttpClient createRestHttpClient(final Context context,
|
public static RestHttpClient createRestHttpClient(final Context context,
|
||||||
final SharedPreferences prefs, final Dns dns,
|
final SharedPreferencesWrapper prefs, final Dns dns,
|
||||||
final ConnectionPool connectionPool) {
|
final ConnectionPool connectionPool) {
|
||||||
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
initOkHttpClient(context, prefs, builder, dns, connectionPool);
|
initOkHttpClient(context, prefs, builder, dns, connectionPool);
|
||||||
return new OkHttpRestClient(builder.build());
|
return new OkHttpRestClient(builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initOkHttpClient(final Context context, final SharedPreferences prefs,
|
public static void initOkHttpClient(final Context context, final SharedPreferencesWrapper prefs,
|
||||||
final OkHttpClient.Builder builder, final Dns dns,
|
final OkHttpClient.Builder builder, final Dns dns,
|
||||||
final ConnectionPool connectionPool) {
|
final ConnectionPool connectionPool) {
|
||||||
updateHttpClientConfiguration(context, builder, prefs, dns, connectionPool);
|
updateHttpClientConfiguration(context, builder, prefs, dns, connectionPool);
|
||||||
|
@ -50,11 +51,11 @@ public class HttpClientFactory implements Constants {
|
||||||
@SuppressLint("SSLCertificateSocketFactoryGetInsecure")
|
@SuppressLint("SSLCertificateSocketFactoryGetInsecure")
|
||||||
public static void updateHttpClientConfiguration(final Context context,
|
public static void updateHttpClientConfiguration(final Context context,
|
||||||
final OkHttpClient.Builder builder,
|
final OkHttpClient.Builder builder,
|
||||||
final SharedPreferences prefs, final Dns dns,
|
final SharedPreferencesWrapper prefs, final Dns dns,
|
||||||
final ConnectionPool connectionPool) {
|
final ConnectionPool connectionPool) {
|
||||||
final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false);
|
final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false);
|
||||||
builder.connectTimeout(prefs.getInt(KEY_CONNECTION_TIMEOUT, 10), TimeUnit.SECONDS);
|
builder.connectTimeout(prefs.getInt(KEY_CONNECTION_TIMEOUT, 10), TimeUnit.SECONDS);
|
||||||
builder.retryOnConnectionFailure(true);
|
builder.retryOnConnectionFailure(prefs.getBoolean(KEY_RETRY_ON_NETWORK_ISSUE));
|
||||||
builder.connectionPool(connectionPool);
|
builder.connectionPool(connectionPool);
|
||||||
if (enableProxy) {
|
if (enableProxy) {
|
||||||
final String proxyType = prefs.getString(KEY_PROXY_TYPE, null);
|
final String proxyType = prefs.getString(KEY_PROXY_TYPE, null);
|
||||||
|
@ -64,7 +65,11 @@ public class HttpClientFactory implements Constants {
|
||||||
TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE)) {
|
TwidereMathUtils.RANGE_INCLUSIVE_INCLUSIVE)) {
|
||||||
final Proxy.Type type = getProxyType(proxyType);
|
final Proxy.Type type = getProxyType(proxyType);
|
||||||
if (type != Proxy.Type.DIRECT) {
|
if (type != Proxy.Type.DIRECT) {
|
||||||
builder.proxySelector(new TwidereProxySelector(context, type, proxyHost, proxyPort));
|
if (TwidereDns.isValidIpAddress(proxyHost)) {
|
||||||
|
builder.proxy(new Proxy(type, InetSocketAddress.createUnresolved(proxyHost, proxyPort)));
|
||||||
|
} else {
|
||||||
|
builder.proxySelector(new TwidereProxySelector(context, type, proxyHost, proxyPort));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final String username = prefs.getString(KEY_PROXY_USERNAME, null);
|
final String username = prefs.getString(KEY_PROXY_USERNAME, null);
|
||||||
|
|
|
@ -23,6 +23,9 @@ import android.app.Application;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -32,9 +35,11 @@ import org.mariotaku.twidere.model.MediaUploadResult;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
||||||
import org.mariotaku.twidere.model.UploaderMediaItem;
|
import org.mariotaku.twidere.model.UploaderMediaItem;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class MediaUploaderInterface extends AbsServiceInterface<IMediaUploader> implements IMediaUploader {
|
public final class MediaUploaderInterface extends AbsServiceInterface<IMediaUploader> implements IMediaUploader {
|
||||||
protected MediaUploaderInterface(Context context, String shortenerName) {
|
protected MediaUploaderInterface(Context context, String uploaderName, Bundle metaData) {
|
||||||
super(context, shortenerName);
|
super(context, uploaderName, metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MediaUploaderInterface getInstance(final Application application, final String uploaderName) {
|
public static MediaUploaderInterface getInstance(final Application application, final String uploaderName) {
|
||||||
|
@ -42,8 +47,10 @@ public final class MediaUploaderInterface extends AbsServiceInterface<IMediaUplo
|
||||||
final Intent intent = new Intent(INTENT_ACTION_EXTENSION_UPLOAD_MEDIA);
|
final Intent intent = new Intent(INTENT_ACTION_EXTENSION_UPLOAD_MEDIA);
|
||||||
final ComponentName component = ComponentName.unflattenFromString(uploaderName);
|
final ComponentName component = ComponentName.unflattenFromString(uploaderName);
|
||||||
intent.setComponent(component);
|
intent.setComponent(component);
|
||||||
if (application.getPackageManager().queryIntentServices(intent, 0).size() != 1) return null;
|
final PackageManager pm = application.getPackageManager();
|
||||||
return new MediaUploaderInterface(application, uploaderName);
|
final List<ResolveInfo> services = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
|
||||||
|
if (services.size() != 1) return null;
|
||||||
|
return new MediaUploaderInterface(application, uploaderName, services.get(0).serviceInfo.metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,19 +23,23 @@ import android.app.Application;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
||||||
import org.mariotaku.twidere.IStatusShortener;
|
import org.mariotaku.twidere.IStatusShortener;
|
||||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
|
||||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||||
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
||||||
import org.mariotaku.twidere.model.StatusShortenResult;
|
import org.mariotaku.twidere.model.StatusShortenResult;
|
||||||
|
|
||||||
public final class StatusShortenerInterface extends AbsServiceInterface<IStatusShortener> implements IStatusShortener {
|
import java.util.List;
|
||||||
|
|
||||||
protected StatusShortenerInterface(Context context, String shortenerName) {
|
public final class StatusShortenerInterface extends AbsServiceInterface<IStatusShortener> {
|
||||||
super(context, shortenerName);
|
|
||||||
|
protected StatusShortenerInterface(Context context, String shortenerName, Bundle metaData) {
|
||||||
|
super(context, shortenerName, metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,37 +47,41 @@ public final class StatusShortenerInterface extends AbsServiceInterface<IStatusS
|
||||||
return IStatusShortener.Stub.asInterface(obj);
|
return IStatusShortener.Stub.asInterface(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public StatusShortenResult shorten(final ParcelableStatusUpdate status,
|
public StatusShortenResult shorten(final ParcelableStatusUpdate status,
|
||||||
final ParcelableAccount currentAccount,
|
final long currentAccountId,
|
||||||
final String overrideStatusText) {
|
final String overrideStatusText) {
|
||||||
final IStatusShortener iface = getInterface();
|
final IStatusShortener iface = getInterface();
|
||||||
if (iface == null) return null;
|
if (iface == null) return null;
|
||||||
try {
|
try {
|
||||||
return iface.shorten(status, currentAccount, overrideStatusText);
|
final String statusJson = JsonSerializer.serialize(status, ParcelableStatusUpdate.class);
|
||||||
|
final String resultJson = iface.shorten(statusJson, currentAccountId, overrideStatusText);
|
||||||
|
return JsonSerializer.parse(resultJson, StatusShortenResult.class);
|
||||||
} catch (final RemoteException e) {
|
} catch (final RemoteException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean callback(StatusShortenResult result, ParcelableStatus status) {
|
public boolean callback(StatusShortenResult result, ParcelableStatus status) {
|
||||||
final IStatusShortener iface = getInterface();
|
final IStatusShortener iface = getInterface();
|
||||||
if (iface == null) return false;
|
if (iface == null) return false;
|
||||||
try {
|
try {
|
||||||
return iface.callback(result, status);
|
final String resultJson = JsonSerializer.serialize(result, StatusShortenResult.class);
|
||||||
|
final String statusJson = JsonSerializer.serialize(status, ParcelableStatus.class);
|
||||||
|
return iface.callback(resultJson, statusJson);
|
||||||
} catch (final RemoteException e) {
|
} catch (final RemoteException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StatusShortenerInterface getInstance(final Application application, final String shortener_name) {
|
public static StatusShortenerInterface getInstance(final Application application, final String shortenerName) {
|
||||||
if (shortener_name == null) return null;
|
if (shortenerName == null) return null;
|
||||||
final Intent intent = new Intent(INTENT_ACTION_EXTENSION_SHORTEN_STATUS);
|
final Intent intent = new Intent(INTENT_ACTION_EXTENSION_SHORTEN_STATUS);
|
||||||
final ComponentName component = ComponentName.unflattenFromString(shortener_name);
|
final ComponentName component = ComponentName.unflattenFromString(shortenerName);
|
||||||
intent.setComponent(component);
|
intent.setComponent(component);
|
||||||
if (application.getPackageManager().queryIntentServices(intent, 0).size() != 1) return null;
|
final PackageManager pm = application.getPackageManager();
|
||||||
return new StatusShortenerInterface(application, shortener_name);
|
final List<ResolveInfo> services = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
|
||||||
|
if (services.size() != 1) return null;
|
||||||
|
return new StatusShortenerInterface(application, shortenerName, services.get(0).serviceInfo.metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -742,6 +742,8 @@
|
||||||
<string name="action_start">Start</string>
|
<string name="action_start">Start</string>
|
||||||
<string name="builtin_dns_resolver">Builtin DNS resolver</string>
|
<string name="builtin_dns_resolver">Builtin DNS resolver</string>
|
||||||
<string name="bandwidth_saving_mode">Bandwidth saving mode</string>
|
<string name="bandwidth_saving_mode">Bandwidth saving mode</string>
|
||||||
|
<string name="retry_on_network_issue">Retry on network issue</string>
|
||||||
|
<string name="retry_on_network_issue_summary">Try recover from network issue automatically</string>
|
||||||
<string name="bandwidth_saving_mode_summary">Disable media preview on metered network</string>
|
<string name="bandwidth_saving_mode_summary">Disable media preview on metered network</string>
|
||||||
<string name="recent_media">Recent media</string>
|
<string name="recent_media">Recent media</string>
|
||||||
<string name="reply_to_name_text">Reply to <xliff:g id="name">%1$s</xliff:g>: <xliff:g id="text">%2$s</xliff:g></string>
|
<string name="reply_to_name_text">Reply to <xliff:g id="name">%1$s</xliff:g>: <xliff:g id="text">%2$s</xliff:g></string>
|
||||||
|
@ -750,4 +752,5 @@
|
||||||
<string name="status_menu_title_format"><xliff:g id="name">%1$s</xliff:g>: <xliff:g id="text">%2$s</xliff:g></string>
|
<string name="status_menu_title_format"><xliff:g id="name">%1$s</xliff:g>: <xliff:g id="text">%2$s</xliff:g></string>
|
||||||
<string name="translate_from_language">Translate from <xliff:g id="language">%s</xliff:g></string>
|
<string name="translate_from_language">Translate from <xliff:g id="language">%s</xliff:g></string>
|
||||||
<string name="translation">Translation</string>
|
<string name="translation">Translation</string>
|
||||||
|
<string name="shortener_version_incompatible">Incompatible shortener</string>
|
||||||
</resources>
|
</resources>
|
|
@ -33,6 +33,12 @@
|
||||||
android:key="custom_host_mapping"
|
android:key="custom_host_mapping"
|
||||||
android:summary="@string/custom_host_mapping_summary"
|
android:summary="@string/custom_host_mapping_summary"
|
||||||
android:title="@string/custom_host_mapping"/>
|
android:title="@string/custom_host_mapping"/>
|
||||||
|
|
||||||
|
<org.mariotaku.twidere.preference.AutoFixSwitchPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="retry_on_network_issue"
|
||||||
|
android:summary="@string/retry_on_network_issue_summary"
|
||||||
|
android:title="@string/retry_on_network_issue"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="category_proxy"
|
android:key="category_proxy"
|
||||||
|
|
Loading…
Reference in New Issue