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

improved combined emoji

improved user agent
This commit is contained in:
Mariotaku Lee 2015-12-26 17:58:07 +08:00
parent d74ffe2814
commit 8c8bd746dc
6 changed files with 236 additions and 112 deletions

View File

@ -119,6 +119,7 @@ import org.mariotaku.twidere.util.MathUtils;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.MediaLoadingHandler;
import org.mariotaku.twidere.util.MenuUtils;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.Nullables;
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
import org.mariotaku.twidere.util.RecyclerViewUtils;
@ -947,11 +948,11 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private final TextView translateResultView;
private final RecyclerView interactUsersView;
public DetailStatusViewHolder(StatusAdapter adapter, View itemView) {
public DetailStatusViewHolder(final StatusAdapter adapter, View itemView) {
super(itemView);
this.linkClickHandler = new StatusLinkClickHandler(adapter.getContext(), null);
this.linkify = new TwidereLinkify(linkClickHandler);
this.adapter = adapter;
this.linkClickHandler = new DetailStatusLinkClickHandler(adapter.getContext(), null, adapter);
this.linkify = new TwidereLinkify(linkClickHandler);
menuBar = (ActionMenuView) itemView.findViewById(R.id.menu_bar);
nameView = (TextView) itemView.findViewById(R.id.name);
screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
@ -1328,7 +1329,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
interactUsersView.setLayoutManager(layoutManager);
if (adapter.isProfileImageEnabled()) {
interactUsersView.setAdapter(new UserProfileImagesAdapter(adapter.getContext()));
interactUsersView.setAdapter(new UserProfileImagesAdapter(fragment, adapter.getContext()));
} else {
interactUsersView.setAdapter(null);
}
@ -1341,9 +1342,11 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private static class UserProfileImagesAdapter extends ArrayRecyclerAdapter<ParcelableUser, ViewHolder> {
private final LayoutInflater mInflater;
private final StatusFragment mFragment;
public UserProfileImagesAdapter(Context context) {
public UserProfileImagesAdapter(StatusFragment fragment, Context context) {
super(context);
mFragment = fragment;
mInflater = LayoutInflater.from(context);
}
@ -1357,7 +1360,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return new ProfileImageViewHolder(this, mInflater.inflate(R.layout.adapter_item_status_interact_user, parent, false));
}
static class ProfileImageViewHolder extends ViewHolder {
static class ProfileImageViewHolder extends ViewHolder implements OnClickListener {
private final UserProfileImagesAdapter adapter;
private final ImageView profileImageView;
@ -1365,14 +1368,52 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
public ProfileImageViewHolder(UserProfileImagesAdapter adapter, View itemView) {
super(itemView);
profileImageView = (ImageView) itemView.findViewById(R.id.profile_image);
itemView.setOnClickListener(this);
this.adapter = adapter;
}
public void displayUser(ParcelableUser item) {
adapter.getMediaLoader().displayProfileImage(profileImageView, item.profile_image_url);
}
@Override
public void onClick(View v) {
adapter.notifyItemClick(getLayoutPosition());
}
}
private void notifyItemClick(int position) {
mFragment.onUserClick(getItem(position));
}
}
private static class DetailStatusLinkClickHandler extends StatusLinkClickHandler {
private final StatusAdapter adapter;
public DetailStatusLinkClickHandler(Context context, MultiSelectManager manager, StatusAdapter adapter) {
super(context, manager);
this.adapter = adapter;
}
@Override
public void onLinkClick(String link, String orig, long accountId, long extraId, int type, boolean sensitive, int start, int end) {
final ParcelableStatus status = adapter.getStatus();
if (status.media != null) {
for (final ParcelableMedia media : status.media) {
if (media.start == start && media.end == end) {
adapter.setDetailMediaExpanded(true);
return;
}
}
}
super.onLinkClick(link, orig, accountId, extraId, type, sensitive, start, end);
}
}
}
private void onUserClick(ParcelableUser user) {
Utils.openUserProfile(getContext(), user, null);
}
private static class SpaceViewHolder extends ViewHolder {

View File

@ -29,10 +29,12 @@ import android.text.style.DynamicDrawableSpan;
*/
public class EmojiSpan extends DynamicDrawableSpan {
private final Drawable drawable;
private Paint.FontMetrics fontMetrics;
public EmojiSpan(Drawable drawable) {
super(ALIGN_BOTTOM);
this.drawable = drawable;
this.fontMetrics = new Paint.FontMetrics();
}
@Override
@ -44,7 +46,8 @@ public class EmojiSpan extends DynamicDrawableSpan {
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
final Drawable drawable = getDrawable();
if (drawable == null) return 0;
final int textHeightPx = Math.round(paint.descent() - paint.ascent());
paint.getFontMetrics(fontMetrics);
final int textHeightPx = Math.round(fontMetrics.descent - fontMetrics.ascent);
final float intrinsicWidth = drawable.getIntrinsicWidth(),
intrinsicHeight = drawable.getIntrinsicHeight();
final int scaledWidth;
@ -53,10 +56,7 @@ public class EmojiSpan extends DynamicDrawableSpan {
} else {
scaledWidth = Math.round(intrinsicWidth * (textHeightPx / intrinsicHeight));
}
if (fm == null) {
fm = paint.getFontMetricsInt();
}
final int top = fm.bottom - textHeightPx, left = 0;
final int top = Math.round(fontMetrics.bottom) - textHeightPx, left = 0;
drawable.setBounds(left, top, left + scaledWidth, top + textHeightPx);
return scaledWidth;
}

View File

@ -49,41 +49,54 @@ public class EmojiSupportUtils {
final ExternalThemeManager.Emoji emoji = manager.getEmoji();
if (!emoji.isSupported()) return;
final CodePointArray array = new CodePointArray(text);
for (int i = array.length() - 1; i >= 0; i--) {
final int codePoint = array.get(i);
for (int arrayIdx = array.length() - 1; arrayIdx >= 0; arrayIdx--) {
final int codePoint = array.get(arrayIdx);
if (isEmoji(codePoint)) {
int arrayIdx = i, arrayEnd = i + 1, arrayIdxOffset = 0;
int textIdx = array.indexOfText(codePoint, i), textIdxOffset = 0;
int indexOffset = 0;
int arrayEnd = arrayIdx + 1, arrayIdxOffset = 0;
int textIdx = array.indexOfText(codePoint, arrayIdx), textIdxOffset = 0;
int skippedIndex = 0;
if (textIdx == -1 || textIdx < textStart) {
continue;
}
final int textEnd = textIdx + Character.charCount(codePoint);
if (isRegionalIndicatorSymbol(codePoint)) {
if (i > 0) {
int prev = array.get(i - 1);
if (isRegionalIndicatorSymbol(prev)) {
if (arrayIdx > 0) {
final int prevCodePoint = array.get(arrayIdx - 1);
if (isRegionalIndicatorSymbol(codePoint)) {
if (isRegionalIndicatorSymbol(prevCodePoint)) {
arrayIdxOffset = -1;
textIdxOffset = -Character.charCount(prev);
indexOffset = -1;
textIdxOffset = -Character.charCount(prevCodePoint);
skippedIndex = -1;
}
}
} else if (isModifier(codePoint)) {
if (i > 0) {
int prev = array.get(i - 1);
if (isEmoji(prev)) {
} else if (isModifier(codePoint)) {
if (isEmoji(prevCodePoint)) {
arrayIdxOffset = -1;
textIdxOffset = -Character.charCount(prev);
indexOffset = -1;
textIdxOffset = -Character.charCount(prevCodePoint);
skippedIndex = -1;
}
}
} else if (isKeyCap(codePoint)) {
if (i > 0) {
int prev = array.get(i - 1);
if (isPhoneNumberSymbol(prev)) {
} else if (isKeyCap(codePoint)) {
if (isPhoneNumberSymbol(prevCodePoint)) {
arrayIdxOffset = -1;
textIdxOffset = -Character.charCount(prev);
indexOffset = -1;
textIdxOffset = -Character.charCount(prevCodePoint);
skippedIndex = -1;
}
} else if (isZeroWidthJoin(prevCodePoint)) {
int notValidControlCount = 0;
int charCount = 0;
for (int i = arrayIdx - 1; i >= 0; i--) {
final int cp = array.get(i);
charCount += Character.charCount(cp);
if (isZeroWidthJoin(cp) || isVariationSelector(cp)) {
// Ignore
notValidControlCount = 0;
continue;
}
notValidControlCount++;
if (notValidControlCount > 1 || i == 0) {
arrayIdxOffset = i - arrayIdx + 1;
textIdxOffset = -charCount + Character.charCount(cp);
skippedIndex = i - arrayIdx + 1;
break;
}
}
}
}
@ -96,7 +109,7 @@ public class EmojiSupportUtils {
// Not emoji combination, just use fallback
textIdxOffset = 0;
arrayIdxOffset = 0;
indexOffset = 0;
skippedIndex = 0;
spans = text.getSpans(textIdx + textIdxOffset, textEnd, EmojiSpan.class);
if (spans.length == 0) {
drawable = emoji.getEmojiDrawableFor(array.subarray(arrayIdx + arrayIdxOffset,
@ -108,11 +121,19 @@ public class EmojiSupportUtils {
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
i += indexOffset;
arrayIdx += skippedIndex;
}
}
}
private static boolean isVariationSelector(int codePoint) {
return codePoint == 0xfe0f;
}
private static boolean isZeroWidthJoin(int codePoint) {
return codePoint == 0x200d;
}
private static boolean isPhoneNumberSymbol(int codePoint) {
return codePoint == 0x0023 || codePoint == 0x002a || inRange(codePoint, 0x0030, 0x0039);
}

View File

@ -6,8 +6,11 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.SSLCertificateSocketFactory;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.webkit.URLUtil;
@ -33,6 +36,7 @@ import org.mariotaku.restfu.http.RestHttpResponse;
import org.mariotaku.restfu.http.mime.StringTypedData;
import org.mariotaku.restfu.http.mime.TypedData;
import org.mariotaku.restfu.okhttp.OkHttpRestClient;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.TwidereConstants;
import org.mariotaku.twidere.api.twitter.Twitter;
import org.mariotaku.twidere.api.twitter.TwitterException;
@ -59,6 +63,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
@ -73,23 +78,27 @@ import static android.text.TextUtils.isEmpty;
*/
public class TwitterAPIFactory implements TwidereConstants {
@WorkerThread
public static Twitter getDefaultTwitterInstance(final Context context, final boolean includeEntities) {
if (context == null) return null;
return getDefaultTwitterInstance(context, includeEntities, true);
}
@WorkerThread
public static Twitter getDefaultTwitterInstance(final Context context, final boolean includeEntities,
final boolean includeRetweets) {
if (context == null) return null;
return getTwitterInstance(context, Utils.getDefaultAccountId(context), includeEntities, includeRetweets);
}
@WorkerThread
public static Twitter getTwitterInstance(final Context context, final long accountId,
final boolean includeEntities) {
return getTwitterInstance(context, accountId, includeEntities, true);
}
@Nullable
@WorkerThread
public static Twitter getTwitterInstance(final Context context, final long accountId,
final boolean includeEntities,
final boolean includeRetweets) {
@ -97,6 +106,7 @@ public class TwitterAPIFactory implements TwidereConstants {
}
@Nullable
@WorkerThread
public static <T> T getTwitterInstance(final Context context, final long accountId,
final boolean includeEntities,
final boolean includeRetweets, Class<T> cls) {
@ -164,6 +174,7 @@ public class TwitterAPIFactory implements TwidereConstants {
return Proxy.NO_PROXY;
}
@WorkerThread
public static <T> T getInstance(final Context context, final Endpoint endpoint,
final Authorization auth, final Map<String, String> extraRequestParams,
final Class<T> cls) {
@ -174,7 +185,7 @@ public class TwitterAPIFactory implements TwidereConstants {
final String consumerSecret = ((OAuthAuthorization) auth).getConsumerSecret();
final ConsumerKeyType officialKeyType = TwitterContentUtils.getOfficialKeyType(context, consumerKey, consumerSecret);
if (officialKeyType != ConsumerKeyType.UNKNOWN) {
userAgent = getUserAgentName(officialKeyType);
userAgent = getUserAgentName(context, officialKeyType);
} else {
userAgent = getTwidereUserAgent(context);
}
@ -191,18 +202,20 @@ public class TwitterAPIFactory implements TwidereConstants {
return factory.build(cls);
}
@WorkerThread
public static <T> T getInstance(final Context context, final Endpoint endpoint,
final Authorization auth, final Class<T> cls) {
return getInstance(context, endpoint, auth, null, cls);
}
@WorkerThread
public static <T> T getInstance(final Context context, final Endpoint endpoint,
final ParcelableCredentials credentials,
final Class<T> cls) {
return getInstance(context, endpoint, credentials, null, cls);
}
@WorkerThread
public static <T> T getInstance(final Context context, final Endpoint endpoint,
final ParcelableCredentials credentials,
final Map<String, String> extraRequestParams, final Class<T> cls) {
@ -210,11 +223,13 @@ public class TwitterAPIFactory implements TwidereConstants {
extraRequestParams, cls);
}
@WorkerThread
static <T> T getInstance(final Context context, final ParcelableCredentials credentials,
final Class<T> cls) {
return getInstance(context, credentials, null, cls);
}
@WorkerThread
static <T> T getInstance(final Context context, final ParcelableCredentials credentials,
final Map<String, String> extraRequestParams, final Class<T> cls) {
if (credentials == null) return null;
@ -327,7 +342,6 @@ public class TwitterAPIFactory implements TwidereConstants {
public static String getApiUrl(final String pattern, final String domain, final String appendPath) {
final String urlBase = getApiBaseUrl(pattern, domain);
if (urlBase == null) return null;
if (appendPath == null) return urlBase.endsWith("/") ? urlBase : urlBase + "/";
final StringBuilder sb = new StringBuilder(urlBase);
if (urlBase.endsWith("/")) {
@ -343,10 +357,22 @@ public class TwitterAPIFactory implements TwidereConstants {
return sb.toString();
}
public static String getUserAgentName(ConsumerKeyType type) {
@WorkerThread
public static String getUserAgentName(Context context, ConsumerKeyType type) {
switch (type) {
case TWITTER_FOR_ANDROID: {
return "TwitterAndroid";
final String versionName = "5.2.4";
final String internalVersionName = "524-r1";
final String model = Build.MODEL;
final String manufacturer = Build.MANUFACTURER;
final int sdkInt = Build.VERSION.SDK_INT;
final String device = Build.DEVICE;
final String brand = Build.BRAND;
final String product = Build.PRODUCT;
final int debug = BuildConfig.DEBUG ? 1 : 0;
return String.format(Locale.ROOT, "TwitterAndroid/%s (%s) %s/%d (%s;%s;%s;%s;%d)",
versionName, internalVersionName, model, sdkInt, manufacturer, device, brand,
product, debug);
}
case TWITTER_FOR_IPHONE: {
return "Twitter-iPhone";
@ -358,7 +384,7 @@ public class TwitterAPIFactory implements TwidereConstants {
return "Twitter-Mac";
}
case TWEETDECK: {
return "TweetDeck";
return UserAgentUtils.getDefaultUserAgentStringSafe(context);
}
}
return "Twitter";
@ -367,10 +393,10 @@ public class TwitterAPIFactory implements TwidereConstants {
public static String getTwidereUserAgent(final Context context) {
final PackageManager pm = context.getPackageManager();
try {
final PackageInfo pi = pm.getPackageInfo(TWIDERE_PACKAGE_NAME, 0);
return TWIDERE_APP_NAME + " " + TWIDERE_PROJECT_URL + " / " + pi.versionName;
final PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
return String.format("%s %s / %s", TWIDERE_APP_NAME, TWIDERE_PROJECT_URL, pi.versionName);
} catch (final PackageManager.NameNotFoundException e) {
return TWIDERE_APP_NAME + " " + TWIDERE_PROJECT_URL;
throw new AssertionError(e);
}
}

View File

@ -22,7 +22,11 @@ package org.mariotaku.twidere.util;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import android.webkit.WebSettings;
import android.webkit.WebView;
@ -33,8 +37,10 @@ import java.lang.reflect.Constructor;
*/
public class UserAgentUtils {
// You may uncomment next line if using Android Annotations library, otherwise just be sure to run it in on the UI thread
@UiThread
public static String getDefaultUserAgentString(Context context) {
if (Looper.myLooper() != Looper.getMainLooper()) throw new IllegalStateException();
if (Looper.myLooper() != Looper.getMainLooper())
throw new IllegalStateException("User-Agent cannot be fetched from worker thread");
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return NewApiWrapper.getDefaultUserAgent(context);
@ -62,8 +68,49 @@ public class UserAgentUtils {
}
}
@WorkerThread
@Nullable
public static String getDefaultUserAgentStringSafe(Context context) {
final Handler handler = new Handler(Looper.getMainLooper());
final FetchUserAgentRunnable runnable = new FetchUserAgentRunnable(context);
handler.post(runnable);
runnable.waitForExecution();
try {
return runnable.getUserAgent();
} finally {
handler.removeCallbacksAndMessages(null);
}
}
private static class FetchUserAgentRunnable implements Runnable {
private final Context context;
private String userAgent;
private boolean userAgentSet;
public FetchUserAgentRunnable(Context context) {
this.context = context;
}
@Override
public void run() {
userAgent = getDefaultUserAgentString(context);
userAgentSet = true;
}
public String getUserAgent() {
return userAgent;
}
public void waitForExecution() {
//noinspection StatementWithEmptyBody
while (!userAgentSet) ;
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
static class NewApiWrapper {
@UiThread
static String getDefaultUserAgent(Context context) {
return WebSettings.getDefaultUserAgent(context);
}

View File

@ -92,19 +92,15 @@ public class TwidereDns implements Constants, Dns {
return cachedHostAddr;
}
}
// Then I'll try to load from custom host mapping.
// Stupid way to find top domain, but really fast.
if (mHostMapping.contains(host)) {
final String mappedAddr = mHostMapping.getString(host, null);
if (mappedAddr != null) {
final InetAddress[] hostAddr = fromAddressString(originalHost, mappedAddr);
putCache(originalHost, hostAddr);
if (BuildConfig.DEBUG) {
Log.v(RESOLVER_LOGTAG, "Got mapped " + Arrays.toString(hostAddr));
}
if (hostAddr != null) {
return hostAddr;
}
final String customMappedHost = findHost(host);
if (customMappedHost != null) {
final InetAddress[] hostAddr = fromAddressString(originalHost, customMappedHost);
putCache(originalHost, hostAddr);
if (BuildConfig.DEBUG && Log.isLoggable(RESOLVER_LOGTAG, Log.VERBOSE)) {
Log.v(RESOLVER_LOGTAG, "Got mapped address " + customMappedHost + " for host " + host);
}
if (hostAddr != null) {
return hostAddr;
}
}
try {
@ -117,55 +113,12 @@ public class TwidereDns implements Constants, Dns {
} catch (UnknownHostException e) {
// Ignore
}
final String customMappedHost = findHost(host);
if (customMappedHost != null) {
final InetAddress[] hostAddr = fromAddressString(originalHost, customMappedHost);
putCache(originalHost, hostAddr);
if (BuildConfig.DEBUG && Log.isLoggable(RESOLVER_LOGTAG, Log.VERBOSE)) {
Log.v(RESOLVER_LOGTAG, "Got mapped address " + customMappedHost + " for host " + host);
}
if (hostAddr != null) {
return hostAddr;
}
}
// Use TCP DNS Query if enabled.
final Resolver dns = getResolver();
if (dns != null && mPreferences.getBoolean(KEY_TCP_DNS_QUERY, false)) {
final Lookup lookup = new Lookup(new Name(host), Type.A, DClass.IN);
final Record[] records;
lookup.setResolver(dns);
lookup.run();
final int result = lookup.getResult();
if (result != Lookup.SUCCESSFUL) {
throw new UnknownHostException("Unable to resolve " + host + ", " + lookup.getErrorString());
}
records = lookup.getAnswers();
final ArrayList<InetAddress> resolvedAddresses = new ArrayList<>();
// Test each IP address resolved.
for (final Record record : records) {
if (record instanceof ARecord) {
final InetAddress ipv4Addr = ((ARecord) record).getAddress();
resolvedAddresses.add(InetAddress.getByAddress(originalHost, ipv4Addr.getAddress()));
} else if (record instanceof AAAARecord) {
final InetAddress ipv6Addr = ((AAAARecord) record).getAddress();
resolvedAddresses.add(InetAddress.getByAddress(originalHost, ipv6Addr.getAddress()));
}
}
if (!resolvedAddresses.isEmpty()) {
final InetAddress[] hostAddr = resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
putCache(originalHost, hostAddr);
if (BuildConfig.DEBUG && Log.isLoggable(RESOLVER_LOGTAG, Log.VERBOSE)) {
Log.v(RESOLVER_LOGTAG, "Resolved " + Arrays.toString(hostAddr));
}
return hostAddr;
}
// No address is reachable, but I believe the IP is correct.
for (final Record record : records) {
if (record instanceof CNAMERecord)
return resolveInternal(originalHost, ((CNAMERecord) record).getTarget().toString());
}
}
// final Resolver dns = getResolver();
// if (dns != null && mPreferences.getBoolean(KEY_TCP_DNS_QUERY, false)) {
// final InetAddress[] hostAddr = resolveDns(originalHost, host, dns);
// if (hostAddr != null) return hostAddr;
// }
if (BuildConfig.DEBUG && Log.isLoggable(RESOLVER_LOGTAG, Log.VERBOSE)) {
Log.v(RESOLVER_LOGTAG, "Resolve address " + host + " failed, using original host");
}
@ -174,6 +127,44 @@ public class TwidereDns implements Constants, Dns {
return defaultAddresses;
}
private InetAddress[] resolveDns(String originalHost, String host, Resolver dns) throws IOException {
final Lookup lookup = new Lookup(new Name(host), Type.A, DClass.IN);
final Record[] records;
lookup.setResolver(dns);
lookup.run();
final int result = lookup.getResult();
if (result != Lookup.SUCCESSFUL) {
throw new UnknownHostException("Unable to resolve " + host + ", " + lookup.getErrorString());
}
records = lookup.getAnswers();
final ArrayList<InetAddress> resolvedAddresses = new ArrayList<>();
// Test each IP address resolved.
for (final Record record : records) {
if (record instanceof ARecord) {
final InetAddress ipv4Addr = ((ARecord) record).getAddress();
resolvedAddresses.add(InetAddress.getByAddress(originalHost, ipv4Addr.getAddress()));
} else if (record instanceof AAAARecord) {
final InetAddress ipv6Addr = ((AAAARecord) record).getAddress();
resolvedAddresses.add(InetAddress.getByAddress(originalHost, ipv6Addr.getAddress()));
}
}
if (!resolvedAddresses.isEmpty()) {
final InetAddress[] hostAddr = resolvedAddresses.toArray(new InetAddress[resolvedAddresses.size()]);
putCache(originalHost, hostAddr);
if (BuildConfig.DEBUG && Log.isLoggable(RESOLVER_LOGTAG, Log.VERBOSE)) {
Log.v(RESOLVER_LOGTAG, "Resolved " + Arrays.toString(hostAddr));
}
return hostAddr;
}
// No address is reachable, but I believe the IP is correct.
for (final Record record : records) {
if (record instanceof CNAMERecord)
return resolveInternal(originalHost, ((CNAMERecord) record).getTarget().toString());
}
return null;
}
private void putCache(String host, InetAddress[] addresses) {
if (ArrayUtils.isEmpty(addresses) || ArrayUtils.contains(addresses, null)) return;
mHostCache.put(host, addresses);
@ -194,9 +185,7 @@ public class TwidereDns implements Constants, Dns {
private Resolver getResolver() throws IOException {
if (mDns != null) return mDns;
mDns = new SimpleResolver(mDnsAddress);
mDns.setTCP(mPreferences.getBoolean(KEY_TCP_DNS_QUERY, false));
return mDns;
return mDns = new SimpleResolver(mDnsAddress);
}
private static boolean hostMatches(final String host, final String rule) {