Example usage for java.util.concurrent Semaphore acquire

List of usage examples for java.util.concurrent Semaphore acquire

Introduction

In this page you can find the example usage for java.util.concurrent Semaphore acquire.

Prototype

public void acquire() throws InterruptedException 

Source Link

Document

Acquires a permit from this semaphore, blocking until one is available, or the thread is Thread#interrupt interrupted .

Usage

From source file:org.telegram.ui.ProfileActivity.java

@Override
public boolean onFragmentCreate() {
    user_id = arguments.getInt("user_id", 0);
    chat_id = getArguments().getInt("chat_id", 0);
    if (user_id != 0) {
        dialog_id = arguments.getLong("dialog_id", 0);
        if (dialog_id != 0) {
            currentEncryptedChat = MessagesController.getInstance().getEncryptedChat((int) (dialog_id >> 32));
        }/* w  w w . j a  va  2 s  .  com*/
        TLRPC.User user = MessagesController.getInstance().getUser(user_id);
        if (user == null) {
            return false;
        }
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces);
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded);
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatCreated);
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatUpdated);
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.blockedUsersDidLoaded);
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.botInfoDidLoaded);
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.userInfoDidLoaded);
        if (currentEncryptedChat != null) {
            NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReceivedNewMessages);
        }
        userBlocked = MessagesController.getInstance().blockedUsers.contains(user_id);
        if (user.bot) {
            BotQuery.loadBotInfo(user.id, true, classGuid);
        }
        MessagesController.getInstance().loadFullUser(MessagesController.getInstance().getUser(user_id),
                classGuid, true);
        participantsMap = null;
    } else if (chat_id != 0) {
        currentChat = MessagesController.getInstance().getChat(chat_id);
        if (currentChat == null) {
            final Semaphore semaphore = new Semaphore(0);
            MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
                @Override
                public void run() {
                    currentChat = MessagesStorage.getInstance().getChat(chat_id);
                    semaphore.release();
                }
            });
            try {
                semaphore.acquire();
            } catch (Exception e) {
                FileLog.e("tmessages", e);
            }
            if (currentChat != null) {
                MessagesController.getInstance().putChat(currentChat, true);
            } else {
                return false;
            }
        }

        if (currentChat.megagroup) {
            getChannelParticipants(true);
        } else {
            participantsMap = null;
        }
        NotificationCenter.getInstance().addObserver(this, NotificationCenter.chatInfoDidLoaded);

        sortedUsers = new ArrayList<>();
        updateOnlineCount();

        avatarUpdater = new AvatarUpdater();
        avatarUpdater.delegate = new AvatarUpdater.AvatarUpdaterDelegate() {
            @Override
            public void didUploadedPhoto(TLRPC.InputFile file, TLRPC.PhotoSize small, TLRPC.PhotoSize big) {
                if (chat_id != 0) {
                    MessagesController.getInstance().changeChatAvatar(chat_id, file);
                }
            }
        };
        avatarUpdater.parentFragment = this;

        if (ChatObject.isChannel(currentChat)) {
            MessagesController.getInstance().loadFullChat(chat_id, classGuid, true);
        }
    } else {
        return false;
    }

    if (dialog_id != 0) {
        SharedMediaQuery.getMediaCount(dialog_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true);
    } else if (user_id != 0) {
        SharedMediaQuery.getMediaCount(user_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true);
    } else if (chat_id > 0) {
        SharedMediaQuery.getMediaCount(-chat_id, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true);
        if (mergeDialogId != 0) {
            SharedMediaQuery.getMediaCount(mergeDialogId, SharedMediaQuery.MEDIA_PHOTOVIDEO, classGuid, true);
        }
    }

    NotificationCenter.getInstance().addObserver(this, NotificationCenter.mediaCountDidLoaded);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeChats);
    updateRowsIds();

    return true;
}

From source file:fur.shadowdrake.minecraft.InstallPanel.java

@SuppressWarnings({ "Convert2Lambda" })
private boolean downloadFile(String filename, String local) throws NetworkException {
    final Semaphore semaphore = new Semaphore(0);
    success = false;//from  www  .  j av a 2  s .  c om
    while (true) {
        result = ftpClient.openDataChannel(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getID() == FtpClient.FTP_OK) {
                    try {
                        InputStream is;
                        FileOutputStream fos;

                        is = ((Socket) e.getSource()).getInputStream();
                        fos = new FileOutputStream(new File(workingDir, local));
                        byte[] buffer = new byte[4096];
                        for (int n = is.read(buffer); n > 0; n = is.read(buffer)) {
                            fos.write(buffer, 0, n);
                            log.advance(n);
                        }
                        fos.close();
                        success = true;
                    } catch (IOException ex) {
                        Logger.getLogger(InstallPanel.class.getName()).log(Level.SEVERE, "Download", ex);
                        log.println("Faild to save file.");
                        success = false;
                    }
                }
            }
        });
        switch (result) {
        case FtpClient.FTP_OK:
            int size = ftpClient.retr(filename, (ActionEvent e) -> {
                ftpClient.closeDataChannel();
                semaphore.release();
            });
            if (size < 0) {
                ftpClient.abandonDataChannel();
            } else {
                log.reset();
                log.setMaximum(size);
            }
            try {
                semaphore.acquire();
            } catch (InterruptedException ex) {
                return false;
            }
            break;
        case FtpClient.FTP_TIMEOUT:
            if (reconnect()) {
                continue;
            } else {
                ftpClient.abandonDataChannel();
                return false;
            }
        default:
            ftpClient.abandonDataChannel();
            return false;
        }
        break;
    }
    return success;
}

From source file:functionaltests.RestSmartProxyTest.java

