Commit 9d113ccb authored by DrKLO's avatar DrKLO

Merge branch 'dev'

parents 2f874619 f6655078
......@@ -3,7 +3,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
classpath 'com.android.tools.build:gradle:1.1.3'
}
}
apply plugin: 'com.android.application'
......@@ -13,7 +13,7 @@ repositories {
}
dependencies {
compile 'com.android.support:support-v4:21.0.+'
compile 'com.android.support:support-v4:22.0.+'
compile 'com.google.android.gms:play-services:3.2.+'
compile 'net.hockeyapp.android:HockeySDK:3.5.+'
compile 'com.googlecode.mp4parser:isoparser:1.0.+'
......@@ -21,8 +21,8 @@ dependencies {
}
android {
compileSdkVersion 21
buildToolsVersion '21.1.2'
compileSdkVersion 22
buildToolsVersion '22.0.1'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
......@@ -81,8 +81,8 @@ android {
defaultConfig {
minSdkVersion 8
targetSdkVersion 21
versionCode 423
versionName "2.4.0"
targetSdkVersion 22
versionCode 492
versionName "2.7.0"
}
}
......@@ -24,7 +24,7 @@
android:label="@string/AppName"
android:theme="@style/Theme.TMessages.Start"
android:name=".ApplicationLoader"
android:hardwareAccelerated="true"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:largeHeap="true">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyCTNmNqbWovP9ETcAob98YlrfOQEAC0CJ4" />
......
......@@ -9,7 +9,7 @@
android:label="@string/AppName"
android:theme="@style/Theme.TMessages.Start"
android:name=".ApplicationLoader"
android:hardwareAccelerated="true"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:largeHeap="true">
</application>
......
......@@ -24,7 +24,7 @@
android:label="@string/AppName"
android:theme="@style/Theme.TMessages.Start"
android:name=".ApplicationLoader"
android:hardwareAccelerated="true"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:largeHeap="true">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyA-t0jLPjUt2FxrA8VPK2EiYHcYcboIR6k" />
......
......@@ -104,7 +104,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_STATIC_LIBRARIES := webp sqlite
LOCAL_MODULE := tmessages.5
LOCAL_MODULE := tmessages.7
LOCAL_CFLAGS := -w -std=gnu99 -O2 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math
......
......@@ -21,6 +21,9 @@ jmethodID jclass_Bitmap_createBitmap;
jclass jclass_Config;
jfieldID jclass_Config_ARGB_8888;
const uint32_t PGPhotoEnhanceHistogramBins = 256;
const uint32_t PGPhotoEnhanceSegments = 4;
jclass createGlobarRef(JNIEnv *env, jclass class) {
if (class) {
return (*env)->NewGlobalRef(env, class);
......@@ -312,6 +315,115 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl
AndroidBitmap_unlockPixels(env, bitmap);
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_calcCDT(JNIEnv *env, jclass class, jobject hsvBuffer, int width, int height, jobject buffer) {
float imageWidth = width;
float imageHeight = height;
float _clipLimit = 1.25f;
uint32_t totalSegments = PGPhotoEnhanceSegments * PGPhotoEnhanceSegments;
uint32_t tileArea = (uint32_t)(floorf(imageWidth / PGPhotoEnhanceSegments) * floorf(imageHeight / PGPhotoEnhanceSegments));
uint32_t clipLimit = (uint32_t)max(1, _clipLimit * tileArea / (float) PGPhotoEnhanceHistogramBins);
float scale = 255.0f / (float) tileArea;
unsigned char *bytes = (*env)->GetDirectBufferAddress(env, hsvBuffer);
uint32_t **hist = calloc(totalSegments, sizeof(uint32_t *));
uint32_t **cdfs = calloc(totalSegments, sizeof(uint32_t *));
uint32_t *cdfsMin = calloc(totalSegments, sizeof(uint32_t));
uint32_t *cdfsMax = calloc(totalSegments, sizeof(uint32_t));
for (uint32_t a = 0; a < totalSegments; a++) {
hist[a] = calloc(PGPhotoEnhanceHistogramBins, sizeof(uint32_t));
cdfs[a] = calloc(PGPhotoEnhanceHistogramBins, sizeof(uint32_t));
}
float xMul = PGPhotoEnhanceSegments / imageWidth;
float yMul = PGPhotoEnhanceSegments / imageHeight;
for (uint32_t y = 0; y < imageHeight; y++) {
uint32_t yOffset = y * width * 4;
for (uint32_t x = 0; x < imageWidth; x++) {
uint32_t index = x * 4 + yOffset;
uint32_t tx = (uint32_t)(x * xMul);
uint32_t ty = (uint32_t)(y * yMul);
uint32_t t = ty * PGPhotoEnhanceSegments + tx;
hist[t][bytes[index + 2]]++;
}
}
for (uint32_t i = 0; i < totalSegments; i++) {
if (clipLimit > 0) {
uint32_t clipped = 0;
for (uint32_t j = 0; j < PGPhotoEnhanceHistogramBins; ++j) {
if (hist[i][j] > clipLimit) {
clipped += hist[i][j] - clipLimit;
hist[i][j] = clipLimit;
}
}
uint32_t redistBatch = clipped / PGPhotoEnhanceHistogramBins;
uint32_t residual = clipped - redistBatch * PGPhotoEnhanceHistogramBins;
for (uint32_t j = 0; j < PGPhotoEnhanceHistogramBins; ++j) {
hist[i][j] += redistBatch;
}
for (uint32_t j = 0; j < residual; ++j) {
hist[i][j]++;
}
}
memcpy(cdfs[i], hist[i], PGPhotoEnhanceHistogramBins * sizeof(uint32_t));
uint32_t hMin = PGPhotoEnhanceHistogramBins - 1;
for (uint32_t j = 0; j < hMin; ++j) {
if (cdfs[j] != 0) {
hMin = j;
}
}
uint32_t cdf = 0;
for (uint32_t j = hMin; j < PGPhotoEnhanceHistogramBins; ++j) {
cdf += cdfs[i][j];
cdfs[i][j] = (uint8_t) min(255, cdf * scale);
}
cdfsMin[i] = cdfs[i][hMin];
cdfsMax[i] = cdfs[i][PGPhotoEnhanceHistogramBins - 1];
}
uint32_t resultSize = 4 * PGPhotoEnhanceHistogramBins * totalSegments;
uint32_t resultBytesPerRow = 4 * PGPhotoEnhanceHistogramBins;
unsigned char *result = (*env)->GetDirectBufferAddress(env, buffer);
for (uint32_t tile = 0; tile < totalSegments; tile++) {
uint32_t yOffset = tile * resultBytesPerRow;
for (uint32_t i = 0; i < PGPhotoEnhanceHistogramBins; i++) {
uint32_t index = i * 4 + yOffset;
result[index] = (uint8_t)cdfs[tile][i];
result[index + 1] = (uint8_t)cdfsMin[tile];
result[index + 2] = (uint8_t)cdfsMax[tile];
result[index + 3] = 255;
}
}
for (uint32_t a = 0; a < totalSegments; a++) {
free(hist[a]);
free(cdfs[a]);
}
free(hist);
free(cdfs);
free(cdfsMax);
free(cdfsMin);
}
JNIEXPORT int Java_org_telegram_messenger_Utilities_pinBitmap(JNIEnv *env, jclass class, jobject bitmap) {
unsigned char *pixels;
return AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 ? 1 : 0;
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_loadBitmap(JNIEnv *env, jclass class, jstring path, jobject bitmap, int scale, int width, int height, int stride) {
AndroidBitmapInfo info;
......
......@@ -43,7 +43,7 @@
<application
android:name=".ApplicationLoader"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:icon="@drawable/ic_launcher"
android:label="@string/AppName"
android:largeHeap="true"
......@@ -52,7 +52,7 @@
<activity
android:name="org.telegram.ui.LaunchActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:hardwareAccelerated="true"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustPan">
<intent-filter>
......
......@@ -28,7 +28,7 @@ public class ByteStream {
private final ArrayList<ByteBufferDesc> queue;
public ByteStream() {
this.queue = new ArrayList<ByteBufferDesc>();
this.queue = new ArrayList<>();
}
public void append(ByteBufferDesc buf) {
......
......@@ -22,17 +22,17 @@ import java.io.IOException;
import java.nio.ByteBuffer;
public interface PyroClientListener {
public void connectedClient(PyroClient client);
void connectedClient(PyroClient client);
public void unconnectableClient(PyroClient client, Exception cause);
void unconnectableClient(PyroClient client, Exception cause);
public void droppedClient(PyroClient client, IOException cause);
void droppedClient(PyroClient client, IOException cause);
public void disconnectedClient(PyroClient client);
void disconnectedClient(PyroClient client);
//
public void receivedData(PyroClient client, ByteBuffer data);
void receivedData(PyroClient client, ByteBuffer data);
public void sentData(PyroClient client, int bytes);
void sentData(PyroClient client, int bytes);
}
......@@ -25,6 +25,7 @@
package org.telegram.PhoneFormat;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLog;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
......@@ -97,9 +98,11 @@ public class PhoneFormat {
}
public void init(String countryCode) {
InputStream stream = null;
ByteArrayOutputStream bos = null;
try {
InputStream stream = ApplicationLoader.applicationContext.getAssets().open("PhoneFormats.dat");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
stream = ApplicationLoader.applicationContext.getAssets().open("PhoneFormats.dat");
bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = stream.read(buf, 0, 1024)) != -1) {
......@@ -111,6 +114,21 @@ public class PhoneFormat {
} catch (Exception e) {
e.printStackTrace();
return;
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
try {
if (stream != null) {
stream.close();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (countryCode != null && countryCode.length() != 0) {
......@@ -119,10 +137,10 @@ public class PhoneFormat {
Locale loc = Locale.getDefault();
defaultCountry = loc.getCountry().toLowerCase();
}
callingCodeOffsets = new HashMap<String, Integer>(255);
callingCodeCountries = new HashMap<String, ArrayList<String>>(255);
callingCodeData = new HashMap<String, CallingCodeInfo>(10);
countryCallingCode = new HashMap<String, String>(255);
callingCodeOffsets = new HashMap<>(255);
callingCodeCountries = new HashMap<>(255);
callingCodeData = new HashMap<>(10);
countryCallingCode = new HashMap<>(255);
parseDataHeader();
initialzed = true;
......@@ -293,7 +311,7 @@ public class PhoneFormat {
offset += 2;
ArrayList<String> strs = new ArrayList<String>(5);
ArrayList<String> strs = new ArrayList<>(5);
String str;
while ((str = valueString(offset)).length() != 0) {
strs.add(str);
......@@ -302,14 +320,14 @@ public class PhoneFormat {
res.trunkPrefixes = strs;
offset++;
strs = new ArrayList<String>(5);
strs = new ArrayList<>(5);
while ((str = valueString(offset)).length() != 0) {
strs.add(str);
offset += str.length() + 1;
}
res.intlPrefixes = strs;
ArrayList<RuleSet> ruleSets = new ArrayList<RuleSet>(setCnt);
ArrayList<RuleSet> ruleSets = new ArrayList<>(setCnt);
offset = start + block1Len;
for (int s = 0; s < setCnt; s++) {
RuleSet ruleSet = new RuleSet();
......@@ -317,7 +335,7 @@ public class PhoneFormat {
offset += 2;
int ruleCnt = value16(offset);
offset += 2;
ArrayList<PhoneRule> rules = new ArrayList<PhoneRule>(ruleCnt);
ArrayList<PhoneRule> rules = new ArrayList<>(ruleCnt);
for (int r = 0; r < ruleCnt; r++) {
PhoneRule rule = new PhoneRule();
rule.minVal = value32(offset);
......@@ -380,7 +398,7 @@ public class PhoneFormat {
callingCodeOffsets.put(callingCode, offset);
ArrayList<String> countries = callingCodeCountries.get(callingCode);
if (countries == null) {
countries = new ArrayList<String>();
countries = new ArrayList<>();
callingCodeCountries.put(callingCode, countries);
}
countries.add(country);
......
......@@ -344,7 +344,7 @@ public class ImageLoader {
});
}
});
AndroidUtilities.runOnUIThread(new Runnable() {
imageLoadQueue.postRunnable(new Runnable() {
@Override
public void run() {
runHttpTasks(true);
......@@ -354,7 +354,7 @@ public class ImageLoader {
@Override
protected void onCancelled() {
AndroidUtilities.runOnUIThread(new Runnable() {
imageLoadQueue.postRunnable(new Runnable() {
@Override
public void run() {
runHttpTasks(true);
......@@ -449,6 +449,11 @@ public class ImageLoader {
originalBitmap = scaledBitmap;
FileOutputStream stream = new FileOutputStream(thumbFile);
originalBitmap.compress(Bitmap.CompressFormat.JPEG, 60, stream);
try {
stream.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
final BitmapDrawable bitmapDrawable = new BitmapDrawable(originalBitmap);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
......@@ -615,7 +620,9 @@ public class ImageLoader {
if (mediaId != null) {
MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, opts);
} else {
BitmapFactory.decodeFile(cacheImage.finalFilePath.getAbsolutePath(), opts);
FileInputStream is = new FileInputStream(cacheFileFinal);
image = BitmapFactory.decodeStream(is, null, opts);
is.close();
}
float photoW = opts.outWidth;
......@@ -633,14 +640,18 @@ public class ImageLoader {
}
}
if (cacheImage.filter == null || blur) {
if (cacheImage.filter == null || blur || cacheImage.httpUrl != null) {
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
} else {
opts.inPreferredConfig = Bitmap.Config.RGB_565;
}
//if (Build.VERSION.SDK_INT < 21) {
// opts.inPurgeable = true;
//}
opts.inDither = false;
if (mediaId != null) {
image = MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, null);
image = MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, opts);
}
if (image == null) {
if (isWebp) {
......@@ -1057,6 +1068,12 @@ public class ImageLoader {
FileLog.e("tmessages", e);
}
}
try {
new File(cachePath, ".nomedia").createNewFile();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
FileLog.e("tmessages", "cache path = " + cachePath);
......@@ -1678,42 +1695,47 @@ public class ImageLoader {
runHttpFileLoadTasks(null, 0);
}
private void runHttpFileLoadTasks(HttpFileTask oldTask, int reason) {
if (oldTask != null) {
currentHttpFileLoadTasksCount--;
}
if (oldTask != null) {
if (reason == 1) {
if (oldTask.canRetry) {
final HttpFileTask newTask = new HttpFileTask(oldTask.url, oldTask.tempFile, oldTask.ext);
Runnable runnable = new Runnable() {
@Override
public void run() {
httpFileLoadTasks.add(newTask);
runHttpFileLoadTasks(null, 0);
private void runHttpFileLoadTasks(final HttpFileTask oldTask, final int reason) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (oldTask != null) {
currentHttpFileLoadTasksCount--;
}
if (oldTask != null) {
if (reason == 1) {
if (oldTask.canRetry) {
final HttpFileTask newTask = new HttpFileTask(oldTask.url, oldTask.tempFile, oldTask.ext);
Runnable runnable = new Runnable() {
@Override
public void run() {
httpFileLoadTasks.add(newTask);
runHttpFileLoadTasks(null, 0);
}
};
retryHttpsTasks.put(oldTask.url, runnable);
AndroidUtilities.runOnUIThread(runnable, 1000);
} else {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidFailedLoad, oldTask.url);
}
};
retryHttpsTasks.put(oldTask.url, runnable);
AndroidUtilities.runOnUIThread(runnable, 1000);
} else {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidFailedLoad, oldTask.url);
} else if (reason == 2) {
httpFileLoadTasksByKeys.remove(oldTask.url);
File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(oldTask.url) + "." + oldTask.ext);
String result = oldTask.tempFile.renameTo(file) ? file.toString() : oldTask.tempFile.toString();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidLoaded, oldTask.url, result);
}
}
while (currentHttpFileLoadTasksCount < 2 && !httpFileLoadTasks.isEmpty()) {
HttpFileTask task = httpFileLoadTasks.poll();
if (android.os.Build.VERSION.SDK_INT >= 11) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
} else {
task.execute(null, null, null);
}
currentHttpFileLoadTasksCount++;
}
} else if (reason == 2) {
httpFileLoadTasksByKeys.remove(oldTask.url);
File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(oldTask.url) + "." + oldTask.ext);
String result = oldTask.tempFile.renameTo(file) ? file.toString() : oldTask.tempFile.toString();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidLoaded, oldTask.url, result);
}
}
while (currentHttpFileLoadTasksCount < 2 && !httpFileLoadTasks.isEmpty()) {
HttpFileTask task = httpFileLoadTasks.poll();
if (android.os.Build.VERSION.SDK_INT >= 11) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
} else {
task.execute(null, null, null);
}
currentHttpFileLoadTasksCount++;
}
});
}
public static Bitmap loadBitmap(String path, Uri uri, float maxWidth, float maxHeight, boolean useMaxScale) {
......@@ -1963,6 +1985,15 @@ public class ImageLoader {
}
}
}
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
if (message.media.webpage.photo != null) {
for (TLRPC.PhotoSize size : message.media.webpage.photo.sizes) {
if (size instanceof TLRPC.TL_photoCachedSize) {
photoSize = size;
break;
}
}
}
}
if (photoSize != null && photoSize.bytes != null && photoSize.bytes.length != 0) {
if (photoSize.location instanceof TLRPC.TL_fileLocationUnavailable) {
......@@ -2000,6 +2031,13 @@ public class ImageLoader {
message.media.video.thumb = newPhotoSize;
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
message.media.document.thumb = newPhotoSize;
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
for (int a = 0; a < message.media.webpage.photo.sizes.size(); a++) {
if (message.media.webpage.photo.sizes.get(a) instanceof TLRPC.TL_photoCachedSize) {
message.media.webpage.photo.sizes.set(a, newPhotoSize);
break;
}
}
}
}
}
......
......@@ -29,8 +29,8 @@ import org.telegram.messenger.Utilities;
public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate {
public static interface ImageReceiverDelegate {
public void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb);
public interface ImageReceiverDelegate {
void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb);
}
private View parentView;
......@@ -68,7 +68,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private Matrix shaderMatrix;
private int alpha = 255;
private boolean isPressed;
private boolean disableRecycle;
private int orientation;
private boolean centerRotation;
private ImageReceiverDelegate delegate;
public ImageReceiver() {
......@@ -209,12 +210,17 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return isPressed;
}
public void setImageBitmap(Bitmap bitmap) {
setImageBitmap(bitmap != null ? new BitmapDrawable(null, bitmap) : null);
public void setOrientation(int angle, boolean center) {
orientation = angle;
centerRotation = center;
}
public void setDisableRecycle(boolean value) {
disableRecycle = value;
public int getOrientation() {
return orientation;
}
public void setImageBitmap(Bitmap bitmap) {
setImageBitmap(bitmap != null ? new BitmapDrawable(null, bitmap) : null);
}
public void setImageBitmap(Drawable bitmap) {
......@@ -280,8 +286,17 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
canvas.drawRoundRect(roundRect, roundRadius, roundRadius, roundPaint);
}
} else {
int bitmapW = bitmapDrawable.getIntrinsicWidth();
int bitmapH = bitmapDrawable.getIntrinsicHeight();
int bitmapW;
int bitmapH;
int originalW = bitmapDrawable.getIntrinsicWidth();
int originalH = bitmapDrawable.getIntrinsicHeight();
if (orientation == 90 || orientation == 270) {
bitmapW = bitmapDrawable.getIntrinsicHeight();
bitmapH = bitmapDrawable.getIntrinsicWidth();
} else {
bitmapW = bitmapDrawable.getIntrinsicWidth();
bitmapH = bitmapDrawable.getIntrinsicHeight();
}
float scaleW = bitmapW / (float) imageW;
float scaleH = bitmapH / (float) imageH;
......@@ -312,14 +327,32 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
canvas.save();
canvas.clipRect(imageX, imageY, imageX + imageW, imageY + imageH);
if (orientation != 0) {
if (centerRotation) {
canvas.rotate(orientation, imageW / 2, imageH / 2);
} else {
canvas.rotate(orientation, 0, 0);
}
}
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
originalW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2, imageY, imageX + (bitmapW + imageW) / 2, imageY + imageH);
} else {
bitmapH /= scaleW;
originalH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2, imageX + imageW, imageY + (bitmapH + imageH) / 2);
}
bitmapDrawable.setBounds(drawRegion);
if (orientation == 90 || orientation == 270) {
int width = (drawRegion.right - drawRegion.left) / 2;
int height = (drawRegion.bottom - drawRegion.top) / 2;
int centerX = (drawRegion.right + drawRegion.left) / 2;
int centerY = (drawRegion.top + drawRegion.bottom) / 2;
bitmapDrawable.setBounds(centerX - height, centerY - width, centerX + height, centerY + width);
} else {
bitmapDrawable.setBounds(drawRegion);
}
if (isVisible) {
try {
bitmapDrawable.setAlpha(alpha);
......@@ -339,8 +372,24 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
canvas.restore();
} else {
canvas.save();
if (orientation != 0) {
if (centerRotation) {
canvas.rotate(orientation, imageW / 2, imageH / 2);
} else {
canvas.rotate(orientation, 0, 0);
}
}
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
bitmapDrawable.setBounds(drawRegion);
if (orientation == 90 || orientation == 270) {
int width = (drawRegion.right - drawRegion.left) / 2;
int height = (drawRegion.bottom - drawRegion.top) / 2;
int centerX = (drawRegion.right + drawRegion.left) / 2;
int centerY = (drawRegion.top + drawRegion.bottom) / 2;
bitmapDrawable.setBounds(centerX - height, centerY - width, centerX + height, centerY + width);
} else {
bitmapDrawable.setBounds(drawRegion);
}
if (isVisible) {
try {
bitmapDrawable.setAlpha(alpha);
......@@ -357,6 +406,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
FileLog.e("tmessages", e);
}
}
canvas.restore();
}
}
}
......@@ -391,6 +441,16 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return null;
}
public int getBitmapWidth() {
Bitmap bitmap = getBitmap();
return orientation == 0 || orientation == 180 ? bitmap.getWidth() : bitmap.getHeight();
}
public int getBitmapHeight() {
Bitmap bitmap = getBitmap();
return orientation == 0 || orientation == 180 ? bitmap.getHeight() : bitmap.getWidth();
}
public void setVisible(boolean value, boolean invalidate) {
if (isVisible == value) {
return;
......@@ -432,10 +492,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return imageX;
}
public int getImageX2() {
return imageX + imageW;
}
public int getImageY() {
return imageY;
}
public int getImageY2() {
return imageY + imageH;
}
public int getImageWidth() {
return imageW;
}
......@@ -617,7 +685,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (newKey != null) {
newBitmap = ImageLoader.getInstance().getImageFromMemory(newKey);
}
if (key == null || image == null || image == newBitmap || disableRecycle) {
if (key == null || image == null || image == newBitmap) {
return;
}
Bitmap bitmap = image.getBitmap();
......
......@@ -54,6 +54,7 @@ public class LocaleController {
public static FastDateFormat formatterWeek;
public static FastDateFormat formatterMonth;
public static FastDateFormat formatterYear;
public static FastDateFormat formatterMonthYear;
public static FastDateFormat formatterYearMax;
public static FastDateFormat chatDate;
public static FastDateFormat chatFullDate;
......@@ -135,7 +136,7 @@ public class LocaleController {
addRules(new String[]{"bem", "brx", "da", "de", "el", "en", "eo", "es", "et", "fi", "fo", "gl", "he", "iw", "it", "nb",
"nl", "nn", "no", "sv", "af", "bg", "bn", "ca", "eu", "fur", "fy", "gu", "ha", "is", "ku",
"lb", "ml", "mr", "nah", "ne", "om", "or", "pa", "pap", "ps", "so", "sq", "sw", "ta", "te",
"tk", "ur", "zu", "mn", "gsw", "chr", "rm", "pt"}, new PluralRules_One());
"tk", "ur", "zu", "mn", "gsw", "chr", "rm", "pt", "an", "ast"}, new PluralRules_One());
addRules(new String[]{"cs", "sk"}, new PluralRules_Czech());
addRules(new String[]{"ff", "fr", "kab"}, new PluralRules_French());
addRules(new String[]{"hr", "ru", "sr", "uk", "be", "bs", "sh"}, new PluralRules_Balkan());
......@@ -443,10 +444,12 @@ public class LocaleController {
}
private HashMap<String, String> getLocaleFileStrings(File file) {
FileInputStream stream = null;
try {
HashMap<String, String> stringMap = new HashMap<>();
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new FileInputStream(file), "UTF-8");
stream = new FileInputStream(file);
parser.setInput(stream, "UTF-8");
int eventType = parser.getEventType();
String name = null;
String value = null;
......@@ -483,6 +486,15 @@ public class LocaleController {
return stringMap;
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
try {
if (stream != null) {
stream.close();
stream = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
return null;
}
......@@ -544,6 +556,9 @@ public class LocaleController {
currentLocale = newLocale;
currentLocaleInfo = localeInfo;
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = allRules.get("en");
}
changingConfiguration = true;
Locale.setDefault(currentLocale);
android.content.res.Configuration config = new android.content.res.Configuration();
......@@ -571,6 +586,9 @@ public class LocaleController {
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
}
if (value == null) {
value = "LOC_ERR:" + key;
}
return value;
}
......@@ -638,6 +656,9 @@ public class LocaleController {
}
currentLocale = newLocale;
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = allRules.get("en");
}
}
}
}
......@@ -695,6 +716,20 @@ public class LocaleController {
}
}
private FastDateFormat createFormatter(Locale locale, String format, String defaultFormat) {
if (format == null || format.length() == 0) {
format = defaultFormat;
}
FastDateFormat formatter = null;
try {
formatter = FastDateFormat.getInstance(format, locale);
} catch (Exception e) {
format = defaultFormat;
formatter = FastDateFormat.getInstance(format, locale);
}
return formatter;
}
public void recreateFormatters() {
Locale locale = currentLocale;
if (locale == null) {
......@@ -706,59 +741,15 @@ public class LocaleController {
}
isRTL = lang.toLowerCase().equals("ar");
nameDisplayOrder = lang.toLowerCase().equals("ko") ? 2 : 1;
String formatString = getStringInternal("formatterMonth", R.string.formatterMonth);
if (formatString == null || formatString.length() == 0) {
formatString = "dd MMM";
}
formatterMonth = FastDateFormat.getInstance(formatString, locale);
formatString = getStringInternal("formatterYear", R.string.formatterYear);
if (formatString == null || formatString.length() == 0) {
formatString = "dd.MM.yy";
}
formatterYear = FastDateFormat.getInstance(formatString, locale);
formatString = getStringInternal("formatterYearMax", R.string.formatterYearMax);
if (formatString == null || formatString.length() == 0) {
formatString = "dd.MM.yyyy";
}
formatterYearMax = FastDateFormat.getInstance(formatString, locale);
formatString = getStringInternal("chatDate", R.string.chatDate);
if (formatString == null || formatString.length() == 0) {
formatString = "d MMMM";
}
chatDate = FastDateFormat.getInstance(formatString, locale);
formatString = getStringInternal("chatFullDate", R.string.chatFullDate);
if (formatString == null || formatString.length() == 0) {
formatString = "d MMMM yyyy";
}
chatFullDate = FastDateFormat.getInstance(formatString, locale);
formatString = getStringInternal("formatterWeek", R.string.formatterWeek);
if (formatString == null || formatString.length() == 0) {
formatString = "EEE";
}
formatterWeek = FastDateFormat.getInstance(formatString, locale);
if (is24HourFormat) {
formatString = getStringInternal("formatterDay24H", R.string.formatterDay24H);
} else {
formatString = getStringInternal("formatterDay12H", R.string.formatterDay12H);
}
if (formatString == null || formatString.length() == 0) {
if (is24HourFormat) {
formatString = "HH:mm";
} else {
formatString = "h:mm a";
}
}
if (lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko")) {
formatterDay = FastDateFormat.getInstance(formatString, locale);
} else {
formatterDay = FastDateFormat.getInstance(formatString, Locale.US);
}
formatterMonth = createFormatter(locale, getStringInternal("formatterMonth", R.string.formatterMonth), "dd MMM");
formatterYear = createFormatter(locale, getStringInternal("formatterYear", R.string.formatterYear), "dd.MM.yy");
formatterYearMax = createFormatter(locale, getStringInternal("formatterYearMax", R.string.formatterYearMax), "dd.MM.yyyy");
chatDate = createFormatter(locale, getStringInternal("chatDate", R.string.chatDate), "d MMMM");
chatFullDate = createFormatter(locale, getStringInternal("chatFullDate", R.string.chatFullDate), "d MMMM yyyy");
formatterWeek = createFormatter(locale, getStringInternal("formatterWeek", R.string.formatterWeek), "EEE");
formatterMonthYear = createFormatter(locale, getStringInternal("formatterMonthYear", R.string.formatterMonthYear), "MMMM yyyy");
formatterDay = createFormatter(lang.toLowerCase().equals("ar") || lang.toLowerCase().equals("ko") ? locale : Locale.US, is24HourFormat ? getStringInternal("formatterDay24H", R.string.formatterDay24H) : getStringInternal("formatterDay12H", R.string.formatterDay12H), is24HourFormat ? "HH:mm" : "h:mm a");
}
public static String stringForMessageListDate(long date) {
......
......@@ -23,7 +23,7 @@ import java.util.zip.ZipFile;
public class NativeLoader {
private final static int LIB_VERSION = 5;
private final static int LIB_VERSION = 7;
private final static String LIB_NAME = "tmessages." + LIB_VERSION;
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";
......
......@@ -48,6 +48,14 @@ public class NotificationCenter {
public static final int updateMessageMedia = totalEvents++;
public static final int recentImagesDidLoaded = totalEvents++;
public static final int replaceMessagesObjects = totalEvents++;
public static final int didSetPasscode = totalEvents++;
public static final int didSetTwoStepPassword = totalEvents++;
public static final int screenStateChanged = totalEvents++;
public static final int appSwitchedToForeground = totalEvents++;
public static final int didLoadedReplyMessages = totalEvents++;
public static final int newSessionReceived = totalEvents++;
public static final int didReceivedWebpages = totalEvents++;
public static final int didReceivedWebpagesInUpdates = totalEvents++;
public static final int httpFileDidLoaded = totalEvents++;
public static final int httpFileDidFailedLoad = totalEvents++;
......@@ -60,7 +68,6 @@ public class NotificationCenter {
public static final int didReceiveSmsCode = totalEvents++;
public static final int emojiDidLoaded = totalEvents++;
public static final int appDidLogout = totalEvents++;
public static final int needPasswordEnter = totalEvents++;
public static final int FileDidUpload = totalEvents++;
public static final int FileDidFailUpload = totalEvents++;
......@@ -106,7 +113,7 @@ public class NotificationCenter {
}
public interface NotificationCenterDelegate {
public abstract void didReceivedNotification(int id, Object... args);
void didReceivedNotification(int id, Object... args);
}
public void postNotificationName(int id, Object... args) {
......
......@@ -28,5 +28,6 @@ public class ScreenReceiver extends BroadcastReceiver {
ConnectionsManager.getInstance().setAppPaused(false, true);
ApplicationLoader.isScreenOn = true;
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.screenStateChanged);
}
}
......@@ -119,7 +119,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -224,7 +224,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -252,7 +252,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -283,7 +283,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -312,7 +312,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -343,7 +343,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -375,7 +375,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -406,7 +406,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -436,7 +436,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -464,7 +464,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -500,7 +500,7 @@ public class SecretChatHelper {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
reqSend = new TLRPC.TL_decryptedMessageService_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
reqSend.random_bytes = new byte[15];
Utilities.random.nextBytes(reqSend.random_bytes);
}
......@@ -659,7 +659,7 @@ public class SecretChatHelper {
int myLayer = Math.max(17, AndroidUtilities.getMyLayerVersion(chat.layer));
layer.layer = Math.min(myLayer, AndroidUtilities.getPeerLayerVersion(chat.layer));
layer.message = req;
layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
layer.random_bytes = new byte[15];
Utilities.random.nextBytes(layer.random_bytes);
toEncryptObject = layer;
......@@ -795,7 +795,7 @@ public class SecretChatHelper {
@Override
public void run() {
newMsgObj.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.id, newMsgObj.id, newMsgObj);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.id, newMsgObj.id, newMsgObj, false);
SendMessagesHelper.getInstance().processSentMessage(newMsgObj.id);
if (newMsgObj.media instanceof TLRPC.TL_messageMediaVideo) {
SendMessagesHelper.getInstance().stopVideoService(attachPath);
......@@ -1072,8 +1072,8 @@ public class SecretChatHelper {
}
});
MessagesStorage.getInstance().deleteDialog(did, true);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.removeAllMessagesFromDialog, did);
}
});
return null;
......@@ -1104,10 +1104,7 @@ public class SecretChatHelper {
}
byte[] salt = new byte[256];
for (int a = 0; a < 256; a++) {
salt[a] = (byte) (Utilities.random.nextDouble() * 256);
}
Utilities.random.nextBytes(salt);
BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes);
BigInteger g_b = BigInteger.valueOf(MessagesStorage.secretG);
g_b = g_b.modPow(new BigInteger(1, salt), p);
......@@ -1409,9 +1406,7 @@ public class SecretChatHelper {
return;
}
final byte[] salt = new byte[256];
for (int a = 0; a < 256; a++) {
salt[a] = (byte) (Utilities.random.nextDouble() * 256);
}
Utilities.random.nextBytes(salt);
BigInteger i_g_a = BigInteger.valueOf(MessagesStorage.secretG);
i_g_a = i_g_a.modPow(new BigInteger(1, salt), new BigInteger(1, MessagesStorage.secretPBytes));
......@@ -1616,7 +1611,7 @@ public class SecretChatHelper {
}
public void startSecretChat(final Context context, final TLRPC.User user) {
if (user == null) {
if (user == null || context == null) {
return;
}
startingSecretChat = true;
......@@ -1777,6 +1772,10 @@ public class SecretChatHelper {
}
}
});
progressDialog.show();
try {
progressDialog.show();
} catch (Exception e) {
//don't promt
}
}
}
......@@ -51,11 +51,11 @@ public class SmsListener extends BroadcastReceiver {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceiveSmsCode, matcher.group(0));
}
}
} catch (Exception e) {
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
} catch(Exception e) {
} catch(Throwable e) {
FileLog.e("tmessages", e);
}
}
......
......@@ -31,7 +31,7 @@ public class WearReplyReceiver extends BroadcastReceiver {
if (dialog_id == 0 || max_id == 0) {
return;
}
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id);
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true);
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false);
}
}
/*
* This is the source code of Telegram for Android v. 2.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 android.text.TextUtils;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.ImageLoader;
import org.telegram.android.MessageObject;
import org.telegram.android.MessagesStorage;
import org.telegram.android.NotificationCenter;
import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLClassStore;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
public class ReplyMessageQuery {
public static void loadReplyMessagesForMessages(final ArrayList<MessageObject> messages, final long dialog_id) {
final ArrayList<Integer> replyMessages = new ArrayList<>();
final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners = new HashMap<>();
for (MessageObject messageObject : messages) {
if (messageObject.getId() > 0 && messageObject.isReply() && messageObject.replyMessageObject == null) {
Integer id = messageObject.messageOwner.reply_to_msg_id;
ArrayList<MessageObject> messageObjects = replyMessageOwners.get(id);
if (messageObjects == null) {
messageObjects = new ArrayList<>();
replyMessageOwners.put(id, messageObjects);
}
messageObjects.add(messageObject);
if (!replyMessages.contains(id)) {
replyMessages.add(id);
}
}
}
if (replyMessages.isEmpty()) {
return;
}
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
final ArrayList<TLRPC.Message> result = new ArrayList<>();
final ArrayList<TLRPC.User> users = new ArrayList<>();
ArrayList<Integer> loadedUsers = new ArrayList<>();
ArrayList<Integer> fromUser = new ArrayList<>();
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid IN(%s)", TextUtils.join(",", replyMessages)));
while (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.dialog_id = dialog_id;
fromUser.add(message.from_id);
if (message.action != null && message.action.user_id != 0) {
fromUser.add(message.action.user_id);
}
if (message.media != null && message.media.user_id != 0) {
fromUser.add(message.media.user_id);
}
if (message.media != null && message.media.audio != null && message.media.audio.user_id != 0) {
fromUser.add(message.media.audio.user_id);
}
if (message.fwd_from_id != 0) {
fromUser.add(message.fwd_from_id);
}
result.add(message);
replyMessages.remove((Integer) message.id);
}
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
}
cursor.dispose();
StringBuilder usersToLoad = new StringBuilder();
for (int uid : fromUser) {
if (!loadedUsers.contains(uid)) {
if (usersToLoad.length() != 0) {
usersToLoad.append(",");
}
usersToLoad.append(uid);
loadedUsers.add(uid);
}
}
if (usersToLoad.length() != 0) {
MessagesStorage.getInstance().getUsersInternal(usersToLoad.toString(), users);
}
broadcastReplyMessages(result, replyMessageOwners, users, dialog_id);
if (!replyMessages.isEmpty()) {
TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages();
req.id = replyMessages;
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
ImageLoader.saveMessagesThumbs(messagesRes.messages);
broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, dialog_id);
MessagesStorage.getInstance().putUsersAndChats(messagesRes.users, null, true, true);
saveReplyMessages(replyMessageOwners, messagesRes.messages);
}
}
});
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
private static void saveReplyMessages(final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners, final ArrayList<TLRPC.Message> result) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
MessagesStorage.getInstance().getDatabase().beginTransaction();
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("UPDATE messages SET replydata = ? WHERE mid = ?");
for (TLRPC.Message message : result) {
ArrayList<MessageObject> messageObjects = replyMessageOwners.get(message.id);
if (messageObjects != null) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(message.getObjectSize());
message.serializeToStream(data);
for (MessageObject messageObject : messageObjects) {
state.requery();
state.bindByteBuffer(1, data.buffer);
state.bindInteger(2, messageObject.getId());
state.step();
}
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
}
}
state.dispose();
MessagesStorage.getInstance().getDatabase().commitTransaction();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
private static void broadcastReplyMessages(final ArrayList<TLRPC.Message> result, final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners, ArrayList<TLRPC.User> users, final long dialog_id) {
final HashMap<Integer, TLRPC.User> usersHashMap = new HashMap<>();
for (TLRPC.User user : users) {
usersHashMap.put(user.id, user);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
boolean changed = false;
for (TLRPC.Message message : result) {
ArrayList<MessageObject> arrayList = replyMessageOwners.get(message.id);
if (arrayList != null) {
MessageObject messageObject = new MessageObject(message, usersHashMap, false);
for (MessageObject m : arrayList) {
m.replyMessageObject = messageObject;
}
changed = true;
}
}
if (changed) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didLoadedReplyMessages, dialog_id);
}
}
});
}
}
......@@ -59,7 +59,7 @@ public class MP4Builder {
private long dataOffset = 0;
private long writedSinceLastMdat = 0;
private boolean writeNewMdat = true;
private HashMap<Track, long[]> track2SampleSizes = new HashMap<Track, long[]>();
private HashMap<Track, long[]> track2SampleSizes = new HashMap<>();
private ByteBuffer sizeBuffer = null;
public MP4Builder createMovie(Mp4Movie mp4Movie) throws Exception {
......@@ -158,7 +158,7 @@ public class MP4Builder {
}
protected FileTypeBox createFileTypeBox() {
LinkedList<String> minorBrands = new LinkedList<String>();
LinkedList<String> minorBrands = new LinkedList<>();
minorBrands.add("isom");
minorBrands.add("3gp4");
return new FileTypeBox("isom", 0, minorBrands);
......@@ -237,7 +237,10 @@ public class MP4Builder {
}
public long getTimescale(Mp4Movie mp4Movie) {
long timescale = mp4Movie.getTracks().iterator().next().getTimeScale();
long timescale = 0;
if (!mp4Movie.getTracks().isEmpty()) {
timescale = mp4Movie.getTracks().iterator().next().getTimeScale();
}
for (Track track : mp4Movie.getTracks()) {
timescale = gcd(track.getTimeScale(), timescale);
}
......@@ -347,7 +350,7 @@ public class MP4Builder {
protected void createStts(Track track, SampleTableBox stbl) {
TimeToSampleBox.Entry lastEntry = null;
List<TimeToSampleBox.Entry> entries = new ArrayList<TimeToSampleBox.Entry>();
List<TimeToSampleBox.Entry> entries = new ArrayList<>();
for (long delta : track.getSampleDurations()) {
if (lastEntry != null && lastEntry.getDelta() == delta) {
......@@ -418,7 +421,7 @@ public class MP4Builder {
}
protected void createStco(Track track, SampleTableBox stbl) {
ArrayList<Long> chunksOffsets = new ArrayList<Long>();
ArrayList<Long> chunksOffsets = new ArrayList<>();
long lastOffset = -1;
for (Sample sample : track.getSamples()) {
long offset = sample.getOffset();
......
......@@ -28,43 +28,43 @@ public interface Cache {
* @param key Cache key
* @return An {@link Entry} or null in the event of a cache miss
*/
public Entry get(String key);
Entry get(String key);
/**
* Adds or replaces an entry to the cache.
* @param key Cache key
* @param entry Data to store and metadata for cache coherency, TTL, etc.
*/
public void put(String key, Entry entry);
void put(String key, Entry entry);
/**
* Performs any potentially long-running actions needed to initialize the cache;
* will be called from a worker thread.
*/
public void initialize();
void initialize();
/**
* Invalidates an entry in the cache.
* @param key Cache key
* @param fullExpire True to fully expire the entry, false to soft expire
*/
public void invalidate(String key, boolean fullExpire);
void invalidate(String key, boolean fullExpire);
/**
* Removes an entry from the cache.
* @param key Cache key
*/
public void remove(String key);
void remove(String key);
/**
* Empties the cache.
*/
public void clear();
void clear();
/**
* Data and metadata for an entry returned by the cache.
*/
public static class Entry {
class Entry {
/** The data returned from cache. */
public byte[] data;
......
......@@ -26,5 +26,5 @@ public interface Network {
* @return A {@link NetworkResponse} with data and caching metadata; will never be null
* @throws VolleyError on errors
*/
public NetworkResponse performRequest(Request<?> request) throws VolleyError;
NetworkResponse performRequest(Request<?> request) throws VolleyError;
}
......@@ -175,7 +175,7 @@ public class RequestQueue {
* {@link RequestQueue#cancelAll(RequestFilter)}.
*/
public interface RequestFilter {
public boolean apply(Request<?> request);
boolean apply(Request<?> request);
}
/**
......
......@@ -26,7 +26,7 @@ public class Response<T> {
/** Callback interface for delivering parsed responses. */
public interface Listener<T> {
/** Called when a response is received. */
public void onResponse(T response);
void onResponse(T response);
}
/** Callback interface for delivering error responses. */
......@@ -35,7 +35,7 @@ public class Response<T> {
* Callback method that an error has been occurred with the
* provided error code and optional user-readable message.
*/
public void onErrorResponse(VolleyError error);
void onErrorResponse(VolleyError error);
}
/** Returns a successful response containing the parsed result. */
......
......@@ -20,16 +20,16 @@ public interface ResponseDelivery {
/**
* Parses a response from the network or cache and delivers it.
*/
public void postResponse(Request<?> request, Response<?> response);
void postResponse(Request<?> request, Response<?> response);
/**
* Parses a response from the network or cache and delivers it. The provided
* Runnable will be executed after delivery.
*/
public void postResponse(Request<?> request, Response<?> response, Runnable runnable);
void postResponse(Request<?> request, Response<?> response, Runnable runnable);
/**
* Posts an error for the given request.
*/
public void postError(Request<?> request, VolleyError error);
void postError(Request<?> request, VolleyError error);
}
......@@ -24,12 +24,12 @@ public interface RetryPolicy {
/**
* Returns the current timeout (used for logging).
*/
public int getCurrentTimeout();
int getCurrentTimeout();
/**
* Returns the current retry count (used for logging).
*/
public int getCurrentRetryCount();
int getCurrentRetryCount();
/**
* Prepares for the next retry by applying a backoff to the timeout.
......@@ -37,5 +37,5 @@ public interface RetryPolicy {
* @throws VolleyError In the event that the retry could not be performed (for example if we
* ran out of attempts), the passed in error is thrown.
*/
public void retry(VolleyError error) throws VolleyError;
void retry(VolleyError error) throws VolleyError;
}
......@@ -27,10 +27,10 @@ public interface Authenticator {
*
* @throws AuthFailureError If authentication did not succeed
*/
public String getAuthToken() throws AuthFailureError;
String getAuthToken() throws AuthFailureError;
/**
* Invalidates the provided auth token.
*/
public void invalidateAuthToken(String authToken);
void invalidateAuthToken(String authToken);
}
......@@ -17,5 +17,5 @@
package org.telegram.ui.Animation;
public interface TypeEvaluator<T> {
public T evaluate(float fraction, T startValue, T endValue);
T evaluate(float fraction, T startValue, T endValue);
}
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.
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.
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