1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-17 04:00:48 +01:00

moved some tasks

This commit is contained in:
Mariotaku Lee 2016-02-14 13:53:10 +08:00
parent 36a052e518
commit bb7cdf1b53
14 changed files with 370 additions and 250 deletions

View File

@ -98,10 +98,8 @@ public interface IntentConstants {
String BROADCAST_MULTI_BLOCKSTATE_CHANGED = INTENT_PACKAGE_PREFIX + "MULTI_BLOCKSTATE_CHANGED";
String BROADCAST_MULTI_MUTESTATE_CHANGED = INTENT_PACKAGE_PREFIX + "MULTI_MUTESTATE_CHANGED";
String BROADCAST_HOME_ACTIVITY_ONCREATE = INTENT_PACKAGE_PREFIX + "HOME_ACTIVITY_ONCREATE";
String BROADCAST_HOME_ACTIVITY_ONSTART = INTENT_PACKAGE_PREFIX + "HOME_ACTIVITY_ONSTART";
String BROADCAST_HOME_ACTIVITY_ONRESUME = INTENT_PACKAGE_PREFIX + "HOME_ACTIVITY_ONRESUME";
String BROADCAST_HOME_ACTIVITY_ONPAUSE = INTENT_PACKAGE_PREFIX + "HOME_ACTIVITY_ONPAUSE";
String BROADCAST_HOME_ACTIVITY_ONSTOP = INTENT_PACKAGE_PREFIX + "HOME_ACTIVITY_ONSTOP";
String BROADCAST_HOME_ACTIVITY_ONDESTROY = INTENT_PACKAGE_PREFIX + "HOME_ACTIVITY_ONDESTROY";
String BROADCAST_DATABASE_READY = INTENT_PACKAGE_PREFIX + "DATABASE_READY";

View File

@ -424,7 +424,6 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
protected void onStart() {
super.onStart();
mMultiSelectHandler.dispatchOnStart();
sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONSTART));
final ContentResolver resolver = getContentResolver();
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mAccountChangeObserver);
mBus.register(this);
@ -462,7 +461,6 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
final ContentResolver resolver = getContentResolver();
resolver.unregisterContentObserver(mAccountChangeObserver);
mPreferences.edit().putInt(KEY_SAVED_TAB_POSITION, mViewPager.getCurrentItem()).apply();
sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONSTOP));
super.onStop();
}

View File