@Test(timeout = TEN_MINUTES)
public void testInErrorEventsReception() throws Exception {
    TaskFlowJob job = createInErrorJob();

    final Semaphore semaphore = new Semaphore(0);
    printJobXmlRepresentation(job);//from  www. j a va  2s  .  co  m

    final MutableBoolean taskHasBeenInError = new MutableBoolean(false);
    final MutableBoolean restartedFromErrorEventReceived = new MutableBoolean(false);

    SchedulerEventListenerExtended listener = new SchedulerEventListenerExtended() {

        @Override
        public void schedulerStateUpdatedEvent(SchedulerEvent eventType) {
            System.out.println("RestSmartProxyTest.schedulerStateUpdatedEvent " + eventType);
        }

        @Override
        public void jobSubmittedEvent(JobState job) {
            System.out.println("RestSmartProxyTest.jobSubmittedEvent");
        }

        @Override
        public void jobStateUpdatedEvent(NotificationData<JobInfo> notification) {
            JobStatus status = notification.getData().getStatus();

            System.out.println("RestSmartProxyTest.jobStateUpdatedEvent, eventType="
                    + notification.getEventType() + ", jobStatus=" + status);

            if (notification.getEventType() == SchedulerEvent.JOB_RESTARTED_FROM_ERROR) {
                restartedFromErrorEventReceived.setTrue();
            }

            if (status == JobStatus.IN_ERROR) {
                semaphore.release();
            }
        }

        @Override
        public void taskStateUpdatedEvent(NotificationData<TaskInfo> notification) {
            TaskStatus status = notification.getData().getStatus();
            System.out.println("RestSmartProxyTest.taskStateUpdatedEvent, taskStatus=" + status);

            if (status == TaskStatus.WAITING_ON_ERROR || status == TaskStatus.IN_ERROR) { // IN_ERROR previously
                taskHasBeenInError.setTrue();
            }
        }

        @Override
        public void usersUpdatedEvent(NotificationData<UserIdentification> notification) {
            System.out.println("RestSmartProxyTest.usersUpdatedEvent " + notification.getData());
        }

        @Override
        public void pullDataFinished(String jobId, String taskName, String localFolderPath) {
            System.out.println("RestSmartProxyTest.pullDataFinished");
        }

        @Override
        public void pullDataFailed(String jobId, String taskName, String remoteFolder_URL, Throwable t) {
            System.out.println("RestSmartProxyTest.pullDataFailed");
        }

        @Override
        public void jobUpdatedFullDataEvent(JobState job) {
            System.out.println("RestSmartProxyTest.jobUpdatedFullDataEvent");

        }
    };

    restSmartProxy.addEventListener(listener);

    JobId jobId = restSmartProxy.submit(job, inputLocalFolder.getAbsolutePath(), pushUrl,
            outputLocalFolder.getAbsolutePath(), pullUrl, false, false);

    // the next line blocks until jobStateUpdatedEvent is called on the
    // listener
    // with job status set to IN_ERROR
    semaphore.acquire();

    String jobIdAsString = jobId.value();

    System.out.println("Restarting all In-Error tasks");
    restSmartProxy.restartAllInErrorTasks(jobIdAsString);

    assertThat(restartedFromErrorEventReceived.booleanValue()).isTrue();
    assertThat(taskHasBeenInError.booleanValue()).isTrue();

}

From source file:org.apache.hadoop.hive.metastore.txn.TxnHandler.java

@Override
public LockHandle acquireLock(String key) throws MetaException {
    /**/*from  w  w  w  .  ja va  2s.  co  m*/
     * The implementation here is a bit kludgey but done so that code exercised by unit tests
     * (which run against Derby which has no support for select for update) is as similar to
     * production code as possible.
     * In particular, with Derby we always run in a single process with a single metastore and
     * the absence of For Update is handled via a Semaphore.  The later would strictly speaking
     * make the SQL statements below unnecessary (for Derby), but then they would not be tested.
     */
    Connection dbConn = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
        try {
            String sqlStmt = sqlGenerator.addForUpdateClause(
                    "select MT_COMMENT from AUX_TABLE where MT_KEY1=" + quoteString(key) + " and MT_KEY2=0");
            lockInternal();
            dbConn = getDbConn(Connection.TRANSACTION_READ_COMMITTED, connPoolMutex);
            stmt = dbConn.createStatement();
            if (LOG.isDebugEnabled()) {
                LOG.debug("About to execute SQL: " + sqlStmt);
            }
            rs = stmt.executeQuery(sqlStmt);
            if (!rs.next()) {
                close(rs);
                try {
                    stmt.executeUpdate(
                            "insert into AUX_TABLE(MT_KEY1,MT_KEY2) values(" + quoteString(key) + ", 0)");
                    dbConn.commit();
                } catch (SQLException ex) {
                    if (!isDuplicateKeyError(ex)) {
                        throw new RuntimeException(
                                "Unable to lock " + quoteString(key) + " due to: " + getMessage(ex), ex);
                    }
                    //if here, it means a concrurrent acquireLock() inserted the 'key'

                    //rollback is done for the benefit of Postgres which throws (SQLState=25P02, ErrorCode=0) if
                    //you attempt any stmt in a txn which had an error.
                    dbConn.rollback();
                }
                rs = stmt.executeQuery(sqlStmt);
                if (!rs.next()) {
                    throw new IllegalStateException(
                            "Unable to lock " + quoteString(key) + ".  Expected row in AUX_TABLE is missing.");
                }
            }
            Semaphore derbySemaphore = null;
            if (dbProduct == DatabaseProduct.DERBY) {
                derbyKey2Lock.putIfAbsent(key, new Semaphore(1));
                derbySemaphore = derbyKey2Lock.get(key);
                derbySemaphore.acquire();
            }
            LOG.debug(quoteString(key) + " locked by " + quoteString(TxnHandler.hostname));
            //OK, so now we have a lock
            return new LockHandleImpl(dbConn, stmt, rs, key, derbySemaphore);
        } catch (SQLException ex) {
            rollbackDBConn(dbConn);
            close(rs, stmt, dbConn);
            checkRetryable(dbConn, ex, "acquireLock(" + key + ")");
            throw new MetaException("Unable to lock " + quoteString(key) + " due to: " + getMessage(ex) + "; "
                    + StringUtils.stringifyException(ex));
        } catch (InterruptedException ex) {
            rollbackDBConn(dbConn);
            close(rs, stmt, dbConn);
            throw new MetaException("Unable to lock " + quoteString(key) + " due to: " + ex.getMessage()
                    + StringUtils.stringifyException(ex));
        } finally {
            unlockInternal();
        }
    } catch (RetryException ex) {
        return acquireLock(key);
    }
}

From source file:org.telepatch.ui.ChatActivity.java

@Override
public boolean onFragmentCreate() {
    final int chatId = arguments.getInt("chat_id", 0);
    final int userId = arguments.getInt("user_id", 0);
    final int encId = arguments.getInt("enc_id", 0);
    scrollToTopOnResume = arguments.getBoolean("scrollToTopOnResume", false);

    if (chatId != 0) {
        currentChat = MessagesController.getInstance().getChat(chatId);
        if (currentChat == null) {
            final Semaphore semaphore = new Semaphore(0);
            MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
                @Override/*from   w w  w.ja  va 2s. c  o m*/
                public void run() {
                    currentChat = MessagesStorage.getInstance().getChat(chatId);
                    semaphore.release();
                }
            });
            try {
                semaphore.acquire();
            } catch (Exception e) {
                FileLog.e("tmessages", e);
            }
            if (currentChat != null) {
                MessagesController.getInstance().putChat(currentChat, true);
            } else {
                return false;
            }
        }
        if (chatId > 0) {
            dialog_id = -chatId;
        } else {
            isBroadcast = true;
            dialog_id = AndroidUtilities.makeBroadcastId(chatId);
        }
        Semaphore semaphore = null;
        if (isBroadcast) {
            semaphore = new Semaphore(0);
        }
        MessagesController.getInstance().loadChatInfo(currentChat.id, semaphore);
        if (isBroadcast) {
            try {
                semaphore.acquire();
            } catch (Exception e) {
                FileLog.e("tmessages", e);
            }
        }
    } else if (userId != 0) {
        currentUser = MessagesController.getInstance().getUser(userId);
        if (currentUser == null) {
            final Semaphore semaphore = new Semaphore(0);
            MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
                @Override
                public void run() {
                    currentUser = MessagesStorage.getInstance().getUser(userId);
                    semaphore.release();
                }
            });
            try {
                semaphore.acquire();
            } catch (Exception e) {
                FileLog.e("tmessages", e);
            }
            if (currentUser != null) {
                MessagesController.getInstance().putUser(currentUser, true);
            } else {
                return false;
            }
        }
        dialog_id = userId;
    } else if (encId != 0) {
        currentEncryptedChat = MessagesController.getInstance().getEncryptedChat(encId);
        if (currentEncryptedChat == null) {
            final Semaphore semaphore = new Semaphore(0);
            MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
                @Override
                public void run() {
                    currentEncryptedChat = MessagesStorage.getInstance().getEncryptedChat(encId);
                    semaphore.release();
                }
            });
            try {
                semaphore.acquire();
            } catch (Exception e) {
                FileLog.e("tmessages", e);
            }
            if (currentEncryptedChat != null) {
                MessagesController.getInstance().putEncryptedChat(currentEncryptedChat, true);
            } else {
                return false;
            }
        }
        currentUser = MessagesController.getInstance().getUser(currentEncryptedChat.user_id);
        if (currentUser == null) {
            final Semaphore semaphore = new Semaphore(0);
            MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() {
                @Override
                public void run() {
                    currentUser = MessagesStorage.getInstance().getUser(currentEncryptedChat.user_id);
                    semaphore.release();
                }
            });
            try {
                semaphore.acquire();
            } catch (Exception e) {
                FileLog.e("tmessages", e);
            }
            if (currentUser != null) {
                MessagesController.getInstance().putUser(currentUser, true);
            } else {
                return false;
            }
        }
        dialog_id = ((long) encId) << 32;
        maxMessageId = Integer.MIN_VALUE;
        minMessageId = Integer.MAX_VALUE;
        MediaController.getInstance().startMediaObserver();
    } else {
        return false;
    }

    //TODO qui elimino la notifica una volta entrato nella chat
    if (preferences.getBoolean("multiple_notify", true)) {
        nm.cancel((int) dialog_id);
    } else {
        nm.cancel(1);
    }

    chatActivityEnterView = new ChatActivityEnterView();
    chatActivityEnterView.setDialogId(dialog_id);
    chatActivityEnterView.setDelegate(new ChatActivityEnterView.ChatActivityEnterViewDelegate() {
        @Override
        public void onMessageSend() {
            chatListView.post(new Runnable() {
                @Override
                public void run() {
                    chatListView.setSelectionFromTop(messages.size() - 1,
                            -100000 - chatListView.getPaddingTop());
                }
            });
        }

        @Override
        public void needSendTyping() {
            MessagesController.getInstance().sendTyping(dialog_id, classGuid);
        }
    });
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesDidLoaded);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.emojiDidLoaded);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.updateInterfaces);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReceivedNewMessages);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.closeChats);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesRead);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesDeleted);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageReceivedByServer);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageReceivedByAck);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageSendError);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.chatInfoDidLoaded);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.contactsDidLoaded);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.encryptedChatUpdated);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesReadedEncrypted);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.removeAllMessagesFromDialog);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioProgressDidChanged);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidReset);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.screenshotTook);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.blockedUsersDidLoaded);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileNewChunkAvailable);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.didCreatedNewDeleteTask);
    NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidStarted);

    super.onFragmentCreate();

    loading = true;

    MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, 0, true, 0,
            classGuid, true, false, null);

    if (currentUser != null) {
        userBlocked = MessagesController.getInstance().blockedUsers.contains(currentUser.id);
    }

    if (AndroidUtilities.isTablet()) {
        NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, dialog_id,
                false);
    }

    typingDotsDrawable = new TypingDotsDrawable();
    typingDotsDrawable.setIsChat(currentChat != null);

    if (currentEncryptedChat != null && AndroidUtilities
            .getMyLayerVersion(currentEncryptedChat.layer) != SendMessagesHelper.CURRENT_SECRET_CHAT_LAYER) {
        SendMessagesHelper.getInstance().sendNotifyLayerMessage(currentEncryptedChat, null);
    }

    return true;
}

From source file:org.apache.brooklyn.location.jclouds.JcloudsLocation.java

protected MachineLocation obtainOnce(ConfigBag setup) throws NoMachinesAvailableException {
    AccessController.Response access = getManagementContext().getAccessController().canProvisionLocation(this);
    if (!access.isAllowed()) {
        throw new IllegalStateException(
                "Access controller forbids provisioning in " + this + ": " + access.getMsg());
    }/*from   w w  w .  ja  v  a 2  s  .c om*/

    setCreationString(setup);
    boolean waitForSshable = !"false".equalsIgnoreCase(setup.get(WAIT_FOR_SSHABLE));
    boolean waitForWinRmable = !"false".equalsIgnoreCase(setup.get(WAIT_FOR_WINRM_AVAILABLE));
    boolean usePortForwarding = setup.get(USE_PORT_FORWARDING);
    boolean skipJcloudsSshing = Boolean.FALSE.equals(setup.get(USE_JCLOUDS_SSH_INIT)) || usePortForwarding;
    JcloudsPortForwarderExtension portForwarder = setup.get(PORT_FORWARDER);
    if (usePortForwarding)
        checkNotNull(portForwarder, "portForwarder, when use-port-forwarding enabled");

    final ComputeService computeService = getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(setup, true);
    CloudMachineNamer cloudMachineNamer = getCloudMachineNamer(setup);
    String groupId = elvis(setup.get(GROUP_ID), cloudMachineNamer.generateNewGroupId(setup));
    NodeMetadata node = null;
    JcloudsMachineLocation machineLocation = null;
    Duration semaphoreTimestamp = null;
    Duration templateTimestamp = null;
    Duration provisionTimestamp = null;
    Duration usableTimestamp = null;
    Duration customizedTimestamp = null;
    Stopwatch provisioningStopwatch = Stopwatch.createStarted();

    try {
        LOG.info("Creating VM " + setup.getDescription() + " in " + this);

        Semaphore machineCreationSemaphore = getMachineCreationSemaphore();
        boolean acquired = machineCreationSemaphore.tryAcquire(0, TimeUnit.SECONDS);
        if (!acquired) {
            LOG.info("Waiting in {} for machine-creation permit ({} other queuing requests already)",
                    new Object[] { this, machineCreationSemaphore.getQueueLength() });
            Stopwatch blockStopwatch = Stopwatch.createStarted();
            machineCreationSemaphore.acquire();
            LOG.info("Acquired in {} machine-creation permit, after waiting {}", this,
                    Time.makeTimeStringRounded(blockStopwatch));
        } else {
            LOG.debug("Acquired in {} machine-creation permit immediately", this);
        }
        semaphoreTimestamp = Duration.of(provisioningStopwatch);

        LoginCredentials userCredentials = null;
        Set<? extends NodeMetadata> nodes;
        Template template;
        try {
            // Setup the template
            template = buildTemplate(computeService, setup);
            boolean expectWindows = isWindows(template, setup);
            if (!skipJcloudsSshing) {
                if (expectWindows) {
                    // TODO Was this too early to look at template.getImage? e.g. customizeTemplate could subsequently modify it.
                    LOG.warn("Ignoring invalid configuration for Windows provisioning of " + template.getImage()
                            + ": " + USE_JCLOUDS_SSH_INIT.getName() + " should be false");
                    skipJcloudsSshing = true;
                } else if (waitForSshable) {
                    userCredentials = initTemplateForCreateUser(template, setup);
                }
            }

            templateTimestamp = Duration.of(provisioningStopwatch);
            // "Name" metadata seems to set the display name; at least in AWS
            // TODO it would be nice if this salt comes from the location's ID (but we don't know that yet as the ssh machine location isn't created yet)
            // TODO in softlayer we want to control the suffix of the hostname which is 3 random hex digits
            template.getOptions().getUserMetadata().put("Name",
                    cloudMachineNamer.generateNewMachineUniqueNameFromGroupId(setup, groupId));

            if (setup.get(JcloudsLocationConfig.INCLUDE_BROOKLYN_USER_METADATA)) {
                template.getOptions().getUserMetadata().put("brooklyn-user", System.getProperty("user.name"));

                Object context = setup.get(CALLER_CONTEXT);
                if (context instanceof Entity) {
                    Entity entity = (Entity) context;
                    template.getOptions().getUserMetadata().put("brooklyn-app-id", entity.getApplicationId());
                    template.getOptions().getUserMetadata().put("brooklyn-app-name",
                            entity.getApplication().getDisplayName());
                    template.getOptions().getUserMetadata().put("brooklyn-entity-id", entity.getId());
                    template.getOptions().getUserMetadata().put("brooklyn-entity-name",
                            entity.getDisplayName());
                    template.getOptions().getUserMetadata().put("brooklyn-server-creation-date",
                            Time.makeDateSimpleStampString());
                }
            }

            customizeTemplate(setup, computeService, template);

            LOG.debug("jclouds using template {} / options {} to provision machine in {}",
                    new Object[] { template, template.getOptions(), setup.getDescription() });

            if (!setup.getUnusedConfig().isEmpty())
                if (LOG.isDebugEnabled())
                    LOG.debug("NOTE: unused flags passed to obtain VM in " + setup.getDescription() + ": "
                            + Sanitizer.sanitize(setup.getUnusedConfig()));

            nodes = computeService.createNodesInGroup(groupId, 1, template);
            provisionTimestamp = Duration.of(provisioningStopwatch);
        } finally {
            machineCreationSemaphore.release();
        }

        node = Iterables.getOnlyElement(nodes, null);
        LOG.debug("jclouds created {} for {}", node, setup.getDescription());
        if (node == null)
            throw new IllegalStateException(
                    "No nodes returned by jclouds create-nodes in " + setup.getDescription());

        boolean windows = isWindows(node, setup);
        if (windows) {
            int newLoginPort = node.getLoginPort() == 22 ? 5985 : node.getLoginPort();
            String newLoginUser = "root".equals(node.getCredentials().getUser()) ? "Administrator"
                    : node.getCredentials().getUser();
            LOG.debug(
                    "jclouds created Windows VM {}; transforming connection details: loginPort from {} to {}; loginUser from {} to {}",
                    new Object[] { node, node.getLoginPort(), newLoginPort, node.getCredentials().getUser(),
                            newLoginUser });

            node = NodeMetadataBuilder.fromNodeMetadata(node).loginPort(newLoginPort)
                    .credentials(LoginCredentials.builder(node.getCredentials()).user(newLoginUser).build())
                    .build();
        }
        // FIXME How do we influence the node.getLoginPort, so it is set correctly for Windows?
        // Setup port-forwarding, if required
        Optional<HostAndPort> sshHostAndPortOverride;
        if (usePortForwarding) {
            sshHostAndPortOverride = Optional.of(portForwarder.openPortForwarding(node, node.getLoginPort(),
                    Optional.<Integer>absent(), Protocol.TCP, Cidr.UNIVERSAL));
        } else {
            sshHostAndPortOverride = Optional.absent();
        }

        LoginCredentials initialCredentials = node.getCredentials();
        if (skipJcloudsSshing) {
            boolean waitForConnectable = (windows) ? waitForWinRmable : waitForSshable;
            if (waitForConnectable) {
                if (windows) {
                    // TODO Does jclouds support any windows user setup?
                    initialCredentials = waitForWinRmAvailable(computeService, node, sshHostAndPortOverride,
                            setup);
                } else {
                    initialCredentials = waitForSshable(computeService, node, sshHostAndPortOverride, setup);
                }
                userCredentials = createUser(computeService, node, sshHostAndPortOverride, initialCredentials,
                        setup);
            }
        }

        // Figure out which login-credentials to use
        LoginCredentials customCredentials = setup.get(CUSTOM_CREDENTIALS);
        if (customCredentials != null) {
            userCredentials = customCredentials;
            //set userName and other data, from these credentials
            Object oldUsername = setup.put(USER, customCredentials.getUser());
            LOG.debug("node {} username {} / {} (customCredentials)",
                    new Object[] { node, customCredentials.getUser(), oldUsername });
            if (customCredentials.getOptionalPassword().isPresent())
                setup.put(PASSWORD, customCredentials.getOptionalPassword().get());
            if (customCredentials.getOptionalPrivateKey().isPresent())
                setup.put(PRIVATE_KEY_DATA, customCredentials.getOptionalPrivateKey().get());
        }
        if (userCredentials == null || (!userCredentials.getOptionalPassword().isPresent()
                && !userCredentials.getOptionalPrivateKey().isPresent())) {
            // We either don't have any userCredentials, or it is missing both a password/key.
            // TODO See waitForSshable, which now handles if the node.getLoginCredentials has both a password+key
            userCredentials = extractVmCredentials(setup, node, initialCredentials);
        }
        if (userCredentials == null) {
            // TODO See waitForSshable, which now handles if the node.getLoginCredentials has both a password+key
            userCredentials = extractVmCredentials(setup, node, initialCredentials);
        }
        if (userCredentials != null) {
            node = NodeMetadataBuilder.fromNodeMetadata(node).credentials(userCredentials).build();
        } else {
            // only happens if something broke above...
            userCredentials = LoginCredentials.fromCredentials(node.getCredentials());
        }
        // store the credentials, in case they have changed
        setup.putIfNotNull(JcloudsLocationConfig.PASSWORD, userCredentials.getOptionalPassword().orNull());
        setup.putIfNotNull(JcloudsLocationConfig.PRIVATE_KEY_DATA,
                userCredentials.getOptionalPrivateKey().orNull());

        // Wait for the VM to be reachable over SSH
        if (waitForSshable && !windows) {
            waitForSshable(computeService, node, sshHostAndPortOverride, ImmutableList.of(userCredentials),
                    setup);
        } else {
            LOG.debug("Skipping ssh check for {} ({}) due to config waitForSshable=false", node,
                    setup.getDescription());
        }
        usableTimestamp = Duration.of(provisioningStopwatch);

        //            JcloudsSshMachineLocation jcloudsSshMachineLocation = null;
        //            WinRmMachineLocation winRmMachineLocation = null;
        // Create a JcloudsSshMachineLocation, and register it
        if (windows) {
            machineLocation = registerWinRmMachineLocation(computeService, node, userCredentials,
                    sshHostAndPortOverride, setup);
        } else {
            machineLocation = registerJcloudsSshMachineLocation(computeService, node,
                    Optional.fromNullable(template), userCredentials, sshHostAndPortOverride, setup);
        }

        if (usePortForwarding && sshHostAndPortOverride.isPresent()) {
            // Now that we have the sshMachineLocation, we can associate the port-forwarding address with it.
            PortForwardManager portForwardManager = setup.get(PORT_FORWARDING_MANAGER);
            if (portForwardManager != null) {
                portForwardManager.associate(node.getId(), sshHostAndPortOverride.get(), machineLocation,
                        node.getLoginPort());
            } else {
                LOG.warn("No port-forward manager for {} so could not associate {} -> {} for {}",
                        new Object[] { this, node.getLoginPort(), sshHostAndPortOverride, machineLocation });
            }
        }

        if ("docker".equals(this.getProvider())) {
            if (windows) {
                throw new UnsupportedOperationException("Docker not supported on Windows");
            }
            Map<Integer, Integer> portMappings = JcloudsUtil.dockerPortMappingsFor(this, node.getId());
            PortForwardManager portForwardManager = setup.get(PORT_FORWARDING_MANAGER);
            if (portForwardManager != null) {
                for (Integer containerPort : portMappings.keySet()) {
                    Integer hostPort = portMappings.get(containerPort);
                    String dockerHost = ((JcloudsSshMachineLocation) machineLocation).getSshHostAndPort()
                            .getHostText();
                    portForwardManager.associate(node.getId(), HostAndPort.fromParts(dockerHost, hostPort),
                            machineLocation, containerPort);
                }
            } else {
                LOG.warn("No port-forward manager for {} so could not associate docker port-mappings for {}",
                        this, machineLocation);
            }
        }

        List<String> customisationForLogging = new ArrayList<String>();
        // Apply same securityGroups rules to iptables, if iptables is running on the node
        if (waitForSshable) {

            String setupScript = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_URL);
            List<String> setupScripts = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_URL_LIST);
            Collection<String> allScripts = new MutableList<String>().appendIfNotNull(setupScript)
                    .appendAll(setupScripts);
            for (String setupScriptItem : allScripts) {
                if (Strings.isNonBlank(setupScriptItem)) {
                    customisationForLogging.add("custom setup script " + setupScriptItem);

                    String setupVarsString = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_VARS);
                    Map<String, String> substitutions = (setupVarsString != null)
                            ? Splitter.on(",").withKeyValueSeparator(":").split(setupVarsString)
                            : ImmutableMap.<String, String>of();
                    String scriptContent = ResourceUtils.create(this).getResourceAsString(setupScriptItem);
                    String script = TemplateProcessor.processTemplateContents(scriptContent,
                            getManagementContext(), substitutions);
                    if (windows) {
                        ((WinRmMachineLocation) machineLocation)
                                .executeCommand(ImmutableList.copyOf((script.replace("\r", "").split("\n"))));
                    } else {
                        ((SshMachineLocation) machineLocation).execCommands("Customizing node " + this,
                                ImmutableList.of(script));
                    }
                }
            }

            if (setup.get(JcloudsLocationConfig.MAP_DEV_RANDOM_TO_DEV_URANDOM)) {
                if (windows) {
                    LOG.warn("Ignoring flag MAP_DEV_RANDOM_TO_DEV_URANDOM on Windows location {}",
                            machineLocation);
                } else {
                    customisationForLogging.add("point /dev/random to urandom");

                    ((SshMachineLocation) machineLocation).execCommands("using urandom instead of random",
                            Arrays.asList("sudo mv /dev/random /dev/random-real",
                                    "sudo ln -s /dev/urandom /dev/random"));
                }
            }

            if (setup.get(GENERATE_HOSTNAME)) {
                if (windows) {
                    // TODO: Generate Windows Hostname
                    LOG.warn("Ignoring flag GENERATE_HOSTNAME on Windows location {}", machineLocation);
                } else {
                    customisationForLogging.add("configure hostname");

                    ((SshMachineLocation) machineLocation).execCommands("Generate hostname " + node.getName(),
                            Arrays.asList("sudo hostname " + node.getName(),
                                    "sudo sed -i \"s/HOSTNAME=.*/HOSTNAME=" + node.getName()
                                            + "/g\" /etc/sysconfig/network",
                                    "sudo bash -c \"echo 127.0.0.1   `hostname` >> /etc/hosts\""));
                }
            }

            if (setup.get(OPEN_IPTABLES)) {
                if (windows) {
                    LOG.warn("Ignoring DEPRECATED flag OPEN_IPTABLES on Windows location {}", machineLocation);
                } else {
                    LOG.warn(
                            "Using DEPRECATED flag OPEN_IPTABLES (will not be supported in future versions) for {} at {}",
                            machineLocation, this);

                    @SuppressWarnings("unchecked")
                    Iterable<Integer> inboundPorts = (Iterable<Integer>) setup.get(INBOUND_PORTS);

                    if (inboundPorts == null || Iterables.isEmpty(inboundPorts)) {
                        LOG.info("No ports to open in iptables (no inbound ports) for {} at {}",
                                machineLocation, this);
                    } else {
                        customisationForLogging.add("open iptables");

                        List<String> iptablesRules = Lists.newArrayList();

                        if (isLocationFirewalldEnabled((SshMachineLocation) machineLocation)) {
                            for (Integer port : inboundPorts) {
                                iptablesRules.add(IptablesCommands.addFirewalldRule(Chain.INPUT, Protocol.TCP,
                                        port, Policy.ACCEPT));
                            }
                        } else {
                            iptablesRules = createIptablesRulesForNetworkInterface(inboundPorts);
                            iptablesRules.add(IptablesCommands.saveIptablesRules());
                        }
                        List<String> batch = Lists.newArrayList();
                        // Some entities, such as Riak (erlang based) have a huge range of ports, which leads to a script that
                        // is too large to run (fails with a broken pipe). Batch the rules into batches of 50
                        for (String rule : iptablesRules) {
                            batch.add(rule);
                            if (batch.size() == 50) {
                                ((SshMachineLocation) machineLocation)
                                        .execCommands("Inserting iptables rules, 50 command batch", batch);
                                batch.clear();
                            }
                        }
                        if (batch.size() > 0) {
                            ((SshMachineLocation) machineLocation).execCommands("Inserting iptables rules",
                                    batch);
                        }
                        ((SshMachineLocation) machineLocation).execCommands("List iptables rules",
                                ImmutableList.of(IptablesCommands.listIptablesRule()));
                    }
                }
            }

            if (setup.get(STOP_IPTABLES)) {
                if (windows) {
                    LOG.warn("Ignoring DEPRECATED flag OPEN_IPTABLES on Windows location {}", machineLocation);
                } else {
                    LOG.warn(
                            "Using DEPRECATED flag STOP_IPTABLES (will not be supported in future versions) for {} at {}",
                            machineLocation, this);

                    customisationForLogging.add("stop iptables");

                    List<String> cmds = ImmutableList.<String>of();
                    if (isLocationFirewalldEnabled((SshMachineLocation) machineLocation)) {
                        cmds = ImmutableList.of(IptablesCommands.firewalldServiceStop(),
                                IptablesCommands.firewalldServiceStatus());
                    } else {
                        cmds = ImmutableList.of(IptablesCommands.iptablesServiceStop(),
                                IptablesCommands.iptablesServiceStatus());
                    }
                    ((SshMachineLocation) machineLocation).execCommands("Stopping iptables", cmds);
                }
            }

            List<String> extraKeyUrlsToAuth = setup.get(EXTRA_PUBLIC_KEY_URLS_TO_AUTH);
            if (extraKeyUrlsToAuth != null && !extraKeyUrlsToAuth.isEmpty()) {
                if (windows) {
                    LOG.warn("Ignoring flag EXTRA_PUBLIC_KEY_URLS_TO_AUTH on Windows location",
                            machineLocation);
                } else {
                    List<String> extraKeyDataToAuth = MutableList.of();
                    for (String keyUrl : extraKeyUrlsToAuth) {
                        extraKeyDataToAuth.add(ResourceUtils.create().getResourceAsString(keyUrl));
                    }
                    ((SshMachineLocation) machineLocation).execCommands("Authorizing ssh keys",
                            ImmutableList.of(new AuthorizeRSAPublicKeys(extraKeyDataToAuth)
                                    .render(org.jclouds.scriptbuilder.domain.OsFamily.UNIX)));
                }
            }

        } else {
            // Otherwise we have deliberately not waited to be ssh'able, so don't try now to
            // ssh to exec these commands!
        }

        // Apply any optional app-specific customization.
        for (JcloudsLocationCustomizer customizer : getCustomizers(setup)) {
            LOG.debug("Customizing machine {}, using customizer {}", machineLocation, customizer);
            customizer.customize(this, computeService, machineLocation);
        }
        for (MachineLocationCustomizer customizer : getMachineCustomizers(setup)) {
            LOG.debug("Customizing machine {}, using customizer {}", machineLocation, customizer);
            customizer.customize(machineLocation);
        }

        customizedTimestamp = Duration.of(provisioningStopwatch);

        try {
            String logMessage = "Finished VM " + setup.getDescription() + " creation:" + " "
                    + machineLocation.getUser() + "@" + machineLocation.getAddress() + ":"
                    + machineLocation.getPort()
                    + (Boolean.TRUE.equals(setup.get(LOG_CREDENTIALS))
                            ? "password=" + userCredentials.getOptionalPassword().or("<absent>") + " && key="
                                    + userCredentials.getOptionalPrivateKey().or("<absent>")
                            : "")
                    + " ready after " + Duration.of(provisioningStopwatch).toStringRounded() + " ("
                    + "semaphore obtained in " + Duration.of(semaphoreTimestamp).toStringRounded() + ";"
                    + template + " template built in "
                    + Duration.of(templateTimestamp).subtract(semaphoreTimestamp).toStringRounded() + ";" + " "
                    + node + " provisioned in "
                    + Duration.of(provisionTimestamp).subtract(templateTimestamp).toStringRounded() + ";" + " "
                    + machineLocation + " connection usable in "
                    + Duration.of(usableTimestamp).subtract(provisionTimestamp).toStringRounded() + ";"
                    + " and os customized in "
                    + Duration.of(customizedTimestamp).subtract(usableTimestamp).toStringRounded() + " - "
                    + Joiner.on(", ").join(customisationForLogging) + ")";
            LOG.info(logMessage);
        } catch (Exception e) {
            // TODO Remove try-catch! @Nakomis: why did you add it? What exception happened during logging?
            Exceptions.propagateIfFatal(e);
            LOG.warn("Problem generating log message summarising completion of jclouds machine provisioning "
                    + machineLocation + " by " + this, e);
        }

        return machineLocation;

    } catch (Exception e) {
        if (e instanceof RunNodesException && ((RunNodesException) e).getNodeErrors().size() > 0) {
            node = Iterables.get(((RunNodesException) e).getNodeErrors().keySet(), 0);
        }
        // sometimes AWS nodes come up busted (eg ssh not allowed); just throw it back (and maybe try for another one)
        boolean destroyNode = (node != null) && Boolean.TRUE.equals(setup.get(DESTROY_ON_FAILURE));

        if (e.toString().contains("VPCResourceNotSpecified")) {
            LOG.error(
                    "Detected that your EC2 account is a legacy 'classic' account, but the recommended instance type requires VPC. "
                            + "You can specify the 'eu-central-1' region to avoid this problem, or you can specify a classic-compatible instance type, "
                            + "or you can specify a subnet to use with 'networkName' "
                            + "(taking care that the subnet auto-assigns public IP's and allows ingress on all ports, "
                            + "as Brooklyn does not currently configure security groups for non-default VPC's; "
                            + "or setting up Brooklyn to be in the subnet or have a jump host or other subnet access configuration). "
                            + "For more information on VPC vs classic see http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-vpc.html.");
        }

        LOG.error(
                "Failed to start VM for " + setup.getDescription() + (destroyNode ? " (destroying)" : "")
                        + (node != null ? "; node " + node : "") + " after "
                        + Duration.of(provisioningStopwatch).toStringRounded()
                        + (semaphoreTimestamp != null
                                ? " (" + "semaphore obtained in "
                                        + Duration.of(semaphoreTimestamp).toStringRounded() + ";"
                                        + (templateTimestamp != null && semaphoreTimestamp != null
                                                ? " template built in " + Duration.of(templateTimestamp)
                                                        .subtract(semaphoreTimestamp).toStringRounded() + ";"
                                                : "")
                                        + (provisionTimestamp != null && templateTimestamp != null
                                                ? " node provisioned in " + Duration.of(provisionTimestamp)
                                                        .subtract(templateTimestamp).toStringRounded() + ";"
                                                : "")
                                        + (usableTimestamp != null && provisioningStopwatch != null
                                                ? " connection usable in "
                                                        + Duration.of(usableTimestamp)
                                                                .subtract(provisionTimestamp).toStringRounded()
                                                        + ";"
                                                : "")
                                        + (customizedTimestamp != null && usableTimestamp != null
                                                ? " and OS customized in " + Duration.of(customizedTimestamp)
                                                        .subtract(usableTimestamp).toStringRounded()
                                                : "")
                                        + ")"
                                : "")
                        + ": " + e.getMessage());
        LOG.debug(Throwables.getStackTraceAsString(e));

        if (destroyNode) {
            Stopwatch destroyingStopwatch = Stopwatch.createStarted();
            if (machineLocation != null) {
                releaseSafely(machineLocation);
            } else {
                releaseNodeSafely(node);
            }
            LOG.info("Destroyed " + (machineLocation != null ? "machine " + machineLocation : "node " + node)
                    + " in " + Duration.of(destroyingStopwatch).toStringRounded());
        }

        throw Exceptions.propagate(e);
    }
}

From source file:org.telegram.android.MessagesController.java

public TLRPC.EncryptedChat getEncryptedChatDB(int chat_id) {
    TLRPC.EncryptedChat chat = encryptedChats.get(chat_id);
    if (chat == null) {
        Semaphore semaphore = new Semaphore(0);
        ArrayList<TLObject> result = new ArrayList<>();
        MessagesStorage.getInstance().getEncryptedChat(chat_id, semaphore, result);
        try {/*from   w  w  w .j av  a2s  .c o  m*/
            semaphore.acquire();
        } catch (Exception e) {
            FileLog.e("tmessages", e);
        }
        if (result.size() == 2) {
            chat = (TLRPC.EncryptedChat) result.get(0);
            TLRPC.User user = (TLRPC.User) result.get(1);
            putEncryptedChat(chat, false);
            putUser(user, true);
        }
    }
    return chat;
}

From source file:org.telegram.messenger.MessagesController.java

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 {//from w w w.  j ava 2s.c o  m
            semaphore.acquire();
        } catch (Exception e) {
            FileLog.e("tmessages", e);
        }
        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;
                newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
                UserConfig.saveConfig(false);
                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) {
                    if (decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv.length != 32) {
                        return null;
                    }
                    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();
                    if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 5000
                            && decryptedMessage.media.thumb_w < 100 && decryptedMessage.media.thumb_h < 100) {
                        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) {
                    if (decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv.length != 32) {
                        return null;
                    }
                    newMessage.media = new TLRPC.TL_messageMediaVideo();
                    newMessage.media.video = new TLRPC.TL_videoEncrypted();
                    if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 5000
                            && decryptedMessage.media.thumb_w < 100 && decryptedMessage.media.thumb_h < 100) {
                        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();
                    } else {
                        newMessage.media.video.thumb = new TLRPC.TL_photoSizeEmpty();
                        newMessage.media.video.thumb.type = "s";
                    }
                    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 if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaDocument) {
                    if (decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv.length != 32) {
                        return null;
                    }
                    newMessage.media = new TLRPC.TL_messageMediaDocument();
                    newMessage.media.document = new TLRPC.TL_documentEncrypted();
                    newMessage.media.document.id = message.file.id;
                    newMessage.media.document.access_hash = message.file.access_hash;
                    newMessage.media.document.user_id = decryptedMessage.media.user_id;
                    newMessage.media.document.date = message.date;
                    newMessage.media.document.file_name = decryptedMessage.media.file_name;
                    newMessage.media.document.mime_type = decryptedMessage.media.mime_type;
                    newMessage.media.document.size = message.file.size;
                    newMessage.media.document.key = decryptedMessage.media.key;
                    newMessage.media.document.iv = decryptedMessage.media.iv;
                    if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 5000
                            && decryptedMessage.media.thumb_w < 100 && decryptedMessage.media.thumb_h < 100) {
                        newMessage.media.document.thumb = new TLRPC.TL_photoCachedSize();
                        newMessage.media.document.thumb.bytes = decryptedMessage.media.thumb;
                        newMessage.media.document.thumb.w = decryptedMessage.media.thumb_w;
                        newMessage.media.document.thumb.h = decryptedMessage.media.thumb_h;
                        newMessage.media.document.thumb.type = "s";
                        newMessage.media.document.thumb.location = new TLRPC.TL_fileLocationUnavailable();
                    } else {
                        newMessage.media.document.thumb = new TLRPC.TL_photoSizeEmpty();
                        newMessage.media.document.thumb.type = "s";
                    }
                    newMessage.media.document.dc_id = message.file.dc_id;
                } 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();
                    UserConfig.saveConfig(false);
                    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;
                }
            } else {
                FileLog.e("tmessages", "unkown message " + object);
            }
        } else {
            FileLog.e("tmessages", "unkown TLObject");
        }
    } else {
        FileLog.e("tmessages", "fingerprint mismatch");
    }
    return null;
}

