aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/services/ShortcutService.java
blob: 56345c663be89bba7ac3d2ea981a91511c94d165 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package de.pixart.messenger.services;

import android.annotation.TargetApi;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import de.pixart.messenger.Config;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Contact;
import de.pixart.messenger.ui.StartConversationActivity;
import de.pixart.messenger.utils.ReplacingSerialSingleThreadExecutor;
import de.pixart.messenger.xmpp.jid.Jid;

public class ShortcutService {
    private final XmppConnectionService xmppConnectionService;
    private final ReplacingSerialSingleThreadExecutor replacingSerialSingleThreadExecutor = new ReplacingSerialSingleThreadExecutor(false);

    public ShortcutService(XmppConnectionService xmppConnectionService) {
        this.xmppConnectionService = xmppConnectionService;
    }

    public void refresh() {
        refresh(false);
    }

    public void refresh(final boolean forceUpdate) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            final Runnable r = new Runnable() {
                @Override
                public void run() {
                    refreshImpl(forceUpdate);
                }
            };
            replacingSerialSingleThreadExecutor.execute(r);
        }
    }

    @TargetApi(25)
    public void report(Contact contact) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            ShortcutManager shortcutManager = xmppConnectionService.getSystemService(ShortcutManager.class);
            shortcutManager.reportShortcutUsed(getShortcutId(contact));
        }
    }

    @TargetApi(25)
    private void refreshImpl(boolean forceUpdate) {
        List<FrequentContact> frequentContacts = xmppConnectionService.databaseBackend.getFrequentContacts(30);
        HashMap<String, Account> accounts = new HashMap<>();
        for (Account account : xmppConnectionService.getAccounts()) {
            accounts.put(account.getUuid(), account);
        }
        List<Contact> contacts = new ArrayList<>();
        for (FrequentContact frequentContact : frequentContacts) {
            Account account = accounts.get(frequentContact.account);
            if (account != null) {
                contacts.add(account.getRoster().getContact(frequentContact.contact));
            }
        }
        ShortcutManager shortcutManager = xmppConnectionService.getSystemService(ShortcutManager.class);
        boolean needsUpdate = forceUpdate || contactsChanged(contacts, shortcutManager.getDynamicShortcuts());
        if (!needsUpdate) {
            Log.d(Config.LOGTAG, "skipping shortcut update");
            return;
        }
        List<ShortcutInfo> newDynamicShortCuts = new ArrayList<>();
        for (Contact contact : contacts) {
            ShortcutInfo shortcut = new ShortcutInfo.Builder(xmppConnectionService, getShortcutId(contact))
                    .setShortLabel(contact.getDisplayName())
                    .setIntent(getShortcutIntent(contact))
                    .setIcon(Icon.createWithBitmap(xmppConnectionService.getAvatarService().getRoundedShortcut(contact)))
                    .build();
            newDynamicShortCuts.add(shortcut);
        }
        if (shortcutManager.setDynamicShortcuts(newDynamicShortCuts)) {
            Log.d(Config.LOGTAG, "updated dynamic shortcuts");
        } else {
            Log.d(Config.LOGTAG, "unable to update dynamic shortcuts");
        }
    }

    private static boolean contactsChanged(List<Contact> needles, List<ShortcutInfo> haystack) {
        for (Contact needle : needles) {
            if (!contactExists(needle, haystack)) {
                return true;
            }
        }
        return needles.size() != haystack.size();
    }

    @TargetApi(25)
    private static boolean contactExists(Contact needle, List<ShortcutInfo> haystack) {
        for (ShortcutInfo shortcutInfo : haystack) {
            if (getShortcutId(needle).equals(shortcutInfo.getId()) && needle.getDisplayName().equals(shortcutInfo.getShortLabel())) {
                return true;
            }
        }
        return false;
    }

    private static String getShortcutId(Contact contact) {
        return contact.getAccount().getJid().toBareJid().toPreppedString() + "#" + contact.getJid().toBareJid().toPreppedString();
    }

    private Intent getShortcutIntent(Contact contact) {
        Intent intent = new Intent(xmppConnectionService, StartConversationActivity.class);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("xmpp:" + contact.getJid().toBareJid().toString()));
        intent.putExtra("account", contact.getAccount().getJid().toBareJid().toString());
        return intent;
    }

    public static class FrequentContact {
        private final String account;
        private final Jid contact;

        public FrequentContact(String account, Jid contact) {
            this.account = account;
            this.contact = contact;
        }
    }
}