dagger migration

This commit is contained in:
Mariotaku Lee 2015-10-06 10:50:44 +08:00
parent 1ff43a360d
commit 674202dbea
8 changed files with 397 additions and 330 deletions

View File

@ -230,8 +230,8 @@ public class TwidereApplication extends MultiDexApplication implements Constants
@Override
public void onLowMemory() {
final ApplicationModule module = getApplicationModule();
module.getMediaLoaderWrapper().clearMemoryCache();
// final ApplicationModule module = getApplicationModule();
// module.getMediaLoaderWrapper().clearMemoryCache();
super.onLowMemory();
}

View File

@ -35,6 +35,7 @@ import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteFullException;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@ -83,7 +84,9 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.StringLongPair;
import org.mariotaku.twidere.model.UnreadItem;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedStatuses;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
@ -139,29 +142,24 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
LazyLoadCallback {
public static final String TAG_OLDEST_MESSAGES = "oldest_messages";
private ContentResolver mContentResolver;
private SQLiteDatabaseWrapper mDatabaseWrapper;
private PermissionsManager mPermissionsManager;
@Nullable
private NotificationManager mNotificationManager;
@Inject
ReadStateManager mReadStateManager;
@Inject
AsyncTwitterWrapper mTwitterWrapper;
@Inject
ImageLoader mMediaLoader;
private ContentResolver mContentResolver;
private SQLiteDatabaseWrapper mDatabaseWrapper;
private PermissionsManager mPermissionsManager;
@Nullable
private NotificationManager mNotificationManager;
private SharedPreferencesWrapper mPreferences;
private ImagePreloader mImagePreloader;
@Inject
private Network mNetwork;
Network mNetwork;
private Handler mHandler;
private boolean mHomeActivityInBackground;
private boolean mNameFirst;
private final BroadcastReceiver mHomeActivityStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
@ -174,105 +172,229 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
};
private boolean mNameFirst;
private static PendingIntent getDeleteIntent(Context context, String type, long accountId, long position) {
// Setup delete intent
final Intent recvIntent = new Intent(context, NotificationReceiver.class);
recvIntent.setAction(BROADCAST_NOTIFICATION_DELETED);
final Uri.Builder recvLinkBuilder = new Uri.Builder();
recvLinkBuilder.scheme(SCHEME_TWIDERE);
recvLinkBuilder.authority(AUTHORITY_NOTIFICATIONS);
recvLinkBuilder.appendPath(type);
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITION, String.valueOf(position));
recvIntent.setData(recvLinkBuilder.build());
return PendingIntent.getBroadcast(context, 0, recvIntent, 0);
}
private static PendingIntent getDeleteIntent(Context context, String type, long accountId, StringLongPair[] positions) {
// Setup delete intent
final Intent recvIntent = new Intent(context, NotificationReceiver.class);
final Uri.Builder recvLinkBuilder = new Uri.Builder();
recvLinkBuilder.scheme(SCHEME_TWIDERE);
recvLinkBuilder.authority(AUTHORITY_NOTIFICATIONS);
recvLinkBuilder.appendPath(type);
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITIONS, StringLongPair.toString(positions));
recvIntent.setData(recvLinkBuilder.build());
return PendingIntent.getBroadcast(context, 0, recvIntent, 0);
}
private static Cursor getPreferencesCursor(final SharedPreferencesWrapper preferences, final String key) {
final MatrixCursor c = new MatrixCursor(TwidereDataStore.Preferences.MATRIX_COLUMNS);
final Map<String, Object> map = new HashMap<>();
final Map<String, ?> all = preferences.getAll();
if (key == null) {
map.putAll(all);
} else {
map.put(key, all.get(key));
}
for (final Map.Entry<String, ?> item : map.entrySet()) {
final Object value = item.getValue();
final int type = getPreferenceType(value);
c.addRow(new Object[]{item.getKey(), ParseUtils.parseString(value), type});
}
return c;
}
private static int getPreferenceType(final Object object) {
if (object == null)
return Preferences.TYPE_NULL;
else if (object instanceof Boolean)
return Preferences.TYPE_BOOLEAN;
else if (object instanceof Integer)
return Preferences.TYPE_INTEGER;
else if (object instanceof Long)
return Preferences.TYPE_LONG;
else if (object instanceof Float)
return Preferences.TYPE_FLOAT;
else if (object instanceof String) return Preferences.TYPE_STRING;
return Preferences.TYPE_INVALID;
}
private static int getUnreadCount(final List<UnreadItem> set, final long... accountIds) {
if (set == null || set.isEmpty()) return 0;
int count = 0;
for (final UnreadItem item : set.toArray(new UnreadItem[set.size()])) {
if (item != null && ArrayUtils.contains(accountIds, item.account_id)) {
count++;
}
}
return count;
}
private static boolean shouldReplaceOnConflict(final int table_id) {
switch (table_id) {
case TABLE_ID_CACHED_HASHTAGS:
case TABLE_ID_CACHED_STATUSES:
case TABLE_ID_CACHED_USERS:
case TABLE_ID_CACHED_RELATIONSHIPS:
case TABLE_ID_SEARCH_HISTORY:
case TABLE_ID_FILTERED_USERS:
case TABLE_ID_FILTERED_KEYWORDS:
case TABLE_ID_FILTERED_SOURCES:
case TABLE_ID_FILTERED_LINKS:
return true;
}
return false;
}
@Override
public int bulkInsert(@NonNull final Uri uri, @NonNull final ContentValues[] valuesArray) {
try {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
case TABLE_ID_NETWORK_USAGES:
return 0;
}
int result = 0;
final long[] newIds = new long[valuesArray.length];
if (table != null) {
mDatabaseWrapper.beginTransaction();
if (tableId == TABLE_ID_CACHED_USERS) {
for (final ContentValues values : valuesArray) {
final Expression where = Expression.equals(CachedUsers.USER_ID,
values.getAsLong(CachedUsers.USER_ID));
mDatabaseWrapper.update(table, values, where.getSQL(), null);
newIds[result++] = mDatabaseWrapper.insertWithOnConflict(table, null,
values, SQLiteDatabase.CONFLICT_REPLACE);
}
} else if (tableId == TABLE_ID_SEARCH_HISTORY) {
for (final ContentValues values : valuesArray) {
values.put(SearchHistory.RECENT_QUERY, System.currentTimeMillis());
final Expression where = Expression.equalsArgs(SearchHistory.QUERY);
final String[] args = {values.getAsString(SearchHistory.QUERY)};
mDatabaseWrapper.update(table, values, where.getSQL(), args);
newIds[result++] = mDatabaseWrapper.insertWithOnConflict(table, null,
values, SQLiteDatabase.CONFLICT_IGNORE);
}
} else if (shouldReplaceOnConflict(tableId)) {
for (final ContentValues values : valuesArray) {
newIds[result++] = mDatabaseWrapper.insertWithOnConflict(table, null,
values, SQLiteDatabase.CONFLICT_REPLACE);
}
} else {
for (final ContentValues values : valuesArray) {
newIds[result++] = mDatabaseWrapper.insert(table, null, values);
}
}
mDatabaseWrapper.setTransactionSuccessful();
mDatabaseWrapper.endTransaction();
}
if (result > 0) {
onDatabaseUpdated(tableId, uri);
}
onNewItemsInserted(uri, tableId, valuesArray, newIds);
return result;
return bulkInsertInternal(uri, valuesArray);
} catch (final SQLException e) {
if (handleSQLException(e)) {
try {
return bulkInsertInternal(uri, valuesArray);
} catch (SQLException e1) {
throw new IllegalStateException(e1);
}
}
throw new IllegalStateException(e);
}
}
private boolean handleSQLException(SQLException e) {
try {
if (e instanceof SQLiteFullException) {
// Drop cached databases
mDatabaseWrapper.delete(CachedUsers.TABLE_NAME, null, null);
mDatabaseWrapper.delete(CachedStatuses.TABLE_NAME, null, null);
mDatabaseWrapper.delete(CachedHashtags.TABLE_NAME, null, null);
mDatabaseWrapper.execSQL("VACUUM");
return true;
}
} catch (SQLException ee) {
throw new IllegalStateException(ee);
}
throw new IllegalStateException(e);
}
private int bulkInsertInternal(@NonNull Uri uri, @NonNull ContentValues[] valuesArray) {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
case TABLE_ID_NETWORK_USAGES:
return 0;
}
int result = 0;
final long[] newIds = new long[valuesArray.length];
if (table != null) {
mDatabaseWrapper.beginTransaction();
if (tableId == TABLE_ID_CACHED_USERS) {
for (final ContentValues values : valuesArray) {
final Expression where = Expression.equals(CachedUsers.USER_ID,
values.getAsLong(CachedUsers.USER_ID));
mDatabaseWrapper.update(table, values, where.getSQL(), null);
newIds[result++] = mDatabaseWrapper.insertWithOnConflict(table, null,
values, SQLiteDatabase.CONFLICT_REPLACE);
}
} else if (tableId == TABLE_ID_SEARCH_HISTORY) {
for (final ContentValues values : valuesArray) {
values.put(SearchHistory.RECENT_QUERY, System.currentTimeMillis());
final Expression where = Expression.equalsArgs(SearchHistory.QUERY);
final String[] args = {values.getAsString(SearchHistory.QUERY)};
mDatabaseWrapper.update(table, values, where.getSQL(), args);
newIds[result++] = mDatabaseWrapper.insertWithOnConflict(table, null,
values, SQLiteDatabase.CONFLICT_IGNORE);
}
} else if (shouldReplaceOnConflict(tableId)) {
for (final ContentValues values : valuesArray) {
newIds[result++] = mDatabaseWrapper.insertWithOnConflict(table, null,
values, SQLiteDatabase.CONFLICT_REPLACE);
}
} else {
for (final ContentValues values : valuesArray) {
newIds[result++] = mDatabaseWrapper.insert(table, null, values);
}
}
mDatabaseWrapper.setTransactionSuccessful();
mDatabaseWrapper.endTransaction();
}
if (result > 0) {
onDatabaseUpdated(tableId, uri);
}
onNewItemsInserted(uri, tableId, valuesArray, newIds);
return result;
}
@Override
public int delete(@NonNull final Uri uri, final String selection, final String[] selectionArgs) {
try {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
return 0;
case VIRTUAL_TABLE_ID_NOTIFICATIONS: {
final List<String> segments = uri.getPathSegments();
if (segments.size() == 1) {
clearNotification();
} else if (segments.size() == 2) {
final int notificationType = ParseUtils.parseInt(segments.get(1));
clearNotification(notificationType, 0);
} else if (segments.size() == 3) {
final int notificationType = ParseUtils.parseInt(segments.get(1));
final long accountId = ParseUtils.parseLong(segments.get(2));
clearNotification(notificationType, accountId);
}
return 1;
}
case VIRTUAL_TABLE_ID_UNREAD_COUNTS: {
return 0;
}
}
if (table == null) return 0;
final int result = mDatabaseWrapper.delete(table, selection, selectionArgs);
if (result > 0) {
onDatabaseUpdated(tableId, uri);
}
return result;
return deleteInternal(uri, selection, selectionArgs);
} catch (final SQLException e) {
if (handleSQLException(e)) {
try {
return deleteInternal(uri, selection, selectionArgs);
} catch (SQLException e1) {
throw new IllegalStateException(e1);
}
}
throw new IllegalStateException(e);
}
}
private int deleteInternal(@NonNull Uri uri, String selection, String[] selectionArgs) {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
return 0;
case VIRTUAL_TABLE_ID_NOTIFICATIONS: {
final List<String> segments = uri.getPathSegments();
if (segments.size() == 1) {
clearNotification();
} else if (segments.size() == 2) {
final int notificationType = ParseUtils.parseInt(segments.get(1));
clearNotification(notificationType, 0);
} else if (segments.size() == 3) {
final int notificationType = ParseUtils.parseInt(segments.get(1));
final long accountId = ParseUtils.parseLong(segments.get(2));
clearNotification(notificationType, accountId);
}
return 1;
}
case VIRTUAL_TABLE_ID_UNREAD_COUNTS: {
return 0;
}
}
if (table == null) return 0;
final int result = mDatabaseWrapper.delete(table, selection, selectionArgs);
if (result > 0) {
onDatabaseUpdated(tableId, uri);
}
return result;
}
@Override
public String getType(@NonNull final Uri uri) {
return null;
@ -281,103 +403,116 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
@Override
public Uri insert(@NonNull final Uri uri, final ContentValues values) {
try {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
return null;
}
final long rowId;
if (tableId == TABLE_ID_CACHED_USERS) {
final Expression where = Expression.equals(CachedUsers.USER_ID,
values.getAsLong(CachedUsers.USER_ID));
mDatabaseWrapper.update(table, values, where.getSQL(), null);
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_IGNORE);
} else if (tableId == TABLE_ID_SEARCH_HISTORY) {
values.put(SearchHistory.RECENT_QUERY, System.currentTimeMillis());
final Expression where = Expression.equalsArgs(SearchHistory.QUERY);
final String[] args = {values.getAsString(SearchHistory.QUERY)};
mDatabaseWrapper.update(table, values, where.getSQL(), args);
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_IGNORE);
} else if (tableId == TABLE_ID_CACHED_RELATIONSHIPS) {
final long accountId = values.getAsLong(CachedRelationships.ACCOUNT_ID);
final long userId = values.getAsLong(CachedRelationships.USER_ID);
final Expression where = Expression.and(
Expression.equals(CachedRelationships.ACCOUNT_ID, accountId),
Expression.equals(CachedRelationships.USER_ID, userId)
);
if (mDatabaseWrapper.update(table, values, where.getSQL(), null) > 0) {
final String[] projection = {CachedRelationships._ID};
final Cursor c = mDatabaseWrapper.query(table, projection, where.getSQL(), null,
null, null, null);
if (c.moveToFirst()) {
rowId = c.getLong(0);
} else {
rowId = 0;
}
c.close();
} else {
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_IGNORE);
}
} else if (tableId == TABLE_ID_NETWORK_USAGES) {
rowId = 0;
final long timeInHours = values.getAsLong(NetworkUsages.TIME_IN_HOURS);
final String requestNetwork = values.getAsString(NetworkUsages.REQUEST_NETWORK);
final String requestType = values.getAsString(NetworkUsages.REQUEST_TYPE);
final SQLInsertQuery insertOrIgnore = SQLQueryBuilder.insertInto(OnConflict.IGNORE, table)
.columns(new String[]{NetworkUsages.TIME_IN_HOURS, NetworkUsages.REQUEST_NETWORK, NetworkUsages.REQUEST_TYPE,
NetworkUsages.KILOBYTES_RECEIVED, NetworkUsages.KILOBYTES_SENT})
.values("?, ?, ?, ?, ?")
.build();
final SQLUpdateQuery updateIncremental = SQLQueryBuilder.update(OnConflict.REPLACE, table)
.set(
new SetValue(NetworkUsages.KILOBYTES_RECEIVED, new RawSQLLang(NetworkUsages.KILOBYTES_RECEIVED + " + ?")),
new SetValue(NetworkUsages.KILOBYTES_SENT, new RawSQLLang(NetworkUsages.KILOBYTES_SENT + " + ?"))
)
.where(Expression.and(
Expression.equals(NetworkUsages.TIME_IN_HOURS, timeInHours),
Expression.equalsArgs(NetworkUsages.REQUEST_NETWORK),
Expression.equalsArgs(NetworkUsages.REQUEST_TYPE)
))
.build();
mDatabaseWrapper.beginTransaction();
mDatabaseWrapper.execSQL(insertOrIgnore.getSQL(),
new Object[]{timeInHours, requestNetwork, requestType, 0.0, 0.0});
mDatabaseWrapper.execSQL(updateIncremental.getSQL(),
new Object[]{values.getAsDouble(NetworkUsages.KILOBYTES_RECEIVED),
values.getAsDouble(NetworkUsages.KILOBYTES_SENT), requestNetwork, requestType});
mDatabaseWrapper.setTransactionSuccessful();
mDatabaseWrapper.endTransaction();
} else if (tableId == VIRTUAL_TABLE_ID_DRAFTS_NOTIFICATIONS) {
rowId = showDraftNotification(uri, values);
} else if (shouldReplaceOnConflict(tableId)) {
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_REPLACE);
} else if (table != null) {
rowId = mDatabaseWrapper.insert(table, null, values);
} else {
return null;
}
onDatabaseUpdated(tableId, uri);
onNewItemsInserted(uri, tableId, values, rowId);
return Uri.withAppendedPath(uri, String.valueOf(rowId));
return insertInternal(uri, values);
} catch (final SQLException e) {
if (handleSQLException(e)) {
try {
return insertInternal(uri, values);
} catch (SQLException e1) {
throw new IllegalStateException(e1);
}
}
throw new IllegalStateException(e);
}
}
private Uri insertInternal(@NonNull Uri uri, ContentValues values) {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
return null;
}
final long rowId;
if (tableId == TABLE_ID_CACHED_USERS) {
final Expression where = Expression.equals(CachedUsers.USER_ID,
values.getAsLong(CachedUsers.USER_ID));
mDatabaseWrapper.update(table, values, where.getSQL(), null);
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_IGNORE);
} else if (tableId == TABLE_ID_SEARCH_HISTORY) {
values.put(SearchHistory.RECENT_QUERY, System.currentTimeMillis());
final Expression where = Expression.equalsArgs(SearchHistory.QUERY);
final String[] args = {values.getAsString(SearchHistory.QUERY)};
mDatabaseWrapper.update(table, values, where.getSQL(), args);
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_IGNORE);
} else if (tableId == TABLE_ID_CACHED_RELATIONSHIPS) {
final long accountId = values.getAsLong(CachedRelationships.ACCOUNT_ID);
final long userId = values.getAsLong(CachedRelationships.USER_ID);
final Expression where = Expression.and(
Expression.equals(CachedRelationships.ACCOUNT_ID, accountId),
Expression.equals(CachedRelationships.USER_ID, userId)
);
if (mDatabaseWrapper.update(table, values, where.getSQL(), null) > 0) {
final String[] projection = {CachedRelationships._ID};
final Cursor c = mDatabaseWrapper.query(table, projection, where.getSQL(), null,
null, null, null);
if (c.moveToFirst()) {
rowId = c.getLong(0);
} else {
rowId = 0;
}
c.close();
} else {
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_IGNORE);
}
} else if (tableId == TABLE_ID_NETWORK_USAGES) {
rowId = 0;
final long timeInHours = values.getAsLong(NetworkUsages.TIME_IN_HOURS);
final String requestNetwork = values.getAsString(NetworkUsages.REQUEST_NETWORK);
final String requestType = values.getAsString(NetworkUsages.REQUEST_TYPE);
final SQLInsertQuery insertOrIgnore = SQLQueryBuilder.insertInto(OnConflict.IGNORE, table)
.columns(new String[]{NetworkUsages.TIME_IN_HOURS, NetworkUsages.REQUEST_NETWORK, NetworkUsages.REQUEST_TYPE,
NetworkUsages.KILOBYTES_RECEIVED, NetworkUsages.KILOBYTES_SENT})
.values("?, ?, ?, ?, ?")
.build();
final SQLUpdateQuery updateIncremental = SQLQueryBuilder.update(OnConflict.REPLACE, table)
.set(
new SetValue(NetworkUsages.KILOBYTES_RECEIVED, new RawSQLLang(NetworkUsages.KILOBYTES_RECEIVED + " + ?")),
new SetValue(NetworkUsages.KILOBYTES_SENT, new RawSQLLang(NetworkUsages.KILOBYTES_SENT + " + ?"))
)
.where(Expression.and(
Expression.equals(NetworkUsages.TIME_IN_HOURS, timeInHours),
Expression.equalsArgs(NetworkUsages.REQUEST_NETWORK),
Expression.equalsArgs(NetworkUsages.REQUEST_TYPE)
))
.build();
mDatabaseWrapper.beginTransaction();
mDatabaseWrapper.execSQL(insertOrIgnore.getSQL(),
new Object[]{timeInHours, requestNetwork, requestType, 0.0, 0.0});
mDatabaseWrapper.execSQL(updateIncremental.getSQL(),
new Object[]{values.getAsDouble(NetworkUsages.KILOBYTES_RECEIVED),
values.getAsDouble(NetworkUsages.KILOBYTES_SENT), requestNetwork, requestType});
mDatabaseWrapper.setTransactionSuccessful();
mDatabaseWrapper.endTransaction();
} else if (tableId == VIRTUAL_TABLE_ID_DRAFTS_NOTIFICATIONS) {
rowId = showDraftNotification(uri, values);
} else if (shouldReplaceOnConflict(tableId)) {
rowId = mDatabaseWrapper.insertWithOnConflict(table, null, values,
SQLiteDatabase.CONFLICT_REPLACE);
} else if (table != null) {
rowId = mDatabaseWrapper.insert(table, null, values);
} else {
return null;
}
onDatabaseUpdated(tableId, uri);
onNewItemsInserted(uri, tableId, values, rowId);
return Uri.withAppendedPath(uri, String.valueOf(rowId));
}
private long showDraftNotification(Uri queryUri, ContentValues values) {
if (values == null) return -1;
final Context context = getContext();
if (values == null || context == null) return -1;
final Long draftId = values.getAsLong(BaseColumns._ID);
if (draftId == null) return -1;
final Expression where = Expression.equals(Drafts._ID, draftId);
final Cursor c = getContentResolver().query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.getSQL(), null, null);
if (c == null) return -1;
final DraftItem.CursorIndices i = new DraftItem.CursorIndices(c);
final DraftItem item;
try {
@ -386,7 +521,6 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
} finally {
c.close();
}
final Context context = getContext();
final String title = context.getString(R.string.status_not_updated);
final String message = context.getString(R.string.status_not_updated_summary);
final Intent intent = new Intent();
@ -601,29 +735,40 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
@Override
public int update(@NonNull final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {
try {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
int result = 0;
if (table != null) {
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
case TABLE_ID_NETWORK_USAGES:
return 0;
}
result = mDatabaseWrapper.update(table, values, selection, selectionArgs);
}
if (result > 0) {
onDatabaseUpdated(tableId, uri);
}
return result;
return updateInternal(uri, values, selection, selectionArgs);
} catch (final SQLException e) {
if (handleSQLException(e)) {
try {
return updateInternal(uri, values, selection, selectionArgs);
} catch (SQLException e1) {
throw new IllegalStateException(e1);
}
}
throw new IllegalStateException(e);
}
}
private int updateInternal(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
final int tableId = getTableId(uri);
final String table = getTableNameById(tableId);
checkWritePermission(tableId, table);
int result = 0;
if (table != null) {
switch (tableId) {
case TABLE_ID_DIRECT_MESSAGES_CONVERSATION:
case TABLE_ID_DIRECT_MESSAGES:
case TABLE_ID_DIRECT_MESSAGES_CONVERSATIONS_ENTRIES:
case TABLE_ID_NETWORK_USAGES:
return 0;
}
result = mDatabaseWrapper.update(table, values, selection, selectionArgs);
}
if (result > 0) {
onDatabaseUpdated(tableId, uri);
}
return result;
}
private boolean checkPermission(final String... permissions) {
return mPermissionsManager.checkCallingPermission(permissions);
}
@ -765,8 +910,8 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
private ParcelFileDescriptor getCacheFileFd(final String name) throws FileNotFoundException {
if (name == null) return null;
final Context mContext = getContext();
final File cacheDir = mContext.getCacheDir();
final Context context = getContext();
final File cacheDir = context.getCacheDir();
final File file = new File(cacheDir, name);
if (!file.exists()) return null;
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
@ -861,7 +1006,6 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
});
}
private void notifyUnreadCountChanged(final int position) {
final Context context = getContext();
final Bus bus = TwidereApplication.getInstance(context).getMessageBus();
@ -888,7 +1032,6 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
notifyContentObserver(getNotificationUri(tableId, uri));
}
private void onNewItemsInserted(final Uri uri, final int tableId, final ContentValues values, final long newId) {
onNewItemsInserted(uri, tableId, new ContentValues[]{values}, new long[]{newId});
}
@ -1135,33 +1278,6 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
return PendingIntent.getActivity(context, 0, homeIntent, 0);
}
private static PendingIntent getDeleteIntent(Context context, String type, long accountId, long position) {
// Setup delete intent
final Intent recvIntent = new Intent(context, NotificationReceiver.class);
recvIntent.setAction(BROADCAST_NOTIFICATION_DELETED);
final Uri.Builder recvLinkBuilder = new Uri.Builder();
recvLinkBuilder.scheme(SCHEME_TWIDERE);
recvLinkBuilder.authority(AUTHORITY_NOTIFICATIONS);
recvLinkBuilder.appendPath(type);
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITION, String.valueOf(position));
recvIntent.setData(recvLinkBuilder.build());
return PendingIntent.getBroadcast(context, 0, recvIntent, 0);
}
private static PendingIntent getDeleteIntent(Context context, String type, long accountId, StringLongPair[] positions) {
// Setup delete intent
final Intent recvIntent = new Intent(context, NotificationReceiver.class);
final Uri.Builder recvLinkBuilder = new Uri.Builder();
recvLinkBuilder.scheme(SCHEME_TWIDERE);
recvLinkBuilder.authority(AUTHORITY_NOTIFICATIONS);
recvLinkBuilder.appendPath(type);
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_ACCOUNT_ID, String.valueOf(accountId));
recvLinkBuilder.appendQueryParameter(QUERY_PARAM_READ_POSITIONS, StringLongPair.toString(positions));
recvIntent.setData(recvLinkBuilder.build());
return PendingIntent.getBroadcast(context, 0, recvIntent, 0);
}
private void setNotificationPreferences(NotificationCompat.Builder builder, AccountPreferences pref, int defaultFlags) {
int notificationDefaults = 0;
if (AccountPreferences.isNotificationHasLight(defaultFlags)) {
@ -1349,66 +1465,6 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
mNameFirst = mPreferences.getBoolean(KEY_NAME_FIRST, false);
}
private static Cursor getPreferencesCursor(final SharedPreferencesWrapper preferences, final String key) {
final MatrixCursor c = new MatrixCursor(TwidereDataStore.Preferences.MATRIX_COLUMNS);
final Map<String, Object> map = new HashMap<>();
final Map<String, ?> all = preferences.getAll();
if (key == null) {
map.putAll(all);
} else {
map.put(key, all.get(key));
}
for (final Map.Entry<String, ?> item : map.entrySet()) {
final Object value = item.getValue();
final int type = getPreferenceType(value);
c.addRow(new Object[]{item.getKey(), ParseUtils.parseString(value), type});
}
return c;
}
private static int getPreferenceType(final Object object) {
if (object == null)
return Preferences.TYPE_NULL;
else if (object instanceof Boolean)
return Preferences.TYPE_BOOLEAN;
else if (object instanceof Integer)
return Preferences.TYPE_INTEGER;
else if (object instanceof Long)
return Preferences.TYPE_LONG;
else if (object instanceof Float)
return Preferences.TYPE_FLOAT;
else if (object instanceof String) return Preferences.TYPE_STRING;
return Preferences.TYPE_INVALID;
}
private static int getUnreadCount(final List<UnreadItem> set, final long... accountIds) {
if (set == null || set.isEmpty()) return 0;
int count = 0;
for (final UnreadItem item : set.toArray(new UnreadItem[set.size()])) {
if (item != null && ArrayUtils.contains(accountIds, item.account_id)) {
count++;
}
}
return count;
}
private static boolean shouldReplaceOnConflict(final int table_id) {
switch (table_id) {
case TABLE_ID_CACHED_HASHTAGS:
case TABLE_ID_CACHED_STATUSES:
case TABLE_ID_CACHED_USERS:
case TABLE_ID_CACHED_RELATIONSHIPS:
case TABLE_ID_SEARCH_HISTORY:
case TABLE_ID_FILTERED_USERS:
case TABLE_ID_FILTERED_KEYWORDS:
case TABLE_ID_FILTERED_SOURCES:
case TABLE_ID_FILTERED_LINKS:
return true;
}
return false;
}
@SuppressWarnings("unused")
private static class GetWritableDatabaseTask extends AsyncTask<Object, Object, SQLiteDatabase> {
private final Context mContext;

View File

@ -87,7 +87,6 @@ import org.mariotaku.twidere.task.CacheUsersStatusesTask;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.util.collection.LongSparseMap;
import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.dagger.ApplicationModule;
import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
import org.mariotaku.twidere.util.message.FavoriteDestroyedEvent;
import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent;
@ -130,9 +129,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
private CopyOnWriteArraySet<Long> mSendingDraftIds = new CopyOnWriteArraySet<>();
public AsyncTwitterWrapper(final Context context) {
public AsyncTwitterWrapper(final Context context, final AsyncTaskManager manager) {
mContext = context;
mAsyncTaskManager = ApplicationModule.get(context).getAsyncTaskManager();
mAsyncTaskManager = manager;
mPreferences = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE, SharedPreferenceConstants.class);
mResolver = context.getContentResolver();

View File

@ -11,9 +11,9 @@ import android.text.TextUtils;
import android.util.Pair;
import android.webkit.URLUtil;
import com.bluelinelabs.logansquare.LoganSquare;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.internal.Internal;
import com.squareup.okhttp.internal.Network;
import org.mariotaku.restfu.ExceptionFactory;
import org.mariotaku.restfu.HttpRequestFactory;
@ -43,7 +43,6 @@ import org.mariotaku.twidere.api.twitter.auth.OAuthAuthorization;
import org.mariotaku.twidere.api.twitter.auth.OAuthEndpoint;
import org.mariotaku.twidere.api.twitter.auth.OAuthToken;
import org.mariotaku.twidere.api.twitter.util.TwitterConverter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ConsumerKeyType;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.model.RequestType;
@ -104,12 +103,16 @@ public class TwitterAPIFactory implements TwidereConstants {
}
public static RestHttpClient getDefaultHttpClient(final Context context) {
if (context == null) return null;
final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
return createHttpClient(context, prefs);
return getDefaultHttpClient(context, ApplicationModule.get(context).getNetwork());
}
public static RestHttpClient createHttpClient(final Context context, final SharedPreferences prefs) {
public static RestHttpClient getDefaultHttpClient(final Context context, final Network network) {
if (context == null || network == null) return null;
final SharedPreferencesWrapper prefs = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
return createHttpClient(context, network, prefs);
}
public static RestHttpClient createHttpClient(final Context context, final Network network, final SharedPreferences prefs) {
final int connectionTimeout = prefs.getInt(KEY_CONNECTION_TIMEOUT, 10);
final boolean ignoreSslError = prefs.getBoolean(KEY_IGNORE_SSL_ERROR, false);
final boolean enableProxy = prefs.getBoolean(KEY_ENABLE_PROXY, false);
@ -128,7 +131,7 @@ public class TwitterAPIFactory implements TwidereConstants {
if (enableProxy) {
client.setProxy(getProxy(prefs));
}
Internal.instance.setNetwork(client, ApplicationModule.get(context).getNetwork());
Internal.instance.setNetwork(client, network);
return new OkHttpRestClient(context, client);
}

View File

@ -30,8 +30,6 @@ import com.squareup.otto.Bus;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.task.ManagedAsyncTask;
import org.mariotaku.twidere.util.dagger.ApplicationModule;
import org.mariotaku.twidere.util.imageloader.TwidereImageDownloader;
import org.mariotaku.twidere.util.message.VideoLoadFinishedEvent;
import java.io.File;
@ -50,12 +48,12 @@ public class VideoLoader {
private final AsyncTaskManager mTaskManager;
private final Bus mBus;
public VideoLoader(Context context) {
public VideoLoader(Context context, ImageDownloader downloader, AsyncTaskManager manager) {
final TwidereApplication app = TwidereApplication.getInstance(context);
mContext = context;
mDiskCache = app.getDiskCache();
mImageDownloader = new TwidereImageDownloader(context, false);
mTaskManager = ApplicationModule.get(context).getAsyncTaskManager();
mImageDownloader = downloader;
mTaskManager = manager;
mBus = app.getMessageBus();
}

View File

@ -27,6 +27,7 @@ import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.utils.L;
import com.squareup.okhttp.internal.Network;
import org.mariotaku.restfu.http.RestHttpClient;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.ActivityTracker;
@ -34,6 +35,7 @@ import org.mariotaku.twidere.util.AsyncTaskManager;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.ReadStateManager;
import org.mariotaku.twidere.util.TwitterAPIFactory;
import org.mariotaku.twidere.util.VideoLoader;
import org.mariotaku.twidere.util.imageloader.TwidereImageDownloader;
import org.mariotaku.twidere.util.net.TwidereNetwork;
@ -56,23 +58,44 @@ public class ApplicationModule {
private final TwidereImageDownloader imageDownloader;
private final AsyncTaskManager asyncTaskManager;
private final Network network;
private final RestHttpClient restHttpClient;
public ApplicationModule(TwidereApplication application) {
activityTracker = new ActivityTracker();
asyncTwitterWrapper = new AsyncTwitterWrapper(application);
readStateManager = new ReadStateManager(application);
imageDownloader = new TwidereImageDownloader(application, true);
imageLoader = createImageLoader(application, imageDownloader);
videoLoader = new VideoLoader(application);
mediaLoaderWrapper = new MediaLoaderWrapper(imageLoader, videoLoader);
asyncTaskManager = AsyncTaskManager.getInstance();
asyncTwitterWrapper = new AsyncTwitterWrapper(application, asyncTaskManager);
readStateManager = new ReadStateManager(application);
network = new TwidereNetwork(application);
restHttpClient = TwitterAPIFactory.getDefaultHttpClient(application, network);
imageDownloader = new TwidereImageDownloader(application, network, true);
imageLoader = createImageLoader(application, imageDownloader);
videoLoader = new VideoLoader(application, imageDownloader, asyncTaskManager);
mediaLoaderWrapper = new MediaLoaderWrapper(imageLoader, videoLoader);
}
public static ApplicationModule get(Context context) {
return TwidereApplication.getInstance(context).getApplicationModule();
}
private static ImageLoader createImageLoader(TwidereApplication application, TwidereImageDownloader imageDownloader) {
final ImageLoader loader = ImageLoader.getInstance();
final ImageLoaderConfiguration.Builder cb = new ImageLoaderConfiguration.Builder(application);
cb.threadPriority(Thread.NORM_PRIORITY - 2);
cb.denyCacheImageMultipleSizesInMemory();
cb.tasksProcessingOrder(QueueProcessingType.LIFO);
// cb.memoryCache(new ImageMemoryCache(40));
cb.diskCache(application.getDiskCache());
cb.imageDownloader(imageDownloader);
L.writeDebugLogs(BuildConfig.DEBUG);
loader.init(cb.build());
return loader;
}
@Provides
public RestHttpClient getRestHttpClient() {
return restHttpClient;
}
@Provides
public AsyncTaskManager getAsyncTaskManager() {
return asyncTaskManager;
@ -113,20 +136,6 @@ public class ApplicationModule {
return mediaLoaderWrapper;
}
private static ImageLoader createImageLoader(TwidereApplication application, TwidereImageDownloader imageDownloader) {
final ImageLoader loader = ImageLoader.getInstance();
final ImageLoaderConfiguration.Builder cb = new ImageLoaderConfiguration.Builder(application);
cb.threadPriority(Thread.NORM_PRIORITY - 2);
cb.denyCacheImageMultipleSizesInMemory();
cb.tasksProcessingOrder(QueueProcessingType.LIFO);
// cb.memoryCache(new ImageMemoryCache(40));
cb.diskCache(application.getDiskCache());
cb.imageDownloader(imageDownloader);
L.writeDebugLogs(BuildConfig.DEBUG);
loader.init(cb.build());
return loader;
}
@Provides
public Network getNetwork() {
return network;

View File

@ -29,6 +29,7 @@ import android.webkit.URLUtil;
import com.nostra13.universalimageloader.core.assist.ContentLengthInputStream;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.squareup.okhttp.internal.Network;
import com.squareup.pollexor.Thumbor;
import com.squareup.pollexor.ThumborUrlBuilder;
@ -69,24 +70,25 @@ public class TwidereImageDownloader extends BaseImageDownloader implements Const
private final SharedPreferencesWrapper mPreferences;
private final boolean mUseThumbor;
private final String mUserAgent;
private final Network mNetwork;
private Thumbor mThumbor;
private RestHttpClient mClient;
private final String mTwitterProfileImageSize;
public TwidereImageDownloader(final Context context, final boolean useThumbor) {
public TwidereImageDownloader(final Context context, final Network network, final boolean useThumbor) {
super(context);
mContext = context;
mNetwork = network;
mPreferences = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE, SharedPreferenceConstants.class);
mTwitterProfileImageSize = context.getString(R.string.profile_image_size);
mUseThumbor = useThumbor;
mUserAgent = UserAgentUtils.getDefaultUserAgentString(context);
reloadConnectivitySettings();
}
public void reloadConnectivitySettings() {
mClient = TwitterAPIFactory.getDefaultHttpClient(mContext);
mClient = TwitterAPIFactory.getDefaultHttpClient(mContext, mNetwork);
if (mUseThumbor && mPreferences.getBoolean(KEY_THUMBOR_ENABLED)) {
final String address = mPreferences.getString(KEY_THUMBOR_ADDRESS, null);
final String securityKey = mPreferences.getString(KEY_THUMBOR_SECURITY_KEY, null);

View File

@ -48,7 +48,7 @@ import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
/**
* IDE gives me warning if I don't change default comment, so I write this XD
* IDE gives me warning if I don't change default comment, so I wrote this XD
* <p/>
* Created by mariotaku on 14/11/19.
*/