@ -39,8 +39,6 @@ import static android.text.TextUtils.isEmpty;
public class RequestPermissionsActivity extends BaseSupportDialogActivity implements OnClickListener {
private PermissionsManager mPermissionsManager;
private ImageView mIconView;
private TextView mNameView, mDescriptionView, mMessageView;
private Button mAcceptButton, mDenyButton;
@ -80,7 +78,6 @@ public class RequestPermissionsActivity extends BaseSupportDialogActivity implem
protected void onCreate(final Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mPermissionsManager = new PermissionsManager(this);
setContentView(R.layout.activity_request_permissions);
mAcceptButton.setOnClickListener(this);
mDenyButton.setOnClickListener(this);

View File

@ -41,6 +41,7 @@ import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.PermissionsManager;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
@ -70,6 +71,9 @@ public abstract class ThemedFragmentActivity extends FragmentActivity implements
protected SharedPreferencesWrapper mPreferences;
@Inject
protected Bus mBus;
@Inject
protected PermissionsManager mPermissionsManager;
// Data fields
private int mCurrentThemeResource, mCurrentThemeColor, mCurrentThemeBackgroundAlpha;

View File

@ -0,0 +1,36 @@
package org.mariotaku.twidere.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* Created by mariotaku on 16/2/11.
*/
public class BaseRefreshTaskParam implements RefreshTaskParam {
private final long[] accountIds, maxIds, sinceIds;
@NonNull
@Override
public long[] getAccountIds() {
return accountIds;
}
@Nullable
@Override
public long[] getMaxIds() {
return maxIds;
}
@Nullable
@Override
public long[] getSinceIds() {
return sinceIds;
}
public BaseRefreshTaskParam(long[] accountIds, long[] maxIds, long[] sinceIds) {
this.accountIds = accountIds;
this.maxIds = maxIds;
this.sinceIds = sinceIds;
}
}

View File

@ -1,27 +1,18 @@
package org.mariotaku.twidere.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* Created by mariotaku on 16/2/11.
* Created by mariotaku on 16/2/14.
*/
public class RefreshTaskParam {
public interface RefreshTaskParam {
@NonNull
long[] getAccountIds();
private final long[] accountIds, maxIds, sinceIds;
@Nullable
long[] getMaxIds();
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;
}
@Nullable
long[] getSinceIds();
}

View File

@ -0,0 +1,21 @@
package org.mariotaku.twidere.model;
import android.support.annotation.Nullable;
/**
* Created by mariotaku on 16/2/14.
*/
public abstract class SimpleRefreshTaskParam implements RefreshTaskParam {
@Nullable
@Override
public long[] getMaxIds() {
return null;
}
@Nullable
@Override
public long[] getSinceIds() {
return null;
}
}

View File

@ -21,13 +21,11 @@ package org.mariotaku.twidere.provider;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
@ -110,6 +108,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Suggestions;
import org.mariotaku.twidere.provider.TwidereDataStore.UnreadCounts;
import org.mariotaku.twidere.receiver.NotificationReceiver;
import org.mariotaku.twidere.service.BackgroundOperationService;
import org.mariotaku.twidere.util.ActivityTracker;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.ImagePreloader;
@ -171,30 +170,19 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
UserColorNameManager mUserColorNameManager;
@Inject
BidiFormatter mBidiFormatter;
@Inject
ActivityTracker mActivityTracker;
@Inject
PermissionsManager mPermissionsManager;
private Handler mHandler;
private ContentResolver mContentResolver;
private SQLiteDatabaseWrapper mDatabaseWrapper;
private PermissionsManager mPermissionsManager;
private ImagePreloader mImagePreloader;
private Executor mBackgroundExecutor;
private boolean mHomeActivityInBackground;
private boolean mNameFirst;
private boolean mUseStarForLikes;
private final BroadcastReceiver mHomeActivityStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (BROADCAST_HOME_ACTIVITY_ONSTART.equals(action)) {
mHomeActivityInBackground = false;
} else if (BROADCAST_HOME_ACTIVITY_ONSTOP.equals(action)) {
mHomeActivityInBackground = true;
}
}
};
private static PendingIntent getMarkReadDeleteIntent(Context context, @NotificationType String type,
long accountId, long position, boolean extraUserFollowing) {
return getMarkReadDeleteIntent(context, type, accountId, position, -1, -1, extraUserFollowing);
@ -571,12 +559,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
mPreferences.registerOnSharedPreferenceChangeListener(this);
mBackgroundExecutor = Executors.newSingleThreadExecutor();
updatePreferences();
mPermissionsManager = new PermissionsManager(context);
mImagePreloader = new ImagePreloader(context, mMediaLoader);
final IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_HOME_ACTIVITY_ONSTART);
filter.addAction(BROADCAST_HOME_ACTIVITY_ONSTOP);
context.registerReceiver(mHomeActivityStateReceiver, filter);
// final GetWritableDatabaseTask task = new
// GetWritableDatabaseTask(context, helper, mDatabaseWrapper);
// task.executeTask();
@ -1144,7 +1127,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
private boolean isNotificationAudible() {
return mHomeActivityInBackground && !Utils.isNotificationsSilent(getContext());
return !mActivityTracker.isHomeActivityStarted() && !Utils.isNotificationsSilent(getContext());
}
private void notifyContentObserver(final Uri uri) {

View File

@ -28,12 +28,16 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import org.apache.commons.lang3.math.NumberUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.model.AccountPreferences;
import org.mariotaku.twidere.model.SimpleRefreshTaskParam;
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.receiver.PowerStateReceiver;
@ -83,38 +87,76 @@ public class RefreshService extends Service implements Constants {
} else if (BROADCAST_RESCHEDULE_TRENDS_REFRESHING.equals(action)) {
rescheduleTrendsRefreshing();
} else if (isAutoRefreshAllowed()) {
final long[] accountIds = DataStoreUtils.getAccountIds(context);
final AccountPreferences[] accountPrefs = AccountPreferences.getAccountPreferences(context, accountIds);
if (BROADCAST_REFRESH_HOME_TIMELINE.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new HomeRefreshableFilter());
final long[] sinceIds = DataStoreUtils.getNewestStatusIds(context, Statuses.CONTENT_URI, refreshIds);
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing home for %s", Arrays.toString(refreshIds)));
}
if (!isHomeTimelineRefreshing()) {
getHomeTimeline(refreshIds, null, sinceIds);
mTwitterWrapper.getHomeTimelineAsync(new SimpleRefreshTaskParam() {
private long[] accountIds;
@NonNull
@Override
public long[] getAccountIds() {
if (accountIds != null) return accountIds;
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountIds(context));
return accountIds = getRefreshableIds(prefs, HomeRefreshableFilter.INSTANCE);
}
@Nullable
@Override
public long[] getSinceIds() {
return DataStoreUtils.getNewestStatusIds(context,
Statuses.CONTENT_URI, getAccountIds());
}
});
}
} else if (BROADCAST_REFRESH_NOTIFICATIONS.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new MentionsRefreshableFilter());
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing notifications for %s", Arrays.toString(refreshIds)));
}
if (!isActivitiesAboutMeRefreshing()) {
getActivitiesAboutMe(refreshIds, null, null);
mTwitterWrapper.getActivitiesAboutMeAsync(new SimpleRefreshTaskParam() {
private long[] accountIds;
@NonNull
@Override
public long[] getAccountIds() {
if (accountIds != null) return accountIds;
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountIds(context));
return accountIds = getRefreshableIds(prefs, MentionsRefreshableFilter.INSTANCE);
}
@Nullable
@Override
public long[] getSinceIds() {
return DataStoreUtils.getNewestActivityMaxPositions(context,
Activities.AboutMe.CONTENT_URI, getAccountIds());
}
});
}
} else if (BROADCAST_REFRESH_DIRECT_MESSAGES.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new MessagesRefreshableFilter());
final long[] sinceIds = DataStoreUtils.getNewestMessageIds(context,
DirectMessages.Inbox.CONTENT_URI,
refreshIds);
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing messages for %s", Arrays.toString(refreshIds)));
}
if (!isReceivedDirectMessagesRefreshing()) {
getReceivedDirectMessages(refreshIds, null, sinceIds);
mTwitterWrapper.getReceivedDirectMessagesAsync(new SimpleRefreshTaskParam() {
private long[] accountIds;
@NonNull
@Override
public long[] getAccountIds() {
if (accountIds != null) return accountIds;
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountIds(context));
return accountIds = getRefreshableIds(prefs, MessagesRefreshableFilter.INSTANCE);
}
@Nullable
@Override
public long[] getSinceIds() {
return DataStoreUtils.getNewestMessageIds(context,
DirectMessages.Inbox.CONTENT_URI, getAccountIds());
}
});
}
} else if (BROADCAST_REFRESH_TRENDS.equals(action)) {
final long[] refreshIds = getRefreshableIds(accountPrefs, new TrendsRefreshableFilter());
final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context,
DataStoreUtils.getAccountIds(context));
final long[] refreshIds = getRefreshableIds(prefs, TrendsRefreshableFilter.INSTANCE);
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, String.format("Auto refreshing trends for %s", Arrays.toString(refreshIds)));
}
@ -234,25 +276,12 @@ public class RefreshService extends Service implements Constants {
return isNetworkAvailable(this) && (isBatteryOkay(this) || !shouldStopAutoRefreshOnBatteryLow(this));
}
private boolean getHomeTimeline(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
return mTwitterWrapper.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
}
private int getLocalTrends(final long[] accountIds) {
final long account_id = getDefaultAccountId(this);
final int woeid = mPreferences.getInt(KEY_LOCAL_TRENDS_WOEID, 1);
return mTwitterWrapper.getLocalTrendsAsync(account_id, woeid);
}
private boolean getActivitiesAboutMe(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
mTwitterWrapper.getActivitiesAboutMeAsync(accountIds, maxIds, sinceIds);
return true;
}
private int getReceivedDirectMessages(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
return mTwitterWrapper.getReceivedDirectMessagesAsync(accountIds, maxIds, sinceIds);
}
private long[] getRefreshableIds(final AccountPreferences[] prefs, final RefreshableAccountFilter filter) {
if (prefs == null) return null;
final long[] temp = new long[prefs.length];
@ -343,7 +372,13 @@ public class RefreshService extends Service implements Constants {
mAlarmManager.cancel(mPendingRefreshTrendsIntent);
}
private interface RefreshableAccountFilter {
boolean isRefreshable(AccountPreferences pref);
}
private static class HomeRefreshableFilter implements RefreshableAccountFilter {
public static final RefreshableAccountFilter INSTANCE = new HomeRefreshableFilter();
@Override
public boolean isRefreshable(final AccountPreferences pref) {
return pref.isAutoRefreshHomeTimelineEnabled();
@ -352,6 +387,8 @@ public class RefreshService extends Service implements Constants {
private static class MentionsRefreshableFilter implements RefreshableAccountFilter {
static final RefreshableAccountFilter INSTANCE = new MentionsRefreshableFilter();
@Override
public boolean isRefreshable(final AccountPreferences pref) {
return pref.isAutoRefreshMentionsEnabled();
@ -360,17 +397,17 @@ public class RefreshService extends Service implements Constants {
}
private static class MessagesRefreshableFilter implements RefreshableAccountFilter {
public static final RefreshableAccountFilter INSTANCE = new MentionsRefreshableFilter();
@Override
public boolean isRefreshable(final AccountPreferences pref) {
return pref.isAutoRefreshDirectMessagesEnabled();
}
}
private interface RefreshableAccountFilter {
boolean isRefreshable(AccountPreferences pref);
}
private static class TrendsRefreshableFilter implements RefreshableAccountFilter {
public static final RefreshableAccountFilter INSTANCE = new TrendsRefreshableFilter();
@Override
public boolean isRefreshable(final AccountPreferences pref) {
return pref.isAutoRefreshTrendsEnabled();

View File

@ -0,0 +1,144 @@
package org.mariotaku.twidere.task;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.desmond.asyncmanager.TaskRunnable;
import com.squareup.otto.Bus;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.TwidereConstants;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterErrorCode;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
import org.mariotaku.twidere.api.twitter.model.Paging;
import org.mariotaku.twidere.api.twitter.model.ResponseList;
import org.mariotaku.twidere.model.RefreshTaskParam;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ContentValuesCreator;
import org.mariotaku.twidere.util.ErrorInfoStore;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.TwitterAPIFactory;
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.GetMessagesTaskEvent;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
/**
* Created by mariotaku on 16/2/14.
*/
public abstract class GetDirectMessagesTask extends TaskRunnable<RefreshTaskParam,
List<TwitterWrapper.MessageListResponse>, Object> implements Constants {
protected final Context context;
@Inject
protected ErrorInfoStore errorInfoStore;
@Inject
protected SharedPreferencesWrapper preferences;
@Inject
protected Bus bus;
public GetDirectMessagesTask(Context context) {
this.context = context;
GeneralComponentHelper.build(context).inject(this);
}
public abstract ResponseList<DirectMessage> getDirectMessages(Twitter twitter, Paging paging)
throws TwitterException;
protected abstract Uri getDatabaseUri();
protected abstract boolean isOutgoing();
@Override
public List<TwitterWrapper.MessageListResponse> doLongOperation(final RefreshTaskParam param) {
final long[] accountIds = param.getAccountIds();
final long[] sinceIds = param.getSinceIds(), maxIds = param.getMaxIds();
final List<TwitterWrapper.MessageListResponse> result = new ArrayList<>();
int idx = 0;
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);
if (twitter == null) continue;
try {
final Paging paging = new Paging();
paging.setCount(loadItemLimit);
long max_id = -1, sinceId = -1;
if (maxIds != null && maxIds[idx] > 0) {
max_id = maxIds[idx];
paging.setMaxId(max_id);
}
if (sinceIds != null && sinceIds[idx] > 0) {
sinceId = sinceIds[idx];
paging.setSinceId(sinceId - 1);
}
final List<DirectMessage> messages = new ArrayList<>();
final boolean truncated = Utils.truncateMessages(getDirectMessages(twitter, paging), messages,
sinceId);
result.add(new TwitterWrapper.MessageListResponse(accountId, max_id, sinceId, messages,
truncated));
storeMessages(accountId, messages, isOutgoing(), true);
errorInfoStore.remove(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId);
} catch (final TwitterException e) {
if (e.getErrorCode() == TwitterErrorCode.NO_DM_PERMISSION) {
errorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId,
ErrorInfoStore.CODE_NO_DM_PERMISSION);
} else if (e.isCausedByNetworkIssue()) {
errorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId,
ErrorInfoStore.CODE_NETWORK_ERROR);
}
if (BuildConfig.DEBUG) {
Log.w(TwidereConstants.LOGTAG, e);
}
result.add(new TwitterWrapper.MessageListResponse(accountId, e));
}
idx++;
}
return result;
}
private boolean storeMessages(long accountId, List<DirectMessage> messages, boolean isOutgoing, boolean notify) {
if (messages == null) return true;
final Uri uri = getDatabaseUri();
final ContentValues[] valuesArray = new ContentValues[messages.size()];
for (int i = 0, j = messages.size(); i < j; i++) {
final DirectMessage message = messages.get(i);
valuesArray[i] = ContentValuesCreator.createDirectMessage(message, accountId, isOutgoing);
}
// Delete all rows conflicting before new data inserted.
// final Expression deleteWhere = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountId),
// Expression.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds)));
// final Uri deleteUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, false);
// mResolver.delete(deleteUri, deleteWhere.getSQL(), null);
// Insert previously fetched items.
final Uri insertUri = UriUtils.appendQueryParameters(uri, TwidereConstants.QUERY_PARAM_NOTIFY, notify);
ContentResolverUtils.bulkInsert(context.getContentResolver(), insertUri, valuesArray);
return false;
}
public void notifyStart() {
bus.post(new GetMessagesTaskEvent(getDatabaseUri(), true, null));
}
@Override
public void callback(List<TwitterWrapper.MessageListResponse> result) {
bus.post(new GetMessagesTaskEvent(getDatabaseUri(), false, AsyncTwitterWrapper.getException(result)));
}
}

View File

@ -27,6 +27,7 @@ import android.os.Bundle;
import org.apache.commons.collections.primitives.ArrayIntList;
import org.apache.commons.collections.primitives.IntList;
import org.mariotaku.twidere.activity.support.HomeActivity;
import edu.tsinghua.hotmobi.HotMobiLogger;
import edu.tsinghua.hotmobi.PreProcessing;
@ -39,6 +40,7 @@ public class ActivityTracker implements Application.ActivityLifecycleCallbacks {
private final IntList mInternalStack = new ArrayIntList();
private SessionEvent mSessionEvent;
private boolean mHomeActivityStarted;
private boolean isSwitchingInSameTask(int hashCode) {
return mInternalStack.lastIndexOf(hashCode) < mInternalStack.size() - 1;
@ -60,6 +62,9 @@ public class ActivityTracker implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityStarted(final Activity activity) {
mInternalStack.add(System.identityHashCode(activity));
if (activity instanceof HomeActivity) {
mHomeActivityStarted = true;
}
// BEGIN HotMobi
if (mSessionEvent == null) {
mSessionEvent = SessionEvent.create(activity);
@ -80,7 +85,9 @@ public class ActivityTracker implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityStopped(Activity activity) {
final int hashCode = System.identityHashCode(activity);
if (activity instanceof HomeActivity) {
mHomeActivityStarted = false;
}
// BEGIN HotMobi
final SessionEvent event = mSessionEvent;
if (event != null && !isSwitchingInSameTask(hashCode)) {
@ -108,4 +115,7 @@ public class ActivityTracker implements Application.ActivityLifecycleCallbacks {
}
public boolean isHomeActivityStarted() {
return mHomeActivityStarted;
}
}

View File

@ -36,12 +36,12 @@ import com.desmond.asyncmanager.BackgroundTask;
import com.desmond.asyncmanager.TaskRunnable;
import com.squareup.otto.Bus;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.collections.primitives.ArrayLongList;
import org.apache.commons.collections.primitives.LongList;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterErrorCode;
import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.http.HttpResponseCode;
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
@ -55,6 +55,7 @@ import org.mariotaku.twidere.api.twitter.model.Trends;
import org.mariotaku.twidere.api.twitter.model.User;
import org.mariotaku.twidere.api.twitter.model.UserList;
import org.mariotaku.twidere.api.twitter.model.UserListUpdate;
import org.mariotaku.twidere.model.BaseRefreshTaskParam;
import org.mariotaku.twidere.model.ListResponse;
import org.mariotaku.twidere.model.ParcelableLocation;
import org.mariotaku.twidere.model.ParcelableMediaUpdate;
@ -79,6 +80,7 @@ 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.GetDirectMessagesTask;
import org.mariotaku.twidere.task.GetHomeTimelineTask;
import org.mariotaku.twidere.task.GetSavedSearchesTask;
import org.mariotaku.twidere.task.ManagedAsyncTask;
@ -89,7 +91,6 @@ import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
import org.mariotaku.twidere.util.message.FavoriteDestroyedEvent;
import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent;
import org.mariotaku.twidere.util.message.FriendshipUserUpdatedEvent;
import org.mariotaku.twidere.util.message.GetMessagesTaskEvent;
import org.mariotaku.twidere.util.message.ProfileUpdatedEvent;
import org.mariotaku.twidere.util.message.StatusDestroyedEvent;
import org.mariotaku.twidere.util.message.StatusListChangedEvent;
@ -102,7 +103,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import edu.tsinghua.hotmobi.HotMobiLogger;
import edu.tsinghua.hotmobi.model.TimelineType;
@ -124,7 +124,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
private LongSparseMap<Long> mCreatingRetweetIds = new LongSparseMap<>();
private LongSparseMap<Long> mDestroyingStatusIds = new LongSparseMap<>();
private CopyOnWriteArraySet<Long> mSendingDraftIds = new CopyOnWriteArraySet<>();
private final LongList mSendingDraftIds = new ArrayLongList();
public AsyncTwitterWrapper(Context context, UserColorNameManager userColorNameManager,
Bus bus, SharedPreferencesWrapper preferences,
@ -144,8 +144,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public void addSendingDraftId(long id) {
mSendingDraftIds.add(id);
mResolver.notifyChange(Drafts.CONTENT_URI_UNSENT, null);
synchronized (mSendingDraftIds) {
mSendingDraftIds.add(id);
mResolver.notifyChange(Drafts.CONTENT_URI_UNSENT, null);
}
}
public int addUserListMembersAsync(final long accountId, final long listId, final ParcelableUser... users) {
@ -282,8 +284,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public boolean getHomeTimelineAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
return getHomeTimelineAsync(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds));
}
public boolean getHomeTimelineAsync(RefreshTaskParam param) {
final GetHomeTimelineTask task = new GetHomeTimelineTask(getContext());
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
task.setParams(param);
task.notifyStart();
AsyncManager.runBackgroundTask(task);
return true;
@ -294,9 +300,22 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return mAsyncTaskManager.add(task, true);
}
public int getReceivedDirectMessagesAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) {
final GetReceivedDirectMessagesTask task = new GetReceivedDirectMessagesTask(accountIds, max_ids, since_ids);
return mAsyncTaskManager.add(task, true);
public void getReceivedDirectMessagesAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
getActivitiesAboutMeAsync(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds));
}
public void getReceivedDirectMessagesAsync(RefreshTaskParam param) {
final GetReceivedDirectMessagesTask task = new GetReceivedDirectMessagesTask(mContext);
task.setParams(param);
task.notifyStart();
AsyncManager.runBackgroundTask(task);
}
public void getSentDirectMessagesAsync(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
final GetSentDirectMessagesTask task = new GetSentDirectMessagesTask(mContext);
task.setParams(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds));
task.notifyStart();
AsyncManager.runBackgroundTask(task);
}
public int getSavedSearchesAsync(long[] accountIds) {
@ -308,12 +327,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
@NonNull
public long[] getSendingDraftIds() {
return ArrayUtils.toPrimitive(mSendingDraftIds.toArray(new Long[mSendingDraftIds.size()]));
}
public int getSentDirectMessagesAsync(final long[] accountIds, final long[] max_ids, final long[] since_ids) {
final GetSentDirectMessagesTask task = new GetSentDirectMessagesTask(accountIds, max_ids, since_ids);
return mAsyncTaskManager.add(task, true);
return mSendingDraftIds.toArray();
}
public AsyncTaskManager getTaskManager() {
@ -428,8 +442,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public void removeSendingDraftId(long id) {
mSendingDraftIds.remove(id);
mResolver.notifyChange(Drafts.CONTENT_URI_UNSENT, null);
synchronized (mSendingDraftIds) {
mSendingDraftIds.removeElement(id);
mResolver.notifyChange(Drafts.CONTENT_URI_UNSENT, null);
}
}
public void removeUnreadCountsAsync(final int position, final LongSparseArray<Set<Long>> counts) {
@ -525,15 +541,19 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
public void getActivitiesAboutMeAsync(final long[] accountIds, long[] maxIds, long[] sinceIds) {
getActivitiesAboutMeAsync(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds));
}
public void getActivitiesAboutMeAsync(final RefreshTaskParam param) {
final GetActivitiesTask task = new GetActivitiesAboutMeTask(getContext());
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
task.setParams(param);
task.notifyStart();
AsyncManager.runBackgroundTask(task);
}
public void getActivitiesByFriendsAsync(long[] accountIds, long[] maxIds, long[] sinceIds) {
final GetActivitiesTask task = new GetActivitiesByFriendsTask(getContext());
task.setParams(new RefreshTaskParam(accountIds, maxIds, sinceIds));
task.setParams(new BaseRefreshTaskParam(accountIds, maxIds, sinceIds));
task.notifyStart();
AsyncManager.runBackgroundTask(task);
}
@ -1719,7 +1739,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
} catch (final TwitterException e) {
exception = e;
}
if (status != null || exception.getErrorCode() == HttpResponseCode.NOT_FOUND) {
if (status != null || (exception != null && exception.getErrorCode() == HttpResponseCode.NOT_FOUND)) {
final ContentValues values = new ContentValues();
values.put(Statuses.MY_RETWEET_ID, -1);
if (status != null) {
@ -1848,122 +1868,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
abstract class GetDirectMessagesTask extends ManagedAsyncTask<Object, Object, List<MessageListResponse>> {
private final long[] accountIds, maxIds, sinceIds;
public GetDirectMessagesTask(final long[] accountIds, final long[] maxIds, final long[] sinceIds,
final String tag) {
super(mContext, tag);
this.accountIds = accountIds;
this.maxIds = maxIds;
this.sinceIds = sinceIds;
}
public abstract ResponseList<DirectMessage> getDirectMessages(Twitter twitter, Paging paging)
throws TwitterException;
protected abstract Uri getDatabaseUri();
protected abstract boolean isOutgoing();
final boolean isMaxIdsValid() {
return maxIds != null && maxIds.length == accountIds.length;
}
final boolean isSinceIdsValid() {
return sinceIds != null && sinceIds.length == accountIds.length;
}
@Override
protected List<MessageListResponse> doInBackground(final Object... params) {
final List<MessageListResponse> result = new ArrayList<>();
if (accountIds == null) return result;
int idx = 0;
final int loadItemLimit = mPreferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
for (final long accountId : accountIds) {
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, true);
if (twitter == null) continue;
try {
final Paging paging = new Paging();
paging.setCount(loadItemLimit);
long max_id = -1, since_id = -1;
if (isMaxIdsValid() && maxIds[idx] > 0) {
max_id = maxIds[idx];
paging.setMaxId(max_id);
}
if (isSinceIdsValid() && sinceIds[idx] > 0) {
since_id = sinceIds[idx];
paging.setSinceId(since_id - 1);
}
final List<DirectMessage> messages = new ArrayList<>();
final boolean truncated = Utils.truncateMessages(getDirectMessages(twitter, paging), messages,
since_id);
result.add(new MessageListResponse(accountId, max_id, since_id, messages,
truncated));
storeMessages(accountId, messages, isOutgoing(), true);
mErrorInfoStore.remove(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId);
} catch (final TwitterException e) {
if (e.getErrorCode() == TwitterErrorCode.NO_DM_PERMISSION) {
mErrorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId,
ErrorInfoStore.CODE_NO_DM_PERMISSION);
} else if (e.isCausedByNetworkIssue()) {
mErrorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountId,
ErrorInfoStore.CODE_NETWORK_ERROR);
}
if (BuildConfig.DEBUG) {
Log.w(LOGTAG, e);
}
result.add(new MessageListResponse(accountId, e));
}
idx++;
}
return result;
}
private boolean storeMessages(long accountId, List<DirectMessage> messages, boolean isOutgoing, boolean notify) {
if (messages == null) return true;
final Uri uri = getDatabaseUri();
final ContentValues[] valuesArray = new ContentValues[messages.size()];
for (int i = 0, j = messages.size(); i < j; i++) {
final DirectMessage message = messages.get(i);
valuesArray[i] = ContentValuesCreator.createDirectMessage(message, accountId, isOutgoing);
}
// Delete all rows conflicting before new data inserted.
// final Expression deleteWhere = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountId),
// Expression.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds)));
// final Uri deleteUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, false);
// mResolver.delete(deleteUri, deleteWhere.getSQL(), null);
// Insert previously fetched items.
final Uri insertUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, notify);
ContentResolverUtils.bulkInsert(mResolver, insertUri, valuesArray);
return false;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
bus.post(new GetMessagesTaskEvent(getDatabaseUri(), true, null));
}
@Override
protected void onPostExecute(final List<MessageListResponse> result) {
super.onPostExecute(result);
bus.post(new GetMessagesTaskEvent(getDatabaseUri(), false, getException(result)));
}
}
class GetLocalTrendsTask extends GetTrendsTask {
private final int woeid;
@ -1987,10 +1891,10 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
class GetReceivedDirectMessagesTask extends GetDirectMessagesTask {
static class GetReceivedDirectMessagesTask extends GetDirectMessagesTask {
public GetReceivedDirectMessagesTask(final long[] account_ids, final long[] max_ids, final long[] since_ids) {
super(account_ids, max_ids, since_ids, TASK_TAG_GET_RECEIVED_DIRECT_MESSAGES);
public GetReceivedDirectMessagesTask(Context context) {
super(context);
}
@Override
@ -2011,24 +1915,17 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
}
@Override
protected void onPostExecute(final List<MessageListResponse> responses) {
super.onPostExecute(responses);
// mAsyncTaskManager.add(new StoreReceivedDirectMessagesTask(responses, !isMaxIdsValid()), true);
}
@Override
protected void onPreExecute() {
public void notifyStart() {
final Intent intent = new Intent(BROADCAST_RESCHEDULE_DIRECT_MESSAGES_REFRESHING);
mContext.sendBroadcast(intent);
super.onPreExecute();
context.sendBroadcast(intent);
super.notifyStart();
}
}
class GetSentDirectMessagesTask extends GetDirectMessagesTask {
static class GetSentDirectMessagesTask extends GetDirectMessagesTask {
public GetSentDirectMessagesTask(final long[] account_ids, final long[] max_ids, final long[] since_ids) {
super(account_ids, max_ids, since_ids, TASK_TAG_GET_SENT_DIRECT_MESSAGES);
public GetSentDirectMessagesTask(Context context) {
super(context);
}
@Override
@ -2047,12 +1944,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
return Outbox.CONTENT_URI;
}
@Override
protected void onPostExecute(final List<MessageListResponse> responses) {
super.onPostExecute(responses);
// mAsyncTaskManager.add(new StoreSentDirectMessagesTask(responses, !isMaxIdsValid()), true);
}
}
public SharedPreferencesWrapper getPreferences() {

View File

@ -51,6 +51,7 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.NotificationManagerWrapper;
import org.mariotaku.twidere.util.PermissionsManager;
import org.mariotaku.twidere.util.ReadStateManager;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.TwidereMathUtils;
@ -120,6 +121,12 @@ public class ApplicationModule implements Constants {
Context.MODE_PRIVATE, SharedPreferenceConstants.class);
}
@Provides
@Singleton
public PermissionsManager permissionsManager() {
return new PermissionsManager(application);
}
@Provides
@Singleton
public UserColorNameManager userColorNameManager() {

View File

@ -50,6 +50,7 @@ import org.mariotaku.twidere.provider.CacheProvider;
import org.mariotaku.twidere.provider.TwidereDataProvider;
import org.mariotaku.twidere.service.BackgroundOperationService;
import org.mariotaku.twidere.service.RefreshService;
import org.mariotaku.twidere.task.GetDirectMessagesTask;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.task.twitter.GetActivitiesTask;
import org.mariotaku.twidere.task.twitter.GetStatusesTask;
@ -141,4 +142,6 @@ public interface GeneralComponent {
void inject(GetStatusesTask task);
void inject(GetActivitiesTask task);
void inject(GetDirectMessagesTask task);
}