diff --git a/TMessagesProj/config/debug/AndroidManifest.xml b/TMessagesProj/config/debug/AndroidManifest.xml index 15b76a337..015b83b61 100644 --- a/TMessagesProj/config/debug/AndroidManifest.xml +++ b/TMessagesProj/config/debug/AndroidManifest.xml @@ -43,8 +43,6 @@ - - diff --git a/TMessagesProj/config/release/AndroidManifest.xml b/TMessagesProj/config/release/AndroidManifest.xml index cd2b91fd7..dbddaaebb 100644 --- a/TMessagesProj/config/release/AndroidManifest.xml +++ b/TMessagesProj/config/release/AndroidManifest.xml @@ -43,8 +43,6 @@ - - diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index b2e98731d..7b88baab1 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -38,6 +38,7 @@ + + + + + + + + + + diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AppStartReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/AppStartReceiver.java new file mode 100644 index 000000000..d1048d029 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/AppStartReceiver.java @@ -0,0 +1,26 @@ +/* + * This is the source code of Telegram for Android v. 1.4.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.messenger; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.telegram.ui.ApplicationLoader; + +public class AppStartReceiver extends BroadcastReceiver { + public void onReceive(Context context, Intent intent) { + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + ApplicationLoader.startPushService(); + } + }); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/AwakeService.java b/TMessagesProj/src/main/java/org/telegram/messenger/AwakeService.java deleted file mode 100644 index b6843433b..000000000 --- a/TMessagesProj/src/main/java/org/telegram/messenger/AwakeService.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This is the source code of Telegram for Android v. 1.3.x. - * It is licensed under GNU GPL v. 2 or later. - * You should have received a copy of the license in this archive (see LICENSE). - * - * Copyright Nikolai Kudashov, 2013-2014. - */ - -package org.telegram.messenger; - -import android.app.Service; -import android.content.Intent; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; - -import org.telegram.ui.ApplicationLoader; - -public class AwakeService extends Service { - @Override - public IBinder onBind(Intent intent) { - return null; - } - - public static volatile int timeout = 10000; - public static boolean isStarted = false; - - private Handler handler = new Handler(Looper.getMainLooper()); - - @Override - public void onCreate() { - super.onCreate(); - FileLog.e("tmessages", "service started"); - check(); - isStarted = true; - } - - public static void startService() { - try { - if (ApplicationLoader.isScreenOn && ApplicationLoader.lastPauseTime == 0) { - return; - } - timeout = 10000; - if (!isStarted) { - ApplicationLoader.applicationContext.startService(new Intent(ApplicationLoader.applicationContext, AwakeService.class)); - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - - private void check() { - handler.postDelayed(new Runnable() { - @Override - public void run() { - ApplicationLoader.postInitApplication(); - timeout -= 1000; - if (timeout <= 0) { - stopSelf(); - isStarted = false; - FileLog.e("tmessages", "service stoped"); - } else { - check(); - } - } - }, 1000); - } -} diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionContext.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionContext.java index 4abe811f4..38bcba64e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionContext.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionContext.java @@ -40,6 +40,10 @@ public class ConnectionContext extends PyroClientAdapter { sessionId = isDebugSession ? (0xabcd000000000000L | (newSessionId & 0x0000ffffffffffffL)) : newSessionId; } + public void setSessionId(long id) { + sessionId = id; + } + public long getSissionId() { return sessionId; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index 1e3d8ede2..a5a14fff3 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -60,13 +60,15 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. private int updatingDcStartTime = 0; private int lastDcUpdateTime = 0; private int currentAppVersion = 0; + private long pushSessionId; + private boolean registeringForPush = false; private boolean paused = false; private Runnable stageRunnable; private Runnable pingRunnable; private long lastPingTime = System.currentTimeMillis(); - private int nextWakeUpTimeout = 60000; - private int nextSleepTimeout = 60000; + private long lastPushPingTime = System.currentTimeMillis(); + private int nextSleepTimeout = 30000; private static volatile ConnectionsManager Instance = null; public static ConnectionsManager getInstance() { @@ -99,6 +101,16 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { + if (datacenters != null) { + if (lastPushPingTime < System.currentTimeMillis() - 29000) { + lastPushPingTime = System.currentTimeMillis(); + Datacenter datacenter = datacenterWithId(currentDatacenterId); + if (datacenter != null) { + generatePing(datacenter, true); + } + } + } + long currentTime = System.currentTimeMillis(); if (ApplicationLoader.lastPauseTime != 0 && ApplicationLoader.lastPauseTime < currentTime - nextSleepTimeout) { boolean dontSleep = false; @@ -133,17 +145,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } try { paused = true; - if (ApplicationLoader.lastPauseTime < currentTime - nextSleepTimeout - nextWakeUpTimeout) { - ApplicationLoader.lastPauseTime = currentTime; - nextSleepTimeout = 30000; - FileLog.e("tmessages", "wakeup network in background by wakeup time = " + nextWakeUpTimeout); - if (nextWakeUpTimeout < 30 * 60 * 1000) { - nextWakeUpTimeout *= 2; - } - } else { - Thread.sleep(500); - return; - } + Thread.sleep(500); + return; } catch (Exception e) { FileLog.e("tmessages", e); } @@ -182,7 +185,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. public void run() { if (paused) { ApplicationLoader.lastPauseTime = System.currentTimeMillis(); - nextWakeUpTimeout = 60000; nextSleepTimeout = 30000; FileLog.e("tmessages", "wakeup network in background by recieved push"); } else if (ApplicationLoader.lastPauseTime != 0) { @@ -198,8 +200,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. @Override public void run() { if (paused) { - nextSleepTimeout = 60000; - nextWakeUpTimeout = 60000; + nextSleepTimeout = 30000; FileLog.e("tmessages", "reset timers by application moved to foreground"); } } @@ -279,6 +280,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. currentDatacenterId = preferences.getInt("currentDatacenterId", 0); timeDifference = preferences.getInt("timeDifference", 0); lastDcUpdateTime = preferences.getInt("lastDcUpdateTime", 0); + pushSessionId = preferences.getLong("pushSessionId", 0); + try { sessionsToDestroy.clear(); String sessionsString = preferences.getString("sessionsToDestroy", null); @@ -325,8 +328,13 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. fillDatacenters(); - if (datacenters.size() != 0 && currentDatacenterId == 0) { - currentDatacenterId = 1; + if (datacenters.size() != 0 && currentDatacenterId == 0 || pushSessionId == 0) { + if (pushSessionId == 0) { + pushSessionId = Utilities.random.nextLong(); + } + if (currentDatacenterId == 0) { + currentDatacenterId = 1; + } saveSession(); } movingToDatacenterId = DEFAULT_DATACENTER_ID; @@ -413,6 +421,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. editor.putInt("currentDatacenterId", currentDatacenterId); editor.putInt("timeDifference", timeDifference); editor.putInt("lastDcUpdateTime", lastDcUpdateTime); + editor.putLong("pushSessionId", pushSessionId); ArrayList sessions = new ArrayList(); if (currentDatacenter.connection != null) { @@ -592,6 +601,29 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. }); } + public void initPushConnection() { + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + Datacenter datacenter = datacenterWithId(currentDatacenterId); + if (datacenter != null) { + if (datacenter.pushConnection == null) { + datacenter.pushConnection = new TcpConnection(datacenter.datacenterId); + datacenter.pushConnection.setSessionId(pushSessionId); + datacenter.pushConnection.delegate = ConnectionsManager.this; + datacenter.pushConnection.transportRequestClass = RPCRequest.RPCRequestClassPush; + datacenter.pushConnection.connect(); + generatePing(datacenter, true); + } else { + if (UserConfig.clientActivated && !UserConfig.registeredForInternalPush) { + registerForPush(); + } + } + } + } + }); + } + public void applyCountryPortNumber(final String phone) { if (phone == null || phone.length() == 0) { return; @@ -1097,12 +1129,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. request.transportChannelToken = datacenterDownloadTransportToken; ArrayList arr = new ArrayList(); arr.add(networkMessage); - proceedToSendingMessages(arr, connection, false, false); + proceedToSendingMessages(arr, connection, false); } else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { request.transportChannelToken = datacenterUploadTransportToken; ArrayList arr = new ArrayList(); arr.add(networkMessage); - proceedToSendingMessages(arr, connection, false, false); + proceedToSendingMessages(arr, connection, false); } } } @@ -1299,11 +1331,11 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } else if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) { ArrayList arr = new ArrayList(); arr.add(networkMessage); - proceedToSendingMessages(arr, requestDatacenter.downloadConnection, false, false); + proceedToSendingMessages(arr, requestDatacenter.downloadConnection, false); } else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { ArrayList arr = new ArrayList(); arr.add(networkMessage); - proceedToSendingMessages(arr, requestDatacenter.uploadConnection, false, false); + proceedToSendingMessages(arr, requestDatacenter.uploadConnection, false); } else { FileLog.e("tmessages", "***** Error: request " + request.rawRequest + " has undefined session"); } @@ -1394,7 +1426,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. datacenter.connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric; } - proceedToSendingMessages(arr, datacenter.connection, hasSendMessage, arr.size() != 0); + proceedToSendingMessages(arr, datacenter.connection, hasSendMessage); } } @@ -1403,7 +1435,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. for (Datacenter datacenter : datacenters.values()) { ArrayList messagesIt = genericMessagesToDatacenters.get(datacenter.datacenterId); if (messagesIt == null || messagesIt.size() == 0) { - generatePing(datacenter); + generatePing(datacenter, false); } } } else { @@ -1485,7 +1517,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } } - void proceedToSendingMessages(ArrayList messageList, TcpConnection connection, boolean reportAck, boolean requestShortTimeout) { + void proceedToSendingMessages(ArrayList messageList, TcpConnection connection, boolean reportAck) { if (connection.getSissionId() == 0) { return; } @@ -1500,10 +1532,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. messages.add(message); } - sendMessagesToTransport(messages, connection, reportAck, requestShortTimeout); + sendMessagesToTransport(messages, connection, reportAck); } - void sendMessagesToTransport(ArrayList messagesToSend, TcpConnection connection, boolean reportAck, boolean requestShortTimeout) { + void sendMessagesToTransport(ArrayList messagesToSend, TcpConnection connection, boolean reportAck) { if (messagesToSend.size() == 0) { return; } @@ -1548,7 +1580,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } } - connection.sendData(null, transportData, reportAck, requestShortTimeout); + connection.sendData(null, transportData, reportAck); } else { FileLog.e("tmessages", "***** Transport data is nil"); } @@ -1750,6 +1782,67 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. }); } + private void registerForPush() { + if (registeringForPush) { + return; + } + UserConfig.registeredForInternalPush = false; + UserConfig.saveConfig(false); + registeringForPush = true; + TLRPC.TL_account_registerDevice req = new TLRPC.TL_account_registerDevice(); + req.token_type = 7; + req.token = "" + pushSessionId; + req.app_sandbox = false; + 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; + PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0); + req.app_version = pInfo.versionName; + if (req.app_version == null) { + req.app_version = "App version unknown"; + } + + } catch (Exception e) { + 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"; + } + + if (req.lang_code == null || req.lang_code.length() == 0) { + req.lang_code = "en"; + } + if (req.device_model == null || req.device_model.length() == 0) { + req.device_model = "Android unknown"; + } + if (req.app_version == null || req.app_version.length() == 0) { + req.app_version = "App version unknown"; + } + if (req.system_version == null || req.system_version.length() == 0) { + req.system_version = "SDK Unknown"; + } + + if (req.app_version != null) { + ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + UserConfig.registeredForInternalPush = true; + UserConfig.saveConfig(false); + saveSession(); + FileLog.e("tmessages", "registered for internal push"); + } + registeringForPush = false; + } + }, null, true, RPCRequest.RPCRequestClassGeneric); + } + } + void processMessage(TLObject message, long messageId, int messageSeqNo, long messageSalt, TcpConnection connection, long innerMsgId, long containerMessageId) { if (message == null) { FileLog.e("tmessages", "message is null"); @@ -1787,8 +1880,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. saveSession(); - if ((connection.transportRequestClass & RPCRequest.RPCRequestClassGeneric) != 0 && datacenter.datacenterId == currentDatacenterId && UserConfig.clientActivated) { - MessagesController.getInstance().getDifference(); + if (datacenter.datacenterId == currentDatacenterId && UserConfig.clientActivated) { + if ((connection.transportRequestClass & RPCRequest.RPCRequestClassGeneric) != 0) { + MessagesController.getInstance().getDifference(); + } else if ((connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) { + registerForPush(); + } } connection.addProcessedSession(newSession.unique_id); } @@ -1812,6 +1909,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. connection.addProcessedMessageId(innerMessageId); } } else if (message instanceof TLRPC.TL_pong) { + if (UserConfig.clientActivated && !UserConfig.registeredForInternalPush && (connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) { + registerForPush(); + } TLRPC.TL_pong pong = (TLRPC.TL_pong)message; long pingId = pong.ping_id; @@ -2168,7 +2268,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ArrayList arr = new ArrayList(); arr.add(networkMessage); - sendMessagesToTransport(arr, connection, false, true); + sendMessagesToTransport(arr, connection, false); } else { connection.addMessageToConfirm(detailedInfo.answer_msg_id); } @@ -2177,52 +2277,55 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. TLObject result = Utilities.decompress(packet.packed_data, getRequestWithMessageId(messageId)); processMessage(result, messageId, messageSeqNo, messageSalt, connection, innerMsgId, containerMessageId); } else if (message instanceof TLRPC.Updates) { - MessagesController.getInstance().processUpdates((TLRPC.Updates)message, false); + if ((connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) { + FileLog.e("tmessages", "received internal push"); + resumeNetworkMaybe(); + } else { + MessagesController.getInstance().processUpdates((TLRPC.Updates) message, false); + } } else { FileLog.e("tmessages", "***** Error: unknown message class " + message); } } void generatePing() { - for (Datacenter datacenter : datacenters.values()) { - if (datacenter.datacenterId == currentDatacenterId) { - generatePing(datacenter); - } + Datacenter datacenter = datacenterWithId(currentDatacenterId); + if (datacenter != null) { + generatePing(datacenter, false); } } static long nextPingId = 0; - ByteBufferDesc generatePingData(Datacenter datacenter, boolean recordTime) { - if (datacenter.connection == null) { - datacenter.connection = new TcpConnection(datacenter.datacenterId); - datacenter.connection.delegate = this; - datacenter.connection.transportRequestClass = RPCRequest.RPCRequestClassGeneric; + private ByteBufferDesc generatePingData(TcpConnection connection) { + if (connection == null) { + return null; } TLRPC.TL_ping_delay_disconnect ping = new TLRPC.TL_ping_delay_disconnect(); ping.ping_id = nextPingId++; ping.disconnect_delay = 35; - - if (recordTime) { - pingIdToDate.put(ping.ping_id, (int)(System.currentTimeMillis() / 1000)); - } + pingIdToDate.put(ping.ping_id, (int)(System.currentTimeMillis() / 1000)); NetworkMessage networkMessage = new NetworkMessage(); - networkMessage.protoMessage = wrapMessage(ping, datacenter.connection, false); + networkMessage.protoMessage = wrapMessage(ping, connection, false); ArrayList arr = new ArrayList(); arr.add(networkMessage); - return createConnectionData(arr, null, datacenter.connection); + return createConnectionData(arr, null, connection); } - void generatePing(Datacenter datacenter) { - if (datacenter.connection == null || datacenter.connection.channelToken == 0) { - return; + void generatePing(Datacenter datacenter, boolean push) { + TcpConnection connection = null; + if (push) { + connection = datacenter.pushConnection; + } else { + connection = datacenter.connection; } - - ByteBufferDesc transportData = generatePingData(datacenter, true); - if (transportData != null) { - datacenter.connection.sendData(null, transportData, false, true); + if (connection != null && (push || !push && connection.channelToken != 0)) { + ByteBufferDesc transportData = generatePingData(connection); + if (transportData != null) { + connection.sendData(null, transportData, false); + } } } @@ -2539,9 +2642,18 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } else { processMessage(message, messageId, messageSeqNo, messageServerSalt, connection, 0, 0); connection.addProcessedMessageId(messageId); + + if ((connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) { + ArrayList messages = new ArrayList(); + NetworkMessage networkMessage = connection.generateConfirmationRequest(); + if (networkMessage != null) { + messages.add(networkMessage); + } + sendMessagesToTransport(messages, connection, false); + } } } else { - proceedToSendingMessages(null, connection, false, false); + proceedToSendingMessages(null, connection, false); } finishUpdatingState(connection); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java b/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java index c89440e8c..f13560ba1 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Datacenter.java @@ -37,6 +37,7 @@ public class Datacenter { public TcpConnection connection; public TcpConnection downloadConnection; public TcpConnection uploadConnection; + public TcpConnection pushConnection; private ArrayList authServerSaltSet = new ArrayList(); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java index 0ac99fa3b..39858fb41 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java @@ -49,8 +49,6 @@ public class GcmBroadcastReceiver extends BroadcastReceiver { } } - AwakeService.startService(); - Utilities.RunOnUIThread(new Runnable() { @Override public void run() { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java index 25a926141..0abc8340a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/HandshakeAction.java @@ -179,7 +179,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti byte[] transportData = messageOs.toByteArray(); - datacenter.connection.sendData(transportData, null, false, false); + datacenter.connection.sendData(transportData, null, false); return transportData; } @@ -576,11 +576,11 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti return; } if (reqPQMsgData != null) { - datacenter.connection.sendData(reqPQMsgData, null, false, false); + datacenter.connection.sendData(reqPQMsgData, null, false); } else if (reqDHMsgData != null) { - datacenter.connection.sendData(reqDHMsgData, null, false, false); + datacenter.connection.sendData(reqDHMsgData, null, false); } else if (setClientDHParamsMsgData != null) { - datacenter.connection.sendData(setClientDHParamsMsgData, null, false, false); + datacenter.connection.sendData(setClientDHParamsMsgData, null, false); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index 4109374aa..2c07ba8de 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -60,6 +60,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter public SparseArray dialogMessage = new SparseArray(); public ConcurrentHashMap> printingUsers = new ConcurrentHashMap>(100, 1.0f, 2); public HashMap printingStrings = new HashMap(); + private int lastPrintingStringCount = 0; private HashMap> delayedMessages = new HashMap>(); public SparseArray sendingMessages = new SparseArray(); @@ -291,6 +292,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter printingUsers.clear(); printingStrings.clear(); totalDialogsCount = 0; + lastPrintingStringCount = 0; hidenAddToContacts.clear(); updatesQueue.clear(); pendingEncMessagesToDelete.clear(); @@ -821,7 +823,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else { scheduleContactsReload = 0; } - if (!printingUsers.isEmpty()) { + if (!printingUsers.isEmpty() || lastPrintingStringCount != printingUsers.size()) { boolean updated = false; ArrayList keys = new ArrayList(printingUsers.keySet()); for (int b = 0; b < keys.size(); b++) { @@ -893,6 +895,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } + lastPrintingStringCount = newPrintingStrings.size(); + Utilities.RunOnUIThread(new Runnable() { @Override public void run() { @@ -3667,7 +3671,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter final ArrayList markAsReadMessages = new ArrayList(); final HashMap markAsReadEncrypted = new HashMap(); final ArrayList deletedMessages = new ArrayList(); - final ArrayList printChanges = new ArrayList(); + boolean printChanged = false; final ArrayList chatInfoToUpdate = new ArrayList(); final ArrayList updatesOnMainThread = new ArrayList(); final ArrayList tasks = new ArrayList(); @@ -3789,9 +3793,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter newUser.userId = update.user_id; newUser.lastTime = currentTime; arr.add(newUser); - if (!printChanges.contains(uid)) { - printChanges.add(uid); - } + printChanged = true; } } } else if (update instanceof TLRPC.TL_updateChatParticipants) { @@ -3959,9 +3961,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter newUser.userId = update.user_id; newUser.lastTime = currentTime; arr.add(newUser); - if (!printChanges.contains(uid)) { - printChanges.add(uid); - } + printChanged = true; } } else if (update instanceof TLRPC.TL_updateEncryptedMessagesRead) { markAsReadEncrypted.put(update.chat_id, Math.max(update.max_date, update.date)); @@ -4067,19 +4067,19 @@ public class MessagesController implements NotificationCenter.NotificationCenter for (HashMap.Entry> pair : messages.entrySet()) { Long key = pair.getKey(); ArrayList value = pair.getValue(); - boolean printChanged = updatePrintingUsersWithNewMessages(key, value); - if (printChanged && !printChanges.contains(key)) { - printChanges.add(key); + if (updatePrintingUsersWithNewMessages(key, value)) { + printChanged = true; } } } - if (!printChanges.isEmpty()) { + if (printChanged) { updatePrintingStrings(); } final MessageObject lastMessageArg = lastMessage; final int interfaceUpdateMaskFinal = interfaceUpdateMask; + final boolean printChangedArg = printChanged; processPendingEncMessages(); @@ -4091,7 +4091,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.getInstance().putMessages(messagesArr, true, true); } - if (!messages.isEmpty() || !markAsReadMessages.isEmpty() || !deletedMessages.isEmpty() || !printChanges.isEmpty() || !chatInfoToUpdate.isEmpty() || !updatesOnMainThread.isEmpty() || !markAsReadEncrypted.isEmpty() || !contactsIds.isEmpty()) { + if (!messages.isEmpty() || !markAsReadMessages.isEmpty() || !deletedMessages.isEmpty() || printChanged || !chatInfoToUpdate.isEmpty() || !updatesOnMainThread.isEmpty() || !markAsReadEncrypted.isEmpty() || !contactsIds.isEmpty()) { Utilities.RunOnUIThread(new Runnable() { @Override public void run() { @@ -4179,7 +4179,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } } - if (!printChanges.isEmpty()) { + if (printChangedArg) { updateMask |= UPDATE_MASK_USER_PRINT; } if (!contactsIds.isEmpty()) { @@ -4508,15 +4508,18 @@ public class MessagesController implements NotificationCenter.NotificationCenter needVibrate = false; } + String name = Utilities.formatName(user.first_name, user.last_name); + String msgShort = msg.replace(name + ": ", "").replace(name + " ", ""); + intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE); intent.setFlags(32768); PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, PendingIntent.FLAG_ONE_SHOT); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ApplicationLoader.applicationContext) - .setContentTitle(LocaleController.getString("AppName", R.string.AppName)) + .setContentTitle(name) .setSmallIcon(R.drawable.notification) - .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) - .setContentText(msg) + .setStyle(new NotificationCompat.BigTextStyle().bigText(msgShort)) + .setContentText(msgShort) .setAutoCancel(true) .setTicker(msg); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsService.java b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsService.java new file mode 100644 index 000000000..0b8e145db --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsService.java @@ -0,0 +1,45 @@ +/* + * This is the source code of Telegram for Android v. 1.3.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.messenger; + +import android.app.Service; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.IBinder; + +import org.telegram.ui.ApplicationLoader; + +public class NotificationsService extends Service { + + @Override + public void onCreate() { + FileLog.e("tmessages", "service started"); + ApplicationLoader.postInitApplication(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + public void onDestroy() { + FileLog.e("tmessages", "service destroyed"); + + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", MODE_PRIVATE); + if (preferences.getBoolean("pushService", true)) { + Intent intent = new Intent("org.telegram.start"); + sendBroadcast(intent); + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java index c6f93e5f5..e444d9837 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java @@ -27,6 +27,7 @@ public class RPCRequest { public static int RPCRequestClassEnableUnauthorized = 8; public static int RPCRequestClassFailOnServerErrors = 16; public static int RPCRequestClassCanCompress = 32; + public static int RPCRequestClassPush = 64; static int RPCRequestClassTransportMask = (RPCRequestClassGeneric | RPCRequestClassDownloadMedia | RPCRequestClassUploadMedia); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java index 96c3f3c2e..170021ee4 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java @@ -127,10 +127,18 @@ public class TcpConnection extends ConnectionContext { } client = selector.connect(new InetSocketAddress(hostAddress, hostPort)); client.addListener(TcpConnection.this); - if (isNextPort) { - client.setTimeout(8000); + if ((transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) { + if (isNextPort) { + client.setTimeout(15000); + } else { + client.setTimeout(30000); + } } else { - client.setTimeout(15000); + if (isNextPort) { + client.setTimeout(8000); + } else { + client.setTimeout(15000); + } } selector.wakeup(); } catch (Exception e) { @@ -270,7 +278,7 @@ public class TcpConnection extends ConnectionContext { connect(); } - public void sendData(final byte[] data, final ByteBufferDesc buff, final boolean reportAck, final boolean startResponseTimeout) { + public void sendData(final byte[] data, final ByteBufferDesc buff, final boolean reportAck) { if (data == null && buff == null) { return; } @@ -408,7 +416,11 @@ public class TcpConnection extends ConnectionContext { Datacenter datacenter = ConnectionsManager.getInstance().datacenterWithId(datacenterId); datacenter.storeCurrentAddressAndPortNum(); isNextPort = false; - client.setTimeout(25000); + if ((transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) { + client.setTimeout(40000); + } else { + client.setTimeout(25000); + } } hasSomeDataSinceLastConnect = true; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index 6e0ddedc6..6bdf8d0d3 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -21,6 +21,7 @@ public class UserConfig { public static int clientUserId = 0; public static boolean clientActivated = false; public static boolean registeredForPush = false; + public static boolean registeredForInternalPush = false; public static String pushString = ""; public static int lastSendMessageId = -210000; public static int lastLocalId = -210000; @@ -56,6 +57,7 @@ public class UserConfig { editor.putString("importHash", importHash); editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos); editor.putInt("contactsVersion", contactsVersion); + editor.putBoolean("registeredForInternalPush", registeredForInternalPush); if (currentUser != null) { if (withFile) { SerializedData data = new SerializedData(); @@ -155,6 +157,7 @@ public class UserConfig { importHash = preferences.getString("importHash", ""); saveIncomingPhotos = preferences.getBoolean("saveIncomingPhotos", false); contactsVersion = preferences.getInt("contactsVersion", 0); + registeredForInternalPush = preferences.getBoolean("registeredForInternalPush", false); String user = preferences.getString("user", null); if (user != null) { byte[] userBytes = Base64.decode(user, Base64.DEFAULT); @@ -177,6 +180,7 @@ public class UserConfig { clientUserId = 0; clientActivated = false; currentUser = null; + registeredForInternalPush = false; registeredForPush = false; contactsHash = ""; importHash = ""; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java index 3c392a698..ea68c1ad5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java @@ -9,7 +9,9 @@ package org.telegram.ui; import android.app.Activity; +import android.app.AlarmManager; import android.app.Application; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -28,6 +30,7 @@ import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.gcm.GoogleCloudMessaging; +import org.telegram.messenger.NotificationsService; import org.telegram.messenger.BuildVars; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; @@ -41,6 +44,7 @@ import org.telegram.ui.Views.BaseFragment; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Calendar; import java.util.concurrent.atomic.AtomicInteger; public class ApplicationLoader extends Application { @@ -125,10 +129,12 @@ public class ApplicationLoader extends Application { MessagesController.getInstance().users.put(UserConfig.clientUserId, UserConfig.currentUser); ConnectionsManager.getInstance().applyCountryPortNumber(UserConfig.currentUser.phone); + ConnectionsManager.getInstance().initPushConnection(); } ApplicationLoader app = (ApplicationLoader)ApplicationLoader.applicationContext; app.initPlayServices(); + FileLog.e("tmessages", "app initied"); } @Override @@ -152,6 +158,31 @@ public class ApplicationLoader extends Application { } catch (Exception e) { e.printStackTrace(); } + + startPushService(); + } + + public static void startPushService() { + SharedPreferences preferences = applicationContext.getSharedPreferences("Notifications", MODE_PRIVATE); + + if (preferences.getBoolean("pushService", true)) { + applicationContext.startService(new Intent(applicationContext, NotificationsService.class)); + + Calendar cal = Calendar.getInstance(); + PendingIntent pintent = PendingIntent.getService(applicationContext, 0, new Intent(applicationContext, NotificationsService.class), 0); + AlarmManager alarm = (AlarmManager) applicationContext.getSystemService(Context.ALARM_SERVICE); + alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30000, pintent); + } else { + stopPushService(); + } + } + + public static void stopPushService() { + applicationContext.stopService(new Intent(applicationContext, NotificationsService.class)); + + PendingIntent pintent = PendingIntent.getService(applicationContext, 0, new Intent(applicationContext, NotificationsService.class), 0); + AlarmManager alarm = (AlarmManager)applicationContext.getSystemService(Context.ALARM_SERVICE); + alarm.cancel(pintent); } @Override diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java index 5a9485489..1f234b4af 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java @@ -158,6 +158,7 @@ public class LoginActivityRegisterView extends SlideView { if (delegate != null) { delegate.needFinishActivity(); } + ConnectionsManager.getInstance().initPushConnection(); } }); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java index e7f4e2845..cfee4afb3 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java @@ -241,6 +241,7 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente if (delegate != null) { delegate.needFinishActivity(); } + ConnectionsManager.getInstance().initPushConnection(); } }); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java index a64a9d85c..5e27e8986 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java @@ -9,7 +9,9 @@ package org.telegram.ui; import android.app.Activity; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.media.Ringtone; @@ -46,6 +48,7 @@ public class SettingsNotificationsActivity extends BaseFragment { private ListView listView; private boolean reseting = false; + private int notificationsServiceRow; private int messageSectionRow; private int messageAlertRow; private int messagePreviewRow; @@ -70,6 +73,7 @@ public class SettingsNotificationsActivity extends BaseFragment { @Override public boolean onFragmentCreate() { + notificationsServiceRow = rowCount++; messageSectionRow = rowCount++; messageAlertRow = rowCount++; messagePreviewRow = rowCount++; @@ -260,6 +264,32 @@ public class SettingsNotificationsActivity extends BaseFragment { editor.putBoolean("EnablePebbleNotifications", !enabled); editor.commit(); listView.invalidateViews(); + } else if (i == notificationsServiceRow) { + final SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + boolean enabled = preferences.getBoolean("pushService", true); + if (!enabled) { + final SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("pushService", !enabled); + editor.commit(); + listView.invalidateViews(); + ApplicationLoader.startPushService(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); + builder.setMessage(LocaleController.getString("NotificationsServiceDisableInfo", R.string.NotificationsServiceDisableInfo)); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ApplicationLoader.stopPushService(); + final SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("pushService", false); + editor.commit(); + listView.invalidateViews(); + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + builder.show().setCanceledOnTouchOutside(true); + } } } }); @@ -492,6 +522,10 @@ public class SettingsNotificationsActivity extends BaseFragment { enabled = preferences.getBoolean("EnablePebbleNotifications", false); textView.setText(LocaleController.getString("Alert", R.string.Alert)); divider.setVisibility(View.INVISIBLE); + } else if (i == notificationsServiceRow) { + enabled = preferences.getBoolean("pushService", true); + textView.setText(LocaleController.getString("NotificationsService", R.string.NotificationsService)); + divider.setVisibility(View.INVISIBLE); } if (enabled) { checkButton.setImageResource(R.drawable.btn_check_on); @@ -542,7 +576,7 @@ public class SettingsNotificationsActivity extends BaseFragment { i == groupAlertRow || i == groupPreviewRow || i == groupVibrateRow || i == inappSoundRow || i == inappVibrateRow || i == inappPreviewRow || i == contactJoinedRow || - i == pebbleAlertRow) { + i == pebbleAlertRow || i == notificationsServiceRow) { return 1; } else { return 2; diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index ab7a6bb71..d7c463859 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -265,6 +265,8 @@ Incorrect localization file Enabled Disabled + Notifications Service + If google play services are enough for you to receive notifications, you can disable Notifications Service. However we recommend you to leave it enabled to keep app running in background and receive instant notifications. لا توجد وسائط بعد diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index b5cd0316c..18cfea7ca 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -265,6 +265,8 @@ Falsche Sprachdatei Enabled Disabled + Notifications Service + If google play services are enough for you to receive notifications, you can disable Notifications Service. However we recommend you to leave it enabled to keep app running in background and receive instant notifications. Noch keine geteilten Medien vorhanden diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index 4c1b7b73f..79b4ee648 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -265,6 +265,8 @@ Fichero de localización incorrecto Enabled Disabled + Notifications Service + If google play services are enough for you to receive notifications, you can disable Notifications Service. However we recommend you to leave it enabled to keep app running in background and receive instant notifications. No hay fotos ni vídeos compartidos aún diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 07ddcd9ac..32022a3d9 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -265,6 +265,8 @@ File della localizzazione non valido Enabled Disabled + Notifications Service + If google play services are enough for you to receive notifications, you can disable Notifications Service. However we recommend you to leave it enabled to keep app running in background and receive instant notifications. Nessun media condiviso diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index 07f55c4ce..25b48141b 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -265,6 +265,8 @@ Ongeldig vertalingsbestand Enabled Disabled + Notifications Service + If google play services are enough for you to receive notifications, you can disable Notifications Service. However we recommend you to leave it enabled to keep app running in background and receive instant notifications. Nog geen media gedeeld diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index ff37b3af8..9dcb4b3a8 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -265,6 +265,8 @@ Incorrect localization file Enabled Disabled + Notifications Service + If google play services are enough for you to receive notifications, you can disable Notifications Service. However we recommend you to leave it enabled to keep app running in background and receive instant notifications. No shared media yet