code cleanup
This commit is contained in:
parent
933a3f8e1a
commit
775ef69952
|
@ -54,4 +54,11 @@ public class BitmapUtils {
|
|||
BitmapFactory.decodeFile(image.getPath(), o);
|
||||
return o.outMimeType;
|
||||
}
|
||||
|
||||
public static int calculateInSampleSize(final int width, final int height, final int preferredWidth,
|
||||
final int preferredHeight) {
|
||||
if (preferredHeight > height && preferredWidth > width) return 1;
|
||||
final int result = Math.round(Math.max(width, height) / (float) Math.max(preferredWidth, preferredHeight));
|
||||
return Math.max(1, result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,20 +55,15 @@ import android.support.v4.net.ConnectivityManagerCompat;
|
|||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.view.accessibility.AccessibilityEventCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.view.menu.MenuBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Toast;
|
||||
|
@ -99,7 +94,6 @@ import org.mariotaku.twidere.view.TabPagerIndicator;
|
|||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -159,13 +153,6 @@ public final class Utils implements Constants {
|
|||
accessibilityManager.sendAccessibilityEvent(event);
|
||||
}
|
||||
|
||||
public static int calculateInSampleSize(final int width, final int height, final int preferredWidth,
|
||||
final int preferredHeight) {
|
||||
if (preferredHeight > height && preferredWidth > width) return 1;
|
||||
final int result = Math.round(Math.max(width, height) / (float) Math.max(preferredWidth, preferredHeight));
|
||||
return Math.max(1, result);
|
||||
}
|
||||
|
||||
public static boolean closeSilently(final Closeable c) {
|
||||
if (c == null) return false;
|
||||
try {
|
||||
|
@ -800,18 +787,6 @@ public final class Utils implements Constants {
|
|||
showErrorMessage(context, message, long_message);
|
||||
}
|
||||
|
||||
public static void startStatusShareChooser(final Context context, final ParcelableStatus status) {
|
||||
final Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.setType("text/plain");
|
||||
final String name = status.user_name, screenName = status.user_screen_name;
|
||||
final String timeString = formatToLongTimeString(context, status.timestamp);
|
||||
final String subject = context.getString(R.string.status_share_subject_format_with_time, name, screenName, timeString);
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
|
||||
intent.putExtra(Intent.EXTRA_TEXT, status.text_plain);
|
||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
context.startActivity(Intent.createChooser(intent, context.getString(R.string.action_share)));
|
||||
}
|
||||
|
||||
public static String trimLineBreak(final String orig) {
|
||||
if (orig == null) return null;
|
||||
return orig.replaceAll("\\n+", "\n");
|
||||
|
@ -863,28 +838,6 @@ public final class Utils implements Constants {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public static <T> Object findFieldOfTypes(T obj, Class<? extends T> cls, Class<?>... checkTypes) {
|
||||
labelField:
|
||||
for (Field field : cls.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object fieldObj;
|
||||
try {
|
||||
fieldObj = field.get(obj);
|
||||
} catch (Exception ignore) {
|
||||
continue;
|
||||
}
|
||||
if (fieldObj != null) {
|
||||
final Class<?> type = fieldObj.getClass();
|
||||
for (Class<?> checkType : checkTypes) {
|
||||
if (!checkType.isAssignableFrom(type)) continue labelField;
|
||||
}
|
||||
return fieldObj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getNotificationId(int baseId, @Nullable UserKey accountKey) {
|
||||
int result = baseId;
|
||||
result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
|
||||
|
@ -962,38 +915,4 @@ public final class Utils implements Constants {
|
|||
return location;
|
||||
}
|
||||
|
||||
public static boolean checkDeviceCompatible() {
|
||||
try {
|
||||
Menu.class.isAssignableFrom(MenuBuilder.class);
|
||||
} catch (Error e) {
|
||||
Analyzer.Companion.logException(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether screen minimum width is not smaller than 600dp, regardless split screen mode
|
||||
*/
|
||||
public static boolean isDeviceTablet(@NonNull Context context) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
final Display defaultDisplay = wm.getDefaultDisplay();
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
defaultDisplay.getMetrics(metrics);
|
||||
} else {
|
||||
defaultDisplay.getRealMetrics(metrics);
|
||||
}
|
||||
final float mw = Math.min(metrics.widthPixels / metrics.density, metrics.heightPixels / metrics.density);
|
||||
return mw >= 600;
|
||||
}
|
||||
|
||||
/*
|
||||
* May return false on tablets when using split window
|
||||
*/
|
||||
public static boolean isScreenTablet(@NonNull Context context) {
|
||||
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
||||
return metrics.widthPixels / metrics.density >= 600;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,8 +26,9 @@ import android.util.AttributeSet
|
|||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import org.mariotaku.twidere.extension.findFieldByTypes
|
||||
import org.mariotaku.twidere.extension.get
|
||||
import org.mariotaku.twidere.util.ThemeUtils
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/16.
|
||||
|
@ -39,10 +40,18 @@ class TwidereToolbar(context: Context, attrs: AttributeSet?) : Toolbar(context,
|
|||
override fun getMenu(): Menu {
|
||||
val menu = super.getMenu()
|
||||
ThemeUtils.setActionBarOverflowColor(this, itemColor)
|
||||
val menuView = Utils.findFieldOfTypes(this, Toolbar::class.java,
|
||||
ActionMenuView::class.java) as? ActionMenuView ?: return menu
|
||||
val presenter = Utils.findFieldOfTypes(menuView, ActionMenuView::class.java,
|
||||
ActionMenuPresenter::class.java) as? ActionMenuPresenter ?: return menu
|
||||
val menuViewField = try {
|
||||
Toolbar::class.java.findFieldByTypes(ActionMenuView::class.java)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
} ?: return menu
|
||||
val menuView = this[menuViewField] as? ActionMenuView ?: return menu
|
||||
val presenterField = try {
|
||||
ActionMenuView::class.java.findFieldByTypes(ActionMenuPresenter::class.java)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
} ?: return menu
|
||||
val presenter = menuView[presenterField] as? ActionMenuPresenter ?: return menu
|
||||
setActionBarOverflowColor(presenter, itemColor)
|
||||
return menu
|
||||
}
|
||||
|
@ -62,8 +71,12 @@ class TwidereToolbar(context: Context, attrs: AttributeSet?) : Toolbar(context,
|
|||
companion object {
|
||||
|
||||
private fun setActionBarOverflowColor(presenter: ActionMenuPresenter, itemColor: Int) {
|
||||
val view = Utils.findFieldOfTypes(presenter, ActionMenuPresenter::class.java,
|
||||
ActionMenuView.ActionMenuChildView::class.java, View::class.java) as? ImageView ?: return
|
||||
val viewField = try {
|
||||
ActionMenuPresenter::class.java.findFieldByTypes(ActionMenuView.ActionMenuChildView::class.java, View::class.java)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
} ?: return
|
||||
val view = presenter[viewField] as? ImageView ?: return
|
||||
view.setColorFilter(itemColor, PorterDuff.Mode.SRC_ATOP)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -868,7 +868,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
|||
|
||||
|
||||
fun hasMultiColumns(): Boolean {
|
||||
if (!Utils.isDeviceTablet(this) || !Utils.isScreenTablet(this)) return false
|
||||
if (!DeviceUtils.isDeviceTablet(this) || !DeviceUtils.isScreenTablet(this)) return false
|
||||
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
return preferences.getBoolean("multi_column_tabs_landscape", resources.getBoolean(R.bool.default_multi_column_tabs_land))
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.mariotaku.twidere.R
|
|||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_INTENT
|
||||
import org.mariotaku.twidere.extension.model.hasInvalidAccount
|
||||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
import org.mariotaku.twidere.util.DeviceUtils
|
||||
import org.mariotaku.twidere.util.StrictModeUtils
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
|
@ -40,7 +41,7 @@ open class MainActivity : BaseActivity() {
|
|||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
val am = AccountManager.get(this)
|
||||
if (!Utils.checkDeviceCompatible()) {
|
||||
if (!DeviceUtils.checkCompatibility()) {
|
||||
startActivity(Intent(this, IncompatibleAlertActivity::class.java))
|
||||
} else if (!AccountUtils.hasAccountPermission(am)) {
|
||||
Toast.makeText(this, R.string.message_toast_no_account_permission, Toast.LENGTH_SHORT).show()
|
||||
|
|
|
@ -48,9 +48,9 @@ import org.mariotaku.twidere.constant.KeyboardShortcutConstants.ACTION_NAVIGATIO
|
|||
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.CONTEXT_TAG_NAVIGATION
|
||||
import org.mariotaku.twidere.extension.applyTheme
|
||||
import org.mariotaku.twidere.fragment.*
|
||||
import org.mariotaku.twidere.util.DeviceUtils
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler
|
||||
import org.mariotaku.twidere.util.ThemeUtils
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
import java.util.*
|
||||
|
||||
class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartFragmentCallback {
|
||||
|
@ -199,7 +199,7 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF
|
|||
R.xml.preferences_theme)
|
||||
entriesAdapter.addPreference("cards", R.drawable.ic_action_card, getString(R.string.cards),
|
||||
R.xml.preferences_cards)
|
||||
if (Utils.isDeviceTablet(this)) {
|
||||
if (DeviceUtils.isDeviceTablet(this)) {
|
||||
entriesAdapter.addPreference("tablet_mode", R.drawable.ic_action_tablet, getString(R.string.preference_title_tablet_mode),
|
||||
R.xml.preferences_tablet_mode)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.extension
|
||||
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/4/17.
|
||||
*/
|
||||
|
||||
fun Class<*>.findFieldByTypes(vararg checkTypes: Class<*>): Field? {
|
||||
return declaredFields.firstOrNull { field ->
|
||||
checkTypes.all { it.isAssignableFrom(field.type) }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.extension
|
||||
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/4/17.
|
||||
*/
|
||||
|
||||
operator fun Any.get(field: Field): Any? {
|
||||
val accessible = field.isAccessible
|
||||
try {
|
||||
field.isAccessible = true
|
||||
return field[this]
|
||||
} finally {
|
||||
field.isAccessible = accessible
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ fun ParcelableMediaUpdate.getMimeType(resolver: ContentResolver): String? {
|
|||
ParcelableMedia.Type.IMAGE -> {
|
||||
val o = BitmapFactory.Options()
|
||||
o.inJustDecodeBounds = true
|
||||
BitmapFactoryUtils.decodeUri(resolver, uri, null, o)
|
||||
BitmapFactoryUtils.decodeUri(resolver, uri, opts = o)
|
||||
return o.outMimeType
|
||||
}
|
||||
else -> return null
|
||||
|
|
|
@ -688,7 +688,7 @@ class UpdateStatusTask(
|
|||
this.deleteAlways = deleteAlways
|
||||
}
|
||||
} finally {
|
||||
Utils.closeSilently(body)
|
||||
body?.close()
|
||||
}
|
||||
body?.deleteOnSuccess?.addAllTo(deleteOnSuccess)
|
||||
body?.deleteAlways?.addAllTo(deleteAlways)
|
||||
|
@ -811,7 +811,7 @@ class UpdateStatusTask(
|
|||
var mediaType = defaultType
|
||||
val o = BitmapFactory.Options()
|
||||
o.inJustDecodeBounds = true
|
||||
BitmapFactoryUtils.decodeUri(resolver, mediaUri, null, o)
|
||||
BitmapFactoryUtils.decodeUri(resolver, mediaUri, opts = o)
|
||||
// Try to use decoded media type
|
||||
if (o.outMimeType != null) {
|
||||
mediaType = o.outMimeType
|
||||
|
@ -823,7 +823,7 @@ class UpdateStatusTask(
|
|||
|
||||
if (imageLimit != null) {
|
||||
if (imageLimit.checkGeomentry(o.outWidth, o.outHeight)) return null
|
||||
o.inSampleSize = Utils.calculateInSampleSize(o.outWidth, o.outHeight,
|
||||
o.inSampleSize = BitmapUtils.calculateInSampleSize(o.outWidth, o.outHeight,
|
||||
imageLimit.maxWidth, imageLimit.maxHeight)
|
||||
}
|
||||
o.inJustDecodeBounds = false
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.graphics.BitmapFactory
|
|||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/7/31.
|
||||
|
@ -14,16 +13,10 @@ import java.io.InputStream
|
|||
object BitmapFactoryUtils {
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun decodeUri(contentResolver: ContentResolver, uri: Uri, outPadding: Rect?,
|
||||
opts: BitmapFactory.Options?, close: Boolean = true): Bitmap? {
|
||||
var st: InputStream? = null
|
||||
try {
|
||||
st = contentResolver.openInputStream(uri)
|
||||
return BitmapFactory.decodeStream(st, outPadding, opts)
|
||||
} finally {
|
||||
if (close) {
|
||||
Utils.closeSilently(st)
|
||||
}
|
||||
fun decodeUri(contentResolver: ContentResolver, uri: Uri, outPadding: Rect? = null,
|
||||
opts: BitmapFactory.Options? = null): Bitmap? {
|
||||
return contentResolver.openInputStream(uri).use {
|
||||
BitmapFactory.decodeStream(it, outPadding, opts)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.support.v7.view.menu.MenuBuilder
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Menu
|
||||
import android.view.WindowManager
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/4/17.
|
||||
*/
|
||||
|
||||
object DeviceUtils {
|
||||
|
||||
fun checkCompatibility(): Boolean {
|
||||
try {
|
||||
Menu::class.java.isAssignableFrom(MenuBuilder::class.java)
|
||||
} catch (e: Error) {
|
||||
Analyzer.logException(e)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether screen minimum width is not smaller than 600dp, regardless split screen mode
|
||||
*/
|
||||
fun isDeviceTablet(context: Context): Boolean {
|
||||
val metrics = DisplayMetrics()
|
||||
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
val defaultDisplay = wm.defaultDisplay
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
defaultDisplay.getMetrics(metrics)
|
||||
} else {
|
||||
defaultDisplay.getRealMetrics(metrics)
|
||||
}
|
||||
val mw = Math.min(metrics.widthPixels / metrics.density, metrics.heightPixels / metrics.density)
|
||||
return mw >= 600
|
||||
}
|
||||
|
||||
/*
|
||||
* May return false on tablets when using split window
|
||||
*/
|
||||
fun isScreenTablet(context: Context): Boolean {
|
||||
val metrics = context.resources.displayMetrics
|
||||
return metrics.widthPixels / metrics.density >= 600
|
||||
}
|
||||
}
|
|
@ -108,9 +108,7 @@ class OAuthPasswordAuthenticator(
|
|||
@Throws(IOException::class, LoginVerificationException::class)
|
||||
private fun getVerificationData(authorizeResponseData: AuthorizeResponseData,
|
||||
challengeResponse: String?): AuthorizeRequestData {
|
||||
var response: HttpResponse? = null
|
||||
try {
|
||||
val data = AuthorizeRequestData()
|
||||
val params = MultiValueMap<String>()
|
||||
val verification = authorizeResponseData.challenge!!
|
||||
params.add("authenticity_token", verification.authenticityToken)
|
||||
|
@ -132,16 +130,16 @@ class OAuthPasswordAuthenticator(
|
|||
authorizeResultBuilder.url(endpoint.construct("/account/login_verification"))
|
||||
authorizeResultBuilder.headers(requestHeaders)
|
||||
authorizeResultBuilder.body(authorizationResultBody)
|
||||
response = client.newCall(authorizeResultBuilder.build()).execute()
|
||||
parseAuthorizeRequestData(response, data)
|
||||
if (TextUtils.isEmpty(data.authenticityToken)) {
|
||||
throw LoginVerificationException()
|
||||
return client.newCall(authorizeResultBuilder.build()).execute().use {
|
||||
val data = AuthorizeRequestData()
|
||||
parseAuthorizeRequestData(it, data)
|
||||
if (data.authenticityToken.isNullOrEmpty()) {
|
||||
throw LoginVerificationException()
|
||||
}
|
||||
return@use data
|
||||
}
|
||||
return data
|
||||
} catch (e: ParseException) {
|
||||
throw LoginVerificationException("Login verification challenge failed", e)
|
||||
} finally {
|
||||
Utils.closeSilently(response)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +186,6 @@ class OAuthPasswordAuthenticator(
|
|||
private fun getAuthorizeResponseData(requestToken: OAuthToken,
|
||||
authorizeRequestData: AuthorizeRequestData,
|
||||
username: String, password: String): AuthorizeResponseData {
|
||||
var response: HttpResponse? = null
|
||||
try {
|
||||
val data = AuthorizeResponseData()
|
||||
val params = MultiValueMap<String>()
|
||||
|
@ -209,7 +206,6 @@ class OAuthPasswordAuthenticator(
|
|||
authorizeResultBuilder.url(endpoint.construct("/oauth/authorize"))
|
||||
authorizeResultBuilder.headers(requestHeaders)
|
||||
authorizeResultBuilder.body(authorizationResultBody)
|
||||
response = client.newCall(authorizeResultBuilder.build()).execute()
|
||||
val handler = object : AbstractSimpleMarkupHandler() {
|
||||
internal var isOAuthPinDivOpened: Boolean = false
|
||||
internal var isChallengeFormOpened: Boolean = false
|
||||
|
@ -297,18 +293,17 @@ class OAuthPasswordAuthenticator(
|
|||
}
|
||||
}
|
||||
}
|
||||
PARSER.parse(SimpleBody.reader(response!!.body), handler)
|
||||
client.newCall(authorizeResultBuilder.build()).execute().use {
|
||||
PARSER.parse(SimpleBody.reader(it.body), handler)
|
||||
}
|
||||
return data
|
||||
} catch (e: ParseException) {
|
||||
throw AuthenticationException("Malformed HTML", e)
|
||||
} finally {
|
||||
Utils.closeSilently(response)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class, AuthenticationException::class)
|
||||
private fun getAuthorizeRequestData(requestToken: OAuthToken): AuthorizeRequestData {
|
||||
var response: HttpResponse? = null
|
||||
try {
|
||||
val data = AuthorizeRequestData()
|
||||
val authorizePageBuilder = HttpRequest.Builder()
|
||||
|
@ -321,16 +316,15 @@ class OAuthPasswordAuthenticator(
|
|||
requestHeaders.add("User-Agent", userAgent)
|
||||
authorizePageBuilder.headers(requestHeaders)
|
||||
val authorizePageRequest = authorizePageBuilder.build()
|
||||
response = client.newCall(authorizePageRequest).execute()
|
||||
parseAuthorizeRequestData(response, data)
|
||||
if (TextUtils.isEmpty(data.authenticityToken)) {
|
||||
client.newCall(authorizePageRequest).execute().use {
|
||||
parseAuthorizeRequestData(it, data)
|
||||
}
|
||||
if (data.authenticityToken.isNullOrEmpty()) {
|
||||
throw AuthenticationException()
|
||||
}
|
||||
return data
|
||||
} catch (e: ParseException) {
|
||||
throw AuthenticationException("Malformed HTML", e)
|
||||
} finally {
|
||||
Utils.closeSilently(response)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,12 +49,27 @@ abstract class TimelineSyncManager(val context: Context) {
|
|||
}
|
||||
|
||||
|
||||
fun blockingGetPosition(@ReadPositionTag positionTag: String, currentTag: String?): Long {
|
||||
val position = fetchPosition(positionTag, currentTag)
|
||||
synchronized(cachedPositions) {
|
||||
cachedPositions[TimelineKey(positionTag, currentTag)] = position
|
||||
}
|
||||
return position
|
||||
}
|
||||
|
||||
fun peekPosition(@ReadPositionTag positionTag: String, currentTag: String?): Long {
|
||||
synchronized(cachedPositions) {
|
||||
return cachedPositions[TimelineKey(positionTag, currentTag)] ?: -1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@UiThread
|
||||
protected abstract fun performSync(data: Array<PositionData>)
|
||||
|
||||
@WorkerThread
|
||||
@Throws(IOException::class)
|
||||
abstract fun blockingGetPosition(@ReadPositionTag positionTag: String, currentTag: String?): Long
|
||||
protected abstract fun fetchPosition(@ReadPositionTag positionTag: String, currentTag: String?): Long
|
||||
|
||||
data class TimelineKey(val positionTag: String, val currentTag: String?)
|
||||
data class PositionData(val positionTag: String, val currentTag: String?, val positionKey: Long)
|
||||
|
@ -80,4 +95,5 @@ abstract class TimelineSyncManager(val context: Context) {
|
|||
fun newFactory(): Factory = ServiceLoader.load(Factory::class.java).firstOrNull() ?: DummyFactory
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue