NekoX/TMessagesProj/src/main/java/org/telegram/messenger/WearDataLayerListenerServic...

314 lines
11 KiB
Java

package org.telegram.messenger;
import android.text.TextUtils;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.CapabilityClient;
import com.google.android.gms.wearable.CapabilityInfo;
import com.google.android.gms.wearable.Channel;
import com.google.android.gms.wearable.MessageClient;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
import org.json.JSONObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WearDataLayerListenerService extends WearableListenerService {
private int currentAccount = UserConfig.selectedAccount;
private static boolean watchConnected;
@Override
public void onCreate() {
super.onCreate();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("WearableDataLayer service created");
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("WearableDataLayer service destroyed");
}
}
@Override
public void onChannelOpened(final Channel ch) {
//new Thread(new Runnable(){
// @Override
// public void run(){
GoogleApiClient apiClient = new GoogleApiClient.Builder(WearDataLayerListenerService.this).addApi(Wearable.API).build();
if (!apiClient.blockingConnect().isSuccess()) {
if (BuildVars.LOGS_ENABLED) {
FileLog.e("failed to connect google api client");
}
return;
}
String path = ch.getPath();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("wear channel path: " + path);
}
try {
if ("/getCurrentUser".equals(path)) {
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(ch.getOutputStream(apiClient).await().getOutputStream()));
if (UserConfig.getInstance(currentAccount).isClientActivated()) {
final TLRPC.User user = UserConfig.getInstance(currentAccount).getCurrentUser();
out.writeInt(user.id);
out.writeUTF(user.first_name);
out.writeUTF(user.last_name);
out.writeUTF(user.phone);
if (user.photo != null) {
final File photo = FileLoader.getPathToAttach(user.photo.photo_small, true);
final CyclicBarrier barrier = new CyclicBarrier(2);
if (!photo.exists()) {
final NotificationCenter.NotificationCenterDelegate listener = (id, account, args) -> {
if (id == NotificationCenter.fileDidLoad) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("file loaded: " + args[0] + " " + args[0].getClass().getName());
}
if (args[0].equals(photo.getName())) {
if (BuildVars.LOGS_ENABLED) {
FileLog.e("LOADED USER PHOTO");
}
try {
barrier.await(10, TimeUnit.MILLISECONDS);
} catch (Exception ignore) {
}
}
}
};
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).addObserver(listener, NotificationCenter.fileDidLoad);
FileLoader.getInstance(currentAccount).loadFile(ImageLocation.getForUserOrChat(user, ImageLocation.TYPE_SMALL), user, null, 1, 1);
});
try {
barrier.await(10, TimeUnit.SECONDS);
} catch (Exception ignore) {
}
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(currentAccount).removeObserver(listener, NotificationCenter.fileDidLoad));
}
if (photo.exists() && photo.length() <= 50 * 1024 * 1024) {
byte[] photoData = new byte[(int) photo.length()];
FileInputStream photoIn = new FileInputStream(photo);
new DataInputStream(photoIn).readFully(photoData);
photoIn.close();
out.writeInt(photoData.length);
out.write(photoData);
} else {
out.writeInt(0);
}
} else {
out.writeInt(0);
}
} else {
out.writeInt(0);
}
out.flush();
out.close();
} else if ("/waitForAuthCode".equals(path)) {
ConnectionsManager.getInstance(currentAccount).setAppPaused(false, false);
final String[] code = {null};
final CyclicBarrier barrier = new CyclicBarrier(2);
final NotificationCenter.NotificationCenterDelegate listener = (id, account, args) -> {
if (id == NotificationCenter.didReceiveNewMessages) {
long did = (Long) args[0];
if (did == 777000) {
ArrayList<MessageObject> arr = (ArrayList<MessageObject>) args[1];
if (arr.size() > 0) {
MessageObject msg = arr.get(0);
if (!TextUtils.isEmpty(msg.messageText)) {
Matcher matcher = Pattern.compile("[0-9]+").matcher(msg.messageText);
if (matcher.find()) {
code[0] = matcher.group();
try {
barrier.await(10, TimeUnit.MILLISECONDS);
} catch (Exception ignore) {
}
}
}
}
}
}
};
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(currentAccount).addObserver(listener, NotificationCenter.didReceiveNewMessages));
try {
barrier.await(30, TimeUnit.SECONDS);
} catch (Exception ignore) {
}
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(currentAccount).removeObserver(listener, NotificationCenter.didReceiveNewMessages));
DataOutputStream out = new DataOutputStream(ch.getOutputStream(apiClient).await().getOutputStream());
if (code[0] != null) {
out.writeUTF(code[0]);
} else {
out.writeUTF("");
}
out.flush();
out.close();
ConnectionsManager.getInstance(currentAccount).setAppPaused(true, false);
} else if ("/getChatPhoto".equals(path)) {
try (DataInputStream in = new DataInputStream(ch.getInputStream(apiClient).await().getInputStream()); DataOutputStream out = new DataOutputStream(ch.getOutputStream(apiClient).await().getOutputStream())) {
String _req = in.readUTF();
JSONObject req = new JSONObject(_req);
int chatID = req.getInt("chat_id");
int accountID = req.getInt("account_id");
int currentAccount = -1;
for (int i = 0; i < UserConfig.getActivatedAccountsCount(); i++) {
if (UserConfig.getInstance(i).getClientUserId() == accountID) {
currentAccount = i;
break;
}
}
if (currentAccount != -1) {
TLRPC.FileLocation location = null;
if (chatID > 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(chatID);
if (user != null && user.photo != null)
location = user.photo.photo_small;
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-chatID);
if (chat != null && chat.photo != null)
location = chat.photo.photo_small;
}
if (location != null) {
File file = FileLoader.getPathToAttach(location, true);
if (file.exists() && file.length() < 102400) {
out.writeInt((int) file.length());
FileInputStream fin = new FileInputStream(file);
byte[] buf = new byte[10240];
int read;
while ((read = fin.read(buf)) > 0) {
out.write(buf, 0, read);
}
fin.close();
} else {
out.writeInt(0);
}
} else {
out.writeInt(0);
}
} else {
out.writeInt(0);
}
out.flush();
} catch (Exception ignore) {
}
}
} catch (Exception x) {
if (BuildVars.LOGS_ENABLED) {
FileLog.e("error processing wear request", x);
}
}
ch.close(apiClient).await();
apiClient.disconnect();
if (BuildVars.LOGS_ENABLED) {
FileLog.d("WearableDataLayer channel thread exiting");
}
// }
//}).start();
}
@Override
public void onMessageReceived(final MessageEvent messageEvent) {
if ("/reply".equals(messageEvent.getPath())) {
AndroidUtilities.runOnUIThread(() -> {
try {
ApplicationLoader.postInitApplication();
String data = new String(messageEvent.getData(), "UTF-8");
JSONObject r = new JSONObject(data);
CharSequence text = r.getString("text");
if (text == null || text.length() == 0) {
return;
}
long dialog_id = r.getLong("chat_id");
int max_id = r.getInt("max_id");
int currentAccount = -1;
int accountID = r.getInt("account_id");
for (int i = 0; i < UserConfig.getActivatedAccountsCount(); i++) {
if (UserConfig.getInstance(i).getClientUserId() == accountID) {
currentAccount = i;
break;
}
}
if (dialog_id == 0 || max_id == 0 || currentAccount == -1) {
return;
}
SendMessagesHelper.getInstance(currentAccount).sendMessage(text.toString(), dialog_id, null, null, null, true, null, null, null, true, 0);
MessagesController.getInstance(currentAccount).markDialogAsRead(dialog_id, max_id, max_id, 0, false, 0, 0, true, 0);
} catch (Exception x) {
if (BuildVars.LOGS_ENABLED)
FileLog.e(x);
}
});
}
}
public static void sendMessageToWatch(final String path, final byte[] data, String capability) {
Wearable.getCapabilityClient(ApplicationLoader.applicationContext)
.getCapability(capability, CapabilityClient.FILTER_REACHABLE)
.addOnCompleteListener(task -> {
CapabilityInfo info = task.getResult();
if (info != null) {
MessageClient mc = Wearable.getMessageClient(ApplicationLoader.applicationContext);
Set<Node> nodes = info.getNodes();
for (Node node : nodes) {
mc.sendMessage(node.getId(), path, data);
}
}
});
}
@Override
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
if ("remote_notifications".equals(capabilityInfo.getName())) {
watchConnected = false;
for (Node node : capabilityInfo.getNodes()) {
if (node.isNearby())
watchConnected = true;
}
}
}
public static void updateWatchConnectionState() {
try {
Wearable.getCapabilityClient(ApplicationLoader.applicationContext)
.getCapability("remote_notifications", CapabilityClient.FILTER_REACHABLE)
.addOnCompleteListener(task -> {
watchConnected = false;
try {
CapabilityInfo capabilityInfo = task.getResult();
if (capabilityInfo == null)
return;
for (Node node : capabilityInfo.getNodes()) {
if (node.isNearby())
watchConnected = true;
}
} catch (Exception ignore) {
}
});
} catch (Throwable ignore) {
}
}
public static boolean isWatchConnected() {
return watchConnected;
}
}