From source file:org.telegram.messenger.MessagesController.java

public boolean processUpdateArray(ArrayList<TLRPC.Update> updates, final ArrayList<TLRPC.User> usersArr,
        final ArrayList<TLRPC.Chat> chatsArr) {
    if (updates.isEmpty()) {
        return true;
    }/*from w  ww. ja v a2s .  c o m*/
    long currentTime = System.currentTimeMillis();

    final HashMap<Long, ArrayList<MessageObject>> messages = new HashMap<Long, ArrayList<MessageObject>>();
    final ArrayList<TLRPC.Message> messagesArr = new ArrayList<TLRPC.Message>();
    final ArrayList<Integer> markAsReadMessages = new ArrayList<Integer>();
    final HashMap<Integer, Integer> markAsReadEncrypted = new HashMap<Integer, Integer>();
    final ArrayList<Integer> deletedMessages = new ArrayList<Integer>();
    final ArrayList<Long> printChanges = new ArrayList<Long>();
    final ArrayList<TLRPC.ChatParticipants> chatInfoToUpdate = new ArrayList<TLRPC.ChatParticipants>();
    final ArrayList<TLRPC.Update> updatesOnMainThread = new ArrayList<TLRPC.Update>();
    final ArrayList<TLRPC.TL_updateEncryptedMessagesRead> tasks = new ArrayList<TLRPC.TL_updateEncryptedMessagesRead>();
    final ArrayList<Integer> contactsIds = new ArrayList<Integer>();
    MessageObject lastMessage = null;

    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;
    }

    if (usersArr != null || chatsArr != null) {
        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);
                    }
                }
            }
        });
    }

    int interfaceUpdateMask = 0;

    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) {
                interfaceUpdateMask |= UPDATE_MASK_CHAT_AVATAR;
            } else if (obj.type == 10) {
                interfaceUpdateMask |= UPDATE_MASK_CHAT_NAME;
            }
            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);
            MessagesStorage.lastPtsValue = update.pts;
            if (upd.message.from_id != UserConfig.clientUserId && upd.message.to_id != null) {
                if (uid != openned_dialog_id || ApplicationLoader.lastPauseTime != 0) {
                    lastMessage = obj;
                }
            }
        } else if (update instanceof TLRPC.TL_updateMessageID) {
            //can't be here
        } else if (update instanceof TLRPC.TL_updateReadMessages) {
            markAsReadMessages.addAll(update.messages);
            MessagesStorage.lastPtsValue = update.pts;
        } else if (update instanceof TLRPC.TL_updateDeleteMessages) {
            deletedMessages.addAll(update.messages);
            MessagesStorage.lastPtsValue = update.pts;
        } else if (update instanceof TLRPC.TL_updateRestoreMessages) {
            MessagesStorage.lastPtsValue = update.pts;
        } 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) {
            interfaceUpdateMask |= UPDATE_MASK_CHAT_MEMBERS;
            chatInfoToUpdate.add(update.participants);
        } else if (update instanceof TLRPC.TL_updateUserStatus) {
            interfaceUpdateMask |= UPDATE_MASK_STATUS;
            updatesOnMainThread.add(update);
        } else if (update instanceof TLRPC.TL_updateUserName) {
            interfaceUpdateMask |= UPDATE_MASK_NAME;
            updatesOnMainThread.add(update);
        } else if (update instanceof TLRPC.TL_updateUserPhoto) {
            interfaceUpdateMask |= UPDATE_MASK_AVATAR;
            MessagesStorage.Instance.clearUserPhotos(update.user_id);
            /*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;
                    }
                }
            }
             }*/

            updatesOnMainThread.add(update);
        } else if (update instanceof TLRPC.TL_updateContactRegistered) {
            if (enableJoined && 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;
                    }
                }
            }
            //                if (!contactsIds.contains(update.user_id)) {
            //                    contactsIds.add(update.user_id);
            //                }
        } else if (update instanceof TLRPC.TL_updateContactLink) {
            if (update.my_link instanceof TLRPC.TL_contacts_myLinkContact
                    || update.my_link instanceof TLRPC.TL_contacts_myLinkRequested && update.my_link.contact) {
                int idx = contactsIds.indexOf(-update.user_id);
                if (idx != -1) {
                    contactsIds.remove(idx);
                }
                if (!contactsIds.contains(update.user_id)) {
                    contactsIds.add(update.user_id);
                }
            } else {
                int idx = contactsIds.indexOf(update.user_id);
                if (idx != -1) {
                    contactsIds.remove(idx);
                }
                if (!contactsIds.contains(update.user_id)) {
                    contactsIds.add(-update.user_id);
                }
            }
        } else if (update instanceof TLRPC.TL_updateActivation) {
            //DEPRECATED
        } else if (update instanceof TLRPC.TL_updateNewAuthorization) {
            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;
                }
            }
        } else if (update instanceof TLRPC.TL_updateNewGeoChatMessage) {
            //DEPRECATED
        } else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) {
            MessagesStorage.lastQtsValue = update.qts;
            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) {
                    if (uid != openned_dialog_id || ApplicationLoader.lastPauseTime != 0) {
                        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_updateChatParticipantAdd) {
            MessagesStorage.Instance.updateChatInfo(update.chat_id, update.user_id, false, update.inviter_id,
                    update.version);
        } else if (update instanceof TLRPC.TL_updateChatParticipantDelete) {
            MessagesStorage.Instance.updateChatInfo(update.chat_id, update.user_id, true, 0, update.version);
        } else if (update instanceof TLRPC.TL_updateDcOptions) {
            ConnectionsManager.Instance.updateDcSettings();
        } 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) {
                    FileLog.e("tmessages", e);
                }
                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);
                if (user == null) {
                    user = usersDict.get(user_id);
                }
                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;

                Utilities.RunOnUIThread(new Runnable() {
                    @Override
                    public void run() {
                        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);
                acceptSecretChat(newChat);
            } 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 (!printChanges.isEmpty()) {
        updatePrintingStrings();
    }

    final MessageObject lastMessageArg = lastMessage;
    final int interfaceUpdateMaskFinal = interfaceUpdateMask;

    if (!contactsIds.isEmpty()) {
        ContactsController.Instance.processContactsUpdates(contactsIds, usersDict);
    }

    if (!messagesArr.isEmpty()) {
        MessagesStorage.Instance.putMessages(messagesArr, true, true);
    }

    if (!messages.isEmpty() || !markAsReadMessages.isEmpty() || !deletedMessages.isEmpty()
            || !printChanges.isEmpty() || !chatInfoToUpdate.isEmpty() || !updatesOnMainThread.isEmpty()
            || !markAsReadEncrypted.isEmpty() || !contactsIds.isEmpty()) {
        Utilities.RunOnUIThread(new Runnable() {
            @Override
            public void run() {
                int updateMask = interfaceUpdateMaskFinal;

                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);
                    }
                    NotificationCenter.Instance.postNotificationName(dialogsNeedReload);
                }
                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);
                            if (message != null && message.messageOwner.date <= entry.getValue()) {
                                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()) {
                    updateMask |= UPDATE_MASK_USER_PRINT;
                }
                if (!contactsIds.isEmpty()) {
                    updateMask |= UPDATE_MASK_NAME;
                    updateMask |= UPDATE_MASK_USER_PHONE;
                }
                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 (updateMask != 0) {
                    NotificationCenter.Instance.postNotificationName(updateInterfaces, updateMask);
                }
                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;
}