NekoX/TMessagesProj/src/main/java/org/telegram/messenger/AndroidUtilities.java

2684 lines
109 KiB
Java
Raw Normal View History

/*
2019-01-23 18:03:33 +01:00
* This is the source code of Telegram for Android v. 5.x.x.
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
2019-01-23 18:03:33 +01:00
* Copyright Nikolai Kudashov, 2013-2018.
*/
2015-09-24 22:52:02 +02:00
package org.telegram.messenger;
import android.animation.Animator;
2017-03-31 01:58:05 +02:00
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
2015-05-21 23:27:27 +02:00
import android.annotation.SuppressLint;
import android.app.Activity;
2018-07-30 04:07:02 +02:00
import android.content.ContentResolver;
2015-05-21 23:27:27 +02:00
import android.content.ContentUris;
import android.content.Context;
2015-05-21 23:27:27 +02:00
import android.content.Intent;
2018-08-27 10:33:11 +02:00
import android.content.IntentFilter;
2017-07-08 18:32:04 +02:00
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
2015-10-29 18:10:07 +01:00
import android.content.pm.PackageManager;
2018-07-30 04:07:02 +02:00
import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
2015-05-21 23:27:27 +02:00
import android.database.Cursor;
2016-04-22 15:49:00 +02:00
import android.graphics.Bitmap;
2015-04-09 20:00:14 +02:00
import android.graphics.Color;
2016-10-11 13:57:01 +02:00
import android.graphics.Matrix;
2016-05-25 23:49:47 +02:00
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
2016-05-25 23:49:47 +02:00
import android.graphics.RectF;
import android.graphics.Typeface;
2016-04-22 15:49:00 +02:00
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
2014-11-17 03:44:57 +01:00
import android.graphics.drawable.Drawable;
2015-05-21 23:27:27 +02:00
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
2019-01-23 18:03:33 +01:00
import android.os.PowerManager;
2015-05-21 23:27:27 +02:00
import android.provider.DocumentsContract;
import android.provider.MediaStore;
2018-07-30 04:07:02 +02:00
import android.provider.Settings;
2019-05-14 14:08:05 +02:00
import androidx.core.content.FileProvider;
import androidx.viewpager.widget.ViewPager;
2017-03-31 01:58:05 +02:00
import android.telephony.TelephonyManager;
2018-07-30 04:07:02 +02:00
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
2019-01-23 18:03:33 +01:00
import android.text.SpannedString;
2017-03-31 01:58:05 +02:00
import android.text.TextUtils;
2018-07-30 04:07:02 +02:00
import android.text.method.LinkMovementMethod;
2015-04-09 20:00:14 +02:00
import android.text.style.ForegroundColorSpan;
import android.util.DisplayMetrics;
2014-11-17 03:44:57 +01:00
import android.util.StateSet;
2018-07-30 04:07:02 +02:00
import android.util.TypedValue;
import android.view.Display;
2018-07-30 04:07:02 +02:00
import android.view.MotionEvent;
import android.view.Gravity;
import android.view.Surface;
import android.view.View;
2018-07-30 04:07:02 +02:00
import android.view.ViewGroup;
import android.view.WindowManager;
2019-05-14 14:08:05 +02:00
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
2018-07-30 04:07:02 +02:00
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.inputmethod.InputMethodManager;
2019-05-14 14:08:05 +02:00
import android.view.inputmethod.InputMethodSubtype;
import android.webkit.MimeTypeMap;
2014-11-11 23:16:17 +01:00
import android.widget.EdgeEffect;
2019-01-23 18:03:33 +01:00
import android.widget.HorizontalScrollView;
2018-07-30 04:07:02 +02:00
import android.widget.LinearLayout;
2014-11-11 23:16:17 +01:00
import android.widget.ListView;
2017-03-31 01:58:05 +02:00
import android.widget.ScrollView;
2018-07-30 04:07:02 +02:00
import android.widget.TextView;
2017-03-31 01:58:05 +02:00
import com.android.internal.telephony.ITelephony;
2019-01-23 18:03:33 +01:00
import com.google.android.gms.auth.api.phone.SmsRetriever;
import com.google.android.gms.auth.api.phone.SmsRetrieverClient;
import com.google.android.gms.tasks.Task;
2017-03-31 01:58:05 +02:00
2015-05-21 23:27:27 +02:00
import net.hockeyapp.android.CrashManager;
import net.hockeyapp.android.CrashManagerListener;
import net.hockeyapp.android.UpdateManager;
2017-03-31 01:58:05 +02:00
import org.telegram.PhoneFormat.PhoneFormat;
2015-09-24 22:52:02 +02:00
import org.telegram.tgnet.ConnectionsManager;
2017-03-31 01:58:05 +02:00
import org.telegram.tgnet.TLObject;
2015-09-24 22:52:02 +02:00
import org.telegram.tgnet.TLRPC;
2017-03-31 01:58:05 +02:00
import org.telegram.ui.ActionBar.AlertDialog;
2016-04-22 15:49:00 +02:00
import org.telegram.ui.ActionBar.BaseFragment;
2018-07-30 04:07:02 +02:00
import org.telegram.ui.ActionBar.BottomSheet;
2017-03-31 01:58:05 +02:00
import org.telegram.ui.ActionBar.Theme;
2018-07-30 04:07:02 +02:00
import org.telegram.ui.Cells.TextDetailSettingsCell;
import org.telegram.ui.Components.ForegroundDetector;
2018-07-30 04:07:02 +02:00
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.PickerBottomLayout;
import org.telegram.ui.Components.TypefaceSpan;
2019-01-23 18:03:33 +01:00
import org.telegram.ui.ThemePreviewActivity;
2019-02-08 03:30:32 +01:00
import org.telegram.ui.WallpapersListActivity;
2018-07-30 04:07:02 +02:00
import java.io.BufferedReader;
2015-05-21 23:27:27 +02:00
import java.io.ByteArrayOutputStream;
import java.io.File;
2015-05-21 23:27:27 +02:00
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
2018-07-30 04:07:02 +02:00
import java.io.InputStreamReader;
2015-05-21 23:27:27 +02:00
import java.io.OutputStream;
2014-10-21 22:35:16 +02:00
import java.lang.reflect.Field;
2014-11-07 11:23:17 +01:00
import java.lang.reflect.Method;
2015-05-21 23:27:27 +02:00
import java.text.SimpleDateFormat;
import java.util.ArrayList;
2018-07-30 04:07:02 +02:00
import java.util.Calendar;
2015-05-21 23:27:27 +02:00
import java.util.Date;
import java.util.Hashtable;
2019-01-23 18:03:33 +01:00
import java.util.List;
2015-05-21 23:27:27 +02:00
import java.util.Locale;
2015-11-26 22:04:02 +01:00
import java.util.regex.Pattern;
public class AndroidUtilities {
2014-10-11 13:30:32 +02:00
2015-01-02 23:15:07 +01:00
private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<>();
private static int prevOrientation = -10;
private static boolean waitingForSms = false;
2016-03-16 13:26:32 +01:00
private static boolean waitingForCall = false;
private static final Object smsLock = new Object();
2016-03-16 13:26:32 +01:00
private static final Object callLock = new Object();
public static int statusBarHeight = 0;
2019-05-14 14:08:05 +02:00
public static boolean firstConfigurationWas;
public static float density = 1;
public static Point displaySize = new Point();
2017-07-08 18:32:04 +02:00
public static int roundMessageSize;
2016-10-11 13:57:01 +02:00
public static boolean incorrectDisplaySizeFix;
public static Integer photoSize = null;
public static DisplayMetrics displayMetrics = new DisplayMetrics();
2015-03-26 18:34:47 +01:00
public static int leftBaseline;
public static boolean usingHardwareInput;
2016-10-11 13:57:01 +02:00
public static boolean isInMultiwindow;
2017-03-31 01:58:05 +02:00
public static DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
2018-07-30 04:07:02 +02:00
public static AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator();
public static OvershootInterpolator overshootInterpolator = new OvershootInterpolator();
2014-09-24 17:08:25 +02:00
private static Boolean isTablet = null;
2015-09-24 22:52:02 +02:00
private static int adjustOwnerClassGuid = 0;
2016-05-25 23:49:47 +02:00
private static Paint roundPaint;
private static RectF bitmapRect;
2015-11-26 22:04:02 +01:00
public static Pattern WEB_URL = null;
2019-01-23 18:03:33 +01:00
2015-11-26 22:04:02 +01:00
static {
try {
final String GOOD_IRI_CHAR = "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
final Pattern IP_ADDRESS = Pattern.compile(
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9]))");
final String IRI = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
final String GOOD_GTLD_CHAR = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
WEB_URL = Pattern.compile(
"((?:(http|https|Http|Https):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "(?:" + DOMAIN_NAME + ")"
+ "(?:\\:\\d{1,5})?)" // plus option port number
+ "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ "(?:\\b|$)");
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-11-26 22:04:02 +01:00
}
}
static {
2015-03-26 18:34:47 +01:00
leftBaseline = isTablet() ? 80 : 72;
2016-10-11 13:57:01 +02:00
checkDisplaySize(ApplicationLoader.applicationContext, null);
}
2019-05-14 14:08:05 +02:00
private static int[] documentIcons = {
2019-01-23 18:03:33 +01:00
R.drawable.media_doc_blue,
R.drawable.media_doc_green,
R.drawable.media_doc_red,
R.drawable.media_doc_yellow
};
2019-05-14 14:08:05 +02:00
private static int[] documentMediaIcons = {
2019-01-23 18:03:33 +01:00
R.drawable.media_doc_blue_b,
R.drawable.media_doc_green_b,
R.drawable.media_doc_red_b,
R.drawable.media_doc_yellow_b
};
public static int getThumbForNameOrMime(String name, String mime, boolean media) {
if (name != null && name.length() != 0) {
int color = -1;
if (name.contains(".doc") || name.contains(".txt") || name.contains(".psd")) {
color = 0;
} else if (name.contains(".xls") || name.contains(".csv")) {
color = 1;
} else if (name.contains(".pdf") || name.contains(".ppt") || name.contains(".key")) {
color = 2;
} else if (name.contains(".zip") || name.contains(".rar") || name.contains(".ai") || name.contains(".mp3") || name.contains(".mov") || name.contains(".avi")) {
color = 3;
}
if (color == -1) {
int idx;
String ext = (idx = name.lastIndexOf('.')) == -1 ? "" : name.substring(idx + 1);
if (ext.length() != 0) {
color = ext.charAt(0) % documentIcons.length;
} else {
color = name.charAt(0) % documentIcons.length;
}
}
return media ? documentMediaIcons[color] : documentIcons[color];
}
return media ? documentMediaIcons[0] : documentIcons[0];
}
2016-04-22 15:49:00 +02:00
public static int[] calcDrawableColor(Drawable drawable) {
int bitmapColor = 0xff000000;
2019-05-14 14:08:05 +02:00
int[] result = new int[4];
2016-04-22 15:49:00 +02:00
try {
if (drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap != null) {
Bitmap b = Bitmaps.createScaledBitmap(bitmap, 1, 1, true);
if (b != null) {
bitmapColor = b.getPixel(0, 0);
2017-03-31 01:58:05 +02:00
if (bitmap != b) {
b.recycle();
}
2016-04-22 15:49:00 +02:00
}
}
} else if (drawable instanceof ColorDrawable) {
bitmapColor = ((ColorDrawable) drawable).getColor();
2016-04-22 15:49:00 +02:00
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2016-04-22 15:49:00 +02:00
}
double[] hsv = rgbToHsv((bitmapColor >> 16) & 0xff, (bitmapColor >> 8) & 0xff, bitmapColor & 0xff);
hsv[1] = Math.min(1.0, hsv[1] + 0.05 + 0.1 * (1.0 - hsv[1]));
2019-01-23 18:03:33 +01:00
double v = Math.max(0, hsv[2] * 0.65);
2019-05-14 14:08:05 +02:00
int[] rgb = hsvToRgb(hsv[0], hsv[1], v);
2016-04-22 15:49:00 +02:00
result[0] = Color.argb(0x66, rgb[0], rgb[1], rgb[2]);
result[1] = Color.argb(0x88, rgb[0], rgb[1], rgb[2]);
2019-01-23 18:03:33 +01:00
double v2 = Math.max(0, hsv[2] * 0.72);
rgb = hsvToRgb(hsv[0], hsv[1], v2);
result[2] = Color.argb(0x66, rgb[0], rgb[1], rgb[2]);
result[3] = Color.argb(0x88, rgb[0], rgb[1], rgb[2]);
2016-04-22 15:49:00 +02:00
return result;
}
private static double[] rgbToHsv(int r, int g, int b) {
double rf = r / 255.0;
double gf = g / 255.0;
double bf = b / 255.0;
double max = (rf > gf && rf > bf) ? rf : (gf > bf) ? gf : bf;
double min = (rf < gf && rf < bf) ? rf : (gf < bf) ? gf : bf;
double h, s;
double d = max - min;
s = max == 0 ? 0 : d / max;
if (max == min) {
h = 0;
} else {
if (rf > gf && rf > bf) {
h = (gf - bf) / d + (gf < bf ? 6 : 0);
} else if (gf > bf) {
h = (bf - rf) / d + 2;
} else {
h = (rf - gf) / d + 4;
}
h /= 6;
}
return new double[]{h, s, max};
}
private static int[] hsvToRgb(double h, double s, double v) {
double r = 0, g = 0, b = 0;
double i = (int) Math.floor(h * 6);
double f = h * 6 - i;
double p = v * (1 - s);
double q = v * (1 - f * s);
double t = v * (1 - (1 - f) * s);
switch ((int) i % 6) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
return new int[]{(int) (r * 255), (int) (g * 255), (int) (b * 255)};
}
2015-09-24 22:52:02 +02:00
public static void requestAdjustResize(Activity activity, int classGuid) {
if (activity == null || isTablet()) {
return;
}
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
adjustOwnerClassGuid = classGuid;
}
2019-05-14 14:08:05 +02:00
public static void setAdjustResizeToNothing(Activity activity, int classGuid) {
if (activity == null || isTablet()) {
return;
}
if (adjustOwnerClassGuid == classGuid) {
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
}
}
2015-09-24 22:52:02 +02:00
public static void removeAdjustResize(Activity activity, int classGuid) {
if (activity == null || isTablet()) {
return;
}
if (adjustOwnerClassGuid == classGuid) {
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
}
}
2016-04-22 15:49:00 +02:00
public static boolean isGoogleMapsInstalled(final BaseFragment fragment) {
try {
ApplicationLoader.applicationContext.getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
if (fragment.getParentActivity() == null) {
return false;
}
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity());
2019-01-23 18:03:33 +01:00
builder.setMessage(LocaleController.getString("InstallGoogleMaps", R.string.InstallGoogleMaps));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), (dialogInterface, i) -> {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.apps.maps"));
fragment.getParentActivity().startActivityForResult(intent, 500);
} catch (Exception e1) {
FileLog.e(e1);
2016-04-22 15:49:00 +02:00
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
fragment.showDialog(builder.create());
return false;
}
}
2019-01-23 18:03:33 +01:00
public static int[] toIntArray(List<Integer> integers) {
int[] ret = new int[integers.size()];
for (int i = 0; i < ret.length; i++) {
ret[i] = integers.get(i);
}
return ret;
}
2016-05-25 23:49:47 +02:00
public static boolean isInternalUri(Uri uri) {
String pathString = uri.getPath();
if (pathString == null) {
return false;
}
2019-01-23 18:03:33 +01:00
// Allow sending VoIP logs from cache/voip_logs
if (pathString.matches(Pattern.quote(new File(ApplicationLoader.applicationContext.getCacheDir(), "voip_logs").getAbsolutePath()) + "/\\d+\\.log")) {
return false;
}
2019-02-08 03:30:32 +01:00
int tries = 0;
2016-05-25 23:49:47 +02:00
while (true) {
2019-02-08 03:30:32 +01:00
if (pathString != null && pathString.length() > 4096) {
return true;
}
2016-05-25 23:49:47 +02:00
String newPath = Utilities.readlink(pathString);
if (newPath == null || newPath.equals(pathString)) {
break;
}
pathString = newPath;
2019-02-08 03:30:32 +01:00
tries++;
if (tries >= 10) {
return true;
}
2016-05-25 23:49:47 +02:00
}
2016-10-11 13:57:01 +02:00
if (pathString != null) {
try {
String path = new File(pathString).getCanonicalPath();
if (path != null) {
pathString = path;
}
} catch (Exception e) {
pathString.replace("/./", "/");
//igonre
}
}
2019-01-23 18:03:33 +01:00
return pathString != null && pathString.toLowerCase().contains("/data/data/" + ApplicationLoader.applicationContext.getPackageName());
2016-05-25 23:49:47 +02:00
}
2019-05-14 14:08:05 +02:00
@SuppressLint("WrongConstant")
public static void lockOrientation(Activity activity) {
2016-04-22 15:49:00 +02:00
if (activity == null || prevOrientation != -10) {
return;
}
try {
prevOrientation = activity.getRequestedOrientation();
2017-03-31 01:58:05 +02:00
WindowManager manager = (WindowManager) activity.getSystemService(Activity.WINDOW_SERVICE);
if (manager != null && manager.getDefaultDisplay() != null) {
int rotation = manager.getDefaultDisplay().getRotation();
int orientation = activity.getResources().getConfiguration().orientation;
if (rotation == Surface.ROTATION_270) {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
2016-04-22 15:49:00 +02:00
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
} else if (rotation == Surface.ROTATION_90) {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
2016-04-22 15:49:00 +02:00
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
} else if (rotation == Surface.ROTATION_0) {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
} else {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
2016-04-22 15:49:00 +02:00
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
} else {
2016-04-22 15:49:00 +02:00
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}
}
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
}
2019-05-14 14:08:05 +02:00
@SuppressLint("WrongConstant")
public static void unlockOrientation(Activity activity) {
2016-04-22 15:49:00 +02:00
if (activity == null) {
return;
}
try {
if (prevOrientation != -10) {
activity.setRequestedOrientation(prevOrientation);
prevOrientation = -10;
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
}
2018-07-30 04:07:02 +02:00
private static class VcardData {
String name;
ArrayList<String> phones = new ArrayList<>();
StringBuilder vcard = new StringBuilder();
}
public static class VcardItem {
public ArrayList<String> vcardData = new ArrayList<>();
public String fullData = "";
public int type;
public boolean checked = true;
public String[] getRawValue() {
int idx = fullData.indexOf(':');
if (idx < 0) {
return new String[0];
}
String valueType = fullData.substring(0, idx);
2019-05-14 14:08:05 +02:00
String value = fullData.substring(idx + 1);
2018-07-30 04:07:02 +02:00
String nameEncoding = null;
String nameCharset = "UTF-8";
String[] params = valueType.split(";");
for (int a = 0; a < params.length; a++) {
String[] args2 = params[a].split("=");
if (args2.length != 2) {
continue;
}
if (args2[0].equals("CHARSET")) {
nameCharset = args2[1];
} else if (args2[0].equals("ENCODING")) {
nameEncoding = args2[1];
}
}
String[] args = value.split(";");
boolean added = false;
for (int a = 0; a < args.length; a++) {
if (TextUtils.isEmpty(args[a])) {
continue;
}
if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
byte[] bytes = decodeQuotedPrintable(getStringBytes(args[a]));
if (bytes != null && bytes.length != 0) {
try {
args[a] = new String(bytes, nameCharset);
} catch (Exception ignore) {
}
}
}
}
return args;
}
public String getValue(boolean format) {
StringBuilder result = new StringBuilder();
int idx = fullData.indexOf(':');
if (idx < 0) {
return "";
}
if (result.length() > 0) {
result.append(", ");
}
String valueType = fullData.substring(0, idx);
2019-05-14 14:08:05 +02:00
String value = fullData.substring(idx + 1);
2018-07-30 04:07:02 +02:00
String nameEncoding = null;
String nameCharset = "UTF-8";
String[] params = valueType.split(";");
for (int a = 0; a < params.length; a++) {
String[] args2 = params[a].split("=");
if (args2.length != 2) {
continue;
}
if (args2[0].equals("CHARSET")) {
nameCharset = args2[1];
} else if (args2[0].equals("ENCODING")) {
nameEncoding = args2[1];
}
}
String[] args = value.split(";");
boolean added = false;
for (int a = 0; a < args.length; a++) {
if (TextUtils.isEmpty(args[a])) {
continue;
}
if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
byte[] bytes = decodeQuotedPrintable(getStringBytes(args[a]));
if (bytes != null && bytes.length != 0) {
try {
args[a] = new String(bytes, nameCharset);
} catch (Exception ignore) {
}
}
}
if (added && result.length() > 0) {
result.append(" ");
}
result.append(args[a]);
if (!added) {
added = args[a].length() > 0;
}
}
if (format) {
if (type == 0) {
return PhoneFormat.getInstance().format(result.toString());
} else if (type == 5) {
String[] date = result.toString().split("T");
if (date.length > 0) {
date = date[0].split("-");
if (date.length == 3) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Utilities.parseInt(date[0]));
calendar.set(Calendar.MONTH, Utilities.parseInt(date[1]) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Utilities.parseInt(date[2]));
return LocaleController.getInstance().formatterYearMax.format(calendar.getTime());
}
}
}
}
return result.toString();
}
public String getRawType(boolean first) {
int idx = fullData.indexOf(':');
if (idx < 0) {
return "";
}
String value = fullData.substring(0, idx);
if (type == 20) {
value = value.substring(2);
2019-05-14 14:08:05 +02:00
String[] args = value.split(";");
2018-07-30 04:07:02 +02:00
if (first) {
value = args[0];
} else if (args.length > 1) {
value = args[args.length - 1];
} else {
value = "";
}
} else {
2019-05-14 14:08:05 +02:00
String[] args = value.split(";");
2018-07-30 04:07:02 +02:00
for (int a = 0; a < args.length; a++) {
if (args[a].indexOf('=') >= 0) {
continue;
}
value = args[a];
}
return value;
}
return value;
}
public String getType() {
if (type == 5) {
return LocaleController.getString("ContactBirthday", R.string.ContactBirthday);
} else if (type == 6) {
if ("ORG".equalsIgnoreCase(getRawType(true))) {
return LocaleController.getString("ContactJob", R.string.ContactJob);
} else {
return LocaleController.getString("ContactJobTitle", R.string.ContactJobTitle);
}
}
int idx = fullData.indexOf(':');
if (idx < 0) {
return "";
}
String value = fullData.substring(0, idx);
if (type == 20) {
value = value.substring(2);
2019-05-14 14:08:05 +02:00
String[] args = value.split(";");
2018-07-30 04:07:02 +02:00
value = args[0];
} else {
2019-05-14 14:08:05 +02:00
String[] args = value.split(";");
2018-07-30 04:07:02 +02:00
for (int a = 0; a < args.length; a++) {
if (args[a].indexOf('=') >= 0) {
continue;
}
value = args[a];
}
if (value.startsWith("X-")) {
value = value.substring(2);
}
2019-05-14 14:08:05 +02:00
switch (value) {
case "PREF":
value = LocaleController.getString("PhoneMain", R.string.PhoneMain);
break;
case "HOME":
value = LocaleController.getString("PhoneHome", R.string.PhoneHome);
break;
case "MOBILE":
case "CELL":
value = LocaleController.getString("PhoneMobile", R.string.PhoneMobile);
break;
case "OTHER":
value = LocaleController.getString("PhoneOther", R.string.PhoneOther);
break;
case "WORK":
value = LocaleController.getString("PhoneWork", R.string.PhoneWork);
break;
}
}
value = value.substring(0, 1).toUpperCase() + value.substring(1).toLowerCase();
2018-07-30 04:07:02 +02:00
return value;
}
}
public static byte[] getStringBytes(String src) {
try {
return src.getBytes("UTF-8");
} catch (Exception ignore) {
}
return new byte[0];
}
public static ArrayList<TLRPC.User> loadVCardFromStream(Uri uri, int currentAccount, boolean asset, ArrayList<VcardItem> items, String name) {
ArrayList<TLRPC.User> result = null;
try {
InputStream stream;
if (asset) {
AssetFileDescriptor fd = ApplicationLoader.applicationContext.getContentResolver().openAssetFileDescriptor(uri, "r");
stream = fd.createInputStream();
} else {
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
stream = cr.openInputStream(uri);
}
ArrayList<VcardData> vcardDatas = new ArrayList<>();
VcardData currentData = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
String line;
String originalLine;
String pendingLine = null;
boolean currentIsPhoto = false;
VcardItem currentItem = null;
while ((originalLine = line = bufferedReader.readLine()) != null) {
if (originalLine.startsWith("PHOTO")) {
currentIsPhoto = true;
continue;
} else {
if (originalLine.indexOf(':') >= 0) {
currentItem = null;
currentIsPhoto = false;
if (originalLine.startsWith("BEGIN:VCARD")) {
vcardDatas.add(currentData = new VcardData());
currentData.name = name;
} else if (originalLine.startsWith("END:VCARD")) {
} else if (items != null) {
if (originalLine.startsWith("TEL")) {
currentItem = new VcardItem();
currentItem.type = 0;
} else if (originalLine.startsWith("EMAIL")) {
currentItem = new VcardItem();
currentItem.type = 1;
} else if (originalLine.startsWith("ADR") || originalLine.startsWith("LABEL") || originalLine.startsWith("GEO")) {
currentItem = new VcardItem();
currentItem.type = 2;
} else if (originalLine.startsWith("URL")) {
currentItem = new VcardItem();
currentItem.type = 3;
} else if (originalLine.startsWith("NOTE")) {
currentItem = new VcardItem();
currentItem.type = 4;
} else if (originalLine.startsWith("BDAY")) {
currentItem = new VcardItem();
currentItem.type = 5;
} else if (originalLine.startsWith("ORG") || originalLine.startsWith("TITLE") || originalLine.startsWith("ROLE")) {
if (currentItem == null) {
currentItem = new VcardItem();
currentItem.type = 6;
}
} else if (originalLine.startsWith("X-ANDROID")) {
currentItem = new VcardItem();
currentItem.type = -1;
} else if (originalLine.startsWith("X-PHONETIC")) {
currentItem = null;
} else if (originalLine.startsWith("X-")) {
currentItem = new VcardItem();
currentItem.type = 20;
}
if (currentItem != null && currentItem.type >= 0) {
items.add(currentItem);
}
}
}
}
if (!currentIsPhoto && currentData != null) {
if (currentItem == null) {
if (currentData.vcard.length() > 0) {
currentData.vcard.append('\n');
}
currentData.vcard.append(originalLine);
} else {
currentItem.vcardData.add(originalLine);
}
}
if (pendingLine != null) {
pendingLine += line;
line = pendingLine;
pendingLine = null;
}
if (line.contains("=QUOTED-PRINTABLE") && line.endsWith("=")) {
pendingLine = line.substring(0, line.length() - 1);
continue;
}
if (!currentIsPhoto && currentData != null && currentItem != null) {
currentItem.fullData = line;
}
int idx = line.indexOf(":");
String[] args;
if (idx >= 0) {
args = new String[]{
line.substring(0, idx),
2019-05-14 14:08:05 +02:00
line.substring(idx + 1).trim()
2018-07-30 04:07:02 +02:00
};
} else {
args = new String[]{line.trim()};
}
if (args.length < 2 || currentData == null) {
continue;
}
if (args[0].startsWith("FN") || args[0].startsWith("ORG") && TextUtils.isEmpty(currentData.name)) {
String nameEncoding = null;
String nameCharset = null;
String[] params = args[0].split(";");
for (String param : params) {
String[] args2 = param.split("=");
if (args2.length != 2) {
continue;
}
if (args2[0].equals("CHARSET")) {
nameCharset = args2[1];
} else if (args2[0].equals("ENCODING")) {
nameEncoding = args2[1];
}
}
currentData.name = args[1];
if (nameEncoding != null && nameEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
byte[] bytes = decodeQuotedPrintable(getStringBytes(currentData.name));
if (bytes != null && bytes.length != 0) {
String decodedName = new String(bytes, nameCharset);
if (decodedName != null) {
currentData.name = decodedName;
}
}
}
} else if (args[0].startsWith("TEL")) {
currentData.phones.add(args[1]);
}
}
try {
bufferedReader.close();
stream.close();
} catch (Exception e) {
FileLog.e(e);
}
for (int a = 0; a < vcardDatas.size(); a++) {
VcardData vcardData = vcardDatas.get(a);
if (vcardData.name != null && !vcardData.phones.isEmpty()) {
if (result == null) {
result = new ArrayList<>();
}
String phoneToUse = vcardData.phones.get(0);
for (int b = 0; b < vcardData.phones.size(); b++) {
String phone = vcardData.phones.get(b);
String sphone = phone.substring(Math.max(0, phone.length() - 7));
if (ContactsController.getInstance(currentAccount).contactsByShortPhone.get(sphone) != null) {
phoneToUse = phone;
break;
}
}
TLRPC.User user = new TLRPC.TL_userContact_old2();
user.phone = phoneToUse;
user.first_name = vcardData.name;
user.last_name = "";
user.id = 0;
user.restriction_reason = vcardData.vcard.toString();
result.add(user);
}
}
} catch (Throwable e) {
FileLog.e(e);
}
return result;
}
public static Typeface getTypeface(String assetPath) {
synchronized (typefaceCache) {
if (!typefaceCache.containsKey(assetPath)) {
try {
2018-07-30 04:07:02 +02:00
Typeface t;
if (Build.VERSION.SDK_INT >= 26) {
Typeface.Builder builder = new Typeface.Builder(ApplicationLoader.applicationContext.getAssets(), assetPath);
if (assetPath.contains("medium")) {
builder.setWeight(700);
}
if (assetPath.contains("italic")) {
builder.setItalic(true);
}
t = builder.build();
} else {
t = Typeface.createFromAsset(ApplicationLoader.applicationContext.getAssets(), assetPath);
}
typefaceCache.put(assetPath, t);
} catch (Exception e) {
2018-07-30 04:07:02 +02:00
if (BuildVars.LOGS_ENABLED) {
FileLog.e("Could not get typeface '" + assetPath + "' because " + e.getMessage());
}
return null;
}
}
return typefaceCache.get(assetPath);
}
}
public static boolean isWaitingForSms() {
2015-05-21 23:27:27 +02:00
boolean value;
synchronized (smsLock) {
value = waitingForSms;
}
return value;
}
public static void setWaitingForSms(boolean value) {
synchronized (smsLock) {
waitingForSms = value;
2019-01-23 18:03:33 +01:00
try {
if (waitingForSms) {
SmsRetrieverClient client = SmsRetriever.getClient(ApplicationLoader.applicationContext);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(aVoid -> {
if (BuildVars.DEBUG_VERSION) {
FileLog.d("sms listener registered");
}
});
}
} catch (Throwable e) {
FileLog.e(e);
}
}
}
2019-05-14 14:08:05 +02:00
public static int getShadowHeight() {
if (density >= 4.0f) {
return 3;
} else if (density >= 2.0f) {
return 2;
} else {
return 1;
}
}
2016-03-16 13:26:32 +01:00
public static boolean isWaitingForCall() {
boolean value;
synchronized (callLock) {
value = waitingForCall;
}
return value;
}
2018-08-27 10:33:11 +02:00
private static CallReceiver callReceiver;
2016-03-16 13:26:32 +01:00
public static void setWaitingForCall(boolean value) {
synchronized (callLock) {
2018-08-27 10:33:11 +02:00
try {
if (value) {
if (callReceiver == null) {
final IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
ApplicationLoader.applicationContext.registerReceiver(callReceiver = new CallReceiver(), filter);
}
} else {
if (callReceiver != null) {
ApplicationLoader.applicationContext.unregisterReceiver(callReceiver);
callReceiver = null;
}
}
} catch (Exception ignore) {
}
2016-03-16 13:26:32 +01:00
waitingForCall = value;
}
}
2019-01-23 18:03:33 +01:00
public static boolean showKeyboard(View view) {
if (view == null) {
2019-01-23 18:03:33 +01:00
return false;
}
2016-05-25 23:49:47 +02:00
try {
2017-03-31 01:58:05 +02:00
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
2019-01-23 18:03:33 +01:00
return inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
2016-05-25 23:49:47 +02:00
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2016-05-25 23:49:47 +02:00
}
2019-01-23 18:03:33 +01:00
return false;
}
public static boolean isKeyboardShowed(View view) {
if (view == null) {
return false;
}
2016-05-25 23:49:47 +02:00
try {
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return inputManager.isActive(view);
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2016-05-25 23:49:47 +02:00
}
return false;
}
2019-05-14 14:08:05 +02:00
public static String[] getCurrentKeyboardLanguage() {
try {
InputMethodManager inputManager = (InputMethodManager) ApplicationLoader.applicationContext.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodSubtype inputMethodSubtype = inputManager.getCurrentInputMethodSubtype();
String locale = null;
if (inputMethodSubtype != null) {
if (Build.VERSION.SDK_INT >= 24) {
locale = inputMethodSubtype.getLanguageTag();
}
if (TextUtils.isEmpty(locale)) {
locale = inputMethodSubtype.getLocale();
}
} else {
inputMethodSubtype = inputManager.getLastInputMethodSubtype();
if (inputMethodSubtype != null) {
if (Build.VERSION.SDK_INT >= 24) {
locale = inputMethodSubtype.getLanguageTag();
}
if (TextUtils.isEmpty(locale)) {
locale = inputMethodSubtype.getLocale();
}
}
}
if (TextUtils.isEmpty(locale)) {
locale = LocaleController.getSystemLocaleStringIso639();
String locale2;
LocaleController.LocaleInfo localeInfo = LocaleController.getInstance().getCurrentLocaleInfo();
locale2 = localeInfo.getBaseLangCode();
if (TextUtils.isEmpty(locale2)) {
locale2 = localeInfo.getLangCode();
}
if (locale.contains(locale2) || locale2.contains(locale)) {
if (!locale.contains("en")) {
locale2 = "en";
} else {
locale2 = null;
}
}
if (!TextUtils.isEmpty(locale2)) {
return new String[]{locale.replace('_', '-'), locale2};
} else {
return new String[]{locale.replace('_', '-')};
}
} else {
return new String[]{locale.replace('_', '-')};
}
} catch (Exception ignore) {
}
return new String[]{"en"};
}
public static void hideKeyboard(View view) {
if (view == null) {
return;
}
2016-05-25 23:49:47 +02:00
try {
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (!imm.isActive()) {
return;
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
}
public static File getCacheDir() {
2015-01-02 23:15:07 +01:00
String state = null;
try {
state = Environment.getExternalStorageState();
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-01-02 23:15:07 +01:00
}
if (state == null || state.startsWith(Environment.MEDIA_MOUNTED)) {
2014-07-20 01:31:49 +02:00
try {
File file = ApplicationLoader.applicationContext.getExternalCacheDir();
if (file != null) {
return file;
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
}
2014-07-20 01:31:49 +02:00
try {
File file = ApplicationLoader.applicationContext.getCacheDir();
if (file != null) {
return file;
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
return new File("");
}
public static int dp(float value) {
if (value == 0) {
return 0;
}
2015-10-29 18:10:07 +01:00
return (int) Math.ceil(density * value);
}
2019-05-14 14:08:05 +02:00
public static int dpr(float value) {
if (value == 0) {
return 0;
}
return Math.round(density * value);
}
2017-03-31 01:58:05 +02:00
public static int dp2(float value) {
if (value == 0) {
return 0;
}
return (int) Math.floor(density * value);
}
public static int compare(int lhs, int rhs) {
if (lhs == rhs) {
return 0;
} else if (lhs > rhs) {
return 1;
}
return -1;
}
2014-10-14 22:36:15 +02:00
public static float dpf2(float value) {
if (value == 0) {
return 0;
}
2014-10-14 22:36:15 +02:00
return density * value;
}
2016-10-11 13:57:01 +02:00
public static void checkDisplaySize(Context context, Configuration newConfiguration) {
try {
2019-05-14 14:08:05 +02:00
int oldDensity = (int) density;
2016-10-11 13:57:01 +02:00
density = context.getResources().getDisplayMetrics().density;
2019-05-14 14:08:05 +02:00
int newDensity = (int) density;
if (firstConfigurationWas && oldDensity != newDensity) {
Theme.reloadAllResources(context);
}
firstConfigurationWas = true;
2016-10-11 13:57:01 +02:00
Configuration configuration = newConfiguration;
if (configuration == null) {
configuration = context.getResources().getConfiguration();
}
usingHardwareInput = configuration.keyboard != Configuration.KEYBOARD_NOKEYS && configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
2016-10-11 13:57:01 +02:00
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (manager != null) {
Display display = manager.getDefaultDisplay();
if (display != null) {
display.getMetrics(displayMetrics);
display.getSize(displaySize);
}
}
2016-10-11 13:57:01 +02:00
if (configuration.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
int newSize = (int) Math.ceil(configuration.screenWidthDp * density);
if (Math.abs(displaySize.x - newSize) > 3) {
displaySize.x = newSize;
}
}
if (configuration.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
int newSize = (int) Math.ceil(configuration.screenHeightDp * density);
if (Math.abs(displaySize.y - newSize) > 3) {
displaySize.y = newSize;
}
}
2017-07-08 18:32:04 +02:00
if (roundMessageSize == 0) {
if (AndroidUtilities.isTablet()) {
roundMessageSize = (int) (AndroidUtilities.getMinTabletSide() * 0.6f);
} else {
roundMessageSize = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.6f);
}
}
2018-07-30 04:07:02 +02:00
if (BuildVars.LOGS_ENABLED) {
FileLog.e("display size = " + displaySize.x + " " + displaySize.y + " " + displayMetrics.xdpi + "x" + displayMetrics.ydpi);
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
}
2018-07-30 04:07:02 +02:00
public static double fixLocationCoord(double value) {
return ((long) (value * 1000000)) / 1000000.0;
}
public static String formapMapUrl(int account, double lat, double lon, int width, int height, boolean marker, int zoom) {
int scale = Math.min(2, (int) Math.ceil(AndroidUtilities.density));
int provider = MessagesController.getInstance(account).mapProvider;
if (provider == 1 || provider == 3) {
String lang = null;
String[] availableLangs = new String[]{"ru_RU", "tr_TR"};
LocaleController.LocaleInfo localeInfo = LocaleController.getInstance().getCurrentLocaleInfo();
for (int a = 0; a < availableLangs.length; a++) {
if (availableLangs[a].toLowerCase().contains(localeInfo.shortName)) {
lang = availableLangs[a];
}
}
if (lang == null) {
lang = "en_US";
}
if (marker) {
return String.format(Locale.US, "https://static-maps.yandex.ru/1.x/?ll=%.6f,%.6f&z=%d&size=%d,%d&l=map&scale=%d&pt=%.6f,%.6f,vkbkm&lang=%s", lon, lat, zoom, width * scale, height * scale, scale, lon, lat, lang);
} else {
return String.format(Locale.US, "https://static-maps.yandex.ru/1.x/?ll=%.6f,%.6f&z=%d&size=%d,%d&l=map&scale=%d&lang=%s", lon, lat, zoom, width * scale, height * scale, scale, lang);
}
} else {
String k = MessagesController.getInstance(account).mapKey;
if (!TextUtils.isEmpty(k)) {
if (marker) {
return String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&maptype=roadmap&scale=%d&markers=color:red%%7Csize:mid%%7C%.6f,%.6f&sensor=false&key=%s", lat, lon, zoom, width, height, scale, lat, lon, k);
} else {
return String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&maptype=roadmap&scale=%d&key=%s", lat, lon, zoom, width, height, scale, k);
}
} else {
if (marker) {
return String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&maptype=roadmap&scale=%d&markers=color:red%%7Csize:mid%%7C%.6f,%.6f&sensor=false", lat, lon, zoom, width, height, scale, lat, lon);
} else {
return String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&maptype=roadmap&scale=%d", lat, lon, zoom, width, height, scale);
}
}
}
}
public static float getPixelsInCM(float cm, boolean isX) {
return (cm / 2.54f) * (isX ? displayMetrics.xdpi : displayMetrics.ydpi);
}
public static long makeBroadcastId(int id) {
2019-01-23 18:03:33 +01:00
return 0x0000000100000000L | ((long) id & 0x00000000FFFFFFFFL);
}
2014-10-14 10:13:16 +02:00
public static int getMyLayerVersion(int layer) {
return layer & 0xffff;
}
public static int getPeerLayerVersion(int layer) {
return (layer >> 16) & 0xffff;
}
public static int setMyLayerVersion(int layer, int version) {
return layer & 0xffff0000 | version;
}
public static int setPeerLayerVersion(int layer, int version) {
return layer & 0x0000ffff | (version << 16);
}
public static void runOnUIThread(Runnable runnable) {
runOnUIThread(runnable, 0);
2014-10-01 21:55:24 +02:00
}
public static void runOnUIThread(Runnable runnable, long delay) {
2014-10-01 21:55:24 +02:00
if (delay == 0) {
ApplicationLoader.applicationHandler.post(runnable);
} else {
ApplicationLoader.applicationHandler.postDelayed(runnable, delay);
}
}
public static void cancelRunOnUIThread(Runnable runnable) {
ApplicationLoader.applicationHandler.removeCallbacks(runnable);
}
public static boolean isTablet() {
2014-09-24 17:08:25 +02:00
if (isTablet == null) {
isTablet = ApplicationLoader.applicationContext.getResources().getBoolean(R.bool.isTablet);
}
return isTablet;
}
public static boolean isSmallTablet() {
float minSide = Math.min(displaySize.x, displaySize.y) / density;
return minSide <= 700;
}
public static int getMinTabletSide() {
if (!isSmallTablet()) {
int smallSide = Math.min(displaySize.x, displaySize.y);
int leftSide = smallSide * 35 / 100;
if (leftSide < dp(320)) {
leftSide = dp(320);
}
return smallSide - leftSide;
} else {
int smallSide = Math.min(displaySize.x, displaySize.y);
int maxSide = Math.max(displaySize.x, displaySize.y);
int leftSide = maxSide * 35 / 100;
if (leftSide < dp(320)) {
leftSide = dp(320);
}
return Math.min(smallSide, maxSide - leftSide);
}
}
public static int getPhotoSize() {
if (photoSize == null) {
photoSize = 1280;
}
return photoSize;
}
2014-10-14 22:36:15 +02:00
2017-12-08 18:35:59 +01:00
/*public static void clearCursorDrawable(EditText editText) {
if (editText == null) {
2014-10-21 22:35:16 +02:00
return;
}
try {
Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
mCursorDrawableRes.setAccessible(true);
mCursorDrawableRes.setInt(editText, 0);
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-10-21 22:35:16 +02:00
}
2017-12-08 18:35:59 +01:00
}*/
2017-03-31 01:58:05 +02:00
private static boolean hasCallPermissions = Build.VERSION.SDK_INT >= 23;
@SuppressWarnings("unchecked")
public static void endIncomingCall() {
if (!hasCallPermissions) {
return;
}
try {
2017-03-31 01:58:05 +02:00
TelephonyManager tm = (TelephonyManager) ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
ITelephony telephonyService = (ITelephony) m.invoke(tm);
telephonyService = (ITelephony) m.invoke(tm);
telephonyService.silenceRinger();
telephonyService.endCall();
} catch (Exception e) {
2018-07-30 04:07:02 +02:00
FileLog.e(e);
}
}
2017-03-31 01:58:05 +02:00
public static boolean checkPhonePattern(String pattern, String phone) {
if (TextUtils.isEmpty(pattern) || pattern.equals("*")) {
return true;
}
2019-05-14 14:08:05 +02:00
String[] args = pattern.split("\\*");
2017-03-31 01:58:05 +02:00
phone = PhoneFormat.stripExceptNumbers(phone);
int checkStart = 0;
int index;
for (int a = 0; a < args.length; a++) {
String arg = args[a];
if (!TextUtils.isEmpty(arg)) {
if ((index = phone.indexOf(arg, checkStart)) == -1) {
return false;
}
checkStart = index + arg.length();
}
}
return true;
}
2016-10-11 13:57:01 +02:00
private static Field mAttachInfoField;
private static Field mStableInsetsField;
2019-01-23 18:03:33 +01:00
public static int getViewInset(View view) {
2015-12-09 19:27:52 +01:00
if (view == null || Build.VERSION.SDK_INT < 21 || view.getHeight() == AndroidUtilities.displaySize.y || view.getHeight() == AndroidUtilities.displaySize.y - statusBarHeight) {
return 0;
}
try {
2016-10-11 13:57:01 +02:00
if (mAttachInfoField == null) {
mAttachInfoField = View.class.getDeclaredField("mAttachInfo");
mAttachInfoField.setAccessible(true);
}
Object mAttachInfo = mAttachInfoField.get(view);
if (mAttachInfo != null) {
2016-10-11 13:57:01 +02:00
if (mStableInsetsField == null) {
mStableInsetsField = mAttachInfo.getClass().getDeclaredField("mStableInsets");
mStableInsetsField.setAccessible(true);
}
Rect insets = (Rect) mStableInsetsField.get(mAttachInfo);
return insets.bottom;
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
return 0;
}
2014-11-07 11:23:17 +01:00
public static Point getRealScreenSize() {
Point size = new Point();
try {
WindowManager windowManager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
windowManager.getDefaultDisplay().getRealSize(size);
} else {
try {
Method mGetRawW = Display.class.getMethod("getRawWidth");
Method mGetRawH = Display.class.getMethod("getRawHeight");
size.set((Integer) mGetRawW.invoke(windowManager.getDefaultDisplay()), (Integer) mGetRawH.invoke(windowManager.getDefaultDisplay()));
} catch (Exception e) {
size.set(windowManager.getDefaultDisplay().getWidth(), windowManager.getDefaultDisplay().getHeight());
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-11-07 11:23:17 +01:00
}
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-11-07 11:23:17 +01:00
}
return size;
}
2014-11-11 23:16:17 +01:00
2018-07-30 04:07:02 +02:00
public static void setEnabled(View view, boolean enabled) {
if (view == null) {
return;
}
view.setEnabled(enabled);
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
setEnabled(viewGroup.getChildAt(i), enabled);
}
}
}
public static CharSequence getTrimmedString(CharSequence src) {
if (src == null || src.length() == 0) {
return src;
}
while (src.length() > 0 && (src.charAt(0) == '\n' || src.charAt(0) == ' ')) {
src = src.subSequence(1, src.length());
}
while (src.length() > 0 && (src.charAt(src.length() - 1) == '\n' || src.charAt(src.length() - 1) == ' ')) {
src = src.subSequence(0, src.length() - 1);
}
return src;
}
2017-03-31 01:58:05 +02:00
public static void setViewPagerEdgeEffectColor(ViewPager viewPager, int color) {
2014-11-11 23:16:17 +01:00
if (Build.VERSION.SDK_INT >= 21) {
try {
2017-03-31 01:58:05 +02:00
Field field = ViewPager.class.getDeclaredField("mLeftEdge");
2019-05-14 14:08:05 +02:00
field.setAccessible(true);
EdgeEffect mLeftEdge = (EdgeEffect) field.get(viewPager);
2017-03-31 01:58:05 +02:00
if (mLeftEdge != null) {
2019-05-14 14:08:05 +02:00
mLeftEdge.setColor(color);
2017-03-31 01:58:05 +02:00
}
field = ViewPager.class.getDeclaredField("mRightEdge");
field.setAccessible(true);
2019-05-14 14:08:05 +02:00
EdgeEffect mRightEdge = (EdgeEffect) field.get(viewPager);
2017-03-31 01:58:05 +02:00
if (mRightEdge != null) {
2019-05-14 14:08:05 +02:00
mRightEdge.setColor(color);
2017-03-31 01:58:05 +02:00
}
2019-01-23 18:03:33 +01:00
} catch (Exception ignore) {
}
}
}
public static void setScrollViewEdgeEffectColor(HorizontalScrollView scrollView, int color) {
if (Build.VERSION.SDK_INT >= 21) {
try {
Field field = HorizontalScrollView.class.getDeclaredField("mEdgeGlowLeft");
field.setAccessible(true);
EdgeEffect mEdgeGlowTop = (EdgeEffect) field.get(scrollView);
if (mEdgeGlowTop != null) {
mEdgeGlowTop.setColor(color);
}
field = HorizontalScrollView.class.getDeclaredField("mEdgeGlowRight");
field.setAccessible(true);
EdgeEffect mEdgeGlowBottom = (EdgeEffect) field.get(scrollView);
if (mEdgeGlowBottom != null) {
mEdgeGlowBottom.setColor(color);
}
2017-03-31 01:58:05 +02:00
} catch (Exception e) {
FileLog.e(e);
}
}
}
public static void setScrollViewEdgeEffectColor(ScrollView scrollView, int color) {
if (Build.VERSION.SDK_INT >= 21) {
try {
Field field = ScrollView.class.getDeclaredField("mEdgeGlowTop");
field.setAccessible(true);
EdgeEffect mEdgeGlowTop = (EdgeEffect) field.get(scrollView);
2014-11-11 23:16:17 +01:00
if (mEdgeGlowTop != null) {
mEdgeGlowTop.setColor(color);
}
2017-03-31 01:58:05 +02:00
field = ScrollView.class.getDeclaredField("mEdgeGlowBottom");
2014-11-11 23:16:17 +01:00
field.setAccessible(true);
2017-03-31 01:58:05 +02:00
EdgeEffect mEdgeGlowBottom = (EdgeEffect) field.get(scrollView);
2014-11-11 23:16:17 +01:00
if (mEdgeGlowBottom != null) {
mEdgeGlowBottom.setColor(color);
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2014-11-11 23:16:17 +01:00
}
}
}
2014-11-17 03:44:57 +01:00
2015-05-21 23:27:27 +02:00
@SuppressLint("NewApi")
2014-11-17 03:44:57 +01:00
public static void clearDrawableAnimation(View view) {
if (Build.VERSION.SDK_INT < 21 || view == null) {
return;
}
2015-05-21 23:27:27 +02:00
Drawable drawable;
2014-11-17 03:44:57 +01:00
if (view instanceof ListView) {
drawable = ((ListView) view).getSelector();
if (drawable != null) {
drawable.setState(StateSet.NOTHING);
}
} else {
drawable = view.getBackground();
if (drawable != null) {
drawable.setState(StateSet.NOTHING);
drawable.jumpToCurrentState();
}
}
}
2015-06-29 19:12:11 +02:00
public static final int FLAG_TAG_BR = 1;
public static final int FLAG_TAG_BOLD = 2;
public static final int FLAG_TAG_COLOR = 4;
2018-07-30 04:07:02 +02:00
public static final int FLAG_TAG_URL = 8;
public static final int FLAG_TAG_ALL = FLAG_TAG_BR | FLAG_TAG_BOLD | FLAG_TAG_URL;
2015-06-29 19:12:11 +02:00
2016-04-22 15:49:00 +02:00
public static SpannableStringBuilder replaceTags(String str) {
2015-06-29 19:12:11 +02:00
return replaceTags(str, FLAG_TAG_ALL);
}
2018-07-30 04:07:02 +02:00
public static SpannableStringBuilder replaceTags(String str, int flag, Object... args) {
2015-04-09 20:00:14 +02:00
try {
2015-05-21 23:27:27 +02:00
int start;
int end;
2015-04-09 20:00:14 +02:00
StringBuilder stringBuilder = new StringBuilder(str);
2015-06-29 19:12:11 +02:00
if ((flag & FLAG_TAG_BR) != 0) {
while ((start = stringBuilder.indexOf("<br>")) != -1) {
stringBuilder.replace(start, start + 4, "\n");
}
while ((start = stringBuilder.indexOf("<br/>")) != -1) {
stringBuilder.replace(start, start + 5, "\n");
}
2015-04-09 20:00:14 +02:00
}
ArrayList<Integer> bolds = new ArrayList<>();
2015-06-29 19:12:11 +02:00
if ((flag & FLAG_TAG_BOLD) != 0) {
while ((start = stringBuilder.indexOf("<b>")) != -1) {
2015-04-09 20:00:14 +02:00
stringBuilder.replace(start, start + 3, "");
end = stringBuilder.indexOf("</b>");
if (end == -1) {
end = stringBuilder.indexOf("<b>");
}
2015-04-09 20:00:14 +02:00
stringBuilder.replace(end, end + 4, "");
bolds.add(start);
bolds.add(end);
2015-06-29 19:12:11 +02:00
}
2017-12-08 18:35:59 +01:00
while ((start = stringBuilder.indexOf("**")) != -1) {
stringBuilder.replace(start, start + 2, "");
end = stringBuilder.indexOf("**");
if (end >= 0) {
stringBuilder.replace(end, end + 2, "");
bolds.add(start);
bolds.add(end);
}
}
2015-06-29 19:12:11 +02:00
}
2018-07-30 04:07:02 +02:00
if ((flag & FLAG_TAG_URL) != 0) {
while ((start = stringBuilder.indexOf("**")) != -1) {
stringBuilder.replace(start, start + 2, "");
end = stringBuilder.indexOf("**");
if (end >= 0) {
stringBuilder.replace(end, end + 2, "");
bolds.add(start);
bolds.add(end);
}
}
}
2015-04-09 20:00:14 +02:00
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(stringBuilder);
for (int a = 0; a < bolds.size() / 2; a++) {
spannableStringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), bolds.get(a * 2), bolds.get(a * 2 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spannableStringBuilder;
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
}
2015-04-09 20:00:14 +02:00
return new SpannableStringBuilder(str);
}
2018-07-30 04:07:02 +02:00
public static class LinkMovementMethodMy extends LinkMovementMethod {
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
try {
boolean result = super.onTouchEvent(widget, buffer, event);
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
Selection.removeSelection(buffer);
}
return result;
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
}
public static boolean needShowPasscode(boolean reset) {
boolean wasInBackground = ForegroundDetector.getInstance().isWasInBackground(reset);
if (reset) {
ForegroundDetector.getInstance().resetBackgroundVar();
}
2018-07-30 04:07:02 +02:00
return SharedConfig.passcodeHash.length() > 0 && wasInBackground &&
(SharedConfig.appLocked || SharedConfig.autoLockIn != 0 && SharedConfig.lastPauseTime != 0 && !SharedConfig.appLocked &&
(SharedConfig.lastPauseTime + SharedConfig.autoLockIn) <= ConnectionsManager.getInstance(UserConfig.selectedAccount).getCurrentTime() || ConnectionsManager.getInstance(UserConfig.selectedAccount).getCurrentTime() + 5 < SharedConfig.lastPauseTime);
}
2015-02-27 20:57:58 +01:00
2015-09-24 22:52:02 +02:00
public static void shakeView(final View view, final float x, final int num) {
2018-07-30 04:07:02 +02:00
if (view == null) {
return;
}
2015-04-09 20:00:14 +02:00
if (num == 6) {
view.setTranslationX(0);
2015-04-09 20:00:14 +02:00
return;
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(ObjectAnimator.ofFloat(view, "translationX", AndroidUtilities.dp(x)));
animatorSet.setDuration(50);
2017-03-31 01:58:05 +02:00
animatorSet.addListener(new AnimatorListenerAdapter() {
2015-04-09 20:00:14 +02:00
@Override
public void onAnimationEnd(Animator animation) {
2015-09-24 22:52:02 +02:00
shakeView(view, num == 5 ? 0 : -x, num + 1);
2015-04-09 20:00:14 +02:00
}
});
animatorSet.start();
2015-04-09 20:00:14 +02:00
}
/*public static String ellipsize(String text, int maxLines, int maxWidth, TextPaint paint) {
if (text == null || paint == null) {
return null;
}
int count;
int offset = 0;
StringBuilder result = null;
TextView
for (int a = 0; a < maxLines; a++) {
count = paint.breakText(text, true, maxWidth, null);
if (a != maxLines - 1) {
if (result == null) {
result = new StringBuilder(count * maxLines + 1);
}
boolean foundSpace = false;
for (int c = count - 1; c >= offset; c--) {
if (text.charAt(c) == ' ') {
foundSpace = true;
result.append(text.substring(offset, c - 1));
offset = c - 1;
}
}
if (!foundSpace) {
offset = count;
}
text = text.substring(0, offset);
} else if (maxLines == 1) {
return text.substring(0, count);
} else {
result.append(text.substring(0, count));
}
}
return result.toString();
}*/
2015-02-27 20:57:58 +01:00
/*public static void turnOffHardwareAcceleration(Window window) {
if (window == null || Build.MODEL == null) {
2015-02-27 20:57:58 +01:00
return;
}
if (Build.MODEL.contains("GT-S5301") ||
Build.MODEL.contains("GT-S5303") ||
Build.MODEL.contains("GT-B5330") ||
Build.MODEL.contains("GT-S5302") ||
Build.MODEL.contains("GT-S6012B") ||
Build.MODEL.contains("MegaFon_SP-AI")) {
window.clearFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
}*/
2015-05-21 23:27:27 +02:00
public static void checkForCrashes(Activity context) {
2019-06-04 12:14:50 +02:00
try {
CrashManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() {
@Override
public boolean includeDeviceData() {
return true;
}
});
} catch (Throwable e) {
FileLog.e(e);
}
2015-05-21 23:27:27 +02:00
}
public static void checkForUpdates(Activity context) {
if (BuildVars.DEBUG_VERSION) {
2015-11-26 22:04:02 +01:00
UpdateManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH);
2015-05-21 23:27:27 +02:00
}
}
public static void unregisterUpdates() {
if (BuildVars.DEBUG_VERSION) {
UpdateManager.unregister();
}
}
2016-05-25 23:49:47 +02:00
public static void addToClipboard(CharSequence str) {
try {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("label", str);
clipboard.setPrimaryClip(clip);
2016-05-25 23:49:47 +02:00
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2016-05-25 23:49:47 +02:00
}
}
2015-05-21 23:27:27 +02:00
public static void addMediaToGallery(String fromPath) {
if (fromPath == null) {
return;
}
File f = new File(fromPath);
Uri contentUri = Uri.fromFile(f);
addMediaToGallery(contentUri);
}
public static void addMediaToGallery(Uri uri) {
if (uri == null) {
return;
}
2015-10-29 18:10:07 +01:00
try {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(uri);
ApplicationLoader.applicationContext.sendBroadcast(mediaScanIntent);
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-10-29 18:10:07 +01:00
}
2015-05-21 23:27:27 +02:00
}
2019-01-23 18:03:33 +01:00
private static File getAlbumDir(boolean secretChat) {
if (secretChat || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
2018-07-30 04:07:02 +02:00
return FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE);
2015-10-29 18:10:07 +01:00
}
2015-05-21 23:27:27 +02:00
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Telegram");
if (!storageDir.mkdirs()) {
2019-01-23 18:03:33 +01:00
if (!storageDir.exists()) {
2018-07-30 04:07:02 +02:00
if (BuildVars.LOGS_ENABLED) {
FileLog.d("failed to create directory");
}
2015-05-21 23:27:27 +02:00
return null;
}
}
} else {
2018-07-30 04:07:02 +02:00
if (BuildVars.LOGS_ENABLED) {
FileLog.d("External storage is not mounted READ/WRITE.");
}
2015-05-21 23:27:27 +02:00
}
return storageDir;
}
@SuppressLint("NewApi")
public static String getPath(final Uri uri) {
try {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && DocumentsContract.isDocumentUri(ApplicationLoader.applicationContext, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(ApplicationLoader.applicationContext, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
switch (type) {
case "image":
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
break;
case "video":
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
break;
case "audio":
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
break;
}
final String selection = "_id=?";
2019-01-23 18:03:33 +01:00
final String[] selectionArgs = new String[]{
2015-05-21 23:27:27 +02:00
split[1]
};
return getDataColumn(ApplicationLoader.applicationContext, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(ApplicationLoader.applicationContext, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-05-21 23:27:27 +02:00
}
return null;
}
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
final String column = "_data";
final String[] projection = {
column
};
2019-05-14 14:08:05 +02:00
try (Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null)) {
2015-05-21 23:27:27 +02:00
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
2016-03-16 13:26:32 +01:00
String value = cursor.getString(column_index);
if (value.startsWith("content://") || !value.startsWith("/") && !value.startsWith("file://")) {
return null;
}
return value;
2015-05-21 23:27:27 +02:00
}
2017-12-08 18:35:59 +01:00
} catch (Exception ignore) {
2015-05-21 23:27:27 +02:00
}
return null;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static File generatePicturePath() {
2019-01-23 18:03:33 +01:00
return generatePicturePath(false);
}
public static File generatePicturePath(boolean secretChat) {
2015-05-21 23:27:27 +02:00
try {
2019-01-23 18:03:33 +01:00
File storageDir = getAlbumDir(secretChat);
2017-12-08 18:35:59 +01:00
Date date = new Date();
date.setTime(System.currentTimeMillis() + Utilities.random.nextInt(1000) + 1);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US).format(date);
2015-05-21 23:27:27 +02:00
return new File(storageDir, "IMG_" + timeStamp + ".jpg");
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-05-21 23:27:27 +02:00
}
return null;
}
public static CharSequence generateSearchName(String name, String name2, String q) {
if (name == null && name2 == null) {
return "";
}
SpannableStringBuilder builder = new SpannableStringBuilder();
String wholeString = name;
if (wholeString == null || wholeString.length() == 0) {
wholeString = name2;
} else if (name2 != null && name2.length() != 0) {
wholeString += " " + name2;
}
wholeString = wholeString.trim();
String lower = " " + wholeString.toLowerCase();
int index;
int lastIndex = 0;
while ((index = lower.indexOf(" " + q, lastIndex)) != -1) {
int idx = index - (index == 0 ? 0 : 1);
int end = q.length() + (index == 0 ? 0 : 1) + idx;
if (lastIndex != 0 && lastIndex != idx + 1) {
builder.append(wholeString.substring(lastIndex, idx));
} else if (lastIndex == 0 && idx != 0) {
builder.append(wholeString.substring(0, idx));
}
2017-03-31 01:58:05 +02:00
String query = wholeString.substring(idx, Math.min(wholeString.length(), end));
2015-05-21 23:27:27 +02:00
if (query.startsWith(" ")) {
builder.append(" ");
}
query = query.trim();
2017-03-31 01:58:05 +02:00
int start = builder.length();
builder.append(query);
builder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4)), start, start + query.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
2015-05-21 23:27:27 +02:00
lastIndex = end;
}
2017-12-08 18:35:59 +01:00
if (lastIndex != -1 && lastIndex < wholeString.length()) {
2019-05-14 14:08:05 +02:00
builder.append(wholeString.substring(lastIndex));
2015-05-21 23:27:27 +02:00
}
return builder;
}
2019-01-23 18:03:33 +01:00
public static boolean isAirplaneModeOn() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
return Settings.System.getInt(ApplicationLoader.applicationContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0;
} else {
return Settings.Global.getInt(ApplicationLoader.applicationContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}
}
2015-05-21 23:27:27 +02:00
public static File generateVideoPath() {
2019-01-23 18:03:33 +01:00
return generateVideoPath(false);
}
public static File generateVideoPath(boolean secretChat) {
2015-05-21 23:27:27 +02:00
try {
2019-01-23 18:03:33 +01:00
File storageDir = getAlbumDir(secretChat);
2017-12-08 18:35:59 +01:00
Date date = new Date();
date.setTime(System.currentTimeMillis() + Utilities.random.nextInt(1000) + 1);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US).format(date);
2015-05-21 23:27:27 +02:00
return new File(storageDir, "VID_" + timeStamp + ".mp4");
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-05-21 23:27:27 +02:00
}
return null;
}
public static String formatFileSize(long size) {
2019-03-03 21:40:48 +01:00
return formatFileSize(size, false);
}
public static String formatFileSize(long size, boolean removeZero) {
2015-05-21 23:27:27 +02:00
if (size < 1024) {
return String.format("%d B", size);
} else if (size < 1024 * 1024) {
2019-03-03 21:40:48 +01:00
float value = size / 1024.0f;
if (removeZero && (value - (int) value) * 10 == 0) {
return String.format("%d KB", (int) value);
} else {
return String.format("%.1f KB", value);
}
2015-05-21 23:27:27 +02:00
} else if (size < 1024 * 1024 * 1024) {
2019-03-03 21:40:48 +01:00
float value = size / 1024.0f / 1024.0f;
if (removeZero && (value - (int) value) * 10 == 0) {
return String.format("%d MB", (int) value);
} else {
return String.format("%.1f MB", value);
}
2015-05-21 23:27:27 +02:00
} else {
2019-03-03 21:40:48 +01:00
float value = size / 1024.0f / 1024.0f / 1024.0f;
if (removeZero && (value - (int) value) * 10 == 0) {
return String.format("%d GB", (int) value);
} else {
return String.format("%.1f GB", value);
}
2015-05-21 23:27:27 +02:00
}
}
public static byte[] decodeQuotedPrintable(final byte[] bytes) {
if (bytes == null) {
return null;
}
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; i++) {
final int b = bytes[i];
if (b == '=') {
try {
final int u = Character.digit((char) bytes[++i], 16);
final int l = Character.digit((char) bytes[++i], 16);
buffer.write((char) ((u << 4) + l));
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-05-21 23:27:27 +02:00
return null;
}
} else {
buffer.write(b);
}
}
byte[] array = buffer.toByteArray();
try {
buffer.close();
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-05-21 23:27:27 +02:00
}
return array;
}
public static boolean copyFile(InputStream sourceFile, File destFile) throws IOException {
OutputStream out = new FileOutputStream(destFile);
byte[] buf = new byte[4096];
int len;
while ((len = sourceFile.read(buf)) > 0) {
Thread.yield();
out.write(buf, 0, len);
}
out.close();
return true;
}
public static boolean copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.exists()) {
destFile.createNewFile();
}
2019-05-14 14:08:05 +02:00
try (FileInputStream source = new FileInputStream(sourceFile); FileOutputStream destination = new FileOutputStream(destFile)) {
2015-05-21 23:27:27 +02:00
destination.getChannel().transferFrom(source.getChannel(), 0, source.getChannel().size());
} catch (Exception e) {
2017-03-31 01:58:05 +02:00
FileLog.e(e);
2015-05-21 23:27:27 +02:00
return false;
}
return true;
}
2016-03-06 02:49:31 +01:00
public static byte[] calcAuthKeyHash(byte[] auth_key) {
byte[] sha1 = Utilities.computeSHA1(auth_key);
byte[] key_hash = new byte[16];
System.arraycopy(sha1, 0, key_hash, 0, 16);
return key_hash;
}
2019-01-23 18:03:33 +01:00
public static void openDocument(MessageObject message, Activity activity, BaseFragment parentFragment) {
if (message == null) {
return;
}
TLRPC.Document document = message.getDocument();
if (document == null) {
return;
}
File f = null;
String fileName = message.messageOwner.media != null ? FileLoader.getAttachFileName(document) : "";
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) {
f = new File(message.messageOwner.attachPath);
}
if (f == null || f != null && !f.exists()) {
f = FileLoader.getPathToMessage(message.messageOwner);
}
if (f != null && f.exists()) {
if (parentFragment != null && f.getName().toLowerCase().endsWith("attheme")) {
Theme.ThemeInfo themeInfo = Theme.applyThemeFile(f, message.getDocumentName(), true);
if (themeInfo != null) {
parentFragment.presentFragment(new ThemePreviewActivity(f, themeInfo));
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setMessage(LocaleController.getString("IncorrectTheme", R.string.IncorrectTheme));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
parentFragment.showDialog(builder.create());
}
} else {
String realMimeType = null;
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
MimeTypeMap myMime = MimeTypeMap.getSingleton();
int idx = fileName.lastIndexOf('.');
if (idx != -1) {
String ext = fileName.substring(idx + 1);
realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (realMimeType == null) {
realMimeType = document.mime_type;
if (realMimeType == null || realMimeType.length() == 0) {
realMimeType = null;
}
}
}
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", f), realMimeType != null ? realMimeType : "text/plain");
} else {
intent.setDataAndType(Uri.fromFile(f), realMimeType != null ? realMimeType : "text/plain");
}
if (realMimeType != null) {
try {
activity.startActivityForResult(intent, 500);
} catch (Exception e) {
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", f), "text/plain");
} else {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
}
activity.startActivityForResult(intent, 500);
}
} else {
activity.startActivityForResult(intent, 500);
}
} catch (Exception e) {
if (activity == null) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.setMessage(LocaleController.formatString("NoHandleAppInstalled", R.string.NoHandleAppInstalled, message.getDocument().mime_type));
if (parentFragment != null) {
parentFragment.showDialog(builder.create());
} else {
builder.show();
}
}
}
}
}
public static void openForView(MessageObject message, final Activity activity) {
File f = null;
String fileName = message.getFileName();
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) {
f = new File(message.messageOwner.attachPath);
}
if (f == null || !f.exists()) {
f = FileLoader.getPathToMessage(message.messageOwner);
}
if (f != null && f.exists()) {
String realMimeType = null;
Intent intent = new Intent(Intent.ACTION_VIEW);
2016-10-11 13:57:01 +02:00
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
MimeTypeMap myMime = MimeTypeMap.getSingleton();
int idx = fileName.lastIndexOf('.');
if (idx != -1) {
String ext = fileName.substring(idx + 1);
realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (realMimeType == null) {
if (message.type == 9 || message.type == 0) {
realMimeType = message.getDocument().mime_type;
}
if (realMimeType == null || realMimeType.length() == 0) {
realMimeType = null;
}
}
2016-10-11 13:57:01 +02:00
}
2018-07-30 04:07:02 +02:00
if (Build.VERSION.SDK_INT >= 26 && realMimeType != null && realMimeType.equals("application/vnd.android.package-archive") && !ApplicationLoader.applicationContext.getPackageManager().canRequestPackageInstalls()) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setMessage(LocaleController.getString("ApkRestricted", R.string.ApkRestricted));
2019-01-23 18:03:33 +01:00
builder.setPositiveButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialogInterface, i) -> {
try {
activity.startActivity(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + activity.getPackageName())));
} catch (Exception e) {
FileLog.e(e);
2018-07-30 04:07:02 +02:00
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.show();
return;
}
2016-10-11 13:57:01 +02:00
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", f), realMimeType != null ? realMimeType : "text/plain");
2017-03-31 01:58:05 +02:00
} else {
intent.setDataAndType(Uri.fromFile(f), realMimeType != null ? realMimeType : "text/plain");
}
if (realMimeType != null) {
try {
activity.startActivityForResult(intent, 500);
} catch (Exception e) {
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", f), "text/plain");
} else {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
}
activity.startActivityForResult(intent, 500);
}
} else {
activity.startActivityForResult(intent, 500);
}
}
}
2019-01-23 18:03:33 +01:00
public static void openForView(TLObject media, Activity activity) {
2017-03-31 01:58:05 +02:00
if (media == null || activity == null) {
return;
}
String fileName = FileLoader.getAttachFileName(media);
File f = FileLoader.getPathToAttach(media, true);
if (f != null && f.exists()) {
String realMimeType = null;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
MimeTypeMap myMime = MimeTypeMap.getSingleton();
int idx = fileName.lastIndexOf('.');
if (idx != -1) {
String ext = fileName.substring(idx + 1);
realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (realMimeType == null) {
if (media instanceof TLRPC.TL_document) {
realMimeType = ((TLRPC.TL_document) media).mime_type;
}
if (realMimeType == null || realMimeType.length() == 0) {
realMimeType = null;
}
}
}
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", f), realMimeType != null ? realMimeType : "text/plain");
} else {
2016-10-11 13:57:01 +02:00
intent.setDataAndType(Uri.fromFile(f), realMimeType != null ? realMimeType : "text/plain");
}
if (realMimeType != null) {
try {
activity.startActivityForResult(intent, 500);
} catch (Exception e) {
2016-10-11 13:57:01 +02:00
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", f), "text/plain");
} else {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
}
activity.startActivityForResult(intent, 500);
}
} else {
activity.startActivityForResult(intent, 500);
}
}
}
2016-10-11 13:57:01 +02:00
2019-01-23 18:03:33 +01:00
public static boolean isBannedForever(TLRPC.TL_chatBannedRights rights) {
return rights == null || Math.abs(rights.until_date - System.currentTimeMillis() / 1000) > 5 * 365 * 24 * 60 * 60;
2017-07-08 18:32:04 +02:00
}
2019-03-03 21:40:48 +01:00
public static void setRectToRect(Matrix matrix, RectF src, RectF dst, int rotation, boolean translate) {
2016-10-11 13:57:01 +02:00
float tx, sx;
float ty, sy;
2019-03-03 21:40:48 +01:00
boolean xLarger = false;
2016-10-11 13:57:01 +02:00
if (rotation == 90 || rotation == 270) {
sx = dst.height() / src.width();
sy = dst.width() / src.height();
} else {
sx = dst.width() / src.width();
sy = dst.height() / src.height();
}
2019-03-03 21:40:48 +01:00
if (sx < sy) {
sx = sy;
xLarger = true;
} else {
sy = sx;
2016-10-11 13:57:01 +02:00
}
2019-03-03 21:40:48 +01:00
if (translate) {
matrix.setTranslate(dst.left, dst.top);
}
2016-10-11 13:57:01 +02:00
if (rotation == 90) {
matrix.preRotate(90);
matrix.preTranslate(0, -dst.width());
} else if (rotation == 180) {
matrix.preRotate(180);
matrix.preTranslate(-dst.width(), -dst.height());
} else if (rotation == 270) {
matrix.preRotate(270);
matrix.preTranslate(-dst.height(), 0);
}
2019-03-03 21:40:48 +01:00
if (translate) {
tx = -src.left * sx;
ty = -src.top * sy;
} else {
tx = dst.left - src.left * sx;
ty = dst.top - src.top * sy;
}
float diff;
if (xLarger) {
diff = dst.width() - src.width() * sy;
} else {
diff = dst.height() - src.height() * sy;
}
diff = diff / 2.0f;
if (xLarger) {
tx += diff;
} else {
ty += diff;
}
2016-10-11 13:57:01 +02:00
matrix.preScale(sx, sy);
2019-03-03 21:40:48 +01:00
if (translate) {
matrix.preTranslate(tx, ty);
}
2016-10-11 13:57:01 +02:00
}
2017-07-08 18:32:04 +02:00
public static boolean handleProxyIntent(Activity activity, Intent intent) {
if (intent == null) {
return false;
}
try {
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
return false;
}
Uri data = intent.getData();
if (data != null) {
String user = null;
String password = null;
String port = null;
String address = null;
2018-07-30 04:07:02 +02:00
String secret = null;
2017-07-08 18:32:04 +02:00
String scheme = data.getScheme();
if (scheme != null) {
if ((scheme.equals("http") || scheme.equals("https"))) {
String host = data.getHost().toLowerCase();
2019-01-23 18:03:33 +01:00
if (host.equals("telegram.me") || host.equals("t.me") || host.equals("telegram.dog")) {
2017-07-08 18:32:04 +02:00
String path = data.getPath();
if (path != null) {
2018-07-30 04:07:02 +02:00
if (path.startsWith("/socks") || path.startsWith("/proxy")) {
2017-07-08 18:32:04 +02:00
address = data.getQueryParameter("server");
port = data.getQueryParameter("port");
user = data.getQueryParameter("user");
password = data.getQueryParameter("pass");
2018-07-30 04:07:02 +02:00
secret = data.getQueryParameter("secret");
2017-07-08 18:32:04 +02:00
}
}
}
} else if (scheme.equals("tg")) {
String url = data.toString();
2018-07-30 04:07:02 +02:00
if (url.startsWith("tg:proxy") || url.startsWith("tg://proxy") || url.startsWith("tg:socks") || url.startsWith("tg://socks")) {
url = url.replace("tg:proxy", "tg://telegram.org").replace("tg://proxy", "tg://telegram.org").replace("tg://socks", "tg://telegram.org").replace("tg:socks", "tg://telegram.org");
2017-07-08 18:32:04 +02:00
data = Uri.parse(url);
address = data.getQueryParameter("server");
port = data.getQueryParameter("port");
user = data.getQueryParameter("user");
password = data.getQueryParameter("pass");
2018-07-30 04:07:02 +02:00
secret = data.getQueryParameter("secret");
2017-07-08 18:32:04 +02:00
}
}
}
if (!TextUtils.isEmpty(address) && !TextUtils.isEmpty(port)) {
if (user == null) {
user = "";
}
if (password == null) {
password = "";
}
2018-07-30 04:07:02 +02:00
if (secret == null) {
secret = "";
}
showProxyAlert(activity, address, port, user, password, secret);
2017-07-08 18:32:04 +02:00
return true;
}
}
} catch (Exception ignore) {
}
return false;
}
2019-01-23 18:03:33 +01:00
public static boolean shouldEnableAnimation() {
if (Build.VERSION.SDK_INT < 26 || Build.VERSION.SDK_INT >= 28) {
return true;
}
PowerManager powerManager = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE);
if (powerManager.isPowerSaveMode()) {
return false;
}
float scale = Settings.Global.getFloat(ApplicationLoader.applicationContext.getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f);
if (scale <= 0.0f) {
return false;
}
return true;
}
2018-07-30 04:07:02 +02:00
public static void showProxyAlert(Activity activity, final String address, final String port, final String user, final String password, final String secret) {
BottomSheet.Builder builder = new BottomSheet.Builder(activity);
final Runnable dismissRunnable = builder.getDismissRunnable();
builder.setApplyTopPadding(false);
builder.setApplyBottomPadding(false);
LinearLayout linearLayout = new LinearLayout(activity);
builder.setCustomView(linearLayout);
linearLayout.setOrientation(LinearLayout.VERTICAL);
if (!TextUtils.isEmpty(secret)) {
TextView titleTextView = new TextView(activity);
titleTextView.setText(LocaleController.getString("UseProxyTelegramInfo2", R.string.UseProxyTelegramInfo2));
titleTextView.setTextColor(Theme.getColor(Theme.key_dialogTextGray4));
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
titleTextView.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
linearLayout.addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 17, 8, 17, 8));
View lineView = new View(activity);
lineView.setBackgroundColor(Theme.getColor(Theme.key_divider));
linearLayout.addView(lineView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
}
for (int a = 0; a < 5; a++) {
String text = null;
String detail = null;
if (a == 0) {
text = address;
detail = LocaleController.getString("UseProxyAddress", R.string.UseProxyAddress);
} else if (a == 1) {
text = "" + port;
detail = LocaleController.getString("UseProxyPort", R.string.UseProxyPort);
} else if (a == 2) {
text = secret;
detail = LocaleController.getString("UseProxySecret", R.string.UseProxySecret);
} else if (a == 3) {
text = user;
detail = LocaleController.getString("UseProxyUsername", R.string.UseProxyUsername);
} else if (a == 4) {
text = password;
detail = LocaleController.getString("UseProxyPassword", R.string.UseProxyPassword);
}
if (TextUtils.isEmpty(text)) {
continue;
}
TextDetailSettingsCell cell = new TextDetailSettingsCell(activity);
cell.setTextAndValue(text, detail, true);
cell.getTextView().setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
cell.getValueTextView().setTextColor(Theme.getColor(Theme.key_dialogTextGray3));
linearLayout.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (a == 2) {
break;
}
2017-07-08 18:32:04 +02:00
}
2018-07-30 04:07:02 +02:00
PickerBottomLayout pickerBottomLayout = new PickerBottomLayout(activity, false);
pickerBottomLayout.setBackgroundColor(Theme.getColor(Theme.key_dialogBackground));
linearLayout.addView(pickerBottomLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM));
pickerBottomLayout.cancelButton.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
pickerBottomLayout.cancelButton.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
pickerBottomLayout.cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
2019-01-23 18:03:33 +01:00
pickerBottomLayout.cancelButton.setOnClickListener(view -> dismissRunnable.run());
2018-07-30 04:07:02 +02:00
pickerBottomLayout.doneButtonTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue2));
pickerBottomLayout.doneButton.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
pickerBottomLayout.doneButtonBadgeTextView.setVisibility(View.GONE);
pickerBottomLayout.doneButtonTextView.setText(LocaleController.getString("ConnectingConnectProxy", R.string.ConnectingConnectProxy).toUpperCase());
2019-01-23 18:03:33 +01:00
pickerBottomLayout.doneButton.setOnClickListener(v -> {
SharedPreferences.Editor editor = MessagesController.getGlobalMainSettings().edit();
editor.putBoolean("proxy_enabled", true);
editor.putString("proxy_ip", address);
int p = Utilities.parseInt(port);
editor.putInt("proxy_port", p);
SharedConfig.ProxyInfo info;
if (TextUtils.isEmpty(secret)) {
editor.remove("proxy_secret");
if (TextUtils.isEmpty(password)) {
2018-07-30 04:07:02 +02:00
editor.remove("proxy_pass");
2019-01-23 18:03:33 +01:00
} else {
editor.putString("proxy_pass", password);
}
if (TextUtils.isEmpty(user)) {
2017-07-08 18:32:04 +02:00
editor.remove("proxy_user");
2019-01-23 18:03:33 +01:00
} else {
editor.putString("proxy_user", user);
2017-07-08 18:32:04 +02:00
}
2019-01-23 18:03:33 +01:00
info = new SharedConfig.ProxyInfo(address, p, user, password, "");
} else {
editor.remove("proxy_pass");
editor.remove("proxy_user");
editor.putString("proxy_secret", secret);
info = new SharedConfig.ProxyInfo(address, p, "", "", secret);
}
editor.commit();
2018-07-30 04:07:02 +02:00
2019-01-23 18:03:33 +01:00
SharedConfig.currentProxy = SharedConfig.addProxy(info);
2018-07-30 04:07:02 +02:00
2019-01-23 18:03:33 +01:00
ConnectionsManager.setProxySettings(true, address, p, user, password, secret);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxySettingsChanged);
dismissRunnable.run();
2017-07-08 18:32:04 +02:00
});
2018-07-30 04:07:02 +02:00
builder.show();
2017-07-08 18:32:04 +02:00
}
2018-08-27 10:33:11 +02:00
2019-05-14 14:08:05 +02:00
@SuppressLint("PrivateApi")
2019-01-23 18:03:33 +01:00
public static String getSystemProperty(String key) {
try {
Class props = Class.forName("android.os.SystemProperties");
return (String) props.getMethod("get", String.class).invoke(null, key);
} catch (Exception ignore) {
}
2018-08-27 10:33:11 +02:00
return null;
}
2019-01-23 18:03:33 +01:00
public static CharSequence concat(CharSequence... text) {
if (text.length == 0) {
return "";
}
if (text.length == 1) {
return text[0];
}
boolean spanned = false;
for (CharSequence piece : text) {
if (piece instanceof Spanned) {
spanned = true;
break;
}
}
if (spanned) {
final SpannableStringBuilder ssb = new SpannableStringBuilder();
for (CharSequence piece : text) {
// If a piece is null, we append the string "null" for compatibility with the
// behavior of StringBuilder and the behavior of the concat() method in earlier
// versions of Android.
ssb.append(piece == null ? "null" : piece);
}
return new SpannedString(ssb);
} else {
final StringBuilder sb = new StringBuilder();
for (CharSequence piece : text) {
sb.append(piece);
}
return sb.toString();
}
}
2019-02-08 03:30:32 +01:00
public static float[] RGBtoHSB(int r, int g, int b) {
float hue, saturation, brightness;
float[] hsbvals = new float[3];
int cmax = (r > g) ? r : g;
if (b > cmax) {
cmax = b;
}
int cmin = (r < g) ? r : g;
if (b < cmin) {
cmin = b;
}
brightness = ((float) cmax) / 255.0f;
if (cmax != 0) {
saturation = ((float) (cmax - cmin)) / ((float) cmax);
} else {
saturation = 0;
}
if (saturation == 0) {
hue = 0;
} else {
float redc = ((float) (cmax - r)) / ((float) (cmax - cmin));
float greenc = ((float) (cmax - g)) / ((float) (cmax - cmin));
float bluec = ((float) (cmax - b)) / ((float) (cmax - cmin));
if (r == cmax) {
hue = bluec - greenc;
} else if (g == cmax) {
hue = 2.0f + redc - bluec;
} else {
hue = 4.0f + greenc - redc;
}
hue = hue / 6.0f;
if (hue < 0) {
hue = hue + 1.0f;
}
}
hsbvals[0] = hue;
hsbvals[1] = saturation;
hsbvals[2] = brightness;
return hsbvals;
}
public static int HSBtoRGB(float hue, float saturation, float brightness) {
int r = 0, g = 0, b = 0;
if (saturation == 0) {
r = g = b = (int) (brightness * 255.0f + 0.5f);
} else {
float h = (hue - (float) Math.floor(hue)) * 6.0f;
float f = h - (float) java.lang.Math.floor(h);
float p = brightness * (1.0f - saturation);
float q = brightness * (1.0f - saturation * f);
float t = brightness * (1.0f - (saturation * (1.0f - f)));
switch ((int) h) {
case 0:
r = (int) (brightness * 255.0f + 0.5f);
g = (int) (t * 255.0f + 0.5f);
b = (int) (p * 255.0f + 0.5f);
break;
case 1:
r = (int) (q * 255.0f + 0.5f);
g = (int) (brightness * 255.0f + 0.5f);
b = (int) (p * 255.0f + 0.5f);
break;
case 2:
r = (int) (p * 255.0f + 0.5f);
g = (int) (brightness * 255.0f + 0.5f);
b = (int) (t * 255.0f + 0.5f);
break;
case 3:
r = (int) (p * 255.0f + 0.5f);
g = (int) (q * 255.0f + 0.5f);
b = (int) (brightness * 255.0f + 0.5f);
break;
case 4:
r = (int) (t * 255.0f + 0.5f);
g = (int) (p * 255.0f + 0.5f);
b = (int) (brightness * 255.0f + 0.5f);
break;
case 5:
r = (int) (brightness * 255.0f + 0.5f);
g = (int) (p * 255.0f + 0.5f);
b = (int) (q * 255.0f + 0.5f);
break;
}
}
return 0xff000000 | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
}
public static int getPatternColor(int color) {
2019-05-14 14:08:05 +02:00
float[] hsb = RGBtoHSB(Color.red(color), Color.green(color), Color.blue(color));
2019-02-08 03:30:32 +01:00
if (hsb[1] > 0.0f || (hsb[2] < 1.0f && hsb[2] > 0.0f)) {
hsb[1] = Math.min(1.0f, hsb[1] + 0.05f + 0.1f * (1.0f - hsb[1]));
}
if (hsb[2] > 0.5f) {
hsb[2] = Math.max(0.0f, hsb[2] * 0.65f);
} else {
hsb[2] = Math.max(0.0f, Math.min(1.0f, 1.0f - hsb[2] * 0.65f));
}
return HSBtoRGB(hsb[0], hsb[1], hsb[2]) & 0x66ffffff;
}
public static int getPatternSideColor(int color) {
2019-05-14 14:08:05 +02:00
float[] hsb = RGBtoHSB(Color.red(color), Color.green(color), Color.blue(color));
2019-02-08 03:30:32 +01:00
hsb[1] = Math.min(1.0f, hsb[1] + 0.05f);
if (hsb[2] > 0.5f) {
hsb[2] = Math.max(0.0f, hsb[2] * 0.90f);
} else{
hsb[2] = Math.max(0.0f, hsb[2] * 0.90f);
}
return HSBtoRGB(hsb[0], hsb[1], hsb[2]) | 0xff000000;
}
public static String getWallPaperUrl(Object object, int currentAccount) {
String link;
if (object instanceof TLRPC.TL_wallPaper) {
TLRPC.TL_wallPaper wallPaper = (TLRPC.TL_wallPaper) object;
link = "https://" + MessagesController.getInstance(currentAccount).linkPrefix + "/bg/" + wallPaper.slug;
StringBuilder modes = new StringBuilder();
if (wallPaper.settings != null) {
if (wallPaper.settings.blur) {
modes.append("blur");
}
if (wallPaper.settings.motion) {
if (modes.length() > 0) {
modes.append("+");
}
modes.append("motion");
}
}
if (modes.length() > 0) {
link += "?mode=" + modes.toString();
}
} else if (object instanceof WallpapersListActivity.ColorWallpaper) {
WallpapersListActivity.ColorWallpaper wallPaper = (WallpapersListActivity.ColorWallpaper) object;
String color = String.format("%02x%02x%02x", (byte) (wallPaper.color >> 16) & 0xff, (byte) (wallPaper.color >> 8) & 0xff, (byte) (wallPaper.color & 0xff)).toLowerCase();
if (wallPaper.pattern != null) {
link = "https://" + MessagesController.getInstance(currentAccount).linkPrefix + "/bg/" + wallPaper.pattern.slug + "?intensity=" + (int) (wallPaper.intensity * 100) + "&bg_color=" + color;
} else {
link = "https://" + MessagesController.getInstance(currentAccount).linkPrefix + "/bg/" + color;
}
} else {
link = null;
}
return link;
}
2019-03-03 21:40:48 +01:00
public static float distanceInfluenceForSnapDuration(float f) {
f -= 0.5F;
f *= 0.47123894F;
return (float) Math.sin((double) f);
}
2019-05-14 14:08:05 +02:00
public static void makeAccessibilityAnnouncement(CharSequence what) {
AccessibilityManager am = (AccessibilityManager) ApplicationLoader.applicationContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (am.isEnabled()) {
AccessibilityEvent ev = AccessibilityEvent.obtain();
ev.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
ev.getText().add(what);
am.sendAccessibilityEvent(ev);
}
}
public static int getOffsetColor(int color1, int color2, float offset, float alpha) {
int rF = Color.red(color2);
int gF = Color.green(color2);
int bF = Color.blue(color2);
int aF = Color.alpha(color2);
int rS = Color.red(color1);
int gS = Color.green(color1);
int bS = Color.blue(color1);
int aS = Color.alpha(color1);
return Color.argb((int) ((aS + (aF - aS) * offset) * alpha), (int) (rS + (rF - rS) * offset), (int) (gS + (gF - gS) * offset), (int) (bS + (bF - bS) * offset));
}
}