[androidtv] Adds additional i18n support to ConnectionManagers (#15184)

Signed-off-by: Ben Rosenblum <rosenblumb@gmail.com>
This commit is contained in:
morph166955 2023-07-15 02:39:45 -05:00 committed by GitHub
parent 4edad54e83
commit cad86bc83b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 138 additions and 53 deletions

View File

@ -61,13 +61,15 @@ public class AndroidTVHandler extends BaseThingHandler {
private static final int THING_STATUS_FREQUENCY = 250; private static final int THING_STATUS_FREQUENCY = 250;
private final AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider; private final AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider;
private final AndroidTVTranslationProvider translationProvider;
private final ThingTypeUID thingTypeUID; private final ThingTypeUID thingTypeUID;
private final String thingID; private final String thingID;
public AndroidTVHandler(Thing thing, AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider, public AndroidTVHandler(Thing thing, AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider,
ThingTypeUID thingTypeUID) { AndroidTVTranslationProvider translationProvider, ThingTypeUID thingTypeUID) {
super(thing); super(thing);
this.commandDescriptionProvider = commandDescriptionProvider; this.commandDescriptionProvider = commandDescriptionProvider;
this.translationProvider = translationProvider;
this.thingTypeUID = thingTypeUID; this.thingTypeUID = thingTypeUID;
this.thingID = this.getThing().getUID().getId(); this.thingID = this.getThing().getUID().getId();
} }
@ -76,6 +78,10 @@ public class AndroidTVHandler extends BaseThingHandler {
thing.setProperty(property, value); thing.setProperty(property, value);
} }
public AndroidTVTranslationProvider getTranslationProvider() {
return translationProvider;
}
public String getThingID() { public String getThingID() {
return this.thingID; return this.thingID;
} }
@ -113,21 +119,17 @@ public class AndroidTVHandler extends BaseThingHandler {
if (googletvConnectionManager != null) { if (googletvConnectionManager != null) {
if (!googletvConnectionManager.getLoggedIn()) { if (!googletvConnectionManager.getLoggedIn()) {
statusMessage = "GoogleTV: " + googletvConnectionManager.getStatusMessage();
failed = true; failed = true;
} else {
statusMessage = "GoogleTV: ONLINE";
} }
statusMessage = "GoogleTV: " + googletvConnectionManager.getStatusMessage();
} }
if (THING_TYPE_SHIELDTV.equals(thingTypeUID)) { if (THING_TYPE_SHIELDTV.equals(thingTypeUID)) {
if (shieldtvConnectionManager != null) { if (shieldtvConnectionManager != null) {
if (!shieldtvConnectionManager.getLoggedIn()) { if (!shieldtvConnectionManager.getLoggedIn()) {
statusMessage = statusMessage + " | ShieldTV: " + shieldtvConnectionManager.getStatusMessage();
failed = true; failed = true;
} else {
statusMessage = statusMessage + " | ShieldTV: ONLINE";
} }
statusMessage = statusMessage + " | ShieldTV: " + shieldtvConnectionManager.getStatusMessage();
} }
} }

View File

@ -18,6 +18,8 @@ import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory; import org.openhab.core.thing.binding.BaseThingHandlerFactory;
@ -41,11 +43,14 @@ public class AndroidTVHandlerFactory extends BaseThingHandlerFactory {
THING_TYPE_SHIELDTV); THING_TYPE_SHIELDTV);
private final AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider; private final AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider;
private final AndroidTVTranslationProvider translationProvider;
@Activate @Activate
public AndroidTVHandlerFactory( public AndroidTVHandlerFactory(
final @Reference AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider) { final @Reference AndroidTVDynamicCommandDescriptionProvider commandDescriptionProvider,
final @Reference TranslationProvider i18nProvider, final @Reference LocaleProvider localeProvider) {
this.commandDescriptionProvider = commandDescriptionProvider; this.commandDescriptionProvider = commandDescriptionProvider;
this.translationProvider = new AndroidTVTranslationProvider(i18nProvider, localeProvider);
} }
@Override @Override
@ -56,6 +61,6 @@ public class AndroidTVHandlerFactory extends BaseThingHandlerFactory {
@Override @Override
protected @Nullable ThingHandler createHandler(Thing thing) { protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID(); ThingTypeUID thingTypeUID = thing.getThingTypeUID();
return new AndroidTVHandler(thing, commandDescriptionProvider, thingTypeUID); return new AndroidTVHandler(thing, commandDescriptionProvider, translationProvider, thingTypeUID);
} }
} }

