2013-10-25 15:19:00 +00:00
/ *
2013-12-20 19:25:49 +00:00
* This is the source code of Telegram for Android v . 1 . 3 . 2 .
2013-10-25 15:19:00 +00:00
* 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 .
* /
package org.telegram.messenger ;
import android.accounts.Account ;
import android.accounts.AccountManager ;
import android.app.AlertDialog ;
2013-10-26 22:34:39 +00:00
import android.app.Notification ;
import android.app.NotificationManager ;
import android.app.PendingIntent ;
2013-10-25 15:19:00 +00:00
import android.app.ProgressDialog ;
import android.content.ContentProviderOperation ;
import android.content.ContentProviderResult ;
import android.content.ContentResolver ;
import android.content.Context ;
2013-10-26 22:34:39 +00:00
import android.content.Intent ;
2013-10-25 15:19:00 +00:00
import android.content.SharedPreferences ;
import android.content.pm.PackageInfo ;
import android.database.Cursor ;
import android.graphics.Bitmap ;
import android.media.AudioManager ;
import android.media.SoundPool ;
import android.net.Uri ;
import android.os.Build ;
import android.os.Vibrator ;
import android.provider.BaseColumns ;
import android.provider.ContactsContract ;
2013-10-26 22:34:39 +00:00
import android.provider.Settings ;
import android.support.v4.app.NotificationCompat ;
2013-12-20 19:25:49 +00:00
import android.support.v7.app.ActionBarActivity ;
2013-10-25 15:19:00 +00:00
import android.text.Html ;
import android.util.SparseArray ;
2013-11-04 12:31:01 +00:00
import org.telegram.PhoneFormat.PhoneFormat ;
2013-10-25 15:19:00 +00:00
import org.telegram.TL.TLClassStore ;
import org.telegram.TL.TLObject ;
import org.telegram.TL.TLRPC ;
import org.telegram.objects.MessageObject ;
import org.telegram.ui.ApplicationLoader ;
2013-10-26 22:34:39 +00:00
import org.telegram.ui.LaunchActivity ;
2013-10-25 15:19:00 +00:00
import java.io.File ;
import java.io.FileInputStream ;
import java.math.BigInteger ;
import java.security.MessageDigest ;
import java.security.SecureRandom ;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.Comparator ;
import java.util.HashMap ;
import java.util.Locale ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.concurrent.Semaphore ;
public class MessagesController implements NotificationCenter . NotificationCenterDelegate {
public ConcurrentHashMap < Integer , TLRPC . Chat > chats = new ConcurrentHashMap < Integer , TLRPC . Chat > ( 100 , 1 . 0f , 1 ) ;
public ConcurrentHashMap < Integer , TLRPC . EncryptedChat > encryptedChats = new ConcurrentHashMap < Integer , TLRPC . EncryptedChat > ( 10 , 1 . 0f , 1 ) ;
public ConcurrentHashMap < Integer , TLRPC . User > users = new ConcurrentHashMap < Integer , TLRPC . User > ( 100 , 1 . 0f , 1 ) ;
public ArrayList < TLRPC . TL_dialog > dialogs = new ArrayList < TLRPC . TL_dialog > ( ) ;
public ArrayList < TLRPC . TL_dialog > dialogsServerOnly = new ArrayList < TLRPC . TL_dialog > ( ) ;
public ConcurrentHashMap < Long , TLRPC . TL_dialog > dialogs_dict = new ConcurrentHashMap < Long , TLRPC . TL_dialog > ( 100 , 1 . 0f , 1 ) ;
public SparseArray < MessageObject > dialogMessage = new SparseArray < MessageObject > ( ) ;
public ConcurrentHashMap < Long , ArrayList < PrintingUser > > printingUsers = new ConcurrentHashMap < Long , ArrayList < PrintingUser > > ( 100 , 1 . 0f , 2 ) ;
public HashMap < Long , CharSequence > printingStrings = new HashMap < Long , CharSequence > ( ) ;
private HashMap < String , DelayedMessage > delayedMessages = new HashMap < String , DelayedMessage > ( ) ;
public SparseArray < MessageObject > sendingMessages = new SparseArray < MessageObject > ( ) ;
public SparseArray < TLRPC . User > hidenAddToContacts = new SparseArray < TLRPC . User > ( ) ;
private SparseArray < TLRPC . EncryptedChat > acceptingChats = new SparseArray < TLRPC . EncryptedChat > ( ) ;
private boolean gettingNewDeleteTask = false ;
private int currentDeletingTaskTime = 0 ;
private Long currentDeletingTask = null ;
private ArrayList < Integer > currentDeletingTaskMids = null ;
public int totalDialogsCount = 0 ;
public boolean loadingDialogs = false ;
public boolean dialogsEndReached = false ;
public boolean gettingDifference = false ;
2013-12-20 19:25:49 +00:00
public boolean gettingDifferenceAgain = false ;
2013-10-25 15:19:00 +00:00
public boolean updatingState = false ;
public boolean firstGettingTask = false ;
public boolean registeringForPush = false ;
private long lastSoundPlay = 0 ;
private long lastStatusUpdateTime = 0 ;
public boolean loadingContacts = true ;
private boolean offlineSended = false ;
private String uploadingAvatar = null ;
private SoundPool soundPool ;
private int sound ;
public static SecureRandom random = new SecureRandom ( ) ;
private Account currentAccount ;
static {
try {
File URANDOM_FILE = new File ( " /dev/urandom " ) ;
FileInputStream sUrandomIn = new FileInputStream ( URANDOM_FILE ) ;
byte [ ] buffer = new byte [ 1024 ] ;
sUrandomIn . read ( buffer ) ;
sUrandomIn . close ( ) ;
random . setSeed ( buffer ) ;
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
}
public static final int MESSAGE_SEND_STATE_SENDING = 1 ;
public static final int MESSAGE_SEND_STATE_SENT = 0 ;
public static final int MESSAGE_SEND_STATE_SEND_ERROR = 2 ;
public static final int UPDATE_MASK_NAME = 1 ;
public static final int UPDATE_MASK_AVATAR = 2 ;
public static final int UPDATE_MASK_STATUS = 4 ;
public static final int UPDATE_MASK_ALL = UPDATE_MASK_AVATAR | UPDATE_MASK_STATUS | UPDATE_MASK_NAME ;
public long openned_dialog_id ;
public static class PrintingUser {
public long lastTime ;
public int userId ;
}
private class DelayedMessage {
public TLRPC . TL_messages_sendMedia sendRequest ;
public TLRPC . TL_decryptedMessage sendEncryptedRequest ;
public int type ;
public TLRPC . FileLocation location ;
public TLRPC . TL_video videoLocation ;
public MessageObject obj ;
public TLRPC . EncryptedChat encryptedChat ;
}
public static class Contact {
public int id ;
public ArrayList < String > phones = new ArrayList < String > ( ) ;
public ArrayList < String > phoneTypes = new ArrayList < String > ( ) ;
public String first_name ;
public String last_name ;
}
public HashMap < Integer , Contact > contactsBook = new HashMap < Integer , Contact > ( ) ;
public HashMap < String , ArrayList < Contact > > contactsSectionsDict = new HashMap < String , ArrayList < Contact > > ( ) ;
public ArrayList < String > sortedContactsSectionsArray = new ArrayList < String > ( ) ;
public ArrayList < TLRPC . TL_contact > contacts = new ArrayList < TLRPC . TL_contact > ( ) ;
public SparseArray < TLRPC . TL_contact > contactsDict = new SparseArray < TLRPC . TL_contact > ( ) ;
public HashMap < String , TLRPC . TL_contact > contactsByPhones = new HashMap < String , TLRPC . TL_contact > ( ) ;
public HashMap < String , ArrayList < TLRPC . TL_contact > > usersSectionsDict = new HashMap < String , ArrayList < TLRPC . TL_contact > > ( ) ;
public ArrayList < String > sortedUsersSectionsArray = new ArrayList < String > ( ) ;
public static MessagesController Instance = new MessagesController ( ) ;
public static final int didReceivedNewMessages = 1 ;
public static final int userPrintUpdate = 2 ;
public static final int userPrintUpdateAll = 19 ;
public static final int updateInterfaces = 3 ;
public static final int dialogsNeedReload = 4 ;
public static final int closeChats = 5 ;
public static final int messagesDeleted = 6 ;
public static final int messagesReaded = 7 ;
public static final int messagesDidLoaded = 8 ;
public static final int messageReceivedByAck = 9 ;
public static final int messageReceivedByServer = 10 ;
public static final int messageSendError = 11 ;
public static final int reloadSearchResults = 12 ;
public static final int contactsDidLoaded = 13 ;
public static final int contactsBookDidLoaded = 14 ;
public static final int chatDidCreated = 15 ;
public static final int chatDidFailCreate = 16 ;
public static final int chatInfoDidLoaded = 17 ;
public static final int mediaDidLoaded = 18 ;
public static final int mediaCountDidLoaded = 20 ;
public static final int encryptedChatUpdated = 21 ;
public static final int messagesReadedEncrypted = 22 ;
public static final int encryptedChatCreated = 23 ;
2013-12-20 19:25:49 +00:00
public static final int userPhotosLoaded = 24 ;
2013-10-25 15:19:00 +00:00
public MessagesController ( ) {
MessagesStorage storage = MessagesStorage . Instance ;
NotificationCenter . Instance . addObserver ( this , FileLoader . FileDidUpload ) ;
NotificationCenter . Instance . addObserver ( this , FileLoader . FileDidFailUpload ) ;
NotificationCenter . Instance . addObserver ( this , 10 ) ;
addSupportUser ( ) ;
try {
soundPool = new SoundPool ( 1 , AudioManager . STREAM_NOTIFICATION , 0 ) ;
2013-11-04 12:31:01 +00:00
sound = soundPool . load ( ApplicationLoader . applicationContext , R . raw . sound_a , 1 ) ;
2013-10-25 15:19:00 +00:00
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
}
public void addSupportUser ( ) {
TLRPC . TL_userForeign user = new TLRPC . TL_userForeign ( ) ;
user . phone = " 333 " ;
user . id = 333000 ;
user . first_name = " Telegram " ;
user . last_name = " " ;
user . status = null ;
user . photo = new TLRPC . TL_userProfilePhotoEmpty ( ) ;
users . put ( user . id , user ) ;
}
@Override
public void didReceivedNotification ( int id , Object . . . args ) {
if ( id = = FileLoader . FileDidUpload ) {
2013-12-20 19:25:49 +00:00
fileDidUploaded ( ( String ) args [ 0 ] , ( TLRPC . InputFile ) args [ 1 ] , ( TLRPC . InputEncryptedFile ) args [ 2 ] ) ;
2013-10-25 15:19:00 +00:00
} else if ( id = = FileLoader . FileDidFailUpload ) {
fileDidFailedUpload ( ( String ) args [ 0 ] ) ;
} else if ( id = = messageReceivedByServer ) {
Integer msgId = ( Integer ) args [ 0 ] ;
MessageObject obj = dialogMessage . get ( msgId ) ;
if ( obj ! = null ) {
Integer newMsgId = ( Integer ) args [ 1 ] ;
dialogMessage . remove ( msgId ) ;
dialogMessage . put ( newMsgId , obj ) ;
obj . messageOwner . id = newMsgId ;
obj . messageOwner . send_state = MessagesController . MESSAGE_SEND_STATE_SENT ;
long uid ;
if ( obj . messageOwner . to_id . chat_id ! = 0 ) {
uid = - obj . messageOwner . to_id . chat_id ;
} else {
if ( obj . messageOwner . to_id . user_id = = UserConfig . clientUserId ) {
obj . messageOwner . to_id . user_id = obj . messageOwner . from_id ;
}
uid = obj . messageOwner . to_id . user_id ;
}
TLRPC . TL_dialog dialog = dialogs_dict . get ( uid ) ;
if ( dialog ! = null ) {
if ( dialog . top_message = = msgId ) {
dialog . top_message = newMsgId ;
}
}
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
}
}
@Override
protected void finalize ( ) throws Throwable {
super . finalize ( ) ;
NotificationCenter . Instance . removeObserver ( this , FileLoader . FileDidUpload ) ;
NotificationCenter . Instance . removeObserver ( this , FileLoader . FileDidFailUpload ) ;
NotificationCenter . Instance . removeObserver ( this , messageReceivedByServer ) ;
}
public void cleanUp ( ) {
dialogs_dict . clear ( ) ;
dialogs . clear ( ) ;
dialogsServerOnly . clear ( ) ;
acceptingChats . clear ( ) ;
users . clear ( ) ;
chats . clear ( ) ;
sendingMessages . clear ( ) ;
delayedMessages . clear ( ) ;
dialogMessage . clear ( ) ;
printingUsers . clear ( ) ;
printingStrings . clear ( ) ;
totalDialogsCount = 0 ;
contactsBook . clear ( ) ;
contactsSectionsDict . clear ( ) ;
sortedContactsSectionsArray . clear ( ) ;
contacts . clear ( ) ;
contactsDict . clear ( ) ;
usersSectionsDict . clear ( ) ;
sortedUsersSectionsArray . clear ( ) ;
contactsByPhones . clear ( ) ;
hidenAddToContacts . clear ( ) ;
currentDeletingTaskTime = 0 ;
currentDeletingTaskMids = null ;
gettingNewDeleteTask = false ;
currentDeletingTask = null ;
loadingContacts = false ;
loadingDialogs = false ;
dialogsEndReached = false ;
gettingDifference = false ;
2013-12-20 19:25:49 +00:00
gettingDifferenceAgain = false ;
2013-10-25 15:19:00 +00:00
firstGettingTask = false ;
updatingState = false ;
lastStatusUpdateTime = 0 ;
offlineSended = false ;
registeringForPush = false ;
uploadingAvatar = null ;
addSupportUser ( ) ;
}
public void didAddedNewTask ( final int minDate ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
if ( currentDeletingTask = = null & & ! gettingNewDeleteTask | | currentDeletingTaskTime ! = 0 & & minDate < currentDeletingTaskTime ) {
getNewDeleteTask ( null ) ;
}
}
} ) ;
}
public void getNewDeleteTask ( final Long oldTask ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
gettingNewDeleteTask = true ;
MessagesStorage . Instance . getNewTask ( oldTask ) ;
}
} ) ;
}
private void checkDeletingTask ( ) {
int currentServerTime = ConnectionsManager . Instance . getCurrentTime ( ) ;
if ( currentDeletingTask ! = null & & currentDeletingTaskTime ! = 0 & & currentDeletingTaskTime < = currentServerTime ) {
currentDeletingTaskTime = 0 ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
deleteMessages ( currentDeletingTaskMids ) ;
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
getNewDeleteTask ( currentDeletingTask ) ;
currentDeletingTaskTime = 0 ;
currentDeletingTask = null ;
}
} ) ;
}
} ) ;
}
}
public void processLoadedDeleteTask ( final Long taskId , final int taskTime , final ArrayList < Integer > messages ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
gettingNewDeleteTask = false ;
if ( taskId ! = null ) {
currentDeletingTaskTime = taskTime ;
currentDeletingTask = taskId ;
currentDeletingTaskMids = messages ;
checkDeletingTask ( ) ;
} else {
currentDeletingTaskTime = 0 ;
currentDeletingTask = null ;
currentDeletingTaskMids = null ;
}
}
} ) ;
}
public void checkAppAccount ( ) {
2013-11-04 12:31:01 +00:00
AccountManager am = AccountManager . get ( ApplicationLoader . applicationContext ) ;
2013-10-25 15:19:00 +00:00
Account [ ] accounts = am . getAccountsByType ( " org.telegram.messenger.account " ) ;
boolean recreateAccount = false ;
if ( UserConfig . currentUser ! = null ) {
if ( accounts . length = = 1 ) {
Account acc = accounts [ 0 ] ;
if ( ! acc . name . equals ( UserConfig . currentUser . phone ) ) {
recreateAccount = true ;
} else {
currentAccount = acc ;
}
} else {
recreateAccount = true ;
}
} else {
if ( accounts . length > 0 ) {
recreateAccount = true ;
}
}
if ( recreateAccount ) {
for ( Account c : accounts ) {
am . removeAccount ( c , null , null ) ;
}
if ( UserConfig . currentUser ! = null ) {
currentAccount = new Account ( UserConfig . currentUser . phone , " org.telegram.messenger.account " ) ;
am . addAccountExplicitly ( currentAccount , " " , null ) ;
}
}
}
2013-12-20 19:25:49 +00:00
public void deleteAllAppAccounts ( ) {
try {
AccountManager am = AccountManager . get ( ApplicationLoader . applicationContext ) ;
Account [ ] accounts = am . getAccountsByType ( " org.telegram.messenger.account " ) ;
for ( Account c : accounts ) {
am . removeAccount ( c , null , null ) ;
}
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
public void loadUserPhotos ( final int uid , final int offset , final int count , final long max_id , final boolean fromCache , final int classGuid ) {
if ( fromCache ) {
MessagesStorage . Instance . getUserPhotos ( uid , offset , count , max_id , classGuid ) ;
} else {
TLRPC . User user = users . get ( uid ) ;
if ( user = = null ) {
return ;
}
TLRPC . TL_photos_getUserPhotos req = new TLRPC . TL_photos_getUserPhotos ( ) ;
req . limit = count ;
req . offset = offset ;
req . max_id = ( int ) max_id ;
TLRPC . InputUser inputUser ;
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
inputUser = new TLRPC . TL_inputUserForeign ( ) ;
inputUser . user_id = user . id ;
inputUser . access_hash = user . access_hash ;
} else {
inputUser = new TLRPC . TL_inputUserContact ( ) ;
inputUser . user_id = user . id ;
}
req . user_id = inputUser ;
long reqId = ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
TLRPC . photos_Photos res = ( TLRPC . photos_Photos ) response ;
processLoadedUserPhotos ( res , uid , offset , count , max_id , fromCache , classGuid ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
ConnectionsManager . Instance . bindRequestToGuid ( reqId , classGuid ) ;
}
}
public void processLoadedUserPhotos ( final TLRPC . photos_Photos res , final int uid , final int offset , final int count , final long max_id , final boolean fromCache , final int classGuid ) {
if ( ! fromCache ) {
MessagesStorage . Instance . putUserPhotos ( uid , res ) ;
} else if ( res = = null | | res . photos . isEmpty ( ) ) {
loadUserPhotos ( uid , offset , count , max_id , false , classGuid ) ;
return ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
NotificationCenter . Instance . postNotificationName ( userPhotosLoaded , uid , offset , count , fromCache , classGuid , res . photos ) ;
}
} ) ;
}
2013-10-25 15:19:00 +00:00
public void processLoadedMedia ( final TLRPC . messages_Messages res , final long uid , int offset , int count , int max_id , final boolean fromCache , final int classGuid ) {
int lower_part = ( int ) uid ;
if ( fromCache & & res . messages . isEmpty ( ) & & lower_part ! = 0 ) {
loadMedia ( uid , offset , count , max_id , false , classGuid ) ;
} else {
if ( ! fromCache ) {
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , true , true ) ;
MessagesStorage . Instance . putMedia ( uid , res . messages ) ;
}
final HashMap < Integer , TLRPC . User > usersLocal = new HashMap < Integer , TLRPC . User > ( ) ;
for ( TLRPC . User u : res . users ) {
usersLocal . put ( u . id , u ) ;
}
final ArrayList < MessageObject > objects = new ArrayList < MessageObject > ( ) ;
for ( TLRPC . Message message : res . messages ) {
objects . add ( new MessageObject ( message , usersLocal ) ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
int totalCount ;
if ( res instanceof TLRPC . TL_messages_messagesSlice ) {
totalCount = res . count ;
} else {
totalCount = res . messages . size ( ) ;
}
for ( TLRPC . User user : res . users ) {
if ( fromCache ) {
users . putIfAbsent ( user . id , user ) ;
} else {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
}
for ( TLRPC . Chat chat : res . chats ) {
if ( fromCache ) {
chats . putIfAbsent ( chat . id , chat ) ;
} else {
chats . put ( chat . id , chat ) ;
}
}
NotificationCenter . Instance . postNotificationName ( mediaDidLoaded , uid , totalCount , objects , fromCache , classGuid ) ;
}
} ) ;
}
}
public void loadMedia ( final long uid , final int offset , final int count , final int max_id , final boolean fromCache , final int classGuid ) {
int lower_part = ( int ) uid ;
if ( fromCache | | lower_part = = 0 ) {
MessagesStorage . Instance . loadMedia ( uid , offset , count , max_id , classGuid ) ;
} else {
TLRPC . TL_messages_search req = new TLRPC . TL_messages_search ( ) ;
req . offset = offset ;
req . limit = count ;
req . max_id = max_id ;
req . filter = new TLRPC . TL_inputMessagesFilterPhotoVideo ( ) ;
req . q = " " ;
if ( uid < 0 ) {
req . peer = new TLRPC . TL_inputPeerChat ( ) ;
req . peer . chat_id = - lower_part ;
} else {
2013-11-04 12:31:01 +00:00
TLRPC . User user = users . get ( lower_part ) ;
2013-10-25 15:19:00 +00:00
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . peer = new TLRPC . TL_inputPeerForeign ( ) ;
req . peer . access_hash = user . access_hash ;
} else {
req . peer = new TLRPC . TL_inputPeerContact ( ) ;
}
req . peer . user_id = lower_part ;
}
long reqId = ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
final TLRPC . messages_Messages res = ( TLRPC . messages_Messages ) response ;
processLoadedMedia ( res , uid , offset , count , max_id , false , classGuid ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
ConnectionsManager . Instance . bindRequestToGuid ( reqId , classGuid ) ;
}
}
public void processLoadedMediaCount ( final int count , final long uid , final int classGuid , final boolean fromCache ) {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
int lower_part = ( int ) uid ;
if ( fromCache & & count = = - 1 & & lower_part ! = 0 ) {
getMediaCount ( uid , classGuid , false ) ;
} else {
if ( ! fromCache ) {
MessagesStorage . Instance . putMediaCount ( uid , count ) ;
}
if ( fromCache & & count = = - 1 ) {
2013-12-20 19:25:49 +00:00
NotificationCenter . Instance . postNotificationName ( mediaCountDidLoaded , uid , 0 , fromCache ) ;
2013-10-25 15:19:00 +00:00
} else {
2013-12-20 19:25:49 +00:00
NotificationCenter . Instance . postNotificationName ( mediaCountDidLoaded , uid , count , fromCache ) ;
2013-10-25 15:19:00 +00:00
}
}
}
} ) ;
}
public void getMediaCount ( final long uid , final int classGuid , boolean fromCache ) {
int lower_part = ( int ) uid ;
if ( fromCache | | lower_part = = 0 ) {
MessagesStorage . Instance . getMediaCount ( uid , classGuid ) ;
} else {
TLRPC . TL_messages_search req = new TLRPC . TL_messages_search ( ) ;
req . offset = 0 ;
req . limit = 1 ;
req . max_id = 0 ;
req . filter = new TLRPC . TL_inputMessagesFilterPhotoVideo ( ) ;
req . q = " " ;
if ( uid < 0 ) {
req . peer = new TLRPC . TL_inputPeerChat ( ) ;
req . peer . chat_id = - lower_part ;
} else {
2013-11-04 12:31:01 +00:00
TLRPC . User user = users . get ( lower_part ) ;
2013-10-25 15:19:00 +00:00
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . peer = new TLRPC . TL_inputPeerForeign ( ) ;
req . peer . access_hash = user . access_hash ;
} else {
req . peer = new TLRPC . TL_inputPeerContact ( ) ;
}
req . peer . user_id = lower_part ;
}
long reqId = ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
final TLRPC . messages_Messages res = ( TLRPC . messages_Messages ) response ;
if ( res instanceof TLRPC . TL_messages_messagesSlice ) {
processLoadedMediaCount ( res . count , uid , classGuid , false ) ;
} else {
processLoadedMediaCount ( res . messages . size ( ) , uid , classGuid , false ) ;
}
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
ConnectionsManager . Instance . bindRequestToGuid ( reqId , classGuid ) ;
}
}
public void uploadAndApplyUserAvatar ( TLRPC . PhotoSize bigPhoto ) {
if ( bigPhoto ! = null ) {
uploadingAvatar = Utilities . getCacheDir ( ) + " / " + bigPhoto . location . volume_id + " _ " + bigPhoto . location . local_id + " .jpg " ;
FileLoader . Instance . uploadFile ( uploadingAvatar , null , null ) ;
}
}
public void readContacts ( ) {
if ( contactsBook . size ( ) ! = 0 ) {
return ;
}
Utilities . globalQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " start read contacts from phone " ) ;
2013-10-25 15:19:00 +00:00
final HashMap < Integer , Contact > contactsMap = new HashMap < Integer , Contact > ( ) ;
final HashMap < String , ArrayList < Contact > > sectionsDict = new HashMap < String , ArrayList < Contact > > ( ) ;
final ArrayList < String > sortedSectionsArray = new ArrayList < String > ( ) ;
2013-11-04 12:31:01 +00:00
ContentResolver cr = ApplicationLoader . applicationContext . getContentResolver ( ) ;
2013-10-25 15:19:00 +00:00
String [ ] projectioPhones = {
ContactsContract . CommonDataKinds . Phone . CONTACT_ID ,
ContactsContract . CommonDataKinds . Phone . NUMBER ,
ContactsContract . CommonDataKinds . Phone . TYPE ,
ContactsContract . CommonDataKinds . Phone . LABEL
} ;
String ids = " " ;
Cursor pCur = cr . query ( ContactsContract . CommonDataKinds . Phone . CONTENT_URI , projectioPhones , null , null , null ) ;
if ( pCur ! = null ) {
if ( pCur . getCount ( ) > 0 ) {
while ( pCur . moveToNext ( ) ) {
String number = pCur . getString ( 1 ) ;
if ( number = = null | | number . length ( ) = = 0 ) {
continue ;
}
Integer id = pCur . getInt ( 0 ) ;
if ( ids . length ( ) ! = 0 ) {
ids + = " , " ;
}
ids + = id ;
int type = pCur . getInt ( 2 ) ;
Contact contact = contactsMap . get ( id ) ;
if ( contact = = null ) {
contact = new Contact ( ) ;
contact . first_name = " " ;
contact . last_name = " " ;
contactsMap . put ( id , contact ) ;
contact . id = id ;
}
2013-11-04 12:31:01 +00:00
2013-10-25 15:19:00 +00:00
contact . phones . add ( number ) ;
if ( type = = ContactsContract . CommonDataKinds . Phone . TYPE_CUSTOM ) {
contact . phoneTypes . add ( pCur . getString ( 3 ) ) ;
} else if ( type = = ContactsContract . CommonDataKinds . Phone . TYPE_HOME ) {
2013-11-04 12:31:01 +00:00
contact . phoneTypes . add ( ApplicationLoader . applicationContext . getString ( R . string . PhoneHome ) ) ;
2013-10-25 15:19:00 +00:00
} else if ( type = = ContactsContract . CommonDataKinds . Phone . TYPE_MOBILE ) {
2013-11-04 12:31:01 +00:00
contact . phoneTypes . add ( ApplicationLoader . applicationContext . getString ( R . string . PhoneMobile ) ) ;
2013-10-25 15:19:00 +00:00
} else if ( type = = ContactsContract . CommonDataKinds . Phone . TYPE_WORK ) {
2013-11-04 12:31:01 +00:00
contact . phoneTypes . add ( ApplicationLoader . applicationContext . getString ( R . string . PhoneWork ) ) ;
2013-10-25 15:19:00 +00:00
} else if ( type = = ContactsContract . CommonDataKinds . Phone . TYPE_MAIN ) {
2013-11-04 12:31:01 +00:00
contact . phoneTypes . add ( ApplicationLoader . applicationContext . getString ( R . string . PhoneMain ) ) ;
2013-10-25 15:19:00 +00:00
} else {
2013-11-04 12:31:01 +00:00
contact . phoneTypes . add ( ApplicationLoader . applicationContext . getString ( R . string . PhoneOther ) ) ;
2013-10-25 15:19:00 +00:00
}
}
}
pCur . close ( ) ;
}
String [ ] projectionNames = {
ContactsContract . CommonDataKinds . StructuredName . CONTACT_ID ,
ContactsContract . CommonDataKinds . StructuredName . GIVEN_NAME ,
ContactsContract . CommonDataKinds . StructuredName . FAMILY_NAME ,
ContactsContract . Data . DISPLAY_NAME ,
ContactsContract . CommonDataKinds . StructuredName . MIDDLE_NAME
} ;
pCur = cr . query ( ContactsContract . Data . CONTENT_URI , projectionNames , ContactsContract . CommonDataKinds . StructuredName . CONTACT_ID + " IN ( " + ids + " ) AND " + ContactsContract . Data . MIMETYPE + " = ' " + ContactsContract . CommonDataKinds . StructuredName . CONTENT_ITEM_TYPE + " ' " , null , null ) ;
if ( pCur ! = null & & pCur . getCount ( ) > 0 ) {
while ( pCur . moveToNext ( ) ) {
int id = pCur . getInt ( 0 ) ;
String fname = pCur . getString ( 1 ) ;
String sname = pCur . getString ( 2 ) ;
String sname2 = pCur . getString ( 3 ) ;
String mname = pCur . getString ( 4 ) ;
Contact contact = contactsMap . get ( id ) ;
if ( contact ! = null ) {
contact . first_name = fname ;
contact . last_name = sname ;
if ( contact . first_name = = null ) {
contact . first_name = " " ;
}
if ( mname ! = null & & mname . length ( ) ! = 0 ) {
if ( contact . first_name . length ( ) ! = 0 ) {
contact . first_name + = " " + mname ;
} else {
contact . first_name = mname ;
}
}
if ( contact . last_name = = null ) {
contact . last_name = " " ;
}
if ( contact . last_name . length ( ) = = 0 & & contact . first_name . length ( ) = = 0 & & sname2 ! = null & & sname2 . length ( ) ! = 0 ) {
contact . first_name = sname2 ;
}
}
}
pCur . close ( ) ;
}
ArrayList < TLRPC . TL_inputPhoneContact > toImport = new ArrayList < TLRPC . TL_inputPhoneContact > ( ) ;
String contactsImportHash = " " ;
MessageDigest mdEnc = null ;
try {
mdEnc = MessageDigest . getInstance ( " MD5 " ) ;
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
for ( HashMap . Entry < Integer , Contact > pair : contactsMap . entrySet ( ) ) {
Contact value = pair . getValue ( ) ;
int id = pair . getKey ( ) ;
for ( int a = 0 ; a < value . phones . size ( ) ; a + + ) {
TLRPC . TL_inputPhoneContact imp = new TLRPC . TL_inputPhoneContact ( ) ;
imp . client_id = id ;
imp . first_name = value . first_name ;
imp . last_name = value . last_name ;
2013-11-04 12:31:01 +00:00
imp . phone = PhoneFormat . stripExceptNumbers ( value . phones . get ( a ) ) ;
2013-10-25 15:19:00 +00:00
toImport . add ( imp ) ;
String str = imp . client_id + imp . first_name + imp . last_name + imp . phone ;
if ( mdEnc ! = null ) {
mdEnc . update ( str . getBytes ( ) ) ;
}
}
2013-12-20 19:25:49 +00:00
String key = value . first_name ;
2013-10-25 15:19:00 +00:00
if ( key . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
key = value . last_name ;
2013-10-25 15:19:00 +00:00
}
if ( key . length ( ) = = 0 ) {
key = " # " ;
if ( value . phones . size ( ) ! = 0 ) {
value . first_name = " + " + value . phones . get ( 0 ) ;
}
} else {
key = key . toUpperCase ( ) ;
}
if ( key . length ( ) > 1 ) {
key = key . substring ( 0 , 1 ) ;
}
ArrayList < Contact > arr = sectionsDict . get ( key ) ;
if ( arr = = null ) {
arr = new ArrayList < Contact > ( ) ;
sectionsDict . put ( key , arr ) ;
sortedSectionsArray . add ( key ) ;
}
arr . add ( value ) ;
}
for ( HashMap . Entry < String , ArrayList < Contact > > entry : sectionsDict . entrySet ( ) ) {
Collections . sort ( entry . getValue ( ) , new Comparator < Contact > ( ) {
@Override
public int compare ( Contact contact , Contact contact2 ) {
2013-12-20 19:25:49 +00:00
String toComapre1 = contact . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre1 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre1 = contact . last_name ;
2013-10-25 15:19:00 +00:00
}
2013-12-20 19:25:49 +00:00
String toComapre2 = contact2 . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre2 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre2 = contact2 . last_name ;
2013-10-25 15:19:00 +00:00
}
return toComapre1 . compareTo ( toComapre2 ) ;
}
} ) ;
}
Collections . sort ( sortedSectionsArray , new Comparator < String > ( ) {
@Override
public int compare ( String s , String s2 ) {
char cv1 = s . charAt ( 0 ) ;
char cv2 = s2 . charAt ( 0 ) ;
if ( cv1 = = '#' ) {
return 1 ;
} else if ( cv2 = = '#' ) {
return - 1 ;
2013-12-20 19:25:49 +00:00
} / * else if ( cv1 > = 'A' & & cv1 < = 'Z' & & cv2 > = 'A' & & cv2 < = 'Z' ) {
2013-10-25 15:19:00 +00:00
return s . compareTo ( s2 ) ;
} else if ( cv1 > = 'A' & & cv1 < = 'Z' & & ! ( cv2 > = 'A' & & cv2 < = 'Z' ) ) {
return 1 ;
} else if ( ! ( cv1 > = 'A' & & cv1 < = 'Z' ) & & cv2 > = 'A' & & cv2 < = 'Z' ) {
return - 1 ;
2013-12-20 19:25:49 +00:00
} * /
2013-10-25 15:19:00 +00:00
return s . compareTo ( s2 ) ;
}
} ) ;
String importHash = String . format ( Locale . US , " %32s " , new BigInteger ( 1 , mdEnc . digest ( ) ) . toString ( 16 ) ) . replace ( ' ' , '0' ) ;
if ( ! toImport . isEmpty ( ) & & ! UserConfig . importHash . equals ( importHash ) ) {
UserConfig . importHash = importHash ;
2013-11-04 12:31:01 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
importContacts ( toImport ) ;
} else {
loadContacts ( true ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
contactsBook = contactsMap ;
contactsSectionsDict = sectionsDict ;
sortedContactsSectionsArray = sortedSectionsArray ;
NotificationCenter . Instance . postNotificationName ( contactsBookDidLoaded ) ;
}
} ) ;
}
} ) ;
}
private void performSyncContacts ( ) {
Utilities . globalQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
try {
Uri rawContactUri = ContactsContract . RawContacts . CONTENT_URI . buildUpon ( ) . appendQueryParameter ( ContactsContract . RawContacts . ACCOUNT_NAME , currentAccount . name ) . appendQueryParameter (
ContactsContract . RawContacts . ACCOUNT_TYPE , currentAccount . type ) . build ( ) ;
2013-11-04 12:31:01 +00:00
Cursor c1 = ApplicationLoader . applicationContext . getContentResolver ( ) . query ( rawContactUri , new String [ ] { BaseColumns . _ID , ContactsContract . RawContacts . SYNC2 } , null , null , null ) ;
2013-10-25 15:19:00 +00:00
HashMap < Integer , Long > bookContacts = new HashMap < Integer , Long > ( ) ;
if ( c1 ! = null ) {
while ( c1 . moveToNext ( ) ) {
bookContacts . put ( c1 . getInt ( 1 ) , c1 . getLong ( 0 ) ) ;
}
c1 . close ( ) ;
for ( TLRPC . TL_contact u : contacts ) {
if ( ! bookContacts . containsKey ( u . user_id ) ) {
TLRPC . User user = users . get ( u . user_id ) ;
addContact ( currentAccount , user , user . phone ) ;
}
}
}
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
}
} ) ;
}
public static long addContact ( Account account , TLRPC . User user , String phone ) {
if ( account = = null | | user = = null | | phone = = null ) {
return - 1 ;
}
ArrayList < ContentProviderOperation > query = new ArrayList < ContentProviderOperation > ( ) ;
ContentProviderOperation . Builder builder = ContentProviderOperation . newInsert ( ContactsContract . RawContacts . CONTENT_URI ) ;
builder . withValue ( ContactsContract . RawContacts . ACCOUNT_NAME , account . name ) ;
builder . withValue ( ContactsContract . RawContacts . ACCOUNT_TYPE , account . type ) ;
builder . withValue ( ContactsContract . RawContacts . SYNC1 , phone ) ;
builder . withValue ( ContactsContract . RawContacts . SYNC2 , user . id ) ;
query . add ( builder . build ( ) ) ;
builder = ContentProviderOperation . newInsert ( ContactsContract . Data . CONTENT_URI ) ;
builder . withValueBackReference ( ContactsContract . CommonDataKinds . StructuredName . RAW_CONTACT_ID , 0 ) ;
builder . withValue ( ContactsContract . Data . MIMETYPE , ContactsContract . CommonDataKinds . StructuredName . CONTENT_ITEM_TYPE ) ;
builder . withValue ( ContactsContract . CommonDataKinds . StructuredName . GIVEN_NAME , user . first_name ) ;
builder . withValue ( ContactsContract . CommonDataKinds . StructuredName . FAMILY_NAME , user . last_name ) ;
query . add ( builder . build ( ) ) ;
builder = ContentProviderOperation . newInsert ( ContactsContract . Data . CONTENT_URI ) ;
builder . withValueBackReference ( ContactsContract . CommonDataKinds . StructuredName . RAW_CONTACT_ID , 0 ) ;
builder . withValue ( ContactsContract . Data . MIMETYPE , ContactsContract . CommonDataKinds . Phone . CONTENT_ITEM_TYPE ) ;
builder . withValue ( ContactsContract . CommonDataKinds . Phone . NUMBER , " + " + phone ) ;
builder . withValue ( ContactsContract . CommonDataKinds . Phone . TYPE , ContactsContract . CommonDataKinds . Phone . TYPE_MOBILE ) ;
query . add ( builder . build ( ) ) ;
builder = ContentProviderOperation . newInsert ( ContactsContract . Data . CONTENT_URI ) ;
builder . withValueBackReference ( ContactsContract . Data . RAW_CONTACT_ID , 0 ) ;
builder . withValue ( ContactsContract . Data . MIMETYPE , " vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile " ) ;
builder . withValue ( ContactsContract . Data . DATA1 , " + " + phone ) ;
builder . withValue ( ContactsContract . Data . DATA2 , " Telegram Profile " ) ;
builder . withValue ( ContactsContract . Data . DATA3 , " + " + phone ) ;
builder . withValue ( ContactsContract . Data . DATA4 , user . id ) ;
query . add ( builder . build ( ) ) ;
try {
2013-11-04 12:31:01 +00:00
ContentProviderResult [ ] result = ApplicationLoader . applicationContext . getContentResolver ( ) . applyBatch ( ContactsContract . AUTHORITY , query ) ;
2013-10-25 15:19:00 +00:00
return Long . parseLong ( result [ 0 ] . uri . getLastPathSegment ( ) ) ;
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
return - 1 ;
}
public void deleteMessages ( ArrayList < Integer > messages ) {
for ( Integer id : messages ) {
MessageObject obj = dialogMessage . get ( id ) ;
if ( obj ! = null ) {
obj . deleted = true ;
}
}
MessagesStorage . Instance . markMessagesAsDeleted ( messages , true ) ;
MessagesStorage . Instance . updateDialogsWithDeletedMessages ( messages , true ) ;
2013-12-20 19:25:49 +00:00
NotificationCenter . Instance . postNotificationName ( messagesDeleted , messages ) ;
2013-10-25 15:19:00 +00:00
ArrayList < Integer > toSend = new ArrayList < Integer > ( ) ;
for ( Integer mid : messages ) {
if ( mid > 0 ) {
toSend . add ( mid ) ;
}
}
if ( toSend . isEmpty ( ) ) {
return ;
}
TLRPC . TL_messages_deleteMessages req = new TLRPC . TL_messages_deleteMessages ( ) ;
req . id = messages ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void deleteDialog ( final long did , int offset , final boolean onlyHistory ) {
TLRPC . TL_dialog dialog = dialogs_dict . get ( did ) ;
if ( dialog ! = null ) {
int lower_part = ( int ) did ;
if ( offset = = 0 ) {
if ( ! onlyHistory ) {
dialogs . remove ( dialog ) ;
dialogsServerOnly . remove ( dialog ) ;
dialogs_dict . remove ( did ) ;
totalDialogsCount - - ;
}
dialogMessage . remove ( dialog . top_message ) ;
MessagesStorage . Instance . deleteDialog ( did , onlyHistory ) ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
if ( lower_part ! = 0 ) {
TLRPC . TL_messages_deleteHistory req = new TLRPC . TL_messages_deleteHistory ( ) ;
req . offset = offset ;
if ( did < 0 ) {
req . peer = new TLRPC . TL_inputPeerChat ( ) ;
req . peer . chat_id = - lower_part ;
} else {
2013-11-04 12:31:01 +00:00
TLRPC . User user = users . get ( lower_part ) ;
2013-10-25 15:19:00 +00:00
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . peer = new TLRPC . TL_inputPeerForeign ( ) ;
req . peer . access_hash = user . access_hash ;
} else {
req . peer = new TLRPC . TL_inputPeerContact ( ) ;
}
req . peer . user_id = lower_part ;
}
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
TLRPC . TL_messages_affectedHistory res = ( TLRPC . TL_messages_affectedHistory ) response ;
if ( res . offset > 0 ) {
deleteDialog ( did , res . offset , onlyHistory ) ;
}
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
} else if ( MessagesStorage . lastSeqValue ! = res . seq ) {
2013-10-25 15:19:00 +00:00
getDifference ( ) ;
}
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
} else {
int encId = ( int ) ( did > > 32 ) ;
declineSecretChat ( encId ) ;
}
}
}
public void loadChatInfo ( final int chat_id ) {
MessagesStorage . Instance . loadChatInfo ( chat_id ) ;
}
public void processChatInfo ( final int chat_id , final TLRPC . ChatParticipants info , final ArrayList < TLRPC . User > usersArr , final boolean fromCache ) {
if ( info = = null & & fromCache ) {
TLRPC . TL_messages_getFullChat req = new TLRPC . TL_messages_getFullChat ( ) ;
req . chat_id = chat_id ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error ! = null ) {
return ;
}
final TLRPC . TL_messages_chatFull res = ( TLRPC . TL_messages_chatFull ) response ;
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , true , true ) ;
MessagesStorage . Instance . updateChatInfo ( chat_id , res . full_chat . participants , false ) ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : res . users ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
for ( TLRPC . Chat chat : res . chats ) {
chats . put ( chat . id , chat ) ;
}
NotificationCenter . Instance . postNotificationName ( chatInfoDidLoaded , chat_id , res . full_chat . participants ) ;
}
} ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
} else {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : usersArr ) {
if ( fromCache ) {
users . putIfAbsent ( user . id , user ) ;
} else {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
}
NotificationCenter . Instance . postNotificationName ( chatInfoDidLoaded , chat_id , info ) ;
}
} ) ;
}
}
public void updateTimerProc ( ) {
long currentTime = System . currentTimeMillis ( ) ;
checkDeletingTask ( ) ;
if ( UserConfig . clientUserId ! = 0 ) {
if ( ApplicationLoader . lastPauseTime = = 0 ) {
if ( lastStatusUpdateTime ! = - 1 & & ( lastStatusUpdateTime = = 0 | | lastStatusUpdateTime < = System . currentTimeMillis ( ) - 55000 | | offlineSended ) ) {
lastStatusUpdateTime = - 1 ;
TLRPC . TL_account_updateStatus req = new TLRPC . TL_account_updateStatus ( ) ;
req . offline = false ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
lastStatusUpdateTime = System . currentTimeMillis ( ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
offlineSended = false ;
}
} else if ( ! offlineSended & & ApplicationLoader . lastPauseTime < = System . currentTimeMillis ( ) - 2000 ) {
TLRPC . TL_account_updateStatus req = new TLRPC . TL_account_updateStatus ( ) ;
req . offline = true ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
offlineSended = true ;
}
}
final ArrayList < Long > uidsToSend = new ArrayList < Long > ( ) ;
if ( ! printingUsers . isEmpty ( ) ) {
ArrayList < Long > keys = new ArrayList < Long > ( printingUsers . keySet ( ) ) ;
for ( int b = 0 ; b < keys . size ( ) ; b + + ) {
Long key = keys . get ( b ) ;
ArrayList < PrintingUser > arr = printingUsers . get ( key ) ;
for ( int a = 0 ; a < arr . size ( ) ; a + + ) {
PrintingUser user = arr . get ( a ) ;
if ( user . lastTime + 5900 < currentTime ) {
if ( ! uidsToSend . contains ( key ) ) {
uidsToSend . add ( key ) ;
}
arr . remove ( user ) ;
a - - ;
}
}
if ( arr . isEmpty ( ) ) {
printingUsers . remove ( key ) ;
keys . remove ( b ) ;
b - - ;
}
}
updatePrintingStrings ( ) ;
if ( ! uidsToSend . isEmpty ( ) ) {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( Long uid : uidsToSend ) {
NotificationCenter . Instance . postNotificationName ( userPrintUpdate , uid ) ;
}
NotificationCenter . Instance . postNotificationName ( userPrintUpdateAll ) ;
}
} ) ;
}
}
}
public void updatePrintingStrings ( ) {
final HashMap < Long , CharSequence > newPrintingStrings = new HashMap < Long , CharSequence > ( ) ;
ArrayList < Long > keys = new ArrayList < Long > ( printingUsers . keySet ( ) ) ;
for ( Long key : keys ) {
if ( key > 0 ) {
2013-12-20 19:25:49 +00:00
newPrintingStrings . put ( key , ApplicationLoader . applicationContext . getString ( R . string . Typing ) ) ;
2013-10-25 15:19:00 +00:00
} else {
ArrayList < PrintingUser > arr = printingUsers . get ( key ) ;
int count = 0 ;
String label = " " ;
for ( PrintingUser pu : arr ) {
2013-11-04 12:31:01 +00:00
TLRPC . User user = users . get ( pu . userId ) ;
2013-10-25 15:19:00 +00:00
if ( user ! = null ) {
if ( label . length ( ) ! = 0 ) {
label + = " , " ;
}
label + = Utilities . formatName ( user . first_name , user . last_name ) ;
count + + ;
}
if ( count = = 2 ) {
break ;
}
}
if ( label . length ( ) ! = 0 ) {
if ( count > 1 ) {
if ( arr . size ( ) > 2 ) {
2013-12-20 19:25:49 +00:00
newPrintingStrings . put ( key , Html . fromHtml ( String . format ( " %s %s %s " , label , String . format ( ApplicationLoader . applicationContext . getString ( R . string . AndMoreTyping ) , arr . size ( ) - 2 ) , ApplicationLoader . applicationContext . getString ( R . string . AreTyping ) ) ) ) ;
2013-10-25 15:19:00 +00:00
} else {
2013-12-20 19:25:49 +00:00
newPrintingStrings . put ( key , Html . fromHtml ( String . format ( " %s %s " , label , ApplicationLoader . applicationContext . getString ( R . string . AreTyping ) ) ) ) ;
2013-10-25 15:19:00 +00:00
}
} else {
2013-12-20 19:25:49 +00:00
newPrintingStrings . put ( key , Html . fromHtml ( String . format ( " %s %s " , label , ApplicationLoader . applicationContext . getString ( R . string . IsTyping ) ) ) ) ;
2013-10-25 15:19:00 +00:00
}
}
}
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
printingStrings = newPrintingStrings ;
}
} ) ;
}
public void processLoadedContacts ( final ArrayList < TLRPC . TL_contact > contactsArr , final ArrayList < TLRPC . User > usersArr , final int from ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " done loading contacts " ) ;
2013-10-25 15:19:00 +00:00
if ( from = = 1 & & contactsArr . isEmpty ( ) ) {
loadContacts ( false ) ;
return ;
}
if ( from = = 0 | | from = = 2 | | from = = 3 ) {
MessagesStorage . Instance . putUsersAndChats ( usersArr , null , true , true ) ;
MessagesStorage . Instance . putContacts ( contactsArr , true ) ;
Collections . sort ( contacts , new Comparator < TLRPC . TL_contact > ( ) {
@Override
public int compare ( TLRPC . TL_contact tl_contact , TLRPC . TL_contact tl_contact2 ) {
if ( tl_contact . user_id > tl_contact2 . user_id ) {
return 1 ;
} else if ( tl_contact . user_id < tl_contact2 . user_id ) {
return - 1 ;
}
return 0 ;
}
} ) ;
String ids = " " ;
for ( TLRPC . TL_contact aContactsArr : contactsArr ) {
if ( ids . length ( ) ! = 0 ) {
ids + = " , " ;
}
ids + = aContactsArr . user_id ;
}
UserConfig . contactsHash = Utilities . MD5 ( ids ) ;
2013-11-04 12:31:01 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
if ( from = = 2 ) {
loadContacts ( false ) ;
}
}
final HashMap < Integer , TLRPC . User > usersDict = new HashMap < Integer , TLRPC . User > ( ) ;
for ( TLRPC . User user : usersArr ) {
usersDict . put ( user . id , user ) ;
}
Collections . sort ( contactsArr , new Comparator < TLRPC . TL_contact > ( ) {
@Override
public int compare ( TLRPC . TL_contact tl_contact , TLRPC . TL_contact tl_contact2 ) {
TLRPC . User user1 = usersDict . get ( tl_contact . user_id ) ;
TLRPC . User user2 = usersDict . get ( tl_contact2 . user_id ) ;
2013-12-20 19:25:49 +00:00
String name1 = user1 . first_name ;
2013-10-25 15:19:00 +00:00
if ( name1 = = null | | name1 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
name1 = user1 . last_name ;
2013-10-25 15:19:00 +00:00
}
2013-12-20 19:25:49 +00:00
String name2 = user2 . first_name ;
2013-10-25 15:19:00 +00:00
if ( name2 = = null | | name2 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
name2 = user2 . last_name ;
2013-10-25 15:19:00 +00:00
}
return name1 . compareTo ( name2 ) ;
}
} ) ;
final HashMap < String , ArrayList < TLRPC . TL_contact > > sectionsDict = new HashMap < String , ArrayList < TLRPC . TL_contact > > ( ) ;
final SparseArray < TLRPC . TL_contact > contactsDictionery = new SparseArray < TLRPC . TL_contact > ( ) ;
final ArrayList < String > sortedSectionsArray = new ArrayList < String > ( ) ;
final HashMap < String , TLRPC . TL_contact > contactsPhones = new HashMap < String , TLRPC . TL_contact > ( ) ;
for ( TLRPC . TL_contact value : contactsArr ) {
TLRPC . User user = usersDict . get ( value . user_id ) ;
2013-12-22 23:47:35 +00:00
if ( user = = null ) {
continue ;
}
2013-10-25 15:19:00 +00:00
contactsDictionery . put ( value . user_id , value ) ;
contactsPhones . put ( user . phone , value ) ;
2013-12-20 19:25:49 +00:00
String key = user . first_name ;
2013-10-25 15:19:00 +00:00
if ( key = = null | | key . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
key = user . last_name ;
2013-10-25 15:19:00 +00:00
}
if ( key . length ( ) = = 0 ) {
key = " # " ;
} else {
key = key . toUpperCase ( ) ;
}
if ( key . length ( ) > 1 ) {
key = key . substring ( 0 , 1 ) ;
}
ArrayList < TLRPC . TL_contact > arr = sectionsDict . get ( key ) ;
if ( arr = = null ) {
arr = new ArrayList < TLRPC . TL_contact > ( ) ;
sectionsDict . put ( key , arr ) ;
sortedSectionsArray . add ( key ) ;
}
arr . add ( value ) ;
}
for ( HashMap . Entry < String , ArrayList < TLRPC . TL_contact > > entry : sectionsDict . entrySet ( ) ) {
Collections . sort ( entry . getValue ( ) , new Comparator < TLRPC . TL_contact > ( ) {
@Override
public int compare ( TLRPC . TL_contact contact , TLRPC . TL_contact contact2 ) {
TLRPC . User user1 = usersDict . get ( contact . user_id ) ;
TLRPC . User user2 = usersDict . get ( contact2 . user_id ) ;
2013-12-20 19:25:49 +00:00
String toComapre1 = user1 . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre1 = = null | | toComapre1 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre1 = user1 . last_name ;
2013-10-25 15:19:00 +00:00
}
2013-12-20 19:25:49 +00:00
String toComapre2 = user2 . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre2 = = null | | toComapre2 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre2 = user2 . last_name ;
2013-10-25 15:19:00 +00:00
}
return toComapre1 . compareTo ( toComapre2 ) ;
}
} ) ;
}
Collections . sort ( sortedSectionsArray , new Comparator < String > ( ) {
@Override
public int compare ( String s , String s2 ) {
char cv1 = s . charAt ( 0 ) ;
char cv2 = s2 . charAt ( 0 ) ;
if ( cv1 = = '#' ) {
return 1 ;
} else if ( cv2 = = '#' ) {
return - 1 ;
2013-12-20 19:25:49 +00:00
} / * else if ( cv1 > = 'A' & & cv1 < = 'Z' & & cv2 > = 'A' & & cv2 < = 'Z' ) {
2013-10-25 15:19:00 +00:00
return s . compareTo ( s2 ) ;
} else if ( cv1 > = 'A' & & cv1 < = 'Z' & & ! ( cv2 > = 'A' & & cv2 < = 'Z' ) ) {
return 1 ;
} else if ( ! ( cv1 > = 'A' & & cv1 < = 'Z' ) & & cv2 > = 'A' & & cv2 < = 'Z' ) {
return - 1 ;
2013-12-20 19:25:49 +00:00
} * /
2013-10-25 15:19:00 +00:00
return s . compareTo ( s2 ) ;
}
} ) ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : usersArr ) {
if ( from = = 1 ) {
users . putIfAbsent ( user . id , user ) ;
} else {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
}
contacts = contactsArr ;
contactsByPhones = contactsPhones ;
contactsDict = contactsDictionery ;
usersSectionsDict = sectionsDict ;
sortedUsersSectionsArray = sortedSectionsArray ;
if ( from = = 0 ) {
loadingContacts = false ;
}
performSyncContacts ( ) ;
NotificationCenter . Instance . postNotificationName ( contactsDidLoaded ) ;
}
} ) ;
}
} ) ;
}
public void sendTyping ( long dialog_id , int classGuid ) {
if ( dialog_id = = 0 ) {
return ;
}
int lower_part = ( int ) dialog_id ;
if ( lower_part ! = 0 ) {
TLRPC . TL_messages_setTyping req = new TLRPC . TL_messages_setTyping ( ) ;
if ( lower_part < 0 ) {
req . peer = new TLRPC . TL_inputPeerChat ( ) ;
req . peer . chat_id = - lower_part ;
} else {
TLRPC . User user = users . get ( lower_part ) ;
2013-12-20 19:25:49 +00:00
if ( user ! = null ) {
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . peer = new TLRPC . TL_inputPeerForeign ( ) ;
req . peer . user_id = user . id ;
req . peer . access_hash = user . access_hash ;
} else {
req . peer = new TLRPC . TL_inputPeerContact ( ) ;
req . peer . user_id = user . id ;
}
2013-10-25 15:19:00 +00:00
} else {
2013-12-20 19:25:49 +00:00
return ;
2013-10-25 15:19:00 +00:00
}
}
req . typing = true ;
long reqId = ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
ConnectionsManager . Instance . bindRequestToGuid ( reqId , classGuid ) ;
} else {
int encId = ( int ) ( dialog_id > > 32 ) ;
TLRPC . EncryptedChat chat = encryptedChats . get ( encId ) ;
if ( chat . auth_key ! = null & & chat . auth_key . length > 1 & & chat instanceof TLRPC . TL_encryptedChat ) {
TLRPC . TL_messages_setEncryptedTyping req = new TLRPC . TL_messages_setEncryptedTyping ( ) ;
req . peer = new TLRPC . TL_inputEncryptedChat ( ) ;
req . peer . chat_id = chat . id ;
req . peer . access_hash = chat . access_hash ;
req . typing = true ;
long reqId = ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
ConnectionsManager . Instance . bindRequestToGuid ( reqId , classGuid ) ;
}
}
}
public void loadContacts ( boolean fromCache ) {
loadingContacts = true ;
if ( fromCache ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " load contacts from cache " ) ;
2013-10-25 15:19:00 +00:00
MessagesStorage . Instance . getContacts ( ) ;
} else {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " load contacts from server " ) ;
2013-10-25 15:19:00 +00:00
TLRPC . TL_contacts_getContacts req = new TLRPC . TL_contacts_getContacts ( ) ;
req . hash = UserConfig . contactsHash ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
TLRPC . contacts_Contacts res = ( TLRPC . contacts_Contacts ) response ;
if ( res instanceof TLRPC . TL_contacts_contactsNotModified ) {
return ;
}
processLoadedContacts ( res . contacts , res . users , 0 ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
}
public void importContacts ( ArrayList < TLRPC . TL_inputPhoneContact > contactsArr ) {
TLRPC . TL_contacts_importContacts req = new TLRPC . TL_contacts_importContacts ( ) ;
req . contacts = contactsArr ;
req . replace = false ;
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " start import contacts " ) ;
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " contacts imported " ) ;
2013-10-25 15:19:00 +00:00
TLRPC . TL_contacts_importedContacts res = ( TLRPC . TL_contacts_importedContacts ) response ;
MessagesStorage . Instance . putUsersAndChats ( res . users , null , true , true ) ;
ArrayList < TLRPC . TL_contact > cArr = new ArrayList < TLRPC . TL_contact > ( ) ;
for ( TLRPC . TL_importedContact c : res . imported ) {
TLRPC . TL_contact contact = new TLRPC . TL_contact ( ) ;
contact . user_id = c . user_id ;
cArr . add ( contact ) ;
}
processLoadedContacts ( cArr , res . users , 2 ) ;
} else {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " import contacts error " + error . text ) ;
2013-10-25 15:19:00 +00:00
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric | RPCRequest . RPCRequestClassFailOnServerErrors ) ;
}
2013-12-20 19:25:49 +00:00
public void loadMessages ( final long dialog_id , final int offset , final int count , final int max_id , boolean fromCache , int midDate , final int classGuid , boolean from_unread , boolean forward ) {
2013-10-25 15:19:00 +00:00
int lower_part = ( int ) dialog_id ;
if ( fromCache | | lower_part = = 0 ) {
2013-12-20 19:25:49 +00:00
MessagesStorage . Instance . getMessages ( dialog_id , offset , count , max_id , midDate , classGuid , from_unread , forward ) ;
2013-10-25 15:19:00 +00:00
} else {
TLRPC . TL_messages_getHistory req = new TLRPC . TL_messages_getHistory ( ) ;
if ( lower_part < 0 ) {
req . peer = new TLRPC . TL_inputPeerChat ( ) ;
req . peer . chat_id = - lower_part ;
} else {
TLRPC . User user = users . get ( lower_part ) ;
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . peer = new TLRPC . TL_inputPeerForeign ( ) ;
req . peer . user_id = user . id ;
req . peer . access_hash = user . access_hash ;
} else {
req . peer = new TLRPC . TL_inputPeerContact ( ) ;
req . peer . user_id = user . id ;
}
}
req . offset = offset ;
req . limit = count ;
req . max_id = max_id ;
long reqId = ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
final TLRPC . messages_Messages res = ( TLRPC . messages_Messages ) response ;
2013-12-20 19:25:49 +00:00
processLoadedMessages ( res , dialog_id , offset , count , max_id , false , classGuid , 0 , 0 , 0 , 0 , false ) ;
2013-10-25 15:19:00 +00:00
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
ConnectionsManager . Instance . bindRequestToGuid ( reqId , classGuid ) ;
}
}
2013-12-20 19:25:49 +00:00
public void processLoadedMessages ( final TLRPC . messages_Messages messagesRes , final long dialog_id , final int offset , final int count , final int max_id , final boolean isCache , final int classGuid , final int first_unread , final int last_unread , final int unread_count , final int last_date , final boolean isForward ) {
2013-10-25 15:19:00 +00:00
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
int lower_id = ( int ) dialog_id ;
if ( ! isCache ) {
MessagesStorage . Instance . putMessages ( messagesRes , dialog_id ) ;
}
2013-12-20 19:25:49 +00:00
if ( lower_id ! = 0 & & isCache & & messagesRes . messages . size ( ) = = 0 & & ! isForward ) {
2013-10-25 15:19:00 +00:00
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
2013-12-20 19:25:49 +00:00
loadMessages ( dialog_id , offset , count , max_id , false , 0 , classGuid , false , false ) ;
2013-10-25 15:19:00 +00:00
}
} ) ;
return ;
}
final HashMap < Integer , TLRPC . User > usersLocal = new HashMap < Integer , TLRPC . User > ( ) ;
for ( TLRPC . User u : messagesRes . users ) {
usersLocal . put ( u . id , u ) ;
}
final ArrayList < MessageObject > objects = new ArrayList < MessageObject > ( ) ;
for ( TLRPC . Message message : messagesRes . messages ) {
message . dialog_id = dialog_id ;
objects . add ( new MessageObject ( message , usersLocal ) ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User u : messagesRes . users ) {
if ( isCache ) {
2013-11-04 12:31:01 +00:00
if ( u . id = = UserConfig . clientUserId | | u . id = = 333000 ) {
users . put ( u . id , u ) ;
} else {
users . putIfAbsent ( u . id , u ) ;
}
2013-10-25 15:19:00 +00:00
} else {
users . put ( u . id , u ) ;
if ( u . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = u ;
}
}
}
for ( TLRPC . Chat c : messagesRes . chats ) {
if ( isCache ) {
chats . putIfAbsent ( c . id , c ) ;
} else {
chats . put ( c . id , c ) ;
}
}
2013-12-20 19:25:49 +00:00
NotificationCenter . Instance . postNotificationName ( messagesDidLoaded , dialog_id , offset , count , objects , isCache , first_unread , last_unread , unread_count , last_date , isForward ) ;
2013-10-25 15:19:00 +00:00
}
} ) ;
}
} ) ;
}
public void loadDialogs ( final int offset , final int serverOffset , final int count , boolean fromCache ) {
if ( loadingDialogs ) {
return ;
}
loadingDialogs = true ;
if ( fromCache ) {
MessagesStorage . Instance . getDialogs ( offset , serverOffset , count ) ;
} else {
TLRPC . TL_messages_getDialogs req = new TLRPC . TL_messages_getDialogs ( ) ;
req . offset = serverOffset ;
req . limit = count ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
final TLRPC . messages_Dialogs dialogsRes = ( TLRPC . messages_Dialogs ) response ;
processLoadedDialogs ( dialogsRes , null , offset , serverOffset , count , false , false ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
}
public void processDialogsUpdate ( final TLRPC . messages_Dialogs dialogsRes , ArrayList < TLRPC . EncryptedChat > encChats ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
final HashMap < Long , TLRPC . TL_dialog > new_dialogs_dict = new HashMap < Long , TLRPC . TL_dialog > ( ) ;
final HashMap < Integer , MessageObject > new_dialogMessage = new HashMap < Integer , MessageObject > ( ) ;
final HashMap < Integer , TLRPC . User > usersLocal = new HashMap < Integer , TLRPC . User > ( ) ;
for ( TLRPC . User u : dialogsRes . users ) {
usersLocal . put ( u . id , u ) ;
}
for ( TLRPC . Message m : dialogsRes . messages ) {
new_dialogMessage . put ( m . id , new MessageObject ( m , usersLocal ) ) ;
}
for ( TLRPC . TL_dialog d : dialogsRes . dialogs ) {
if ( d . last_message_date = = 0 ) {
MessageObject mess = new_dialogMessage . get ( d . top_message ) ;
if ( mess ! = null ) {
d . last_message_date = mess . messageOwner . date ;
}
}
if ( d . id = = 0 ) {
if ( d . peer instanceof TLRPC . TL_peerUser ) {
d . id = d . peer . user_id ;
} else if ( d . peer instanceof TLRPC . TL_peerChat ) {
d . id = - d . peer . chat_id ;
}
}
new_dialogs_dict . put ( d . id , d ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User u : dialogsRes . users ) {
users . putIfAbsent ( u . id , u ) ;
}
for ( TLRPC . Chat c : dialogsRes . chats ) {
chats . putIfAbsent ( c . id , c ) ;
}
for ( HashMap . Entry < Long , TLRPC . TL_dialog > pair : new_dialogs_dict . entrySet ( ) ) {
long key = pair . getKey ( ) ;
TLRPC . TL_dialog value = pair . getValue ( ) ;
TLRPC . TL_dialog currentDialog = dialogs_dict . get ( key ) ;
if ( currentDialog = = null ) {
dialogs_dict . put ( key , value ) ;
dialogMessage . put ( value . top_message , new_dialogMessage . get ( value . top_message ) ) ;
} else {
currentDialog . unread_count = value . unread_count ;
MessageObject oldMsg = dialogMessage . get ( currentDialog . top_message ) ;
if ( oldMsg = = null | | currentDialog . top_message > 0 ) {
if ( oldMsg ! = null & & oldMsg . deleted | | value . top_message > currentDialog . top_message ) {
dialogs_dict . put ( key , value ) ;
if ( oldMsg ! = null ) {
dialogMessage . remove ( oldMsg . messageOwner . id ) ;
}
dialogMessage . put ( value . top_message , new_dialogMessage . get ( value . top_message ) ) ;
}
} else {
MessageObject newMsg = new_dialogMessage . get ( value . top_message ) ;
if ( oldMsg . deleted | | newMsg = = null | | newMsg . messageOwner . date > oldMsg . messageOwner . date ) {
dialogs_dict . put ( key , value ) ;
dialogMessage . remove ( oldMsg . messageOwner . id ) ;
dialogMessage . put ( value . top_message , new_dialogMessage . get ( value . top_message ) ) ;
}
}
}
}
dialogs . clear ( ) ;
dialogsServerOnly . clear ( ) ;
dialogs . addAll ( dialogs_dict . values ( ) ) ;
Collections . sort ( dialogs , new Comparator < TLRPC . TL_dialog > ( ) {
@Override
public int compare ( TLRPC . TL_dialog tl_dialog , TLRPC . TL_dialog tl_dialog2 ) {
if ( tl_dialog . last_message_date = = tl_dialog2 . last_message_date ) {
return 0 ;
} else if ( tl_dialog . last_message_date < tl_dialog2 . last_message_date ) {
return 1 ;
} else {
return - 1 ;
}
}
} ) ;
for ( TLRPC . TL_dialog d : dialogs ) {
if ( ( int ) d . id ! = 0 ) {
dialogsServerOnly . add ( d ) ;
}
}
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
} ) ;
}
} ) ;
}
public void processLoadedDialogs ( final TLRPC . messages_Dialogs dialogsRes , final ArrayList < TLRPC . EncryptedChat > encChats , final int offset , final int serverOffset , final int count , final boolean isCache , final boolean resetEnd ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
if ( isCache & & dialogsRes . dialogs . size ( ) = = 0 ) {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User u : dialogsRes . users ) {
if ( isCache ) {
2013-11-04 12:31:01 +00:00
if ( u . id = = UserConfig . clientUserId | | u . id = = 333000 ) {
users . put ( u . id , u ) ;
} else {
users . putIfAbsent ( u . id , u ) ;
}
2013-10-25 15:19:00 +00:00
} else {
users . put ( u . id , u ) ;
if ( u . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = u ;
}
}
}
loadingDialogs = false ;
if ( resetEnd ) {
dialogsEndReached = false ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
loadDialogs ( offset , serverOffset , count , false ) ;
}
} ) ;
return ;
}
final HashMap < Long , TLRPC . TL_dialog > new_dialogs_dict = new HashMap < Long , TLRPC . TL_dialog > ( ) ;
final HashMap < Integer , MessageObject > new_dialogMessage = new HashMap < Integer , MessageObject > ( ) ;
final HashMap < Integer , TLRPC . User > usersLocal = new HashMap < Integer , TLRPC . User > ( ) ;
int new_totalDialogsCount ;
if ( ! isCache ) {
MessagesStorage . Instance . putDialogs ( dialogsRes ) ;
}
if ( dialogsRes instanceof TLRPC . TL_messages_dialogsSlice ) {
TLRPC . TL_messages_dialogsSlice slice = ( TLRPC . TL_messages_dialogsSlice ) dialogsRes ;
new_totalDialogsCount = slice . count ;
} else {
new_totalDialogsCount = dialogsRes . dialogs . size ( ) ;
}
for ( TLRPC . User u : dialogsRes . users ) {
usersLocal . put ( u . id , u ) ;
}
for ( TLRPC . Message m : dialogsRes . messages ) {
new_dialogMessage . put ( m . id , new MessageObject ( m , usersLocal ) ) ;
}
for ( TLRPC . TL_dialog d : dialogsRes . dialogs ) {
if ( d . last_message_date = = 0 ) {
MessageObject mess = new_dialogMessage . get ( d . top_message ) ;
if ( mess ! = null ) {
d . last_message_date = mess . messageOwner . date ;
}
}
if ( d . id = = 0 ) {
if ( d . peer instanceof TLRPC . TL_peerUser ) {
d . id = d . peer . user_id ;
} else if ( d . peer instanceof TLRPC . TL_peerChat ) {
d . id = - d . peer . chat_id ;
}
}
new_dialogs_dict . put ( d . id , d ) ;
}
final int arg1 = new_totalDialogsCount ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User u : dialogsRes . users ) {
if ( isCache ) {
2013-11-04 12:31:01 +00:00
if ( u . id = = UserConfig . clientUserId | | u . id = = 333000 ) {
users . put ( u . id , u ) ;
} else {
users . putIfAbsent ( u . id , u ) ;
}
2013-10-25 15:19:00 +00:00
} else {
users . put ( u . id , u ) ;
if ( u . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = u ;
}
}
}
for ( TLRPC . Chat c : dialogsRes . chats ) {
if ( isCache ) {
chats . putIfAbsent ( c . id , c ) ;
} else {
chats . put ( c . id , c ) ;
}
}
if ( encChats ! = null ) {
for ( TLRPC . EncryptedChat encryptedChat : encChats ) {
encryptedChats . put ( encryptedChat . id , encryptedChat ) ;
}
}
loadingDialogs = false ;
totalDialogsCount = arg1 ;
for ( HashMap . Entry < Long , TLRPC . TL_dialog > pair : new_dialogs_dict . entrySet ( ) ) {
long key = pair . getKey ( ) ;
TLRPC . TL_dialog value = pair . getValue ( ) ;
TLRPC . TL_dialog currentDialog = dialogs_dict . get ( key ) ;
if ( currentDialog = = null ) {
dialogs_dict . put ( key , value ) ;
dialogMessage . put ( value . top_message , new_dialogMessage . get ( value . top_message ) ) ;
} else {
MessageObject oldMsg = dialogMessage . get ( value . top_message ) ;
if ( oldMsg = = null | | currentDialog . top_message > 0 ) {
if ( oldMsg ! = null & & oldMsg . deleted | | value . top_message > currentDialog . top_message ) {
if ( oldMsg ! = null ) {
dialogMessage . remove ( oldMsg . messageOwner . id ) ;
}
dialogs_dict . put ( key , value ) ;
dialogMessage . put ( value . top_message , new_dialogMessage . get ( value . top_message ) ) ;
}
} else {
MessageObject newMsg = new_dialogMessage . get ( value . top_message ) ;
if ( oldMsg . deleted | | newMsg = = null | | newMsg . messageOwner . date > oldMsg . messageOwner . date ) {
dialogMessage . remove ( oldMsg . messageOwner . id ) ;
dialogs_dict . put ( key , value ) ;
dialogMessage . put ( value . top_message , new_dialogMessage . get ( value . top_message ) ) ;
}
}
}
}
dialogs . clear ( ) ;
dialogsServerOnly . clear ( ) ;
dialogs . addAll ( dialogs_dict . values ( ) ) ;
Collections . sort ( dialogs , new Comparator < TLRPC . TL_dialog > ( ) {
@Override
public int compare ( TLRPC . TL_dialog tl_dialog , TLRPC . TL_dialog tl_dialog2 ) {
if ( tl_dialog . last_message_date = = tl_dialog2 . last_message_date ) {
return 0 ;
} else if ( tl_dialog . last_message_date < tl_dialog2 . last_message_date ) {
return 1 ;
} else {
return - 1 ;
}
}
} ) ;
for ( TLRPC . TL_dialog d : dialogs ) {
if ( ( int ) d . id ! = 0 ) {
dialogsServerOnly . add ( d ) ;
}
}
dialogsEndReached = ( dialogsRes . dialogs . size ( ) = = 0 | | dialogsRes . dialogs . size ( ) ! = count ) & & ! isCache ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
} ) ;
}
} ) ;
}
public TLRPC . TL_photo generatePhotoSizes ( String path ) {
long time = System . currentTimeMillis ( ) ;
Bitmap bitmap = FileLoader . loadBitmap ( path , 800 , 800 ) ;
ArrayList < TLRPC . PhotoSize > sizes = new ArrayList < TLRPC . PhotoSize > ( ) ;
TLRPC . PhotoSize size = FileLoader . scaleAndSaveImage ( bitmap , 90 , 90 , 55 , true ) ;
if ( size ! = null ) {
size . type = " s " ;
sizes . add ( size ) ;
}
size = FileLoader . scaleAndSaveImage ( bitmap , 320 , 320 , 87 , false ) ;
if ( size ! = null ) {
size . type = " m " ;
sizes . add ( size ) ;
}
size = FileLoader . scaleAndSaveImage ( bitmap , 800 , 800 , 87 , false ) ;
if ( size ! = null ) {
size . type = " x " ;
sizes . add ( size ) ;
}
2013-12-20 19:25:49 +00:00
if ( Build . VERSION . SDK_INT < 11 ) {
if ( bitmap ! = null ) {
bitmap . recycle ( ) ;
}
2013-10-25 15:19:00 +00:00
}
if ( sizes . isEmpty ( ) ) {
return null ;
} else {
2013-11-04 12:31:01 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
TLRPC . TL_photo photo = new TLRPC . TL_photo ( ) ;
photo . user_id = UserConfig . clientUserId ;
photo . date = ConnectionsManager . Instance . getCurrentTime ( ) ;
photo . sizes = sizes ;
photo . caption = " " ;
photo . geo = new TLRPC . TL_geoPointEmpty ( ) ;
return photo ;
}
}
2013-12-20 19:25:49 +00:00
public void markDialogAsRead ( final long dialog_id , final int max_id , final int max_positive_id , final int offset , final int max_date , final boolean was ) {
2013-10-25 15:19:00 +00:00
int lower_part = ( int ) dialog_id ;
if ( lower_part ! = 0 ) {
if ( max_id = = 0 & & offset = = 0 ) {
return ;
}
TLRPC . TL_messages_readHistory req = new TLRPC . TL_messages_readHistory ( ) ;
if ( lower_part < 0 ) {
req . peer = new TLRPC . TL_inputPeerChat ( ) ;
req . peer . chat_id = - lower_part ;
} else {
TLRPC . User user = users . get ( lower_part ) ;
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . peer = new TLRPC . TL_inputPeerForeign ( ) ;
req . peer . user_id = user . id ;
req . peer . access_hash = user . access_hash ;
} else {
req . peer = new TLRPC . TL_inputPeerContact ( ) ;
req . peer . user_id = user . id ;
}
}
2013-12-20 19:25:49 +00:00
req . max_id = max_positive_id ;
2013-10-25 15:19:00 +00:00
req . offset = offset ;
if ( offset = = 0 ) {
2013-12-20 19:25:49 +00:00
MessagesStorage . Instance . processPendingRead ( dialog_id , max_positive_id , max_date , false ) ;
2013-10-25 15:19:00 +00:00
}
2013-12-20 19:25:49 +00:00
if ( req . max_id ! = Integer . MAX_VALUE ) {
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
MessagesStorage . Instance . processPendingRead ( dialog_id , max_positive_id , max_date , true ) ;
TLRPC . TL_messages_affectedHistory res = ( TLRPC . TL_messages_affectedHistory ) response ;
if ( res . offset > 0 ) {
markDialogAsRead ( dialog_id , 0 , max_positive_id , res . offset , max_date , was ) ;
}
2013-10-25 15:19:00 +00:00
2013-12-20 19:25:49 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
} else if ( MessagesStorage . lastSeqValue ! = res . seq ) {
getDifference ( ) ;
}
2013-10-25 15:19:00 +00:00
}
}
2013-12-20 19:25:49 +00:00
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
2013-10-25 15:19:00 +00:00
if ( offset = = 0 ) {
TLRPC . TL_dialog dialog = dialogs_dict . get ( dialog_id ) ;
if ( dialog ! = null ) {
dialog . unread_count = 0 ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
TLRPC . TL_messages_receivedMessages req2 = new TLRPC . TL_messages_receivedMessages ( ) ;
2013-12-20 19:25:49 +00:00
req2 . max_id = max_positive_id ;
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . performRpc ( req2 , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric | RPCRequest . RPCRequestClassFailOnServerErrors ) ;
}
} else {
if ( max_date = = 0 ) {
return ;
}
int encId = ( int ) ( dialog_id > > 32 ) ;
TLRPC . EncryptedChat chat = encryptedChats . get ( encId ) ;
if ( chat . auth_key ! = null & & chat . auth_key . length > 1 & & chat instanceof TLRPC . TL_encryptedChat ) {
TLRPC . TL_messages_readEncryptedHistory req = new TLRPC . TL_messages_readEncryptedHistory ( ) ;
req . peer = new TLRPC . TL_inputEncryptedChat ( ) ;
req . peer . chat_id = chat . id ;
req . peer . access_hash = chat . access_hash ;
req . max_date = max_date ;
2013-12-20 19:25:49 +00:00
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
2013-12-20 19:25:49 +00:00
//MessagesStorage.Instance.processPendingRead(dialog_id, max_id, max_date, true);
2013-10-25 15:19:00 +00:00
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
2013-12-20 19:25:49 +00:00
}
MessagesStorage . Instance . processPendingRead ( dialog_id , max_id , max_date , false ) ;
TLRPC . TL_dialog dialog = dialogs_dict . get ( dialog_id ) ;
if ( dialog ! = null ) {
dialog . unread_count = 0 ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
2013-10-25 15:19:00 +00:00
2013-12-20 19:25:49 +00:00
if ( chat . ttl > 0 & & was ) {
int serverTime = Math . max ( ConnectionsManager . Instance . getCurrentTime ( ) , max_date ) ;
MessagesStorage . Instance . createTaskForDate ( chat . id , serverTime , serverTime , 0 ) ;
2013-10-25 15:19:00 +00:00
}
}
}
public void cancelSendingMessage ( MessageObject object ) {
String keyToRemvoe = null ;
for ( HashMap . Entry < String , DelayedMessage > entry : delayedMessages . entrySet ( ) ) {
if ( entry . getValue ( ) . obj . messageOwner . id = = object . messageOwner . id ) {
keyToRemvoe = entry . getKey ( ) ;
break ;
}
}
if ( keyToRemvoe ! = null ) {
ArrayList < Integer > messages = new ArrayList < Integer > ( ) ;
messages . add ( object . messageOwner . id ) ;
FileLoader . Instance . cancelUploadFile ( keyToRemvoe ) ;
deleteMessages ( messages ) ;
}
}
private long getNextRandomId ( ) {
long val = 0 ;
while ( val = = 0 ) {
val = random . nextLong ( ) ;
}
return val ;
}
public void sendMessage ( TLRPC . User user , long peer ) {
sendMessage ( null , 0 , 0 , null , null , null , null , user , peer ) ;
}
public void sendMessage ( MessageObject message , long peer ) {
sendMessage ( null , 0 , 0 , null , null , message , null , null , peer ) ;
}
public void sendMessage ( String message , long peer ) {
sendMessage ( message , 0 , 0 , null , null , null , null , null , peer ) ;
}
public void sendMessage ( TLRPC . FileLocation location , long peer ) {
sendMessage ( null , 0 , 0 , null , null , null , location , null , peer ) ;
}
public void sendMessage ( double lat , double lon , long peer ) {
sendMessage ( null , lat , lon , null , null , null , null , null , peer ) ;
}
public void sendMessage ( TLRPC . TL_photo photo , long peer ) {
sendMessage ( null , 0 , 0 , photo , null , null , null , null , peer ) ;
}
public void sendMessage ( TLRPC . TL_video video , long peer ) {
sendMessage ( null , 0 , 0 , null , video , null , null , null , peer ) ;
}
public void sendTTLMessage ( TLRPC . EncryptedChat encryptedChat ) {
TLRPC . TL_messageService newMsg = new TLRPC . TL_messageService ( ) ;
newMsg . action = new TLRPC . TL_messageActionTTLChange ( ) ;
newMsg . action . ttl = encryptedChat . ttl ;
newMsg . local_id = newMsg . id = UserConfig . getNewMessageId ( ) ;
newMsg . from_id = UserConfig . clientUserId ;
newMsg . unread = true ;
newMsg . dialog_id = ( ( long ) encryptedChat . id ) < < 32 ;
newMsg . to_id = new TLRPC . TL_peerUser ( ) ;
if ( encryptedChat . participant_id = = UserConfig . clientUserId ) {
newMsg . to_id . user_id = encryptedChat . admin_id ;
} else {
newMsg . to_id . user_id = encryptedChat . participant_id ;
}
newMsg . out = true ;
newMsg . date = ConnectionsManager . Instance . getCurrentTime ( ) ;
newMsg . random_id = getNextRandomId ( ) ;
2013-11-04 12:31:01 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
final MessageObject newMsgObj = new MessageObject ( newMsg , users ) ;
newMsgObj . messageOwner . send_state = MESSAGE_SEND_STATE_SENDING ;
final ArrayList < MessageObject > objArr = new ArrayList < MessageObject > ( ) ;
objArr . add ( newMsgObj ) ;
ArrayList < TLRPC . Message > arr = new ArrayList < TLRPC . Message > ( ) ;
arr . add ( newMsg ) ;
MessagesStorage . Instance . putMessages ( arr , false , true ) ;
updateInterfaceWithMessages ( newMsg . dialog_id , objArr ) ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
sendingMessages . put ( newMsg . id , newMsgObj ) ;
TLRPC . TL_decryptedMessageService reqSend = new TLRPC . TL_decryptedMessageService ( ) ;
reqSend . random_id = newMsg . random_id ;
reqSend . random_bytes = new byte [ Math . max ( 1 , ( int ) Math . ceil ( random . nextDouble ( ) * 16 ) ) ] ;
random . nextBytes ( reqSend . random_bytes ) ;
reqSend . action = new TLRPC . TL_decryptedMessageActionSetMessageTTL ( ) ;
reqSend . action . ttl_seconds = encryptedChat . ttl ;
performSendEncryptedRequest ( reqSend , newMsgObj , encryptedChat , null ) ;
}
private void sendMessage ( String message , double lat , double lon , TLRPC . TL_photo photo , TLRPC . TL_video video , MessageObject msgObj , TLRPC . FileLocation location , TLRPC . User user , long peer ) {
TLRPC . Message newMsg = null ;
int type = - 1 ;
if ( message ! = null ) {
newMsg = new TLRPC . TL_message ( ) ;
newMsg . media = new TLRPC . TL_messageMediaEmpty ( ) ;
type = 0 ;
newMsg . message = message ;
} else if ( lat ! = 0 & & lon ! = 0 ) {
newMsg = new TLRPC . TL_message ( ) ;
newMsg . media = new TLRPC . TL_messageMediaGeo ( ) ;
newMsg . media . geo = new TLRPC . TL_geoPoint ( ) ;
newMsg . media . geo . lat = lat ;
newMsg . media . geo . _long = lon ;
newMsg . message = " " ;
type = 1 ;
} else if ( photo ! = null ) {
newMsg = new TLRPC . TL_message ( ) ;
newMsg . media = new TLRPC . TL_messageMediaPhoto ( ) ;
newMsg . media . photo = photo ;
type = 2 ;
newMsg . message = " -1 " ;
TLRPC . FileLocation location1 = photo . sizes . get ( photo . sizes . size ( ) - 1 ) . location ;
newMsg . attachPath = Utilities . getCacheDir ( ) + " / " + location1 . volume_id + " _ " + location1 . local_id + " .jpg " ;
} else if ( video ! = null ) {
newMsg = new TLRPC . TL_message ( ) ;
newMsg . media = new TLRPC . TL_messageMediaVideo ( ) ;
newMsg . media . video = video ;
type = 3 ;
newMsg . message = " -1 " ;
newMsg . attachPath = video . path ;
} else if ( msgObj ! = null ) {
newMsg = new TLRPC . TL_messageForwarded ( ) ;
if ( msgObj . messageOwner instanceof TLRPC . TL_messageForwarded ) {
newMsg . fwd_from_id = msgObj . messageOwner . fwd_from_id ;
newMsg . fwd_date = msgObj . messageOwner . fwd_date ;
newMsg . media = msgObj . messageOwner . media ;
newMsg . message = msgObj . messageOwner . message ;
newMsg . fwd_msg_id = msgObj . messageOwner . id ;
type = 4 ;
} else if ( msgObj . type = = 11 ) {
newMsg . fwd_from_id = msgObj . messageOwner . from_id ;
newMsg . fwd_date = msgObj . messageOwner . date ;
newMsg . media = new TLRPC . TL_messageMediaPhoto ( ) ;
newMsg . media . photo = msgObj . messageOwner . action . photo ;
newMsg . message = " " ;
newMsg . fwd_msg_id = msgObj . messageOwner . id ;
type = 5 ;
} else {
newMsg . fwd_from_id = msgObj . messageOwner . from_id ;
newMsg . fwd_date = msgObj . messageOwner . date ;
newMsg . media = msgObj . messageOwner . media ;
newMsg . message = msgObj . messageOwner . message ;
newMsg . fwd_msg_id = msgObj . messageOwner . id ;
type = 4 ;
}
} else if ( location ! = null ) {
} else if ( user ! = null ) {
newMsg = new TLRPC . TL_message ( ) ;
newMsg . media = new TLRPC . TL_messageMediaContact ( ) ;
newMsg . media . phone_number = user . phone ;
newMsg . media . first_name = user . first_name ;
newMsg . media . last_name = user . last_name ;
newMsg . media . user_id = user . id ;
newMsg . message = " " ;
type = 6 ;
}
if ( newMsg = = null ) {
return ;
}
newMsg . local_id = newMsg . id = UserConfig . getNewMessageId ( ) ;
newMsg . from_id = UserConfig . clientUserId ;
newMsg . unread = true ;
newMsg . dialog_id = peer ;
int lower_id = ( int ) peer ;
TLRPC . EncryptedChat encryptedChat = null ;
TLRPC . InputPeer sendToPeer = null ;
if ( lower_id ! = 0 ) {
if ( lower_id < 0 ) {
newMsg . to_id = new TLRPC . TL_peerChat ( ) ;
newMsg . to_id . chat_id = - lower_id ;
sendToPeer = new TLRPC . TL_inputPeerChat ( ) ;
sendToPeer . chat_id = - lower_id ;
} else {
newMsg . to_id = new TLRPC . TL_peerUser ( ) ;
newMsg . to_id . user_id = lower_id ;
TLRPC . User sendToUser = users . get ( lower_id ) ;
2013-12-20 19:25:49 +00:00
if ( sendToUser = = null ) {
return ;
}
2013-10-25 15:19:00 +00:00
if ( sendToUser instanceof TLRPC . TL_userForeign | | sendToUser instanceof TLRPC . TL_userRequest ) {
sendToPeer = new TLRPC . TL_inputPeerForeign ( ) ;
sendToPeer . user_id = sendToUser . id ;
sendToPeer . access_hash = sendToUser . access_hash ;
} else {
sendToPeer = new TLRPC . TL_inputPeerContact ( ) ;
sendToPeer . user_id = sendToUser . id ;
}
}
} else {
encryptedChat = encryptedChats . get ( ( int ) ( peer > > 32 ) ) ;
newMsg . to_id = new TLRPC . TL_peerUser ( ) ;
if ( encryptedChat . participant_id = = UserConfig . clientUserId ) {
newMsg . to_id . user_id = encryptedChat . admin_id ;
} else {
newMsg . to_id . user_id = encryptedChat . participant_id ;
}
newMsg . ttl = encryptedChat . ttl ;
}
newMsg . out = true ;
newMsg . date = ConnectionsManager . Instance . getCurrentTime ( ) ;
newMsg . random_id = getNextRandomId ( ) ;
2013-11-04 12:31:01 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
final MessageObject newMsgObj = new MessageObject ( newMsg , null ) ;
newMsgObj . messageOwner . send_state = MESSAGE_SEND_STATE_SENDING ;
final ArrayList < MessageObject > objArr = new ArrayList < MessageObject > ( ) ;
objArr . add ( newMsgObj ) ;
ArrayList < TLRPC . Message > arr = new ArrayList < TLRPC . Message > ( ) ;
arr . add ( newMsg ) ;
MessagesStorage . Instance . putMessages ( arr , false , true ) ;
updateInterfaceWithMessages ( peer , objArr ) ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
sendingMessages . put ( newMsg . id , newMsgObj ) ;
if ( type = = 0 ) {
if ( encryptedChat = = null ) {
TLRPC . TL_messages_sendMessage reqSend = new TLRPC . TL_messages_sendMessage ( ) ;
reqSend . message = message ;
reqSend . peer = sendToPeer ;
reqSend . random_id = newMsg . random_id ;
performSendMessageRequest ( reqSend , newMsgObj ) ;
} else {
TLRPC . TL_decryptedMessage reqSend = new TLRPC . TL_decryptedMessage ( ) ;
reqSend . random_id = newMsg . random_id ;
reqSend . random_bytes = new byte [ Math . max ( 1 , ( int ) Math . ceil ( random . nextDouble ( ) * 16 ) ) ] ;
random . nextBytes ( reqSend . random_bytes ) ;
reqSend . message = message ;
reqSend . media = new TLRPC . TL_decryptedMessageMediaEmpty ( ) ;
performSendEncryptedRequest ( reqSend , newMsgObj , encryptedChat , null ) ;
}
} else if ( type = = 1 | | type = = 2 | | type = = 3 | | type = = 5 | | type = = 6 ) {
if ( encryptedChat = = null ) {
TLRPC . TL_messages_sendMedia reqSend = new TLRPC . TL_messages_sendMedia ( ) ;
reqSend . peer = sendToPeer ;
reqSend . random_id = newMsg . random_id ;
if ( type = = 1 ) {
reqSend . media = new TLRPC . TL_inputMediaGeoPoint ( ) ;
reqSend . media . geo_point = new TLRPC . TL_inputGeoPoint ( ) ;
reqSend . media . geo_point . lat = lat ;
reqSend . media . geo_point . _long = lon ;
performSendMessageRequest ( reqSend , newMsgObj ) ;
} else if ( type = = 2 ) {
reqSend . media = new TLRPC . TL_inputMediaUploadedPhoto ( ) ;
DelayedMessage delayedMessage = new DelayedMessage ( ) ;
delayedMessage . sendRequest = reqSend ;
delayedMessage . type = 0 ;
delayedMessage . obj = newMsgObj ;
delayedMessage . location = photo . sizes . get ( photo . sizes . size ( ) - 1 ) . location ;
performSendDelayedMessage ( delayedMessage ) ;
} else if ( type = = 3 ) {
reqSend . media = new TLRPC . TL_inputMediaUploadedThumbVideo ( ) ;
reqSend . media . duration = video . duration ;
reqSend . media . w = video . w ;
reqSend . media . h = video . h ;
DelayedMessage delayedMessage = new DelayedMessage ( ) ;
delayedMessage . sendRequest = reqSend ;
delayedMessage . type = 1 ;
delayedMessage . obj = newMsgObj ;
delayedMessage . location = video . thumb . location ;
delayedMessage . videoLocation = video ;
performSendDelayedMessage ( delayedMessage ) ;
} else if ( type = = 5 ) {
reqSend . media = new TLRPC . TL_inputMediaPhoto ( ) ;
TLRPC . TL_inputPhoto ph = new TLRPC . TL_inputPhoto ( ) ;
ph . id = msgObj . messageOwner . action . photo . id ;
ph . access_hash = msgObj . messageOwner . action . photo . access_hash ;
( ( TLRPC . TL_inputMediaPhoto ) reqSend . media ) . id = ph ;
performSendMessageRequest ( reqSend , newMsgObj ) ;
} else if ( type = = 6 ) {
reqSend . media = new TLRPC . TL_inputMediaContact ( ) ;
reqSend . media . phone_number = user . phone ;
reqSend . media . first_name = user . first_name ;
reqSend . media . last_name = user . last_name ;
performSendMessageRequest ( reqSend , newMsgObj ) ;
}
} else {
TLRPC . TL_decryptedMessage reqSend = new TLRPC . TL_decryptedMessage ( ) ;
reqSend . random_id = newMsg . random_id ;
reqSend . random_bytes = new byte [ Math . max ( 1 , ( int ) Math . ceil ( random . nextDouble ( ) * 16 ) ) ] ;
random . nextBytes ( reqSend . random_bytes ) ;
reqSend . message = " " ;
if ( type = = 1 ) {
reqSend . media = new TLRPC . TL_decryptedMessageMediaGeoPoint ( ) ;
reqSend . media . lat = lat ;
reqSend . media . _long = lon ;
performSendEncryptedRequest ( reqSend , newMsgObj , encryptedChat , null ) ;
} else if ( type = = 2 ) {
reqSend . media = new TLRPC . TL_decryptedMessageMediaPhoto ( ) ;
reqSend . media . iv = new byte [ 32 ] ;
reqSend . media . key = new byte [ 32 ] ;
random . nextBytes ( reqSend . media . iv ) ;
random . nextBytes ( reqSend . media . key ) ;
TLRPC . PhotoSize small = photo . sizes . get ( 0 ) ;
TLRPC . PhotoSize big = photo . sizes . get ( photo . sizes . size ( ) - 1 ) ;
reqSend . media . thumb = small . bytes ;
reqSend . media . thumb_h = small . h ;
reqSend . media . thumb_w = small . w ;
reqSend . media . w = big . w ;
reqSend . media . h = big . h ;
reqSend . media . size = big . size ;
DelayedMessage delayedMessage = new DelayedMessage ( ) ;
delayedMessage . sendEncryptedRequest = reqSend ;
delayedMessage . type = 0 ;
delayedMessage . obj = newMsgObj ;
delayedMessage . encryptedChat = encryptedChat ;
delayedMessage . location = photo . sizes . get ( photo . sizes . size ( ) - 1 ) . location ;
performSendDelayedMessage ( delayedMessage ) ;
} else if ( type = = 3 ) {
reqSend . media = new TLRPC . TL_decryptedMessageMediaVideo ( ) ;
reqSend . media . iv = new byte [ 32 ] ;
reqSend . media . key = new byte [ 32 ] ;
random . nextBytes ( reqSend . media . iv ) ;
random . nextBytes ( reqSend . media . key ) ;
reqSend . media . duration = video . duration ;
reqSend . media . size = video . size ;
reqSend . media . w = video . w ;
reqSend . media . h = video . h ;
reqSend . media . thumb = video . thumb . bytes ;
reqSend . media . thumb_h = video . thumb . h ;
reqSend . media . thumb_w = video . thumb . w ;
DelayedMessage delayedMessage = new DelayedMessage ( ) ;
delayedMessage . sendEncryptedRequest = reqSend ;
delayedMessage . type = 1 ;
delayedMessage . obj = newMsgObj ;
delayedMessage . encryptedChat = encryptedChat ;
delayedMessage . videoLocation = video ;
performSendDelayedMessage ( delayedMessage ) ;
} else if ( type = = 5 ) {
} else if ( type = = 6 ) {
reqSend . media = new TLRPC . TL_decryptedMessageMediaContact ( ) ;
reqSend . media . phone_number = user . phone ;
reqSend . media . first_name = user . first_name ;
reqSend . media . last_name = user . last_name ;
reqSend . media . user_id = user . id ;
performSendEncryptedRequest ( reqSend , newMsgObj , encryptedChat , null ) ;
}
}
} else if ( type = = 4 ) {
TLRPC . TL_messages_forwardMessage reqSend = new TLRPC . TL_messages_forwardMessage ( ) ;
reqSend . peer = sendToPeer ;
reqSend . random_id = newMsg . random_id ;
if ( msgObj . messageOwner . id > = 0 ) {
reqSend . id = msgObj . messageOwner . id ;
} else {
reqSend . id = msgObj . messageOwner . fwd_msg_id ;
}
performSendMessageRequest ( reqSend , newMsgObj ) ;
}
}
private void processSendedMessage ( TLRPC . Message newMsg , TLRPC . Message sendedMessage , TLRPC . EncryptedFile file , TLRPC . DecryptedMessage decryptedMessage ) {
if ( sendedMessage ! = null ) {
if ( sendedMessage . media instanceof TLRPC . TL_messageMediaPhoto & & sendedMessage . media . photo ! = null & & newMsg . media instanceof TLRPC . TL_messageMediaPhoto & & newMsg . media . photo ! = null ) {
for ( TLRPC . PhotoSize size : sendedMessage . media . photo . sizes ) {
2013-12-20 19:25:49 +00:00
if ( size instanceof TLRPC . TL_photoSizeEmpty ) {
continue ;
}
2013-10-25 15:19:00 +00:00
for ( TLRPC . PhotoSize size2 : newMsg . media . photo . sizes ) {
if ( size . type . equals ( size2 . type ) ) {
String fileName = size2 . location . volume_id + " _ " + size2 . location . local_id ;
String fileName2 = size . location . volume_id + " _ " + size . location . local_id ;
if ( fileName . equals ( fileName2 ) ) {
break ;
}
File cacheFile = new File ( Utilities . getCacheDir ( ) , fileName + " .jpg " ) ;
File cacheFile2 = new File ( Utilities . getCacheDir ( ) , fileName2 + " .jpg " ) ;
cacheFile . renameTo ( cacheFile2 ) ;
FileLoader . Instance . replaceImageInCache ( fileName , fileName2 ) ;
size2 . location = size . location ;
break ;
}
}
}
sendedMessage . message = newMsg . message ;
sendedMessage . attachPath = newMsg . attachPath ;
} else if ( sendedMessage . media instanceof TLRPC . TL_messageMediaVideo & & sendedMessage . media . video ! = null & & newMsg . media instanceof TLRPC . TL_messageMediaVideo & & newMsg . media . video ! = null ) {
TLRPC . PhotoSize size2 = newMsg . media . video . thumb ;
TLRPC . PhotoSize size = sendedMessage . media . video . thumb ;
2013-12-20 19:25:49 +00:00
if ( size2 . location ! = null & & size . location ! = null & & ! ( size instanceof TLRPC . TL_photoSizeEmpty ) & & ! ( size2 instanceof TLRPC . TL_photoSizeEmpty ) ) {
String fileName = size2 . location . volume_id + " _ " + size2 . location . local_id ;
String fileName2 = size . location . volume_id + " _ " + size . location . local_id ;
if ( fileName . equals ( fileName2 ) ) {
return ;
}
File cacheFile = new File ( Utilities . getCacheDir ( ) , fileName + " .jpg " ) ;
File cacheFile2 = new File ( Utilities . getCacheDir ( ) , fileName2 + " .jpg " ) ;
boolean result = cacheFile . renameTo ( cacheFile2 ) ;
FileLoader . Instance . replaceImageInCache ( fileName , fileName2 ) ;
size2 . location = size . location ;
sendedMessage . message = newMsg . message ;
sendedMessage . attachPath = newMsg . attachPath ;
2013-10-25 15:19:00 +00:00
}
}
} else if ( file ! = null ) {
if ( newMsg . media instanceof TLRPC . TL_messageMediaPhoto & & newMsg . media . photo ! = null ) {
TLRPC . PhotoSize size = newMsg . media . photo . sizes . get ( newMsg . media . photo . sizes . size ( ) - 1 ) ;
String fileName = size . location . volume_id + " _ " + size . location . local_id ;
size . location = new TLRPC . TL_fileEncryptedLocation ( ) ;
size . location . key = decryptedMessage . media . key ;
size . location . iv = decryptedMessage . media . iv ;
size . location . dc_id = file . dc_id ;
size . location . volume_id = file . id ;
size . location . secret = file . access_hash ;
size . location . local_id = file . key_fingerprint ;
String fileName2 = size . location . volume_id + " _ " + size . location . local_id ;
File cacheFile = new File ( Utilities . getCacheDir ( ) , fileName + " .jpg " ) ;
File cacheFile2 = new File ( Utilities . getCacheDir ( ) , fileName2 + " .jpg " ) ;
boolean result = cacheFile . renameTo ( cacheFile2 ) ;
FileLoader . Instance . replaceImageInCache ( fileName , fileName2 ) ;
ArrayList < TLRPC . Message > arr = new ArrayList < TLRPC . Message > ( ) ;
arr . add ( newMsg ) ;
MessagesStorage . Instance . putMessages ( arr , false , true ) ;
} else if ( newMsg . media instanceof TLRPC . TL_messageMediaVideo & & newMsg . media . video ! = null ) {
TLRPC . Video video = newMsg . media . video ;
newMsg . media . video = new TLRPC . TL_videoEncrypted ( ) ;
newMsg . media . video . duration = video . duration ;
newMsg . media . video . thumb = video . thumb ;
newMsg . media . video . id = video . id ;
newMsg . media . video . dc_id = file . dc_id ;
newMsg . media . video . w = video . w ;
newMsg . media . video . h = video . h ;
newMsg . media . video . date = video . date ;
newMsg . media . video . caption = " " ;
newMsg . media . video . user_id = video . user_id ;
newMsg . media . video . size = file . size ;
newMsg . media . video . id = file . id ;
newMsg . media . video . access_hash = file . access_hash ;
newMsg . media . video . key = decryptedMessage . media . key ;
newMsg . media . video . iv = decryptedMessage . media . iv ;
newMsg . media . video . path = video . path ;
ArrayList < TLRPC . Message > arr = new ArrayList < TLRPC . Message > ( ) ;
arr . add ( newMsg ) ;
MessagesStorage . Instance . putMessages ( arr , false , true ) ;
}
}
}
private void performSendEncryptedRequest ( final TLRPC . DecryptedMessage req , final MessageObject newMsgObj , final TLRPC . EncryptedChat chat , final TLRPC . InputEncryptedFile encryptedFile ) {
2013-11-04 12:31:01 +00:00
if ( req = = null ) {
return ;
}
2013-10-25 15:19:00 +00:00
//TLRPC.decryptedMessageLayer messageLayer = new TLRPC.decryptedMessageLayer();
//messageLayer.layer = 8;
//messageLayer.message = req;
SerializedData data = new SerializedData ( ) ;
req . serializeToStream ( data ) ;
SerializedData toEncrypt = new SerializedData ( ) ;
toEncrypt . writeInt32 ( data . length ( ) ) ;
toEncrypt . writeRaw ( data . toByteArray ( ) ) ;
byte [ ] innerData = toEncrypt . toByteArray ( ) ;
byte [ ] messageKeyFull = Utilities . computeSHA1 ( innerData ) ;
byte [ ] messageKey = new byte [ 16 ] ;
System . arraycopy ( messageKeyFull , messageKeyFull . length - 16 , messageKey , 0 , 16 ) ;
MessageKeyData keyData = Utilities . generateMessageKeyData ( chat . auth_key , messageKey , false ) ;
SerializedData dataForEncryption = new SerializedData ( ) ;
dataForEncryption . writeRaw ( innerData ) ;
2013-12-20 19:25:49 +00:00
byte [ ] b = new byte [ 1 ] ;
2013-10-25 15:19:00 +00:00
while ( dataForEncryption . length ( ) % 16 ! = 0 ) {
2013-12-20 19:25:49 +00:00
MessagesController . random . nextBytes ( b ) ;
dataForEncryption . writeByte ( b [ 0 ] ) ;
2013-10-25 15:19:00 +00:00
}
byte [ ] encryptedData = Utilities . aesIgeEncryption ( dataForEncryption . toByteArray ( ) , keyData . aesKey , keyData . aesIv , true , false ) ;
data = new SerializedData ( ) ;
data . writeInt64 ( chat . key_fingerprint ) ;
data . writeRaw ( messageKey ) ;
data . writeRaw ( encryptedData ) ;
TLObject reqToSend ;
if ( encryptedFile = = null ) {
TLRPC . TL_messages_sendEncrypted req2 = new TLRPC . TL_messages_sendEncrypted ( ) ;
req2 . data = data . toByteArray ( ) ;
req2 . random_id = req . random_id ;
req2 . peer = new TLRPC . TL_inputEncryptedChat ( ) ;
req2 . peer . chat_id = chat . id ;
req2 . peer . access_hash = chat . access_hash ;
reqToSend = req2 ;
} else {
TLRPC . TL_messages_sendEncryptedFile req2 = new TLRPC . TL_messages_sendEncryptedFile ( ) ;
req2 . data = data . toByteArray ( ) ;
req2 . random_id = req . random_id ;
req2 . peer = new TLRPC . TL_inputEncryptedChat ( ) ;
req2 . peer . chat_id = chat . id ;
req2 . peer . access_hash = chat . access_hash ;
req2 . file = encryptedFile ;
reqToSend = req2 ;
}
ConnectionsManager . Instance . performRpc ( reqToSend , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
TLRPC . messages_SentEncryptedMessage res = ( TLRPC . messages_SentEncryptedMessage ) response ;
2013-12-20 19:25:49 +00:00
newMsgObj . messageOwner . date = res . date ;
2013-10-25 15:19:00 +00:00
if ( res . file instanceof TLRPC . TL_encryptedFile ) {
processSendedMessage ( newMsgObj . messageOwner , null , res . file , req ) ;
}
MessagesStorage . Instance . updateMessageStateAndId ( newMsgObj . messageOwner . random_id , newMsgObj . messageOwner . id , newMsgObj . messageOwner . id , res . date , true ) ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
newMsgObj . messageOwner . send_state = MESSAGE_SEND_STATE_SENT ;
NotificationCenter . Instance . postNotificationName ( messageReceivedByServer , newMsgObj . messageOwner . id , newMsgObj . messageOwner . id ) ;
sendingMessages . remove ( newMsgObj . messageOwner . id ) ;
}
} ) ;
} else {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
sendingMessages . remove ( newMsgObj . messageOwner . id ) ;
newMsgObj . messageOwner . send_state = MESSAGE_SEND_STATE_SEND_ERROR ;
NotificationCenter . Instance . postNotificationName ( messageSendError , newMsgObj . messageOwner . id ) ;
}
} ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
private void performSendMessageRequest ( TLObject req , final MessageObject newMsgObj ) {
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
final int oldId = newMsgObj . messageOwner . id ;
ArrayList < TLRPC . Message > sendedMessages = new ArrayList < TLRPC . Message > ( ) ;
if ( response instanceof TLRPC . TL_messages_sentMessage ) {
TLRPC . TL_messages_sentMessage res = ( TLRPC . TL_messages_sentMessage ) response ;
newMsgObj . messageOwner . id = res . id ;
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastDateValue = res . date ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
2013-10-25 15:19:00 +00:00
} else {
getDifference ( ) ;
}
} else if ( response instanceof TLRPC . messages_StatedMessage ) {
TLRPC . messages_StatedMessage res = ( TLRPC . messages_StatedMessage ) response ;
sendedMessages . add ( res . message ) ;
newMsgObj . messageOwner . id = res . message . id ;
processSendedMessage ( newMsgObj . messageOwner , res . message , null , null ) ;
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . lastDateValue = res . message . date ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
2013-10-25 15:19:00 +00:00
} else {
getDifference ( ) ;
}
} else if ( response instanceof TLRPC . messages_StatedMessages ) {
TLRPC . messages_StatedMessages res = ( TLRPC . messages_StatedMessages ) response ;
if ( ! res . messages . isEmpty ( ) ) {
TLRPC . Message message = res . messages . get ( 0 ) ;
newMsgObj . messageOwner . id = message . id ;
sendedMessages . add ( message ) ;
processSendedMessage ( newMsgObj . messageOwner , message , null , null ) ;
}
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
2013-10-25 15:19:00 +00:00
} else {
getDifference ( ) ;
}
}
MessagesStorage . Instance . updateMessageStateAndId ( newMsgObj . messageOwner . random_id , oldId , newMsgObj . messageOwner . id , 0 , true ) ;
if ( ! sendedMessages . isEmpty ( ) ) {
MessagesStorage . Instance . putMessages ( sendedMessages , true , true ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
newMsgObj . messageOwner . send_state = MESSAGE_SEND_STATE_SENT ;
NotificationCenter . Instance . postNotificationName ( messageReceivedByServer , oldId , newMsgObj . messageOwner . id ) ;
sendingMessages . remove ( oldId ) ;
}
} ) ;
} else {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
sendingMessages . remove ( newMsgObj . messageOwner . id ) ;
newMsgObj . messageOwner . send_state = MESSAGE_SEND_STATE_SEND_ERROR ;
NotificationCenter . Instance . postNotificationName ( messageSendError , newMsgObj . messageOwner . id ) ;
}
} ) ;
}
}
} , null , ( req instanceof TLRPC . TL_messages_forwardMessages ? null : new RPCRequest . RPCQuickAckDelegate ( ) {
@Override
public void quickAck ( ) {
final int msg_id = newMsgObj . messageOwner . id ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
newMsgObj . messageOwner . send_state = MESSAGE_SEND_STATE_SENT ;
NotificationCenter . Instance . postNotificationName ( messageReceivedByAck , msg_id ) ;
}
} ) ;
}
} ) , true , RPCRequest . RPCRequestClassGeneric | RPCRequest . RPCRequestClassFailOnServerErrors , ConnectionsManager . DEFAULT_DATACENTER_ID ) ;
}
private void performSendDelayedMessage ( final DelayedMessage message ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
if ( message . type = = 0 ) {
String location = Utilities . getCacheDir ( ) + " / " + message . location . volume_id + " _ " + message . location . local_id + " .jpg " ;
delayedMessages . put ( location , message ) ;
if ( message . sendRequest ! = null ) {
FileLoader . Instance . uploadFile ( location , null , null ) ;
} else {
FileLoader . Instance . uploadFile ( location , message . sendEncryptedRequest . media . key , message . sendEncryptedRequest . media . iv ) ;
}
} else if ( message . type = = 1 ) {
if ( message . sendRequest ! = null ) {
if ( message . sendRequest . media . thumb = = null ) {
String location = Utilities . getCacheDir ( ) + " / " + message . location . volume_id + " _ " + message . location . local_id + " .jpg " ;
delayedMessages . put ( location , message ) ;
FileLoader . Instance . uploadFile ( location , null , null ) ;
} else {
String location = message . videoLocation . path ;
if ( location = = null ) {
location = Utilities . getCacheDir ( ) + " / " + message . videoLocation . id + " .mp4 " ;
}
delayedMessages . put ( location , message ) ;
FileLoader . Instance . uploadFile ( location , null , null ) ;
}
} else {
String location = message . videoLocation . path ;
if ( location = = null ) {
location = Utilities . getCacheDir ( ) + " / " + message . videoLocation . id + " .mp4 " ;
}
delayedMessages . put ( location , message ) ;
FileLoader . Instance . uploadFile ( location , message . sendEncryptedRequest . media . key , message . sendEncryptedRequest . media . iv ) ;
}
}
}
} ) ;
}
public void fileDidFailedUpload ( final String location ) {
if ( uploadingAvatar ! = null & & uploadingAvatar . equals ( location ) ) {
uploadingAvatar = null ;
} else {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
DelayedMessage obj = delayedMessages . get ( location ) ;
if ( obj ! = null ) {
obj . obj . messageOwner . send_state = MESSAGE_SEND_STATE_SEND_ERROR ;
sendingMessages . remove ( obj . obj . messageOwner . id ) ;
NotificationCenter . Instance . postNotificationName ( messageSendError , obj . obj . messageOwner . id ) ;
delayedMessages . remove ( location ) ;
}
}
} ) ;
}
}
public void rebuildContactsWithNewUser ( final TLRPC . User user , final long bookId ) {
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
final HashMap < Integer , Contact > contactsMapBook = new HashMap < Integer , Contact > ( contactsBook ) ;
final HashMap < String , ArrayList < Contact > > sectionsDictBook = new HashMap < String , ArrayList < Contact > > ( ) ;
final ArrayList < String > sortedSectionsArrayBook = new ArrayList < String > ( ) ;
Contact newContactBook = new Contact ( ) ;
newContactBook . first_name = user . first_name ;
newContactBook . last_name = user . last_name ;
newContactBook . id = ( int ) bookId ;
newContactBook . phones = new ArrayList < String > ( ) ;
newContactBook . phones . add ( user . phone ) ;
newContactBook . phoneTypes = new ArrayList < String > ( ) ;
2013-11-04 12:31:01 +00:00
newContactBook . phoneTypes . add ( ApplicationLoader . applicationContext . getString ( R . string . PhoneMobile ) ) ;
2013-10-25 15:19:00 +00:00
contactsMapBook . put ( ( int ) bookId , newContactBook ) ;
String contactsImportHash = " " ;
MessageDigest mdEnc = null ;
try {
mdEnc = MessageDigest . getInstance ( " MD5 " ) ;
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
for ( HashMap . Entry < Integer , Contact > pair : contactsMapBook . entrySet ( ) ) {
Contact value = pair . getValue ( ) ;
int id = pair . getKey ( ) ;
if ( mdEnc ! = null ) {
for ( int a = 0 ; a < value . phones . size ( ) ; a + + ) {
String str = id + value . first_name + value . last_name + value . phones . get ( a ) ;
mdEnc . update ( str . getBytes ( ) ) ;
}
}
String key = value . last_name ;
if ( key . length ( ) = = 0 ) {
key = value . first_name ;
}
if ( key . length ( ) = = 0 ) {
key = " # " ;
if ( value . phones . size ( ) ! = 0 ) {
value . first_name = " + " + value . phones . get ( 0 ) ;
}
} else {
key = key . toUpperCase ( ) ;
}
if ( key . length ( ) > 1 ) {
key = key . substring ( 0 , 1 ) ;
}
ArrayList < Contact > arr = sectionsDictBook . get ( key ) ;
if ( arr = = null ) {
arr = new ArrayList < Contact > ( ) ;
sectionsDictBook . put ( key , arr ) ;
sortedSectionsArrayBook . add ( key ) ;
}
arr . add ( value ) ;
}
for ( HashMap . Entry < String , ArrayList < Contact > > entry : sectionsDictBook . entrySet ( ) ) {
Collections . sort ( entry . getValue ( ) , new Comparator < Contact > ( ) {
@Override
public int compare ( Contact contact , Contact contact2 ) {
2013-12-20 19:25:49 +00:00
String toComapre1 = contact . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre1 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre1 = contact . last_name ;
2013-10-25 15:19:00 +00:00
}
2013-12-20 19:25:49 +00:00
String toComapre2 = contact2 . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre2 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre2 = contact2 . last_name ;
2013-10-25 15:19:00 +00:00
}
return toComapre1 . compareTo ( toComapre2 ) ;
}
} ) ;
}
Collections . sort ( sortedSectionsArrayBook , new Comparator < String > ( ) {
@Override
public int compare ( String s , String s2 ) {
char cv1 = s . charAt ( 0 ) ;
char cv2 = s2 . charAt ( 0 ) ;
if ( cv1 = = '#' ) {
return 1 ;
} else if ( cv2 = = '#' ) {
return - 1 ;
2013-12-20 19:25:49 +00:00
} / * else if ( cv1 > = 'A' & & cv1 < = 'Z' & & cv2 > = 'A' & & cv2 < = 'Z' ) {
2013-10-25 15:19:00 +00:00
return s . compareTo ( s2 ) ;
} else if ( cv1 > = 'A' & & cv1 < = 'Z' & & ! ( cv2 > = 'A' & & cv2 < = 'Z' ) ) {
return 1 ;
} else if ( ! ( cv1 > = 'A' & & cv1 < = 'Z' ) & & cv2 > = 'A' & & cv2 < = 'Z' ) {
return - 1 ;
2013-12-20 19:25:49 +00:00
} * /
2013-10-25 15:19:00 +00:00
return s . compareTo ( s2 ) ;
}
} ) ;
String importHash = String . format ( Locale . US , " %32s " , new BigInteger ( 1 , mdEnc . digest ( ) ) . toString ( 16 ) ) . replace ( ' ' , '0' ) ;
//end of phone book update
final ArrayList < TLRPC . TL_contact > contactsArr = new ArrayList < TLRPC . TL_contact > ( contacts ) ;
TLRPC . TL_contact newContact = new TLRPC . TL_contact ( ) ;
newContact . user_id = user . id ;
contactsArr . add ( newContact ) ;
Collections . sort ( contactsArr , new Comparator < TLRPC . TL_contact > ( ) {
@Override
public int compare ( TLRPC . TL_contact tl_contact , TLRPC . TL_contact tl_contact2 ) {
TLRPC . User user1 = users . get ( tl_contact . user_id ) ;
TLRPC . User user2 = users . get ( tl_contact2 . user_id ) ;
2013-12-20 19:25:49 +00:00
String name1 = user1 . first_name ;
2013-10-25 15:19:00 +00:00
if ( name1 = = null | | name1 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
name1 = user1 . last_name ;
2013-10-25 15:19:00 +00:00
}
2013-12-20 19:25:49 +00:00
String name2 = user2 . first_name ;
2013-10-25 15:19:00 +00:00
if ( name2 = = null | | name2 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
name2 = user2 . last_name ;
2013-10-25 15:19:00 +00:00
}
return name1 . compareTo ( name2 ) ;
}
} ) ;
final HashMap < String , ArrayList < TLRPC . TL_contact > > sectionsDict = new HashMap < String , ArrayList < TLRPC . TL_contact > > ( ) ;
final SparseArray < TLRPC . TL_contact > contactsDictionery = new SparseArray < TLRPC . TL_contact > ( ) ;
final ArrayList < String > sortedSectionsArray = new ArrayList < String > ( ) ;
final HashMap < String , TLRPC . TL_contact > contactsPhones = new HashMap < String , TLRPC . TL_contact > ( ) ;
for ( TLRPC . TL_contact value : contactsArr ) {
TLRPC . User user = users . get ( value . user_id ) ;
contactsDictionery . put ( value . user_id , value ) ;
contactsPhones . put ( user . phone , value ) ;
String key = user . last_name ;
if ( key = = null | | key . length ( ) = = 0 ) {
key = user . first_name ;
}
if ( key . length ( ) = = 0 ) {
key = " # " ;
} else {
key = key . toUpperCase ( ) ;
}
if ( key . length ( ) > 1 ) {
key = key . substring ( 0 , 1 ) ;
}
ArrayList < TLRPC . TL_contact > arr = sectionsDict . get ( key ) ;
if ( arr = = null ) {
arr = new ArrayList < TLRPC . TL_contact > ( ) ;
sectionsDict . put ( key , arr ) ;
sortedSectionsArray . add ( key ) ;
}
arr . add ( value ) ;
}
for ( HashMap . Entry < String , ArrayList < TLRPC . TL_contact > > entry : sectionsDict . entrySet ( ) ) {
Collections . sort ( entry . getValue ( ) , new Comparator < TLRPC . TL_contact > ( ) {
@Override
public int compare ( TLRPC . TL_contact contact , TLRPC . TL_contact contact2 ) {
TLRPC . User user1 = users . get ( contact . user_id ) ;
TLRPC . User user2 = users . get ( contact2 . user_id ) ;
2013-12-20 19:25:49 +00:00
String toComapre1 = user1 . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre1 = = null | | toComapre1 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre1 = user1 . last_name ;
2013-10-25 15:19:00 +00:00
}
2013-12-20 19:25:49 +00:00
String toComapre2 = user2 . first_name ;
2013-10-25 15:19:00 +00:00
if ( toComapre2 = = null | | toComapre2 . length ( ) = = 0 ) {
2013-12-20 19:25:49 +00:00
toComapre2 = user2 . last_name ;
2013-10-25 15:19:00 +00:00
}
return toComapre1 . compareTo ( toComapre2 ) ;
}
} ) ;
}
Collections . sort ( sortedSectionsArray , new Comparator < String > ( ) {
@Override
public int compare ( String s , String s2 ) {
char cv1 = s . charAt ( 0 ) ;
char cv2 = s2 . charAt ( 0 ) ;
if ( cv1 = = '#' ) {
return 1 ;
} else if ( cv2 = = '#' ) {
return - 1 ;
}
2013-12-20 19:25:49 +00:00
// } else if (cv1 >= 'A' && cv1 <= 'Z' && cv2 >= 'A' && cv2 <= 'Z') {
// return s.compareTo(s2);
// } else if (cv1 >= 'A' && cv1 <= 'Z' && !(cv2 >= 'A' && cv2 <= 'Z')) {
// return 1;
// } else if (!(cv1 >= 'A' && cv1 <= 'Z') && cv2 >= 'A' && cv2 <= 'Z') {
// return -1;
// }
2013-10-25 15:19:00 +00:00
return s . compareTo ( s2 ) ;
}
} ) ;
final ArrayList < TLRPC . TL_contact > contactsArrSortedByIds = new ArrayList < TLRPC . TL_contact > ( contactsArr ) ;
Collections . sort ( contactsArrSortedByIds , new Comparator < TLRPC . TL_contact > ( ) {
@Override
public int compare ( TLRPC . TL_contact lhs , TLRPC . TL_contact rhs ) {
Integer lid = lhs . user_id ;
Integer rid = rhs . user_id ;
return lid . compareTo ( rid ) ;
}
} ) ;
String ids = " " ;
for ( TLRPC . TL_contact aContactsArr : contactsArrSortedByIds ) {
if ( ids . length ( ) ! = 0 ) {
ids + = " , " ;
}
ids + = aContactsArr . user_id ;
}
UserConfig . contactsHash = Utilities . MD5 ( ids ) ;
UserConfig . importHash = importHash ;
2013-11-04 12:31:01 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
MessagesStorage . Instance . putContacts ( contactsArr , true ) ;
ArrayList < TLRPC . User > users = new ArrayList < TLRPC . User > ( ) ;
users . add ( user ) ;
MessagesStorage . Instance . putUsersAndChats ( users , null , true , true ) ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
contactsBook = contactsMapBook ;
contactsSectionsDict = sectionsDictBook ;
sortedContactsSectionsArray = sortedSectionsArrayBook ;
NotificationCenter . Instance . postNotificationName ( contactsBookDidLoaded ) ;
contacts = contactsArr ;
contactsByPhones = contactsPhones ;
contactsDict = contactsDictionery ;
usersSectionsDict = sectionsDict ;
sortedUsersSectionsArray = sortedSectionsArray ;
NotificationCenter . Instance . postNotificationName ( contactsDidLoaded ) ;
NotificationCenter . Instance . postNotificationName ( updateInterfaces , UPDATE_MASK_ALL ) ;
}
} ) ;
}
} ) ;
}
public void addContact ( TLRPC . User user ) {
if ( user = = null ) {
return ;
}
long num = addContact ( currentAccount , user , user . phone ) ;
rebuildContactsWithNewUser ( user , num ) ;
TLRPC . TL_contacts_importContacts req = new TLRPC . TL_contacts_importContacts ( ) ;
ArrayList < TLRPC . TL_inputPhoneContact > contacts = new ArrayList < TLRPC . TL_inputPhoneContact > ( ) ;
TLRPC . TL_inputPhoneContact c = new TLRPC . TL_inputPhoneContact ( ) ;
c . phone = user . phone ;
c . first_name = user . first_name ;
c . last_name = user . last_name ;
c . client_id = num ;
contacts . add ( c ) ;
req . contacts = contacts ;
req . replace = false ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric | RPCRequest . RPCRequestClassFailOnServerErrors ) ;
}
2013-12-20 19:25:49 +00:00
public void fileDidUploaded ( final String location , final TLRPC . InputFile file , final TLRPC . InputEncryptedFile encryptedFile ) {
2013-10-25 15:19:00 +00:00
if ( uploadingAvatar ! = null & & uploadingAvatar . equals ( location ) ) {
TLRPC . TL_photos_uploadProfilePhoto req = new TLRPC . TL_photos_uploadProfilePhoto ( ) ;
req . caption = " " ;
req . crop = new TLRPC . TL_inputPhotoCropAuto ( ) ;
req . file = file ;
req . geo_point = new TLRPC . TL_inputGeoPointEmpty ( ) ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
} else {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
DelayedMessage message = delayedMessages . get ( location ) ;
if ( message ! = null ) {
if ( file ! = null ) {
if ( message . type = = 0 ) {
message . sendRequest . media . file = file ;
performSendMessageRequest ( message . sendRequest , message . obj ) ;
} else if ( message . type = = 1 ) {
if ( message . sendRequest . media . thumb = = null ) {
message . sendRequest . media . thumb = file ;
performSendDelayedMessage ( message ) ;
} else {
message . sendRequest . media . file = file ;
performSendMessageRequest ( message . sendRequest , message . obj ) ;
}
}
} else if ( encryptedFile ! = null ) {
if ( message . type = = 0 ) {
performSendEncryptedRequest ( message . sendEncryptedRequest , message . obj , message . encryptedChat , encryptedFile ) ;
} else if ( message . type = = 1 ) {
performSendEncryptedRequest ( message . sendEncryptedRequest , message . obj , message . encryptedChat , encryptedFile ) ;
}
}
delayedMessages . remove ( location ) ;
}
}
} ) ;
}
}
2013-12-20 19:25:49 +00:00
public void createChat ( String title , ArrayList < Integer > selectedContacts , final TLRPC . InputFile uploadedAvatar ) {
2013-10-25 15:19:00 +00:00
TLRPC . TL_messages_createChat req = new TLRPC . TL_messages_createChat ( ) ;
req . title = title ;
for ( Integer uid : selectedContacts ) {
2013-11-04 12:31:01 +00:00
TLRPC . User user = users . get ( uid ) ;
2013-10-25 15:19:00 +00:00
TLRPC . InputUser inputUser ;
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
inputUser = new TLRPC . TL_inputUserForeign ( ) ;
inputUser . user_id = user . id ;
inputUser . access_hash = user . access_hash ;
} else {
inputUser = new TLRPC . TL_inputUserContact ( ) ;
inputUser . user_id = user . id ;
}
req . users . add ( inputUser ) ;
}
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error ! = null ) {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
NotificationCenter . Instance . postNotificationName ( chatDidFailCreate ) ;
}
} ) ;
return ;
}
final TLRPC . messages_StatedMessage res = ( TLRPC . messages_StatedMessage ) response ;
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , true , true ) ;
final ArrayList < TLRPC . Message > messages = new ArrayList < TLRPC . Message > ( ) ;
messages . add ( res . message ) ;
MessagesStorage . Instance . putMessages ( messages , true , true ) ;
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
} else if ( MessagesStorage . lastSeqValue ! = res . seq ) {
2013-10-25 15:19:00 +00:00
getDifference ( ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : res . users ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
for ( TLRPC . Chat chat : res . chats ) {
chats . put ( chat . id , chat ) ;
}
final ArrayList < MessageObject > messagesObj = new ArrayList < MessageObject > ( ) ;
messagesObj . add ( new MessageObject ( res . message , users ) ) ;
TLRPC . Chat chat = res . chats . get ( 0 ) ;
updateInterfaceWithMessages ( - chat . id , messagesObj ) ;
NotificationCenter . Instance . postNotificationName ( chatDidCreated , chat . id ) ;
if ( uploadedAvatar ! = null ) {
changeChatAvatar ( chat . id , uploadedAvatar ) ;
}
}
} ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void addUserToChat ( int chat_id , final int user_id , final TLRPC . ChatParticipants info ) {
TLRPC . TL_messages_addChatUser req = new TLRPC . TL_messages_addChatUser ( ) ;
req . chat_id = chat_id ;
req . fwd_limit = 50 ;
2013-11-04 12:31:01 +00:00
TLRPC . User user = users . get ( user_id ) ;
2013-10-25 15:19:00 +00:00
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . user_id = new TLRPC . TL_inputUserForeign ( ) ;
req . user_id . user_id = user . id ;
req . user_id . access_hash = user . access_hash ;
} else {
req . user_id = new TLRPC . TL_inputUserContact ( ) ;
req . user_id . user_id = user . id ;
}
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error ! = null ) {
return ;
}
final TLRPC . messages_StatedMessage res = ( TLRPC . messages_StatedMessage ) response ;
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , true , true ) ;
final ArrayList < TLRPC . Message > messages = new ArrayList < TLRPC . Message > ( ) ;
messages . add ( res . message ) ;
MessagesStorage . Instance . putMessages ( messages , true , true ) ;
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
} else if ( MessagesStorage . lastSeqValue ! = res . seq ) {
2013-10-25 15:19:00 +00:00
getDifference ( ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : res . users ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
for ( TLRPC . Chat chat : res . chats ) {
chats . put ( chat . id , chat ) ;
}
final ArrayList < MessageObject > messagesObj = new ArrayList < MessageObject > ( ) ;
messagesObj . add ( new MessageObject ( res . message , users ) ) ;
TLRPC . Chat chat = res . chats . get ( 0 ) ;
chats . put ( chat . id , chat ) ;
updateInterfaceWithMessages ( - chat . id , messagesObj ) ;
NotificationCenter . Instance . postNotificationName ( updateInterfaces , UPDATE_MASK_ALL ) ;
if ( info ! = null ) {
for ( TLRPC . TL_chatParticipant p : info . participants ) {
if ( p . user_id = = user_id ) {
return ;
}
}
TLRPC . TL_chatParticipant newPart = new TLRPC . TL_chatParticipant ( ) ;
newPart . user_id = user_id ;
newPart . inviter_id = UserConfig . clientUserId ;
newPart . date = ConnectionsManager . Instance . getCurrentTime ( ) ;
info . participants . add ( 0 , newPart ) ;
MessagesStorage . Instance . updateChatInfo ( info . chat_id , info , true ) ;
NotificationCenter . Instance . postNotificationName ( chatInfoDidLoaded , info . chat_id , info ) ;
}
}
} ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void deleteUserFromChat ( int chat_id , final int user_id , final TLRPC . ChatParticipants info ) {
TLRPC . TL_messages_deleteChatUser req = new TLRPC . TL_messages_deleteChatUser ( ) ;
req . chat_id = chat_id ;
2013-11-04 12:31:01 +00:00
TLRPC . User user = users . get ( user_id ) ;
2013-10-25 15:19:00 +00:00
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
req . user_id = new TLRPC . TL_inputUserForeign ( ) ;
req . user_id . user_id = user . id ;
req . user_id . access_hash = user . access_hash ;
} else if ( user instanceof TLRPC . TL_userSelf ) {
req . user_id = new TLRPC . TL_inputUserSelf ( ) ;
} else {
req . user_id = new TLRPC . TL_inputUserContact ( ) ;
req . user_id . user_id = user . id ;
}
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error ! = null ) {
return ;
}
final TLRPC . messages_StatedMessage res = ( TLRPC . messages_StatedMessage ) response ;
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , true , true ) ;
if ( user_id ! = UserConfig . clientUserId ) {
final ArrayList < TLRPC . Message > messages = new ArrayList < TLRPC . Message > ( ) ;
messages . add ( res . message ) ;
MessagesStorage . Instance . putMessages ( messages , true , true ) ;
}
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
} else if ( MessagesStorage . lastSeqValue ! = res . seq ) {
2013-10-25 15:19:00 +00:00
getDifference ( ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : res . users ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
for ( TLRPC . Chat chat : res . chats ) {
chats . put ( chat . id , chat ) ;
}
if ( user_id ! = UserConfig . clientUserId ) {
final ArrayList < MessageObject > messagesObj = new ArrayList < MessageObject > ( ) ;
messagesObj . add ( new MessageObject ( res . message , users ) ) ;
TLRPC . Chat chat = res . chats . get ( 0 ) ;
chats . put ( chat . id , chat ) ;
updateInterfaceWithMessages ( - chat . id , messagesObj ) ;
NotificationCenter . Instance . postNotificationName ( updateInterfaces , UPDATE_MASK_ALL ) ;
}
boolean changed = false ;
if ( info ! = null ) {
for ( int a = 0 ; a < info . participants . size ( ) ; a + + ) {
TLRPC . TL_chatParticipant p = info . participants . get ( a ) ;
if ( p . user_id = = user_id ) {
info . participants . remove ( a ) ;
changed = true ;
break ;
}
}
if ( changed ) {
MessagesStorage . Instance . updateChatInfo ( info . chat_id , info , true ) ;
NotificationCenter . Instance . postNotificationName ( chatInfoDidLoaded , info . chat_id , info ) ;
}
}
}
} ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void changeChatTitle ( int chat_id , String title ) {
TLRPC . TL_messages_editChatTitle req = new TLRPC . TL_messages_editChatTitle ( ) ;
req . chat_id = chat_id ;
req . title = title ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error ! = null ) {
return ;
}
final TLRPC . messages_StatedMessage res = ( TLRPC . messages_StatedMessage ) response ;
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , true , true ) ;
final ArrayList < TLRPC . Message > messages = new ArrayList < TLRPC . Message > ( ) ;
messages . add ( res . message ) ;
MessagesStorage . Instance . putMessages ( messages , true , true ) ;
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
} else if ( MessagesStorage . lastSeqValue ! = res . seq ) {
2013-10-25 15:19:00 +00:00
getDifference ( ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : res . users ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
for ( TLRPC . Chat chat : res . chats ) {
chats . put ( chat . id , chat ) ;
}
final ArrayList < MessageObject > messagesObj = new ArrayList < MessageObject > ( ) ;
messagesObj . add ( new MessageObject ( res . message , users ) ) ;
TLRPC . Chat chat = res . chats . get ( 0 ) ;
chats . put ( chat . id , chat ) ;
updateInterfaceWithMessages ( - chat . id , messagesObj ) ;
NotificationCenter . Instance . postNotificationName ( updateInterfaces , UPDATE_MASK_ALL ) ;
}
} ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
2013-12-20 19:25:49 +00:00
public void changeChatAvatar ( int chat_id , TLRPC . InputFile uploadedAvatar ) {
2013-10-25 15:19:00 +00:00
TLRPC . TL_messages_editChatPhoto req2 = new TLRPC . TL_messages_editChatPhoto ( ) ;
req2 . chat_id = chat_id ;
if ( uploadedAvatar ! = null ) {
req2 . photo = new TLRPC . TL_inputChatUploadedPhoto ( ) ;
req2 . photo . file = uploadedAvatar ;
req2 . photo . crop = new TLRPC . TL_inputPhotoCropAuto ( ) ;
} else {
req2 . photo = new TLRPC . TL_inputChatPhotoEmpty ( ) ;
}
ConnectionsManager . Instance . performRpc ( req2 , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error ! = null ) {
return ;
}
final TLRPC . messages_StatedMessage res = ( TLRPC . messages_StatedMessage ) response ;
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , true , true ) ;
final ArrayList < TLRPC . Message > messages = new ArrayList < TLRPC . Message > ( ) ;
messages . add ( res . message ) ;
MessagesStorage . Instance . putMessages ( messages , true , true ) ;
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = res . seq ) {
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
} else if ( MessagesStorage . lastSeqValue ! = res . seq ) {
2013-10-25 15:19:00 +00:00
getDifference ( ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : res . users ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
for ( TLRPC . Chat chat : res . chats ) {
chats . put ( chat . id , chat ) ;
}
final ArrayList < MessageObject > messagesObj = new ArrayList < MessageObject > ( ) ;
messagesObj . add ( new MessageObject ( res . message , users ) ) ;
TLRPC . Chat chat = res . chats . get ( 0 ) ;
chats . put ( chat . id , chat ) ;
updateInterfaceWithMessages ( - chat . id , messagesObj ) ;
NotificationCenter . Instance . postNotificationName ( updateInterfaces , UPDATE_MASK_ALL ) ;
}
} ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void unregistedPush ( ) {
if ( ! UserConfig . registeredForPush | | UserConfig . pushString . length ( ) = = 0 ) {
return ;
}
TLRPC . TL_account_unregisterDevice req = new TLRPC . TL_account_unregisterDevice ( ) ;
req . token = UserConfig . pushString ;
req . token_type = 2 ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
TLRPC . TL_auth_logOut req2 = new TLRPC . TL_auth_logOut ( ) ;
ConnectionsManager . Instance . performRpc ( req2 , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void registerForPush ( final String regid ) {
if ( regid = = null | | regid . length ( ) = = 0 | | registeringForPush | | UserConfig . clientUserId = = 0 ) {
return ;
}
if ( UserConfig . registeredForPush & & regid . equals ( UserConfig . pushString ) ) {
return ;
}
registeringForPush = true ;
TLRPC . TL_account_registerDevice req = new TLRPC . TL_account_registerDevice ( ) ;
2013-12-20 19:25:49 +00:00
req . token_type = 2 ;
req . token = regid ;
req . app_sandbox = false ;
2013-10-25 15:19:00 +00:00
try {
req . lang_code = Locale . getDefault ( ) . getCountry ( ) ;
req . device_model = Build . MANUFACTURER + Build . MODEL ;
if ( req . device_model = = null ) {
req . device_model = " Android unknown " ;
}
req . system_version = " SDK " + Build . VERSION . SDK_INT ;
2013-11-04 12:31:01 +00:00
PackageInfo pInfo = ApplicationLoader . applicationContext . getPackageManager ( ) . getPackageInfo ( ApplicationLoader . applicationContext . getPackageName ( ) , 0 ) ;
2013-10-25 15:19:00 +00:00
req . app_version = pInfo . versionName ;
if ( req . app_version = = null ) {
req . app_version = " App version unknown " ;
}
2013-12-20 19:25:49 +00:00
2013-10-25 15:19:00 +00:00
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
req . lang_code = " en " ;
req . device_model = " Android unknown " ;
req . system_version = " SDK " + Build . VERSION . SDK_INT ;
req . app_version = " App version unknown " ;
2013-10-25 15:19:00 +00:00
}
if ( req . app_version ! = null ) {
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " registered for push " ) ;
2013-10-25 15:19:00 +00:00
UserConfig . registeredForPush = true ;
UserConfig . pushString = regid ;
2013-11-04 12:31:01 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
registeringForPush = false ;
}
} ) ;
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
}
public void loadCurrentState ( ) {
if ( updatingState ) {
return ;
}
updatingState = true ;
TLRPC . TL_updates_getState req = new TLRPC . TL_updates_getState ( ) ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
updatingState = false ;
if ( error = = null ) {
TLRPC . TL_updates_state res = ( TLRPC . TL_updates_state ) response ;
2013-11-04 12:31:01 +00:00
MessagesStorage . lastDateValue = res . date ;
MessagesStorage . lastPtsValue = res . pts ;
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastQtsValue = res . qts ;
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
2013-10-25 15:19:00 +00:00
} else {
loadCurrentState ( ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void getDifference ( ) {
registerForPush ( UserConfig . pushString ) ;
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastDateValue = = 0 ) {
2013-10-25 15:19:00 +00:00
loadCurrentState ( ) ;
return ;
}
if ( gettingDifference ) {
return ;
}
if ( ! firstGettingTask ) {
getNewDeleteTask ( null ) ;
firstGettingTask = true ;
}
gettingDifference = true ;
TLRPC . TL_updates_getDifference req = new TLRPC . TL_updates_getDifference ( ) ;
2013-11-04 12:31:01 +00:00
req . pts = MessagesStorage . lastPtsValue ;
req . date = MessagesStorage . lastDateValue ;
req . qts = MessagesStorage . lastQtsValue ;
2013-10-25 15:19:00 +00:00
if ( ConnectionsManager . Instance . connectionState = = 0 ) {
ConnectionsManager . Instance . connectionState = 3 ;
final int stateCopy = ConnectionsManager . Instance . connectionState ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
NotificationCenter . Instance . postNotificationName ( 703 , stateCopy ) ;
}
} ) ;
}
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
gettingDifference = false ;
2013-12-20 19:25:49 +00:00
gettingDifferenceAgain = false ;
2013-10-25 15:19:00 +00:00
if ( error = = null ) {
final TLRPC . updates_Difference res = ( TLRPC . updates_Difference ) response ;
2013-12-20 19:25:49 +00:00
gettingDifferenceAgain = res instanceof TLRPC . TL_updates_differenceSlice ;
2013-10-25 15:19:00 +00:00
final HashMap < Integer , TLRPC . User > usersDict = new HashMap < Integer , TLRPC . User > ( ) ;
for ( TLRPC . User user : res . users ) {
usersDict . put ( user . id , user ) ;
}
final ArrayList < TLRPC . TL_updateMessageID > msgUpdates = new ArrayList < TLRPC . TL_updateMessageID > ( ) ;
if ( ! res . other_updates . isEmpty ( ) ) {
for ( int a = 0 ; a < res . other_updates . size ( ) ; a + + ) {
TLRPC . Update upd = res . other_updates . get ( a ) ;
if ( upd instanceof TLRPC . TL_updateMessageID ) {
msgUpdates . add ( ( TLRPC . TL_updateMessageID ) upd ) ;
res . other_updates . remove ( a ) ;
a - - ;
}
}
}
MessagesStorage . Instance . storageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
if ( ! msgUpdates . isEmpty ( ) ) {
final HashMap < Integer , Integer > corrected = new HashMap < Integer , Integer > ( ) ;
for ( TLRPC . TL_updateMessageID update : msgUpdates ) {
Integer oldId = MessagesStorage . Instance . updateMessageStateAndId ( update . random_id , null , update . id , 0 , false ) ;
if ( oldId ! = null ) {
corrected . put ( oldId , update . id ) ;
}
}
if ( ! corrected . isEmpty ( ) ) {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( HashMap . Entry < Integer , Integer > entry : corrected . entrySet ( ) ) {
Integer oldId = entry . getKey ( ) ;
sendingMessages . remove ( oldId ) ;
Integer newId = entry . getValue ( ) ;
NotificationCenter . Instance . postNotificationName ( messageReceivedByServer , oldId , newId ) ;
}
}
} ) ;
}
}
Utilities . stageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
if ( ! res . new_messages . isEmpty ( ) | | ! res . new_encrypted_messages . isEmpty ( ) ) {
final HashMap < Long , ArrayList < MessageObject > > messages = new HashMap < Long , ArrayList < MessageObject > > ( ) ;
for ( TLRPC . EncryptedMessage encryptedMessage : res . new_encrypted_messages ) {
TLRPC . Message message = decryptMessage ( encryptedMessage ) ;
if ( message ! = null ) {
res . new_messages . add ( message ) ;
}
}
2013-12-20 19:25:49 +00:00
MessageObject lastMessage = null ;
2013-10-25 15:19:00 +00:00
for ( TLRPC . Message message : res . new_messages ) {
MessageObject obj = new MessageObject ( message , usersDict ) ;
2013-12-20 19:25:49 +00:00
long dialog_id = obj . messageOwner . dialog_id ;
if ( dialog_id = = 0 ) {
if ( obj . messageOwner . to_id . chat_id ! = 0 ) {
dialog_id = - obj . messageOwner . to_id . chat_id ;
} else {
dialog_id = obj . messageOwner . to_id . user_id ;
}
}
if ( ( dialog_id ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) & & ! obj . messageOwner . out & & ( lastMessage = = null | | lastMessage . messageOwner . date < obj . messageOwner . date ) ) {
lastMessage = obj ;
}
2013-10-25 15:19:00 +00:00
long uid ;
if ( message . dialog_id ! = 0 ) {
uid = message . dialog_id ;
} else {
if ( message . to_id . chat_id ! = 0 ) {
uid = - message . to_id . chat_id ;
} else {
if ( message . to_id . user_id = = UserConfig . clientUserId ) {
message . to_id . user_id = message . from_id ;
}
uid = message . to_id . user_id ;
}
}
ArrayList < MessageObject > arr = messages . get ( uid ) ;
if ( arr = = null ) {
arr = new ArrayList < MessageObject > ( ) ;
messages . put ( uid , arr ) ;
}
arr . add ( obj ) ;
}
MessagesStorage . Instance . storageQueue . postRunnable ( new Runnable ( ) {
@Override
public void run ( ) {
MessagesStorage . Instance . startTransaction ( false ) ;
MessagesStorage . Instance . putMessages ( res . new_messages , false , false ) ;
MessagesStorage . Instance . putUsersAndChats ( res . users , res . chats , false , false ) ;
MessagesStorage . Instance . commitTransaction ( false ) ;
}
} ) ;
2013-12-20 19:25:49 +00:00
final MessageObject object = lastMessage ;
2013-10-25 15:19:00 +00:00
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
for ( TLRPC . User user : res . users ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
for ( TLRPC . Chat chat : res . chats ) {
chats . put ( chat . id , chat ) ;
}
for ( HashMap . Entry < Long , ArrayList < MessageObject > > pair : messages . entrySet ( ) ) {
Long key = pair . getKey ( ) ;
ArrayList < MessageObject > value = pair . getValue ( ) ;
updateInterfaceWithMessages ( key , value ) ;
}
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
2013-12-20 19:25:49 +00:00
if ( object ! = null ) {
showInAppNotification ( object ) ;
}
2013-10-25 15:19:00 +00:00
}
} ) ;
}
if ( res ! = null & & ! res . other_updates . isEmpty ( ) ) {
2013-12-20 19:25:49 +00:00
processUpdateArray ( res . other_updates , res . users , res . chats ) ;
2013-10-25 15:19:00 +00:00
}
if ( res instanceof TLRPC . TL_updates_difference ) {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastSeqValue = res . state . seq ;
MessagesStorage . lastDateValue = res . state . date ;
MessagesStorage . lastPtsValue = res . state . pts ;
MessagesStorage . lastQtsValue = res . state . qts ;
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . connectionState = 0 ;
final int stateCopy = ConnectionsManager . Instance . connectionState ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
NotificationCenter . Instance . postNotificationName ( 703 , stateCopy ) ;
}
} ) ;
} else if ( res instanceof TLRPC . TL_updates_differenceSlice ) {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastSeqValue = res . intermediate_state . seq ;
MessagesStorage . lastDateValue = res . intermediate_state . date ;
MessagesStorage . lastPtsValue = res . intermediate_state . pts ;
MessagesStorage . lastQtsValue = res . intermediate_state . qts ;
2013-12-20 19:25:49 +00:00
gettingDifferenceAgain = true ;
2013-10-25 15:19:00 +00:00
getDifference ( ) ;
} else if ( res instanceof TLRPC . TL_updates_differenceEmpty ) {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastSeqValue = res . seq ;
MessagesStorage . lastDateValue = res . date ;
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . connectionState = 0 ;
final int stateCopy = ConnectionsManager . Instance . connectionState ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
NotificationCenter . Instance . postNotificationName ( 703 , stateCopy ) ;
}
} ) ;
}
2013-11-04 12:31:01 +00:00
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
2013-10-25 15:19:00 +00:00
}
} ) ;
}
} ) ;
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " received defference with date = " + MessagesStorage . lastDateValue + " pts = " + MessagesStorage . lastPtsValue + " seq = " + MessagesStorage . lastSeqValue ) ;
FileLog . e ( " tmessages " , " messages = " + res . new_messages . size ( ) + " users = " + res . users . size ( ) + " chats = " + res . chats . size ( ) + " other updates = " + res . other_updates . size ( ) ) ;
2013-10-25 15:19:00 +00:00
} else {
loadCurrentState ( ) ;
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " get difference error, don't know what to do :( " ) ;
2013-10-25 15:19:00 +00:00
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void processUpdates ( final TLRPC . Updates updates ) {
boolean needGetDiff = false ;
boolean needReceivedQueue = false ;
if ( updates instanceof TLRPC . TL_updateShort ) {
ArrayList < TLRPC . Update > arr = new ArrayList < TLRPC . Update > ( ) ;
arr . add ( updates . update ) ;
2013-12-20 19:25:49 +00:00
//MessagesStorage.lastDateValue = updates.date;
2013-10-25 15:19:00 +00:00
processUpdateArray ( arr , null , null ) ;
} else if ( updates instanceof TLRPC . TL_updateShortChatMessage ) {
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = updates . seq & & chats . get ( updates . chat_id ) ! = null & & users . get ( updates . from_id ) ! = null ) {
2013-10-25 15:19:00 +00:00
TLRPC . TL_message message = new TLRPC . TL_message ( ) ;
message . from_id = updates . from_id ;
message . id = updates . id ;
message . to_id = new TLRPC . TL_peerChat ( ) ;
message . to_id . chat_id = updates . chat_id ;
message . message = updates . message ;
message . date = updates . date ;
message . unread = true ;
message . media = new TLRPC . TL_messageMediaEmpty ( ) ;
2013-11-04 12:31:01 +00:00
MessagesStorage . lastSeqValue = updates . seq ;
MessagesStorage . lastPtsValue = updates . pts ;
2013-10-25 15:19:00 +00:00
final MessageObject obj = new MessageObject ( message , null ) ;
final ArrayList < MessageObject > objArr = new ArrayList < MessageObject > ( ) ;
objArr . add ( obj ) ;
ArrayList < TLRPC . Message > arr = new ArrayList < TLRPC . Message > ( ) ;
arr . add ( message ) ;
MessagesStorage . Instance . putMessages ( arr , false , true ) ;
final boolean printUpdate = updatePrintingUsersWithNewMessages ( - updates . chat_id , objArr ) ;
if ( printUpdate ) {
updatePrintingStrings ( ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
if ( printUpdate ) {
NotificationCenter . Instance . postNotificationName ( userPrintUpdate , ( long ) ( - updates . chat_id ) ) ;
NotificationCenter . Instance . postNotificationName ( userPrintUpdateAll ) ;
}
if ( obj . messageOwner . from_id ! = UserConfig . clientUserId ) {
long dialog_id ;
if ( obj . messageOwner . to_id . chat_id ! = 0 ) {
dialog_id = - obj . messageOwner . to_id . chat_id ;
} else {
dialog_id = obj . messageOwner . to_id . user_id ;
}
2013-12-20 19:25:49 +00:00
if ( dialog_id ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) {
2013-10-25 15:19:00 +00:00
showInAppNotification ( obj ) ;
}
}
updateInterfaceWithMessages ( - updates . chat_id , objArr ) ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
} ) ;
} else {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " need get diff TL_updateShortChatMessage, seq: " + MessagesStorage . lastSeqValue + " " + updates . seq ) ;
2013-10-25 15:19:00 +00:00
needGetDiff = true ;
}
} else if ( updates instanceof TLRPC . TL_updateShortMessage ) {
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = updates . seq & & users . get ( updates . from_id ) ! = null ) {
2013-10-25 15:19:00 +00:00
TLRPC . TL_message message = new TLRPC . TL_message ( ) ;
message . from_id = updates . from_id ;
message . id = updates . id ;
message . to_id = new TLRPC . TL_peerUser ( ) ;
message . to_id . user_id = updates . from_id ;
message . message = updates . message ;
message . date = updates . date ;
message . unread = true ;
message . media = new TLRPC . TL_messageMediaEmpty ( ) ;
2013-11-04 12:31:01 +00:00
MessagesStorage . lastSeqValue = updates . seq ;
MessagesStorage . lastPtsValue = updates . pts ;
MessagesStorage . lastDateValue = updates . date ;
2013-10-25 15:19:00 +00:00
final MessageObject obj = new MessageObject ( message , null ) ;
final ArrayList < MessageObject > objArr = new ArrayList < MessageObject > ( ) ;
objArr . add ( obj ) ;
ArrayList < TLRPC . Message > arr = new ArrayList < TLRPC . Message > ( ) ;
arr . add ( message ) ;
MessagesStorage . Instance . putMessages ( arr , false , true ) ;
final boolean printUpdate = updatePrintingUsersWithNewMessages ( updates . from_id , objArr ) ;
if ( printUpdate ) {
updatePrintingStrings ( ) ;
}
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
if ( printUpdate ) {
NotificationCenter . Instance . postNotificationName ( userPrintUpdate , ( long ) ( updates . from_id ) ) ;
NotificationCenter . Instance . postNotificationName ( userPrintUpdateAll ) ;
}
if ( obj . messageOwner . from_id ! = UserConfig . clientUserId ) {
long dialog_id ;
if ( obj . messageOwner . to_id . chat_id ! = 0 ) {
dialog_id = - obj . messageOwner . to_id . chat_id ;
} else {
dialog_id = obj . messageOwner . to_id . user_id ;
}
2013-12-20 19:25:49 +00:00
if ( dialog_id ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) {
2013-10-25 15:19:00 +00:00
showInAppNotification ( obj ) ;
}
}
updateInterfaceWithMessages ( updates . from_id , objArr ) ;
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
} ) ;
} else {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " need get diff TL_updateShortMessage, seq: " + MessagesStorage . lastSeqValue + " " + updates . seq ) ;
2013-10-25 15:19:00 +00:00
needGetDiff = true ;
}
} else if ( updates instanceof TLRPC . TL_updatesCombined ) {
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = updates . seq_start | | updates . seq_start = = 0 | | MessagesStorage . lastSeqValue = = updates . seq_start ) {
2013-10-25 15:19:00 +00:00
MessagesStorage . Instance . putUsersAndChats ( updates . users , updates . chats , true , true ) ;
2013-11-04 12:31:01 +00:00
int lastPtsValue = MessagesStorage . lastPtsValue ;
int lastQtsValue = MessagesStorage . lastQtsValue ;
2013-10-25 15:19:00 +00:00
if ( ! processUpdateArray ( updates . updates , updates . users , updates . chats ) ) {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastPtsValue = lastPtsValue ;
MessagesStorage . lastQtsValue = lastQtsValue ;
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " need get diff inner TL_updatesCombined, seq: " + MessagesStorage . lastSeqValue + " " + updates . seq ) ;
2013-10-25 15:19:00 +00:00
needGetDiff = true ;
} else {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastDateValue = updates . date ;
MessagesStorage . lastSeqValue = updates . seq ;
if ( MessagesStorage . lastQtsValue ! = lastQtsValue ) {
2013-10-25 15:19:00 +00:00
needReceivedQueue = true ;
}
}
} else {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " need get diff TL_updatesCombined, seq: " + MessagesStorage . lastSeqValue + " " + updates . seq_start ) ;
2013-10-25 15:19:00 +00:00
needGetDiff = true ;
}
} else if ( updates instanceof TLRPC . TL_updates ) {
2013-11-04 12:31:01 +00:00
if ( MessagesStorage . lastSeqValue + 1 = = updates . seq | | updates . seq = = 0 | | updates . seq = = MessagesStorage . lastSeqValue ) {
2013-10-25 15:19:00 +00:00
MessagesStorage . Instance . putUsersAndChats ( updates . users , updates . chats , true , true ) ;
2013-11-04 12:31:01 +00:00
int lastPtsValue = MessagesStorage . lastPtsValue ;
int lastQtsValue = MessagesStorage . lastQtsValue ;
2013-10-25 15:19:00 +00:00
if ( ! processUpdateArray ( updates . updates , updates . users , updates . chats ) ) {
needGetDiff = true ;
2013-11-04 12:31:01 +00:00
MessagesStorage . lastPtsValue = lastPtsValue ;
MessagesStorage . lastQtsValue = lastQtsValue ;
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " need get diff inner TL_updates, seq: " + MessagesStorage . lastSeqValue + " " + updates . seq ) ;
2013-10-25 15:19:00 +00:00
} else {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastDateValue = updates . date ;
MessagesStorage . lastSeqValue = updates . seq ;
if ( MessagesStorage . lastQtsValue ! = lastQtsValue ) {
2013-10-25 15:19:00 +00:00
needReceivedQueue = true ;
}
}
} else {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " need get diff TL_updates, seq: " + MessagesStorage . lastSeqValue + " " + updates . seq ) ;
2013-10-25 15:19:00 +00:00
needGetDiff = true ;
}
} else if ( updates instanceof TLRPC . TL_updatesTooLong ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , " need get diff TL_updatesTooLong " ) ;
2013-10-25 15:19:00 +00:00
needGetDiff = true ;
}
if ( needGetDiff ) {
getDifference ( ) ;
}
if ( needReceivedQueue ) {
TLRPC . TL_messages_receivedQueue req = new TLRPC . TL_messages_receivedQueue ( ) ;
2013-11-04 12:31:01 +00:00
req . max_qts = MessagesStorage . lastQtsValue ;
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
2013-11-04 12:31:01 +00:00
MessagesStorage . Instance . saveDiffParams ( MessagesStorage . lastSeqValue , MessagesStorage . lastPtsValue , MessagesStorage . lastDateValue , MessagesStorage . lastQtsValue ) ;
2013-10-25 15:19:00 +00:00
}
public boolean processUpdateArray ( ArrayList < TLRPC . Update > updates , final ArrayList < TLRPC . User > usersArr , final ArrayList < TLRPC . Chat > chatsArr ) {
if ( updates . isEmpty ( ) ) {
return true ;
}
long currentTime = System . currentTimeMillis ( ) ;
final HashMap < Long , ArrayList < MessageObject > > messages = new HashMap < Long , ArrayList < MessageObject > > ( ) ; //to chats+
final ArrayList < TLRPC . Message > messagesArr = new ArrayList < TLRPC . Message > ( ) ; //to db+
final ArrayList < Integer > markAsReadMessages = new ArrayList < Integer > ( ) ; //to db+ and chats+ and dialogs+
final HashMap < Integer , Integer > markAsReadEncrypted = new HashMap < Integer , Integer > ( ) ; //to db+ and chats+ and dialogs+
final ArrayList < Integer > deletedMessages = new ArrayList < Integer > ( ) ; //to db+ and chats+ and dialogs+
final ArrayList < Long > printChanges = new ArrayList < Long > ( ) ; //to chats+ and dialogs
final ArrayList < TLRPC . ChatParticipants > chatInfoToUpdate = new ArrayList < TLRPC . ChatParticipants > ( ) ; //to db+ and chats
final ArrayList < TLRPC . Update > updatesOnMainThread = new ArrayList < TLRPC . Update > ( ) ; //to db+ and every interface+
final ArrayList < TLRPC . TL_updateEncryptedMessagesRead > tasks = new ArrayList < TLRPC . TL_updateEncryptedMessagesRead > ( ) ;
MessageObject lastMessage = null ;
boolean usersAdded = false ;
boolean checkForUsers = true ;
ConcurrentHashMap < Integer , TLRPC . User > usersDict ;
ConcurrentHashMap < Integer , TLRPC . Chat > chatsDict ;
if ( usersArr ! = null ) {
usersDict = new ConcurrentHashMap < Integer , TLRPC . User > ( ) ;
for ( TLRPC . User user : usersArr ) {
usersDict . put ( user . id , user ) ;
}
} else {
checkForUsers = false ;
usersDict = users ;
}
if ( chatsArr ! = null ) {
chatsDict = new ConcurrentHashMap < Integer , TLRPC . Chat > ( ) ;
for ( TLRPC . Chat chat : chatsArr ) {
chatsDict . put ( chat . id , chat ) ;
}
} else {
checkForUsers = false ;
chatsDict = chats ;
}
boolean chatAvatarUpdated = false ;
boolean reloadContacts = false ;
for ( TLRPC . Update update : updates ) {
if ( update instanceof TLRPC . TL_updateNewMessage ) {
TLRPC . TL_updateNewMessage upd = ( TLRPC . TL_updateNewMessage ) update ;
if ( checkForUsers ) {
if ( usersDict . get ( upd . message . from_id ) = = null & & users . get ( upd . message . from_id ) = = null | | upd . message . to_id . chat_id ! = 0 & & chatsDict . get ( upd . message . to_id . chat_id ) = = null & & chats . get ( upd . message . to_id . chat_id ) = = null ) {
return false ;
}
}
messagesArr . add ( upd . message ) ;
MessageObject obj = new MessageObject ( upd . message , usersDict ) ;
if ( obj . type = = 11 ) {
chatAvatarUpdated = true ;
}
long uid ;
if ( upd . message . to_id . chat_id ! = 0 ) {
uid = - upd . message . to_id . chat_id ;
} else {
if ( upd . message . to_id . user_id = = UserConfig . clientUserId ) {
upd . message . to_id . user_id = upd . message . from_id ;
}
uid = upd . message . to_id . user_id ;
}
ArrayList < MessageObject > arr = messages . get ( uid ) ;
if ( arr = = null ) {
arr = new ArrayList < MessageObject > ( ) ;
messages . put ( uid , arr ) ;
}
arr . add ( obj ) ;
2013-11-04 12:31:01 +00:00
MessagesStorage . lastPtsValue = update . pts ;
2013-10-25 15:19:00 +00:00
if ( upd . message . from_id ! = UserConfig . clientUserId & & upd . message . to_id ! = null ) {
2013-12-20 19:25:49 +00:00
if ( uid ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) {
2013-10-25 15:19:00 +00:00
lastMessage = obj ;
}
}
} else if ( update instanceof TLRPC . TL_updateMessageID ) {
//can't be here
} else if ( update instanceof TLRPC . TL_updateReadMessages ) {
markAsReadMessages . addAll ( update . messages ) ;
2013-11-04 12:31:01 +00:00
MessagesStorage . lastPtsValue = update . pts ;
2013-10-25 15:19:00 +00:00
} else if ( update instanceof TLRPC . TL_updateDeleteMessages ) {
deletedMessages . addAll ( update . messages ) ;
2013-11-04 12:31:01 +00:00
MessagesStorage . lastPtsValue = update . pts ;
2013-10-25 15:19:00 +00:00
} else if ( update instanceof TLRPC . TL_updateRestoreMessages ) {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastPtsValue = update . pts ;
2013-10-25 15:19:00 +00:00
} else if ( update instanceof TLRPC . TL_updateUserTyping | | update instanceof TLRPC . TL_updateChatUserTyping ) {
if ( update . user_id ! = UserConfig . clientUserId ) {
long uid = - update . chat_id ;
if ( uid = = 0 ) {
uid = update . user_id ;
}
ArrayList < PrintingUser > arr = printingUsers . get ( uid ) ;
if ( arr = = null ) {
arr = new ArrayList < PrintingUser > ( ) ;
printingUsers . put ( uid , arr ) ;
}
boolean exist = false ;
for ( PrintingUser u : arr ) {
if ( u . userId = = update . user_id ) {
exist = true ;
u . lastTime = currentTime ;
break ;
}
}
if ( ! exist ) {
PrintingUser newUser = new PrintingUser ( ) ;
newUser . userId = update . user_id ;
newUser . lastTime = currentTime ;
arr . add ( newUser ) ;
if ( ! printChanges . contains ( uid ) ) {
printChanges . add ( uid ) ;
}
}
}
} else if ( update instanceof TLRPC . TL_updateChatParticipants ) {
chatInfoToUpdate . add ( update . participants ) ;
} else if ( update instanceof TLRPC . TL_updateUserStatus ) {
updatesOnMainThread . add ( update ) ;
} else if ( update instanceof TLRPC . TL_updateUserName ) {
updatesOnMainThread . add ( update ) ;
} else if ( update instanceof TLRPC . TL_updateUserPhoto ) {
2013-12-20 19:25:49 +00:00
/ * if ( ! ( update . photo instanceof TLRPC . TL_userProfilePhotoEmpty ) ) { DEPRECATED
if ( usersDict . containsKey ( update . user_id ) ) {
TLRPC . TL_messageService newMessage = new TLRPC . TL_messageService ( ) ;
newMessage . action = new TLRPC . TL_messageActionUserUpdatedPhoto ( ) ;
newMessage . action . newUserPhoto = update . photo ;
newMessage . local_id = newMessage . id = UserConfig . getNewMessageId ( ) ;
UserConfig . saveConfig ( false ) ;
newMessage . unread = true ;
newMessage . date = update . date ;
newMessage . from_id = update . user_id ;
newMessage . to_id = new TLRPC . TL_peerUser ( ) ;
newMessage . to_id . user_id = UserConfig . clientUserId ;
newMessage . out = false ;
newMessage . dialog_id = update . user_id ;
messagesArr . add ( newMessage ) ;
MessageObject obj = new MessageObject ( newMessage , usersDict ) ;
ArrayList < MessageObject > arr = messages . get ( newMessage . dialog_id ) ;
if ( arr = = null ) {
arr = new ArrayList < MessageObject > ( ) ;
messages . put ( newMessage . dialog_id , arr ) ;
}
arr . add ( obj ) ;
if ( newMessage . from_id ! = UserConfig . clientUserId & & newMessage . to_id ! = null ) {
if ( newMessage . dialog_id ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) {
lastMessage = obj ;
}
}
}
} * /
2013-10-25 15:19:00 +00:00
updatesOnMainThread . add ( update ) ;
} else if ( update instanceof TLRPC . TL_updateContactRegistered ) {
2013-12-20 19:25:49 +00:00
if ( usersDict . containsKey ( update . user_id ) ) {
TLRPC . TL_messageService newMessage = new TLRPC . TL_messageService ( ) ;
newMessage . action = new TLRPC . TL_messageActionUserJoined ( ) ;
newMessage . local_id = newMessage . id = UserConfig . getNewMessageId ( ) ;
UserConfig . saveConfig ( false ) ;
newMessage . unread = true ;
newMessage . date = update . date ;
newMessage . from_id = update . user_id ;
newMessage . to_id = new TLRPC . TL_peerUser ( ) ;
newMessage . to_id . user_id = UserConfig . clientUserId ;
newMessage . out = false ;
newMessage . dialog_id = update . user_id ;
messagesArr . add ( newMessage ) ;
MessageObject obj = new MessageObject ( newMessage , usersDict ) ;
ArrayList < MessageObject > arr = messages . get ( newMessage . dialog_id ) ;
if ( arr = = null ) {
arr = new ArrayList < MessageObject > ( ) ;
messages . put ( newMessage . dialog_id , arr ) ;
}
arr . add ( obj ) ;
if ( newMessage . from_id ! = UserConfig . clientUserId & & newMessage . to_id ! = null ) {
if ( newMessage . dialog_id ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) {
lastMessage = obj ;
}
}
}
2013-10-25 15:19:00 +00:00
reloadContacts = true ;
//updateContactRegistered#2575bbb9 user_id:int date:int = Update;
//updateContactRegistered Импортированный ранее контакт зарегистрировался
} else if ( update instanceof TLRPC . TL_updateContactLink ) {
reloadContacts = true ;
//updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
//updateContactLink Изменилась связь с пользователем
} else if ( update instanceof TLRPC . TL_updateActivation ) {
//updateActivation#6f690963 user_id:int = Update;
//updateActivation Пользователь активировал свой аккаунт
} else if ( update instanceof TLRPC . TL_updateNewAuthorization ) {
2013-12-20 19:25:49 +00:00
TLRPC . TL_messageService newMessage = new TLRPC . TL_messageService ( ) ;
newMessage . action = new TLRPC . TL_messageActionLoginUnknownLocation ( ) ;
newMessage . action . title = update . device ;
newMessage . action . address = update . location ;
newMessage . local_id = newMessage . id = UserConfig . getNewMessageId ( ) ;
UserConfig . saveConfig ( false ) ;
newMessage . unread = true ;
newMessage . date = update . date ;
newMessage . from_id = 333000 ;
newMessage . to_id = new TLRPC . TL_peerUser ( ) ;
newMessage . to_id . user_id = UserConfig . clientUserId ;
newMessage . out = false ;
newMessage . dialog_id = 333000 ;
messagesArr . add ( newMessage ) ;
MessageObject obj = new MessageObject ( newMessage , usersDict ) ;
ArrayList < MessageObject > arr = messages . get ( newMessage . dialog_id ) ;
if ( arr = = null ) {
arr = new ArrayList < MessageObject > ( ) ;
messages . put ( newMessage . dialog_id , arr ) ;
}
arr . add ( obj ) ;
if ( newMessage . from_id ! = UserConfig . clientUserId & & newMessage . to_id ! = null ) {
if ( newMessage . dialog_id ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) {
lastMessage = obj ;
}
}
2013-10-25 15:19:00 +00:00
} else if ( update instanceof TLRPC . TL_updateNewGeoChatMessage ) {
//TODO
} else if ( update instanceof TLRPC . TL_updateNewEncryptedMessage ) {
2013-11-04 12:31:01 +00:00
MessagesStorage . lastQtsValue = update . qts ;
2013-10-25 15:19:00 +00:00
TLRPC . Message message = decryptMessage ( ( ( TLRPC . TL_updateNewEncryptedMessage ) update ) . message ) ;
if ( message ! = null ) {
int cid = ( ( TLRPC . TL_updateNewEncryptedMessage ) update ) . message . chat_id ;
messagesArr . add ( message ) ;
MessageObject obj = new MessageObject ( message , usersDict ) ;
long uid = ( ( long ) cid ) < < 32 ;
ArrayList < MessageObject > arr = messages . get ( uid ) ;
if ( arr = = null ) {
arr = new ArrayList < MessageObject > ( ) ;
messages . put ( uid , arr ) ;
}
arr . add ( obj ) ;
if ( message . from_id ! = UserConfig . clientUserId & & message . to_id ! = null ) {
2013-12-20 19:25:49 +00:00
if ( uid ! = openned_dialog_id | | ApplicationLoader . lastPauseTime ! = 0 ) {
2013-10-25 15:19:00 +00:00
lastMessage = obj ;
}
}
}
} else if ( update instanceof TLRPC . TL_updateEncryptedChatTyping ) {
long uid = ( ( long ) update . chat_id ) < < 32 ;
ArrayList < PrintingUser > arr = printingUsers . get ( uid ) ;
if ( arr = = null ) {
arr = new ArrayList < PrintingUser > ( ) ;
printingUsers . put ( uid , arr ) ;
}
boolean exist = false ;
for ( PrintingUser u : arr ) {
if ( u . userId = = update . user_id ) {
exist = true ;
u . lastTime = currentTime ;
break ;
}
}
if ( ! exist ) {
PrintingUser newUser = new PrintingUser ( ) ;
newUser . userId = update . user_id ;
newUser . lastTime = currentTime ;
arr . add ( newUser ) ;
if ( ! printChanges . contains ( uid ) ) {
printChanges . add ( uid ) ;
}
}
} else if ( update instanceof TLRPC . TL_updateEncryptedMessagesRead ) {
markAsReadEncrypted . put ( update . chat_id , Math . max ( update . max_date , update . date ) ) ;
tasks . add ( ( TLRPC . TL_updateEncryptedMessagesRead ) update ) ;
} else if ( update instanceof TLRPC . TL_updateEncryption ) {
final TLRPC . EncryptedChat newChat = update . chat ;
long dialog_id = ( ( long ) newChat . id ) < < 32 ;
TLRPC . EncryptedChat existingChat = encryptedChats . get ( newChat . id ) ;
if ( existingChat = = null ) {
Semaphore semaphore = new Semaphore ( 0 ) ;
ArrayList < TLObject > result = new ArrayList < TLObject > ( ) ;
MessagesStorage . Instance . getEncryptedChat ( newChat . id , semaphore , result ) ;
try {
semaphore . acquire ( ) ;
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
if ( result . size ( ) = = 2 ) {
existingChat = ( TLRPC . EncryptedChat ) result . get ( 0 ) ;
TLRPC . User user = ( TLRPC . User ) result . get ( 1 ) ;
users . putIfAbsent ( user . id , user ) ;
}
}
if ( newChat instanceof TLRPC . TL_encryptedChatRequested & & existingChat = = null ) {
int user_id = newChat . participant_id ;
if ( user_id = = UserConfig . clientUserId ) {
user_id = newChat . admin_id ;
}
TLRPC . User user = users . get ( user_id ) ;
2013-12-20 19:25:49 +00:00
if ( user = = null ) {
user = usersDict . get ( user_id ) ;
}
2013-10-25 15:19:00 +00:00
newChat . user_id = user_id ;
final TLRPC . TL_dialog dialog = new TLRPC . TL_dialog ( ) ;
dialog . id = dialog_id ;
dialog . unread_count = 0 ;
dialog . top_message = 0 ;
dialog . last_message_date = update . date ;
usersAdded = true ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
if ( usersArr ! = null ) {
for ( TLRPC . User user : usersArr ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
}
if ( chatsArr ! = null ) {
for ( TLRPC . Chat chat : chatsArr ) {
chats . put ( chat . id , chat ) ;
}
}
dialogs_dict . put ( dialog . id , dialog ) ;
dialogs . add ( dialog ) ;
dialogsServerOnly . clear ( ) ;
encryptedChats . put ( newChat . id , newChat ) ;
Collections . sort ( dialogs , new Comparator < TLRPC . TL_dialog > ( ) {
@Override
public int compare ( TLRPC . TL_dialog tl_dialog , TLRPC . TL_dialog tl_dialog2 ) {
if ( tl_dialog . last_message_date = = tl_dialog2 . last_message_date ) {
return 0 ;
} else if ( tl_dialog . last_message_date < tl_dialog2 . last_message_date ) {
return 1 ;
} else {
return - 1 ;
}
}
} ) ;
for ( TLRPC . TL_dialog d : dialogs ) {
if ( ( int ) d . id ! = 0 ) {
dialogsServerOnly . add ( d ) ;
}
}
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
}
} ) ;
MessagesStorage . Instance . putEncryptedChat ( newChat , user , dialog ) ;
2013-11-04 12:31:01 +00:00
acceptSecretChat ( newChat ) ;
2013-10-25 15:19:00 +00:00
} else if ( newChat instanceof TLRPC . TL_encryptedChat ) {
if ( existingChat ! = null & & existingChat instanceof TLRPC . TL_encryptedChatWaiting & & ( existingChat . auth_key = = null | | existingChat . auth_key . length = = 1 ) ) {
newChat . a_or_b = existingChat . a_or_b ;
newChat . user_id = existingChat . user_id ;
processAcceptedSecretChat ( newChat ) ;
}
} else {
final TLRPC . EncryptedChat exist = existingChat ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
if ( exist ! = null ) {
newChat . user_id = exist . user_id ;
newChat . auth_key = exist . auth_key ;
encryptedChats . put ( newChat . id , newChat ) ;
}
MessagesStorage . Instance . updateEncryptedChat ( newChat ) ;
NotificationCenter . Instance . postNotificationName ( encryptedChatUpdated , newChat ) ;
}
} ) ;
}
}
}
if ( ! messages . isEmpty ( ) ) {
for ( HashMap . Entry < Long , ArrayList < MessageObject > > pair : messages . entrySet ( ) ) {
Long key = pair . getKey ( ) ;
ArrayList < MessageObject > value = pair . getValue ( ) ;
boolean printChanged = updatePrintingUsersWithNewMessages ( key , value ) ;
if ( printChanged & & ! printChanges . contains ( key ) ) {
printChanges . add ( key ) ;
}
}
}
if ( reloadContacts ) {
loadContacts ( false ) ;
}
if ( ! printChanges . isEmpty ( ) ) {
updatePrintingStrings ( ) ;
}
final MessageObject lastMessageArg = lastMessage ;
final boolean reloadInterfaceForce = chatAvatarUpdated ;
if ( ! messagesArr . isEmpty ( ) ) {
MessagesStorage . Instance . putMessages ( messagesArr , true , true ) ;
}
final boolean usersAddedConst = usersAdded ;
if ( ! messages . isEmpty ( ) | | ! markAsReadMessages . isEmpty ( ) | | ! deletedMessages . isEmpty ( ) | | ! printChanges . isEmpty ( ) | | ! chatInfoToUpdate . isEmpty ( ) | | ! updatesOnMainThread . isEmpty ( ) | | ! markAsReadEncrypted . isEmpty ( ) ) {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
if ( ! usersAddedConst ) {
if ( usersArr ! = null ) {
for ( TLRPC . User user : usersArr ) {
users . put ( user . id , user ) ;
if ( user . id = = UserConfig . clientUserId ) {
UserConfig . currentUser = user ;
}
}
}
if ( chatsArr ! = null ) {
for ( TLRPC . Chat chat : chatsArr ) {
chats . put ( chat . id , chat ) ;
}
}
}
boolean avatarsUpdate = false ;
if ( ! updatesOnMainThread . isEmpty ( ) ) {
ArrayList < TLRPC . User > dbUsers = new ArrayList < TLRPC . User > ( ) ;
ArrayList < TLRPC . User > dbUsersStatus = new ArrayList < TLRPC . User > ( ) ;
for ( TLRPC . Update update : updatesOnMainThread ) {
TLRPC . User toDbUser = new TLRPC . User ( ) ;
toDbUser . id = update . user_id ;
TLRPC . User currentUser = users . get ( update . user_id ) ;
if ( update instanceof TLRPC . TL_updateUserStatus ) {
if ( ! ( update . status instanceof TLRPC . TL_userStatusEmpty ) ) {
if ( currentUser ! = null ) {
currentUser . id = update . user_id ;
currentUser . status = update . status ;
if ( update . status instanceof TLRPC . TL_userStatusOnline ) {
currentUser . status . was_online = update . status . expires ;
} else if ( update . status instanceof TLRPC . TL_userStatusOffline ) {
currentUser . status . expires = update . status . was_online ;
} else {
currentUser . status . was_online = 0 ;
currentUser . status . expires = 0 ;
}
}
toDbUser . status = update . status ;
dbUsersStatus . add ( toDbUser ) ;
}
} else if ( update instanceof TLRPC . TL_updateUserName ) {
if ( currentUser ! = null ) {
currentUser . first_name = update . first_name ;
currentUser . last_name = update . last_name ;
}
toDbUser . first_name = update . first_name ;
toDbUser . last_name = update . last_name ;
dbUsers . add ( toDbUser ) ;
} else if ( update instanceof TLRPC . TL_updateUserPhoto ) {
if ( currentUser ! = null ) {
currentUser . photo = update . photo ;
}
avatarsUpdate = true ;
toDbUser . photo = update . photo ;
dbUsers . add ( toDbUser ) ;
}
}
MessagesStorage . Instance . updateUsers ( dbUsersStatus , true , true , true ) ;
MessagesStorage . Instance . updateUsers ( dbUsers , false , true , true ) ;
}
if ( ! messages . isEmpty ( ) ) {
for ( HashMap . Entry < Long , ArrayList < MessageObject > > entry : messages . entrySet ( ) ) {
Long key = entry . getKey ( ) ;
ArrayList < MessageObject > value = entry . getValue ( ) ;
updateInterfaceWithMessages ( key , value ) ;
}
}
if ( ! markAsReadMessages . isEmpty ( ) ) {
for ( Integer id : markAsReadMessages ) {
MessageObject obj = dialogMessage . get ( id ) ;
if ( obj ! = null ) {
obj . messageOwner . unread = false ;
}
}
NotificationCenter . Instance . postNotificationName ( messagesReaded , markAsReadMessages ) ;
}
if ( ! markAsReadEncrypted . isEmpty ( ) ) {
for ( HashMap . Entry < Integer , Integer > entry : markAsReadEncrypted . entrySet ( ) ) {
NotificationCenter . Instance . postNotificationName ( messagesReadedEncrypted , entry . getKey ( ) , entry . getValue ( ) ) ;
long dialog_id = ( long ) ( entry . getKey ( ) ) < < 32 ;
TLRPC . TL_dialog dialog = dialogs_dict . get ( dialog_id ) ;
if ( dialog ! = null ) {
MessageObject message = dialogMessage . get ( dialog . top_message ) ;
2013-12-20 19:25:49 +00:00
if ( message ! = null & & message . messageOwner . date < = entry . getValue ( ) ) {
2013-10-25 15:19:00 +00:00
message . messageOwner . unread = false ;
}
}
}
}
if ( ! deletedMessages . isEmpty ( ) ) {
NotificationCenter . Instance . postNotificationName ( messagesDeleted , deletedMessages ) ;
for ( Integer id : deletedMessages ) {
MessageObject obj = dialogMessage . get ( id ) ;
if ( obj ! = null ) {
obj . deleted = true ;
}
}
}
if ( ! printChanges . isEmpty ( ) ) {
for ( Long uid : printChanges ) {
NotificationCenter . Instance . postNotificationName ( userPrintUpdate , uid ) ;
}
NotificationCenter . Instance . postNotificationName ( userPrintUpdateAll ) ;
}
if ( ! chatInfoToUpdate . isEmpty ( ) ) {
for ( TLRPC . ChatParticipants info : chatInfoToUpdate ) {
MessagesStorage . Instance . updateChatInfo ( info . chat_id , info , true ) ;
NotificationCenter . Instance . postNotificationName ( chatInfoDidLoaded , info . chat_id , info ) ;
}
}
if ( avatarsUpdate | | reloadInterfaceForce ) {
NotificationCenter . Instance . postNotificationName ( updateInterfaces , UPDATE_MASK_ALL ) ;
} else {
NotificationCenter . Instance . postNotificationName ( updateInterfaces , UPDATE_MASK_NAME | UPDATE_MASK_STATUS ) ;
}
if ( lastMessageArg ! = null ) {
showInAppNotification ( lastMessageArg ) ;
}
}
} ) ;
}
if ( ! markAsReadMessages . isEmpty ( ) | | ! markAsReadEncrypted . isEmpty ( ) ) {
MessagesStorage . Instance . markMessagesAsRead ( markAsReadMessages , markAsReadEncrypted , true ) ;
}
if ( ! deletedMessages . isEmpty ( ) ) {
MessagesStorage . Instance . markMessagesAsDeleted ( deletedMessages , true ) ;
}
if ( ! deletedMessages . isEmpty ( ) ) {
MessagesStorage . Instance . updateDialogsWithDeletedMessages ( deletedMessages , true ) ;
}
if ( ! markAsReadMessages . isEmpty ( ) ) {
MessagesStorage . Instance . updateDialogsWithReadedMessages ( markAsReadMessages , true ) ;
}
if ( ! tasks . isEmpty ( ) ) {
for ( TLRPC . TL_updateEncryptedMessagesRead update : tasks ) {
MessagesStorage . Instance . createTaskForDate ( update . chat_id , update . max_date , update . date , 1 ) ;
}
}
return true ;
}
private boolean updatePrintingUsersWithNewMessages ( long uid , ArrayList < MessageObject > messages ) {
if ( uid > 0 ) {
ArrayList < PrintingUser > arr = printingUsers . get ( uid ) ;
if ( arr ! = null ) {
printingUsers . remove ( uid ) ;
return true ;
}
} else if ( uid < 0 ) {
ArrayList < Integer > messagesUsers = new ArrayList < Integer > ( ) ;
for ( MessageObject message : messages ) {
if ( ! messagesUsers . contains ( message . messageOwner . from_id ) ) {
messagesUsers . add ( message . messageOwner . from_id ) ;
}
}
ArrayList < PrintingUser > arr = printingUsers . get ( uid ) ;
boolean changed = false ;
if ( arr ! = null ) {
for ( int a = 0 ; a < arr . size ( ) ; a + + ) {
PrintingUser user = arr . get ( a ) ;
if ( messagesUsers . contains ( user . userId ) ) {
arr . remove ( a ) ;
a - - ;
if ( arr . isEmpty ( ) ) {
printingUsers . remove ( uid ) ;
}
changed = true ;
}
}
}
if ( changed ) {
return true ;
}
}
return false ;
}
private void playNotificationSound ( ) {
if ( lastSoundPlay > System . currentTimeMillis ( ) - 1800 ) {
return ;
}
try {
lastSoundPlay = System . currentTimeMillis ( ) ;
soundPool . play ( sound , 1 , 1 , 1 , 0 , 1 ) ;
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
}
private void showInAppNotification ( MessageObject messageObject ) {
2013-12-20 19:25:49 +00:00
if ( ApplicationLoader . lastPauseTime ! = 0 ) {
ApplicationLoader . lastPauseTime = System . currentTimeMillis ( ) ;
FileLog . e ( " tmessages " , " reset sleep timeout by recieved message " ) ;
}
if ( messageObject = = null ) {
return ;
}
2013-11-04 12:31:01 +00:00
SharedPreferences preferences = ApplicationLoader . applicationContext . getSharedPreferences ( " Notifications " , Context . MODE_PRIVATE ) ;
2013-10-25 15:19:00 +00:00
boolean globalEnabled = preferences . getBoolean ( " EnableAll " , true ) ;
if ( ! globalEnabled ) {
return ;
}
2013-10-26 22:34:39 +00:00
if ( ApplicationLoader . lastPauseTime = = 0 ) {
boolean inAppSounds = preferences . getBoolean ( " EnableInAppSounds " , true ) ;
boolean inAppVibrate = preferences . getBoolean ( " EnableInAppVibrate " , true ) ;
boolean inAppPreview = preferences . getBoolean ( " EnableInAppPreview " , true ) ;
if ( inAppSounds | | inAppVibrate | | inAppPreview ) {
long dialog_id = messageObject . messageOwner . dialog_id ;
int user_id = messageObject . messageOwner . from_id ;
int chat_id = 0 ;
if ( dialog_id = = 0 ) {
if ( messageObject . messageOwner . to_id . chat_id ! = 0 ) {
dialog_id = - messageObject . messageOwner . to_id . chat_id ;
chat_id = messageObject . messageOwner . to_id . chat_id ;
} else if ( messageObject . messageOwner . to_id . user_id ! = 0 ) {
if ( messageObject . messageOwner . to_id . user_id = = UserConfig . clientUserId ) {
dialog_id = messageObject . messageOwner . from_id ;
} else {
dialog_id = messageObject . messageOwner . to_id . user_id ;
}
}
} else {
TLRPC . EncryptedChat chat = encryptedChats . get ( ( int ) ( dialog_id > > 32 ) ) ;
if ( chat = = null ) {
return ;
2013-10-25 15:19:00 +00:00
}
}
2013-10-26 22:34:39 +00:00
if ( dialog_id = = 0 ) {
return ;
}
TLRPC . User user = users . get ( user_id ) ;
if ( user = = null ) {
return ;
}
TLRPC . Chat chat ;
if ( chat_id ! = 0 ) {
chat = chats . get ( chat_id ) ;
if ( chat = = null ) {
return ;
}
}
String key = " notify_ " + dialog_id ;
boolean value = preferences . getBoolean ( key , true ) ;
if ( ! value ) {
2013-10-25 15:19:00 +00:00
return ;
}
2013-10-26 22:34:39 +00:00
if ( inAppPreview ) {
NotificationCenter . Instance . postNotificationName ( 701 , messageObject ) ;
}
if ( inAppVibrate ) {
2013-11-04 12:31:01 +00:00
Vibrator v = ( Vibrator ) ApplicationLoader . applicationContext . getSystemService ( Context . VIBRATOR_SERVICE ) ;
2013-10-26 22:34:39 +00:00
v . vibrate ( 100 ) ;
}
if ( inAppSounds ) {
playNotificationSound ( ) ;
}
2013-10-25 15:19:00 +00:00
}
2013-10-26 22:34:39 +00:00
} else {
long dialog_id = messageObject . messageOwner . dialog_id ;
int chat_id = messageObject . messageOwner . to_id . chat_id ;
int user_id = messageObject . messageOwner . to_id . user_id ;
2013-12-20 19:25:49 +00:00
if ( user_id ! = 0 & & user_id = = UserConfig . clientUserId ) {
user_id = messageObject . messageOwner . from_id ;
}
2013-10-25 15:19:00 +00:00
if ( dialog_id = = 0 ) {
2013-10-26 22:34:39 +00:00
if ( chat_id ! = 0 ) {
dialog_id = - chat_id ;
} else if ( user_id ! = 0 ) {
dialog_id = user_id ;
}
2013-10-25 15:19:00 +00:00
}
2013-10-26 22:34:39 +00:00
if ( dialog_id ! = 0 ) {
String key = " notify_ " + dialog_id ;
boolean value = preferences . getBoolean ( key , true ) ;
if ( ! value ) {
2013-10-25 15:19:00 +00:00
return ;
}
}
2013-10-26 22:34:39 +00:00
boolean groupEnabled = preferences . getBoolean ( " EnableGroup " , true ) ;
if ( chat_id ! = 0 & & ! globalEnabled ) {
2013-10-25 15:19:00 +00:00
return ;
}
2013-10-26 22:34:39 +00:00
boolean globalVibrate = preferences . getBoolean ( " EnableVibrateAll " , true ) ;
boolean groupVibrate = preferences . getBoolean ( " EnableVibrateGroup " , true ) ;
String defaultPath = null ;
Uri defaultUri = Settings . System . DEFAULT_NOTIFICATION_URI ;
if ( defaultUri ! = null ) {
defaultPath = defaultUri . getPath ( ) ;
}
String globalSound = preferences . getString ( " GlobalSoundPath " , defaultPath ) ;
String chatSound = preferences . getString ( " GroupSoundPath " , defaultPath ) ;
String userSoundPath = null ;
String chatSoundPath = null ;
2013-11-04 12:31:01 +00:00
NotificationManager mNotificationManager = ( NotificationManager ) ApplicationLoader . applicationContext . getSystemService ( Context . NOTIFICATION_SERVICE ) ;
Intent intent = new Intent ( ApplicationLoader . applicationContext , LaunchActivity . class ) ;
2013-12-20 19:25:49 +00:00
String msg = null ;
2013-10-26 22:34:39 +00:00
if ( ( int ) dialog_id ! = 0 ) {
if ( chat_id ! = 0 ) {
intent . putExtra ( " chatId " , chat_id ) ;
}
if ( user_id ! = 0 ) {
intent . putExtra ( " userId " , user_id ) ;
}
2013-12-20 19:25:49 +00:00
if ( chat_id = = 0 & & user_id ! = 0 ) {
TLRPC . User u = users . get ( user_id ) ;
if ( u = = null ) {
return ;
}
if ( messageObject . messageOwner instanceof TLRPC . TL_messageService ) {
if ( messageObject . messageOwner . action instanceof TLRPC . TL_messageActionUserJoined ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationContactJoined , Utilities . formatName ( u . first_name , u . last_name ) ) ;
} else if ( messageObject . messageOwner . action instanceof TLRPC . TL_messageActionUserUpdatedPhoto ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationContactNewPhoto , Utilities . formatName ( u . first_name , u . last_name ) ) ;
} else if ( messageObject . messageOwner . action instanceof TLRPC . TL_messageActionLoginUnknownLocation ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationUnrecognizedDevice , messageObject . messageOwner . action . title , messageObject . messageOwner . action . address ) ;
}
} else {
if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaEmpty ) {
if ( messageObject . messageOwner . message ! = null & & messageObject . messageOwner . message . length ( ) ! = 0 ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageText , Utilities . formatName ( u . first_name , u . last_name ) , messageObject . messageOwner . message ) ;
} else {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageNoText , Utilities . formatName ( u . first_name , u . last_name ) ) ;
}
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaPhoto ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessagePhoto , Utilities . formatName ( u . first_name , u . last_name ) ) ;
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaVideo ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageVideo , Utilities . formatName ( u . first_name , u . last_name ) ) ;
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaContact ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageContact , Utilities . formatName ( u . first_name , u . last_name ) ) ;
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaGeo ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageMap , Utilities . formatName ( u . first_name , u . last_name ) ) ;
}
}
} else if ( chat_id ! = 0 & & user_id = = 0 ) {
TLRPC . Chat chat = chats . get ( chat_id ) ;
if ( chat = = null ) {
return ;
}
TLRPC . User u = users . get ( messageObject . messageOwner . from_id ) ;
if ( u = = null ) {
return ;
}
if ( messageObject . messageOwner instanceof TLRPC . TL_messageService ) {
if ( messageObject . messageOwner . action instanceof TLRPC . TL_messageActionChatAddUser ) {
if ( messageObject . messageOwner . action . user_id = = UserConfig . clientUserId ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationInvitedToGroup , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
} else {
TLRPC . User u2 = users . get ( messageObject . messageOwner . action . user_id ) ;
if ( u2 = = null ) {
return ;
}
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationGroupAddMember , Utilities . formatName ( u . first_name , u . last_name ) , chat . title , Utilities . formatName ( u2 . first_name , u2 . last_name ) ) ;
}
} else if ( messageObject . messageOwner . action instanceof TLRPC . TL_messageActionChatEditTitle ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationEditedGroupName , Utilities . formatName ( u . first_name , u . last_name ) , messageObject . messageOwner . action . title ) ;
} else if ( messageObject . messageOwner . action instanceof TLRPC . TL_messageActionChatEditPhoto | | messageObject . messageOwner . action instanceof TLRPC . TL_messageActionChatDeletePhoto ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationEditedGroupPhoto , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
} else if ( messageObject . messageOwner . action instanceof TLRPC . TL_messageActionChatDeleteUser ) {
if ( messageObject . messageOwner . action . user_id = = UserConfig . clientUserId ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationGroupKickYou , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
} else if ( messageObject . messageOwner . action . user_id = = u . id ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationGroupLeftMember , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
} else {
TLRPC . User u2 = users . get ( messageObject . messageOwner . action . user_id ) ;
if ( u2 = = null ) {
return ;
}
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationGroupKickMember , Utilities . formatName ( u . first_name , u . last_name ) , chat . title , Utilities . formatName ( u2 . first_name , u2 . last_name ) ) ;
}
}
} else {
if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaEmpty ) {
if ( messageObject . messageOwner . message ! = null & & messageObject . messageOwner . message . length ( ) ! = 0 ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageGroupText , Utilities . formatName ( u . first_name , u . last_name ) , chat . title , messageObject . messageOwner . message ) ;
} else {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageGroupNoText , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
}
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaPhoto ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageGroupPhoto , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaVideo ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageGroupVideo , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaContact ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageGroupContact , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
} else if ( messageObject . messageOwner . media instanceof TLRPC . TL_messageMediaGeo ) {
msg = ApplicationLoader . applicationContext . getString ( R . string . NotificationMessageGroupMap , Utilities . formatName ( u . first_name , u . last_name ) , chat . title ) ;
}
}
}
2013-10-26 22:34:39 +00:00
} else {
2013-11-04 12:31:01 +00:00
msg = ApplicationLoader . applicationContext . getString ( R . string . YouHaveNewMessage ) ;
2013-10-26 22:34:39 +00:00
}
2013-12-20 19:25:49 +00:00
if ( msg = = null ) {
return ;
}
2013-10-26 22:34:39 +00:00
boolean needVibrate = false ;
if ( user_id ! = 0 ) {
userSoundPath = preferences . getString ( " sound_path_ " + user_id , null ) ;
needVibrate = globalVibrate ;
2013-10-25 15:19:00 +00:00
}
2013-10-26 22:34:39 +00:00
if ( chat_id ! = 0 ) {
chatSoundPath = preferences . getString ( " sound_chat_path_ " + chat_id , null ) ;
needVibrate = groupVibrate ;
2013-10-25 15:19:00 +00:00
}
2013-10-26 22:34:39 +00:00
String choosenSoundPath = null ;
if ( user_id ! = 0 ) {
if ( userSoundPath ! = null ) {
choosenSoundPath = userSoundPath ;
} else if ( globalSound ! = null ) {
choosenSoundPath = globalSound ;
}
} else if ( chat_id ! = 0 ) {
if ( chatSoundPath ! = null ) {
choosenSoundPath = chatSoundPath ;
} else if ( chatSound ! = null ) {
choosenSoundPath = chatSound ;
}
} else {
choosenSoundPath = globalSound ;
2013-10-25 15:19:00 +00:00
}
2013-10-26 22:34:39 +00:00
intent . setAction ( " com.tmessages.openchat " + Math . random ( ) + Integer . MAX_VALUE ) ;
2013-12-20 19:25:49 +00:00
intent . setFlags ( 32768 ) ;
2013-11-04 12:31:01 +00:00
PendingIntent contentIntent = PendingIntent . getActivity ( ApplicationLoader . applicationContext , 0 , intent , PendingIntent . FLAG_ONE_SHOT ) ;
2013-10-26 22:34:39 +00:00
2013-11-04 12:31:01 +00:00
NotificationCompat . Builder mBuilder = new NotificationCompat . Builder ( ApplicationLoader . applicationContext )
. setContentTitle ( ApplicationLoader . applicationContext . getString ( R . string . AppName ) )
2013-10-26 22:34:39 +00:00
. setSmallIcon ( R . drawable . notification )
. setStyle ( new NotificationCompat . BigTextStyle ( )
. bigText ( msg ) )
. setContentText ( msg )
. setAutoCancel ( true )
. setTicker ( msg ) ;
if ( needVibrate ) {
mBuilder . setVibrate ( new long [ ] { 0 , 100 , 0 , 100 } ) ;
}
if ( choosenSoundPath ! = null & & ! choosenSoundPath . equals ( " NoSound " ) ) {
if ( choosenSoundPath . equals ( defaultPath ) ) {
mBuilder . setSound ( defaultUri ) ;
} else {
mBuilder . setSound ( Uri . parse ( choosenSoundPath ) ) ;
}
}
mBuilder . setContentIntent ( contentIntent ) ;
mNotificationManager . cancel ( 1 ) ;
Notification notification = mBuilder . build ( ) ;
notification . ledARGB = 0xff00ff00 ;
notification . ledOnMS = 1000 ;
notification . ledOffMS = 1000 ;
notification . flags | = Notification . FLAG_SHOW_LIGHTS ;
2013-12-20 19:25:49 +00:00
try {
mNotificationManager . notify ( 1 , notification ) ;
} catch ( Exception e ) {
FileLog . e ( " tmessages " , e ) ;
}
2013-10-25 15:19:00 +00:00
}
}
private void updateInterfaceWithMessages ( long uid , ArrayList < MessageObject > messages ) {
int unreadCount = 0 ;
MessageObject lastMessage = null ;
int lastDate = 0 ;
TLRPC . TL_dialog dialog = dialogs_dict . get ( uid ) ;
NotificationCenter . Instance . postNotificationName ( didReceivedNewMessages , uid , messages ) ;
for ( MessageObject message : messages ) {
if ( message . messageOwner . unread & & message . messageOwner . from_id ! = UserConfig . clientUserId ) {
unreadCount + + ;
}
if ( lastMessage = = null | | message . messageOwner . date > lastDate ) {
lastMessage = message ;
lastDate = message . messageOwner . date ;
}
}
if ( dialog = = null ) {
dialog = new TLRPC . TL_dialog ( ) ;
dialog . id = uid ;
dialog . unread_count = unreadCount ;
dialog . top_message = lastMessage . messageOwner . id ;
dialog . last_message_date = lastMessage . messageOwner . date ;
dialogs_dict . put ( uid , dialog ) ;
dialogs . add ( dialog ) ;
dialogMessage . put ( lastMessage . messageOwner . id , lastMessage ) ;
} else {
dialogMessage . remove ( dialog . top_message ) ;
dialog . unread_count + = unreadCount ;
dialog . top_message = lastMessage . messageOwner . id ;
dialog . last_message_date = lastMessage . messageOwner . date ;
dialogMessage . put ( lastMessage . messageOwner . id , lastMessage ) ;
}
dialogsServerOnly . clear ( ) ;
Collections . sort ( dialogs , new Comparator < TLRPC . TL_dialog > ( ) {
@Override
public int compare ( TLRPC . TL_dialog tl_dialog , TLRPC . TL_dialog tl_dialog2 ) {
if ( tl_dialog . last_message_date = = tl_dialog2 . last_message_date ) {
return 0 ;
} else if ( tl_dialog . last_message_date < tl_dialog2 . last_message_date ) {
return 1 ;
} else {
return - 1 ;
}
}
} ) ;
for ( TLRPC . TL_dialog d : dialogs ) {
if ( ( int ) d . id ! = 0 ) {
dialogsServerOnly . add ( d ) ;
}
}
}
public TLRPC . Message decryptMessage ( TLRPC . EncryptedMessage message ) {
TLRPC . EncryptedChat chat = encryptedChats . get ( message . chat_id ) ;
if ( chat = = null ) {
Semaphore semaphore = new Semaphore ( 0 ) ;
ArrayList < TLObject > result = new ArrayList < TLObject > ( ) ;
MessagesStorage . Instance . getEncryptedChat ( message . chat_id , semaphore , result ) ;
try {
semaphore . acquire ( ) ;
} catch ( Exception e ) {
2013-12-20 19:25:49 +00:00
FileLog . e ( " tmessages " , e ) ;
2013-10-25 15:19:00 +00:00
}
if ( result . size ( ) = = 2 ) {
chat = ( TLRPC . EncryptedChat ) result . get ( 0 ) ;
TLRPC . User user = ( TLRPC . User ) result . get ( 1 ) ;
encryptedChats . put ( chat . id , chat ) ;
users . putIfAbsent ( user . id , user ) ;
}
}
if ( chat = = null ) {
return null ;
}
SerializedData is = new SerializedData ( message . bytes ) ;
long fingerprint = is . readInt64 ( ) ;
if ( chat . key_fingerprint = = fingerprint ) {
byte [ ] messageKey = is . readData ( 16 ) ;
MessageKeyData keyData = Utilities . generateMessageKeyData ( chat . auth_key , messageKey , false ) ;
byte [ ] messageData = is . readData ( message . bytes . length - 24 ) ;
messageData = Utilities . aesIgeEncryption ( messageData , keyData . aesKey , keyData . aesIv , false , false ) ;
is = new SerializedData ( messageData ) ;
int len = is . readInt32 ( ) ;
TLObject object = TLClassStore . Instance ( ) . TLdeserialize ( is , is . readInt32 ( ) ) ;
if ( object ! = null ) {
int from_id = chat . admin_id ;
if ( from_id = = UserConfig . clientUserId ) {
from_id = chat . participant_id ;
}
if ( object instanceof TLRPC . TL_decryptedMessage ) {
TLRPC . TL_decryptedMessage decryptedMessage = ( TLRPC . TL_decryptedMessage ) object ;
TLRPC . TL_message newMessage = new TLRPC . TL_message ( ) ;
newMessage . message = decryptedMessage . message ;
newMessage . date = message . date ;
2013-12-20 19:25:49 +00:00
newMessage . local_id = newMessage . id = UserConfig . getNewMessageId ( ) ;
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
newMessage . from_id = from_id ;
newMessage . to_id = new TLRPC . TL_peerUser ( ) ;
newMessage . to_id . user_id = UserConfig . clientUserId ;
newMessage . out = false ;
newMessage . unread = true ;
newMessage . dialog_id = ( ( long ) chat . id ) < < 32 ;
newMessage . ttl = chat . ttl ;
if ( decryptedMessage . media instanceof TLRPC . TL_decryptedMessageMediaEmpty ) {
newMessage . media = new TLRPC . TL_messageMediaEmpty ( ) ;
} else if ( decryptedMessage . media instanceof TLRPC . TL_decryptedMessageMediaContact ) {
newMessage . media = new TLRPC . TL_messageMediaContact ( ) ;
newMessage . media . last_name = decryptedMessage . media . last_name ;
newMessage . media . first_name = decryptedMessage . media . first_name ;
newMessage . media . phone_number = decryptedMessage . media . phone_number ;
newMessage . media . user_id = decryptedMessage . media . user_id ;
} else if ( decryptedMessage . media instanceof TLRPC . TL_decryptedMessageMediaGeoPoint ) {
newMessage . media = new TLRPC . TL_messageMediaGeo ( ) ;
newMessage . media . geo = new TLRPC . TL_geoPoint ( ) ;
newMessage . media . geo . lat = decryptedMessage . media . lat ;
newMessage . media . geo . _long = decryptedMessage . media . _long ;
} else if ( decryptedMessage . media instanceof TLRPC . TL_decryptedMessageMediaPhoto ) {
2013-12-20 19:25:49 +00:00
if ( decryptedMessage . media . key . length ! = 32 | | decryptedMessage . media . iv . length ! = 32 ) {
return null ;
}
2013-10-25 15:19:00 +00:00
newMessage . media = new TLRPC . TL_messageMediaPhoto ( ) ;
newMessage . media . photo = new TLRPC . TL_photo ( ) ;
newMessage . media . photo . user_id = newMessage . from_id ;
newMessage . media . photo . date = newMessage . date ;
newMessage . media . photo . caption = " " ;
newMessage . media . photo . geo = new TLRPC . TL_geoPointEmpty ( ) ;
TLRPC . TL_photoCachedSize small = new TLRPC . TL_photoCachedSize ( ) ;
small . w = decryptedMessage . media . thumb_w ;
small . h = decryptedMessage . media . thumb_h ;
small . bytes = decryptedMessage . media . thumb ;
small . type = " s " ;
small . location = new TLRPC . TL_fileLocationUnavailable ( ) ;
newMessage . media . photo . sizes . add ( small ) ;
TLRPC . TL_photoSize big = new TLRPC . TL_photoSize ( ) ;
big . w = decryptedMessage . media . w ;
big . h = decryptedMessage . media . h ;
big . type = " x " ;
big . size = message . file . size ;
big . location = new TLRPC . TL_fileEncryptedLocation ( ) ;
big . location . key = decryptedMessage . media . key ;
big . location . iv = decryptedMessage . media . iv ;
big . location . dc_id = message . file . dc_id ;
big . location . volume_id = message . file . id ;
big . location . secret = message . file . access_hash ;
big . location . local_id = message . file . key_fingerprint ;
newMessage . media . photo . sizes . add ( big ) ;
} else if ( decryptedMessage . media instanceof TLRPC . TL_decryptedMessageMediaVideo ) {
2013-12-20 19:25:49 +00:00
if ( decryptedMessage . media . key . length ! = 32 | | decryptedMessage . media . iv . length ! = 32 ) {
return null ;
}
2013-10-25 15:19:00 +00:00
newMessage . media = new TLRPC . TL_messageMediaVideo ( ) ;
newMessage . media . video = new TLRPC . TL_videoEncrypted ( ) ;
newMessage . media . video . thumb = new TLRPC . TL_photoCachedSize ( ) ;
newMessage . media . video . thumb . bytes = decryptedMessage . media . thumb ;
newMessage . media . video . thumb . w = decryptedMessage . media . thumb_w ;
newMessage . media . video . thumb . h = decryptedMessage . media . thumb_h ;
newMessage . media . video . thumb . type = " s " ;
newMessage . media . video . thumb . location = new TLRPC . TL_fileLocationUnavailable ( ) ;
newMessage . media . video . duration = decryptedMessage . media . duration ;
newMessage . media . video . dc_id = message . file . dc_id ;
newMessage . media . video . w = decryptedMessage . media . w ;
newMessage . media . video . h = decryptedMessage . media . h ;
newMessage . media . video . date = message . date ;
newMessage . media . video . caption = " " ;
newMessage . media . video . user_id = from_id ;
newMessage . media . video . size = message . file . size ;
newMessage . media . video . id = message . file . id ;
newMessage . media . video . access_hash = message . file . access_hash ;
newMessage . media . video . key = decryptedMessage . media . key ;
newMessage . media . video . iv = decryptedMessage . media . iv ;
} else {
return null ;
}
return newMessage ;
} else if ( object instanceof TLRPC . TL_decryptedMessageService ) {
TLRPC . TL_decryptedMessageService serviceMessage = ( TLRPC . TL_decryptedMessageService ) object ;
if ( serviceMessage . action instanceof TLRPC . TL_decryptedMessageActionSetMessageTTL ) {
TLRPC . TL_messageService newMessage = new TLRPC . TL_messageService ( ) ;
newMessage . action = new TLRPC . TL_messageActionTTLChange ( ) ;
newMessage . action . ttl = chat . ttl = serviceMessage . action . ttl_seconds ;
newMessage . local_id = newMessage . id = UserConfig . getNewMessageId ( ) ;
2013-12-20 19:25:49 +00:00
UserConfig . saveConfig ( false ) ;
2013-10-25 15:19:00 +00:00
newMessage . unread = true ;
newMessage . date = message . date ;
newMessage . from_id = from_id ;
newMessage . to_id = new TLRPC . TL_peerUser ( ) ;
newMessage . to_id . user_id = UserConfig . clientUserId ;
newMessage . out = false ;
newMessage . dialog_id = ( ( long ) chat . id ) < < 32 ;
MessagesStorage . Instance . updateEncryptedChatTTL ( chat ) ;
return newMessage ;
}
}
}
}
return null ;
}
public void processAcceptedSecretChat ( final TLRPC . EncryptedChat encryptedChat ) {
2013-12-23 11:05:57 +00:00
BigInteger p = new BigInteger ( 1 , MessagesStorage . secretPBytes ) ;
2013-10-25 15:19:00 +00:00
BigInteger i_authKey = new BigInteger ( 1 , encryptedChat . g_a_or_b ) ;
2013-12-23 11:05:57 +00:00
2013-12-23 11:54:31 +00:00
if ( ! Utilities . isGoodGaAndGb ( i_authKey , p ) ) {
2013-12-23 11:05:57 +00:00
declineSecretChat ( encryptedChat . id ) ;
return ;
}
i_authKey = i_authKey . modPow ( new BigInteger ( 1 , encryptedChat . a_or_b ) , p ) ;
2013-10-25 15:19:00 +00:00
byte [ ] authKey = i_authKey . toByteArray ( ) ;
if ( authKey . length > 256 ) {
byte [ ] correctedAuth = new byte [ 256 ] ;
System . arraycopy ( authKey , authKey . length - 256 , correctedAuth , 0 , 256 ) ;
authKey = correctedAuth ;
} else if ( authKey . length < 256 ) {
byte [ ] correctedAuth = new byte [ 256 ] ;
System . arraycopy ( authKey , 0 , correctedAuth , 256 - authKey . length , authKey . length ) ;
for ( int a = 0 ; a < 256 - authKey . length ; a + + ) {
authKey [ a ] = 0 ;
}
authKey = correctedAuth ;
}
byte [ ] authKeyHash = Utilities . computeSHA1 ( authKey ) ;
byte [ ] authKeyId = new byte [ 8 ] ;
System . arraycopy ( authKeyHash , authKeyHash . length - 8 , authKeyId , 0 , 8 ) ;
long fingerprint = Utilities . bytesToLong ( authKeyId ) ;
if ( encryptedChat . key_fingerprint = = fingerprint ) {
encryptedChat . auth_key = authKey ;
MessagesStorage . Instance . updateEncryptedChat ( encryptedChat ) ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
encryptedChats . put ( encryptedChat . id , encryptedChat ) ;
NotificationCenter . Instance . postNotificationName ( encryptedChatUpdated , encryptedChat ) ;
}
} ) ;
} else {
final TLRPC . TL_encryptedChatDiscarded newChat = new TLRPC . TL_encryptedChatDiscarded ( ) ;
newChat . id = encryptedChat . id ;
newChat . user_id = encryptedChat . user_id ;
newChat . auth_key = encryptedChat . auth_key ;
MessagesStorage . Instance . updateEncryptedChat ( newChat ) ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
encryptedChats . put ( newChat . id , newChat ) ;
NotificationCenter . Instance . postNotificationName ( encryptedChatUpdated , newChat ) ;
}
} ) ;
declineSecretChat ( encryptedChat . id ) ;
}
}
public void declineSecretChat ( int chat_id ) {
TLRPC . TL_messages_discardEncryption req = new TLRPC . TL_messages_discardEncryption ( ) ;
req . chat_id = chat_id ;
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void acceptSecretChat ( final TLRPC . EncryptedChat encryptedChat ) {
if ( acceptingChats . get ( encryptedChat . id ) ! = null ) {
return ;
}
acceptingChats . put ( encryptedChat . id , encryptedChat ) ;
TLRPC . TL_messages_getDhConfig req = new TLRPC . TL_messages_getDhConfig ( ) ;
req . random_length = 256 ;
2013-11-04 12:31:01 +00:00
req . version = MessagesStorage . lastSecretVersion ;
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
TLRPC . messages_DhConfig res = ( TLRPC . messages_DhConfig ) response ;
if ( response instanceof TLRPC . TL_messages_dhConfig ) {
2013-12-23 11:05:57 +00:00
if ( ! Utilities . isGoodPrime ( res . p , res . g ) ) {
2013-12-22 23:47:35 +00:00
acceptingChats . remove ( encryptedChat . id ) ;
declineSecretChat ( encryptedChat . id ) ;
return ;
}
2013-11-04 12:31:01 +00:00
MessagesStorage . secretPBytes = res . p ;
MessagesStorage . secretG = res . g ;
MessagesStorage . lastSecretVersion = res . version ;
MessagesStorage . Instance . saveSecretParams ( MessagesStorage . lastSecretVersion , MessagesStorage . secretG , MessagesStorage . secretPBytes ) ;
2013-10-25 15:19:00 +00:00
}
byte [ ] salt = new byte [ 256 ] ;
for ( int a = 0 ; a < 256 ; a + + ) {
salt [ a ] = ( byte ) ( ( byte ) ( random . nextDouble ( ) * 255 ) ^ res . random [ a ] ) ;
}
encryptedChat . a_or_b = salt ;
2013-12-23 11:05:57 +00:00
BigInteger p = new BigInteger ( 1 , MessagesStorage . secretPBytes ) ;
BigInteger g_b = BigInteger . valueOf ( MessagesStorage . secretG ) ;
g_b = g_b . modPow ( new BigInteger ( 1 , salt ) , p ) ;
BigInteger g_a = new BigInteger ( 1 , encryptedChat . g_a ) ;
2013-12-23 11:54:31 +00:00
if ( ! Utilities . isGoodGaAndGb ( g_a , p ) ) {
2013-12-23 11:05:57 +00:00
acceptingChats . remove ( encryptedChat . id ) ;
declineSecretChat ( encryptedChat . id ) ;
return ;
}
byte [ ] g_b_bytes = g_b . toByteArray ( ) ;
if ( g_b_bytes . length > 256 ) {
2013-10-25 15:19:00 +00:00
byte [ ] correctedAuth = new byte [ 256 ] ;
2013-12-23 11:05:57 +00:00
System . arraycopy ( g_b_bytes , 1 , correctedAuth , 0 , 256 ) ;
g_b_bytes = correctedAuth ;
2013-10-25 15:19:00 +00:00
}
2013-12-23 11:05:57 +00:00
g_a = g_a . modPow ( new BigInteger ( 1 , salt ) , p ) ;
2013-10-25 15:19:00 +00:00
2013-12-23 11:05:57 +00:00
byte [ ] authKey = g_a . toByteArray ( ) ;
2013-10-25 15:19:00 +00:00
if ( authKey . length > 256 ) {
byte [ ] correctedAuth = new byte [ 256 ] ;
System . arraycopy ( authKey , authKey . length - 256 , correctedAuth , 0 , 256 ) ;
authKey = correctedAuth ;
} else if ( authKey . length < 256 ) {
byte [ ] correctedAuth = new byte [ 256 ] ;
System . arraycopy ( authKey , 0 , correctedAuth , 256 - authKey . length , authKey . length ) ;
for ( int a = 0 ; a < 256 - authKey . length ; a + + ) {
authKey [ a ] = 0 ;
}
authKey = correctedAuth ;
}
byte [ ] authKeyHash = Utilities . computeSHA1 ( authKey ) ;
byte [ ] authKeyId = new byte [ 8 ] ;
System . arraycopy ( authKeyHash , authKeyHash . length - 8 , authKeyId , 0 , 8 ) ;
encryptedChat . auth_key = authKey ;
TLRPC . TL_messages_acceptEncryption req2 = new TLRPC . TL_messages_acceptEncryption ( ) ;
2013-12-23 11:05:57 +00:00
req2 . g_b = g_b_bytes ;
2013-10-25 15:19:00 +00:00
req2 . peer = new TLRPC . TL_inputEncryptedChat ( ) ;
req2 . peer . chat_id = encryptedChat . id ;
req2 . peer . access_hash = encryptedChat . access_hash ;
req2 . key_fingerprint = Utilities . bytesToLong ( authKeyId ) ;
ConnectionsManager . Instance . performRpc ( req2 , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
acceptingChats . remove ( encryptedChat . id ) ;
if ( error = = null ) {
final TLRPC . EncryptedChat newChat = ( TLRPC . EncryptedChat ) response ;
newChat . auth_key = encryptedChat . auth_key ;
newChat . user_id = encryptedChat . user_id ;
MessagesStorage . Instance . updateEncryptedChat ( newChat ) ;
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
encryptedChats . put ( newChat . id , newChat ) ;
NotificationCenter . Instance . postNotificationName ( encryptedChatUpdated , newChat ) ;
}
} ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
} else {
acceptingChats . remove ( encryptedChat . id ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric ) ;
}
public void startSecretChat ( final Context context , final int user_id ) {
final ProgressDialog progressDialog = new ProgressDialog ( context ) ;
progressDialog . setMessage ( context . getString ( R . string . Loading ) ) ;
progressDialog . setCanceledOnTouchOutside ( false ) ;
progressDialog . setCancelable ( false ) ;
progressDialog . show ( ) ;
TLRPC . TL_messages_getDhConfig req = new TLRPC . TL_messages_getDhConfig ( ) ;
req . random_length = 256 ;
2013-11-04 12:31:01 +00:00
req . version = MessagesStorage . lastSecretVersion ;
2013-10-25 15:19:00 +00:00
ConnectionsManager . Instance . performRpc ( req , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
TLRPC . messages_DhConfig res = ( TLRPC . messages_DhConfig ) response ;
if ( response instanceof TLRPC . TL_messages_dhConfig ) {
2013-12-23 11:05:57 +00:00
if ( ! Utilities . isGoodPrime ( res . p , res . g ) ) {
2013-12-22 23:47:35 +00:00
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
if ( ! ( ( ActionBarActivity ) context ) . isFinishing ( ) ) {
progressDialog . dismiss ( ) ;
}
}
} ) ;
return ;
}
2013-11-04 12:31:01 +00:00
MessagesStorage . secretPBytes = res . p ;
MessagesStorage . secretG = res . g ;
MessagesStorage . lastSecretVersion = res . version ;
MessagesStorage . Instance . saveSecretParams ( MessagesStorage . lastSecretVersion , MessagesStorage . secretG , MessagesStorage . secretPBytes ) ;
2013-10-25 15:19:00 +00:00
}
final byte [ ] salt = new byte [ 256 ] ;
for ( int a = 0 ; a < 256 ; a + + ) {
salt [ a ] = ( byte ) ( ( byte ) ( random . nextDouble ( ) * 255 ) ^ res . random [ a ] ) ;
}
2013-12-23 11:05:57 +00:00
2013-11-04 12:31:01 +00:00
BigInteger i_g_a = BigInteger . valueOf ( MessagesStorage . secretG ) ;
i_g_a = i_g_a . modPow ( new BigInteger ( 1 , salt ) , new BigInteger ( 1 , MessagesStorage . secretPBytes ) ) ;
2013-10-25 15:19:00 +00:00
byte [ ] g_a = i_g_a . toByteArray ( ) ;
if ( g_a . length > 256 ) {
byte [ ] correctedAuth = new byte [ 256 ] ;
System . arraycopy ( g_a , 1 , correctedAuth , 0 , 256 ) ;
g_a = correctedAuth ;
}
2013-11-04 12:31:01 +00:00
final TLRPC . User user = users . get ( user_id ) ;
2013-10-25 15:19:00 +00:00
TLRPC . InputUser inputUser ;
if ( user instanceof TLRPC . TL_userForeign | | user instanceof TLRPC . TL_userRequest ) {
inputUser = new TLRPC . TL_inputUserForeign ( ) ;
inputUser . user_id = user . id ;
inputUser . access_hash = user . access_hash ;
} else {
inputUser = new TLRPC . TL_inputUserContact ( ) ;
inputUser . user_id = user . id ;
}
TLRPC . TL_messages_requestEncryption req2 = new TLRPC . TL_messages_requestEncryption ( ) ;
req2 . g_a = g_a ;
req2 . user_id = inputUser ;
req2 . random_id = ( int ) ( random . nextDouble ( ) * Integer . MAX_VALUE ) ;
ConnectionsManager . Instance . performRpc ( req2 , new RPCRequest . RPCRequestDelegate ( ) {
@Override
public void run ( final TLObject response , TLRPC . TL_error error ) {
if ( error = = null ) {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
2013-12-20 19:25:49 +00:00
if ( ! ( ( ActionBarActivity ) context ) . isFinishing ( ) ) {
2013-10-25 15:19:00 +00:00
progressDialog . dismiss ( ) ;
}
TLRPC . EncryptedChat chat = ( TLRPC . EncryptedChat ) response ;
chat . user_id = chat . participant_id ;
encryptedChats . put ( chat . id , chat ) ;
chat . a_or_b = salt ;
TLRPC . TL_dialog dialog = new TLRPC . TL_dialog ( ) ;
dialog . id = ( ( long ) chat . id ) < < 32 ;
dialog . unread_count = 0 ;
dialog . top_message = 0 ;
dialog . last_message_date = ConnectionsManager . Instance . getCurrentTime ( ) ;
dialogs_dict . put ( dialog . id , dialog ) ;
dialogs . add ( dialog ) ;
dialogsServerOnly . clear ( ) ;
Collections . sort ( dialogs , new Comparator < TLRPC . TL_dialog > ( ) {
@Override
public int compare ( TLRPC . TL_dialog tl_dialog , TLRPC . TL_dialog tl_dialog2 ) {
if ( tl_dialog . last_message_date = = tl_dialog2 . last_message_date ) {
return 0 ;
} else if ( tl_dialog . last_message_date < tl_dialog2 . last_message_date ) {
return 1 ;
} else {
return - 1 ;
}
}
} ) ;
for ( TLRPC . TL_dialog d : dialogs ) {
if ( ( int ) d . id ! = 0 ) {
dialogsServerOnly . add ( d ) ;
}
}
NotificationCenter . Instance . postNotificationName ( dialogsNeedReload ) ;
MessagesStorage . Instance . putEncryptedChat ( chat , user , dialog ) ;
NotificationCenter . Instance . postNotificationName ( encryptedChatCreated , chat ) ;
}
} ) ;
} else {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
2013-12-20 19:25:49 +00:00
if ( ! ( ( ActionBarActivity ) context ) . isFinishing ( ) ) {
2013-10-25 15:19:00 +00:00
progressDialog . dismiss ( ) ;
AlertDialog . Builder builder = new AlertDialog . Builder ( context ) ;
builder . setTitle ( context . getString ( R . string . AppName ) ) ;
builder . setMessage ( String . format ( context . getString ( R . string . CreateEncryptedChatOutdatedError ) , user . first_name , user . first_name ) ) ;
2013-11-04 12:31:01 +00:00
builder . setPositiveButton ( ApplicationLoader . applicationContext . getString ( R . string . OK ) , null ) ;
2013-10-25 15:19:00 +00:00
builder . show ( ) . setCanceledOnTouchOutside ( true ) ;
}
}
} ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric | RPCRequest . RPCRequestClassFailOnServerErrors ) ;
} else {
Utilities . RunOnUIThread ( new Runnable ( ) {
@Override
public void run ( ) {
2013-12-20 19:25:49 +00:00
if ( ! ( ( ActionBarActivity ) context ) . isFinishing ( ) ) {
2013-10-25 15:19:00 +00:00
progressDialog . dismiss ( ) ;
}
}
} ) ;
}
}
} , null , true , RPCRequest . RPCRequestClassGeneric | RPCRequest . RPCRequestClassFailOnServerErrors ) ;
}
}