tweaking dns

This commit is contained in:
Mariotaku Lee 2016-02-11 23:33:38 +08:00
parent 6ca8f3b384
commit 0d87425259
23 changed files with 457 additions and 305 deletions

View File

@ -0,0 +1,8 @@
package org.mariotaku.twidere.test;
/**
* Created by mariotaku on 16/2/11.
*/
public class OkHttpTest {
}

View File

@ -44,7 +44,7 @@ public class DebugModeUtils {
private static RefWatcher sRefWatcher;
public static void initForHttpClient(final OkHttpClient.Builder builder) {
public static void initForOkHttpClient(final OkHttpClient.Builder builder) {
builder.addNetworkInterceptor(new StethoInterceptor());
}

View File

@ -115,7 +115,7 @@ public class HotMobiLogger implements HotMobiConstants {
return prefs.getLong(KEY_LAST_UPLOAD_TIME, -1);
}
public static boolean log(final String msg) {
public static boolean printLog(final String msg) {
if (BuildConfig.DEBUG) {
final StackTraceElement ste = new Throwable().fillInStackTrace().getStackTrace()[1];
final String fullName = ste.getClassName();

View File

@ -23,23 +23,21 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.util.BugReporter;
import org.mariotaku.twidere.util.Utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.Locale;
import edu.tsinghua.hotmobi.model.UploadLogEvent;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Upload logs to target server
@ -48,24 +46,22 @@ import okhttp3.Response;
public class UploadLogsTask implements Runnable {
private final Context context;
private final OkHttpClient client;
public UploadLogsTask(Context context) {
this.context = context;
this.client = new OkHttpClient();
}
@Override
public void run() {
final SharedPreferences prefs = context.getSharedPreferences("spice_data_profiling", Context.MODE_PRIVATE);
final SharedPreferences prefs = context.getSharedPreferences(HotMobiConstants.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
if (prefs.contains(HotMobiConstants.KEY_LAST_UPLOAD_TIME)) {
final long lastUpload = prefs.getLong(HotMobiConstants.KEY_LAST_UPLOAD_TIME, System.currentTimeMillis());
final double deltaDays = (System.currentTimeMillis() - lastUpload) /
(double) HotMobiLogger.UPLOAD_INTERVAL_MILLIS;
if (deltaDays < 1) {
HotMobiLogger.log("Last uploaded was conducted in 1 day ago.");
HotMobiLogger.printLog("Last uploaded was conducted in 1 day ago.");
return;
}
}
@ -86,25 +82,32 @@ public class UploadLogsTask implements Runnable {
return !filename.equalsIgnoreCase(todayDir);
}
};
for (Object dayLogsDirObj : ArrayUtils.nullToEmpty(logsDir.listFiles(filter))) {
final File dayLogsDir = (File) dayLogsDirObj;
File[] dayLogsDirs = logsDir.listFiles(filter);
if (dayLogsDirs == null) return false;
for (File dayLogsDir : dayLogsDirs) {
File[] logFiles = dayLogsDir.listFiles();
if (logFiles == null) continue;
boolean succeeded = true;
for (Object logFileObj : ArrayUtils.nullToEmpty(dayLogsDir.listFiles())) {
File logFile = (File) logFileObj;
for (File logFile : logFiles) {
OutputStream os = null;
InputStream is = null;
try {
final Request.Builder builder = new Request.Builder();
builder.url("http://www.dnext.xyz/usage/upload");
builder.header("X-HotMobi-UUID", uuid);
builder.header("X-HotMobi-Date", dayLogsDir.getName());
builder.header("X-HotMobi-FileName", logFile.getName());
builder.header("User-Agent", String.format(Locale.ROOT,
final UploadLogEvent uploadLogEvent = UploadLogEvent.create(context, logFile);
HttpURLConnection conn = (HttpURLConnection) new URL("http://www.dnext.xyz/usage/upload").openConnection();
conn.setRequestProperty("X-HotMobi-UUID", uuid);
conn.setRequestProperty("X-HotMobi-Date", dayLogsDir.getName());
conn.setRequestProperty("X-HotMobi-FileName", logFile.getName());
conn.setRequestProperty("User-Agent", String.format(Locale.ROOT,
"HotMobi (Twidere %s %d)", BuildConfig.VERSION_NAME,
BuildConfig.VERSION_CODE));
builder.method("POST", RequestBody.create(MediaType.parse("text/plain"), logFile));
final UploadLogEvent uploadLogEvent = UploadLogEvent.create(context, logFile);
final Response response = client.newCall(builder.build()).execute();
if (response.isSuccessful()) {
uploadLogEvent.finish(response);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
os = conn.getOutputStream();
is = new FileInputStream(logFile);
Utils.copyStream(is, os);
final int responseCode = conn.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
uploadLogEvent.finish(conn);
if (!uploadLogEvent.shouldSkip()) {
HotMobiLogger.getInstance(context).log(uploadLogEvent);
}
@ -114,6 +117,9 @@ public class UploadLogsTask implements Runnable {
Log.w(HotMobiLogger.LOGTAG, e);
succeeded = false;
hasErrors = true;
} finally {
Utils.closeSilently(is);
Utils.closeSilently(os);
}
}
if (succeeded) {

View File

@ -12,21 +12,19 @@ import com.hannesdorfmann.parcelableplease.annotation.Bagger;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Headers;
import okhttp3.Response;
/**
* Created by mariotaku on 16/1/2.
*/
@ParcelablePlease
@JsonObject
public class UploadLogEvent extends BaseEvent implements Parcelable {
private static final String X_DNEXT_PREFIX = "X-Dnext";
public static final Creator<UploadLogEvent> CREATOR = new Creator<UploadLogEvent>() {
public UploadLogEvent createFromParcel(Parcel source) {
UploadLogEvent target = new UploadLogEvent();
@ -83,19 +81,23 @@ public class UploadLogEvent extends BaseEvent implements Parcelable {
UploadLogEventParcelablePlease.writeToParcel(this, dest, flags);
}
public void finish(Response response) {
public void finish(HttpURLConnection response) {
HashMap<String, String> extraHeaders = new HashMap<>();
final Headers headers = response.headers();
for (int i = 0, j = headers.size(); i < j; i++) {
final String name = headers.name(i);
if (StringUtils.startsWithIgnoreCase(name, "X-Dnext")) {
extraHeaders.put(name, headers.value(i));
final Map<String, List<String>> headers = response.getHeaderFields();
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
final String name = entry.getKey();
if (name == null) continue;
if (name.regionMatches(true, 0, X_DNEXT_PREFIX, 0, X_DNEXT_PREFIX.length())) {
for (String value : entry.getValue()) {
extraHeaders.put(name, value);
}
}
}
setExtraHeaders(extraHeaders);
markEnd();
}
public static UploadLogEvent create(Context context, File file) {
UploadLogEvent event = new UploadLogEvent();
event.markStart(context);

View File

@ -161,6 +161,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
mDrawerLayout.closeDrawers();
}
@NonNull
public long[] getActivatedAccountIds() {
final Fragment fragment = getLeftDrawerFragment();
if (fragment instanceof AccountsDashboardFragment) {

View File

@ -139,8 +139,6 @@ public class TwidereApplication extends MultiDexApplication implements Constants
migrateUsageStatisticsPreferences();
Utils.startRefreshServiceIfNeeded(this);
reloadConnectivitySettings();
DependencyHolder holder = DependencyHolder.get(this);
registerActivityLifecycleCallbacks(holder.getActivityTracker());
@ -263,9 +261,12 @@ public class TwidereApplication extends MultiDexApplication implements Constants
final RestHttpClient client = holder.getRestHttpClient();
if (client instanceof OkHttpRestClient) {
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
HttpClientFactory.initDefaultHttpClient(this, holder.getPreferences(), builder,
HttpClientFactory.initOkHttpClient(this, holder.getPreferences(), builder,
holder.getDns());
((OkHttpRestClient) client).setClient(builder.build());
final OkHttpRestClient restClient = (OkHttpRestClient) client;
// Kill all connections
restClient.getClient().connectionPool().evictAll();
restClient.setClient(builder.build());
}
}

View File

@ -2,13 +2,18 @@ package org.mariotaku.twidere.fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -71,8 +76,21 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
return inflater.inflate(R.layout.fragment_network_diagnostics, container, false);
}
private void appendMessage(String message) {
mLogTextView.append(message);
private void appendMessage(LogText message) {
SpannableString coloredText = SpannableString.valueOf(message.message);
switch (message.state) {
case LogText.State.GOOD: {
coloredText.setSpan(new ForegroundColorSpan(Color.GREEN), 0, coloredText.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
}
case LogText.State.BAD: {
coloredText.setSpan(new ForegroundColorSpan(Color.RED), 0, coloredText.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
break;
}
}
mLogTextView.append(coloredText);
}
static class DiagnosticsTask extends AsyncTask<Object, LogText, Object> {
@ -146,7 +164,7 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
testDns(dns, host);
testNativeLookup(host);
} else {
publishProgress(new LogText("API URL format is invalid"));
publishProgress(new LogText("API URL format is invalid", LogText.State.BAD));
publishProgress(LogText.LINEBREAK);
}
@ -197,9 +215,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
} else {
publishProgress(new LogText(String.valueOf(dns.lookup(host))));
}
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis() - start)));
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis()
- start), LogText.State.GOOD));
} catch (UnknownHostException e) {
publishProgress(new LogText("ERROR: " + e.getMessage()));
publishProgress(new LogText("ERROR: " + e.getMessage(), LogText.State.BAD));
}
publishProgress(LogText.LINEBREAK);
}
@ -209,9 +228,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
try {
final long start = SystemClock.uptimeMillis();
publishProgress(new LogText(Arrays.toString(InetAddress.getAllByName(host))));
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis() - start)));
publishProgress(new LogText(String.format(" OK (%d ms)", SystemClock.uptimeMillis()
- start), LogText.State.GOOD));
} catch (UnknownHostException e) {
publishProgress(new LogText("ERROR: " + e.getMessage()));
publishProgress(new LogText("ERROR: " + e.getMessage(), LogText.State.BAD));
}
publishProgress(LogText.LINEBREAK);
}
@ -221,9 +241,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
try {
final long start = SystemClock.uptimeMillis();
test.execute(twitter);
publishProgress(new LogText(String.format("OK (%d ms)", SystemClock.uptimeMillis() - start)));
publishProgress(new LogText(String.format("OK (%d ms)", SystemClock.uptimeMillis()
- start), LogText.State.GOOD));
} catch (TwitterException e) {
publishProgress(new LogText("ERROR: " + e.getMessage()));
publishProgress(new LogText("ERROR: " + e.getMessage(), LogText.State.BAD));
}
publishProgress(LogText.LINEBREAK);
}
@ -238,7 +259,7 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
NetworkDiagnosticsFragment fragment = mFragmentRef.get();
if (fragment == null) return;
for (LogText value : values) {
fragment.appendMessage(value.message);
fragment.appendMessage(value);
}
}
@ -282,9 +303,10 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
static class LogText {
static final LogText LINEBREAK = new LogText("\n");
String message;
int state;
@State
int state = State.DEFAULT;
LogText(String message, int state) {
LogText(String message, @State int state) {
this.message = message;
this.state = state;
}
@ -292,6 +314,13 @@ public class NetworkDiagnosticsFragment extends BaseFragment {
LogText(String message) {
this.message = message;
}
@IntDef({State.DEFAULT, State.GOOD, State.BAD})
@interface State {
int DEFAULT = 0;
int GOOD = 1;
int BAD = 2;
}
}
}

View File

@ -153,6 +153,7 @@ public class AccountsDashboardFragment extends BaseSupportFragment implements Lo
};
private boolean mSwitchAccountAnimationPlaying;
@NonNull
public long[] getActivatedAccountIds() {
if (mAccountActionProvider != null) {
return mAccountActionProvider.getActivatedAccountIds();

View File

@ -233,9 +233,11 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
@Override
protected long[][] doInBackground(final Object... params) {
final Context context = getContext();
if (context == null) return null;
final long[][] result = new long[2][];
result[0] = getAccountIds();
result[1] = DataStoreUtils.getNewestMessageIds(getActivity(),
result[1] = DataStoreUtils.getNewestMessageIds(context,
DirectMessages.Inbox.CONTENT_URI, result[0]);
return result;
}
@ -243,7 +245,7 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
@Override
protected void onPostExecute(final long[][] result) {
final AsyncTwitterWrapper twitter = mTwitterWrapper;
if (twitter == null) return;
if (twitter == null || result == null) return;
twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
twitter.getSentDirectMessagesAsync(result[0], null, null);
}
@ -326,6 +328,7 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
}
@NonNull
protected long[] getAccountIds() {
final Bundle args = getArguments();
if (args != null && args.getLong(EXTRA_ACCOUNT_ID) > 0) {
@ -368,13 +371,13 @@ public class DirectMessagesFragment extends AbsContentListRecyclerViewFragment<M
@Override
protected long[][] doInBackground(final Object... params) {
final FragmentActivity activity = getActivity();
if (activity == null) return null;
final Context context = getContext();
if (context == null) return null;
final long[][] result = new long[3][];
result[0] = getAccountIds();
result[1] = DataStoreUtils.getOldestMessageIds(activity,
result[1] = DataStoreUtils.getOldestMessageIds(context,
DirectMessages.Inbox.CONTENT_URI, result[0]);
result[2] = DataStoreUtils.getOldestMessageIds(activity,
result[2] = DataStoreUtils.getOldestMessageIds(context,
DirectMessages.Outbox.CONTENT_URI, result[0]);
return result;
}

View File

@ -0,0 +1,27 @@
package org.mariotaku.twidere.model;
/**
* Created by mariotaku on 16/2/11.
*/
public class RefreshTaskParam {
private final long[] accountIds, maxIds, sinceIds;
public long[] getAccountIds() {
return accountIds;
}
public long[] getMaxIds() {
return maxIds;
}
public long[] getSinceIds() {
return sinceIds;
}
public RefreshTaskParam(long[] accountIds, long[] maxIds, long[] sinceIds) {
this.accountIds = accountIds;
this.maxIds = maxIds;
this.sinceIds = sinceIds;
}
}

View File

@ -22,8 +22,8 @@ package org.mariotaku.twidere.task;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.os.AsyncTask;
import com.desmond.asyncmanager.TaskRunnable;
import com.twitter.Extractor;
import org.mariotaku.twidere.Constants;
@ -40,7 +40,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CacheUsersStatusesTask extends AsyncTask<TwitterListResponse<Status>, Object, Object> implements Constants {
public class CacheUsersStatusesTask extends TaskRunnable<TwitterListResponse<Status>, Object, Object> implements Constants {
private final Context context;
@ -48,49 +48,44 @@ public class CacheUsersStatusesTask extends AsyncTask<TwitterListResponse<Status
this.context = context;
}
@SafeVarargs
@Override
protected final Object doInBackground(final TwitterListResponse<org.mariotaku.twidere.api.twitter.model.Status>... args) {
if (args == null || args.length == 0) return null;
public final Object doLongOperation(final TwitterListResponse<Status> params) {
final ContentResolver resolver = context.getContentResolver();
final Extractor extractor = new Extractor();
for (final TwitterListResponse<org.mariotaku.twidere.api.twitter.model.Status> response : args) {
if (response == null || !response.hasData()) {
continue;
}
final List<org.mariotaku.twidere.api.twitter.model.Status> list = response.getData();
for (int bulkIdx = 0, totalSize = list.size(); bulkIdx < totalSize; bulkIdx += 100) {
for (int idx = bulkIdx, end = Math.min(totalSize, bulkIdx + ContentResolverUtils.MAX_BULK_COUNT); idx < end; idx++) {
final org.mariotaku.twidere.api.twitter.model.Status status = list.get(idx);
if (params == null || !params.hasData()) {
return null;
}
final List<Status> list = params.getData();
for (int bulkIdx = 0, totalSize = list.size(); bulkIdx < totalSize; bulkIdx += 100) {
for (int idx = bulkIdx, end = Math.min(totalSize, bulkIdx + ContentResolverUtils.MAX_BULK_COUNT); idx < end; idx++) {
final Status status = list.get(idx);
final Set<ContentValues> usersValues = new HashSet<>();
final Set<ContentValues> statusesValues = new HashSet<>();
final Set<ContentValues> hashTagValues = new HashSet<>();
final Set<ContentValues> usersValues = new HashSet<>();
final Set<ContentValues> statusesValues = new HashSet<>();
final Set<ContentValues> hashTagValues = new HashSet<>();
statusesValues.add(ContentValuesCreator.createStatus(status, response.accountId));
final String text = TwitterContentUtils.unescapeTwitterStatusText(status.getText());
for (final String hashtag : extractor.extractHashtags(text)) {
final ContentValues values = new ContentValues();
values.put(CachedHashtags.NAME, hashtag);
hashTagValues.add(values);
}
final ContentValues cachedUser = ContentValuesCreator.createCachedUser(status.getUser());
cachedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
usersValues.add(cachedUser);
if (status.isRetweet()) {
final ContentValues cachedRetweetedUser = ContentValuesCreator.createCachedUser(status.getRetweetedStatus().getUser());
cachedRetweetedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
usersValues.add(cachedRetweetedUser);
}
ContentResolverUtils.bulkInsert(resolver, CachedStatuses.CONTENT_URI, statusesValues);
ContentResolverUtils.bulkInsert(resolver, CachedHashtags.CONTENT_URI, hashTagValues);
ContentResolverUtils.bulkInsert(resolver, CachedUsers.CONTENT_URI, usersValues);
statusesValues.add(ContentValuesCreator.createStatus(status, params.accountId));
final String text = TwitterContentUtils.unescapeTwitterStatusText(status.getText());
for (final String hashtag : extractor.extractHashtags(text)) {
final ContentValues values = new ContentValues();
values.put(CachedHashtags.NAME, hashtag);
hashTagValues.add(values);
}
final ContentValues cachedUser = ContentValuesCreator.createCachedUser(status.getUser());
cachedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
usersValues.add(cachedUser);
if (status.isRetweet()) {
final ContentValues cachedRetweetedUser = ContentValuesCreator.createCachedUser(status.getRetweetedStatus().getUser());
cachedRetweetedUser.put(CachedUsers.LAST_SEEN, System.currentTimeMillis());
usersValues.add(cachedRetweetedUser);
}
ContentResolverUtils.bulkInsert(resolver, CachedStatuses.CONTENT_URI, statusesValues);
ContentResolverUtils.bulkInsert(resolver, CachedHashtags.CONTENT_URI, hashTagValues);
ContentResolverUtils.bulkInsert(resolver, CachedUsers.CONTENT_URI, usersValues);
}
}
return null;
}

View File

@ -0,0 +1,62 @@
package org.mariotaku.twidere.task;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.annotation.ReadPositionTag;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Activity;
import org.mariotaku.twidere.api.twitter.model.CursorTimestampResponse;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
import org.mariotaku.twidere.util.ErrorInfoStore;
import org.mariotaku.twidere.util.Utils;
/**
* Created by mariotaku on 16/2/11.
*/
public class GetActivitiesAboutMeTask extends GetActivitiesTask {
public GetActivitiesAboutMeTask(Context context) {
super(context);
}
@NonNull
@Override
protected String getErrorInfoKey() {
return ErrorInfoStore.KEY_INTERACTIONS;
}
@Override
protected void saveReadPosition(long accountId, Twitter twitter) {
try {
CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true);
final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, accountId);
readStateManager.setPosition(tag, response.getCursor(), false);
} catch (TwitterException e) {
// Ignore
}
}
@Override
protected ResponseList<Activity> getActivities(@NonNull final Twitter twitter, final long accountId, final Paging paging) throws TwitterException {
if (Utils.shouldUsePrivateAPIs(context, accountId)) {
return twitter.getActivitiesAboutMe(paging);
}
final ResponseList<Activity> activities = new ResponseList<>();
for (Status status : twitter.getMentionsTimeline(paging)) {
activities.add(Activity.fromMention(accountId, status));
}
return activities;
}
@Override
protected Uri getContentUri() {
return TwidereDataStore.Activities.AboutMe.CONTENT_URI;
}
}

View File

@ -0,0 +1,45 @@
package org.mariotaku.twidere.task;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Activity;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
import org.mariotaku.twidere.util.ErrorInfoStore;
/**
* Created by mariotaku on 16/2/11.
*/
public class GetActivitiesByFriendsTask extends GetActivitiesTask {
public GetActivitiesByFriendsTask(Context context) {
super(context);
}
@NonNull
@Override
protected String getErrorInfoKey() {
return ErrorInfoStore.KEY_ACTIVITIES_BY_FRIENDS;
}
@Override
protected void saveReadPosition(long accountId, Twitter twitter) {
}
@Override
protected ResponseList<Activity> getActivities(@NonNull Twitter twitter, long accountId, Paging paging) throws TwitterException {
return twitter.getActivitiesByFriends(paging);
}
@Override
protected Uri getContentUri() {
return TwidereDataStore.Activities.ByFriends.CONTENT_URI;
}
}

View File

@ -0,0 +1,52 @@
package org.mariotaku.twidere.task;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.task.twitter.GetStatusesTask;
import org.mariotaku.twidere.util.ErrorInfoStore;
import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 16/2/11.
*/
public class GetHomeTimelineTask extends GetStatusesTask {
public GetHomeTimelineTask(Context context) {
super(context);
}
@NonNull
@Override
public ResponseList<Status> getStatuses(final Twitter twitter, final Paging paging)
throws TwitterException {
return twitter.getHomeTimeline(paging);
}
@NonNull
@Override
protected Uri getContentUri() {
return TwidereDataStore.Statuses.CONTENT_URI;
}
@TimelineType
@Override
protected String getTimelineType() {
return TimelineType.HOME;
}
@NonNull
@Override
protected String getErrorInfoKey() {
return ErrorInfoStore.KEY_HOME_TIMELINE;
}
}

View File

@ -5,62 +5,74 @@ import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.util.Log;
import com.desmond.asyncmanager.TaskRunnable;
import com.squareup.otto.Bus;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Activity;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.model.ParcelableActivity;
import org.mariotaku.twidere.model.RefreshTaskParam;
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ContentValuesCreator;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.ErrorInfoStore;
import org.mariotaku.twidere.util.ReadStateManager;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.TwitterAPIFactory;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
import org.mariotaku.twidere.util.message.GetActivitiesTaskEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
/**
* Created by mariotaku on 16/1/4.
*/
public abstract class GetActivitiesTask extends ManagedAsyncTask<Object, Object, Object> {
public abstract class GetActivitiesTask extends TaskRunnable<RefreshTaskParam, Object, Object> implements Constants {
protected final AsyncTwitterWrapper twitterWrapper;
protected final long[] accountIds;
protected final long[] maxIds;
protected final long[] sinceIds;
protected final Context context;
@Inject
protected SharedPreferencesWrapper preferences;
@Inject
protected Bus bus;
@Inject
protected ErrorInfoStore errorInfoStore;
@Inject
protected ReadStateManager readStateManager;
public GetActivitiesTask(AsyncTwitterWrapper twitterWrapper, String tag, long[] accountIds, long[] maxIds, long[] sinceIds) {
super(twitterWrapper.getContext(), tag);
this.twitterWrapper = twitterWrapper;
this.accountIds = accountIds;
this.maxIds = maxIds;
this.sinceIds = sinceIds;
public GetActivitiesTask(Context context) {
this.context = context;
GeneralComponentHelper.build(context).inject(this);
}
@Override
protected Object doInBackground(Object... params) {
final Context context = twitterWrapper.getContext();
public Object doLongOperation(RefreshTaskParam param) {
final long[] accountIds = param.getAccountIds(), maxIds = param.getMaxIds(), sinceIds = param.getSinceIds();
final ContentResolver cr = context.getContentResolver();
final int loadItemLimit = twitterWrapper.getPreferences().getInt(KEY_LOAD_ITEM_LIMIT);
final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT);
boolean saveReadPosition = false;
for (int i = 0; i < accountIds.length; i++) {
final long accountId = accountIds[i];
final boolean noItemsBefore = DataStoreUtils.getActivitiesCount(context,
getContentUri(), accountId) <= 0;
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId,
true);
final boolean noItemsBefore = DataStoreUtils.getActivitiesCount(context, getContentUri(),
accountId) <= 0;
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true);
if (twitter == null) continue;
final Paging paging = new Paging();
paging.count(loadItemLimit);
if (maxIds != null && maxIds[i] > 0) {
@ -73,10 +85,9 @@ public abstract class GetActivitiesTask extends ManagedAsyncTask<Object, Object,
saveReadPosition = true;
}
}
final ErrorInfoStore errorInfoStore = twitterWrapper.getErrorInfoStore();
// We should delete old activities has intersection with new items
try {
final ResponseList<Activity> activities = getActivities(accountId, twitter, paging);
final ResponseList<Activity> activities = getActivities(twitter, accountId, paging);
storeActivities(cr, loadItemLimit, accountId, noItemsBefore, activities);
// if (saveReadPosition && TwitterAPIFactory.isOfficialTwitterInstance(context, twitter)) {
if (saveReadPosition) {
@ -141,19 +152,26 @@ public abstract class GetActivitiesTask extends ManagedAsyncTask<Object, Object,
protected abstract void saveReadPosition(long accountId, Twitter twitter);
protected abstract ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException;
protected ResponseList<Activity> getActivities(@NonNull final Twitter twitter, final long accountId, final Paging paging) throws TwitterException {
if (Utils.shouldUsePrivateAPIs(context, accountId)) {
return twitter.getActivitiesAboutMe(paging);
}
final ResponseList<Activity> activities = new ResponseList<>();
for (Status status : twitter.getMentionsTimeline(paging)) {
activities.add(Activity.fromMention(accountId, status));
}
return activities;
}
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
public void callback(Object result) {
bus.post(new GetActivitiesTaskEvent(getContentUri(), false, null));
}
protected abstract Uri getContentUri();
@Override
protected void onPreExecute() {
super.onPreExecute();
@UiThread
public void notifyStart() {
bus.post(new GetActivitiesTaskEvent(getContentUri(), true, null));
}
}

View File

@ -6,23 +6,28 @@ import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import android.util.Log;
import com.desmond.asyncmanager.AsyncManager;
import com.desmond.asyncmanager.TaskRunnable;
import com.squareup.otto.Bus;
import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.sqliteqb.library.Columns;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.sqliteqb.library.RawItemArray;
import org.mariotaku.sqliteqb.library.SQLFunctions;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.api.twitter.model.Status;
import org.mariotaku.twidere.model.RefreshTaskParam;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.task.CacheUsersStatusesTask;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.util.AsyncTaskUtils;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ContentValuesCreator;
import org.mariotaku.twidere.util.DataStoreUtils;
@ -34,11 +39,14 @@ import org.mariotaku.twidere.util.TwitterWrapper;
import org.mariotaku.twidere.util.UriUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
import org.mariotaku.twidere.util.message.GetStatusesTaskEvent;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import edu.tsinghua.hotmobi.HotMobiLogger;
import edu.tsinghua.hotmobi.model.RefreshEvent;
import edu.tsinghua.hotmobi.model.TimelineType;
@ -46,42 +54,35 @@ import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 16/1/2.
*/
public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWrapper.TwitterListResponse<Status>, List<TwitterWrapper.StatusListResponse>> {
public abstract class GetStatusesTask extends TaskRunnable<RefreshTaskParam,
List<TwitterWrapper.StatusListResponse>, Object> implements Constants {
private final long[] accountIds, maxIds, sinceIds;
private final AsyncTwitterWrapper twitterWrapper;
protected final Context context;
@Inject
protected SharedPreferencesWrapper preferences;
@Inject
protected Bus bus;
@Inject
protected ErrorInfoStore errorInfoStore;
public GetStatusesTask(AsyncTwitterWrapper twitterWrapper, final long[] accountIds,
final long[] maxIds, final long[] sinceIds, final String tag) {
super(twitterWrapper.getContext(), tag);
this.twitterWrapper = twitterWrapper;
this.accountIds = accountIds;
this.maxIds = maxIds;
this.sinceIds = sinceIds;
public GetStatusesTask(Context context) {
this.context = context;
GeneralComponentHelper.build(context).inject(this);
}
@NonNull
public abstract ResponseList<org.mariotaku.twidere.api.twitter.model.Status> getStatuses(Twitter twitter, Paging paging)
public abstract ResponseList<Status> getStatuses(Twitter twitter, Paging paging)
throws TwitterException;
@NonNull
protected abstract Uri getDatabaseUri();
protected abstract Uri getContentUri();
final boolean isMaxIdsValid() {
return maxIds != null && maxIds.length == accountIds.length;
}
final boolean isSinceIdsValid() {
return sinceIds != null && sinceIds.length == accountIds.length;
}
private void storeStatus(long accountId, List<org.mariotaku.twidere.api.twitter.model.Status> statuses,
long sinceId, long maxId, boolean notify, int loadItemLimit) {
private void storeStatus(long accountId, List<Status> statuses,
long sinceId, long maxId, boolean notify) {
if (statuses == null || statuses.isEmpty() || accountId <= 0) {
return;
}
final Uri uri = getDatabaseUri();
final Context context = twitterWrapper.getContext();
final Uri uri = getContentUri();
final ContentResolver resolver = context.getContentResolver();
final boolean noItemsBefore = DataStoreUtils.getStatusCount(context, uri, accountId) <= 0;
final ContentValues[] values = new ContentValues[statuses.size()];
@ -90,7 +91,7 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
int minIdx = -1;
boolean hasIntersection = false;
for (int i = 0, j = statuses.size(); i < j; i++) {
final org.mariotaku.twidere.api.twitter.model.Status status = statuses.get(i);
final Status status = statuses.get(i);
values[i] = ContentValuesCreator.createStatus(status, accountId);
values[i].put(Statuses.INSERTED_DATE, System.currentTimeMillis());
final long id = status.getId();
@ -143,33 +144,23 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
@TimelineType
protected abstract String getTimelineType();
@SafeVarargs
@Override
protected final void onProgressUpdate(TwitterWrapper.TwitterListResponse<org.mariotaku.twidere.api.twitter.model.Status>... values) {
AsyncTaskUtils.executeTask(new CacheUsersStatusesTask(twitterWrapper.getContext()), values);
public void callback(List<TwitterWrapper.StatusListResponse> result) {
bus.post(new GetStatusesTaskEvent(getContentUri(), false, AsyncTwitterWrapper.getException(result)));
}
@Override
protected void onPostExecute(List<TwitterWrapper.StatusListResponse> result) {
super.onPostExecute(result);
bus.post(new GetStatusesTaskEvent(getDatabaseUri(), false, AsyncTwitterWrapper.getException(result)));
@UiThread
public void notifyStart() {
bus.post(new GetStatusesTaskEvent(getContentUri(), true, null));
}
@Override
protected void onPreExecute() {
super.onPreExecute();
bus.post(new GetStatusesTaskEvent(getDatabaseUri(), true, null));
}
@Override
protected List<TwitterWrapper.StatusListResponse> doInBackground(final Object... params) {
public List<TwitterWrapper.StatusListResponse> doLongOperation(final RefreshTaskParam param) {
final long[] accountIds = param.getAccountIds(), maxIds = param.getMaxIds(), sinceIds = param.getSinceIds();
final List<TwitterWrapper.StatusListResponse> result = new ArrayList<>();
if (accountIds == null) return result;
int idx = 0;
final SharedPreferencesWrapper preferences = twitterWrapper.getPreferences();
final Context context = twitterWrapper.getContext();
final ErrorInfoStore errorInfoStore = twitterWrapper.getErrorInfoStore();
final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
for (final long accountId : accountIds) {
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true);
@ -193,10 +184,13 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
} else {
sinceId = -1;
}
final List<org.mariotaku.twidere.api.twitter.model.Status> statuses = getStatuses(twitter, paging);
final List<Status> statuses = getStatuses(twitter, paging);
TwitterContentUtils.getStatusesWithQuoteData(twitter, statuses);
storeStatus(accountId, statuses, sinceId, maxId, true, loadItemLimit);
publishProgress(new TwitterWrapper.StatusListResponse(accountId, statuses));
storeStatus(accountId, statuses, sinceId, maxId, true);
// TODO cache related data and preload
final CacheUsersStatusesTask cacheTask = new CacheUsersStatusesTask(context);
cacheTask.setParams(new TwitterWrapper.StatusListResponse(accountId, statuses));
AsyncManager.runBackgroundTask(cacheTask);
errorInfoStore.remove(getErrorInfoKey(), accountId);
} catch (final TwitterException e) {
if (BuildConfig.DEBUG) {
@ -216,4 +210,5 @@ public abstract class GetStatusesTask extends ManagedAsyncTask<Object, TwitterWr
@NonNull
protected abstract String getErrorInfoKey();
}

View File

@ -40,12 +40,9 @@ import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.annotation.ReadPositionTag;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.http.HttpResponseCode;
import org.mariotaku.twidere.api.twitter.model.Activity;
import org.mariotaku.twidere.api.twitter.model.CursorTimestampResponse;
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
import org.mariotaku.twidere.api.twitter.model.ErrorInfo;
import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate;
@ -65,6 +62,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.RefreshTaskParam;
import org.mariotaku.twidere.model.Response;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.provider.TwidereDataStore;
@ -79,9 +77,11 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.service.BackgroundOperationService;
import org.mariotaku.twidere.task.GetActivitiesAboutMeTask;
import org.mariotaku.twidere.task.GetActivitiesByFriendsTask;
import org.mariotaku.twidere.task.GetHomeTimelineTask;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
import org.mariotaku.twidere.task.twitter.GetStatusesTask;
import org.mariotaku.twidere.util.collection.LongSparseMap;
import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
@ -282,9 +282,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return mContext;
}
public boolean getHomeTimelineAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) {
final GetHomeTimelineTask task = new GetHomeTimelineTask(this, accountIds, max_ids, since_ids);
mAsyncTaskManager.add(task, true);
public boolean getHomeTimelineAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
final GetHomeTimelineTask task = new GetHomeTimelineTask(getContext());
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
task.notifyStart();
AsyncManager.runBackgroundTask(task);
return true;
}
@ -525,69 +527,18 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}.setResultHandler(bus));
}
public void getActivitiesAboutMeAsync(long[] accountIds, long[] maxIds, long[] sinceIds) {
mAsyncTaskManager.add(new GetActivitiesTask(this, TASK_TAG_GET_MENTIONS, accountIds, maxIds, sinceIds) {
@NonNull
@Override
protected String getErrorInfoKey() {
return ErrorInfoStore.KEY_INTERACTIONS;
}
@Override
protected void saveReadPosition(long accountId, Twitter twitter) {
try {
CursorTimestampResponse response = twitter.getActivitiesAboutMeUnread(true);
final String tag = Utils.getReadPositionTagWithAccounts(ReadPositionTag.ACTIVITIES_ABOUT_ME, accountIds);
mReadStateManager.setPosition(tag, response.getCursor(), false);
} catch (TwitterException e) {
// Ignore
}
}
@Override
protected ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException {
if (Utils.shouldUsePrivateAPIs(getContext(), accountId)) {
return twitter.getActivitiesAboutMe(paging);
}
final ResponseList<Activity> activities = new ResponseList<>();
for (org.mariotaku.twidere.api.twitter.model.Status status : twitter.getMentionsTimeline(paging)) {
activities.add(Activity.fromMention(accountId, status));
}
return activities;
}
@Override
protected Uri getContentUri() {
return Activities.AboutMe.CONTENT_URI;
}
}, true);
public void getActivitiesAboutMeAsync(final long[] accountIds, long[] maxIds, long[] sinceIds) {
final GetActivitiesTask task = new GetActivitiesAboutMeTask(getContext());
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
task.notifyStart();
AsyncManager.runBackgroundTask(task);
}
public void getActivitiesByFriendsAsync(long[] accountIds, long[] maxIds, long[] sinceIds) {
mAsyncTaskManager.add(new GetActivitiesTask(this, "get_activities_by_friends", accountIds, maxIds, sinceIds) {
@NonNull
@Override
protected String getErrorInfoKey() {
return ErrorInfoStore.KEY_ACTIVITIES_BY_FRIENDS;
}
@Override
protected void saveReadPosition(long accountId, Twitter twitter) {
}
@Override
protected ResponseList<Activity> getActivities(long accountId, Twitter twitter, Paging paging) throws TwitterException {
return twitter.getActivitiesByFriends(paging);
}
@Override
protected Uri getContentUri() {
return Activities.ByFriends.CONTENT_URI;
}
}, true);
final GetActivitiesTask task = new GetActivitiesByFriendsTask(getContext());
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
task.notifyStart();
AsyncManager.runBackgroundTask(task);
}
public void setActivitiesAboutMeUnreadAsync(final long[] accountIds, final long cursor) {
@ -2045,55 +1996,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
static class GetHomeTimelineTask extends GetStatusesTask {
private AsyncTwitterWrapper twitterWrapper;
public GetHomeTimelineTask(AsyncTwitterWrapper asyncTwitterWrapper, final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
super(asyncTwitterWrapper, accountIds, maxIds, sinceIds, TASK_TAG_GET_HOME_TIMELINE);
this.twitterWrapper = asyncTwitterWrapper;
}
@NonNull
@Override
public ResponseList<org.mariotaku.twidere.api.twitter.model.Status> getStatuses(final Twitter twitter, final Paging paging)
throws TwitterException {
return twitter.getHomeTimeline(paging);
}
@NonNull
@Override
protected Uri getDatabaseUri() {
return Statuses.CONTENT_URI;
}
@TimelineType
@Override
protected String getTimelineType() {
return TimelineType.HOME;
}
@Override
protected void onPostExecute(final List<StatusListResponse> result) {
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
final Intent intent = new Intent(BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING);
twitterWrapper.getContext().sendBroadcast(intent);
super.onPreExecute();
}
@NonNull
@Override
protected String getErrorInfoKey() {
return ErrorInfoStore.KEY_HOME_TIMELINE;
}
}
class GetLocalTrendsTask extends GetTrendsTask {
private final int woeid;
@ -2511,4 +2413,5 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
}
}

View File

@ -182,13 +182,15 @@ public class DataStoreUtils implements Constants {
}
@NonNull
public static long[] getNewestMessageIds(final Context context, final Uri uri, final long[] accountIds) {
public static long[] getNewestMessageIds(@NonNull final Context context, @NonNull final Uri uri,
@NonNull final long[] accountIds) {
return getLongFieldArray(context, uri, accountIds, DirectMessages.ACCOUNT_ID, DirectMessages.MESSAGE_ID,
new OrderBy(SQLFunctions.MAX(DirectMessages.MESSAGE_TIMESTAMP)));
}
@NonNull
public static long[] getNewestStatusIds(final Context context, final Uri uri, final long[] accountIds) {
public static long[] getNewestStatusIds(@NonNull final Context context, @NonNull final Uri uri,
@NonNull final long[] accountIds) {
return getLongFieldArray(context, uri, accountIds, Statuses.ACCOUNT_ID, Statuses.STATUS_ID,
new OrderBy(SQLFunctions.MAX(Statuses.STATUS_TIMESTAMP)));
}
@ -353,6 +355,7 @@ public class DataStoreUtils implements Constants {
}
}
@NonNull
public static long[] getActivatedAccountIds(final Context context) {
if (context == null) return new long[0];
final Cursor cur = ContentResolverUtils.query(context.getContentResolver(), Accounts.CONTENT_URI,

View File

@ -31,20 +31,15 @@ import static android.text.TextUtils.isEmpty;
*/
public class HttpClientFactory implements Constants {
public static RestHttpClient getDefaultHttpClient(final Context context, SharedPreferences prefs, Dns dns) {
if (context == null) return null;
return createHttpClient(context, prefs, dns);
}
public static RestHttpClient createHttpClient(final Context context, final SharedPreferences prefs, Dns dns) {
public static RestHttpClient createRestHttpClient(final Context context, final SharedPreferences prefs, Dns dns) {
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
initDefaultHttpClient(context, prefs, builder, dns);
initOkHttpClient(context, prefs, builder, dns);
return new OkHttpRestClient(builder.build());
}
public static void initDefaultHttpClient(Context context, SharedPreferences prefs, OkHttpClient.Builder builder, Dns dns) {
public static void initOkHttpClient(Context context, SharedPreferences prefs, OkHttpClient.Builder builder, Dns dns) {
updateHttpClientConfiguration(context, prefs, dns, builder);
DebugModeUtils.initForHttpClient(builder);
DebugModeUtils.initForOkHttpClient(builder);
}
@SuppressLint("SSLCertificateSocketFactoryGetInsecure")
@ -54,7 +49,7 @@ public class HttpClientFactory implements Constants {
final long connectionTimeout = prefs.getInt(KEY_CONNECTION_TIMEOUT, 10);
final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false);
builder.connectTimeout(connectionTimeout, TimeUnit.SECONDS);
builder.connectionPool(new ConnectionPool(0, 1, TimeUnit.MINUTES));
builder.connectionPool(new ConnectionPool(5, 30, TimeUnit.SECONDS));
if (enableProxy) {
final String proxyType = prefs.getString(KEY_PROXY_TYPE, null);
final String proxyHost = prefs.getString(KEY_PROXY_HOST, null);

View File

@ -135,7 +135,7 @@ public class ApplicationModule implements Constants {
@Provides
@Singleton
public RestHttpClient restHttpClient(SharedPreferencesWrapper prefs, Dns dns) {
return HttpClientFactory.getDefaultHttpClient(application, prefs, dns);
return HttpClientFactory.createRestHttpClient(application, prefs, dns);
}
@Provides

View File

@ -51,6 +51,8 @@ import org.mariotaku.twidere.provider.TwidereDataProvider;
import org.mariotaku.twidere.service.BackgroundOperationService;
import org.mariotaku.twidere.service.RefreshService;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
import org.mariotaku.twidere.task.twitter.GetStatusesTask;
import org.mariotaku.twidere.text.util.EmojiEditableFactory;
import org.mariotaku.twidere.text.util.EmojiSpannableFactory;
import org.mariotaku.twidere.util.MultiSelectEventHandler;
@ -135,4 +137,8 @@ public interface GeneralComponent {
void inject(TwitterAPIStatusesLoader loader);
void inject(MediaViewerActivity activity);
void inject(GetStatusesTask task);
void inject(GetActivitiesTask task);
}

View File

@ -29,7 +29,7 @@ import okhttp3.OkHttpClient;
*/
public class DebugModeUtils {
public static void initForHttpClient(final OkHttpClient.Builder builder) {
public static void initForOkHttpClient(final OkHttpClient.Builder builder) {
// No-op
}