View File

@ -0,0 +1,54 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.androidtv.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@link AndroidTVTranslationProvider} provides i18n message lookup.
*
* @author Ben Rosenblum - Initial contribution
*/
@NonNullByDefault
public class AndroidTVTranslationProvider {
private final Bundle bundle;
private final TranslationProvider i18nProvider;
private final LocaleProvider localeProvider;
private final Logger logger = LoggerFactory.getLogger(AndroidTVTranslationProvider.class);
public AndroidTVTranslationProvider(TranslationProvider i18nProvider, LocaleProvider localeProvider) {
this.bundle = FrameworkUtil.getBundle(this.getClass());
this.i18nProvider = i18nProvider;
this.localeProvider = localeProvider;
}
public String getText(String key, @Nullable Object... arguments) {
@Nullable
String text = i18nProvider.getText(bundle, key, null, localeProvider.getLocale(), arguments);
if (text != null) {
logger.trace("Translated: {} as {}", key, text);
return text;
} else {
logger.trace("Failed to translate: {}", key);
return key;
}
}
}

View File

@ -60,6 +60,7 @@ import javax.net.ssl.X509TrustManager;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.androidtv.internal.AndroidTVHandler; import org.openhab.binding.androidtv.internal.AndroidTVHandler;
import org.openhab.binding.androidtv.internal.AndroidTVTranslationProvider;
import org.openhab.binding.androidtv.internal.utils.AndroidTVPKI; import org.openhab.binding.androidtv.internal.utils.AndroidTVPKI;
import org.openhab.core.OpenHAB; import org.openhab.core.OpenHAB;
import org.openhab.core.library.types.NextPreviousType; import org.openhab.core.library.types.NextPreviousType;
@ -97,6 +98,7 @@ public class GoogleTVConnectionManager {
private final AndroidTVHandler handler; private final AndroidTVHandler handler;
private GoogleTVConfiguration config; private GoogleTVConfiguration config;
private final AndroidTVTranslationProvider translationProvider;
private @NonNullByDefault({}) SSLSocketFactory sslSocketFactory; private @NonNullByDefault({}) SSLSocketFactory sslSocketFactory;
private @Nullable SSLSocket sslSocket; private @Nullable SSLSocket sslSocket;
@ -166,6 +168,7 @@ public class GoogleTVConnectionManager {
messageParser = new GoogleTVMessageParser(this); messageParser = new GoogleTVMessageParser(this);
this.config = config; this.config = config;
this.handler = handler; this.handler = handler;
this.translationProvider = handler.getTranslationProvider();
this.connectionManager = this; this.connectionManager = this;
this.scheduler = handler.getScheduler(); this.scheduler = handler.getScheduler();
this.encryptionKey = androidtvPKI.generateEncryptionKey(); this.encryptionKey = androidtvPKI.generateEncryptionKey();
@ -177,6 +180,7 @@ public class GoogleTVConnectionManager {
messageParser = new GoogleTVMessageParser(this); messageParser = new GoogleTVMessageParser(this);
this.config = config; this.config = config;
this.handler = handler; this.handler = handler;
this.translationProvider = handler.getTranslationProvider();
this.connectionManager = connectionManager; this.connectionManager = connectionManager;
this.scheduler = handler.getScheduler(); this.scheduler = handler.getScheduler();
this.encryptionKey = androidtvPKI.generateEncryptionKey(); this.encryptionKey = androidtvPKI.generateEncryptionKey();
@ -298,16 +302,17 @@ public class GoogleTVConnectionManager {
private void setStatus(boolean isLoggedIn) { private void setStatus(boolean isLoggedIn) {
if (isLoggedIn) { if (isLoggedIn) {
setStatus(isLoggedIn, "ONLINE"); setStatus(isLoggedIn, "online.online");
} else { } else {
setStatus(isLoggedIn, "UNKNOWN"); setStatus(isLoggedIn, "offline.unknown");
} }
} }
private void setStatus(boolean isLoggedIn, String statusMessage) { private void setStatus(boolean isLoggedIn, String statusMessage) {
if ((this.isLoggedIn != isLoggedIn) || (!this.statusMessage.equals(statusMessage))) { String translatedMessage = translationProvider.getText(statusMessage);
if ((this.isLoggedIn != isLoggedIn) || (!this.statusMessage.equals(translatedMessage))) {
this.isLoggedIn = isLoggedIn; this.isLoggedIn = isLoggedIn;
this.statusMessage = statusMessage; this.statusMessage = translatedMessage;
handler.checkThingStatus(); handler.checkThingStatus();
} }
} }
@ -501,10 +506,10 @@ public class GoogleTVConnectionManager {
shimAsyncInitializeTask = scheduler.submit(this::shimInitialize); shimAsyncInitializeTask = scheduler.submit(this::shimInitialize);
} }
} catch (NoSuchAlgorithmException | IOException e) { } catch (NoSuchAlgorithmException | IOException e) {
setStatus(false, "Error initializing keystore"); setStatus(false, "offline.error-initalizing-keystore");
logger.debug("Error initializing keystore", e); logger.debug("Error initializing keystore", e);
} catch (UnrecoverableKeyException e) { } catch (UnrecoverableKeyException e) {
setStatus(false, "Key unrecoverable with supplied password"); setStatus(false, "offline.key-unrecoverable-with-supplied-password");
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
logger.debug("General security exception", e); logger.debug("General security exception", e);
} catch (Exception e) { } catch (Exception e) {
@ -530,12 +535,12 @@ public class GoogleTVConnectionManager {
logger.debug("{} - Connection to {}:{} {} successful", handler.getThingID(), config.ipAddress, logger.debug("{} - Connection to {}:{} {} successful", handler.getThingID(), config.ipAddress,
config.port, config.mode); config.port, config.mode);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
setStatus(false, "Unknown host"); setStatus(false, "offline.unknown-host");
logger.debug("{} - Unknown host {}", handler.getThingID(), config.ipAddress); logger.debug("{} - Unknown host {}", handler.getThingID(), config.ipAddress);
return; return;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// port out of valid range // port out of valid range
setStatus(false, "Invalid port number"); setStatus(false, "offline.invalid-port-number");
logger.debug("{} - Invalid port number {}:{}", handler.getThingID(), config.ipAddress, config.port); logger.debug("{} - Invalid port number {}:{}", handler.getThingID(), config.ipAddress, config.port);
return; return;
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
@ -546,7 +551,7 @@ public class GoogleTVConnectionManager {
String message = e.getMessage(); String message = e.getMessage();
if ((message != null) && (message.contains("certificate_unknown")) if ((message != null) && (message.contains("certificate_unknown"))
&& (!config.mode.equals(PIN_MODE)) && (!config.shim)) { && (!config.mode.equals(PIN_MODE)) && (!config.shim)) {
setStatus(false, "PIN Process Incomplete"); setStatus(false, "offline.pin-process-incomplete");
logger.debug("{} - GoogleTV PIN Process Incomplete", handler.getThingID()); logger.debug("{} - GoogleTV PIN Process Incomplete", handler.getThingID());
reconnectTaskCancel(true); reconnectTaskCancel(true);
startChildConnectionManager(this.config.port + 1, PIN_MODE); startChildConnectionManager(this.config.port + 1, PIN_MODE);
@ -562,8 +567,8 @@ public class GoogleTVConnectionManager {
this.shimServerSocket = null; this.shimServerSocket = null;
} }
} else { } else {
setStatus(false, "Error opening GoogleTV SSL connection. Check log."); setStatus(false, "offline.error-opening-ssl-connection-check-log");
logger.info("{} - Error opening GoogleTV SSL connection to {}:{} {}", handler.getThingID(), logger.info("{} - Error opening SSL connection to {}:{} {}", handler.getThingID(),
config.ipAddress, config.port, e.getMessage()); config.ipAddress, config.port, e.getMessage());
disconnect(false); disconnect(false);
scheduleConnectRetry(config.reconnect); // Possibly a temporary problem. Try again later. scheduleConnectRetry(config.reconnect); // Possibly a temporary problem. Try again later.
@ -571,7 +576,7 @@ public class GoogleTVConnectionManager {
return; return;
} }
setStatus(false, "Initializing"); setStatus(false, "offline.initializing");
logger.trace("{} - Starting Reader Thread for {}:{}", handler.getThingID(), config.ipAddress, logger.trace("{} - Starting Reader Thread for {}:{}", handler.getThingID(), config.ipAddress,
config.port); config.port);
@ -826,7 +831,7 @@ public class GoogleTVConnectionManager {
synchronized (connectionLock) { synchronized (connectionLock) {
if (!this.disposing) { if (!this.disposing) {
logger.debug("{} - Attempting to reconnect to the GoogleTV", handler.getThingID()); logger.debug("{} - Attempting to reconnect to the GoogleTV", handler.getThingID());
setStatus(false, "reconnecting"); setStatus(false, "offline.reconnecting");
disconnect(false); disconnect(false);
connect(); connect();
} }
@ -852,12 +857,12 @@ public class GoogleTVConnectionManager {
} }
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
logger.debug("Interrupted while sending to GoogleTV"); logger.debug("Interrupted while sending to GoogleTV");
setStatus(false, "Interrupted"); setStatus(false, "offline.interrupted");
break; // exit loop and terminate thread break; // exit loop and terminate thread
} catch (IOException e) { } catch (IOException e) {
logger.warn("{} - Communication error, will try to reconnect GoogleTV. Error: {}", logger.warn("{} - Communication error, will try to reconnect GoogleTV. Error: {}",
handler.getThingID(), e.getMessage()); handler.getThingID(), e.getMessage());
setStatus(false, "Communication error, will try to reconnect"); setStatus(false, "offline.communication-error-will-try-to-reconnect");
sendQueue.add(command); // Requeue command sendQueue.add(command); // Requeue command
this.isLoggedIn = false; this.isLoggedIn = false;
reconnect(); reconnect();
@ -944,12 +949,12 @@ public class GoogleTVConnectionManager {
} }
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
logger.debug("Interrupted while reading"); logger.debug("Interrupted while reading");
setStatus(false, "Interrupted"); setStatus(false, "offline.interrupted");
} catch (IOException e) { } catch (IOException e) {
String message = e.getMessage(); String message = e.getMessage();
if ((message != null) && (message.contains("certificate_unknown")) && (!config.mode.equals(PIN_MODE)) if ((message != null) && (message.contains("certificate_unknown")) && (!config.mode.equals(PIN_MODE))
&& (!config.shim)) { && (!config.shim)) {
setStatus(false, "PIN Process Incomplete"); setStatus(false, "offline.pin-process-incomplete");
logger.debug("{} - GoogleTV PIN Process Incomplete", handler.getThingID()); logger.debug("{} - GoogleTV PIN Process Incomplete", handler.getThingID());
reconnectTaskCancel(true); reconnectTaskCancel(true);
startChildConnectionManager(this.config.port + 1, PIN_MODE); startChildConnectionManager(this.config.port + 1, PIN_MODE);
@ -966,11 +971,11 @@ public class GoogleTVConnectionManager {
} }
} else { } else {
logger.debug("I/O error while reading from stream: {}", e.getMessage()); logger.debug("I/O error while reading from stream: {}", e.getMessage());
setStatus(false, "I/O Error"); setStatus(false, "offline.io-error");
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
logger.warn("Runtime exception in reader thread", e); logger.warn("Runtime exception in reader thread", e);
setStatus(false, "Runtime exception"); setStatus(false, "offline.runtime-exception");
} finally { } finally {
logger.debug("{} - Message reader thread exiting {}", handler.getThingID(), config.port); logger.debug("{} - Message reader thread exiting {}", handler.getThingID(), config.port);
} }
@ -1038,13 +1043,13 @@ public class GoogleTVConnectionManager {
} }
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
logger.debug("Interrupted while reading"); logger.debug("Interrupted while reading");
setStatus(false, "Interrupted"); setStatus(false, "offline.interrupted");
} catch (IOException e) { } catch (IOException e) {
logger.debug("I/O error while reading from stream: {}", e.getMessage()); logger.debug("I/O error while reading from stream: {}", e.getMessage());
setStatus(false, "I/O Error"); setStatus(false, "offline.io-error");
} catch (RuntimeException e) { } catch (RuntimeException e) {
logger.warn("Runtime exception in reader thread", e); logger.warn("Runtime exception in reader thread", e);
setStatus(false, "Runtime exception"); setStatus(false, "offline.runtime-exception");
} finally { } finally {
logger.debug("Shim message reader thread exiting {}", config.port); logger.debug("Shim message reader thread exiting {}", config.port);
} }
@ -1263,7 +1268,7 @@ public class GoogleTVConnectionManager {
if (config.mode.equals(DEFAULT_MODE)) { if (config.mode.equals(DEFAULT_MODE)) {
if ((!isLoggedIn) && (command.toString().equals("REQUEST")) if ((!isLoggedIn) && (command.toString().equals("REQUEST"))
&& (childConnectionManager == null)) { && (childConnectionManager == null)) {
setStatus(false, "User Forced PIN Process"); setStatus(false, "offline.user-forced-pin-process");
logger.debug("{} - User Forced PIN Process", handler.getThingID()); logger.debug("{} - User Forced PIN Process", handler.getThingID());
disconnect(true); disconnect(true);
startChildConnectionManager(config.port + 1, PIN_MODE); startChildConnectionManager(config.port + 1, PIN_MODE);

View File

@ -58,6 +58,7 @@ import javax.net.ssl.X509TrustManager;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.androidtv.internal.AndroidTVHandler; import org.openhab.binding.androidtv.internal.AndroidTVHandler;
import org.openhab.binding.androidtv.internal.AndroidTVTranslationProvider;
import org.openhab.binding.androidtv.internal.utils.AndroidTVPKI; import org.openhab.binding.androidtv.internal.utils.AndroidTVPKI;
import org.openhab.core.OpenHAB; import org.openhab.core.OpenHAB;
import org.openhab.core.library.types.StringType; import org.openhab.core.library.types.StringType;
@ -87,6 +88,7 @@ public class ShieldTVConnectionManager {
private final AndroidTVHandler handler; private final AndroidTVHandler handler;
private ShieldTVConfiguration config; private ShieldTVConfiguration config;
private final AndroidTVTranslationProvider translationProvider;
private @NonNullByDefault({}) SSLSocketFactory sslSocketFactory; private @NonNullByDefault({}) SSLSocketFactory sslSocketFactory;
private @Nullable SSLSocket sslSocket; private @Nullable SSLSocket sslSocket;
@ -148,6 +150,7 @@ public class ShieldTVConnectionManager {
messageParser = new ShieldTVMessageParser(this); messageParser = new ShieldTVMessageParser(this);
this.config = config; this.config = config;
this.handler = handler; this.handler = handler;
this.translationProvider = handler.getTranslationProvider();
this.scheduler = handler.getScheduler(); this.scheduler = handler.getScheduler();
this.encryptionKey = androidtvPKI.generateEncryptionKey(); this.encryptionKey = androidtvPKI.generateEncryptionKey();
initialize(); initialize();
@ -215,16 +218,17 @@ public class ShieldTVConnectionManager {
private void setStatus(boolean isLoggedIn) { private void setStatus(boolean isLoggedIn) {
if (isLoggedIn) { if (isLoggedIn) {
setStatus(isLoggedIn, "ONLINE"); setStatus(isLoggedIn, "online.online");
} else { } else {
setStatus(isLoggedIn, "UNKNOWN"); setStatus(isLoggedIn, "offline.unknown");
} }
} }
private void setStatus(boolean isLoggedIn, String statusMessage) { private void setStatus(boolean isLoggedIn, String statusMessage) {
if ((this.isLoggedIn != isLoggedIn) || (!this.statusMessage.equals(statusMessage))) { String translatedMessage = translationProvider.getText(statusMessage);
if ((this.isLoggedIn != isLoggedIn) || (!this.statusMessage.equals(translatedMessage))) {
this.isLoggedIn = isLoggedIn; this.isLoggedIn = isLoggedIn;
this.statusMessage = statusMessage; this.statusMessage = translatedMessage;
handler.checkThingStatus(); handler.checkThingStatus();
} }
} }
@ -399,10 +403,10 @@ public class ShieldTVConnectionManager {
shimAsyncInitializeTask = scheduler.submit(this::shimInitialize); shimAsyncInitializeTask = scheduler.submit(this::shimInitialize);
} }
} catch (NoSuchAlgorithmException | IOException e) { } catch (NoSuchAlgorithmException | IOException e) {
setStatus(false, "Error initializing keystore"); setStatus(false, "offline.error-initalizing-keystore");
logger.debug("Error initializing keystore", e); logger.debug("Error initializing keystore", e);
} catch (UnrecoverableKeyException e) { } catch (UnrecoverableKeyException e) {
setStatus(false, "Key unrecoverable with supplied password"); setStatus(false, "offline.key-unrecoverable-with-supplied-password");
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
logger.debug("General security exception", e); logger.debug("General security exception", e);
} catch (Exception e) { } catch (Exception e) {
@ -424,26 +428,26 @@ public class ShieldTVConnectionManager {
new InputStreamReader(sslSocket.getInputStream(), StandardCharsets.ISO_8859_1)); new InputStreamReader(sslSocket.getInputStream(), StandardCharsets.ISO_8859_1));
this.sslSocket = sslSocket; this.sslSocket = sslSocket;
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
setStatus(false, "Unknown host"); setStatus(false, "offline.unknown-host");
return; return;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// port out of valid range // port out of valid range
setStatus(false, "Invalid port number"); setStatus(false, "offline.invalid-port-number");
return; return;
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
logger.debug("Interrupted while establishing ShieldTV connection"); logger.debug("Interrupted while establishing ShieldTV connection");
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
return; return;
} catch (IOException e) { } catch (IOException e) {
setStatus(false, "Error opening ShieldTV SSL connection. Check log."); setStatus(false, "offline.error-opening-ssl-connection-check-log");
logger.info("{} - Error opening ShieldTV SSL connection to {}:{} {}", handler.getThingID(), logger.info("{} - Error opening SSL connection to {}:{} {}", handler.getThingID(), config.ipAddress,
config.ipAddress, config.port, e.getMessage()); config.port, e.getMessage());
disconnect(false); disconnect(false);
scheduleConnectRetry(config.reconnect); // Possibly a temporary problem. Try again later. scheduleConnectRetry(config.reconnect); // Possibly a temporary problem. Try again later.
return; return;
} }
setStatus(false, "Initializing"); setStatus(false, "offline.initializing");
Thread readerThread = new Thread(this::readerThreadJob, "ShieldTV reader " + handler.getThingID()); Thread readerThread = new Thread(this::readerThreadJob, "ShieldTV reader " + handler.getThingID());
readerThread.setDaemon(true); readerThread.setDaemon(true);
@ -640,7 +644,7 @@ public class ShieldTVConnectionManager {
synchronized (connectionLock) { synchronized (connectionLock) {
if (!this.disposing) { if (!this.disposing) {
logger.debug("{} - Attempting to reconnect to the ShieldTV", handler.getThingID()); logger.debug("{} - Attempting to reconnect to the ShieldTV", handler.getThingID());
setStatus(false, "reconnecting"); setStatus(false, "offline.reconnecting");
disconnect(false); disconnect(false);
connect(); connect();
} }
@ -666,12 +670,12 @@ public class ShieldTVConnectionManager {
} }
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
logger.debug("Interrupted while sending to ShieldTV"); logger.debug("Interrupted while sending to ShieldTV");
setStatus(false, "Interrupted"); setStatus(false, "offline.interrupted");
break; // exit loop and terminate thread break; // exit loop and terminate thread
} catch (IOException e) { } catch (IOException e) {
logger.warn("{} - Communication error, will try to reconnect ShieldTV. Error: {}", logger.warn("{} - Communication error, will try to reconnect ShieldTV. Error: {}",
handler.getThingID(), e.getMessage()); handler.getThingID(), e.getMessage());
setStatus(false, "Communication error, will try to reconnect"); setStatus(false, "offline.communication-error-will-try-to-reconnect");
sendQueue.add(command); // Requeue command sendQueue.add(command); // Requeue command
this.isLoggedIn = false; this.isLoggedIn = false;
reconnect(); reconnect();
@ -785,13 +789,13 @@ public class ShieldTVConnectionManager {
} }
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
logger.debug("Interrupted while reading"); logger.debug("Interrupted while reading");
setStatus(false, "Interrupted"); setStatus(false, "offline.interrupted");
} catch (IOException e) { } catch (IOException e) {
logger.debug("I/O error while reading from stream: {}", e.getMessage()); logger.debug("I/O error while reading from stream: {}", e.getMessage());
setStatus(false, "I/O Error"); setStatus(false, "offline.io-error");
} catch (RuntimeException e) { } catch (RuntimeException e) {
logger.warn("Runtime exception in reader thread", e); logger.warn("Runtime exception in reader thread", e);
setStatus(false, "Runtime exception"); setStatus(false, "offline.runtime-exception");
} finally { } finally {
logger.debug("{} - Message reader thread exiting", handler.getThingID()); logger.debug("{} - Message reader thread exiting", handler.getThingID());
} }
@ -886,13 +890,13 @@ public class ShieldTVConnectionManager {
} }
} catch (InterruptedIOException e) { } catch (InterruptedIOException e) {
logger.debug("Interrupted while reading"); logger.debug("Interrupted while reading");
setStatus(false, "Interrupted"); setStatus(false, "offline.interrupted");
} catch (IOException e) { } catch (IOException e) {
logger.debug("I/O error while reading from stream: {}", e.getMessage()); logger.debug("I/O error while reading from stream: {}", e.getMessage());
setStatus(false, "I/O Error"); setStatus(false, "offline.io-error");
} catch (RuntimeException e) { } catch (RuntimeException e) {
logger.warn("Runtime exception in reader thread", e); logger.warn("Runtime exception in reader thread", e);
setStatus(false, "Runtime exception"); setStatus(false, "offline.runtime-exception");
} finally { } finally {
logger.debug("Message reader thread exiting"); logger.debug("Message reader thread exiting");
} }

View File

@ -66,4 +66,19 @@ channel-type.androidtv.player.description = Player Control
offline.protocols-starting = Protocols Starting offline.protocols-starting = Protocols Starting
offline.googletv-address-not-specified = googletv address not specified offline.googletv-address-not-specified = googletv address not specified
offline.shieldtv-address-not-specified = shieldtv address not specified offline.shieldtv-address-not-specified = shieldtv address not specified
offline.error-initalizing-keystore = Error initializing keystore
offline.key-unrecoverable-with-supplied-password = Key unrecoverable with supplied password
offline.unknown-host = Unknown host
offline.invalid-port-number = Invalid port number
offline.pin-process-incomplete = PIN Process Incomplete
offline.error-opening-ssl-connection-check-log = Error opening SSL connection. Check log.
offline.initializing = Initializing
offline.reconnecting = Reconnecting
offline.communication-error-will-try-to-reconnect = Communication error, will try to reconnect
offline.interrupted = Interrupted
offline.io-error = I/O Error
offline.runtime-exception = Runtime exception
offline.user-forced-pin-process = User Forced PIN Process
offline.unknown = Unknown
online.online = Online