Commit a93d2994 authored by DrKLO's avatar DrKLO

Update to 3.0.1

parent 16346188
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
apply plugin: 'com.android.application'
repositories {
......@@ -13,7 +5,7 @@ repositories {
}
dependencies {
compile 'com.android.support:support-v4:22.1.+'
compile 'com.android.support:support-v4:22.2.+'
compile 'com.google.android.gms:play-services:3.2.+'
compile 'net.hockeyapp.android:HockeySDK:3.5.+'
compile 'com.googlecode.mp4parser:isoparser:1.0.+'
......@@ -81,7 +73,7 @@ android {
defaultConfig {
minSdkVersion 8
targetSdkVersion 22
versionCode 542
versionName "2.9.1"
versionCode 572
versionName "3.0.1"
}
}
......@@ -430,7 +430,7 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_loadBitmap(JNIEnv *env, jcl
AndroidBitmapInfo info;
int i;
if ((i = AndroidBitmap_getInfo(env, bitmap, &info)) >= 0) {
char *fileName = (*env)->GetStringUTFChars(env, path, NULL);
FILE *infile;
......@@ -438,7 +438,7 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_loadBitmap(JNIEnv *env, jcl
if ((infile = fopen(fileName, "rb"))) {
struct my_error_mgr jerr;
struct jpeg_decompress_struct cinfo;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
......@@ -557,7 +557,7 @@ JNIEXPORT jobject Java_org_telegram_messenger_Utilities_loadWebpImage(JNIEnv *en
if (!WebPDecodeRGBAInto((uint8_t*)inputBuffer, len, (uint8_t*)bitmapPixels, bitmapInfo.height * bitmapInfo.stride, bitmapInfo.stride)) {
AndroidBitmap_unlockPixels(env, outputBitmap);
(*env)->DeleteLocalRef(env, outputBitmap);
(*env)->ThrowNew(env, jclass_RuntimeException, "Failed to unlock Bitmap pixels");
(*env)->ThrowNew(env, jclass_RuntimeException, "Failed to decode webp image");
return 0;
}
......
......@@ -8,9 +8,11 @@
package org.telegram.SQLite;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import java.nio.ByteBuffer;
import java.util.HashMap;
public class SQLitePreparedStatement {
private boolean isFinalized = false;
......@@ -19,6 +21,8 @@ public class SQLitePreparedStatement {
private int queryArgsCount;
private boolean finalizeAfterQuery = false;
private static HashMap<SQLitePreparedStatement, String> hashMap;
public int getStatementHandle() {
return sqliteStatementHandle;
}
......@@ -26,6 +30,15 @@ public class SQLitePreparedStatement {
public SQLitePreparedStatement(SQLiteDatabase db, String sql, boolean finalize) throws SQLiteException {
finalizeAfterQuery = finalize;
sqliteStatementHandle = prepare(db.getSQLiteHandle(), sql);
if (BuildVars.DEBUG_VERSION) {
if (hashMap == null) {
hashMap = new HashMap<>();
}
hashMap.put(this, sql);
for (HashMap.Entry<SQLitePreparedStatement, String> entry : hashMap.entrySet()) {
FileLog.d("tmessages", "exist entry = " + entry.getValue());
}
}
}
......@@ -88,6 +101,9 @@ public class SQLitePreparedStatement {
return;
}
try {
if (BuildVars.DEBUG_VERSION) {
hashMap.remove(this);
}
isFinalized = true;
finalize(sqliteStatementHandle);
} catch (SQLiteException e) {
......
......@@ -616,22 +616,31 @@ public class AndroidUtilities {
}
}
public static final int FLAG_TAG_BR = 1;
public static final int FLAG_TAG_BOLD = 2;
public static final int FLAG_TAG_COLOR = 4;
public static final int FLAG_TAG_ALL = FLAG_TAG_BR | FLAG_TAG_BOLD | FLAG_TAG_COLOR;
public static Spannable replaceTags(String str) {
return replaceTags(str, FLAG_TAG_ALL);
}
public static Spannable replaceTags(String str, int flag) {
try {
int start;
int startColor = -1;
int end;
StringBuilder stringBuilder = new StringBuilder(str);
while ((start = stringBuilder.indexOf("<br>")) != -1) {
stringBuilder.replace(start, start + 4, "\n");
}
while ((start = stringBuilder.indexOf("<br/>")) != -1) {
stringBuilder.replace(start, start + 5, "\n");
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");
}
}
ArrayList<Integer> bolds = new ArrayList<>();
ArrayList<Integer> colors = new ArrayList<>();
while ((start = stringBuilder.indexOf("<b>")) != -1 || (startColor = stringBuilder.indexOf("<c#")) != -1) {
if (start != -1) {
if ((flag & FLAG_TAG_BOLD) != 0) {
while ((start = stringBuilder.indexOf("<b>")) != -1) {
stringBuilder.replace(start, start + 3, "");
end = stringBuilder.indexOf("</b>");
if (end == -1) {
......@@ -640,17 +649,20 @@ public class AndroidUtilities {
stringBuilder.replace(end, end + 4, "");
bolds.add(start);
bolds.add(end);
} else if (startColor != -1) {
stringBuilder.replace(startColor, startColor + 2, "");
end = stringBuilder.indexOf(">", startColor);
int color = Color.parseColor(stringBuilder.substring(startColor, end));
stringBuilder.replace(startColor, end + 1, "");
}
}
ArrayList<Integer> colors = new ArrayList<>();
if ((flag & FLAG_TAG_COLOR) != 0) {
while ((start = stringBuilder.indexOf("<c#")) != -1) {
stringBuilder.replace(start, start + 2, "");
end = stringBuilder.indexOf(">", start);
int color = Color.parseColor(stringBuilder.substring(start, end));
stringBuilder.replace(start, end + 1, "");
end = stringBuilder.indexOf("</c>");
stringBuilder.replace(end, end + 4, "");
colors.add(startColor);
colors.add(start);
colors.add(end);
colors.add(color);
startColor = -1;
}
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(stringBuilder);
......
......@@ -89,6 +89,15 @@ public class AnimatorSetProxy {
return this;
}
public AnimatorSetProxy setStartDelay(long delay) {
if (View10.NEED_PROXY) {
((AnimatorSet10) animatorSet).setStartDelay(delay);
} else {
((AnimatorSet) animatorSet).setStartDelay(delay);
}
return this;
}
public void start() {
if (View10.NEED_PROXY) {
((AnimatorSet10) animatorSet).start();
......
......@@ -956,14 +956,8 @@ public class ContactsController {
public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) {
TLRPC.User user1 = usersDict.get(tl_contact.user_id);
TLRPC.User user2 = usersDict.get(tl_contact2.user_id);
String name1 = user1.first_name;
if (name1 == null || name1.length() == 0) {
name1 = user1.last_name;
}
String name2 = user2.first_name;
if (name2 == null || name2.length() == 0) {
name2 = user2.last_name;
}
String name1 = UserObject.getFirstName(user1);
String name2 = UserObject.getFirstName(user2);
return name1.compareTo(name2);
}
});
......@@ -989,10 +983,7 @@ public class ContactsController {
contactsByPhonesDict.put(user.phone, value);
}
String key = user.first_name;
if (key == null || key.length() == 0) {
key = user.last_name;
}
String key = UserObject.getFirstName(user);
if (key.length() > 1) {
key = key.substring(0, 1);
}
......@@ -1160,14 +1151,8 @@ public class ContactsController {
public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) {
TLRPC.User user1 = MessagesController.getInstance().getUser(tl_contact.user_id);
TLRPC.User user2 = MessagesController.getInstance().getUser(tl_contact2.user_id);
String name1 = user1.first_name;
if (name1 == null || name1.length() == 0) {
name1 = user1.last_name;
}
String name2 = user2.first_name;
if (name2 == null || name2.length() == 0) {
name2 = user2.last_name;
}
String name1 = UserObject.getFirstName(user1);
String name2 = UserObject.getFirstName(user2);
return name1.compareTo(name2);
}
});
......@@ -1183,10 +1168,7 @@ public class ContactsController {
continue;
}
String key = user.first_name;
if (key == null || key.length() == 0) {
key = user.last_name;
}
String key = UserObject.getFirstName(user);
if (key.length() > 1) {
key = key.substring(0, 1);
}
......@@ -1638,7 +1620,7 @@ public class ContactsController {
for (TLRPC.User user : users) {
if (user.phone != null && user.phone.length() > 0) {
CharSequence name = ContactsController.formatName(user.first_name, user.last_name);
CharSequence name = UserObject.getUserName(user);
MessagesStorage.getInstance().applyPhoneBookUpdates(user.phone, "");
Contact contact = contactsBookSPhones.get(user.phone);
if (contact != null) {
......
......@@ -21,6 +21,7 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.Spanned;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.view.View;
......@@ -416,6 +417,14 @@ public class Emoji {
return false;
}
private static boolean isNextCharIsColor(CharSequence cs, int i) {
if (i + 2 >= cs.length()) {
return false;
}
int value = cs.charAt(i + 1) << 16 | cs.charAt(i + 2);
return value == 0xd83cdffb || value == 0xd83cdffc || value == 0xd83cdffd || value == 0xd83cdffe || value == 0xd83cdfff;
}
public static CharSequence replaceEmoji(CharSequence cs, Paint.FontMetricsInt fontMetrics, int size) {
if (cs == null || cs.length() == 0) {
return cs;
......@@ -439,12 +448,16 @@ public class Emoji {
buf |= c;
EmojiDrawable d = Emoji.getEmojiDrawable(buf);
if (d != null) {
boolean nextIsSkinTone = isNextCharIsColor(cs, i);
EmojiSpan span = new EmojiSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM, size, fontMetrics);
emojiCount++;
if (c >= 0xDDE6 && c <= 0xDDFA) {
s.setSpan(span, i - 3, i + 1, 0);
s.setSpan(span, i - 3, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
s.setSpan(span, i - 1, i + 1, 0);
s.setSpan(span, i - 1, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (nextIsSkinTone) {
i += 2;
}
}
buf = 0;
......@@ -457,9 +470,13 @@ public class Emoji {
buf |= c;
EmojiDrawable d = Emoji.getEmojiDrawable(buf);
if (d != null) {
boolean nextIsSkinTone = isNextCharIsColor(cs, i);
EmojiSpan span = new EmojiSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM, size, fontMetrics);
emojiCount++;
s.setSpan(span, i - 1, i + 1, 0);
s.setSpan(span, i - 1, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (nextIsSkinTone) {
i += 2;
}
}
buf = 0;
}
......@@ -467,9 +484,13 @@ public class Emoji {
} else if (inArray(c, emojiChars)) {
EmojiDrawable d = Emoji.getEmojiDrawable(c);
if (d != null) {
boolean nextIsSkinTone = isNextCharIsColor(cs, i);
EmojiSpan span = new EmojiSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM, size, fontMetrics);
emojiCount++;
s.setSpan(span, i, i + 1, 0);
s.setSpan(span, i, i + (nextIsSkinTone ? 3 : 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (nextIsSkinTone) {
i += 2;
}
}
}
if (emojiCount >= 50) {
......
......@@ -46,6 +46,7 @@ import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
......@@ -140,62 +141,67 @@ public class ImageLoader {
fileOutputStream = new RandomAccessFile(tempFile, "rws");
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
try {
if (httpConnection != null && httpConnection instanceof HttpURLConnection) {
int code = ((HttpURLConnection) httpConnection).getResponseCode();
if (code != HttpURLConnection.HTTP_OK && code != HttpURLConnection.HTTP_ACCEPTED && code != HttpURLConnection.HTTP_NOT_MODIFIED) {
canRetry = false;
}
if (e instanceof UnknownHostException) {
canRetry = false;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (httpConnectionStream != null) {
if (canRetry) {
try {
byte[] data = new byte[1024 * 4];
while (true) {
if (isCancelled()) {
break;
if (httpConnection != null && httpConnection instanceof HttpURLConnection) {
int code = ((HttpURLConnection) httpConnection).getResponseCode();
if (code != HttpURLConnection.HTTP_OK && code != HttpURLConnection.HTTP_ACCEPTED && code != HttpURLConnection.HTTP_NOT_MODIFIED) {
canRetry = false;
}
try {
int read = httpConnectionStream.read(data);
if (read > 0) {
fileOutputStream.write(data, 0, read);
} else if (read == -1) {
done = true;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (httpConnectionStream != null) {
try {
byte[] data = new byte[1024 * 4];
while (true) {
if (isCancelled()) {
break;
} else {
}
try {
int read = httpConnectionStream.read(data);
if (read > 0) {
fileOutputStream.write(data, 0, read);
} else if (read == -1) {
done = true;
break;
} else {
break;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
break;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
break;
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
}
try {
if (fileOutputStream != null) {
fileOutputStream.close();
fileOutputStream = null;
try {
if (fileOutputStream != null) {
fileOutputStream.close();
fileOutputStream = null;
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
try {
if (httpConnectionStream != null) {
httpConnectionStream.close();
try {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
return done;
......@@ -537,7 +543,7 @@ public class ImageLoader {
boolean canDeleteFile = true;
boolean useNativeWebpLoaded = false;
if (Build.VERSION.SDK_INT < 18) {
if (Build.VERSION.SDK_INT < 19) {
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(cacheFileFinal, "r");
......@@ -1892,13 +1898,6 @@ public class ImageLoader {
BitmapFactory.decodeFileDescriptor(fileDescriptor, null, bmOptions);
} catch (Throwable e) {
FileLog.e("tmessages", e);
try {
if (parcelFD != null) {
parcelFD.close();
}
} catch (Throwable e2) {
FileLog.e("tmessages", e2);
}
return null;
}
}
......
......@@ -807,7 +807,7 @@ public class LocaleController {
return getString("Online", R.string.Online);
}
}
if (user == null || user.status == null || user.status.expires == 0 || user instanceof TLRPC.TL_userDeleted || user instanceof TLRPC.TL_userEmpty) {
if (user == null || user.status == null || user.status.expires == 0 || UserObject.isDeleted(user) || user instanceof TLRPC.TL_userEmpty) {
return getString("ALongTimeAgo", R.string.ALongTimeAgo);
} else {
int currentTime = ConnectionsManager.getInstance().getCurrentTime();
......
......@@ -41,6 +41,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.view.View;
......@@ -198,6 +199,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
private SensorManager sensorManager;
private Sensor proximitySensor;
private boolean ignoreProximity;
private PowerManager.WakeLock proximityWakeLock;
private ArrayList<MessageObject> videoConvertQueue = new ArrayList<>();
private final Object videoQueueSync = new Object();
......@@ -220,6 +222,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
private boolean saveToGallery = true;
public static AlbumEntry allPhotosAlbumEntry;
private HashMap<String, ArrayList<WeakReference<FileDownloadProgressListener>>> loadingFileObservers = new HashMap<>();
private HashMap<Integer, String> observersByTag = new HashMap<>();
private boolean listenerInProgress = false;
......@@ -355,6 +359,40 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
}
/*private class GalleryObserverInternal extends ContentObserver {
public GalleryObserverInternal() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadGalleryPhotosAlbums(0);
}
}, 2000);
}
}
private class GalleryObserverExternal extends ContentObserver {
public GalleryObserverExternal() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadGalleryPhotosAlbums(0);
}
}, 2000);
}
}*/
private ExternalObserver externalObserver = null;
private InternalObserver internalObserver = null;
private long lastSecretChatEnterTime = 0;
......@@ -428,6 +466,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
try {
sensorManager = (SensorManager) ApplicationLoader.applicationContext.getSystemService(Context.SENSOR_SERVICE);
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
PowerManager powerManager = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE);
proximityWakeLock = powerManager.newWakeLock(0x00000020, "proximity");
} catch (Exception e) {
FileLog.e("tmessages", e);
}
......@@ -484,6 +524,17 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
MediaStore.Images.ImageColumns.TITLE
};
}
/*try {
ApplicationLoader.applicationContext.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, new GalleryObserverExternal());
} catch (Exception e) {
FileLog.e("tmessages", e);
}
try {
ApplicationLoader.applicationContext.getContentResolver().registerContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, false, new GalleryObserverInternal());
} catch (Exception e) {
FileLog.e("tmessages", e);
}*/
}
private void startProgressTimer() {
......@@ -1191,7 +1242,10 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (sensorManager != null && proximitySensor != null) {
sensorManager.unregisterListener(this);
}
} catch (Exception e) {
if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
}
......@@ -1204,6 +1258,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (sensorManager != null && proximitySensor != null) {
sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
}
if (!NotificationsController.getInstance().audioManager.isWiredHeadsetOn() && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
......@@ -1319,7 +1376,14 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioDidStarted, messageObject);
clenupPlayer(true);
final File cacheFile = FileLoader.getPathToMessage(messageObject.messageOwner);
File file = null;
if (messageObject.messageOwner.attachPath != null && messageObject.messageOwner.attachPath.length() > 0) {
file = new File(messageObject.messageOwner.attachPath);
if (!file.exists()) {
file = null;
}
}
final File cacheFile = file != null ? file : FileLoader.getPathToMessage(messageObject.messageOwner);
if (isOpusFile(cacheFile.getAbsolutePath()) == 1) {
synchronized (playerObjectSync) {
......@@ -2094,7 +2158,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
try {
albums.clear();
allPhotosAlbum = null;
AlbumEntry allVideosAlbum = null;
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, "", null, MediaStore.Video.Media.DATE_TAKEN + " DESC");
if (cursor != null) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID);
......@@ -2116,12 +2180,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
PhotoEntry photoEntry = new PhotoEntry(bucketId, imageId, dateTaken, path, 0, true);
if (allPhotosAlbum == null) {
allPhotosAlbum = new AlbumEntry(0, LocaleController.getString("AllVideo", R.string.AllVideo), photoEntry, true);
videoAlbumsSorted.add(0, allPhotosAlbum);
if (allVideosAlbum == null) {
allVideosAlbum = new AlbumEntry(0, LocaleController.getString("AllVideo", R.string.AllVideo), photoEntry, true);
videoAlbumsSorted.add(0, allVideosAlbum);
}
if (allPhotosAlbum != null) {
allPhotosAlbum.addPhoto(photoEntry);
if (allVideosAlbum != null) {
allVideosAlbum.addPhoto(photoEntry);
}
AlbumEntry albumEntry = albums.get(bucketId);
......@@ -2153,9 +2217,11 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
final Integer cameraAlbumIdFinal = cameraAlbumId;
final Integer cameraAlbumVideoIdFinal = cameraAlbumVideoId;
final AlbumEntry allPhotosAlbumFinal = allPhotosAlbum;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
allPhotosAlbumEntry = allPhotosAlbumFinal;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.albumsDidLoaded, guid, albumsSorted, cameraAlbumIdFinal, videoAlbumsSorted, cameraAlbumVideoIdFinal);
}
});
......
......@@ -61,6 +61,8 @@ public class MessageObject {
public int textHeight;
public int blockHeight = Integer.MAX_VALUE;
public static Pattern urlPattern;
public static class TextLayoutBlock {
public StaticLayout textLayout;
public float textXOffset = 0;
......@@ -212,7 +214,7 @@ public class MessageObject {
messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, AndroidUtilities.formatTTLString(message.action.ttl));
} else {
if (fromUser != null) {
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, fromUser.first_name, AndroidUtilities.formatTTLString(message.action.ttl));
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, UserObject.getFirstName(fromUser), AndroidUtilities.formatTTLString(message.action.ttl));
} else {
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, "", AndroidUtilities.formatTTLString(message.action.ttl));
}
......@@ -222,7 +224,7 @@ public class MessageObject {
messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved);
} else {
if (fromUser != null) {
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, fromUser.first_name);
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, UserObject.getFirstName(fromUser));
} else {
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, "");
}
......@@ -239,20 +241,17 @@ public class MessageObject {
to_user = MessagesController.getInstance().getUser(messageOwner.to_id.user_id);
}
}
String name = "";
if (to_user != null) {
name = to_user.first_name;
}
String name = to_user != null ? UserObject.getFirstName(to_user) : "";
messageText = LocaleController.formatString("NotificationUnrecognizedDevice", R.string.NotificationUnrecognizedDevice, name, date, message.action.title, message.action.address);
} else if (message.action instanceof TLRPC.TL_messageActionUserJoined) {
if (fromUser != null) {
messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, ContactsController.formatName(fromUser.first_name, fromUser.last_name));
messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, UserObject.getUserName(fromUser));
} else {
messageText = LocaleController.formatString("NotificationContactJoined", R.string.NotificationContactJoined, "");
}
} else if (message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
if (fromUser != null) {
messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, ContactsController.formatName(fromUser.first_name, fromUser.last_name));
messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, UserObject.getUserName(fromUser));
} else {
messageText = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, "");
}
......@@ -274,7 +273,7 @@ public class MessageObject {
messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, AndroidUtilities.formatTTLString(action.ttl_seconds));
} else {
if (fromUser != null) {
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, fromUser.first_name, AndroidUtilities.formatTTLString(action.ttl_seconds));
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, UserObject.getFirstName(fromUser), AndroidUtilities.formatTTLString(action.ttl_seconds));
} else {
messageText = LocaleController.formatString("MessageLifetimeChanged", R.string.MessageLifetimeChanged, "", AndroidUtilities.formatTTLString(action.ttl_seconds));
}
......@@ -284,7 +283,7 @@ public class MessageObject {
messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved);
} else {
if (fromUser != null) {
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, fromUser.first_name);
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, UserObject.getFirstName(fromUser));
} else {
messageText = LocaleController.formatString("MessageLifetimeRemoved", R.string.MessageLifetimeRemoved, "");
}
......@@ -484,7 +483,7 @@ public class MessageObject {
}
public CharSequence replaceWithLink(CharSequence source, String param, TLRPC.User user) {
String name = ContactsController.formatName(user.first_name, user.last_name);
String name = UserObject.getUserName(user);
int start = TextUtils.indexOf(source, param);
URLSpanNoUnderlineBold span = new URLSpanNoUnderlineBold("" + user.id);
SpannableStringBuilder builder = new SpannableStringBuilder(TextUtils.replace(source, new String[]{param}, new String[]{name}));
......@@ -524,8 +523,8 @@ public class MessageObject {
return FileLoader.MEDIA_DIR_CACHE;
}
private boolean containsUrls(CharSequence message) {
if (message == null || message.length() < 3 || message.length() > 1024 * 20) {
private static boolean containsUrls(CharSequence message) {
if (message == null || message.length() < 2 || message.length() > 1024 * 20) {
return false;
}
......@@ -550,7 +549,7 @@ public class MessageObject {
} else if (!(c != ' ' && digitsInRow > 0)) {
digitsInRow = 0;
}
if ((c == '@' || c == '#') && i == 0 || i != 0 && (message.charAt(i - 1) == ' ' || message.charAt(i - 1) == '\n')) {
if ((c == '@' || c == '#' || c == '/') && i == 0 || i != 0 && (message.charAt(i - 1) == ' ' || message.charAt(i - 1) == '\n')) {
return true;
}
if (c == ':') {
......@@ -613,14 +612,16 @@ public class MessageObject {
}
}
private void addUsernamesAndHashtags(CharSequence charSequence) {
private static void addUsernamesAndHashtags(CharSequence charSequence) {
try {
Pattern pattern = Pattern.compile("(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+");
Matcher matcher = pattern.matcher(charSequence);
if (urlPattern == null) {
urlPattern = Pattern.compile("(^|\\s)/[a-zA-Z@\\d_]{1,255}|(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+");
}
Matcher matcher = urlPattern.matcher(charSequence);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
if (charSequence.charAt(start) != '@' && charSequence.charAt(start) != '#') {
if (charSequence.charAt(start) != '@' && charSequence.charAt(start) != '#' && charSequence.charAt(start) != '/') {
start++;
}
URLSpanNoUnderline url = new URLSpanNoUnderline(charSequence.subSequence(start, end).toString());
......@@ -631,14 +632,7 @@ public class MessageObject {
}
}
private void generateLayout() {
if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) {
return;
}
generateLinkDescription();
textLayoutBlocks = new ArrayList<>();
public static void addLinks(CharSequence messageText) {
if (messageText instanceof Spannable && containsUrls(messageText)) {
if (messageText.length() < 100) {
try {
......@@ -655,6 +649,17 @@ public class MessageObject {
}
addUsernamesAndHashtags(messageText);
}
}
private void generateLayout() {
if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) {
return;
}
generateLinkDescription();
textLayoutBlocks = new ArrayList<>();
addLinks(messageText);
int maxWidth;
if (AndroidUtilities.isTablet()) {
......@@ -903,7 +908,7 @@ public class MessageObject {
}
public boolean isSendError() {
return messageOwner.send_state == MESSAGE_SEND_STATE_SEND_ERROR;
return messageOwner.send_state == MESSAGE_SEND_STATE_SEND_ERROR && messageOwner.id < 0;
}
public boolean isSent() {
......
......@@ -44,7 +44,6 @@ public class NotificationCenter {
public static final int pushMessagesUpdated = totalEvents++;
public static final int blockedUsersDidLoaded = totalEvents++;
public static final int openedChatChanged = totalEvents++;
public static final int hideEmojiKeyboard = totalEvents++;
public static final int stopEncodingService = totalEvents++;
public static final int didCreatedNewDeleteTask = totalEvents++;
public static final int mainUserInfoChanged = totalEvents++;
......@@ -62,6 +61,9 @@ public class NotificationCenter {
public static final int stickersDidLoaded = totalEvents++;
public static final int didReplacedPhotoInMemCache = totalEvents++;
public static final int messagesReadContent = totalEvents++;
public static final int botInfoDidLoaded = totalEvents++;
public static final int botKeyboardDidLoaded = totalEvents++;
public static final int chatSearchResultsAvailable = totalEvents++;
public static final int httpFileDidLoaded = totalEvents++;
public static final int httpFileDidFailedLoad = totalEvents++;
......@@ -147,7 +149,7 @@ public class NotificationCenter {
public void postNotificationName(int id, Object... args) {
boolean allowDuringAnimation = false;
if (id == dialogsNeedReload || id == closeChats || id == messagesDidLoaded || id == mediaCountDidLoaded || id == mediaDidLoaded) {
if (id == dialogsNeedReload || id == closeChats || id == messagesDidLoaded || id == mediaCountDidLoaded || id == mediaDidLoaded || id == botInfoDidLoaded || id == botKeyboardDidLoaded) {
allowDuringAnimation = true;
}
postNotificationNameInternal(id, allowDuringAnimation, args);
......
/*
* This is the source code of Telegram for Android v. 2.0.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).
*
* Copyright Nikolai Kudashov, 2013-2014.
*/
package org.telegram.android;
import android.app.IntentService;
import android.content.Intent;
public class NotificationDelay extends IntentService {
public NotificationDelay() {
super("NotificationDelay");
}
@Override
protected void onHandleIntent(Intent intent) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationsController.getInstance().notificationDelayReached();
}
});
}
}
......@@ -449,7 +449,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) {
sendMessage(messageObject.messageOwner.media, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media.phone_number != null) {
TLRPC.User user = new TLRPC.TL_userContact();
TLRPC.User user = new TLRPC.TL_userContact_old2();
user.phone = messageObject.messageOwner.media.phone_number;
user.first_name = messageObject.messageOwner.media.first_name;
user.last_name = messageObject.messageOwner.media.last_name;
......@@ -503,12 +503,14 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
document.attributes.remove(a);
document.attributes.add(new TLRPC.TL_documentAttributeSticker_old());
break;
if ((int) peer == 0) {
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
document.attributes.remove(a);
document.attributes.add(new TLRPC.TL_documentAttributeSticker_old());
break;
}
}
}
SendMessagesHelper.getInstance().sendMessage((TLRPC.TL_document) document, null, null, peer, replyingMessageObject);
......@@ -537,7 +539,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (sendToUser == null) {
return;
}
if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) {
if (sendToUser.access_hash != 0) {
sendToPeer = new TLRPC.TL_inputPeerForeign();
sendToPeer.user_id = sendToUser.id;
sendToPeer.access_hash = sendToUser.access_hash;
......@@ -736,6 +738,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
ArrayList<TLRPC.InputUser> sendToPeers = null;
if (lower_id == 0) {
encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id);
if (encryptedChat == null) {
if (msgObj != null) {
MessagesStorage.getInstance().markMessageAsSendError(msgObj.getId());
msgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, msgObj.getId());
processSentMessage(msgObj.getId());
}
return;
}
}
if (retry) {
......@@ -766,7 +777,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
video = (TLRPC.TL_video) newMsg.media.video;
}
} else if (msgObj.type == 12) {
user = new TLRPC.TL_userRequest();
user = new TLRPC.TL_userRequest_old2();
user.phone = newMsg.media.phone_number;
user.first_name = newMsg.media.first_name;
user.last_name = newMsg.media.last_name;
......@@ -862,6 +873,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg.media.first_name = user.first_name;
newMsg.media.last_name = user.last_name;
newMsg.media.user_id = user.id;
if (newMsg.media.first_name == null) {
user.first_name = newMsg.media.first_name = "";
}
if (newMsg.media.last_name == null) {
user.last_name = newMsg.media.last_name = "";
}
newMsg.message = "";
type = 6;
} else if (document != null) {
......@@ -941,7 +958,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
processSentMessage(newMsg.id);
return;
}
if (sendToUser instanceof TLRPC.TL_userForeign || sendToUser instanceof TLRPC.TL_userRequest) {
if ((sendToUser.flags & TLRPC.USER_FLAG_BOT) != 0) {
newMsg.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
}
if (sendToUser.access_hash != 0) {
sendToPeer = new TLRPC.TL_inputPeerForeign();
sendToPeer.user_id = sendToUser.id;
sendToPeer.access_hash = sendToUser.access_hash;
......@@ -1758,6 +1778,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
sentMessage.attachPath = newMsg.attachPath;
}
}
} else if (sentMessage.media instanceof TLRPC.TL_messageMediaContact && newMsg.media instanceof TLRPC.TL_messageMediaContact) {
newMsg.media = sentMessage.media;
}
}
......@@ -2162,15 +2184,30 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
return src;
}
public static void prepareSendingText(String text, long dialog_id) {
text = getTrimmedString(text);
if (text.length() != 0) {
int count = (int) Math.ceil(text.length() / 4096.0f);
for (int a = 0; a < count; a++) {
String mess = text.substring(a * 4096, Math.min((a + 1) * 4096, text.length()));
SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, null, null, true);
public static void prepareSendingText(final String text, final long dialog_id) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
String textFinal = getTrimmedString(text);
if (textFinal.length() != 0) {
int count = (int) Math.ceil(textFinal.length() / 4096.0f);
for (int a = 0; a < count; a++) {
String mess = textFinal.substring(a * 4096, Math.min((a + 1) * 4096, textFinal.length()));
SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, null, null, true);
}
}
}
});
}
});
}
}
});
}
public static void prepareSendingPhotos(ArrayList<String> paths, ArrayList<Uri> uris, final long dialog_id, final MessageObject reply_to_msg, final ArrayList<String> captions) {
......
/*
* This is the source code of Telegram for Android v. 2.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).
*
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.android;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
public class UserObject {
public static boolean isDeleted(TLRPC.User user) {
return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || (user.flags & TLRPC.USER_FLAG_DELETED) != 0;
}
public static boolean isContact(TLRPC.User user) {
return user instanceof TLRPC.TL_userContact_old2 || (user.flags & TLRPC.USER_FLAG_CONTACT) != 0 || (user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) != 0;
}
public static boolean isUserSelf(TLRPC.User user) {
return user instanceof TLRPC.TL_userSelf_old3 || (user.flags & TLRPC.USER_FLAG_SELF) != 0;
}
public static String getUserName(TLRPC.User user) {
if (user == null || isDeleted(user)) {
return LocaleController.getString("HiddenName", R.string.HiddenName);
}
return ContactsController.formatName(user.first_name, user.last_name);
}
public static String getFirstName(TLRPC.User user) {
if (user == null || isDeleted(user)) {
return "DELETED";
}
String name = user.first_name;
if (name == null || name.length() == 0) {
name = user.last_name;
}
return name != null && name.length() > 0 ? name : "DELETED";
}
}
/*
* This is the source code of Telegram for Android v. 2.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).
*
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.android.query;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessagesStorage;
import org.telegram.android.NotificationCenter;
import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.TLRPC;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
public class BotQuery {
private static HashMap<Integer, TLRPC.BotInfo> botInfos = new HashMap<>();
private static HashMap<Long, TLRPC.Message> botKeyboards = new HashMap<>();
private static HashMap<Integer, Long> botKeyboardsByMids = new HashMap<>();
public static void cleanup() {
botInfos.clear();
}
public static void clearBotKeyboard(final long did, final ArrayList<Integer> messages) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (messages != null) {
for (int a = 0; a < messages.size(); a++) {
Long did = botKeyboardsByMids.get(messages.get(a));
if (did != null) {
botKeyboards.remove(did);
botKeyboardsByMids.remove(messages.get(a));
NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, null, did);
}
}
} else {
botKeyboards.remove(did);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, null, did);
}
}
});
}
public static void loadBotKeyboard(final long did) {
TLRPC.Message keyboard = botKeyboards.get(did);
if (keyboard != null) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, keyboard, did);
return;
}
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
TLRPC.Message botKeyboard = null;
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT info FROM bot_keyboard WHERE uid = %d", did));
if (cursor.next()) {
ByteBufferDesc data;
if (!cursor.isNull(0)) {
data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
botKeyboard = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
}
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
}
}
cursor.dispose();
if (botKeyboard != null) {
final TLRPC.Message botKeyboardFinal = botKeyboard;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, botKeyboardFinal, did);
}
});
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public static void loadBotInfo(final int uid, boolean cache, final int classGuid) {
if (cache) {
TLRPC.BotInfo botInfo = botInfos.get(uid);
if (botInfo != null) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.botInfoDidLoaded, botInfo, classGuid);
return;
}
}
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
TLRPC.BotInfo botInfo = null;
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT info FROM bot_info WHERE uid = %d", uid));
if (cursor.next()) {
ByteBufferDesc data;
if (!cursor.isNull(0)) {
data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
botInfo = TLRPC.BotInfo.TLdeserialize(data, data.readInt32(false), false);
}
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
}
}
cursor.dispose();
if (botInfo != null) {
final TLRPC.BotInfo botInfoFinal = botInfo;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.botInfoDidLoaded, botInfoFinal, classGuid);
}
});
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public static void putBotKeyboard(final long did, final TLRPC.Message message) {
if (message == null) {
return;
}
try {
int mid = 0;
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT mid FROM bot_keyboard WHERE uid = %d", did));
if (cursor.next()) {
mid = cursor.intValue(0);
}
cursor.dispose();
if (mid >= message.id) {
return;
}
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO bot_keyboard VALUES(?, ?, ?)");
state.requery();
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(message.getObjectSize());
message.serializeToStream(data);
state.bindLong(1, did);
state.bindInteger(2, message.id);
state.bindByteBuffer(3, data.buffer);
state.step();
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
state.dispose();
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
TLRPC.Message old = botKeyboards.put(did, message);
if (old != null) {
botKeyboardsByMids.remove(old.id);
}
botKeyboardsByMids.put(message.id, did);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.botKeyboardDidLoaded, message, did);
}
});
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static void putBotInfo(final TLRPC.BotInfo botInfo) {
if (botInfo == null || botInfo instanceof TLRPC.TL_botInfoEmpty) {
return;
}
botInfos.put(botInfo.user_id, botInfo);
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO bot_info(uid, info) VALUES(?, ?)");
state.requery();
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(botInfo.getObjectSize());
botInfo.serializeToStream(data);
state.bindInteger(1, botInfo.user_id);
state.bindByteBuffer(2, data.buffer);
state.step();
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
state.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
}
/*
* This is the source code of Telegram for Android v. 2.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).
*
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.android.query;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessageObject;
import org.telegram.android.MessagesController;
import org.telegram.android.MessagesStorage;
import org.telegram.android.NotificationCenter;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import java.util.ArrayList;
public class MessagesSearchQuery {
private static long reqId;
private static int lastReqId;
private static boolean messagesSearchEndReached;
private static ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
private static String lastSearchQuery;
private static int lastReturnedNum;
private static int getMask() {
int mask = 0;
if (lastReturnedNum < searchResultMessages.size() - 1) {
mask |= 1;
}
if (lastReturnedNum > 0) {
mask |= 2;
}
return mask;
}
public static void searchMessagesInChat(String query, long dialog_id, final int guid, int direction) {
if (reqId != 0) {
ConnectionsManager.getInstance().cancelRpc(reqId, true);
reqId = 0;
}
int max_id = 0;
if (query == null || query.length() == 0) {
if (direction == 1) {
lastReturnedNum++;
if (lastReturnedNum < searchResultMessages.size()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask());
return;
} else {
if (messagesSearchEndReached) {
lastReturnedNum--;
return;
}
query = lastSearchQuery;
max_id = searchResultMessages.get(searchResultMessages.size() - 1).getId();
}
} else if (direction == 2) {
lastReturnedNum--;
if (lastReturnedNum < 0) {
lastReturnedNum = 0;
return;
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask());
return;
} else {
return;
}
}
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.limit = 21;
int lower_part = (int) dialog_id;
if (lower_part < 0) {
req.peer = new TLRPC.TL_inputPeerChat();
req.peer.chat_id = -lower_part;
} else {
TLRPC.User user = MessagesController.getInstance().getUser(lower_part);
if (user == null) {
return;
}
if (user.access_hash != 0) {
req.peer = new TLRPC.TL_inputPeerForeign();
req.peer.access_hash = user.access_hash;
} else {
req.peer = new TLRPC.TL_inputPeerContact();
}
req.peer.user_id = lower_part;
}
req.q = query;
req.max_id = max_id;
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
final int currentReqId = ++lastReqId;
lastSearchQuery = query;
reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(final TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (currentReqId == lastReqId) {
if (error == null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true);
MessagesController.getInstance().putUsers(res.users, false);
MessagesController.getInstance().putChats(res.chats, false);
if (req.max_id == 0) {
lastReturnedNum = 0;
searchResultMessages.clear();
}
boolean added = false;
for (int a = 0; a < Math.min(res.messages.size(), 20); a++) {
TLRPC.Message message = res.messages.get(a);
added = true;
searchResultMessages.add(new MessageObject(message, null, false));
}
messagesSearchEndReached = res.messages.size() != 21;
if (searchResultMessages.isEmpty()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask());
} else {
if (added) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask());
}
}
}
}
reqId = 0;
}
});
}
}, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors);
}
}
......@@ -55,7 +55,10 @@ public class SharedMediaQuery {
req.peer.chat_id = -lower_part;
} else {
TLRPC.User user = MessagesController.getInstance().getUser(lower_part);
if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) {
if (user == null) {
return;
}
if (user.access_hash != 0) {
req.peer = new TLRPC.TL_inputPeerForeign();
req.peer.access_hash = user.access_hash;
} else {
......@@ -98,7 +101,10 @@ public class SharedMediaQuery {
req.peer.chat_id = -lower_part;
} else {
TLRPC.User user = MessagesController.getInstance().getUser(lower_part);
if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) {
if (user == null) {
return;
}
if (user.access_hash != 0) {
req.peer = new TLRPC.TL_inputPeerForeign();
req.peer.access_hash = user.access_hash;
} else {
......
......@@ -5030,7 +5030,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
* @see #notifyItemRangeInserted(int, int)
* @see #notifyItemRangeRemoved(int, int)
*/
public final void notifyDataSetChanged() {
public void notifyDataSetChanged() {
mObservable.notifyChanged();
}
......@@ -5045,7 +5045,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
*
* @see #notifyItemRangeChanged(int, int)
*/
public final void notifyItemChanged(int position) {
public void notifyItemChanged(int position) {
mObservable.notifyItemRangeChanged(position, 1);
}
......@@ -5062,7 +5062,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
*
* @see #notifyItemChanged(int)
*/
public final void notifyItemRangeChanged(int positionStart, int itemCount) {
public void notifyItemRangeChanged(int positionStart, int itemCount) {
mObservable.notifyItemRangeChanged(positionStart, itemCount);
}
......@@ -5079,7 +5079,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
*
* @see #notifyItemRangeInserted(int, int)
*/
public final void notifyItemInserted(int position) {
public void notifyItemInserted(int position) {
mObservable.notifyItemRangeInserted(position, 1);
}
......@@ -5094,7 +5094,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
* @param fromPosition Previous position of the item.
* @param toPosition New position of the item.
*/
public final void notifyItemMoved(int fromPosition, int toPosition) {
public void notifyItemMoved(int fromPosition, int toPosition) {
mObservable.notifyItemMoved(fromPosition, toPosition);
}
......@@ -5113,7 +5113,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
*
* @see #notifyItemInserted(int)
*/
public final void notifyItemRangeInserted(int positionStart, int itemCount) {
public void notifyItemRangeInserted(int positionStart, int itemCount) {
mObservable.notifyItemRangeInserted(positionStart, itemCount);
}
......@@ -5130,7 +5130,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
*
* @see #notifyItemRangeRemoved(int, int)
*/
public final void notifyItemRemoved(int position) {
public void notifyItemRemoved(int position) {
mObservable.notifyItemRangeRemoved(position, 1);
}
......@@ -5147,7 +5147,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView {
* @param positionStart Previous position of the first item that was removed
* @param itemCount Number of items removed from the data set
*/
public final void notifyItemRangeRemoved(int positionStart, int itemCount) {
public void notifyItemRangeRemoved(int positionStart, int itemCount) {
mObservable.notifyItemRangeRemoved(positionStart, itemCount);
}
}
......
......@@ -10,7 +10,7 @@ package org.telegram.messenger;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static int BUILD_VERSION = 542;
public static int BUILD_VERSION = 572;
public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id
public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id
public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here";
......
......@@ -297,6 +297,9 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
}
} else if (message instanceof TLRPC.Server_DH_Params) {
if (message instanceof TLRPC.TL_server_DH_params_ok) {
if (authNewNonce == null) {
return;
}
TLRPC.TL_server_DH_params_ok serverDhParams = (TLRPC.TL_server_DH_params_ok)message;
SerializedData tmpAesKey = new SerializedData();
......
......@@ -132,7 +132,7 @@ public class UserConfig {
int ver = data.readInt32(false);
if (ver == 1) {
int constructor = data.readInt32(false);
currentUser = TLRPC.TL_userSelf.TLdeserialize(data, constructor, false);
currentUser = TLRPC.User.TLdeserialize(data, constructor, false);
MessagesStorage.lastDateValue = data.readInt32(false);
MessagesStorage.lastPtsValue = data.readInt32(false);
MessagesStorage.lastSeqValue = data.readInt32(false);
......@@ -159,7 +159,7 @@ public class UserConfig {
});
} else if (ver == 2) {
int constructor = data.readInt32(false);
currentUser = TLRPC.TL_userSelf.TLdeserialize(data, constructor, false);
currentUser = TLRPC.User.TLdeserialize(data, constructor, false);
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
registeredForPush = preferences.getBoolean("registeredForPush", false);
......@@ -211,7 +211,7 @@ public class UserConfig {
byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
if (userBytes != null) {
SerializedData data = new SerializedData(userBytes);
currentUser = TLRPC.TL_userSelf.TLdeserialize(data, data.readInt32(false), false);
currentUser = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.cleanup();
}
}
......
......@@ -270,7 +270,7 @@ public class Utilities {
}
public static boolean arraysEquals(byte[] arr1, int offset1, byte[] arr2, int offset2) {
if (arr1 == null || arr2 == null || arr1.length - offset1 != arr2.length - offset2 || arr1.length - offset1 < 0) {
if (arr1 == null || arr2 == null || offset1 < 0 || offset2 < 0 || arr1.length - offset1 != arr2.length - offset2 || arr1.length - offset1 < 0 || arr2.length - offset2 < 0) {
return false;
}
boolean result = true;
......
......@@ -25,6 +25,7 @@ import android.widget.FrameLayout;
import android.widget.ListView;
import org.telegram.android.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
......@@ -147,7 +148,7 @@ public class DrawerLayoutContainer extends FrameLayout {
}
requestLayout();
final int newVisibility = drawerPosition > 0 ? VISIBLE : INVISIBLE;
final int newVisibility = drawerPosition > 0 ? VISIBLE : GONE;
if (drawerLayout.getVisibility() != newVisibility) {
drawerLayout.setVisibility(newVisibility);
}
......@@ -393,10 +394,14 @@ public class DrawerLayoutContainer extends FrameLayout {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (drawerLayout != child) {
child.layout(lp.leftMargin, lp.topMargin, lp.leftMargin + child.getMeasuredWidth(), lp.topMargin + child.getMeasuredHeight());
} else {
child.layout(-child.getMeasuredWidth() + (int)drawerPosition, lp.topMargin, (int)drawerPosition, lp.topMargin + child.getMeasuredHeight());
try {
if (drawerLayout != child) {
child.layout(lp.leftMargin, lp.topMargin, lp.leftMargin + child.getMeasuredWidth(), lp.topMargin + child.getMeasuredHeight());
} else {
child.layout(-child.getMeasuredWidth() + (int)drawerPosition, lp.topMargin, (int)drawerPosition, lp.topMargin + child.getMeasuredHeight());
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
inLayout = false;
......
......@@ -51,7 +51,7 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
}
public void destroy() {
public void onDestroy() {
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.FileDidFailedLoad);
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment