summaryrefslogtreecommitdiff
path: root/base/src/main/java/com/smartdevicelink/managers/screen/BaseSubscribeButtonManager.java
blob: 05addbffe12a7af2c24639800d04180370c0750b (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package com.smartdevicelink.managers.screen;

import androidx.annotation.NonNull;

import com.smartdevicelink.managers.BaseSubManager;
import com.smartdevicelink.managers.CompletionListener;
import com.smartdevicelink.managers.ISdl;
import com.smartdevicelink.protocol.enums.FunctionID;
import com.smartdevicelink.proxy.RPCNotification;
import com.smartdevicelink.proxy.RPCResponse;
import com.smartdevicelink.proxy.rpc.OnButtonEvent;
import com.smartdevicelink.proxy.rpc.OnButtonPress;
import com.smartdevicelink.proxy.rpc.SubscribeButton;
import com.smartdevicelink.proxy.rpc.UnsubscribeButton;
import com.smartdevicelink.proxy.rpc.enums.ButtonName;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener;
import com.smartdevicelink.util.DebugTool;

import java.util.HashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * <strong>SubscribeButtonManager</strong> <br>
 * <p>
 * Note: This class must be accessed through the SdlManager. Do not instantiate it by itself. <br>
 */
abstract class BaseSubscribeButtonManager extends BaseSubManager {

    private static final String TAG = "SubscribeButtonManager";
    final HashMap<ButtonName, CopyOnWriteArrayList<OnButtonListener>> onButtonListeners;
    private OnRPCNotificationListener onButtonPressListener;
    private OnRPCNotificationListener onButtonEventListener;

    BaseSubscribeButtonManager(@NonNull ISdl internalInterface) {
        super(internalInterface);
        setRpcNotificationListeners();
        onButtonListeners = new HashMap<>();
    }

    @Override
    public void start(CompletionListener listener) {
        transitionToState(READY);
        super.start(listener);
    }

    @Override
    public void dispose() {
        super.dispose();
        if (onButtonListeners != null) {
            onButtonListeners.clear();
        }
        internalInterface.removeOnRPCNotificationListener(FunctionID.ON_BUTTON_PRESS, onButtonPressListener);
        internalInterface.removeOnRPCNotificationListener(FunctionID.ON_BUTTON_EVENT, onButtonEventListener);
    }

    /***
     * Checks to see if Button is already subscribed and adds listener to hashmap.
     * If button is not already subscribed to, it call method:
     * subscribeButtonRequest to send RPC request
     * @param buttonName - Is the button that the developer wants to subscribe to
     * @param listener - Is the listener that was sent by developer
     */
    void addButtonListener(ButtonName buttonName, OnButtonListener listener) {
        if (listener == null) {
            DebugTool.logError(TAG, "OnButtonListener cannot be null");
            return;
        }
        if (buttonName == null) {
            listener.onError("ButtonName cannot be null");
            return;
        }

        if (onButtonListeners.get(buttonName) == null) {
            subscribeButtonRequest(buttonName, listener);
            return;
        }

        if (onButtonListeners.get(buttonName).contains(listener)) {
            DebugTool.logWarning(TAG, "Already subscribed to button named: " + buttonName);
            return;
        }
        onButtonListeners.get(buttonName).add(listener);
    }

    /**
     * Unsubscribe form button and/or listener sent by developer
     *
     * @param buttonName Is the button that the developer wants to unsubscribe from
     * @param listener   - the listener that was sent by developer
     */
    void removeButtonListener(final ButtonName buttonName, final OnButtonListener listener) {
        if (listener == null) {
            DebugTool.logError(TAG, "OnButtonListener cannot be null: ");
            return;
        }

        if (buttonName == null) {
            listener.onError("ButtonName cannot be null");
            return;
        }

        if (onButtonListeners.get(buttonName) == null || !onButtonListeners.get(buttonName).contains(listener)) {
            listener.onError("Attempting to unsubscribe to the " + buttonName + " button failed because it is not currently subscribed");
            return;
        }

        if (onButtonListeners.get(buttonName).size() > 1) {
            onButtonListeners.get(buttonName).remove(listener);
            return;
        }
        unsubscribeButtonRequest(buttonName, listener);
    }

    /**
     * Send the UnsubscribeButton RPC
     *
     * @param buttonName - ButtonName - name of button
     * @param listener - OnButtonListener - listener to get notified
     */
    private void unsubscribeButtonRequest(final ButtonName buttonName, final OnButtonListener listener) {
        UnsubscribeButton unsubscribeButtonRequest = new UnsubscribeButton(buttonName);
        unsubscribeButtonRequest.setOnRPCResponseListener(new OnRPCResponseListener() {
            @Override
            public void onResponse(int correlationId, RPCResponse response) {
                if (response.getSuccess()) {
                    onButtonListeners.remove(buttonName);
                } else {
                    listener.onError("Attempt to unsubscribe to button named " + buttonName + " Failed. ResultCode: " + response.getResultCode() + " info: " + response.getInfo());
                }
            }
        });
        internalInterface.sendRPC(unsubscribeButtonRequest);
    }

    /**
     * Send the SubscribeButton RPC
     *
     * @param buttonName - ButtonName - name of button
     * @param listener   - OnButtonListener - listener to get notified
     */
    private void subscribeButtonRequest(final ButtonName buttonName, final OnButtonListener listener) {
        SubscribeButton subscribeButtonRequest = new SubscribeButton(buttonName);
        subscribeButtonRequest.setOnRPCResponseListener(new OnRPCResponseListener() {
            @Override
            public void onResponse(int correlationId, RPCResponse response) {
                if (response.getSuccess()) {
                    onButtonListeners.put(buttonName, new CopyOnWriteArrayList<OnButtonListener>());
                    onButtonListeners.get(buttonName).add(listener);
                } else {
                    listener.onError("Attempt to subscribe to button named " + buttonName + " Failed . ResultCode: " + response.getResultCode() + " info: " + response.getInfo());
                }
            }
        });
        internalInterface.sendRPC(subscribeButtonRequest);
    }

    /**
     * Sets up RpcNotificationListeners for button presses and events, is setup when manager is created
     */
    private void setRpcNotificationListeners() {
        onButtonPressListener = new OnRPCNotificationListener() {
            @Override
            public void onNotified(RPCNotification notification) {
                OnButtonPress onButtonPressNotification = (OnButtonPress) notification;
                CopyOnWriteArrayList<OnButtonListener> listeners = onButtonListeners.get(onButtonPressNotification.getButtonName());
                if (listeners != null && listeners.size() > 0) {
                    for (OnButtonListener listener : listeners) {
                        listener.onPress(onButtonPressNotification.getButtonName(), onButtonPressNotification);
                    }
                }
            }
        };
        internalInterface.addOnRPCNotificationListener(FunctionID.ON_BUTTON_PRESS, onButtonPressListener);

        onButtonEventListener = new OnRPCNotificationListener() {
            @Override
            public void onNotified(RPCNotification notification) {
                OnButtonEvent onButtonEvent = (OnButtonEvent) notification;
                CopyOnWriteArrayList<OnButtonListener> listeners = onButtonListeners.get(onButtonEvent.getButtonName());
                if (listeners != null && listeners.size() > 0) {
                    for (OnButtonListener listener : listeners) {
                        listener.onEvent(onButtonEvent.getButtonName(), onButtonEvent);
                    }
                }
            }
        };
        internalInterface.addOnRPCNotificationListener(FunctionID.ON_BUTTON_EVENT, onButtonEventListener);
    }
}