Commit 56e22d4c authored by DrKLO's avatar DrKLO

Update to 4.2.0

source before release? how this even possible?
parent bcc13a5c
......@@ -602,7 +602,8 @@ LOCAL_C_INCLUDES := \
./jni/boringssl/include \
./jni/breakpad/common/android/include \
./jni/breakpad \
./jni/ffmpeg/include
./jni/ffmpeg/include \
./jni/intro
LOCAL_SRC_FILES += \
./libyuv/source/compare_common.cc \
......@@ -660,6 +661,7 @@ LOCAL_SRC_FILES += \
./utils.c \
./image.c \
./video.c \
./intro/IntroRenderer.c \
./gifvideo.cpp \
./SqliteWrapper.cpp \
./TgNetWrapper.cpp \
......
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef TMESSAGES_INTRO_RENDERER_H
#define TMESSAGES_INTRO_RENDERER_H
#include <GLES2/gl2.h>
extern float scale_factor;
extern int width, height;
extern int y_offset_absolute;
typedef enum {
Default = 0,
EaseIn = 1,
EaseOut = 2,
EaseInEaseOut = 3,
Linear = 4,
Sin = 5,
EaseOutBounce,
TIMING_NUM
} timing_type;
typedef float vec2[2];
typedef float vec4[4];
typedef vec4 mat4x4[4];
typedef enum {NORMAL, NORMAL_ONE, RED, BLUE, LIGHT_RED, LIGHT_BLUE} texture_program_type;
typedef struct {
float x;
float y;
} CPoint;
typedef struct {
float width;
float height;
} CSize;
typedef struct {
float x;
float y;
float z;
} xyz;
typedef struct {
GLuint program;
GLint a_position_location;
GLint a_texture_coordinates_location;
GLint u_mvp_matrix_location;
GLint u_texture_unit_location;
GLint u_alpha_loaction;
} TextureProgram;
typedef struct {
GLuint program;
GLint a_position_location;
GLint u_mvp_matrix_location;
GLint u_color_location;
GLint u_alpha_loaction;
} ColorProgram;
typedef struct {
float side_length;
float start_angle;
float end_angle;
float angle;
CSize size;
float radius;
float width;
} VarParams;
typedef struct {
size_t datasize;
int round_count;
GLenum triangle_mode;
int is_star;
} ConstParams;
typedef struct {
xyz anchor;
xyz position;
float rotation;
xyz scale;
} LayerParams;
typedef struct {
xyz anchor;
xyz position;
float rotation;
xyz scale;
float alpha;
VarParams var_params;
ConstParams const_params;
LayerParams layer_params;
} Params;
typedef struct {
vec4 color;
CPoint *data;
GLuint buffer;
int num_points;
Params params;
} Shape;
typedef struct {
GLuint texture;
CPoint *data;
GLuint buffer;
int num_points;
Params params;
} TexturedShape;
#endif
......@@ -72,6 +72,37 @@ JNIEXPORT jint Java_org_telegram_messenger_Utilities_aesCtrDecryption(JNIEnv *en
return num;
}
JNIEXPORT jint Java_org_telegram_messenger_Utilities_aesCtrDecryptionByteArray(JNIEnv *env, jclass class, jbyteArray buffer, jbyteArray key, jbyteArray iv, int offset, int length, int fileOffset) {
unsigned char *bufferBuff = (unsigned char *)(*env)->GetByteArrayElements(env, buffer, NULL);
unsigned char *keyBuff = (unsigned char *)(*env)->GetByteArrayElements(env, key, NULL);
unsigned char *ivBuff = (unsigned char *)(*env)->GetByteArrayElements(env, iv, NULL);
AES_KEY akey;
uint8_t count[16];
AES_set_encrypt_key(keyBuff, 32 * 8, &akey);
unsigned int num = (unsigned int) (fileOffset % 16);
int o = fileOffset / 16;
ivBuff[15] = (uint8_t) (o & 0xff);
ivBuff[14] = (uint8_t) ((o >> 8) & 0xff);
ivBuff[13] = (uint8_t) ((o >> 16) & 0xff);
ivBuff[12] = (uint8_t) ((o >> 24) & 0xff);
AES_encrypt(ivBuff, count, &akey);
o = (fileOffset + 15) / 16;
ivBuff[15] = (uint8_t) (o & 0xff);
ivBuff[14] = (uint8_t) ((o >> 8) & 0xff);
ivBuff[13] = (uint8_t) ((o >> 16) & 0xff);
ivBuff[12] = (uint8_t) ((o >> 24) & 0xff);
AES_ctr128_encrypt(bufferBuff + offset, bufferBuff + offset, length, &akey, ivBuff, count, &num);
(*env)->ReleaseByteArrayElements(env, key, keyBuff, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, iv, ivBuff, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, buffer, bufferBuff, 0);
return num;
}
JNIEXPORT jstring Java_org_telegram_messenger_Utilities_readlink(JNIEnv *env, jclass class, jstring path) {
static char buf[1000];
char *fileName = (*env)->GetStringUTFChars(env, path, NULL);
......
......@@ -162,6 +162,7 @@
</activity>
<activity
android:name="org.telegram.ui.IntroActivity"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity>
<activity
......@@ -179,15 +180,6 @@
android:resizeableActivity="false"
android:windowSoftInputMode="adjustResize|stateHidden">
</activity>
<activity
android:name=".GoogleVoiceClientActivity"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.voicesearch.SEND_MESSAGE_TO_CONTACTS" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name="org.telegram.ui.VoIPActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
......@@ -266,7 +258,6 @@
<service android:name=".ClearCacheService" android:exported="false"/>
<service android:name=".VideoEncodingService" android:enabled="true"/>
<service android:name=".voip.VoIPService" android:enabled="true"/>
<service android:name=".GoogleVoiceClientService"/>
<service android:name=".MusicPlayerService" android:exported="true" android:enabled="true"/>
<service android:name=".MusicBrowserService" android:exported="true">
<intent-filter>
......
......@@ -60,6 +60,8 @@ import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.view.inputmethod.InputMethodManager;
import android.webkit.MimeTypeMap;
import android.widget.EdgeEffect;
......@@ -120,6 +122,9 @@ public class AndroidUtilities {
public static boolean usingHardwareInput;
public static boolean isInMultiwindow;
public static DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
public static OvershootInterpolator overshootInterpolator = new OvershootInterpolator();
private static Boolean isTablet = null;
private static int adjustOwnerClassGuid = 0;
......@@ -637,11 +642,7 @@ public class AndroidUtilities {
public static int getPhotoSize() {
if (photoSize == null) {
if (Build.VERSION.SDK_INT >= 16) {
photoSize = 1280;
} else {
photoSize = 800;
}
photoSize = 1280;
}
return photoSize;
}
......@@ -1134,7 +1135,8 @@ public class AndroidUtilities {
ForegroundDetector.getInstance().resetBackgroundVar();
}
return UserConfig.passcodeHash.length() > 0 && wasInBackground &&
(UserConfig.appLocked || UserConfig.autoLockIn != 0 && UserConfig.lastPauseTime != 0 && !UserConfig.appLocked && (UserConfig.lastPauseTime + UserConfig.autoLockIn) <= ConnectionsManager.getInstance().getCurrentTime());
(UserConfig.appLocked || UserConfig.autoLockIn != 0 && UserConfig.lastPauseTime != 0 && !UserConfig.appLocked &&
(UserConfig.lastPauseTime + UserConfig.autoLockIn) <= ConnectionsManager.getInstance().getCurrentTime() || ConnectionsManager.getInstance().getCurrentTime() + 5 < UserConfig.lastPauseTime);
}
public static void shakeView(final View view, final float x, final int num) {
......
......@@ -11,8 +11,8 @@ package org.telegram.messenger;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static boolean DEBUG_PRIVATE_VERSION = false;
public static int BUILD_VERSION = 1030;
public static String BUILD_VERSION_STRING = "4.1";
public static int BUILD_VERSION = 1040;
public static String BUILD_VERSION_STRING = "4.2";
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";
......
......@@ -14,4 +14,5 @@ public class DownloadObject {
public TLObject object;
public int type;
public long id;
public boolean secret;
}
......@@ -340,23 +340,32 @@ public class FileLoader {
return result[0];
}
public void loadFile(TLRPC.PhotoSize photo, String ext, boolean cacheOnly) {
loadFile(null, null, photo.location, ext, photo.size, false, cacheOnly || (photo != null && photo.size == 0 || photo.location.key != null));
public void loadFile(TLRPC.PhotoSize photo, String ext, int cacheType) {
if (cacheType == 0 && (photo != null && photo.size == 0 || photo.location.key != null)) {
cacheType = 1;
}
loadFile(null, null, photo.location, ext, photo.size, false, cacheType);
}
public void loadFile(TLRPC.Document document, boolean force, boolean cacheOnly) {
loadFile(document, null, null, null, 0, force, cacheOnly || document != null && document.key != null);
public void loadFile(TLRPC.Document document, boolean force, int cacheType) {
if (cacheType == 0 && (document != null && document.key != null)) {
cacheType = 1;
}
loadFile(document, null, null, null, 0, force, cacheType);
}
public void loadFile(TLRPC.TL_webDocument document, boolean force, boolean cacheOnly) {
loadFile(null, document, null, null, 0, force, cacheOnly);
public void loadFile(TLRPC.TL_webDocument document, boolean force, int cacheType) {
loadFile(null, document, null, null, 0, force, cacheType);
}
public void loadFile(TLRPC.FileLocation location, String ext, int size, boolean cacheOnly) {
loadFile(null, null, location, ext, size, true, cacheOnly || size == 0 || (location != null && location.key != null));
public void loadFile(TLRPC.FileLocation location, String ext, int size, int cacheType) {
if (cacheType == 0 && (size == 0 || location != null && location.key != null)) {
cacheType = 1;
}
loadFile(null, null, location, ext, size, true, cacheType);
}
private void loadFile(final TLRPC.Document document, final TLRPC.TL_webDocument webDocument, final TLRPC.FileLocation location, final String locationExt, final int locationSize, final boolean force, final boolean cacheOnly) {
private void loadFile(final TLRPC.Document document, final TLRPC.TL_webDocument webDocument, final TLRPC.FileLocation location, final String locationExt, final int locationSize, final boolean force, final int cacheType) {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
......@@ -424,8 +433,10 @@ public class FileLoader {
type = MEDIA_DIR_DOCUMENT;
}
}
if (!cacheOnly) {
if (cacheType == 0) {
storeDir = getDirectory(type);
} else if (cacheType == 2) {
operation.setEncryptFile(true);
}
operation.setPaths(storeDir, tempDir);
......@@ -668,13 +679,13 @@ public class FileLoader {
}
} else {
if (message.media instanceof TLRPC.TL_messageMediaDocument) {
return getPathToAttach(message.media.document);
return getPathToAttach(message.media.document, message.media.ttl_seconds != 0);
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
ArrayList<TLRPC.PhotoSize> sizes = message.media.photo.sizes;
if (sizes.size() > 0) {
TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize());
if (sizeFull != null) {
return getPathToAttach(sizeFull);
return getPathToAttach(sizeFull, message.media.ttl_seconds != 0);
}
}
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
......@@ -819,6 +830,10 @@ public class FileLoader {
return "";
}
public static File getInternalCacheDir() {
return ApplicationLoader.applicationContext.getCacheDir();
}
public static String getDocumentExtension(TLRPC.Document document) {
String fileName = getDocumentFileName(document);
int idx = fileName.lastIndexOf('.');
......@@ -911,7 +926,24 @@ public class FileLoader {
public void run() {
for (int a = 0; a < files.size(); a++) {
File file = files.get(a);
if (file.exists()) {
File encrypted = new File(file.getAbsolutePath() + ".enc");
if (encrypted.exists()) {
try {
if (!encrypted.delete()) {
encrypted.deleteOnExit();
}
} catch (Exception e) {
FileLog.e(e);
}
try {
File key = new File(FileLoader.getInternalCacheDir(), file.getName() + ".enc.key");
if (!key.delete()) {
key.deleteOnExit();
}
} catch (Exception e) {
FileLog.e(e);
}
} else if (file.exists()) {
try {
if (!file.delete()) {
file.deleteOnExit();
......
......@@ -9,18 +9,16 @@
package org.telegram.messenger;
public class Intro {
public static native void on_draw_frame();
public static native void set_scroll_offset(float a_offset);
public static native void set_page(int page);
public static native void set_date(float a);
public static native void set_date0(float a);
public static native void set_pages_textures(int a1, int a2, int a3, int a4, int a5, int a6);
public static native void set_ic_textures(int a_ic_bubble_dot, int a_ic_bubble, int a_ic_cam_lens, int a_ic_cam, int a_ic_pencil, int a_ic_pin, int a_ic_smile_eye, int a_ic_smile, int a_ic_videocam);
public static native void set_telegram_textures(int a_telegram_sphere, int a_telegram_plane);
public static native void set_fast_textures(int a_fast_body, int a_fast_spiral, int a_fast_arrow, int a_fast_arrow_shadow);
public static native void set_free_textures(int a_knot_up, int a_knot_down);
public static native void set_powerful_textures(int a_powerful_mask, int a_powerful_star, int a_powerful_infinity, int a_powerful_infinity_white);
public static native void set_private_textures(int a_private_door, int a_private_screw);
public static native void on_surface_created();
public static native void on_surface_changed(int a_width_px, int a_height_px, float a_scale_factor, int a1, int a2, int a3, int a4, int a5);
public static native void onDrawFrame();
public static native void setScrollOffset(float a_offset);
public static native void setPage(int page);
public static native void setDate(float a);
public static native void setIcTextures(int a_ic_bubble_dot, int a_ic_bubble, int a_ic_cam_lens, int a_ic_cam, int a_ic_pencil, int a_ic_pin, int a_ic_smile_eye, int a_ic_smile, int a_ic_videocam);
public static native void setTelegramTextures(int a_telegram_sphere, int a_telegram_plane);
public static native void setFastTextures(int a_fast_body, int a_fast_spiral, int a_fast_arrow, int a_fast_arrow_shadow);
public static native void setFreeTextures(int a_knot_up, int a_knot_down);
public static native void setPowerfulTextures(int a_powerful_mask, int a_powerful_star, int a_powerful_infinity, int a_powerful_infinity_white);
public static native void setPrivateTextures(int a_private_door, int a_private_screw);
public static native void onSurfaceCreated();
public static native void onSurfaceChanged(int a_width_px, int a_height_px, float a_scale_factor, int a1);
}
......@@ -1283,6 +1283,9 @@ public class LocaleController {
localeInfo.version = difference.version;
}
saveOtherLanguages();
if (currentLocaleInfo != null && currentLocaleInfo.isLocal()) {
return;
}
try {
Locale newLocale;
String[] args = localeInfo.shortName.split("_");
......
......@@ -317,6 +317,12 @@ public class MessageObject {
}
}
}
} else if (message.action instanceof TLRPC.TL_messageActionScreenshotTaken) {
if (isOut()) {
messageText = LocaleController.formatString("ActionTakeScreenshootYou", R.string.ActionTakeScreenshootYou);
} else {
messageText = replaceWithLink(LocaleController.getString("ActionTakeScreenshoot", R.string.ActionTakeScreenshoot), "un1", fromUser);
}
} else if (message.action instanceof TLRPC.TL_messageActionCreatedBroadcastList) {
messageText = LocaleController.formatString("YouCreatedBroadcastList", R.string.YouCreatedBroadcastList);
} else if (message.action instanceof TLRPC.TL_messageActionChannelCreate) {
......@@ -386,7 +392,7 @@ public class MessageObject {
} else if (!isMediaEmpty()) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
messageText = LocaleController.getString("AttachPhoto", R.string.AttachPhoto);
} else if (isVideo()) {
} else if (isVideo() || message.media instanceof TLRPC.TL_messageMediaDocument && message.media.document instanceof TLRPC.TL_documentEmpty && message.media.ttl_seconds != 0) {
messageText = LocaleController.getString("AttachVideo", R.string.AttachVideo);
} else if (isVoice()) {
messageText = LocaleController.getString("AttachAudio", R.string.AttachAudio);
......@@ -1138,6 +1144,9 @@ public class MessageObject {
if (TextUtils.isEmpty(messageText) && eventId == 0) {
messageText = "Empty message";
}
} else if (messageOwner.media.ttl_seconds != 0 && (messageOwner.media.photo instanceof TLRPC.TL_photoEmpty || messageOwner.media.document instanceof TLRPC.TL_documentEmpty)) {
contentType = 1;
type = 10;
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
type = 1;
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
......@@ -1254,9 +1263,6 @@ public class MessageObject {
}
public static boolean isRoundVideoDocument(TLRPC.Document document) {
if (Build.VERSION.SDK_INT < 16) {
return false;
}
if (document != null && document.mime_type != null && document.mime_type.equals("video/mp4")) {
int width = 0;
int height = 0;
......@@ -2023,13 +2029,28 @@ public class MessageObject {
return messageOwner.id;
}
public static boolean shouldEncryptPhotoOrVideo(TLRPC.Message message) {
return message instanceof TLRPC.TL_message && (message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaDocument) && message.media.ttl_seconds != 0 ||
message instanceof TLRPC.TL_message_secret && (message.media instanceof TLRPC.TL_messageMediaPhoto || isVideoMessage(message)) && message.ttl > 0 && message.ttl <= 60;
}
public boolean shouldEncryptPhotoOrVideo() {
return shouldEncryptPhotoOrVideo(messageOwner);
}
public static boolean isSecretPhotoOrVideo(TLRPC.Message message) {
return message instanceof TLRPC.TL_message && (message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaDocument) && message.media.ttl_seconds != 0 ||
message instanceof TLRPC.TL_message_secret && (message.media instanceof TLRPC.TL_messageMediaPhoto || isRoundVideoMessage(message) || isVideoMessage(message)) && message.ttl > 0 && message.ttl <= 60;
}
public boolean isSecretPhoto() {
return messageOwner instanceof TLRPC.TL_message_secret && (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || isRoundVideo()) && messageOwner.ttl > 0 && messageOwner.ttl <= 60;
return messageOwner instanceof TLRPC.TL_message && (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || messageOwner.media instanceof TLRPC.TL_messageMediaDocument) && messageOwner.media.ttl_seconds != 0 ||
messageOwner instanceof TLRPC.TL_message_secret && (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || isRoundVideo() || isVideo()) && messageOwner.ttl > 0 && messageOwner.ttl <= 60;
}
public boolean isSecretMedia() {
return messageOwner instanceof TLRPC.TL_message_secret &&
((messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || isRoundVideo()) && messageOwner.ttl > 0 && messageOwner.ttl <= 60 || isVoice() || isVideo());
return messageOwner instanceof TLRPC.TL_message && (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || messageOwner.media instanceof TLRPC.TL_messageMediaDocument) && messageOwner.media.ttl_seconds != 0 ||
messageOwner instanceof TLRPC.TL_message_secret && ((messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || isRoundVideo()) && messageOwner.ttl > 0 && messageOwner.ttl <= 60 || isVoice() || isVideo());
}
public static void setUnreadFlags(TLRPC.Message message, int flag) {
......@@ -2092,14 +2113,19 @@ public class MessageObject {
return messageOwner.send_state == MESSAGE_SEND_STATE_SENT || messageOwner.id > 0;
}
public String getSecretTimeString() {
if (!isSecretMedia()) {
return null;
}
public int getSecretTimeLeft() {
int secondsLeft = messageOwner.ttl;
if (messageOwner.destroyTime != 0) {
secondsLeft = Math.max(0, messageOwner.destroyTime - ConnectionsManager.getInstance().getCurrentTime());
}
return secondsLeft;
}
public String getSecretTimeString() {
if (!isSecretMedia()) {
return null;
}
int secondsLeft = getSecretTimeLeft();
String str;
if (secondsLeft < 60) {
str = secondsLeft + "s";
......@@ -2188,7 +2214,7 @@ public class MessageObject {
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
if (Build.VERSION.SDK_INT >= 16 && attribute.round_message) {
if (attribute.round_message) {
return false;
}
isVideo = true;
......@@ -2229,9 +2255,6 @@ public class MessageObject {
}
public static boolean isRoundVideoMessage(TLRPC.Message message) {
if (Build.VERSION.SDK_INT < 16) {
return false;
}
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
return isRoundVideoDocument(message.media.webpage.document);
}
......@@ -2428,9 +2451,6 @@ public class MessageObject {
}
public boolean isRoundVideo() {
if (Build.VERSION.SDK_INT < 16) {
return false;
}
if (isRoundVideoCached == 0) {
isRoundVideoCached = type == 5 || isRoundVideoMessage(messageOwner) ? 1 : 2;
}
......@@ -2501,6 +2521,8 @@ public class MessageObject {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
return attribute.duration;
} else if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
return attribute.duration;
}
}
return 0;
......@@ -2667,7 +2689,13 @@ public class MessageObject {
if (type == 1) {
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, AndroidUtilities.getPhotoSize());
if (currentPhotoObject != null) {
mediaExists = FileLoader.getPathToMessage(messageOwner).exists();
File file = FileLoader.getPathToMessage(messageOwner);
if (isSecretPhoto()) {
mediaExists = new File(file.getAbsolutePath() + ".enc").exists();
}
if (!mediaExists) {
mediaExists = file.exists();
}
}
} else if (type == 8 || type == 3 || type == 9 || type == 2 || type == 14 || type == 5) {
if (messageOwner.attachPath != null && messageOwner.attachPath.length() > 0) {
......@@ -2675,7 +2703,13 @@ public class MessageObject {
attachPathExists = f.exists();
}
if (!attachPathExists) {
mediaExists = FileLoader.getPathToMessage(messageOwner).exists();
File file = FileLoader.getPathToMessage(messageOwner);
if (type == 3 && isSecretPhoto()) {
mediaExists = new File(file.getAbsolutePath() + ".enc").exists();
}
if (!mediaExists) {
mediaExists = file.exists();
}
}
} else {
TLRPC.Document document = getDocument();
......
......@@ -121,6 +121,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
private boolean gettingNewDeleteTask;
private int currentDeletingTaskTime;
private ArrayList<Integer> currentDeletingTaskMids;
private int currentDeletingTaskChannelId;
private Runnable currentDeleteTaskRunnable;
public boolean loadingDialogs;
......@@ -270,6 +271,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageReceivedByServer);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateMessageMedia);
addSupportUser();
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
enableJoined = preferences.getBoolean("EnableContactJoined", true);
......@@ -578,6 +580,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (obj != null) {
dialogMessagesByIds.put(newMsgId, obj);
}
} else if (id == NotificationCenter.updateMessageMedia) {
TLRPC.Message message = (TLRPC.Message) args[0];
MessageObject existMessageObject = dialogMessagesByIds.get(message.id);
if (existMessageObject != null) {
existMessageObject.messageOwner.media = message.media;
if (message.media.ttl_seconds != 0 && (message.media.photo instanceof TLRPC.TL_photoEmpty || message.media.document instanceof TLRPC.TL_documentEmpty)) {
existMessageObject.setType();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.notificationsSettingsUpdated);
}
}
}
}
......@@ -644,6 +656,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
currentDeletingTaskTime = 0;
currentDeletingTaskMids = null;
currentDeletingTaskChannelId = 0;
gettingNewDeleteTask = false;
loadingDialogs = false;
dialogsEndReached = false;
......@@ -1546,12 +1559,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
public void didAddedNewTask(final int minDate, final SparseArray<ArrayList<Integer>> mids) {
public void didAddedNewTask(final int minDate, final SparseArray<ArrayList<Long>> mids) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
if (currentDeletingTaskMids == null && !gettingNewDeleteTask || currentDeletingTaskTime != 0 && minDate < currentDeletingTaskTime) {
getNewDeleteTask(null);
getNewDeleteTask(null, 0);
}
}
});
......@@ -1563,12 +1576,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter
});
}
public void getNewDeleteTask(final ArrayList<Integer> oldTask) {
public void getNewDeleteTask(final ArrayList<Integer> oldTask, final int channelId) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
gettingNewDeleteTask = true;
MessagesStorage.getInstance().getNewTask(oldTask);
MessagesStorage.getInstance().getNewTask(oldTask, channelId);
}
});
}
......@@ -1582,15 +1595,19 @@ public class MessagesController implements NotificationCenter.NotificationCenter
Utilities.stageQueue.cancelRunnable(currentDeleteTaskRunnable);
}
currentDeleteTaskRunnable = null;
final ArrayList<Integer> mids = new ArrayList<>(currentDeletingTaskMids);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
deleteMessages(currentDeletingTaskMids, null, null, 0, false);
if (!mids.isEmpty() && mids.get(0) > 0) {
MessagesStorage.getInstance().emptyMessagesMedia(mids);
} else {
deleteMessages(mids, null, null, 0, false);
}
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
getNewDeleteTask(currentDeletingTaskMids);
getNewDeleteTask(mids, currentDeletingTaskChannelId);
currentDeletingTaskTime = 0;
currentDeletingTaskMids = null;
}
......@@ -1602,7 +1619,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return false;
}
public void processLoadedDeleteTask(final int taskTime, final ArrayList<Integer> messages) {
public void processLoadedDeleteTask(final int taskTime, final ArrayList<Integer> messages, final int channelId) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
......@@ -3279,7 +3296,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
@Override
public void run() {
if (!firstGettingTask) {
getNewDeleteTask(null);
getNewDeleteTask(null, 0);
firstGettingTask = true;
}
......@@ -3970,7 +3987,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
messageId |= ((long) message.to_id.channel_id) << 32;
}
arrayList.add(messageId);
MessagesStorage.getInstance().markMessagesContentAsRead(arrayList);
MessagesStorage.getInstance().markMessagesContentAsRead(arrayList, 0);
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
......@@ -4002,7 +4019,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
messageId |= ((long) messageObject.messageOwner.to_id.channel_id) << 32;
}
arrayList.add(messageId);
MessagesStorage.getInstance().markMessagesContentAsRead(arrayList);
MessagesStorage.getInstance().markMessagesContentAsRead(arrayList, 0);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesReadContent, arrayList);
if (messageObject.getId() < 0) {
markMessageAsRead(messageObject.getDialogId(), messageObject.messageOwner.random_id, Integer.MIN_VALUE);
......@@ -4021,6 +4038,25 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
public void markMessageAsRead(final int mid, final int channelId, int ttl) {
if (mid == 0 || ttl <= 0) {
return;
}
int time = ConnectionsManager.getInstance().getCurrentTime();
MessagesStorage.getInstance().createTaskForMid(mid, channelId, time, time, ttl, false);
TLRPC.TL_messages_readMessageContents req = new TLRPC.TL_messages_readMessageContents();
req.id.add(mid);
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
TLRPC.TL_messages_affectedMessages res = (TLRPC.TL_messages_affectedMessages) response;
processNewDifferenceParams(-1, res.pts, -1, res.pts_count);
}
}
});
}
public void markMessageAsRead(final long dialog_id, final long random_id, int ttl) {
if (random_id == 0 || dialog_id == 0 || ttl <= 0 && ttl != Integer.MIN_VALUE) {
return;
......@@ -7887,7 +7923,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.getInstance().markMessagesAsRead(markAsReadMessagesInbox, markAsReadMessagesOutbox, markAsReadEncrypted, true);
}
if (!markAsReadMessages.isEmpty()) {
MessagesStorage.getInstance().markMessagesContentAsRead(markAsReadMessages);
MessagesStorage.getInstance().markMessagesContentAsRead(markAsReadMessages, ConnectionsManager.getInstance().getCurrentTime());
}
if (deletedMessages.size() != 0) {
for (int a = 0; a < deletedMessages.size(); a++) {
......
......@@ -916,13 +916,21 @@ public class NotificationsController {
if (!shortMessage && Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(messageObject.messageOwner.media.caption)) {
msg = LocaleController.formatString("NotificationMessageText", R.string.NotificationMessageText, name, "\uD83D\uDDBC " + messageObject.messageOwner.media.caption);
} else {
msg = LocaleController.formatString("NotificationMessagePhoto", R.string.NotificationMessagePhoto, name);
if (messageObject.messageOwner.media.ttl_seconds != 0) {
msg = LocaleController.formatString("NotificationMessageSDPhoto", R.string.NotificationMessageSDPhoto, name);
} else {
msg = LocaleController.formatString("NotificationMessagePhoto", R.string.NotificationMessagePhoto, name);
}
}
} else if (messageObject.isVideo()) {
if (!shortMessage && Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(messageObject.messageOwner.media.caption)) {
msg = LocaleController.formatString("NotificationMessageText", R.string.NotificationMessageText, name, "\uD83D\uDCF9 " + messageObject.messageOwner.media.caption);
} else {
msg = LocaleController.formatString("NotificationMessageVideo", R.string.NotificationMessageVideo, name);
if (messageObject.messageOwner.media.ttl_seconds != 0) {
msg = LocaleController.formatString("NotificationMessageSDVideo", R.string.NotificationMessageSDVideo, name);
} else {
msg = LocaleController.formatString("NotificationMessageVideo", R.string.NotificationMessageVideo, name);
}
}
} else if (messageObject.isGame()) {
msg = LocaleController.formatString("NotificationMessageGame", R.string.NotificationMessageGame, name, messageObject.messageOwner.media.game.title);
......@@ -1037,6 +1045,8 @@ public class NotificationsController {
msg = LocaleController.formatString("ActionMigrateFromGroupNotify", R.string.ActionMigrateFromGroupNotify, chat.title);
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChannelMigrateFrom) {
msg = LocaleController.formatString("ActionMigrateFromGroupNotify", R.string.ActionMigrateFromGroupNotify, messageObject.messageOwner.action.title);
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionScreenshotTaken) {
msg = messageObject.messageText.toString();
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage) {
if (messageObject.replyMessageObject == null) {
if (!ChatObject.isChannel(chat) || chat.megagroup) {
......
......@@ -849,6 +849,7 @@ public class SecretChatHelper {
return null;
}
newMessage.media = new TLRPC.TL_messageMediaPhoto();
newMessage.media.flags |= 3;
newMessage.media.caption = decryptedMessage.media.caption != null ? decryptedMessage.media.caption : "";
newMessage.media.photo = new TLRPC.TL_photo();
newMessage.media.photo.date = newMessage.date;
......@@ -881,6 +882,7 @@ public class SecretChatHelper {
return null;
}
newMessage.media = new TLRPC.TL_messageMediaDocument();
newMessage.media.flags |= 3;
newMessage.media.document = new TLRPC.TL_documentEncrypted();
newMessage.media.document.key = decryptedMessage.media.key;
newMessage.media.document.iv = decryptedMessage.media.iv;
......@@ -919,6 +921,7 @@ public class SecretChatHelper {
return null;
}
newMessage.media = new TLRPC.TL_messageMediaDocument();
newMessage.media.flags |= 3;
newMessage.media.caption = decryptedMessage.media.caption != null ? decryptedMessage.media.caption : "";
newMessage.media.document = new TLRPC.TL_documentEncrypted();
newMessage.media.document.id = file.id;
......@@ -956,6 +959,7 @@ public class SecretChatHelper {
}
} else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaExternalDocument) {
newMessage.media = new TLRPC.TL_messageMediaDocument();
newMessage.media.flags |= 3;
newMessage.media.caption = "";
newMessage.media.document = new TLRPC.TL_document();
newMessage.media.document.id = decryptedMessage.media.id;
......@@ -974,6 +978,7 @@ public class SecretChatHelper {
return null;
}
newMessage.media = new TLRPC.TL_messageMediaDocument();
newMessage.media.flags |= 3;
newMessage.media.document = new TLRPC.TL_documentEncrypted();
newMessage.media.document.key = decryptedMessage.media.key;
newMessage.media.document.iv = decryptedMessage.media.iv;
......
......@@ -53,6 +53,7 @@ public class Utilities {
public native static int convertVideoFrame(ByteBuffer src, ByteBuffer dest, int destFormat, int width, int height, int padding, int swap);
private native static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, int offset, int length);
public native static void aesCtrDecryption(ByteBuffer buffer, byte[] key, byte[] iv, int offset, int length);
public native static void aesCtrDecryptionByteArray(byte[] buffer, byte[] key, byte[] iv, int offset, int length, int n);
public native static String readlink(String path);
public static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, boolean changeIv, int offset, int length) {
......
......@@ -201,7 +201,7 @@ public class Browser {
} else if ("telegram.me".equals(host) || "t.me".equals(host) || "telegram.dog".equals(host) || "telesco.pe".equals(host)) {
String path = uri.getPath();
if (path != null && path.length() > 1) {
return true;
return !path.toLowerCase().equals("/iv");
}
}
return false;
......
......@@ -102,6 +102,9 @@ public class CameraController implements MediaRecorder.OnInfoListener {
List<Camera.Size> list = params.getSupportedPreviewSizes();
for (int a = 0; a < list.size(); a++) {
Camera.Size size = list.get(a);
if (size.width == 1280 && size.height != 720) {
continue;
}
if (size.height < 2160 && size.width < 2160) {
cameraInfo.previewSizes.add(new Size(size.width, size.height));
FileLog.e("preview size = " + size.width + " " + size.height);
......@@ -111,6 +114,9 @@ public class CameraController implements MediaRecorder.OnInfoListener {
list = params.getSupportedPictureSizes();
for (int a = 0; a < list.size(); a++) {
Camera.Size size = list.get(a);
if (size.width == 1280 && size.height != 720) {
continue;
}
if (!"samsung".equals(Build.MANUFACTURER) || !"jflteuc".equals(Build.PRODUCT) || size.width < 2048) {
cameraInfo.pictureSizes.add(new Size(size.width, size.height));
FileLog.e("picture size = " + size.width + " " + size.height);
......@@ -119,6 +125,25 @@ public class CameraController implements MediaRecorder.OnInfoListener {
camera.release();
result.add(cameraInfo);
Comparator<Size> comparator = new Comparator<Size>() {
@Override
public int compare(Size o1, Size o2) {
if (o1.mWidth < o2.mWidth) {
return 1;
} else if (o1.mWidth > o2.mWidth) {
return -1;
} else {
if (o1.mHeight < o2.mHeight) {
return 1;
} else if (o1.mHeight > o2.mHeight) {
return -1;
}
return 0;
}
}
};
Collections.sort(cameraInfo.previewSizes, comparator);
Collections.sort(cameraInfo.pictureSizes, comparator);
}
cameraInfos = result;
}
......@@ -648,7 +673,6 @@ public class CameraController implements MediaRecorder.OnInfoListener {
onVideoTakeCallback = null;
}
} catch (Exception e) {
FileLog.e(e);
}
}
});
......
......@@ -24,7 +24,6 @@ import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLog;
import java.util.ArrayList;
import java.util.List;
public class CameraSession {
......@@ -400,7 +399,17 @@ public class CameraSession {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraInfo.cameraId, info);
int displayOrientation = getDisplayOrientation(info, false);
recorder.setOrientationHint(displayOrientation);
int outputOrientation = 0;
if (jpegOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
outputOrientation = (info.orientation - jpegOrientation + 360) % 360;
} else {
outputOrientation = (info.orientation + jpegOrientation) % 360;
}
}
recorder.setOrientationHint(outputOrientation);
int highProfile = getHigh();
boolean canGoHigh = CamcorderProfile.hasProfile(cameraInfo.cameraId, highProfile);
......
......@@ -147,7 +147,7 @@ public class SharedMediaQuery {
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
return MEDIA_PHOTOVIDEO;
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
if (MessageObject.isVoiceMessage(message)) {
if (MessageObject.isVoiceMessage(message) || MessageObject.isRoundVideoMessage(message)) {
return MEDIA_AUDIO;
} else if (MessageObject.isVideoMessage(message)) {
return MEDIA_PHOTOVIDEO;
......@@ -170,7 +170,9 @@ public class SharedMediaQuery {
}
public static boolean canAddMessageToMedia(TLRPC.Message message) {
if (message instanceof TLRPC.TL_message_secret && message.media instanceof TLRPC.TL_messageMediaPhoto && message.ttl != 0 && message.ttl <= 60) {
if (message instanceof TLRPC.TL_message && (message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaDocument) && message.media.ttl_seconds != 0) {
return false;
} else if (message instanceof TLRPC.TL_message_secret && message.media instanceof TLRPC.TL_messageMediaPhoto && message.ttl != 0 && message.ttl <= 60) {
return false;
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto ||
message.media instanceof TLRPC.TL_messageMediaDocument && !MessageObject.isGifDocument(message.media.document)) {
......
/*
* This is the source code of Telegram for Android v. 3.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-2017.
*/
package org.telegram.messenger.secretmedia;
import android.net.Uri;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.exoplayer2.C;
import org.telegram.messenger.exoplayer2.upstream.DataSource;
import org.telegram.messenger.exoplayer2.upstream.DataSpec;
import org.telegram.messenger.exoplayer2.upstream.TransferListener;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public final class EncryptedFileDataSource implements DataSource {
/**
* Thrown when IOException is encountered during local file read operation.
*/
public static class EncryptedFileDataSourceException extends IOException {
public EncryptedFileDataSourceException(IOException cause) {
super(cause);
}
}
private final TransferListener<? super EncryptedFileDataSource> listener;
private RandomAccessFile file;
private Uri uri;
private long bytesRemaining;
private boolean opened;
private byte[] key = new byte[32];
private byte[] iv = new byte[16];
private int fileOffset;
public EncryptedFileDataSource() {
this(null);
}
public EncryptedFileDataSource(TransferListener<? super EncryptedFileDataSource> listener) {
this.listener = listener;
}
@Override
public long open(DataSpec dataSpec) throws EncryptedFileDataSourceException {
try {
uri = dataSpec.uri;
File path = new File(dataSpec.uri.getPath());
String name = path.getName();
File keyPath = new File(FileLoader.getInternalCacheDir(), name + ".key");
RandomAccessFile keyFile = new RandomAccessFile(keyPath, "r");
keyFile.read(key);
keyFile.read(iv);
keyFile.close();
file = new RandomAccessFile(path, "r");
file.seek(dataSpec.position);
fileOffset = (int) dataSpec.position;
bytesRemaining = dataSpec.length == C.LENGTH_UNSET ? file.length() - dataSpec.position : dataSpec.length;
if (bytesRemaining < 0) {
throw new EOFException();
}
} catch (IOException e) {
throw new EncryptedFileDataSourceException(e);
}
opened = true;
if (listener != null) {
listener.onTransferStart(this, dataSpec);
}
return bytesRemaining;
}
@Override
public int read(byte[] buffer, int offset, int readLength) throws EncryptedFileDataSourceException {
if (readLength == 0) {
return 0;
} else if (bytesRemaining == 0) {
return C.RESULT_END_OF_INPUT;
} else {
int bytesRead;
try {
bytesRead = file.read(buffer, offset, (int) Math.min(bytesRemaining, readLength));
Utilities.aesCtrDecryptionByteArray(buffer, key, iv, offset, bytesRead, fileOffset);
fileOffset += bytesRead;
} catch (IOException e) {
throw new EncryptedFileDataSourceException(e);
}
if (bytesRead > 0) {
bytesRemaining -= bytesRead;
if (listener != null) {
listener.onBytesTransferred(this, bytesRead);
}
}
return bytesRead;
}
}
@Override
public Uri getUri() {
return uri;
}
@Override
public void close() throws EncryptedFileDataSourceException {
uri = null;
fileOffset = 0;
try {
if (file != null) {
file.close();
}
} catch (IOException e) {
throw new EncryptedFileDataSourceException(e);
} finally {
file = null;
if (opened) {
opened = false;
if (listener != null) {
listener.onTransferEnd(this);
}
}
}
}
}
/*
* This is the source code of Telegram for Android v. 3.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-2017.
*/
package org.telegram.messenger.secretmedia;
import org.telegram.messenger.Utilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
public class EncryptedFileInputStream extends FileInputStream {
private byte[] key = new byte[32];
private byte[] iv = new byte[16];
private int fileOffset;
public EncryptedFileInputStream(File file, File keyFile) throws Exception {
super(file);
RandomAccessFile randomAccessFile = new RandomAccessFile(keyFile, "r");
randomAccessFile.read(key, 0, 32);
randomAccessFile.read(iv, 0, 16);
randomAccessFile.close();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int result = super.read(b, off, len);
Utilities.aesCtrDecryptionByteArray(b, key, iv, off, len, fileOffset);
fileOffset += len;
return result;
}
@Override
public long skip(long n) throws IOException {
fileOffset += n;
return super.skip(n);
}
public static void decryptBytesWithKeyFile(byte[] bytes, int offset, int length, File keyFile) throws Exception {
byte[] key = new byte[32];
byte[] iv = new byte[16];
RandomAccessFile randomAccessFile = new RandomAccessFile(keyFile, "r");
randomAccessFile.read(key, 0, 32);
randomAccessFile.read(iv, 0, 16);
randomAccessFile.close();
Utilities.aesCtrDecryptionByteArray(bytes, key, iv, offset, length, 0);
}
}
/*
* This is the source code of Telegram for Android v. 3.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-2017.
*/
package org.telegram.messenger.secretmedia;
import android.content.Context;
import android.net.Uri;
import org.telegram.messenger.exoplayer2.upstream.AssetDataSource;
import org.telegram.messenger.exoplayer2.upstream.ContentDataSource;
import org.telegram.messenger.exoplayer2.upstream.DataSource;
import org.telegram.messenger.exoplayer2.upstream.DataSpec;
import org.telegram.messenger.exoplayer2.upstream.DefaultHttpDataSource;
import org.telegram.messenger.exoplayer2.upstream.FileDataSource;
import org.telegram.messenger.exoplayer2.upstream.TransferListener;
import org.telegram.messenger.exoplayer2.util.Assertions;
import org.telegram.messenger.exoplayer2.util.Util;
import java.io.IOException;
public final class ExtendedDefaultDataSource implements DataSource {
private static final String SCHEME_ASSET = "asset";
private static final String SCHEME_CONTENT = "content";
private final DataSource baseDataSource;
private final DataSource fileDataSource;
private final DataSource encryptedFileDataSource;
private final DataSource assetDataSource;
private final DataSource contentDataSource;
private DataSource dataSource;
/**
* Constructs a new instance, optionally configured to follow cross-protocol redirects.
*
* @param context A context.
* @param listener An optional listener.
* @param userAgent The User-Agent string that should be used when requesting remote data.
* @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
* to HTTPS and vice versa) are enabled when fetching remote data.
*/
public ExtendedDefaultDataSource(Context context, TransferListener<? super DataSource> listener,
String userAgent, boolean allowCrossProtocolRedirects) {
this(context, listener, userAgent, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, allowCrossProtocolRedirects);
}
/**
* Constructs a new instance, optionally configured to follow cross-protocol redirects.
*
* @param context A context.
* @param listener An optional listener.
* @param userAgent The User-Agent string that should be used when requesting remote data.
* @param connectTimeoutMillis The connection timeout that should be used when requesting remote
* data, in milliseconds. A timeout of zero is interpreted as an infinite timeout.
* @param readTimeoutMillis The read timeout that should be used when requesting remote data,
* in milliseconds. A timeout of zero is interpreted as an infinite timeout.
* @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
* to HTTPS and vice versa) are enabled when fetching remote data.
*/
public ExtendedDefaultDataSource(Context context, TransferListener<? super DataSource> listener,
String userAgent, int connectTimeoutMillis, int readTimeoutMillis,
boolean allowCrossProtocolRedirects) {
this(context, listener,
new DefaultHttpDataSource(userAgent, null, listener, connectTimeoutMillis,
readTimeoutMillis, allowCrossProtocolRedirects, null));
}
/**
* Constructs a new instance that delegates to a provided {@link DataSource} for URI schemes other
* than file, asset and content.
*
* @param context A context.
* @param listener An optional listener.
* @param baseDataSource A {@link DataSource} to use for URI schemes other than file, asset and
* content. This {@link DataSource} should normally support at least http(s).
*/
public ExtendedDefaultDataSource(Context context, TransferListener<? super DataSource> listener,
DataSource baseDataSource) {
this.baseDataSource = Assertions.checkNotNull(baseDataSource);
this.fileDataSource = new FileDataSource(listener);
this.encryptedFileDataSource = new EncryptedFileDataSource(listener);
this.assetDataSource = new AssetDataSource(context, listener);
this.contentDataSource = new ContentDataSource(context, listener);
}
@Override
public long open(DataSpec dataSpec) throws IOException {
Assertions.checkState(dataSource == null);
// Choose the correct source for the scheme.
String scheme = dataSpec.uri.getScheme();
if (Util.isLocalFileUri(dataSpec.uri)) {
if (dataSpec.uri.getPath().startsWith("/android_asset/")) {
dataSource = assetDataSource;
} else {
if (dataSpec.uri.getPath().endsWith(".enc")) {
dataSource = encryptedFileDataSource;
} else {
dataSource = fileDataSource;
}
}
} else if (SCHEME_ASSET.equals(scheme)) {
dataSource = assetDataSource;
} else if (SCHEME_CONTENT.equals(scheme)) {
dataSource = contentDataSource;
} else {
dataSource = baseDataSource;
}
// Open the source and return.
return dataSource.open(dataSpec);
}
@Override
public int read(byte[] buffer, int offset, int readLength) throws IOException {
return dataSource.read(buffer, offset, readLength);
}
@Override
public Uri getUri() {
return dataSource == null ? null : dataSource.getUri();
}
@Override
public void close() throws IOException {
if (dataSource != null) {
try {
dataSource.close();
} finally {
dataSource = null;
}
}
}
}
/*
* This is the source code of Telegram for Android v. 3.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-2017.
*/
package org.telegram.messenger.secretmedia;
import android.content.Context;
import org.telegram.messenger.exoplayer2.upstream.DataSource;
import org.telegram.messenger.exoplayer2.upstream.DefaultDataSource;
import org.telegram.messenger.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import org.telegram.messenger.exoplayer2.upstream.TransferListener;
public final class ExtendedDefaultDataSourceFactory implements DataSource.Factory {
private final Context context;
private final TransferListener<? super DataSource> listener;
private final DataSource.Factory baseDataSourceFactory;
/**
* @param context A context.
* @param userAgent The User-Agent string that should be used.
*/
public ExtendedDefaultDataSourceFactory(Context context, String userAgent) {
this(context, userAgent, null);
}
/**
* @param context A context.
* @param userAgent The User-Agent string that should be used.
* @param listener An optional listener.
*/
public ExtendedDefaultDataSourceFactory(Context context, String userAgent,
TransferListener<? super DataSource> listener) {
this(context, listener, new DefaultHttpDataSourceFactory(userAgent, listener));
}
/**
* @param context A context.
* @param listener An optional listener.
* @param baseDataSourceFactory A {@link DataSource.Factory} to be used to create a base {@link DataSource}
* for {@link DefaultDataSource}.
* @see DefaultDataSource#DefaultDataSource(Context, TransferListener, DataSource)
*/
public ExtendedDefaultDataSourceFactory(Context context, TransferListener<? super DataSource> listener,
DataSource.Factory baseDataSourceFactory) {
this.context = context.getApplicationContext();
this.listener = listener;
this.baseDataSourceFactory = baseDataSourceFactory;
}
@Override
public ExtendedDefaultDataSource createDataSource() {
return new ExtendedDefaultDataSource(context, listener, baseDataSourceFactory.createDataSource());
}
}
\ No newline at end of file
......@@ -55,6 +55,8 @@ public class ActionBar extends FrameLayout {
private int extraHeight;
private AnimatorSet actionModeAnimation;
private int titleRightMargin;
private boolean allowOverlayTitle;
private CharSequence lastTitle;
private CharSequence lastSubtitle;
......@@ -172,6 +174,10 @@ public class ActionBar extends FrameLayout {
addView(titleTextView, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
}
public void setTitleRightMargin(int value) {
titleRightMargin = value;
}
public void setTitle(CharSequence value) {
if (value != null && titleTextView == null) {
createTitleTextView();
......@@ -490,7 +496,7 @@ public class ActionBar extends FrameLayout {
}
if (titleTextView != null && titleTextView.getVisibility() != GONE || subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
int availableWidth = width - (menu != null ? menu.getMeasuredWidth() : 0) - AndroidUtilities.dp(16) - textLeft;
int availableWidth = width - (menu != null ? menu.getMeasuredWidth() : 0) - AndroidUtilities.dp(16) - textLeft - titleRightMargin;
if (titleTextView != null && titleTextView.getVisibility() != GONE) {
titleTextView.setTextSize(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18 : 20);
......
......@@ -66,6 +66,8 @@ public class BottomSheet extends Dialog {
private boolean allowDrawContent = true;
private boolean useHardwareLayer = true;
private DialogInterface.OnClickListener onClickListener;
private CharSequence[] items;
......@@ -593,33 +595,33 @@ public class BottomSheet extends Dialog {
containerView.setVisibility(View.INVISIBLE);
container.addView(containerView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
int topOffset = 0;
if (title != null) {
TextView titleView = new TextView(getContext());
titleView.setLines(1);
titleView.setSingleLine(true);
titleView.setText(title);
titleView.setTextColor(Theme.getColor(Theme.key_dialogTextGray2));
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
titleView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
titleView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), AndroidUtilities.dp(8));
titleView.setGravity(Gravity.CENTER_VERTICAL);
containerView.addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48));
titleView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
topOffset += 48;
}
if (customView != null) {
if (customView.getParent() != null) {
ViewGroup viewGroup = (ViewGroup) customView.getParent();
viewGroup.removeView(customView);
}
containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
containerView.addView(customView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, topOffset, 0, 0));
} else {
int topOffset = 0;
if (title != null) {
TextView titleView = new TextView(getContext());
titleView.setLines(1);
titleView.setSingleLine(true);
titleView.setText(title);
titleView.setTextColor(Theme.getColor(Theme.key_dialogTextGray2));
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
titleView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
titleView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), AndroidUtilities.dp(8));
titleView.setGravity(Gravity.CENTER_VERTICAL);
containerView.addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48));
titleView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
topOffset += 48;
}
if (items != null) {
FrameLayout rowLayout = null;
int lastRowLayoutNum = 0;
......@@ -659,6 +661,10 @@ public class BottomSheet extends Dialog {
showWithoutAnimation = value;
}
public void setBackgroundColor(int color) {
shadowDrawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
}
@Override
public void show() {
super.show();
......@@ -754,7 +760,7 @@ public class BottomSheet extends Dialog {
containerView.setVisibility(View.VISIBLE);
if (!onCustomOpenAnimation()) {
if (Build.VERSION.SDK_INT >= 20) {
if (Build.VERSION.SDK_INT >= 20 && useHardwareLayer) {
container.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
containerView.setTranslationY(containerView.getMeasuredHeight());
......@@ -773,7 +779,9 @@ public class BottomSheet extends Dialog {
if (delegate != null) {
delegate.onOpenAnimationEnd();
}
container.setLayerType(View.LAYER_TYPE_NONE, null);
if (useHardwareLayer) {
container.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
}
......@@ -981,6 +989,11 @@ public class BottomSheet extends Dialog {
return this;
}
public Builder setUseHardwareLayer(boolean value) {
bottomSheet.useHardwareLayer = value;
return this;
}
public Builder setDelegate(BottomSheetDelegate delegate) {
bottomSheet.setDelegate(delegate);
return this;
......
......@@ -2415,23 +2415,21 @@ public class Theme {
chat_composeShadowDrawable = context.getResources().getDrawable(R.drawable.compose_panel_shadow);
if (Build.VERSION.SDK_INT >= 16) {
try {
int bitmapSize = AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6);
Bitmap bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShadowLayer(AndroidUtilities.dp(4), 0, 0, 0x5f000000);
canvas.drawCircle(bitmapSize / 2, bitmapSize / 2, AndroidUtilities.roundMessageSize / 2 - AndroidUtilities.dp(1), paint);
try {
int bitmapSize = AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6);
Bitmap bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShadowLayer(AndroidUtilities.dp(4), 0, 0, 0x5f000000);
canvas.drawCircle(bitmapSize / 2, bitmapSize / 2, AndroidUtilities.roundMessageSize / 2 - AndroidUtilities.dp(1), paint);
try {
canvas.setBitmap(null);
} catch (Exception ignore) {
}
chat_roundVideoShadow = new BitmapDrawable(bitmap);
} catch (Throwable ignore) {
canvas.setBitmap(null);
} catch (Exception ignore) {
}
chat_roundVideoShadow = new BitmapDrawable(bitmap);
} catch (Throwable ignore) {
}
applyChatTheme(fontsOnly);
......
......@@ -77,7 +77,7 @@ public class StickersAdapter extends RecyclerListView.SelectionAdapter implement
File f = FileLoader.getPathToAttach(document.thumb, "webp", true);
if (!f.exists()) {
stickersToLoad.add(FileLoader.getAttachFileName(document.thumb, "webp"));
FileLoader.getInstance().loadFile(document.thumb.location, "webp", 0, true);
FileLoader.getInstance().loadFile(document.thumb.location, "webp", 0, 1);
}
}
return stickersToLoad.isEmpty();
......
......@@ -225,6 +225,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen
message.message = "-1";
message.attachPath = audioEntry.path;
message.media = new TLRPC.TL_messageMediaDocument();
message.media.flags |= 3;
message.media.document = new TLRPC.TL_document();
message.flags |= TLRPC.MESSAGE_FLAG_HAS_MEDIA | TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
......
......@@ -129,13 +129,13 @@ public class FeaturedStickerSetCell extends FrameLayout {
}
}
};
addButton.setPadding(AndroidUtilities.dp(17), 0, AndroidUtilities.dp(17), 0);
addButton.setGravity(Gravity.CENTER);
addButton.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
addButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
addButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addButton.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed)));
addButton.setText(LocaleController.getString("Add", R.string.Add).toUpperCase());
addButton.setPadding(AndroidUtilities.dp(17), 0, AndroidUtilities.dp(17), 0);
addView(addButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 28, Gravity.TOP | (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT), LocaleController.isRTL ? 14 : 0, 18, LocaleController.isRTL ? 0 : 14, 0));
checkImage = new ImageView(context);
......
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