1package eu.siacs.conversations.services;
2
3import android.annotation.TargetApi;
4import android.content.ComponentName;
5import android.content.Context;
6import android.content.Intent;
7import android.content.IntentFilter;
8import android.content.ServiceConnection;
9import android.graphics.drawable.Icon;
10import android.os.Build;
11import android.os.Bundle;
12import android.os.IBinder;
13import android.service.chooser.ChooserTarget;
14import android.service.chooser.ChooserTargetService;
15
16import java.util.ArrayList;
17import java.util.List;
18
19import eu.siacs.conversations.entities.Conversation;
20import eu.siacs.conversations.ui.ConversationsActivity;
21import eu.siacs.conversations.utils.Compatibility;
22
23@TargetApi(Build.VERSION_CODES.M)
24public class ContactChooserTargetService extends ChooserTargetService implements ServiceConnection {
25
26 private final Object lock = new Object();
27 private final int MAX_TARGETS = 5;
28 private XmppConnectionService mXmppConnectionService;
29
30 private static boolean textOnly(IntentFilter filter) {
31 for (int i = 0; i < filter.countDataTypes(); ++i) {
32 if (!"text/plain".equals(filter.getDataType(i))) {
33 return false;
34 }
35 }
36 return true;
37 }
38
39 @Override
40 public List<ChooserTarget> onGetChooserTargets(ComponentName targetActivityName, IntentFilter matchedFilter) {
41 final ArrayList<ChooserTarget> chooserTargets = new ArrayList<>();
42 if (!EventReceiver.hasEnabledAccounts(this)) {
43 return chooserTargets;
44 }
45 final Intent intent = new Intent(this, XmppConnectionService.class);
46 intent.setAction("contact_chooser");
47 Compatibility.startService(this, intent);
48 bindService(intent, this, Context.BIND_AUTO_CREATE);
49 try {
50 waitForService();
51 final ArrayList<Conversation> conversations = new ArrayList<>();
52 if (!mXmppConnectionService.areMessagesInitialized()) {
53 return chooserTargets;
54 }
55
56 mXmppConnectionService.populateWithOrderedConversations(conversations, textOnly(matchedFilter));
57 final ComponentName componentName = new ComponentName(this, ConversationsActivity.class);
58 final int pixel = AvatarService.getSystemUiAvatarSize(this);
59 for (Conversation conversation : conversations) {
60 if (conversation.sentMessagesCount() == 0) {
61 continue;
62 }
63 final String name = conversation.getName().toString();
64 final Icon icon = Icon.createWithBitmap(mXmppConnectionService.getAvatarService().get(conversation, pixel));
65 final float score = 1 - (1.0f / MAX_TARGETS) * chooserTargets.size();
66 final Bundle extras = new Bundle();
67 extras.putString(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());
68 chooserTargets.add(new ChooserTarget(name, icon, score, componentName, extras));
69 if (chooserTargets.size() >= MAX_TARGETS) {
70 break;
71 }
72 }
73 } catch (InterruptedException e) {
74 }
75 unbindService(this);
76 return chooserTargets;
77 }
78
79 @Override
80 public void onServiceConnected(ComponentName name, IBinder service) {
81 XmppConnectionService.XmppConnectionBinder binder = (XmppConnectionService.XmppConnectionBinder) service;
82 mXmppConnectionService = binder.getService();
83 synchronized (this.lock) {
84 lock.notifyAll();
85 }
86 }
87
88 @Override
89 public void onServiceDisconnected(ComponentName name) {
90 mXmppConnectionService = null;
91 }
92
93 private void waitForService() throws InterruptedException {
94 if (mXmppConnectionService == null) {
95 synchronized (this.lock) {
96 lock.wait();
97 }
98 }
99 }
100}