]> git.basschouten.com Git - openhab-addons.git/blob
caa5cbefc3f1525c65ccdcbf05d4ec7a4343e7ea
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 /*
14  * WebOSTVKeyboardInput
15  * Connect SDK
16  *
17  * Copyright (c) 2014 LG Electronics.
18  * Created by Hyun Kook Khang on 19 Jan 2014
19  *
20  * Licensed under the Apache License, Version 2.0 (the "License");
21  * you may not use this file except in compliance with the License.
22  * You may obtain a copy of the License at
23  *
24  *     http://www.apache.org/licenses/LICENSE-2.0
25  *
26  * Unless required by applicable law or agreed to in writing, software
27  * distributed under the License is distributed on an "AS IS" BASIS,
28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  * See the License for the specific language governing permissions and
30  * limitations under the License.
31  */
32
33 package org.openhab.binding.lgwebos.internal.handler;
34
35 import java.util.ArrayList;
36 import java.util.List;
37
38 import org.openhab.binding.lgwebos.internal.handler.command.ServiceCommand;
39 import org.openhab.binding.lgwebos.internal.handler.command.ServiceSubscription;
40 import org.openhab.binding.lgwebos.internal.handler.core.ResponseListener;
41 import org.openhab.binding.lgwebos.internal.handler.core.TextInputStatusInfo;
42
43 import com.google.gson.JsonObject;
44
45 /**
46  * {@link LGWebOSTVKeyboardInput} handles WebOSTV keyboard api.
47  *
48  * @author Hyun Kook Khang - Connect SDK initial contribution
49  * @author Sebastian Prehn - Adoption for openHAB
50  */
51 public class LGWebOSTVKeyboardInput {
52
53     private LGWebOSTVSocket service;
54     private boolean waiting;
55     private final List<String> toSend;
56
57     private static final String KEYBOARD_INPUT = "ssap://com.webos.service.ime/registerRemoteKeyboard";
58     private static final String ENTER = "ENTER";
59     private static final String DELETE = "DELETE";
60
61     public LGWebOSTVKeyboardInput(LGWebOSTVSocket service) {
62         this.service = service;
63         waiting = false;
64         toSend = new ArrayList<>();
65     }
66
67     public void sendText(String input) {
68         toSend.add(input);
69         if (!waiting) { // TODO: use a latch,and send in any case
70             sendData();
71         }
72     }
73
74     public void sendEnter() {
75         sendText(ENTER);
76     }
77
78     public void sendDel() {
79         if (toSend.isEmpty()) {
80             toSend.add(DELETE);
81             if (!waiting) {
82                 sendData();
83             }
84         } else {
85             toSend.remove(toSend.size() - 1);
86         }
87     }
88
89     private void sendData() {
90         waiting = true;
91
92         String uri;
93         String typeTest = toSend.get(0);
94
95         JsonObject payload = new JsonObject();
96
97         if (typeTest.equals(ENTER)) {
98             toSend.remove(0);
99             uri = "ssap://com.webos.service.ime/sendEnterKey";
100         } else if (typeTest.equals(DELETE)) {
101             uri = "ssap://com.webos.service.ime/deleteCharacters";
102
103             int count = 0;
104             while (!toSend.isEmpty() && toSend.get(0).equals(DELETE)) {
105                 toSend.remove(0);
106                 count++;
107             }
108
109             payload.addProperty("count", count);
110         } else {
111             uri = "ssap://com.webos.service.ime/insertText";
112             StringBuilder sb = new StringBuilder();
113
114             while (!toSend.isEmpty() && !(toSend.get(0).equals(DELETE) || toSend.get(0).equals(ENTER))) {
115                 String text = toSend.get(0);
116                 sb.append(text);
117                 toSend.remove(0);
118             }
119
120             payload.addProperty("text", sb.toString());
121             payload.addProperty("replace", 0);
122         }
123
124         ResponseListener<JsonObject> responseListener = new ResponseListener<>() {
125
126             @Override
127             public void onSuccess(JsonObject response) {
128                 waiting = false;
129                 if (!toSend.isEmpty()) {
130                     sendData();
131                 }
132             }
133
134             @Override
135             public void onError(String error) {
136                 waiting = false;
137                 if (!toSend.isEmpty()) {
138                     sendData();
139                 }
140             }
141         };
142
143         ServiceCommand<JsonObject> request = new ServiceCommand<>(uri, payload, x -> x, responseListener);
144         service.sendCommand(request);
145     }
146
147     public ServiceSubscription<TextInputStatusInfo> connect(final ResponseListener<TextInputStatusInfo> listener) {
148         ServiceSubscription<TextInputStatusInfo> subscription = new ServiceSubscription<>(KEYBOARD_INPUT, null,
149                 rawData -> parseRawKeyboardData(rawData), listener);
150         service.sendCommand(subscription);
151
152         return subscription;
153     }
154
155     private TextInputStatusInfo parseRawKeyboardData(JsonObject rawData) {
156         boolean focused = false;
157         String contentType = null;
158         boolean predictionEnabled = false;
159         boolean correctionEnabled = false;
160         boolean autoCapitalization = false;
161         boolean hiddenText = false;
162         boolean focusChanged = false;
163
164         TextInputStatusInfo keyboard = new TextInputStatusInfo();
165         keyboard.setRawData(rawData);
166
167         if (rawData.has("currentWidget")) {
168             JsonObject currentWidget = (JsonObject) rawData.get("currentWidget");
169             focused = currentWidget.get("focus").getAsBoolean();
170
171             if (currentWidget.has("contentType")) {
172                 contentType = currentWidget.get("contentType").getAsString();
173             }
174             if (currentWidget.has("predictionEnabled")) {
175                 predictionEnabled = currentWidget.get("predictionEnabled").getAsBoolean();
176             }
177             if (currentWidget.has("correctionEnabled")) {
178                 correctionEnabled = currentWidget.get("correctionEnabled").getAsBoolean();
179             }
180             if (currentWidget.has("autoCapitalization")) {
181                 autoCapitalization = currentWidget.get("autoCapitalization").getAsBoolean();
182             }
183             if (currentWidget.has("hiddenText")) {
184                 hiddenText = currentWidget.get("hiddenText").getAsBoolean();
185             }
186         }
187         if (rawData.has("focusChanged")) {
188             focusChanged = rawData.get("focusChanged").getAsBoolean();
189         }
190
191         keyboard.setFocused(focused);
192         keyboard.setContentType(contentType);
193         keyboard.setPredictionEnabled(predictionEnabled);
194         keyboard.setCorrectionEnabled(correctionEnabled);
195         keyboard.setAutoCapitalization(autoCapitalization);
196         keyboard.setHiddenText(hiddenText);
197         keyboard.setFocusChanged(focusChanged);
198
199         return keyboard;
200     }
201 }