diff options
Diffstat (limited to 'android/sdl_android/src/main')
101 files changed, 2713 insertions, 2051 deletions
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java b/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java index f5265ccf0..cdba04757 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlConnection.java @@ -1,39 +1,38 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.SdlConnection;
import android.content.ComponentName;
-import android.util.Log;
import com.smartdevicelink.exception.SdlException;
import com.smartdevicelink.protocol.AbstractProtocol;
@@ -56,6 +55,7 @@ import com.smartdevicelink.transport.TCPTransportConfig; import com.smartdevicelink.transport.USBTransport;
import com.smartdevicelink.transport.USBTransportConfig;
import com.smartdevicelink.transport.enums.TransportType;
+import com.smartdevicelink.util.DebugTool;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -127,10 +127,10 @@ public class SdlConnection implements IProtocolListener, ITransportListener { //rsvp = new RouterServiceValidator(((MultiplexTransportConfig)transportConfig).getContext());
//vlad.setFlags(RouterServiceValidator.FLAG_DEBUG_VERSION_CHECK);
if(rsvp.validate()){
- Log.w(TAG, "SDL Router service is valid; attempting to connect");
+ DebugTool.logWarning(TAG, "SDL Router service is valid; attempting to connect");
((MultiplexTransportConfig)transportConfig).setService(rsvp.getService());//Let thes the transport broker know which service to connect to
}else{
- Log.w(TAG, "SDL Router service isn't trusted. Enabling legacy bluetooth connection.");
+ DebugTool.logWarning(TAG, "SDL Router service isn't trusted. Enabling legacy bluetooth connection.");
if(cachedMultiConfig == null){
cachedMultiConfig = (MultiplexTransportConfig) transportConfig;
cachedMultiConfig.setService(null);
@@ -573,7 +573,7 @@ public class SdlConnection implements IProtocolListener, ITransportListener { public void forceHardwareConnectEvent(TransportType type){
if(_transport == null){
- Log.w(TAG, "Unable to force connect, transport was null!");
+ DebugTool.logWarning(TAG, "Unable to force connect, transport was null!");
return;
}
if(isLegacyModeEnabled()){//We know we should no longer be in legacy mode for future connections, so lets clear out that flag
@@ -594,7 +594,7 @@ public class SdlConnection implements IProtocolListener, ITransportListener { }
}else if(tempCompName!=null){
//We have a conflicting service request
- Log.w(TAG, "Conflicting services. Disconnecting from current and connecting to new");
+ DebugTool.logWarning(TAG, "Conflicting services. Disconnecting from current and connecting to new");
//Log.w(TAG, "Old service " + config.getService().toShortString());
//Log.w(TAG, "New Serivce " + tempCompName.toString());
multi.disconnect();
@@ -626,9 +626,9 @@ public class SdlConnection implements IProtocolListener, ITransportListener { //_transport.disconnect();
return;
}
- Log.w(TAG, "Using own transport, but not connected. Attempting to join multiplexing");
+ DebugTool.logWarning(TAG, "Using own transport, but not connected. Attempting to join multiplexing");
}else{
- Log.w(TAG, "Currently in legacy mode connected to own transport service. Nothing will take place on trnasport cycle");
+ DebugTool.logWarning(TAG, "Currently in legacy mode connected to own transport service. Nothing will take place on trnasport cycle");
}
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java b/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java index 33f9d885e..86488cca0 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession.java @@ -1,39 +1,38 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.SdlConnection;
import android.annotation.SuppressLint;
import android.os.Build;
-import android.util.Log;
import android.view.Surface;
import com.smartdevicelink.encoder.SdlEncoder;
@@ -61,6 +60,7 @@ import com.smartdevicelink.streaming.video.VideoStreamingParameters; import com.smartdevicelink.transport.BaseTransportConfig;
import com.smartdevicelink.transport.MultiplexTransport;
import com.smartdevicelink.transport.enums.TransportType;
+import com.smartdevicelink.util.DebugTool;
import com.smartdevicelink.util.Version;
import java.io.IOException;
@@ -264,7 +264,7 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList return packetizer;
}
default:
- Log.e(TAG, "Protocol " + protocol + " is not supported.");
+ DebugTool.logError(TAG, "Protocol " + protocol + " is not supported.");
return null;
}
} catch (IOException e) {
@@ -285,15 +285,17 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList }
}
+ @Deprecated
public void startRPCStream(InputStream is, RPCRequest request, SessionType sType, byte rpcSessionID, byte wiproVersion) {
try {
mRPCPacketizer = new StreamRPCPacketizer(null, this, is, request, sType, rpcSessionID, wiproVersion, 0, this);
mRPCPacketizer.start();
} catch (Exception e) {
- Log.e(TAG, "Unable to start streaming:" + e.toString());
+ DebugTool.logError(TAG, "Unable to start streaming:" + e.toString());
}
}
+ @Deprecated
public OutputStream startRPCStream(RPCRequest request, SessionType sType, byte rpcSessionID, byte wiproVersion) {
try {
OutputStream os = new PipedOutputStream();
@@ -302,11 +304,12 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList mRPCPacketizer.start();
return os;
} catch (Exception e) {
- Log.e(TAG, "Unable to start streaming:" + e.toString());
+ DebugTool.logError(TAG, "Unable to start streaming:" + e.toString());
}
return null;
}
+ @Deprecated
public void pauseRPCStream()
{
if (mRPCPacketizer != null)
@@ -315,6 +318,7 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList }
}
+ @Deprecated
public void resumeRPCStream()
{
if (mRPCPacketizer != null)
@@ -323,6 +327,7 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList }
}
+ @Deprecated
public void stopRPCStream()
{
if (mRPCPacketizer != null)
@@ -633,7 +638,7 @@ public class SdlSession implements ISdlConnectionListener, IHeartbeatMonitorList @Override
public void sendHeartbeat(IHeartbeatMonitor monitor) {
- Log.d(TAG, "Asked to send heartbeat");
+ DebugTool.logInfo(TAG, "Asked to send heartbeat");
if (_sdlConnection != null)
_sdlConnection.sendHeartbeat(this);
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession2.java b/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession2.java index 14258cbfe..44bb1fbfc 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession2.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/SdlConnection/SdlSession2.java @@ -33,7 +33,6 @@ package com.smartdevicelink.SdlConnection; import android.content.Context; -import android.util.Log; import com.smartdevicelink.exception.SdlException; import com.smartdevicelink.protocol.ISdlProtocol; @@ -47,6 +46,7 @@ import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.MultiplexTransportConfig; import com.smartdevicelink.transport.TCPTransportConfig; import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.util.DebugTool; import com.smartdevicelink.util.MediaStreamingStatus; import com.smartdevicelink.util.Version; @@ -210,7 +210,7 @@ public class SdlSession2 extends SdlSession implements ISdlProtocol{ public void shutdown(String info){ - Log.d(TAG, "Shutdown - " + info); + DebugTool.logInfo(TAG, "Shutdown - " + info); if(mediaStreamingStatus != null) { mediaStreamingStatus.clear(); } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java b/android/sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java index 362564da8..8f3001294 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/encoder/EncoderUtils.java @@ -33,7 +33,8 @@ package com.smartdevicelink.encoder; import android.annotation.TargetApi; import android.media.MediaFormat; import android.os.Build; -import android.util.Log; + +import com.smartdevicelink.util.DebugTool; import java.nio.ByteBuffer; @@ -63,7 +64,7 @@ public final class EncoderUtils { if (name.equals("video/avc")) { return getAVCCodecSpecificData(format); } else { - Log.w(TAG, "Retrieving codec-specific data for " + name + " is not supported"); + DebugTool.logWarning(TAG, "Retrieving codec-specific data for " + name + " is not supported"); return null; } } @@ -81,7 +82,7 @@ public final class EncoderUtils { // For H.264, "csd-0" contains SPS and "csd-1" contains PPS. Refer to the documentation // of MediaCodec. if (!(format.containsKey("csd-0") && format.containsKey("csd-1"))) { - Log.w(TAG, "H264 codec specific data not found"); + DebugTool.logWarning(TAG, "H264 codec specific data not found"); return null; } @@ -96,7 +97,7 @@ public final class EncoderUtils { pps.get(output, spsLen, ppsLen); } catch (Exception e) { // should not happen - Log.w(TAG, "Error while copying H264 codec specific data: " + e); + DebugTool.logWarning(TAG, "Error while copying H264 codec specific data: " + e); return null; } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java b/android/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java index dafb3207c..7172b0225 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/encoder/SdlEncoder.java @@ -36,10 +36,10 @@ import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; import android.os.Build; -import android.util.Log; import android.view.Surface; import com.smartdevicelink.proxy.interfaces.IVideoStreamListener; +import com.smartdevicelink.util.DebugTool; import java.io.IOException; import java.io.PipedOutputStream; @@ -198,7 +198,7 @@ public class SdlEncoder { MediaFormat format = mEncoder.getOutputFormat(); mH264CodecSpecificData = EncoderUtils.getCodecSpecificData(format); } else { - Log.w(TAG, "Output format change notified more than once, ignoring."); + DebugTool.logWarning(TAG, "Output format change notified more than once, ignoring."); } } else if (encoderStatus < 0) { } else { @@ -208,7 +208,7 @@ public class SdlEncoder { if (mH264CodecSpecificData != null) { mBufferInfo.size = 0; } else { - Log.i(TAG, "H264 codec specific data not retrieved yet."); + DebugTool.logInfo(TAG, "H264 codec specific data not retrieved yet."); } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/encoder/VirtualDisplayEncoder.java b/android/sdl_android/src/main/java/com/smartdevicelink/encoder/VirtualDisplayEncoder.java index 6b7f2a686..766e10aaa 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/encoder/VirtualDisplayEncoder.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/encoder/VirtualDisplayEncoder.java @@ -40,7 +40,6 @@ import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; import android.os.Build; -import android.util.Log; import android.view.Display; import android.view.Surface; @@ -49,6 +48,7 @@ import com.smartdevicelink.proxy.rpc.ImageResolution; import com.smartdevicelink.proxy.rpc.VideoStreamingFormat; import com.smartdevicelink.proxy.rpc.enums.VideoStreamingCodec; import com.smartdevicelink.streaming.video.VideoStreamingParameters; +import com.smartdevicelink.util.DebugTool; import java.nio.ByteBuffer; @@ -83,12 +83,12 @@ public class VirtualDisplayEncoder { */ public void init(Context context, IVideoStreamListener outputListener, VideoStreamingParameters streamingParams) throws Exception { if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - Log.e(TAG, "API level of 19 required for VirtualDisplayEncoder"); + DebugTool.logError(TAG, "API level of 19 required for VirtualDisplayEncoder"); throw new Exception("API level of 19 required"); } if (context == null || outputListener == null || streamingParams == null || streamingParams.getResolution() == null || streamingParams.getFormat() == null) { - Log.e(TAG, "init parameters cannot be null for VirtualDisplayEncoder"); + DebugTool.logError(TAG, "init parameters cannot be null for VirtualDisplayEncoder"); throw new Exception("init parameters cannot be null"); } @@ -122,7 +122,7 @@ public class VirtualDisplayEncoder { */ public void start() throws Exception { if (!initPassed) { - Log.e(TAG, "VirtualDisplayEncoder was not properly initialized with the init() method."); + DebugTool.logError(TAG, "VirtualDisplayEncoder was not properly initialized with the init() method."); return; } if (streamingParams == null || streamingParams.getResolution() == null || streamingParams.getFormat() == null) { @@ -142,7 +142,7 @@ public class VirtualDisplayEncoder { startEncoder(); } catch (Exception ex) { - Log.e(TAG, "Unable to create Virtual Display."); + DebugTool.logError(TAG, "Unable to create Virtual Display."); throw new RuntimeException(ex); } } @@ -150,7 +150,7 @@ public class VirtualDisplayEncoder { public void shutDown() { if (!initPassed) { - Log.e(TAG, "VirtualDisplayEncoder was not properly initialized with the init() method."); + DebugTool.logError(TAG, "VirtualDisplayEncoder was not properly initialized with the init() method."); return; } try { @@ -175,7 +175,7 @@ public class VirtualDisplayEncoder { inputSurface = null; } } catch (Exception ex) { - Log.e(TAG, "shutDown() failed"); + DebugTool.logError(TAG, "shutDown() failed"); } } @@ -266,7 +266,7 @@ public class VirtualDisplayEncoder { encoderThread = new Thread(new EncoderCompat()); } else { - Log.e(TAG, "Unable to start encoder. Android OS version " + Build.VERSION.SDK_INT + "is not supported"); + DebugTool.logError(TAG, "Unable to start encoder. Android OS version " + Build.VERSION.SDK_INT + "is not supported"); } return surface; @@ -315,7 +315,7 @@ public class VirtualDisplayEncoder { try { drainEncoder(false); } catch (Exception e) { - Log.w(TAG, "Error attempting to drain encoder"); + DebugTool.logWarning(TAG, "Error attempting to drain encoder"); } finally { mVideoEncoder.release(); } @@ -349,7 +349,7 @@ public class VirtualDisplayEncoder { MediaFormat format = mVideoEncoder.getOutputFormat(); mH264CodecSpecificData = EncoderUtils.getCodecSpecificData(format); } else { - Log.w(TAG, "Output format change notified more than once, ignoring."); + DebugTool.logWarning(TAG, "Output format change notified more than once, ignoring."); } } } else { @@ -359,7 +359,7 @@ public class VirtualDisplayEncoder { if (mH264CodecSpecificData != null) { mVideoBufferInfo.size = 0; } else { - Log.i(TAG, "H264 codec specific data not retrieved yet."); + DebugTool.logInfo(TAG, "H264 codec specific data not retrieved yet."); } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java index 23c37bea5..fd5e5c891 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/ProxyBridge.java @@ -129,6 +129,7 @@ import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener; import java.util.concurrent.CopyOnWriteArrayList; +@Deprecated public class ProxyBridge implements IProxyListener{ private final Object RPC_LISTENER_LOCK = new Object(); private SparseArray<CopyOnWriteArrayList<OnRPCListener>> rpcListeners = null; diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java index b0ff164cd..06b9abd7b 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java @@ -39,1205 +39,340 @@ import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.util.Log; -import com.smartdevicelink.exception.SdlException; import com.smartdevicelink.managers.audio.AudioStreamManager; import com.smartdevicelink.managers.file.FileManager; -import com.smartdevicelink.managers.file.FileManagerConfig; -import com.smartdevicelink.managers.file.filetypes.SdlArtwork; -import com.smartdevicelink.managers.lifecycle.LifecycleConfigurationUpdate; import com.smartdevicelink.managers.lockscreen.LockScreenConfig; import com.smartdevicelink.managers.lockscreen.LockScreenManager; import com.smartdevicelink.managers.permission.PermissionManager; import com.smartdevicelink.managers.screen.ScreenManager; import com.smartdevicelink.managers.video.VideoStreamManager; -import com.smartdevicelink.protocol.enums.FunctionID; -import com.smartdevicelink.protocol.enums.SessionType; -import com.smartdevicelink.proxy.RPCMessage; -import com.smartdevicelink.proxy.RPCRequest; -import com.smartdevicelink.proxy.RPCResponse; -import com.smartdevicelink.proxy.SdlProxyBase; -import com.smartdevicelink.proxy.SystemCapabilityManager; -import com.smartdevicelink.proxy.callbacks.OnServiceEnded; -import com.smartdevicelink.proxy.callbacks.OnServiceNACKed; -import com.smartdevicelink.proxy.interfaces.IAudioStreamListener; -import com.smartdevicelink.proxy.interfaces.ISdl; -import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; -import com.smartdevicelink.proxy.interfaces.IVideoStreamListener; -import com.smartdevicelink.proxy.interfaces.OnSystemCapabilityListener; -import com.smartdevicelink.proxy.rpc.ChangeRegistration; -import com.smartdevicelink.proxy.rpc.OnHMIStatus; -import com.smartdevicelink.proxy.rpc.RegisterAppInterfaceResponse; -import com.smartdevicelink.proxy.rpc.SdlMsgVersion; -import com.smartdevicelink.proxy.rpc.SetAppIcon; -import com.smartdevicelink.proxy.rpc.TTSChunk; -import com.smartdevicelink.proxy.rpc.TemplateColorScheme; import com.smartdevicelink.proxy.rpc.enums.AppHMIType; -import com.smartdevicelink.proxy.rpc.enums.Language; -import com.smartdevicelink.proxy.rpc.enums.Result; -import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; -import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; -import com.smartdevicelink.proxy.rpc.listeners.OnMultipleRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCRequestListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; -import com.smartdevicelink.security.SdlSecurityBase; -import com.smartdevicelink.streaming.audio.AudioStreamingCodec; -import com.smartdevicelink.streaming.audio.AudioStreamingParams; -import com.smartdevicelink.streaming.video.VideoStreamingParameters; import com.smartdevicelink.transport.BaseTransportConfig; import com.smartdevicelink.transport.MultiplexTransportConfig; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.transport.utl.TransportRecord; import com.smartdevicelink.util.DebugTool; -import com.smartdevicelink.util.Version; -import org.json.JSONException; - -import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Vector; /** * <strong>SDLManager</strong> <br> - * + * <p> * This is the main point of contact between an application and SDL <br> - * + * <p> * It is broken down to these areas: <br> - * + * <p> * 1. SDLManagerBuilder <br> * 2. ISdl Interface along with its overridden methods - This can be passed into attached managers <br> * 3. Sending Requests <br> * 4. Helper methods */ -public class SdlManager extends BaseSdlManager{ - private static final String TAG = "SdlManager"; - private SdlProxyBase proxy; - private SdlArtwork appIcon; - private Context context; - private SdlManagerListener managerListener; - private List<Class<? extends SdlSecurityBase>> sdlSecList; - private LockScreenConfig lockScreenConfig; - private FileManagerConfig fileManagerConfig; - private ServiceEncryptionListener serviceEncryptionListener; - - // Managers - private PermissionManager permissionManager; - private FileManager fileManager; - private LockScreenManager lockScreenManager; - private ScreenManager screenManager; - private VideoStreamManager videoStreamManager; - private AudioStreamManager audioStreamManager; - - - // Initialize proxyBridge with anonymous lifecycleListener - private final ProxyBridge proxyBridge = new ProxyBridge(new ProxyBridge.LifecycleListener() { - @Override - public void onProxyConnected() { - DebugTool.logInfo("Proxy is connected. Now initializing."); - changeRegistrationRetry = 0; - checkLifecycleConfiguration(); - initialize(); - } - - @Override - public void onProxyClosed(String info, Exception e, SdlDisconnectedReason reason){ - if (!reason.equals(SdlDisconnectedReason.LANGUAGE_CHANGE)){ - dispose(); - } - } - - @Override - public void onServiceEnded(OnServiceEnded serviceEnded){ - - } - - @Override - public void onServiceNACKed(OnServiceNACKed serviceNACKed){ - - } - - @Override - public void onError(String info, Exception e){ - - } - }); - - // Sub manager listener - private final CompletionListener subManagerListener = new CompletionListener() { - @Override - public synchronized void onComplete(boolean success) { - if(!success){ - Log.e(TAG, "Sub manager failed to initialize"); - } - checkState(); - } - }; - - @Override - void checkState() { - if (permissionManager != null && fileManager != null && screenManager != null && (!lockScreenConfig.isEnabled() || lockScreenManager != null)) { - if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.getState() == BaseSubManager.READY && (!lockScreenConfig.isEnabled() || lockScreenManager.getState() == BaseSubManager.READY)) { - DebugTool.logInfo("Starting sdl manager, all sub managers are in ready state"); - transitionToState(BaseSubManager.READY); - handleQueuedNotifications(); - notifyDevListener(null); - onReady(); - } else if (permissionManager.getState() == BaseSubManager.ERROR && fileManager.getState() == BaseSubManager.ERROR && screenManager.getState() == BaseSubManager.ERROR && (!lockScreenConfig.isEnabled() || lockScreenManager.getState() == BaseSubManager.ERROR)) { - String info = "ERROR starting sdl manager, all sub managers are in error state"; - Log.e(TAG, info); - transitionToState(BaseSubManager.ERROR); - notifyDevListener(info); - } else if (permissionManager.getState() == BaseSubManager.SETTING_UP || fileManager.getState() == BaseSubManager.SETTING_UP || screenManager.getState() == BaseSubManager.SETTING_UP || (lockScreenConfig.isEnabled() && lockScreenManager != null && lockScreenManager.getState() == BaseSubManager.SETTING_UP)) { - DebugTool.logInfo("SETTING UP sdl manager, some sub managers are still setting up"); - transitionToState(BaseSubManager.SETTING_UP); - // No need to notify developer here! - } else { - Log.w(TAG, "LIMITED starting sdl manager, some sub managers are in error or limited state and the others finished setting up"); - transitionToState(BaseSubManager.LIMITED); - handleQueuedNotifications(); - notifyDevListener(null); - onReady(); - } - } else { - // We should never be here, but somehow one of the sub-sub managers is null - String info = "ERROR one of the sdl sub managers is null"; - Log.e(TAG, info); - transitionToState(BaseSubManager.ERROR); - notifyDevListener(info); - } - } - - private void notifyDevListener(String info) { - if (managerListener != null) { - if (getState() == BaseSubManager.ERROR){ - managerListener.onError(info, null); - } else { - managerListener.onStart(); - } - } - } - - private void onReady(){ - // Set the app icon - if (SdlManager.this.appIcon != null && SdlManager.this.appIcon.getName() != null) { - if (fileManager != null && fileManager.getState() == BaseSubManager.READY && !fileManager.hasUploadedFile(SdlManager.this.appIcon)) { - fileManager.uploadArtwork(SdlManager.this.appIcon, new CompletionListener() { - @Override - public void onComplete(boolean success) { - if (success) { - SetAppIcon msg = new SetAppIcon(SdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); - } - } - }); - } else { - SetAppIcon msg = new SetAppIcon(SdlManager.this.appIcon.getName()); - _internalInterface.sendRPCRequest(msg); - } - } - } +public class SdlManager extends BaseSdlManager { + private Context context; + private LockScreenConfig lockScreenConfig; - @Override - protected void checkLifecycleConfiguration(){ - final Language actualLanguage = this.getRegisterAppInterfaceResponse().getLanguage(); + // Managers + private LockScreenManager lockScreenManager; + private VideoStreamManager videoStreamManager; + private AudioStreamManager audioStreamManager; - if (actualLanguage != null && !actualLanguage.equals(hmiLanguage)) { - - final LifecycleConfigurationUpdate lcu = managerListener.managerShouldUpdateLifecycle(actualLanguage); - - if (lcu != null) { - ChangeRegistration changeRegistration = new ChangeRegistration(actualLanguage, actualLanguage); - changeRegistration.setAppName(lcu.getAppName()); - changeRegistration.setNgnMediaScreenAppName(lcu.getShortAppName()); - changeRegistration.setTtsName(lcu.getTtsName()); - changeRegistration.setVrSynonyms(lcu.getVoiceRecognitionCommandNames()); - changeRegistration.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - if (response.getSuccess()){ - // go through and change sdlManager properties that were changed via the LCU update - hmiLanguage = actualLanguage; - - if (lcu.getAppName() != null) { - appName = lcu.getAppName(); - } - - if (lcu.getShortAppName() != null) { - shortAppName = lcu.getShortAppName(); - } - - if (lcu.getTtsName() != null) { - ttsChunks = lcu.getTtsName(); - } - - if (lcu.getVoiceRecognitionCommandNames() != null) { - vrSynonyms = lcu.getVoiceRecognitionCommandNames(); - } - } - try { - DebugTool.logInfo(response.serializeJSON().toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public void onError(int correlationId, Result resultCode, String info) { - DebugTool.logError("Change Registration onError: " + resultCode + " | Info: " + info); - changeRegistrationRetry++; - if (changeRegistrationRetry < MAX_RETRY) { - final Handler handler = new Handler(Looper.getMainLooper()); - handler.postDelayed(new Runnable() { - @Override - public void run() { - checkLifecycleConfiguration(); - DebugTool.logInfo("Retry Change Registration Count: " + changeRegistrationRetry); - } - }, 3000); - } - } - }); - this.sendRPC(changeRegistration); - } - } - } - - @Override - protected void initialize(){ - // Instantiate sub managers - this.permissionManager = new PermissionManager(_internalInterface); - this.fileManager = new FileManager(_internalInterface, context, fileManagerConfig); - if (lockScreenConfig.isEnabled()) { - this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface); - } - this.screenManager = new ScreenManager(_internalInterface, this.fileManager); - if(getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)){ - this.videoStreamManager = new VideoStreamManager(_internalInterface); - } else { - this.videoStreamManager = null; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN - && (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)) ) { - this.audioStreamManager = new AudioStreamManager(_internalInterface, context); - } else { - this.audioStreamManager = null; - } - - // Start sub managers - this.permissionManager.start(subManagerListener); - this.fileManager.start(subManagerListener); - if (lockScreenConfig.isEnabled()){ - this.lockScreenManager.start(subManagerListener); - } - this.screenManager.start(subManagerListener); - } - - /** Dispose SdlManager and clean its resources - * <strong>Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed.</strong> - */ - @SuppressLint("NewApi") - @Override - public void dispose() { - if (this.permissionManager != null) { - this.permissionManager.dispose(); - } - - if (this.fileManager != null) { - this.fileManager.dispose(); - } + /** + * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up + */ + @Override + public void start() { + if (lifecycleManager == null) { + if (transport != null && transport.getTransportType() == TransportType.MULTIPLEX) { + //Do the thing + MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig) (transport); + final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); + multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { + @Override + public void onTransportEvent(List<TransportRecord> connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { + + //Pass to submanagers that need it + if (videoStreamManager != null) { + videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + + if (audioStreamManager != null) { + audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + //If the developer supplied a listener to start, it is time to call that + if (devListener != null) { + devListener.onTransportEvent(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); + } + } + }); + + //If the requires audio support has not been set, it should be set to true if the + //app is a media app, and false otherwise + if (multiplexTransportConfig.requiresAudioSupport() == null) { + multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); + } + } + + super.start(); + + lifecycleManager.setContext(context); + lifecycleManager.start(); + } + } + + @Override + protected void initialize() { + // Instantiate sub managers + this.permissionManager = new PermissionManager(_internalInterface); + this.fileManager = new FileManager(_internalInterface, context, fileManagerConfig); + if (lockScreenConfig.isEnabled()) { + this.lockScreenManager = new LockScreenManager(lockScreenConfig, context, _internalInterface); + } + this.screenManager = new ScreenManager(_internalInterface, this.fileManager); + if (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION)) { + this.videoStreamManager = new VideoStreamManager(_internalInterface); + } else { + this.videoStreamManager = null; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN + && (getAppTypes().contains(AppHMIType.NAVIGATION) || getAppTypes().contains(AppHMIType.PROJECTION))) { + this.audioStreamManager = new AudioStreamManager(_internalInterface, context); + } else { + this.audioStreamManager = null; + } + + // Start sub managers + this.permissionManager.start(subManagerListener); + this.fileManager.start(subManagerListener); + if (lockScreenConfig.isEnabled()) { + this.lockScreenManager.start(subManagerListener); + } + this.screenManager.start(subManagerListener); + } + + @Override + void checkState() { + if (permissionManager != null && fileManager != null && screenManager != null && (!lockScreenConfig.isEnabled() || lockScreenManager != null)) { + if (permissionManager.getState() == BaseSubManager.READY && fileManager.getState() == BaseSubManager.READY && screenManager.getState() == BaseSubManager.READY && (!lockScreenConfig.isEnabled() || lockScreenManager.getState() == BaseSubManager.READY)) { + DebugTool.logInfo(TAG, "Starting sdl manager, all sub managers are in ready state"); + transitionToState(BaseSubManager.READY); + handleQueuedNotifications(); + notifyDevListener(null); + onReady(); + } else if (permissionManager.getState() == BaseSubManager.ERROR && fileManager.getState() == BaseSubManager.ERROR && screenManager.getState() == BaseSubManager.ERROR && (!lockScreenConfig.isEnabled() || lockScreenManager.getState() == BaseSubManager.ERROR)) { + String info = "ERROR starting sdl manager, all sub managers are in error state"; + DebugTool.logError(TAG, info); + transitionToState(BaseSubManager.ERROR); + notifyDevListener(info); + } else if (permissionManager.getState() == BaseSubManager.SETTING_UP || fileManager.getState() == BaseSubManager.SETTING_UP || screenManager.getState() == BaseSubManager.SETTING_UP || (lockScreenConfig.isEnabled() && lockScreenManager != null && lockScreenManager.getState() == BaseSubManager.SETTING_UP)) { + DebugTool.logInfo(TAG, "SETTING UP sdl manager, some sub managers are still setting up"); + transitionToState(BaseSubManager.SETTING_UP); + // No need to notify developer here! + } else { + DebugTool.logWarning(TAG, "LIMITED starting sdl manager, some sub managers are in error or limited state and the others finished setting up"); + transitionToState(BaseSubManager.LIMITED); + handleQueuedNotifications(); + notifyDevListener(null); + onReady(); + } + } else { + // We should never be here, but somehow one of the sub-sub managers is null + String info = "ERROR one of the sdl sub managers is null"; + DebugTool.logError(TAG, info); + transitionToState(BaseSubManager.ERROR); + notifyDevListener(info); + } + } + + private void notifyDevListener(String info) { + if (managerListener != null) { + if (getState() == BaseSubManager.ERROR) { + managerListener.onError(info, null); + } else { + managerListener.onStart(); + } + } + } + + @Override + void retryChangeRegistration() { + changeRegistrationRetry++; + if (changeRegistrationRetry < MAX_RETRY) { + final Handler handler = new Handler(Looper.getMainLooper()); + handler.postDelayed(new Runnable() { + @Override + public void run() { + checkLifecycleConfiguration(); + DebugTool.logInfo(TAG, "Retry Change Registration Count: " + changeRegistrationRetry); + } + }, 3000); + } + } - if (this.lockScreenManager != null) { - this.lockScreenManager.dispose(); - } + /** + * Dispose SdlManager and clean its resources + * <strong>Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed.</strong> + */ + @SuppressLint("NewApi") + @Override + public synchronized void dispose() { + if (this.permissionManager != null) { + this.permissionManager.dispose(); + } - if (this.screenManager != null) { - this.screenManager.dispose(); - } + if (this.fileManager != null) { + this.fileManager.dispose(); + } - if(this.videoStreamManager != null) { - this.videoStreamManager.dispose(); - } + if (this.lockScreenManager != null) { + this.lockScreenManager.dispose(); + } - // SuppressLint("NewApi") is used because audioStreamManager is only available on android >= jelly bean - if (this.audioStreamManager != null) { - this.audioStreamManager.dispose(); - } + if (this.screenManager != null) { + this.screenManager.dispose(); + } - if (this.proxy != null && !proxy.isDisposed()) { - try { - this.proxy.dispose(); - } catch (SdlException e) { - DebugTool.logError("Issue disposing proxy in SdlManager", e); - } - } + if (this.videoStreamManager != null) { + this.videoStreamManager.dispose(); + } - if(managerListener != null){ - managerListener.onDestroy(); - managerListener = null; - } + // SuppressLint("NewApi") is used because audioStreamManager is only available on android >= jelly bean + if (this.audioStreamManager != null) { + this.audioStreamManager.dispose(); + } - transitionToState(BaseSubManager.SHUTDOWN); - } + if (this.lifecycleManager != null) { + this.lifecycleManager.stop(); + } - // MANAGER GETTERS + if (managerListener != null) { + managerListener.onDestroy(); + managerListener = null; + } - /** - * Gets the PermissionManager. <br> - * <strong>Note: PermissionManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> - * @return a PermissionManager object - */ - public PermissionManager getPermissionManager() { - if (permissionManager.getState() != BaseSubManager.READY && permissionManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG,"PermissionManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return permissionManager; - } + transitionToState(BaseSubManager.SHUTDOWN); + } - /** - * Gets the FileManager. <br> - * <strong>Note: FileManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> - * @return a FileManager object - */ - public FileManager getFileManager() { - if (fileManager.getState() != BaseSubManager.READY && fileManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "FileManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return fileManager; - } + // MANAGER GETTERS /** * Gets the VideoStreamManager. <br> - * The VideoStreamManager returned will only be not null if the registered app type is - * either NAVIGATION or PROJECTION. Once the VideoStreamManager is retrieved, its start() - * method will need to be called before use. + * The VideoStreamManager returned will only be not null if the registered app type is + * either NAVIGATION or PROJECTION. Once the VideoStreamManager is retrieved, its start() + * method will need to be called before use. * <br><br><strong>Note: VideoStreamManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> + * * @return a VideoStreamManager object attached to this SdlManager instance */ - public @Nullable + public @Nullable VideoStreamManager getVideoStreamManager() { - checkSdlManagerState(); - return videoStreamManager; - } + checkSdlManagerState(); + return videoStreamManager; + } /** * Gets the AudioStreamManager. <br> - * The AudioStreamManager returned will only be not null if the registered app type is - * either NAVIGATION or PROJECTION. Once the AudioStreamManager is retrieved, its start() - * method will need to be called before use. + * The AudioStreamManager returned will only be not null if the registered app type is + * either NAVIGATION or PROJECTION. Once the AudioStreamManager is retrieved, its start() + * method will need to be called before use. * <br><strong>Note: AudioStreamManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> + * * @return a AudioStreamManager object */ - public @Nullable AudioStreamManager getAudioStreamManager() { - checkSdlManagerState(); - return audioStreamManager; - } - - /** - * Gets the ScreenManager. <br> - * <strong>Note: ScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> - * @return a ScreenManager object - */ - public ScreenManager getScreenManager() { - if (screenManager.getState() != BaseSubManager.READY && screenManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "ScreenManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return screenManager; - } - - /** - * Gets the LockScreenManager. <br> - * <strong>Note: LockScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> - * @return a LockScreenManager object - */ - public LockScreenManager getLockScreenManager() { - if (lockScreenManager.getState() != BaseSubManager.READY && lockScreenManager.getState() != BaseSubManager.LIMITED){ - Log.e(TAG, "LockScreenManager should not be accessed because it is not in READY/LIMITED state"); - } - checkSdlManagerState(); - return lockScreenManager; - } - - /** - * Gets the SystemCapabilityManager. <br> - * <strong>Note: SystemCapabilityManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> - * @return a SystemCapabilityManager object - */ - public SystemCapabilityManager getSystemCapabilityManager(){ - return proxy.getSystemCapabilityManager(); - } - - /** - * Method to retrieve the RegisterAppInterface Response message that was sent back from the - * module. It contains various attributes about the connected module and can be used to adapt - * to different module types and their supported features. - * - * @return RegisterAppInterfaceResponse received from the module or null if the app has not yet - * registered with the module. - */ - @Override - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse(){ - if(proxy != null){ - return proxy.getRegisterAppInterfaceResponse(); - } - return null; - } - - /** - * Get the current OnHMIStatus - * @return OnHMIStatus object represents the current OnHMIStatus - */ - @Override - public OnHMIStatus getCurrentHMIStatus(){ - if(this.proxy !=null ){ - return proxy.getCurrentHMIStatus(); - } - return null; - } - - /** - * Retrieves the auth token, if any, that was attached to the StartServiceACK for the RPC - * service from the module. For example, this should be used to login to a user account. - * @return the string representation of the auth token - */ - @Override - public String getAuthToken(){ - return this.proxy.getAuthToken(); - } - - // PROTECTED GETTERS - - protected LockScreenConfig getLockScreenConfig() { return lockScreenConfig; } - - protected FileManagerConfig getFileManagerConfig() { return fileManagerConfig; } - - // SENDING REQUESTS - - /** - * Send RPC Message - * @param message RPCMessage - */ - @Override - public void sendRPC(RPCMessage message) { - try{ - proxy.sendRPC(message); - }catch (SdlException exception){ - handleSdlException(exception); - } - } - - /** - * Takes a list of RPCMessages and sends it to SDL in a synchronous fashion. Responses are captured through callback on OnMultipleRequestListener. - * For sending requests asynchronously, use sendRequests <br> - * - * <strong>NOTE: This will override any listeners on individual RPCs</strong><br> - * - * <strong>ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out</strong> - * - * @param rpcs is the list of RPCMessages being sent - * @param listener listener for updates and completions - */ - @Override - public void sendSequentialRPCs(final List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener){ - - List<RPCRequest> rpcRequestList = new ArrayList<>(); - for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); - } - } - - if (rpcRequestList.size() > 0) { - try{ - proxy.sendSequentialRequests(rpcRequestList, listener); - }catch (SdlException exception){ - handleSdlException(exception); - } - } - } - - /** - * Takes a list of RPCMessages and sends it to SDL. Responses are captured through callback on OnMultipleRequestListener. - * For sending requests synchronously, use sendSequentialRPCs <br> - * - * <strong>NOTE: This will override any listeners on individual RPCs</strong> <br> - * - * <strong>ADDITIONAL NOTE: This only takes the type of RPCRequest for now, notifications and responses will be thrown out</strong> - * - * @param rpcs is the list of RPCMessages being sent - * @param listener listener for updates and completions - */ - @Override - public void sendRPCs(List<? extends RPCMessage> rpcs, final OnMultipleRequestListener listener) { - - List<RPCRequest> rpcRequestList = new ArrayList<>(); - for (int i = 0; i < rpcs.size(); i++) { - if (rpcs.get(i) instanceof RPCRequest){ - rpcRequestList.add((RPCRequest)rpcs.get(i)); - } - } - - if (rpcRequestList.size() > 0) { - try{ - proxy.sendRequests(rpcRequestList, listener); - }catch (SdlException exception){ - handleSdlException(exception); - } - } - } - - private void handleSdlException(SdlException exception){ - if(exception != null){ - DebugTool.logError("Caught SdlException: " + exception.getSdlExceptionCause()); - // In the future this should handle logic to dispose the manager if it is an unrecoverable error - }else{ - DebugTool.logError("Caught SdlException" ); - } - } - - /** - * Add an OnRPCNotificationListener - * @param listener listener that will be called when a notification is received - */ - @Override - public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - proxy.addOnRPCNotificationListener(notificationId,listener); - } - - /** - * Remove an OnRPCNotificationListener - * @param listener listener that was previously added - */ - @Override - public void removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener){ - proxy.removeOnRPCNotificationListener(notificationId, listener); - } - - /** - * Add an OnRPCRequestListener - * @param listener listener that will be called when a request is received - */ - @Override - public void addOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - proxy.addOnRPCRequestListener(requestId,listener); - } - - /** - * Remove an OnRPCRequestListener - * @param listener listener that was previously added - */ - @Override - public void removeOnRPCRequestListener(FunctionID requestId, OnRPCRequestListener listener){ - proxy.removeOnRPCRequestListener(requestId, listener); - } - - // LIFECYCLE / OTHER - - // STARTUP - - /** - * Starts up a SdlManager, and calls provided callback called once all BaseSubManagers are done setting up - */ - @SuppressWarnings("unchecked") - @Override - public void start(){ - if (proxy == null) { - try { - if(transport!= null && transport.getTransportType() == TransportType.MULTIPLEX){ - //Do the thing - MultiplexTransportConfig multiplexTransportConfig = (MultiplexTransportConfig)(transport); - final MultiplexTransportConfig.TransportListener devListener = multiplexTransportConfig.getTransportListener(); - multiplexTransportConfig.setTransportListener(new MultiplexTransportConfig.TransportListener() { - @Override - public void onTransportEvent(List<TransportRecord> connectedTransports, boolean audioStreamTransportAvail, boolean videoStreamTransportAvail) { - - //Pass to submanagers that need it - if(videoStreamManager != null){ - videoStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } - - if(audioStreamManager != null){ - audioStreamManager.handleTransportUpdated(connectedTransports, audioStreamTransportAvail, videoStreamTransportAvail); - } - //If the developer supplied a listener to start, it is time to call that - if(devListener != null){ - devListener.onTransportEvent(connectedTransports,audioStreamTransportAvail,videoStreamTransportAvail); - } - } - }); - - //If the requires audio support has not been set, it should be set to true if the - //app is a media app, and false otherwise - if(multiplexTransportConfig.requiresAudioSupport() == null){ - multiplexTransportConfig.setRequiresAudioSupport(isMediaApp); - } - } - - proxy = new SdlProxyBase(proxyBridge, context, appName, shortAppName, isMediaApp, hmiLanguage, - hmiLanguage, hmiTypes, appId, transport, vrSynonyms, ttsChunks, dayColorScheme, - nightColorScheme) {}; - proxy.setMinimumProtocolVersion(minimumProtocolVersion); - proxy.setMinimumRPCVersion(minimumRPCVersion); - if (sdlSecList != null && !sdlSecList.isEmpty()) { - proxy.setSdlSecurity(sdlSecList, serviceEncryptionListener); - } - //Setup the notification queue - initNotificationQueue(); - - } catch (SdlException e) { - transitionToState(BaseSubManager.ERROR); - if (managerListener != null) { - managerListener.onError("Unable to start manager", e); - } - } - } - } - - protected void setProxy(SdlProxyBase proxy){ - this.proxy = proxy; - } - - // INTERNAL INTERFACE - private ISdl _internalInterface = new ISdl() { - @Override - public void start() { - try{ - proxy.initializeProxy(); - }catch (SdlException e){ - e.printStackTrace(); - } - } - - @Override - public void stop() { - try{ - proxy.dispose(); - }catch (SdlException e){ - e.printStackTrace(); - } - } - - @Override - public boolean isConnected() { - return proxy.getIsConnected(); - } - - @Override - public void addServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - proxy.addServiceListener(serviceType,sdlServiceListener); - } - - @Override - public void removeServiceListener(SessionType serviceType, ISdlServiceListener sdlServiceListener) { - proxy.removeServiceListener(serviceType,sdlServiceListener); - } - - @Override - public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) { - if(proxy.getIsConnected()){ - proxy.startVideoService(encrypted,parameters); - } - } + public @Nullable + AudioStreamManager getAudioStreamManager() { + checkSdlManagerState(); + return audioStreamManager; + } - @Override - public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters){ - if(proxy.getIsConnected()){ - return proxy.startVideoStream(isEncrypted, parameters); - }else{ - DebugTool.logError("Unable to start video stream, proxy not connected"); - return null; - } - } - - @Override - public void stopVideoService() { - if(proxy.getIsConnected()){ - proxy.endVideoStream(); - } - } - - @Override - public void startAudioService(boolean isEncrypted, AudioStreamingCodec codec, - AudioStreamingParams params) { - if(proxy.getIsConnected()){ - proxy.startAudioStream(isEncrypted, codec, params); - } - } - - @Override - public void startAudioService(boolean encrypted) { - if(isConnected()){ - proxy.startService(SessionType.PCM, encrypted); - } - } - - @Override - public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec, - AudioStreamingParams params) { - return proxy.startAudioStream(isEncrypted, codec, params); - } - - @Override - public void stopAudioService() { - if(proxy.getIsConnected()){ - proxy.endAudioStream(); - } - } - - @Override - public void sendRPCRequest(RPCRequest message){ - try { - proxy.sendRPC(message); - } catch (SdlException e) { - e.printStackTrace(); - } - } - - @Override - public void sendRPC(RPCMessage message) { - try { - proxy.sendRPC(message); - } catch (SdlException e) { - e.printStackTrace(); - } - } - - @Override - public void sendRequests(List<? extends RPCRequest> rpcs, OnMultipleRequestListener listener) { - try { - proxy.sendRequests(rpcs, listener); - } catch (SdlException e) { - e.printStackTrace(); - } - } - - @Override - public void sendSequentialRPCs(List<? extends RPCMessage> rpcs, OnMultipleRequestListener listener) { - try { - proxy.sendSequentialRequests(rpcs,listener); - } catch (SdlException e) { - DebugTool.logError("Issue sending sequential RPCs ", e); - } - } - - @Override - public void addOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - proxy.addOnRPCNotificationListener(notificationId,listener); - } - - @Override - public boolean removeOnRPCNotificationListener(FunctionID notificationId, OnRPCNotificationListener listener) { - return proxy.removeOnRPCNotificationListener(notificationId,listener); - } - - @Override - public void addOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) { - proxy.addOnRPCRequestListener(functionID, listener); - } - - @Override - public boolean removeOnRPCRequestListener(FunctionID functionID, OnRPCRequestListener listener) { - return proxy.removeOnRPCRequestListener(functionID, listener); - } - - @Override - public void addOnRPCListener(final FunctionID responseId, final OnRPCListener listener) { - proxyBridge.addRpcListener(responseId, listener); - } - - @Override - public boolean removeOnRPCListener(final FunctionID responseId, final OnRPCListener listener) { - return proxyBridge.removeOnRPCListener(responseId, listener); - } - - @Override - public Object getCapability(SystemCapabilityType systemCapabilityType){ - return proxy.getCapability(systemCapabilityType); - } - - @Override - public void getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener) { - proxy.getCapability(systemCapabilityType, scListener); - } - - @Override - public RegisterAppInterfaceResponse getRegisterAppInterfaceResponse() { - return proxy.getRegisterAppInterfaceResponse(); - } - - @Override - public Object getCapability(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener scListener, boolean forceUpdate) { - if (proxy != null && proxy.getSystemCapabilityManager() != null) { - return proxy.getSystemCapabilityManager().getCapability(systemCapabilityType, scListener, forceUpdate); - } - return null; - } - - @Override - public boolean isCapabilitySupported(SystemCapabilityType systemCapabilityType){ - return proxy.isCapabilitySupported(systemCapabilityType); - } - - @Override - public void addOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { - proxy.addOnSystemCapabilityListener(systemCapabilityType, listener); - } - - @Override - public boolean removeOnSystemCapabilityListener(SystemCapabilityType systemCapabilityType, OnSystemCapabilityListener listener) { - return proxy.removeOnSystemCapabilityListener(systemCapabilityType, listener); - } - - @Override - public boolean isTransportForServiceAvailable(SessionType serviceType) { - if(SessionType.NAV.equals(serviceType)){ - return proxy.isVideoStreamTransportAvailable(); - }else if(SessionType.PCM.equals(serviceType)){ - return proxy.isAudioStreamTransportAvailable(); - } - return false; - } - - @Override - public SdlMsgVersion getSdlMsgVersion(){ - try { - return proxy.getSdlMsgVersion(); - } catch (SdlException e) { - e.printStackTrace(); - } - return null; - } - - @Override - public @NonNull Version getProtocolVersion() { - if(proxy.getProtocolVersion() != null){ - return proxy.getProtocolVersion(); - }else{ - return new Version(1,0,0); - } - } - - @Override - public void startRPCEncryption() { - if (proxy != null) { - proxy.startProtectedRPCService(); - } - } - - }; - - - // BUILDER - public static class Builder { - SdlManager sdlManager; - - /** - * Builder for the SdlManager. Parameters in the constructor are required. - * @param context the current context - * @param appId the app's ID - * @param appName the app's name - * @param listener a SdlManagerListener object - */ - public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener){ - sdlManager = new SdlManager(); - setContext(context); - setAppId(appId); - setAppName(appName); - setManagerListener(listener); - } - /** - * Builder for the SdlManager. Parameters in the constructor are required. - * @param context the current context - * @param appId the app's ID - * @param appName the app's name - * @param listener a SdlManagerListener object - */ - public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull BaseTransportConfig transport, @NonNull final SdlManagerListener listener){ - sdlManager = new SdlManager(); - setContext(context); - setAppId(appId); - setAppName(appName); - setTransportType(transport); - setManagerListener(listener); - } - - /** - * Sets the App ID - * @param appId - */ - public Builder setAppId(@NonNull final String appId){ - sdlManager.appId = appId; - return this; - } - - /** - * Sets the Application Name - * @param appName - */ - public Builder setAppName(@NonNull final String appName){ - sdlManager.appName = appName; - return this; - } - - /** - * Sets the Short Application Name - * @param shortAppName - */ - public Builder setShortAppName(final String shortAppName) { - sdlManager.shortAppName = shortAppName; - return this; - } - - /** - * Sets the minimum protocol version that will be permitted to connect. - * If the protocol version of the head unit connected is below this version, - * the app will disconnect with an EndService protocol message and will not register. - * @param minimumProtocolVersion the minimum Protocol spec version that should be accepted - */ - public Builder setMinimumProtocolVersion(final Version minimumProtocolVersion) { - sdlManager.minimumProtocolVersion = minimumProtocolVersion; - return this; - } - - /** - * The minimum RPC version that will be permitted to connect. - * If the RPC version of the head unit connected is below this version, an UnregisterAppInterface will be sent. - * @param minimumRPCVersion the minimum RPC spec version that should be accepted - */ - public Builder setMinimumRPCVersion(final Version minimumRPCVersion) { - sdlManager.minimumRPCVersion = minimumRPCVersion; - return this; - } - - /** - * Sets the Language of the App - * @param hmiLanguage the desired language to be used on the display/HMI of the connected module - */ - public Builder setLanguage(final Language hmiLanguage){ - sdlManager.hmiLanguage = hmiLanguage; - return this; - } - - /** - * Sets the TemplateColorScheme for daytime - * @param dayColorScheme color scheme that will be used (if supported) when the display is - * in a "Day Mode" or similar. Should comprise of colors that contrast - * well during the day under sunlight. - */ - public Builder setDayColorScheme(final TemplateColorScheme dayColorScheme){ - sdlManager.dayColorScheme = dayColorScheme; - return this; - } - - /** - * Sets the TemplateColorScheme for nighttime - * @param nightColorScheme color scheme that will be used (if supported) when the display is - * in a "Night Mode" or similar. Should comprise of colors that - * contrast well during the night and are not brighter than average. - */ - public Builder setNightColorScheme(final TemplateColorScheme nightColorScheme){ - sdlManager.nightColorScheme = nightColorScheme; - return this; - } - - /** - * Sets the FileManagerConfig for the session.<br> - * <strong>Note: If not set, the default configuration value of 1 will be set for - * artworkRetryCount and fileRetryCount in FileManagerConfig</strong> - * @param fileManagerConfig - configuration options - */ - public Builder setFileManagerConfig (final FileManagerConfig fileManagerConfig){ - sdlManager.fileManagerConfig = fileManagerConfig; - return this; - } - - /** - * Sets the LockScreenConfig for the session. <br> - * <strong>Note: If not set, the default configuration will be used.</strong> - * @param lockScreenConfig - configuration options - */ - public Builder setLockScreenConfig (final LockScreenConfig lockScreenConfig){ - sdlManager.lockScreenConfig = lockScreenConfig; - return this; - } - - /** - * Sets the icon for the app on head unit / In-Vehicle-Infotainment system <br> - * @param sdlArtwork the icon that will be used to represent this application on the - * connected module - */ - public Builder setAppIcon(final SdlArtwork sdlArtwork){ - sdlManager.appIcon = sdlArtwork; - return this; - } - - /** - * Sets the vector of AppHMIType <br> - * <strong>Note: This should be an ordered list from most -> least relevant</strong> - * @param hmiTypes HMI types that represent this application. For example, if the app is a - * music player, the MEDIA HMIType should be included. - */ - public Builder setAppTypes(final Vector<AppHMIType> hmiTypes){ - - sdlManager.hmiTypes = hmiTypes; - - if (hmiTypes != null) { - sdlManager.isMediaApp = hmiTypes.contains(AppHMIType.MEDIA); - } - - return this; - } - - /** - * Sets the voice recognition synonyms that can be used to identify this application. - * @param vrSynonyms a vector of Strings that can be associated with this app. For example the app's name should - * be included as well as any phonetic spellings of the app name that might help the on-board - * VR system associated a users spoken word with the supplied synonyms. - */ - public Builder setVrSynonyms(final Vector<String> vrSynonyms) { - sdlManager.vrSynonyms = vrSynonyms; - return this; - } - - /** - * Sets the Text-To-Speech Name of the application. These TTSChunks might be used by the module as an audio - * representation of the app's name. - * @param ttsChunks the TTS chunks that can represent this app's name - */ - public Builder setTtsName(final Vector<TTSChunk> ttsChunks) { - sdlManager.ttsChunks = ttsChunks; - return this; - } - - /** - * This Object type may change with the transport refactor - * Sets the BaseTransportConfig - * @param transport the type of transport that should be used for this SdlManager instance. - */ - public Builder setTransportType(@NonNull BaseTransportConfig transport){ - sdlManager.transport = transport; - return this; - } - - /** - * Sets the Context - * @param context - */ - public Builder setContext(Context context){ - sdlManager.context = context; - return this; - } - - /** - * Sets the Security library - * @param secList The list of security class(es) - */ - @Deprecated - public Builder setSdlSecurity(List<Class<? extends SdlSecurityBase>> secList) { - sdlManager.sdlSecList = secList; - return this; - } - - /** - * Sets the security libraries and a callback to notify caller when there is update to encryption service - * @param secList The list of security class(es) - * @param listener The callback object - */ - public Builder setSdlSecurity(@NonNull List<Class<? extends SdlSecurityBase>> secList, ServiceEncryptionListener listener) { - sdlManager.sdlSecList = secList; - sdlManager.serviceEncryptionListener = listener; - return this; - } - - /** - * Set the SdlManager Listener - * @param listener the listener - */ - public Builder setManagerListener(@NonNull final SdlManagerListener listener){ - sdlManager.managerListener = listener; - return this; - } - - /** - * Set RPCNotification listeners. SdlManager will preload these listeners before any RPCs are sent/received. - * @param listeners a map of listeners that will be called when a notification is received. - * Key represents the FunctionID of the notification and value represents the listener - */ - public Builder setRPCNotificationListeners(Map<FunctionID, OnRPCNotificationListener> listeners){ - sdlManager.onRPCNotificationListeners = listeners; - return this; - } - - /** - * Build SdlManager ang get it ready to be started - * <strong>Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed.</strong> - * @return SdlManager instance that is ready to be started - */ - public SdlManager build() { - - if (sdlManager.appName == null) { - throw new IllegalArgumentException("You must specify an app name by calling setAppName"); - } - - if (sdlManager.appId == null) { - throw new IllegalArgumentException("You must specify an app ID by calling setAppId"); - } - - if (sdlManager.managerListener == null) { - throw new IllegalArgumentException("You must set a SdlManagerListener object"); - } - - if (sdlManager.transport == null) { - throw new IllegalArgumentException("You must set a transport type object"); - } - - if (sdlManager.hmiTypes == null) { - Vector<AppHMIType> hmiTypesDefault = new Vector<>(); - hmiTypesDefault.add(AppHMIType.DEFAULT); - sdlManager.hmiTypes = hmiTypesDefault; - sdlManager.isMediaApp = false; - } - - if (sdlManager.lockScreenConfig == null){ - // if lock screen params are not set, use default - sdlManager.lockScreenConfig = new LockScreenConfig(); - } - - if(sdlManager.fileManagerConfig == null){ - //if FileManagerConfig is not set use default - sdlManager.fileManagerConfig = new FileManagerConfig(); - } - - if (sdlManager.hmiLanguage == null){ - sdlManager.hmiLanguage = Language.EN_US; - } - - if (sdlManager.minimumProtocolVersion == null){ - sdlManager.minimumProtocolVersion = new Version("1.0.0"); - } - - if (sdlManager.minimumRPCVersion == null){ - sdlManager.minimumRPCVersion = new Version("1.0.0"); - } - - sdlManager.transitionToState(BaseSubManager.SETTING_UP); - - return sdlManager; - } - } - - /** - * Start a secured RPC service - */ - public void startRPCEncryption() { - if (proxy != null) { - proxy.startProtectedRPCService(); - } - } + /** + * Gets the LockScreenManager. <br> + * <strong>Note: LockScreenManager should be used only after SdlManager.start() CompletionListener callback is completed successfully.</strong> + * + * @return a LockScreenManager object + */ + public LockScreenManager getLockScreenManager() { + if (lockScreenManager.getState() != BaseSubManager.READY && lockScreenManager.getState() != BaseSubManager.LIMITED) { + DebugTool.logError(TAG, "LockScreenManager should not be accessed because it is not in READY/LIMITED state"); + } + checkSdlManagerState(); + return lockScreenManager; + } + + // PROTECTED GETTERS + protected LockScreenConfig getLockScreenConfig() { + return lockScreenConfig; + } + + // BUILDER + public static class Builder extends BaseSdlManager.Builder { + /** + * Builder for the SdlManager. Parameters in the constructor are required. + * + * @param context the current context + * @param appId the app's ID + * @param appName the app's name + * @param listener a SdlManagerListener object + */ + public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull final SdlManagerListener listener) { + super(appId, appName, listener); + setContext(context); + } + + /** + * Builder for the SdlManager. Parameters in the constructor are required. + * + * @param context the current context + * @param appId the app's ID + * @param appName the app's name + * @param listener a SdlManagerListener object + */ + public Builder(@NonNull Context context, @NonNull final String appId, @NonNull final String appName, @NonNull BaseTransportConfig transport, @NonNull final SdlManagerListener listener) { + super(appId, appName, listener); + setContext(context); + setTransportType(transport); + } + + /** + * Sets the LockScreenConfig for the session. <br> + * <strong>Note: If not set, the default configuration will be used.</strong> + * + * @param lockScreenConfig - configuration options + */ + public Builder setLockScreenConfig(final LockScreenConfig lockScreenConfig) { + sdlManager.lockScreenConfig = lockScreenConfig; + return this; + } + + /** + * Sets the Context + * + * @param context the current context + */ + public Builder setContext(Context context) { + sdlManager.context = context; + return this; + } + + /** + * Build SdlManager ang get it ready to be started + * <strong>Note: new instance of SdlManager should be created on every connection. SdlManager cannot be reused after getting disposed.</strong> + * + * @return SdlManager instance that is ready to be started + */ + public SdlManager build() { + if (sdlManager.transport == null) { + throw new IllegalArgumentException("You must set a transport type object"); + } + + if (sdlManager.lockScreenConfig == null) { + // if lock screen params are not set, use default + sdlManager.lockScreenConfig = new LockScreenConfig(); + } + + super.build(); + + return sdlManager; + } + } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java index d27ac27b5..aa0e4f84a 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManagerListener.java @@ -64,6 +64,22 @@ public interface SdlManagerListener extends BaseSdlManagerListener{ * @param language The language of the connected head unit the manager is trying to update the configuration. * @return An object of LifecycleConfigurationUpdate if the head unit language is supported, * otherwise null to indicate that the language is not supported. + * @deprecated use {@link #managerShouldUpdateLifecycle(Language language, Language hmiLanguage)} instead */ + @Deprecated LifecycleConfigurationUpdate managerShouldUpdateLifecycle(Language language); + + /** + * Called when the SDL manager detected a language mismatch. In case of a language mismatch the + * manager should change the apps registration by updating the lifecycle configuration to the + * specified language. If the app can support the specified language it should return an Object + * of LifecycleConfigurationUpdate, otherwise it should return null to indicate that the language + * is not supported. + * + * @param language The VR+TTS language of the connected head unit the manager is trying to update the configuration. + * @param hmiLanguage The HMI display language of the connected head unit the manager is trying to update the configuration. + * @return An object of LifecycleConfigurationUpdate if the head unit language is supported, + * otherwise null to indicate that the language is not supported. + */ + LifecycleConfigurationUpdate managerShouldUpdateLifecycle(Language language, Language hmiLanguage); } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoder.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoder.java index e88313036..cba0d212b 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoder.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoder.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.managers.audio;
import android.content.Context;
@@ -38,9 +38,9 @@ import android.net.Uri; import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
-import android.util.Log;
import com.smartdevicelink.managers.audio.AudioStreamManager.SampleType;
+import com.smartdevicelink.util.DebugTool;
import java.nio.ByteBuffer;
@@ -89,7 +89,7 @@ public class AudioDecoder extends BaseAudioDecoder { SampleBuffer targetSampleBuffer = AudioDecoder.super.onOutputBufferAvailable(outputBuffer);
AudioDecoder.this.listener.onAudioDataAvailable(targetSampleBuffer);
} else {
- Log.w(TAG, "output buffer empty. Chance that silence was detected");
+ DebugTool.logWarning(TAG, "output buffer empty. Chance that silence was detected");
}
mediaCodec.releaseOutputBuffer(i, false);
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java index 984475eaf..1fdf5b219 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioDecoderCompat.java @@ -38,9 +38,9 @@ import android.net.Uri; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; -import android.util.Log; import com.smartdevicelink.managers.audio.AudioStreamManager.SampleType; +import com.smartdevicelink.util.DebugTool; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; @@ -107,7 +107,7 @@ public class AudioDecoderCompat extends BaseAudioDecoder { public void run() { final AudioDecoderCompat reference = weakReference.get(); if (reference == null) { - Log.w(TAG, "AudioDecoderCompat reference was null"); + DebugTool.logWarning(TAG, "AudioDecoderCompat reference was null"); return; } final ByteBuffer[] inputBuffersArray = reference.decoder.getInputBuffers(); diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java index 55bff7bba..bb78741c7 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/AudioStreamManager.java @@ -41,7 +41,6 @@ import android.os.Looper; import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
-import android.util.Log;
import com.smartdevicelink.SdlConnection.SdlSession;
import com.smartdevicelink.managers.CompletionListener;
@@ -60,6 +59,7 @@ import com.smartdevicelink.proxy.rpc.enums.PredefinedWindows; import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType;
import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener;
import com.smartdevicelink.transport.utl.TransportRecord;
+import com.smartdevicelink.util.DebugTool;
import com.smartdevicelink.util.Version;
import java.lang.annotation.Retention;
@@ -145,7 +145,7 @@ public class AudioStreamManager extends BaseAudioStreamManager { serviceCompletionHandler.removeCallbacks(serviceCompletionTimeoutCallback);
streamingStateMachine.transitionToState(StreamingStateMachine.ERROR);
- Log.e(TAG, "OnServiceError: " + reason);
+ DebugTool.logError(TAG, "OnServiceError: " + reason);
streamingStateMachine.transitionToState(StreamingStateMachine.NONE);
if (serviceCompletionListener != null) {
@@ -229,7 +229,7 @@ public class AudioStreamManager extends BaseAudioStreamManager { @Override
public void onError(String info) {
- Log.e(TAG, "Error retrieving audio streaming capability: " + info);
+ DebugTool.logError(TAG, "Error retrieving audio streaming capability: " + info);
streamingStateMachine.transitionToState(StreamingStateMachine.ERROR);
transitionToState(ERROR);
}
@@ -256,14 +256,14 @@ public class AudioStreamManager extends BaseAudioStreamManager { public void startAudioStream(boolean encrypted, final CompletionListener completionListener) {
// audio stream cannot be started without a connected internal interface
if (!internalInterface.isConnected()) {
- Log.w(TAG, "startAudioStream called without being connected.");
+ DebugTool.logWarning(TAG, "startAudioStream called without being connected.");
finish(completionListener, false);
return;
}
// streaming state must be NONE (starting the service is ready. starting stream is started)
if (streamingStateMachine.getState() != StreamingStateMachine.NONE) {
- Log.w(TAG, "startAudioStream called but streamingStateMachine is not in state NONE (current: " + streamingStateMachine.getState() + ")");
+ DebugTool.logWarning(TAG, "startAudioStream called but streamingStateMachine is not in state NONE (current: " + streamingStateMachine.getState() + ")");
finish(completionListener, false);
return;
}
@@ -333,14 +333,14 @@ public class AudioStreamManager extends BaseAudioStreamManager { */
public void stopAudioStream(final CompletionListener completionListener) {
if (!internalInterface.isConnected()) {
- Log.w(TAG, "stopAudioStream called without being connected");
+ DebugTool.logWarning(TAG, "stopAudioStream called without being connected");
finish(completionListener, false);
return;
}
// streaming state must be STARTED (starting the service is ready. starting stream is started)
if (streamingStateMachine.getState() != StreamingStateMachine.STARTED) {
- Log.w(TAG, "stopAudioStream called but streamingStateMachine is not STARTED (current: " + streamingStateMachine.getState() + ")");
+ DebugTool.logWarning(TAG, "stopAudioStream called but streamingStateMachine is not STARTED (current: " + streamingStateMachine.getState() + ")");
finish(completionListener, false);
return;
}
@@ -414,7 +414,7 @@ public class AudioStreamManager extends BaseAudioStreamManager { @Override
public void onDecoderError(Exception e) {
- Log.e(TAG, "decoder error", e);
+ DebugTool.logError(TAG, "decoder error", e);
}
};
@@ -444,7 +444,7 @@ public class AudioStreamManager extends BaseAudioStreamManager { public void pushBuffer(ByteBuffer data, CompletionListener completionListener) {
// streaming state must be STARTED (starting the service is ready. starting stream is started)
if (streamingStateMachine.getState() != StreamingStateMachine.STARTED) {
- Log.w(TAG, "AudioStreamManager is not ready!");
+ DebugTool.logWarning(TAG, "AudioStreamManager is not ready!");
return;
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/BaseAudioDecoder.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/BaseAudioDecoder.java index f0a04dc7b..14ad46620 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/BaseAudioDecoder.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/BaseAudioDecoder.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.managers.audio;
import android.content.Context;
@@ -40,10 +40,10 @@ import android.net.Uri; import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
-import android.util.Log;
import com.smartdevicelink.managers.audio.AudioStreamManager.SampleType;
import com.smartdevicelink.proxy.rpc.AudioPassThruCapabilities;
+import com.smartdevicelink.util.DebugTool;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
@@ -252,7 +252,7 @@ public abstract class BaseAudioDecoder { }
protected void onMediaCodecError(@NonNull MediaCodec.CodecException e) {
- Log.e(TAG, "MediaCodec.onError: " + e.getLocalizedMessage());
+ DebugTool.logError(TAG, "MediaCodec.onError: " + e.getLocalizedMessage());
if (listener != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
listener.onDecoderError(e);
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/SampleBuffer.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/SampleBuffer.java index af618c696..05a9cc285 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/SampleBuffer.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/audio/SampleBuffer.java @@ -1,39 +1,38 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.managers.audio;
-import android.util.Log;
-
import com.smartdevicelink.managers.audio.AudioStreamManager.SampleType;
+import com.smartdevicelink.util.DebugTool;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -210,7 +209,7 @@ public class SampleBuffer { return avg;
}
default: {
- Log.e(TAG, "SampleBuffer.get(int): The sample type is not known: " + sampleType);
+ DebugTool.logError(TAG, "SampleBuffer.get(int): The sample type is not known: " + sampleType);
return 0.0;
}
}
@@ -274,7 +273,7 @@ public class SampleBuffer { break;
}
default: {
- Log.e(TAG, "SampleBuffer.set(int): The sample type is not known: " + sampleType);
+ DebugTool.logError(TAG, "SampleBuffer.set(int): The sample type is not known: " + sampleType);
}
}
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java index 3e1702346..a29ce1536 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/file/FileManager.java @@ -36,11 +36,11 @@ import android.content.Context; import android.content.res.Resources; import android.net.Uri; import android.support.annotation.NonNull; -import android.util.Log; import com.smartdevicelink.managers.file.filetypes.SdlFile; import com.smartdevicelink.proxy.interfaces.ISdl; import com.smartdevicelink.proxy.rpc.PutFile; +import com.smartdevicelink.util.DebugTool; import java.io.IOException; import java.io.InputStream; @@ -142,7 +142,7 @@ public class FileManager extends BaseFileManager { is = context.get().getResources().openRawResource(resource); return contentsOfInputStream(is); } catch (Resources.NotFoundException e) { - Log.w(TAG, "Can't read from resource", e); + DebugTool.logError(TAG, "Can't read from resource", e); return null; } finally { if (is != null) { @@ -166,7 +166,7 @@ public class FileManager extends BaseFileManager { is = context.get().getContentResolver().openInputStream(uri); return contentsOfInputStream(is); } catch (IOException e){ - Log.w(TAG, "Can't read from Uri", e); + DebugTool.logError(TAG, "Can't read from Uri", e); return null; } finally { if (is != null) { diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java new file mode 100644 index 000000000..99723b456 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/EncryptionLifecycleManager.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.lifecycle; + +import android.support.annotation.NonNull; + +import com.smartdevicelink.managers.ServiceEncryptionListener; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.proxy.interfaces.ISdl; + +class EncryptionLifecycleManager extends BaseEncryptionLifecycleManager { + + EncryptionLifecycleManager(@NonNull ISdl internalInterface, ServiceEncryptionListener listener) { + super(internalInterface, listener); + internalInterface.addServiceListener(SessionType.NAV, securedServiceListener); + internalInterface.addServiceListener(SessionType.PCM, securedServiceListener); + } +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java new file mode 100644 index 000000000..021e5d49a --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lifecycle/LifecycleManager.java @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2019-2020 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package com.smartdevicelink.managers.lifecycle; + +import android.app.Service; +import android.content.Context; +import android.support.annotation.RestrictTo; + +import com.smartdevicelink.SdlConnection.SdlSession; +import com.smartdevicelink.SdlConnection.SdlSession2; +import com.smartdevicelink.exception.SdlException; +import com.smartdevicelink.exception.SdlExceptionCause; +import com.smartdevicelink.protocol.enums.SessionType; +import com.smartdevicelink.proxy.interfaces.ISdlServiceListener; +import com.smartdevicelink.proxy.rpc.enums.SdlDisconnectedReason; +import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; +import com.smartdevicelink.security.SdlSecurityBase; +import com.smartdevicelink.streaming.video.VideoStreamingParameters; +import com.smartdevicelink.transport.BaseTransportConfig; +import com.smartdevicelink.transport.MultiplexTransportConfig; +import com.smartdevicelink.transport.TCPTransportConfig; +import com.smartdevicelink.transport.USBTransportConfig; +import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.util.DebugTool; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collections; + +/** + * The lifecycle manager creates a central point for all SDL session logic to converge. It should only be used by + * the library itself. Usage outside the library is not permitted and will not be protected for in the future. + * + */ +@RestrictTo(RestrictTo.Scope.LIBRARY) +public class LifecycleManager extends BaseLifecycleManager { + private ISdlServiceListener videoServiceListener; + private boolean videoServiceStartResponseReceived = false; + private boolean videoServiceStartResponse = false; + private WeakReference<Context> contextWeakReference; + + public LifecycleManager(AppConfig appConfig, BaseTransportConfig config, LifecycleListener listener) { + super(appConfig, config, listener); + } + + @Override + void initialize() { + super.initialize(); + + //Handle legacy USB connections + if (_transportConfig != null && TransportType.USB.equals(_transportConfig.getTransportType())) { + //A USB transport config was provided + USBTransportConfig usbTransportConfig = (USBTransportConfig) _transportConfig; + if (usbTransportConfig.getUsbAccessory() == null) { + DebugTool.logInfo(TAG,"Legacy USB transport config was used, but received null for accessory. Attempting to connect with router service"); + //The accessory was null which means it came from a router service + MultiplexTransportConfig multiplexTransportConfig = new MultiplexTransportConfig(usbTransportConfig.getUSBContext(), appConfig.getAppID()); + multiplexTransportConfig.setRequiresHighBandwidth(true); + multiplexTransportConfig.setSecurityLevel(MultiplexTransportConfig.FLAG_MULTI_SECURITY_OFF); + multiplexTransportConfig.setPrimaryTransports(Collections.singletonList(TransportType.USB)); + multiplexTransportConfig.setSecondaryTransports(new ArrayList<TransportType>()); + _transportConfig = multiplexTransportConfig; + } + } + + if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.MULTIPLEX)) { + this.session = new SdlSession2(sdlConnectionListener, (MultiplexTransportConfig) _transportConfig); + } else if (_transportConfig != null && _transportConfig.getTransportType().equals(TransportType.TCP)) { + this.session = new SdlSession2(sdlConnectionListener, (TCPTransportConfig) _transportConfig); + } else { + this.session = SdlSession.createSession((byte) getProtocolVersion().getMajor(), sdlConnectionListener, _transportConfig); + } + } + + @Override + void cycle(SdlDisconnectedReason disconnectedReason) { + clean(); + initialize(); + if (!SdlDisconnectedReason.LEGACY_BLUETOOTH_MODE_ENABLED.equals(disconnectedReason) && !SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST.equals(disconnectedReason)) { + //We don't want to alert higher if we are just cycling for legacy bluetooth + onClose("Sdl Proxy Cycled", new SdlException("Sdl Proxy Cycled", SdlExceptionCause.SDL_PROXY_CYCLED), disconnectedReason); + } + if (session != null) { + try { + session.startSession(); + } catch (SdlException e) { + e.printStackTrace(); + } + } + } + + @RestrictTo(RestrictTo.Scope.LIBRARY) + public void setContext(Context context) { + this.contextWeakReference = new WeakReference<>(context); + } + + @Override + void setSdlSecurityStaticVars() { + super.setSdlSecurityStaticVars(); + + Context context = null; + Service service = null; + + if(this.contextWeakReference != null){ + context = contextWeakReference.get(); + } + if (context != null && context instanceof Service) { + service = (Service) context; + } + SdlSecurityBase.setAppService(service); + SdlSecurityBase.setContext(context); + } + + @Override + void onServiceStarted(SessionType sessionType) { + super.onServiceStarted(sessionType); + if (sessionType.eq(SessionType.NAV)) { + videoServiceStartResponseReceived = true; + videoServiceStartResponse = true; + } + } + + @Override + void onTransportDisconnected(String info, boolean availablePrimary, BaseTransportConfig transportConfig) { + super.onTransportDisconnected(info, availablePrimary, transportConfig); + if (availablePrimary) { + _transportConfig = transportConfig; + DebugTool.logInfo(TAG, "notifying RPC session ended, but potential primary transport available"); + cycle(SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST); + } else { + onClose(info, null, null); + } + } + + @Override + void onStartServiceNACKed(SessionType sessionType) { + super.onStartServiceNACKed(sessionType); + if (sessionType.eq(SessionType.NAV)) { + videoServiceStartResponseReceived = true; + videoServiceStartResponse = false; + } + } + + /** + * This method will try to start the video service with the requested parameters. + * When it returns it will attempt to store the accepted parameters if available. + * + * @param isEncrypted if the service should be encrypted + * @param parameters the desired video streaming parameters + */ + @Override + void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters) { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning(TAG, "Connection is not available."); + return; + } + + session.setDesiredVideoParams(parameters); + tryStartVideoStream(isEncrypted, parameters); + } + + /** + * Try to open a video service by using the video streaming parameters supplied. + * Only information from codecs, width and height are used during video format negotiation. + * + * @param isEncrypted Specify true if packets on this service have to be encrypted + * @param parameters VideoStreamingParameters that are desired. Does not guarantee this is what will be accepted. + * @return If the service is opened successfully, an instance of VideoStreamingParams is + * returned which contains accepted video format. If the service is opened with legacy + * mode (i.e. without any negotiation) then an instance of VideoStreamingParams is + * returned. If the service was not opened then null is returned. + */ + private void tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } + if (getProtocolVersion() != null && getProtocolVersion().getMajor() >= 5 && !systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)) { + DebugTool.logWarning(TAG, "Module doesn't support video streaming."); + return; + } + if (parameters == null) { + DebugTool.logWarning(TAG, "Video parameters were not supplied."); + return; + } + + + if (!videoServiceStartResponseReceived || !videoServiceStartResponse //If we haven't started the service before + || (videoServiceStartResponse && isEncrypted && !session.isServiceProtected(SessionType.NAV))) { //Or the service has been started but we'd like to start an encrypted one + session.setDesiredVideoParams(parameters); + + videoServiceStartResponseReceived = false; + videoServiceStartResponse = false; + + addVideoServiceListener(); + session.startService(SessionType.NAV, session.getSessionId(), isEncrypted); + + } + } + + private void addVideoServiceListener() { + // videos may be started and stopped. Only add this once + if (videoServiceListener == null) { + + videoServiceListener = new ISdlServiceListener() { + @Override + public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) { + videoServiceStartResponseReceived = true; + videoServiceStartResponse = true; + } + + @Override + public void onServiceEnded(SdlSession session, SessionType type) { + // reset nav flags so nav can start upon the next transport connection + videoServiceStartResponseReceived = false; + videoServiceStartResponse = false; + } + + @Override + public void onServiceError(SdlSession session, SessionType type, String reason) { + // if there is an error reset the flags so that there is a chance to restart streaming + videoServiceStartResponseReceived = false; + videoServiceStartResponse = false; + } + }; + session.addServiceListener(SessionType.NAV, videoServiceListener); + } + } + + /** + * Closes the opened video service (serviceType 11) + * + * @return true if the video service is closed successfully, return false otherwise + */ + @Override + void endVideoStream() { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning(TAG, "Connection is not available."); + return; + } + + session.stopVideoStream(); + } + + @Override + void startAudioService(boolean isEncrypted) { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning(TAG, "Connection is not available."); + return; + } + session.startService(SessionType.PCM, session.getSessionId(), isEncrypted); + } + + /** + * Closes the opened audio service (serviceType 10) + * + * @return true if the audio service is closed successfully, return false otherwise + */ + @Override + void endAudioStream() { + if (session == null) { + DebugTool.logWarning(TAG, "SdlSession is not created yet."); + return; + } + if (!session.getIsConnected()) { + DebugTool.logWarning(TAG, "Connection is not available."); + return; + } + + session.stopAudioStream(); + } +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java index b2b8e6b14..711afcc72 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenDeviceIconManager.java @@ -27,6 +27,7 @@ class LockScreenDeviceIconManager { private Context context; private static final String SDL_DEVICE_STATUS_SHARED_PREFS = "sdl.lockScreenIcon"; private static final String STORED_ICON_DIRECTORY_PATH = "sdl/lock_screen_icon/"; + private static final String TAG = "LockScreenDeviceIconManager"; interface OnIconRetrievedListener { void onImageRetrieved(Bitmap icon); @@ -49,10 +50,10 @@ class LockScreenDeviceIconManager { Bitmap icon = null; try { if (isIconCachedAndValid(iconURL)) { - DebugTool.logInfo("Icon Is Up To Date"); + DebugTool.logInfo(TAG, "Icon Is Up To Date"); icon = getFileFromCache(iconURL); if (icon == null) { - DebugTool.logInfo("Icon from cache was null, attempting to re-download"); + DebugTool.logInfo(TAG, "Icon from cache was null, attempting to re-download"); icon = AndroidTools.downloadImage(iconURL); if (icon != null) { saveFileToCache(icon, iconURL); @@ -64,7 +65,7 @@ class LockScreenDeviceIconManager { iconRetrievedListener.onImageRetrieved(icon); } else { // The icon is unknown or expired. Download the image, save it to the cache, and update the archive file - DebugTool.logInfo("Lock Screen Icon Update Needed"); + DebugTool.logInfo(TAG, "Lock Screen Icon Update Needed"); icon = AndroidTools.downloadImage(iconURL); if (icon != null) { saveFileToCache(icon, iconURL); @@ -94,15 +95,15 @@ class LockScreenDeviceIconManager { SharedPreferences sharedPref = this.context.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE); String iconLastUpdatedTime = sharedPref.getString(iconHash, null); if(iconLastUpdatedTime == null) { - DebugTool.logInfo("No Icon Details Found In Shared Preferences"); + DebugTool.logInfo(TAG, "No Icon Details Found In Shared Preferences"); return false; } else { - DebugTool.logInfo("Icon Details Found"); + DebugTool.logInfo(TAG, "Icon Details Found"); long lastUpdatedTime = 0; try { lastUpdatedTime = Long.parseLong(iconLastUpdatedTime); } catch (NumberFormatException e) { - DebugTool.logInfo("Invalid time stamp stored to shared preferences, clearing cache and share preferences"); + DebugTool.logInfo(TAG, "Invalid time stamp stored to shared preferences, clearing cache and share preferences"); clearIconDirectory(); sharedPref.edit().clear().commit(); } @@ -134,7 +135,7 @@ class LockScreenDeviceIconManager { fos.close(); writeDeviceIconParametersToSharedPreferences(iconHash); } catch (Exception e) { - DebugTool.logError("Failed to save icon to cache"); + DebugTool.logError(TAG, "Failed to save icon to cache"); e.printStackTrace(); } } @@ -152,7 +153,7 @@ class LockScreenDeviceIconManager { if (iconLastUpdatedTime != null) { Bitmap cachedIcon = BitmapFactory.decodeFile(this.context.getCacheDir() + "/" + STORED_ICON_DIRECTORY_PATH + "/" + iconHash); if(cachedIcon == null) { - DebugTool.logError("Failed to get Bitmap from decoding file cache"); + DebugTool.logError(TAG, "Failed to get Bitmap from decoding file cache"); clearIconDirectory(); sharedPref.edit().clear().commit(); return null; @@ -160,7 +161,7 @@ class LockScreenDeviceIconManager { return cachedIcon; } } else { - DebugTool.logError("Failed to get shared preferences"); + DebugTool.logError(TAG, "Failed to get shared preferences"); return null; } } @@ -194,7 +195,7 @@ class LockScreenDeviceIconManager { } iconHash = hashtext; } catch (NoSuchAlgorithmException e) { - DebugTool.logError("Unable to hash icon url"); + DebugTool.logError(TAG, "Unable to hash icon url"); e.printStackTrace(); } return iconHash; diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java index 2e81894ed..9e63b9fb8 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/LockScreenManager.java @@ -38,7 +38,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.os.Build; -import android.util.Log; import com.smartdevicelink.managers.BaseSubManager; import com.smartdevicelink.managers.CompletionListener; @@ -192,7 +191,7 @@ public class LockScreenManager extends BaseSubManager { if (notification != null) { OnDriverDistraction ddState = (OnDriverDistraction) notification; Boolean isDismissible = ddState.getLockscreenDismissibility(); - Log.i(TAG, "Lock screen dismissible: "+ isDismissible); + DebugTool.logInfo(TAG, "Lock screen dismissible: "+ isDismissible); if (isDismissible != null) { // both of these conditions must be met to be able to dismiss lockscreen if (isDismissible && enableDismissGesture){ @@ -393,7 +392,7 @@ public class LockScreenManager extends BaseSubManager { @Override public void onError(String info) { - DebugTool.logError(info); + DebugTool.logError(TAG, info); } }); } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java index d87d27ca2..a1af673a2 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/lockscreen/SDLLockScreenActivity.java @@ -38,9 +38,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.GestureDetector; import android.view.MotionEvent; +import android.view.View; import android.view.Window; import android.widget.ImageView; import android.widget.RelativeLayout; @@ -64,6 +69,9 @@ public class SDLLockScreenActivity extends Activity { private static final int MIN_SWIPE_DISTANCE = 200; private boolean mIsDismissible; private GestureDetector mGestureDetector; + private int backgroundColor = Color.parseColor("#394e60"); + private boolean useWhiteIconAndTextColor; + private final BroadcastReceiver lockScreenBroadcastReceiver = new BroadcastReceiver() { @Override @@ -137,18 +145,20 @@ public class SDLLockScreenActivity extends Activity { int customIcon = intent.getIntExtra(LOCKSCREEN_ICON_EXTRA, 0); int customView = intent.getIntExtra(LOCKSCREEN_CUSTOM_VIEW_EXTRA, 0); Bitmap deviceIcon = intent.getParcelableExtra(LOCKSCREEN_DEVICE_LOGO_BITMAP); + backgroundColor = (customColor != 0) ? customColor : backgroundColor; if (customView != 0){ setCustomView(customView); } else { setContentView(R.layout.activity_sdllock_screen); + setBackgroundColor(); + useWhiteIconAndTextColor = shouldUseWhiteForegroundForBackgroundColor(); - if (customColor != 0){ - changeBackgroundColor(customColor); - } - + // set Lock Screen Icon if (customIcon != 0){ changeIcon(customIcon); + } else { + setSdlLogo(); } if (deviceLogoEnabled && deviceIcon != null){ @@ -158,19 +168,85 @@ public class SDLLockScreenActivity extends Activity { String warningMsg = intent.getStringExtra(KEY_LOCKSCREEN_WARNING_MSG); if (mIsDismissible) { setLockscreenWarningMessage(warningMsg); + } else if (!useWhiteIconAndTextColor) { + setTextColorBlack(); } } } } - private void changeBackgroundColor(int customColor) { + /** + * Sets the lockScreen logo + */ + private void setSdlLogo() { + ImageView lockScreen_iv = findViewById(R.id.lockscreen_image); + Drawable sdlIcon = getResources().getDrawable(R.drawable.sdl_lockscreen_icon); + // Checks color contrast and determines if the logo should be black or white + if (useWhiteIconAndTextColor) { + int color = Color.parseColor("#ffffff"); + + int red = (color & 0xFF0000) / 0xFFFF; + int green = (color & 0xFF00) / 0xFF; + int blue = color & 0xFF; + + float[] matrix = {0, 0, 0, 0, red, + 0, 0, 0, 0, green, + 0, 0, 0, 0, blue, + 0, 0, 0, 1, 0}; + + ColorFilter colorFilter = new ColorMatrixColorFilter(matrix); + sdlIcon.setColorFilter(colorFilter); + } + lockScreen_iv.setImageDrawable(sdlIcon); + } + + /** + * Changes the text color to white on the lockScreen + */ + private void setTextColorBlack() { + TextView tv = findViewById(R.id.lockscreen_text); + tv.setTextColor(Color.parseColor("#000000")); + } + + /** + * Calculates the contrast of the background to determine if the Icon and Text color + * should be white or black + * @return True if Background and Icon should be white, False if black + */ + private boolean shouldUseWhiteForegroundForBackgroundColor() { + float r = Color.red(backgroundColor) / 255f; + float b = Color.blue(backgroundColor) / 255f; + float g = Color.green(backgroundColor) / 255f; + + // http://stackoverflow.com/a/3943023 + r = (r <= 0.3928f) ? (r / 12.92f) : (float) Math.pow(((r + 0.055f) / 1.055f), 2.4f); + g = (g <= 0.3928f) ? (g / 12.92f) : (float) Math.pow(((g + 0.055f) / 1.055f), 2.4f); + b = (b <= 0.3928f) ? (b / 12.92f) : (float) Math.pow(((b + 0.055f) / 1.055f), 2.4f); + + float luminescence = 0.2126f * r + 0.7152f * g + 0.0722f * b; + return luminescence <= 0.179; + } + + /** + * Sets the color of the background + * Will use default color if not set in LockScreenConfig + */ + private void setBackgroundColor() { RelativeLayout layout = findViewById(R.id.lockscreen_relative_layout); - layout.setBackgroundColor(getResources().getColor(customColor)); + layout.setBackgroundColor(backgroundColor); } + /** + * Used to change LockScreen default Icon to customIcon set in LockScreenConfig + * @param customIcon + */ private void changeIcon(int customIcon) { - ImageView lockscreen_iv = findViewById(R.id.lockscreen_image); - lockscreen_iv.setBackgroundResource(customIcon); + ImageView lockScreen_iv = findViewById(R.id.lockscreen_image); + lockScreen_iv.setVisibility(View.GONE); + + ImageView lockScreenCustom_iv = findViewById(R.id.appIcon); + lockScreenCustom_iv.setVisibility(View.VISIBLE); + lockScreenCustom_iv.setBackgroundResource(customIcon); } private void setDeviceLogo(Bitmap deviceLogo) { @@ -183,6 +259,9 @@ public class SDLLockScreenActivity extends Activity { private void setLockscreenWarningMessage(String msg) { TextView tv = findViewById(R.id.lockscreen_text); if (tv != null) { + if (!useWhiteIconAndTextColor) { + tv.setTextColor(Color.parseColor("#000000")); + } tv.setText(msg != null ? msg : getString(R.string.default_lockscreen_warning_message)); } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/SubscribeButtonManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/SubscribeButtonManager.java new file mode 100644 index 000000000..f38cf79d0 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/SubscribeButtonManager.java @@ -0,0 +1,17 @@ +package com.smartdevicelink.managers.screen; + +import android.support.annotation.NonNull; +import com.smartdevicelink.proxy.interfaces.ISdl; + +/** + * <strong>SubscribeButtonManager</strong> <br> + * + * Note: This class must be accessed through the SdlManager. Do not instantiate it by itself. <br> + * + */ +class SubscribeButtonManager extends BaseSubscribeButtonManager { + + SubscribeButtonManager(@NonNull ISdl internalInterface) { + super(internalInterface); + } +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java index b6f49a9a4..a9225e0eb 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java @@ -36,7 +36,6 @@ import android.annotation.TargetApi; import android.content.Context; import android.os.SystemClock; import android.util.DisplayMetrics; -import android.util.Log; import android.view.Display; import android.view.InputDevice; import android.view.MotionEvent; @@ -110,7 +109,7 @@ public class VideoStreamManager extends BaseVideoStreamManager { } if (VideoStreamManager.this.streamListener == null) { - Log.e(TAG, "Error starting video stream"); + DebugTool.logError(TAG, "Error starting video stream"); stateMachine.transitionToState(StreamingStateMachine.ERROR); return; } @@ -137,7 +136,7 @@ public class VideoStreamManager extends BaseVideoStreamManager { @Override public void onServiceError(SdlSession session, SessionType type, String reason) { - DebugTool.logError("Unable to start video service: " + reason); + DebugTool.logError(TAG, "Unable to start video service: " + reason); stateMachine.transitionToState(StreamingStateMachine.ERROR); transitionToState(BaseSubManager.ERROR); } @@ -236,7 +235,7 @@ public class VideoStreamManager extends BaseVideoStreamManager { @Override public void onError(String info) { - Log.e(TAG, "Error retrieving video streaming capability: " + info); + DebugTool.logError(TAG, "Error retrieving video streaming capability: " + info); stateMachine.transitionToState(StreamingStateMachine.ERROR); transitionToState(ERROR); } @@ -269,7 +268,7 @@ public class VideoStreamManager extends BaseVideoStreamManager { this.remoteDisplayClass = remoteDisplayClass; int majorProtocolVersion = internalInterface.getProtocolVersion().getMajor(); if(majorProtocolVersion >= 5 && !internalInterface.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)){ - Log.e(TAG, "Video streaming not supported on this module"); + DebugTool.logError(TAG, "Video streaming not supported on this module"); stateMachine.transitionToState(StreamingStateMachine.ERROR); return; } @@ -286,7 +285,7 @@ public class VideoStreamManager extends BaseVideoStreamManager { @Override public void onError(String info) { stateMachine.transitionToState(StreamingStateMachine.ERROR); - Log.e(TAG, "Error retrieving video streaming capability: " + info); + DebugTool.logError(TAG, "Error retrieving video streaming capability: " + info); } }); }else{ @@ -313,7 +312,7 @@ public class VideoStreamManager extends BaseVideoStreamManager { protected void startStreaming(VideoStreamingParameters parameters, boolean encrypted){ this.parameters = parameters; if (!isHMIStateVideoStreamCapable(currentOnHMIStatus)) { - Log.e(TAG, "Cannot start video service in the current HMI status"); + DebugTool.logError(TAG, "Cannot start video service in the current HMI status"); return; } //Start the video service @@ -496,7 +495,7 @@ public class VideoStreamManager extends BaseVideoStreamManager { showPresentation.start(); } catch (Exception ex) { - Log.e(TAG, "Unable to create Virtual Display."); + DebugTool.logError(TAG, "Unable to create Virtual Display."); if(DebugTool.isDebugEnabled()){ ex.printStackTrace(); } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/protocol/SdlPacket.java b/android/sdl_android/src/main/java/com/smartdevicelink/protocol/SdlPacket.java new file mode 100644 index 000000000..21a34c695 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/protocol/SdlPacket.java @@ -0,0 +1,116 @@ +package com.smartdevicelink.protocol; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.smartdevicelink.transport.utl.TransportRecord; +import com.smartdevicelink.util.DebugTool; + +public class SdlPacket extends BaseSdlPacket implements Parcelable { + private static final String TAG = "SdlPacket"; + private static final int EXTRA_PARCEL_DATA_LENGTH = 24; + + public SdlPacket(int version, boolean encryption, int frameType, + int serviceType, int frameInfo, int sessionId, + int dataSize, int messageId, byte[] payload) { + super(version, encryption, frameType, serviceType, frameInfo, sessionId, dataSize, messageId, payload); + } + + public SdlPacket(int version, boolean encryption, int frameType, + int serviceType, int frameInfo, int sessionId, + int dataSize, int messageId, byte[] payload, int offset, int bytesToWrite) { + super(version, encryption, frameType, serviceType, frameInfo, sessionId, dataSize, messageId, payload, offset, bytesToWrite); + } + + protected SdlPacket() { + super(); + } + + protected SdlPacket(BaseSdlPacket packet) { + super(packet); + } + + /* *************************************************************************************************************************************************** + * *********************************************************** Parceable Overrides ***************************************************************** + *****************************************************************************************************************************************************/ + + + + //I think this is FIFO...right? + public SdlPacket(Parcel p) { + this.version = p.readInt(); + this.encryption = (p.readInt() == 0) ? false : true; + this.frameType = p.readInt(); + this.serviceType = p.readInt(); + this.frameInfo = p.readInt(); + this.sessionId = p.readInt(); + this.dataSize = p.readInt(); + this.messageId = p.readInt(); + if(p.readInt() == 1){ //We should have a payload attached + payload = new byte[dataSize]; + p.readByteArray(payload); + } + + this.priorityCoefficient = p.readInt(); + + if(p.dataAvail() > EXTRA_PARCEL_DATA_LENGTH) { //See note on constant for why not 0 + try { + messagingVersion = p.readInt(); + if (messagingVersion >= 2) { + if (p.readInt() == 1) { //We should have a transport type attached + this.transportRecord = (TransportRecord) p.readParcelable(TransportRecord.class.getClassLoader()); + } + } + }catch (RuntimeException e){ + DebugTool.logError(TAG, "Error creating packet from parcel", e); + } + } + } + + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + + dest.writeInt(version); + dest.writeInt(encryption? 1 : 0); + dest.writeInt(frameType); + dest.writeInt(serviceType); + dest.writeInt(frameInfo); + dest.writeInt(sessionId); + dest.writeInt(dataSize); + dest.writeInt(messageId); + dest.writeInt(payload!=null? 1 : 0); + if(payload!=null){ + dest.writeByteArray(payload); + } + dest.writeInt(priorityCoefficient); + + ///Additions after initial creation + if(messagingVersion > 1){ + dest.writeInt(messagingVersion); + + dest.writeInt(transportRecord!=null? 1 : 0); + if(transportRecord != null){ + dest.writeParcelable(transportRecord,0); + } + } + + } + + public static final Parcelable.Creator<SdlPacket> CREATOR = new Parcelable.Creator<SdlPacket>() { + public SdlPacket createFromParcel(Parcel in) { + return new SdlPacket(in); + } + + @Override + public SdlPacket[] newArray(int size) { + return new SdlPacket[size]; + } + + }; +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java b/android/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java index 4a9c68dc5..ad887929a 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/protocol/WiProProtocol.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.protocol;
import com.smartdevicelink.SdlConnection.SdlConnection;
@@ -60,6 +60,7 @@ import java.util.List; */
@Deprecated
public class WiProProtocol extends AbstractProtocol {
+ private static final String TAG = "WiProProtocol";
private final static String FailurePropagating_Msg = "Failure propagating ";
//If increasing MAX PROTOCOL VERSION major version, make sure to alter it in SdlPsm
public static final Version MAX_PROTOCOL_VERSION = new Version("5.0.0");
@@ -365,7 +366,7 @@ public class WiProProtocol extends AbstractProtocol { try {
accumulator = new ByteArrayOutputStream(totalSize);
}catch(OutOfMemoryError e){
- DebugTool.logError("OutOfMemory error", e); //Garbled bits were received
+ DebugTool.logError(TAG, "OutOfMemory error", e); //Garbled bits were received
accumulator = null;
}
}
@@ -405,7 +406,7 @@ public class WiProProtocol extends AbstractProtocol { try {
handleProtocolMessageReceived(message);
} catch (Exception excp) {
- DebugTool.logError(FailurePropagating_Msg + "onProtocolMessageReceived: " + excp.toString(), excp);
+ DebugTool.logError(TAG, FailurePropagating_Msg + "onProtocolMessageReceived: " + excp.toString(), excp);
} // end-catch
hasFirstFrame = false;
@@ -631,7 +632,7 @@ public class WiProProtocol extends AbstractProtocol { try {
handleProtocolMessageReceived(message);
} catch (Exception ex) {
- DebugTool.logError(FailurePropagating_Msg + "onProtocolMessageReceived: " + ex.toString(), ex);
+ DebugTool.logError(TAG,FailurePropagating_Msg + "onProtocolMessageReceived: " + ex.toString(), ex);
handleProtocolError(FailurePropagating_Msg + "onProtocolMessageReceived: ", ex);
} // end-catch
} // end-method
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCStreamController.java b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCStreamController.java index 1cf3cec4a..28f1989e1 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCStreamController.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/RPCStreamController.java @@ -33,6 +33,7 @@ package com.smartdevicelink.proxy; import com.smartdevicelink.streaming.StreamRPCPacketizer; +@Deprecated public class RPCStreamController { private StreamRPCPacketizer rpcPacketizer; private Integer iCorrelationID; diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java index ad9969163..b3d6df61d 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java @@ -43,13 +43,13 @@ import android.os.SystemClock; import android.support.annotation.NonNull;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.Surface;
+import com.livio.taskmaster.Taskmaster;
import com.smartdevicelink.BuildConfig;
import com.smartdevicelink.Dispatcher.IDispatchingStrategy;
import com.smartdevicelink.Dispatcher.ProxyMessageDispatcher;
@@ -313,6 +313,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> private Set<String> encryptionRequiredRPCs = new HashSet<>();
private boolean rpcSecuredServiceStarted;
private ServiceEncryptionListener serviceEncryptionListener;
+ private Taskmaster taskmaster;
// Interface broker
private SdlInterfaceBroker _interfaceBroker = null;
@@ -401,11 +402,20 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
@Override
+ public void sendRPCs(List<? extends RPCMessage> rpcs, OnMultipleRequestListener listener) {
+ try {
+ SdlProxyBase.this.sendRequests(rpcs, listener);
+ } catch (SdlException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
public void sendSequentialRPCs(List<? extends RPCMessage> rpcs, OnMultipleRequestListener listener) {
try{
SdlProxyBase.this.sendSequentialRequests(rpcs,listener);
}catch (SdlException e ){
- DebugTool.logError("Issue sending sequential RPCs ", e);
+ DebugTool.logError(TAG, "Issue sending sequential RPCs ", e);
}
}
@@ -528,7 +538,23 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> public void startRPCEncryption() {
SdlProxyBase.this.startProtectedRPCService();
}
+
+ @Override
+ public Taskmaster getTaskmaster() {
+ return SdlProxyBase.this.getTaskmaster();
+ }
};
+
+ Taskmaster getTaskmaster() {
+ if (taskmaster == null) {
+ Taskmaster.Builder builder = new Taskmaster.Builder();
+ builder.setThreadCount(2);
+ builder.shouldBeDaemon(false);
+ taskmaster = builder.build();
+ taskmaster.start();
+ }
+ return taskmaster;
+ }
private void notifyPutFileStreamError(Exception e, String info)
{
@@ -565,7 +591,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> //if (!_advancedLifecycleManagementEnabled) {
// If original model, notify app the proxy is closed so it will delete and reinstanciate
- Log.d(TAG, "notifying proxy of closed");
+ DebugTool.logInfo(TAG, "notifying proxy of closed");
notifyProxyClosed(info, new SdlException("Transport disconnected.", SdlExceptionCause.SDL_UNAVAILABLE), SdlDisconnectedReason.TRANSPORT_DISCONNECT);
//}// else If ALM, nothing is required to be done here
@@ -578,7 +604,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (altTransportAvailable){
SdlProxyBase.this._transportConfig = transportConfig;
- Log.d(TAG, "notifying RPC session ended, but potential primary transport available");
+ DebugTool.logInfo(TAG, "notifying RPC session ended, but potential primary transport available");
cycleProxy(SdlDisconnectedReason.PRIMARY_TRANSPORT_CYCLE_REQUEST);
}else{
notifyProxyClosed(info, new SdlException("Transport disconnected.", SdlExceptionCause.SDL_UNAVAILABLE), SdlDisconnectedReason.TRANSPORT_DISCONNECT);
@@ -587,7 +613,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> @Override
public void onTransportError(String info, Exception e) {
- DebugTool.logError("Transport failure: " + info, e);
+ DebugTool.logError(TAG, "Transport failure: " + info, e);
notifyPutFileStreamError(e, info);
@@ -634,7 +660,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (minimumProtocolVersion != null && minimumProtocolVersion.isNewerThan(getProtocolVersion()) == 1){
- Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum protocol version %s is greater than the supported protocol version %s", minimumProtocolVersion, getProtocolVersion()));
+ DebugTool.logWarning(TAG, String.format("Disconnecting from head unit, the configured minimum protocol version %s is greater than the supported protocol version %s", minimumProtocolVersion, getProtocolVersion()));
try {
disposeInternal(SdlDisconnectedReason.MINIMUM_PROTOCOL_VERSION_HIGHER_THAN_SUPPORTED);
} catch (SdlException e) {
@@ -742,7 +768,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> @Override
public void onHeartbeatTimedOut(byte sessionID) {
final String msg = "Heartbeat timeout";
- DebugTool.logInfo(msg);
+ DebugTool.logInfo(TAG, msg);
Intent sendIntent = createBroadcastIntent();
updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "onHeartbeatTimedOut");
@@ -868,7 +894,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> boolean callbackToUIThread, Boolean preRegister, String sHashID, Boolean bAppResumeEnab,
BaseTransportConfig transportConfig) throws SdlException
{
- Log.i(TAG, "SDL_LIB_VERSION: " + BuildConfig.VERSION_NAME);
+ DebugTool.logInfo(TAG, "SDL_LIB_VERSION: " + BuildConfig.VERSION_NAME);
setProtocolVersion(new Version(PROX_PROT_VER_ONE,0,0));
if (preRegister != null && preRegister)
@@ -1307,6 +1333,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> } else {
sURLString = msg.getUrl();
}
+ sURLString = sURLString.replaceFirst("http://", "https://");
Integer iTimeout = msg.getTimeout();
@@ -1364,7 +1391,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (urlConnection == null)
{
- Log.i(TAG, "urlConnection is null, check RPC input parameters");
+ DebugTool.logInfo(TAG, "urlConnection is null, check RPC input parameters");
updateBroadcastIntent(sendIntent, "COMMENT2", "urlConnection is null, check RPC input parameters");
return;
}
@@ -1391,7 +1418,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (iResponseCode != HttpURLConnection.HTTP_OK)
{
- Log.i(TAG, "Response code not HTTP_OK, returning from sendOnSystemRequestToUrl.");
+ DebugTool.logInfo(TAG, "Response code not HTTP_OK, returning from sendOnSystemRequestToUrl.");
updateBroadcastIntent(sendIntent, "COMMENT2", "Response code not HTTP_OK, aborting request. ");
return;
}
@@ -1418,7 +1445,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> updateBroadcastIntent(sendIntent, "DATA", "Data from cloud response: " + response.toString());
sendRPCMessagePrivate(putFile);
- Log.i("sendSystemRequestToUrl", "sent to sdl");
+ DebugTool.logInfo(TAG, "sendSystemRequestToUrl sent to sdl");
updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.PUT_FILE.toString());
updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST);
@@ -1450,7 +1477,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
else
{
- DebugTool.logError("sendSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
//Log.i("sendSystemRequestToUrl", "sendSystemRequestToUrl: Data in JSON Object neither an array nor a string.");
return;
}
@@ -1485,7 +1512,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (getIsConnected())
{
sendRPCMessagePrivate(mySystemRequest);
- Log.i("sendSystemRequestToUrl", "sent to sdl");
+ DebugTool.logInfo(TAG, "sendSystemRequestToUrl sent to sdl");
updateBroadcastIntent(sendIntent2, "RPC_NAME", FunctionID.SYSTEM_REQUEST.toString());
updateBroadcastIntent(sendIntent2, "TYPE", RPCMessage.KEY_REQUEST);
@@ -1495,43 +1522,43 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
catch (SdlException e)
{
- DebugTool.logError("sendSystemRequestToUrl: Could not get data from JSONObject received.", e);
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: Could not get data from JSONObject received.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " SdlException encountered sendOnSystemRequestToUrl: "+ e);
//Log.i("pt", "sendSystemRequestToUrl: Could not get data from JSONObject received."+ e);
}
catch (JSONException e)
{
- DebugTool.logError("sendSystemRequestToUrl: JSONException: ", e);
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: JSONException: ", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " JSONException encountered sendOnSystemRequestToUrl: "+ e);
//Log.i("pt", "sendSystemRequestToUrl: JSONException: "+ e);
}
catch (UnsupportedEncodingException e)
{
- DebugTool.logError("sendSystemRequestToUrl: Could not encode string.", e);
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: Could not encode string.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " UnsupportedEncodingException encountered sendOnSystemRequestToUrl: "+ e);
//Log.i("pt", "sendSystemRequestToUrl: Could not encode string."+ e);
}
catch (ProtocolException e)
{
- DebugTool.logError("sendSystemRequestToUrl: Could not set request method to post.", e);
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: Could not set request method to post.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " ProtocolException encountered sendOnSystemRequestToUrl: "+ e);
//Log.i("pt", "sendSystemRequestToUrl: Could not set request method to post."+ e);
}
catch (MalformedURLException e)
{
- DebugTool.logError("sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server.", e);
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server.", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " MalformedURLException encountered sendOnSystemRequestToUrl: "+ e);
//Log.i("pt", "sendSystemRequestToUrl: URL Exception when sending SystemRequest to an external server."+ e);
}
catch (IOException e)
{
- DebugTool.logError("sendSystemRequestToUrl: IOException: ", e);
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: IOException: ", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " IOException while sending to cloud: IOException: "+ e);
//Log.i("pt", "sendSystemRequestToUrl: IOException: "+ e);
}
catch (Exception e)
{
- DebugTool.logError("sendSystemRequestToUrl: Unexpected Exception: ", e);
+ DebugTool.logError(TAG, "sendSystemRequestToUrl: Unexpected Exception: ", e);
updateBroadcastIntent(sendIntent, "COMMENT3", " Exception encountered sendOnSystemRequestToUrl: "+ e);
//Log.i("pt", "sendSystemRequestToUrl: Unexpected Exception: " + e);
}
@@ -1606,7 +1633,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> //A USB transport config was provided
USBTransportConfig usbTransportConfig = (USBTransportConfig) _transportConfig;
if (usbTransportConfig.getUsbAccessory() == null) {
- DebugTool.logInfo("Legacy USB transport config was used, but received null for accessory. Attempting to connect with router service");
+ DebugTool.logInfo(TAG, "Legacy USB transport config was used, but received null for accessory. Attempting to connect with router service");
//The accessory was null which means it came from a router service
MultiplexTransportConfig multiplexTransportConfig = new MultiplexTransportConfig(usbTransportConfig.getUSBContext(), _appID);
multiplexTransportConfig.setRequiresHighBandwidth(true);
@@ -1638,7 +1665,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> public void forceOnConnected(){
synchronized(CONNECTION_REFERENCE_LOCK) {
if (sdlSession != null) {
- Log.d(TAG, "Forcing on connected.... might actually need this"); //FIXME
+ DebugTool.logInfo(TAG, "Forcing on connected.... might actually need this"); //FIXME
/*if(sdlSession.getSdlConnection()==null){ //There is an issue when switching from v1 to v2+ where the connection is closed. So we restart the session during this call.
try {
sdlSession.startSession();
@@ -1822,6 +1849,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> public void dispose() throws SdlException {
SdlTrace.logProxyEvent("Application called dispose() method.", SDL_LIB_TRACE_KEY);
disposeInternal(SdlDisconnectedReason.APPLICATION_REQUESTED_DISCONNECT);
+ if (taskmaster != null) {
+ taskmaster.shutdown();
+ }
}
/**
* Terminates the App's Interface Registration, closes the transport connection, ends the protocol session, and frees any resources used by the proxy.
@@ -1963,7 +1993,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (functionName != null) {
hashTemp.put(RPCMessage.KEY_FUNCTION_NAME, functionName);
} else {
- DebugTool.logWarning("Dispatch Incoming Message - function name is null unknown RPC. FunctionId: " + message.getFunctionID());
+ DebugTool.logWarning(TAG, "Dispatch Incoming Message - function name is null unknown RPC. FunctionId: " + message.getFunctionID());
return;
}
if (message.getRPCType() == 0x00) {
@@ -1980,13 +2010,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
handleRPCMessage(hash);
} catch (final Exception excp) {
- DebugTool.logError("Failure handling protocol message: " + excp.toString(), excp);
+ DebugTool.logError(TAG, "Failure handling protocol message: " + excp.toString(), excp);
passErrorToProxyListener("Error handing incoming protocol message.", excp);
} // end-catch
} //else { Handle other protocol message types here}
} catch (final Exception e) {
// Pass error to application through listener
- DebugTool.logError("Error handing proxy event.", e);
+ DebugTool.logError(TAG, "Error handing proxy event.", e);
passErrorToProxyListener("Error handing incoming protocol message.", e);
}
}
@@ -2014,7 +2044,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
catch (final Exception e)
{
- DebugTool.logError("Error handing proxy event.", e);
+ DebugTool.logError(TAG, "Error handing proxy event.", e);
passErrorToProxyListener("Error serializing message.", e);
return null;
}
@@ -2119,14 +2149,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> default:
// Diagnostics
SdlTrace.logProxyEvent("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.", SDL_LIB_TRACE_KEY);
- DebugTool.logError("Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.");
+ DebugTool.logError(TAG, "Unknown RPC Message encountered. Check for an updated version of the SDL Proxy.");
break;
}
SdlTrace.logProxyEvent("Proxy fired callback: " + message.getFunctionName(), SDL_LIB_TRACE_KEY);
} catch(final Exception e) {
// Pass error to application through listener
- DebugTool.logError("Error handing proxy event.", e);
+ DebugTool.logError(TAG, "Error handing proxy event.", e);
if (_callbackToUIThread) {
// Run in UI thread
_mainUIHandler.post(new Runnable() {
@@ -2142,11 +2172,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
private void handleErrorsFromInternalMessageDispatcher(String info, Exception e) {
- DebugTool.logError(info, e);
+ DebugTool.logError(TAG, info, e);
// This error cannot be passed to the user, as it indicates an error
// in the communication between the proxy and the application.
- DebugTool.logError("InternalMessageDispatcher failed.", e);
+ DebugTool.logError(TAG, "InternalMessageDispatcher failed.", e);
// Note, this is the only place where the _proxyListener should be referenced asdlhronously,
// with an error on the internalMessageDispatcher, we have no other reliable way of
@@ -2183,7 +2213,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> @Override
public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) {
if(_proxyDisposed){
- DebugTool.logInfo("Ignoring start service packet, proxy is disposed");
+ DebugTool.logInfo(TAG, "Ignoring start service packet, proxy is disposed");
return;
}
if(SessionType.RPC.equals(type)){
@@ -2192,13 +2222,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (serviceEncryptionListener != null) {
serviceEncryptionListener.onEncryptionServiceUpdated(type, isEncrypted, null);
}
- DebugTool.logInfo("onServiceStarted, session Type: " + type.getName() + ", isEncrypted: " + isEncrypted);
+ DebugTool.logInfo(TAG, "onServiceStarted, session Type: " + type.getName() + ", isEncrypted: " + isEncrypted);
}
@Override
public void onServiceEnded(SdlSession session, SessionType type) {
if(_proxyDisposed){
- DebugTool.logInfo("Ignoring end service packet, proxy is disposed");
+ DebugTool.logInfo(TAG, "Ignoring end service packet, proxy is disposed");
return;
}
if (SessionType.RPC.equals(type)) {
@@ -2207,13 +2237,13 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (serviceEncryptionListener != null) {
serviceEncryptionListener.onEncryptionServiceUpdated(type, false, null);
}
- DebugTool.logInfo("onServiceEnded, session Type: " + type.getName());
+ DebugTool.logInfo(TAG, "onServiceEnded, session Type: " + type.getName());
}
@Override
public void onServiceError(SdlSession session, SessionType type, String reason) {
if(_proxyDisposed){
- DebugTool.logInfo("Ignoring start service error, proxy is disposed");
+ DebugTool.logInfo(TAG, "Ignoring start service error, proxy is disposed");
return;
}
if (SessionType.RPC.equals(type)) {
@@ -2222,7 +2252,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (serviceEncryptionListener != null) {
serviceEncryptionListener.onEncryptionServiceUpdated(type, false, "onServiceError: " + reason);
}
- DebugTool.logError("onServiceError, session Type: " + type.getName() + ", reason: " + reason);
+ DebugTool.logError(TAG, "onServiceError, session Type: " + type.getName() + ", reason: " + reason);
}
};
@@ -2307,7 +2337,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> listener.onError(request.getCorrelationID(), Result.ABORTED, errorInfo);
}
}
- DebugTool.logWarning(errorInfo);
+ DebugTool.logWarning(TAG, errorInfo);
return;
}
@@ -2630,14 +2660,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> private void handleRPCMessage(Hashtable<String, Object> hash) {
if (hash == null){
- DebugTool.logError("handleRPCMessage: hash is null, returning.");
+ DebugTool.logError(TAG, "handleRPCMessage: hash is null, returning.");
return;
}
RPCMessage rpcMsg = RpcConverter.convertTableToRpc(hash);
if (rpcMsg == null){
- DebugTool.logError("handleRPCMessage: rpcMsg is null, returning.");
+ DebugTool.logError(TAG, "handleRPCMessage: rpcMsg is null, returning.");
return;
}
@@ -2695,7 +2725,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }else{
rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION;
}
- DebugTool.logInfo("Negotiated RPC Spec version = " + rpcSpecVersion);
+ DebugTool.logInfo(TAG, "Negotiated RPC Spec version = " + rpcSpecVersion);
_vehicleType = msg.getVehicleType();
_systemSoftwareVersion = msg.getSystemSoftwareVersion();
@@ -2723,11 +2753,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (!isDebugEnabled())
{
enableDebugTool();
- DebugTool.logInfo(sVersionInfo, false);
+ DebugTool.logInfo(TAG, sVersionInfo, false);
disableDebugTool();
}
else
- DebugTool.logInfo(sVersionInfo, false);
+ DebugTool.logInfo(TAG, sVersionInfo, false);
sendIntent = createBroadcastIntent();
updateBroadcastIntent(sendIntent, "FUNCTION_NAME", "RAI_RESPONSE");
@@ -2745,7 +2775,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> //If the RPC version is too low we should simply dispose this proxy
if (minimumRPCVersion != null && minimumRPCVersion.isNewerThan(rpcSpecVersion) == 1) {
- Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum RPC version %s is greater than the supported RPC version %s", minimumRPCVersion, rpcSpecVersion));
+ DebugTool.logWarning(TAG, String.format("Disconnecting from head unit, the configured minimum RPC version %s is greater than the supported RPC version %s", minimumRPCVersion, rpcSpecVersion));
try {
disposeInternal(SdlDisconnectedReason.MINIMUM_RPC_VERSION_HIGHER_THAN_SUPPORTED);
} catch (SdlException e) {
@@ -2775,7 +2805,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> } else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID
&& functionName.equals(FunctionID.ON_ENCODED_SYNC_P_DATA.toString())) {
- Log.i("pt", "POLICIES_CORRELATION_ID SystemRequest Notification (Legacy)");
+ DebugTool.logInfo(TAG, "POLICIES_CORRELATION_ID SystemRequest Notification (Legacy)");
final OnSystemRequest msg = new OnSystemRequest(hash);
@@ -2796,7 +2826,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> else if ((new RPCResponse(hash)).getCorrelationID() == POLICIES_CORRELATION_ID
&& functionName.equals(FunctionID.ENCODED_SYNC_P_DATA.toString())) {
- Log.i("pt", "POLICIES_CORRELATION_ID SystemRequest Response (Legacy)");
+ DebugTool.logInfo(TAG, "POLICIES_CORRELATION_ID SystemRequest Response (Legacy)");
final SystemRequestResponse msg = new SystemRequestResponse(hash);
Intent sendIntent = createBroadcastIntent();
@@ -2864,7 +2894,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> } else {
rpcSpecVersion = MAX_SUPPORTED_RPC_VERSION;
}
- DebugTool.logInfo("Negotiated RPC Spec version = " + rpcSpecVersion);
+ DebugTool.logInfo(TAG, "Negotiated RPC Spec version = " + rpcSpecVersion);
_vehicleType = msg.getVehicleType();
_systemSoftwareVersion = msg.getSystemSoftwareVersion();
@@ -2886,11 +2916,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (!isDebugEnabled())
{
enableDebugTool();
- DebugTool.logInfo("SDL Proxy Version: " + _proxyVersionInfo);
+ DebugTool.logInfo(TAG, "SDL Proxy Version: " + _proxyVersionInfo);
disableDebugTool();
}
else
- DebugTool.logInfo("SDL Proxy Version: " + _proxyVersionInfo);
+ DebugTool.logInfo(TAG, "SDL Proxy Version: " + _proxyVersionInfo);
// RegisterAppInterface
if (_advancedLifecycleManagementEnabled) {
@@ -2905,7 +2935,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
//If the RPC version is too low we should simply dispose this proxy
if (minimumRPCVersion != null && minimumRPCVersion.isNewerThan(rpcSpecVersion) == 1) {
- Log.w(TAG, String.format("Disconnecting from head unit, the configured minimum RPC version %s is greater than the supported RPC version %s", minimumRPCVersion, rpcSpecVersion));
+ DebugTool.logWarning(TAG, String.format("Disconnecting from head unit, the configured minimum RPC version %s is greater than the supported RPC version %s", minimumRPCVersion, rpcSpecVersion));
try {
disposeInternal(SdlDisconnectedReason.MINIMUM_RPC_VERSION_HIGHER_THAN_SUPPORTED);
} catch (SdlException e) {
@@ -4006,10 +4036,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
} else {
if (_sdlMsgVersion != null) {
- DebugTool.logError("Unrecognized response Message: " + functionName +
+ DebugTool.logError(TAG, "Unrecognized response Message: " + functionName +
" SDL Message Version = " + _sdlMsgVersion);
} else {
- DebugTool.logError("Unrecognized response Message: " + functionName);
+ DebugTool.logError(TAG, "Unrecognized response Message: " + functionName);
}
} // end-if
@@ -4129,7 +4159,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> updateBroadcastIntent(sendIntent, "COMMENT1", "Sending to cloud: " + msg.getUrl());
sendBroadcastIntent(sendIntent);
- Log.i("pt", "send to url");
+ DebugTool.logInfo(TAG, "send to url");
if ( (msg.getUrl() != null) )
{
@@ -4299,27 +4329,30 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> //Cache this for when the lockscreen is displayed
lockScreenIconRequest = msg;
} else if (requestType == RequestType.ICON_URL) {
- //Download the icon file and send SystemRequest RPC
- Thread handleOffBoardTransmissionThread = new Thread() {
- @Override
- public void run() {
- byte[] file = FileUtls.downloadFile(msg.getUrl());
- if (file != null) {
- SystemRequest systemRequest = new SystemRequest();
- systemRequest.setFileName(msg.getUrl());
- systemRequest.setBulkData(file);
- systemRequest.setRequestType(RequestType.ICON_URL);
- try {
- sendRPCMessagePrivate(systemRequest);
- } catch (SdlException e) {
- e.printStackTrace();
+ if (msg.getUrl() != null) {
+ //Download the icon file and send SystemRequest RPC
+ Thread handleOffBoardTransmissionThread = new Thread() {
+ @Override
+ public void run() {
+ String urlHttps = msg.getUrl().replaceFirst("http://", "https://");
+ byte[] file = FileUtls.downloadFile(urlHttps);
+ if (file != null) {
+ SystemRequest systemRequest = new SystemRequest();
+ systemRequest.setFileName(msg.getUrl());
+ systemRequest.setBulkData(file);
+ systemRequest.setRequestType(RequestType.ICON_URL);
+ try {
+ sendRPCMessagePrivate(systemRequest);
+ } catch (SdlException e) {
+ e.printStackTrace();
+ }
+ } else {
+ DebugTool.logError(TAG, "File was null at: " + urlHttps);
}
- } else {
- DebugTool.logError("File was null at: " + msg.getUrl());
}
- }
- };
- handleOffBoardTransmissionThread.start();
+ };
+ handleOffBoardTransmissionThread.start();
+ }
}
}
@@ -4538,10 +4571,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
} else {
if (_sdlMsgVersion != null) {
- DebugTool.logInfo("Unrecognized notification Message: " + functionName +
+ DebugTool.logInfo(TAG, "Unrecognized notification Message: " + functionName +
" connected to SDL using message version: " + _sdlMsgVersion.getMajorVersion() + "." + _sdlMsgVersion.getMinorVersion());
} else {
- DebugTool.logInfo("Unrecognized notification Message: " + functionName);
+ DebugTool.logInfo(TAG, "Unrecognized notification Message: " + functionName);
}
} // end-if
} // end-if notification
@@ -4585,7 +4618,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> } else if (notification instanceof OnButtonPress) {
OnButtonPress onButtonPress = new OnButtonPress();
onButtonPress.setButtonPressMode(((OnButtonPress) notification).getButtonPressMode());
- onButtonPress.setCustomButtonName(((OnButtonPress) notification).getCustomButtonName());
+ onButtonPress.setCustomButtonID(((OnButtonPress) notification).getCustomButtonID());
notification2 = onButtonPress;
} else {
return null;
@@ -4868,7 +4901,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> protected void notifyProxyClosed(final String info, final Exception e, final SdlDisconnectedReason reason) {
SdlTrace.logProxyEvent("NotifyProxyClose", SDL_LIB_TRACE_KEY);
- Log.d(TAG, "notifyProxyClosed: " + info);
+ DebugTool.logInfo(TAG, "notifyProxyClosed: " + info);
OnProxyClosed message = new OnProxyClosed(info, e, reason);
queueInternalMessage(message);
}
@@ -4988,7 +5021,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> rpcPacketizer.start();
return new RPCStreamController(rpcPacketizer, request.getCorrelationID());
} catch (Exception e) {
- Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
+ DebugTool.logError(TAG, "SyncConnectionUnable to start streaming:", e);
return null;
}
}
@@ -5009,7 +5042,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> rpcPacketizer.start();
return new RPCStreamController(rpcPacketizer, request.getCorrelationID());
} catch (Exception e) {
- Log.e("SyncConnection", "Unable to start streaming:" + e.toString());
+ DebugTool.logError(TAG, "SyncConnection Unable to start streaming:", e);
return null;
}
}
@@ -5294,10 +5327,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
builder.append(paramName);
}
- DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString());
+ DebugTool.logWarning(TAG, "StartService for nav failed. Rejected params: " + builder.toString());
} else {
- DebugTool.logWarning("StartService for nav failed (rejected params not supplied)");
+ DebugTool.logWarning(TAG, "StartService for nav failed (rejected params not supplied)");
}
return null;
}
@@ -5334,11 +5367,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> @SuppressWarnings("unused")
public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) {
if (sdlSession == null) {
- DebugTool.logWarning("SdlSession is not created yet.");
+ DebugTool.logWarning(TAG, "SdlSession is not created yet.");
return null;
}
if (!sdlSession.getIsConnected()) {
- DebugTool.logWarning("Connection is not available.");
+ DebugTool.logWarning(TAG, "Connection is not available.");
return null;
}
@@ -5360,11 +5393,11 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> */
public void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters) {
if (sdlSession == null) {
- DebugTool.logWarning("SdlSession is not created yet.");
+ DebugTool.logWarning(TAG, "SdlSession is not created yet.");
return;
}
if (!sdlSession.getIsConnected()) {
- DebugTool.logWarning("Connection is not available.");
+ DebugTool.logWarning(TAG, "Connection is not available.");
return;
}
@@ -5462,7 +5495,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> @TargetApi(19)
public void startRemoteDisplayStream(Context context, final Class<? extends SdlRemoteDisplay> remoteDisplay, final VideoStreamingParameters parameters, final boolean encrypted){
if(protocolVersion!= null && protocolVersion.getMajor() >= 5 && !_systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)){
- Log.e(TAG, "Video streaming not supported on this module");
+ DebugTool.logError(TAG, "Video streaming not supported on this module");
return;
}
//Create streaming manager
@@ -5483,7 +5516,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> @Override
public void onError(String info) {
- Log.e(TAG, "Error retrieving video streaming capability: " + info);
+ DebugTool.logError(TAG, "Error retrieving video streaming capability: " + info);
}
});
@@ -5529,15 +5562,15 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> @SuppressWarnings("unused")
private VideoStreamingParameters tryStartVideoStream(boolean isEncrypted, VideoStreamingParameters parameters) {
if (sdlSession == null) {
- DebugTool.logWarning("SdlSession is not created yet.");
+ DebugTool.logWarning(TAG, "SdlSession is not created yet.");
return null;
}
if(protocolVersion!= null && protocolVersion.getMajor() >= 5 && !_systemCapabilityManager.isCapabilitySupported(SystemCapabilityType.VIDEO_STREAMING)){
- DebugTool.logWarning("Module doesn't support video streaming.");
+ DebugTool.logWarning(TAG, "Module doesn't support video streaming.");
return null;
}
if (parameters == null) {
- DebugTool.logWarning("Video parameters were not supplied.");
+ DebugTool.logWarning(TAG, "Video parameters were not supplied.");
return null;
}
@@ -5576,10 +5609,10 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> builder.append(paramName);
}
- DebugTool.logWarning("StartService for nav failed. Rejected params: " + builder.toString());
+ DebugTool.logWarning(TAG, "StartService for nav failed. Rejected params: " + builder.toString());
} else {
- DebugTool.logWarning("StartService for nav failed (rejected params not supplied)");
+ DebugTool.logWarning(TAG, "StartService for nav failed (rejected params not supplied)");
}
return null;
@@ -5667,15 +5700,15 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> public IAudioStreamListener startAudioStream(boolean isEncrypted, AudioStreamingCodec codec,
AudioStreamingParams params) {
if (sdlSession == null) {
- DebugTool.logWarning("SdlSession is not created yet.");
+ DebugTool.logWarning(TAG, "SdlSession is not created yet.");
return null;
}
if (!sdlSession.getIsConnected()) {
- DebugTool.logWarning("Connection is not available.");
+ DebugTool.logWarning(TAG, "Connection is not available.");
return null;
}
if (codec != AudioStreamingCodec.LPCM) {
- DebugTool.logWarning("Audio codec " + codec + " is not supported.");
+ DebugTool.logWarning(TAG, "Audio codec " + codec + " is not supported.");
return null;
}
@@ -5692,7 +5725,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> scheduler.shutdown();
if (pcmServiceStartResponse) {
- DebugTool.logInfo("StartService for audio succeeded");
+ DebugTool.logInfo(TAG, "StartService for audio succeeded");
return sdlSession.startAudioStream();
} else {
if (pcmServiceStartRejectedParams != null) {
@@ -5703,9 +5736,9 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> }
builder.append(paramName);
}
- DebugTool.logWarning("StartService for audio failed. Rejected params: " + builder.toString());
+ DebugTool.logWarning(TAG, "StartService for audio failed. Rejected params: " + builder.toString());
} else {
- DebugTool.logWarning("StartService for audio failed (rejected params not supplied)");
+ DebugTool.logWarning(TAG, "StartService for audio failed (rejected params not supplied)");
}
return null;
}
@@ -5842,7 +5875,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> l.onLockScreenIconDownloaded(bitmap);
}
else{
- String url = lockScreenIconRequest.getUrl();
+ String url = lockScreenIconRequest.getUrl().replaceFirst("http://", "https://");
sdlSession.getLockScreenMan().downloadLockScreenIcon(url, l);
}
}
@@ -6741,7 +6774,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> if (sdlMsgVersion == null) {
sdlMsgVersion = new SdlMsgVersion();
if(protocolVersion.getMajor() == 1) {
- DebugTool.logInfo("Connected to an older module, must send 1.0.0 as RPC spec");
+ DebugTool.logInfo(TAG, "Connected to an older module, must send 1.0.0 as RPC spec");
sdlMsgVersion.setMajorVersion(1);
sdlMsgVersion.setMinorVersion(0);
}else {
@@ -8377,7 +8410,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> //streamListener = startVideoStream(encrypted,parameters);d
streamListener = sdlSession.startVideoStream();
if(streamListener == null){
- Log.e(TAG, "Error starting video service");
+ DebugTool.logError(TAG, "Error starting video service");
return;
}
VideoStreamingCapability capability = (VideoStreamingCapability)_systemCapabilityManager.getCapability(SystemCapabilityType.VIDEO_STREAMING);
@@ -8394,7 +8427,7 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> } catch (Exception e) {
e.printStackTrace();
}
- Log.d(TAG, parameters.toString());
+ DebugTool.logInfo(TAG, parameters.toString());
}
public void stopStreaming(){
@@ -8483,14 +8516,14 @@ public abstract class SdlProxyBase<proxyListenerType extends IProxyListenerBase> showPresentation.start();
} catch (Exception ex) {
- Log.e(TAG, "Unable to create Virtual Display.");
+ DebugTool.logError(TAG, "Unable to create Virtual Display.");
}
}
@Override
public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) {
if(SessionType.NAV.equals(type) && session != null ){
- DebugTool.logInfo("Video service has been started. Starting video stream from proxy");
+ DebugTool.logInfo(TAG, "Video service has been started. Starting video stream from proxy");
if(session.getAcceptedVideoParams() != null){
videoStreamingParameters = session.getAcceptedVideoParams();
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamRPCPacketizer.java b/android/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamRPCPacketizer.java index eb6b14e84..59904888d 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamRPCPacketizer.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamRPCPacketizer.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.streaming;
import com.smartdevicelink.SdlConnection.SdlSession;
@@ -54,6 +54,7 @@ import java.io.IOException; import java.io.InputStream;
import java.util.Hashtable;
+@Deprecated
public class StreamRPCPacketizer extends AbstractPacketizer implements IPutFileResponseListener, Runnable{
private Integer iInitialCorrID = 0;
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/streaming/video/SdlRemoteDisplay.java b/android/sdl_android/src/main/java/com/smartdevicelink/streaming/video/SdlRemoteDisplay.java index c720cd22c..cdb80ef1e 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/streaming/video/SdlRemoteDisplay.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/streaming/video/SdlRemoteDisplay.java @@ -39,13 +39,14 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; -import android.util.Log; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; +import com.smartdevicelink.util.DebugTool; + import java.lang.reflect.Constructor; import java.util.concurrent.Callable; @@ -183,7 +184,7 @@ public abstract class SdlRemoteDisplay extends Presentation { remoteDisplay = (SdlRemoteDisplay) constructor.newInstance(context, mDisplay); } catch (Exception e) { e.printStackTrace(); - Log.e(TAG, "Unable to create Presentation Class"); + DebugTool.logError(TAG, "Unable to create Presentation Class"); presentationShowError = true; return; } @@ -196,7 +197,7 @@ public abstract class SdlRemoteDisplay extends Presentation { } } catch (WindowManager.InvalidDisplayException ex) { - Log.e(TAG, "Couldn't show presentation! Display was removed in the meantime.", ex); + DebugTool.logError(TAG, "Couldn't show presentation! Display was removed in the meantime.", ex); remoteDisplay = null; presentationShowError = true; } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/trace/SdlTrace.java b/android/sdl_android/src/main/java/com/smartdevicelink/trace/SdlTrace.java index 531f02831..e3bedd6a2 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/trace/SdlTrace.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/trace/SdlTrace.java @@ -433,7 +433,7 @@ public class SdlTrace { try {
localTraceListener.logXmlMsg(msg, SDL_LIB_TRACE_KEY);
} catch (Exception ex) {
- DebugTool.logError("Failure calling ISTListener: " + ex.toString(), ex);
+ DebugTool.logError(SYSTEM_LOG_TAG, "Failure calling ISTListener: " + ex.toString(), ex);
return false;
}
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/trace/TraceDeviceInfo.java b/android/sdl_android/src/main/java/com/smartdevicelink/trace/TraceDeviceInfo.java index 587a6ae2b..584b388ef 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/trace/TraceDeviceInfo.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/trace/TraceDeviceInfo.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
/**
*
*/
@@ -50,6 +50,7 @@ import java.util.Set; public class TraceDeviceInfo {
// http://developer.android.com/guide/topics/data/data-storage.html
+ private static final String TAG = "TraceDeviceInfo";
private static TelephonyManager m_telephonyManager;
// Constructor
@@ -74,7 +75,7 @@ public class TraceDeviceInfo { try { // getDeviceId() requires android.permission.READ_PHONE_STATE
info = "<deviceid>" + m_telephonyManager.getDeviceId() + "</deviceid>";
} catch (Exception e1) {
- DebugTool.logError("Failure getting telephony device ID: " + e1.toString(), e1);
+ DebugTool.logError(TAG, "Failure getting telephony device ID: " + e1.toString(), e1);
}
info = "<pt>";
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/BTTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/BTTransport.java index bc204ebaf..f86a3f062 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/BTTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/BTTransport.java @@ -1,34 +1,34 @@ -/* - * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following - * disclaimer in the documentation and/or other materials provided with the - * distribution. - * - * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ +/*
+ * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
package com.smartdevicelink.transport;
import android.bluetooth.BluetoothAdapter;
@@ -58,7 +58,8 @@ import java.util.UUID; *
*/
@Deprecated
-public class BTTransport extends SdlTransport {
+public class BTTransport extends SdlTransport {
+ private static final String TAG = "BTTransport";
//936DA01F9ABD4D9D80C702AF85C822A8
private final static UUID SDL_V4_MOBILE_APPLICATION_SVC_CLASS = new UUID(0x936DA01F9ABD4D9DL, 0x80C702AF85C822A8L);
@@ -296,7 +297,7 @@ public class BTTransport extends SdlTransport { _transportReader = null;
}
} catch (Exception e) {
- DebugTool.logError("Failed to stop transport reader thread.", e);
+ DebugTool.logError(TAG, "Failed to stop transport reader thread.", e);
} // end-catch
try {
@@ -305,7 +306,7 @@ public class BTTransport extends SdlTransport { _bluetoothAdapterMonitor = null;
}
} catch (Exception e) {
- DebugTool.logError("Failed to stop adapter monitor thread.", e);
+ DebugTool.logError(TAG, "Failed to stop adapter monitor thread.", e);
}
try {
@@ -314,7 +315,7 @@ public class BTTransport extends SdlTransport { _serverSocket = null;
}
} catch (Exception e) {
- DebugTool.logError("Failed to close serverSocket", e);
+ DebugTool.logError(TAG, "Failed to close serverSocket", e);
} // end-catch
try {
@@ -323,7 +324,7 @@ public class BTTransport extends SdlTransport { _activeSocket = null;
}
} catch (Exception e) {
- DebugTool.logError("Failed to close activeSocket", e);
+ DebugTool.logError(TAG, "Failed to close activeSocket", e);
} // end-catch
@@ -334,7 +335,7 @@ public class BTTransport extends SdlTransport { _output = null;
}
} catch (Exception e) {
- DebugTool.logError("Failed to close output stream", e);
+ DebugTool.logError(TAG, "Failed to close output stream", e);
} // end-catch
if (ex == null) {
@@ -361,7 +362,7 @@ public class BTTransport extends SdlTransport { _output.write(msgBytes, 0, msgBytes.length);
sendResult = true;
} catch (Exception ex) {
- DebugTool.logError("Error writing to Bluetooth socket: " + ex.toString(), ex);
+ DebugTool.logError(TAG, "Error writing to Bluetooth socket: " + ex.toString(), ex);
handleTransportError("Error writing to Bluetooth socket:", ex);
sendResult = false;
} // end-catch
@@ -461,7 +462,7 @@ public class BTTransport extends SdlTransport { if(currentByte == -1){ //If we read a -1 and the psm didn't move forward, then there is a problem
if (!isHalted) {
// Only call disconnect if the thread has not been halted
- DebugTool.logError("End of stream reached!");
+ DebugTool.logError(TAG, "End of stream reached!");
disconnect("End of stream reached.", null);
}
}
@@ -479,7 +480,7 @@ public class BTTransport extends SdlTransport { // Only call disconnect if the thread has not been halted
clearInputStream();
String errString = "Failure in BTTransport reader thread: " + excp.toString();
- DebugTool.logError(errString, excp);
+ DebugTool.logError(TAG, errString, excp);
disconnect(errString, excp);
}
return;
@@ -493,7 +494,7 @@ public class BTTransport extends SdlTransport { _input = null;
}
} catch (Exception e) {
- DebugTool.logError("Failed to close input stream", e);
+ DebugTool.logError(TAG, "Failed to close input stream", e);
} // end-catch
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBaseTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBaseTransport.java index d1dc5cbb3..10c1c9880 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBaseTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBaseTransport.java @@ -32,7 +32,9 @@ package com.smartdevicelink.transport; +import android.os.Bundle; import android.os.Handler; +import android.os.Message; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.transport.utl.TransportRecord; @@ -46,6 +48,10 @@ public abstract class MultiplexBaseTransport { public static final int STATE_CONNECTED = 3; // now connected to a remote device public static final int STATE_ERROR = 4; // Something bad happened, we wil not try to restart the thread + public static final String ERROR_REASON_KEY = "ERROR_REASON"; + public static final byte REASON_SPP_ERROR = 0x01; // REASON = SPP error, which is sent through bundle. + public static final byte REASON_NONE = 0x0; + public static final String LOG = "log"; public static final String DEVICE_NAME = "device_name"; public static final String DEVICE_ADDRESS = "device_address"; @@ -67,16 +73,22 @@ public abstract class MultiplexBaseTransport { } protected synchronized void setState(int state) { + setState(state, null); + } + + protected synchronized void setState(int state, Bundle bundle) { if(state == mState){ return; //State hasn't changed. Will not updated listeners. } //Log.d(TAG, "Setting state from: " +mState + " to: " +state); - int previousState = mState; + int arg2 = mState; mState = state; // Give the new state to the Handler so the UI Activity can update //Also sending the previous state so we know if we lost a connection - handler.obtainMessage(SdlRouterService.MESSAGE_STATE_CHANGE, state, previousState, getTransportRecord()).sendToTarget(); + Message msg = handler.obtainMessage(SdlRouterService.MESSAGE_STATE_CHANGE, state, arg2, getTransportRecord()); + msg.setData(bundle); + msg.sendToTarget(); } public String getAddress(){ @@ -114,6 +126,7 @@ public abstract class MultiplexBaseTransport { } protected abstract void stop(int state); + protected void stop(int state, byte error) {}; public abstract void write(byte[] out, int offset, int count); diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java index 644cda21b..5b67fa444 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexBluetoothTransport.java @@ -30,11 +30,11 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.RequiresPermission; -import android.util.Log; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.transport.utl.TransportRecord; +import com.smartdevicelink.util.DebugTool; import java.io.IOException; import java.io.InputStream; @@ -263,29 +263,41 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ * Stop all threads */ public synchronized void stop() { - stop(STATE_NONE); + stop(STATE_NONE, REASON_NONE); } - protected synchronized void stop(int stateToTransitionTo) { - //Log.d(TAG, "Attempting to close the bluetooth serial server"); - if (mConnectThread != null) { - mConnectThread.cancel(); - mConnectThread = null; - } - if (mConnectedThread != null) { - mConnectedThread.cancel(); - mConnectedThread = null; - } - if (mConnectedWriteThread != null) {mConnectedWriteThread.cancel(); mConnectedWriteThread = null;} + protected synchronized void stop(int stateToTransitionTo) { + this.stop(stateToTransitionTo, REASON_NONE); + } + @Override + protected synchronized void stop(int stateToTransitionTo, byte error) { + super.stop(stateToTransitionTo, error); + DebugTool.logInfo(TAG, "Attempting to close the bluetooth serial server"); + if (mConnectThread != null) { + mConnectThread.cancel(); + mConnectThread = null; + } - if (mSecureAcceptThread != null) { - mSecureAcceptThread.cancel(); - mSecureAcceptThread = null; - } + if (mConnectedThread != null) { + mConnectedThread.cancel(); + mConnectedThread = null; + } + if (mConnectedWriteThread != null) {mConnectedWriteThread.cancel(); mConnectedWriteThread = null;} + + if (mSecureAcceptThread != null) { + mSecureAcceptThread.cancel(); + mSecureAcceptThread = null; + } + + if (stateToTransitionTo == MultiplexBaseTransport.STATE_ERROR) { + Bundle bundle = new Bundle(); + bundle.putByte(ERROR_REASON_KEY, error); + setState(stateToTransitionTo, bundle); + } else { + setState(stateToTransitionTo, null); + } + } - setState(stateToTransitionTo); - } - /** * Write to the ConnectedThread in an unsynchronized manner @@ -375,6 +387,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ } } catch (IOException e) { //Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e); + MultiplexBluetoothTransport.this.stop(STATE_ERROR, REASON_SPP_ERROR); //Let's try to shut down this thead }catch(SecurityException e2){ //Log.e(TAG, "<LIVIO> Security Exception in Accept Thread - "+e2.toString()); @@ -390,7 +403,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ @RequiresPermission(Manifest.permission.BLUETOOTH) public void run() { synchronized(THREAD_LOCK){ - Log.d(TAG, "Socket Type: " + mSocketType + + DebugTool.logInfo(TAG, "Socket Type: " + mSocketType + " BEGIN mAcceptThread" + this); setName("AcceptThread" + mSocketType); @@ -401,12 +414,12 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ while (mState != STATE_CONNECTED) { try { if(listenAttempts>=5){ - Log.e(TAG, "Complete failure in attempting to listen for Bluetooth connection, erroring out."); - MultiplexBluetoothTransport.this.stop(STATE_ERROR); + DebugTool.logError(TAG, "Complete failure in attempting to listen for Bluetooth connection, erroring out."); + MultiplexBluetoothTransport.this.stop(STATE_ERROR, REASON_NONE); return; } listenAttempts++; - Log.d(TAG, "SDL Bluetooth Accept thread is running."); + DebugTool.logInfo(TAG, "SDL Bluetooth Accept thread is running."); // This is a blocking call and will only return on a // successful connection or an exception @@ -416,13 +429,13 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ } else{ - Log.e(TAG, "Listening Socket was null, stopping the bluetooth serial server."); - MultiplexBluetoothTransport.this.stop(STATE_ERROR); + DebugTool.logError(TAG, "Listening Socket was null, stopping the bluetooth serial server."); + MultiplexBluetoothTransport.this.stop(STATE_ERROR, REASON_NONE); return; } } catch (IOException e) { - Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed"); - MultiplexBluetoothTransport.this.stop(STATE_ERROR); + DebugTool.logError(TAG, "Socket Type: " + mSocketType + "accept() failed"); + MultiplexBluetoothTransport.this.stop(STATE_ERROR, REASON_SPP_ERROR); return; } @@ -440,29 +453,29 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ case STATE_CONNECTED: // Either not ready or already connected. Terminate new socket. try { - Log.d(TAG, "Close unwanted socket"); + DebugTool.logInfo(TAG, "Close unwanted socket"); socket.close(); } catch (IOException e) { - Log.e(TAG, "Could not close unwanted socket", e); + DebugTool.logError(TAG, "Could not close unwanted socket", e); } break; } } } } - Log.d(TAG, mState + " END mAcceptThread, socket Type: " + mSocketType); + DebugTool.logInfo(TAG, mState + " END mAcceptThread, socket Type: " + mSocketType); } } public synchronized void cancel() { - Log.d(TAG, mState + " Socket Type " + mSocketType + " cancel "); + DebugTool.logInfo(TAG, mState + " Socket Type " + mSocketType + " cancel "); try { if(mmServerSocket != null){ mmServerSocket.close(); } } catch (IOException e) { - Log.e(TAG, mState + " Socket Type " + mSocketType + " close() of server failed "+ Arrays.toString(e.getStackTrace())); + DebugTool.logError(TAG, mState + " Socket Type " + mSocketType + " close() of server failed "+ Arrays.toString(e.getStackTrace())); } } } @@ -488,7 +501,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ try{ mAdapter.cancelDiscovery(); }catch(SecurityException e2){ - Log.e(TAG, "Don't have required permision to cancel discovery. Moving on"); + DebugTool.logError(TAG, "Don't have required permision to cancel discovery. Moving on"); } } @@ -575,11 +588,11 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ }else{tryInsecure = true;} } catch (IOException io) { tryInsecure = true; - Log.e(TAG,"createRfcommSocketToServiceRecord exception - " + io.toString()); + DebugTool.logError(TAG, "createRfcommSocketToServiceRecord exception - " + io.toString()); SdlRouterService.setBluetoothPrefs(0,SHARED_PREFS); } catch (Exception e){ - Log.e(TAG,"createRfcommSocketToServiceRecord exception - " + e.toString()); + DebugTool.logError(TAG, "createRfcommSocketToServiceRecord exception - " + e.toString()); SdlRouterService.setBluetoothPrefs(0,SHARED_PREFS); } @@ -640,13 +653,13 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ } } catch (IOException e) { connectionFailed(); - Log.e(TAG,e.getClass().getSimpleName() + DebugTool.logError(TAG,e.getClass().getSimpleName() + " caught connecting to the bluetooth socket: " + e.toString()); try { mmSocket.close(); } catch (IOException e2) { - Log.e(TAG,"unable to close() socket during connection failure" + e2); + DebugTool.logError(TAG, "unable to close() socket during connection failure" + e2); } return; } @@ -665,13 +678,13 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ } else { - Log.e(TAG, "There was a problem opening up RFCOMM"); + DebugTool.logError(TAG, "There was a problem opening up RFCOMM"); } } public void cancel() { try { - Log.d(TAG, "Calling Cancel in the connect thread"); + DebugTool.logInfo(TAG, "Calling Cancel in the connect thread"); mmSocket.close(); } catch (IOException e) { // close() of connect socket failed @@ -701,7 +714,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ tmpOut = socket.getOutputStream(); } catch (IOException e) { // temp sockets not created - Log.e(TAG, "Connected Write Thread: " + e.getMessage()); + DebugTool.logError(TAG, "Connected Write Thread: " + e.getMessage()); } mmOutStream = tmpOut; @@ -714,7 +727,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ public void write(byte[] buffer, int offset, int count) { try { if(buffer==null){ - Log.w(TAG, "Can't write to device, nothing to send"); + DebugTool.logWarning(TAG, "Can't write to device, nothing to send"); return; } //This would be a good spot to log out all bytes received @@ -723,7 +736,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ } catch (IOException|NullPointerException e) { // STRICTLY to catch mmOutStream NPE // Exception during write //OMG! WE MUST NOT BE CONNECTED ANYMORE! LET THE USER KNOW - Log.e(TAG, "Error sending bytes to connected device!"); + DebugTool.logError(TAG, "Error sending bytes to connected device!"); connectionLost(); } } @@ -740,7 +753,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ } } catch (IOException e) { // close() of connect socket failed - Log.d(TAG, "Write Thread: " + e.getMessage()); + DebugTool.logInfo(TAG, "Write Thread: " + e.getMessage()); } } } @@ -760,7 +773,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ tmpIn = socket.getInputStream(); } catch (IOException e) { // temp sockets not created - Log.e(TAG, "Connected Read Thread: "+e.getMessage()); + DebugTool.logError(TAG, "Connected Read Thread: "+e.getMessage()); } mmInStream = tmpIn; @@ -768,7 +781,7 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ @SuppressLint("NewApi") public void run() { - Log.d(TAG, "Running the Connected Thread"); + DebugTool.logInfo(TAG, "Running the Connected Thread"); byte input = 0; int bytesRead = 0; byte[] buffer = new byte[READ_BUFFER_SIZE]; @@ -801,9 +814,11 @@ public class MultiplexBluetoothTransport extends MultiplexBaseTransport{ } } } catch (IOException|NullPointerException e) { // NPE is ONLY to catch error on mmInStream - Log.e(TAG, "Lost connection in the Connected Thread"); - e.printStackTrace(); - connectionLost(); + DebugTool.logError(TAG, "Lost connection in the Connected Thread"); + if(DebugTool.isDebugEnabled()){ + e.printStackTrace(); + } + connectionLost(); break; } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java index 0fa211bd9..50d6ba051 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTcpTransport.java @@ -36,11 +36,11 @@ import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.util.Log; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.transport.utl.WiFiSocketFactory; +import com.smartdevicelink.util.DebugTool; import java.io.IOException; import java.io.InputStream; @@ -99,7 +99,7 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport { } } catch (Exception e) { - logError("TCPTransport: Exception during transport thread starting", e); + logError(TAG, "TCPTransport: Exception during transport thread starting", e); } } } else { @@ -134,7 +134,7 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport { } mSocket = null; } catch (IOException e) { - logError("TCPTransport.disconnect: Exception during disconnect: " + e.getMessage()); + logError(TAG,"TCPTransport.disconnect: Exception during disconnect: " + e.getMessage()); } setState(state); @@ -227,7 +227,7 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport { mInputStream = mSocket.getInputStream(); startWriteThread(); } catch (IOException e) { - logError("TCPTransport.connect: Exception during connect stage: " + e.getMessage()); + logError(TAG, "TCPTransport.connect: Exception during connect stage: " + e.getMessage()); } bConnected = (null != mSocket) && mSocket.isConnected(); @@ -314,7 +314,7 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport { if (psm.getState() == SdlPsm.FINISHED_STATE) { synchronized (MultiplexTcpTransport.this) { - Log.d(TAG, "Packet formed, sending off"); + DebugTool.logInfo(TAG, "Packet formed, sending off"); SdlPacket packet = psm.getFormedPacket(); packet.setTransportRecord(getTransportRecord()); handler.obtainMessage(SdlRouterService.MESSAGE_READ, packet).sendToTarget(); @@ -348,9 +348,9 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport { */ private void internalHandleStreamReadError() { if(isHalted){ - logError("TCPTransport.run: Exception during reading data, but thread already halted"); + logError(TAG, "TCPTransport.run: Exception during reading data, but thread already halted"); } else { - logError("TCPTransport.run: Exception during reading data"); + logError(TAG, "TCPTransport.run: Exception during reading data"); MultiplexTcpTransport.this.stop(STATE_NONE); } } @@ -382,13 +382,13 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport { logInfo("TCPTransport.sendBytesOverTransport: successfully sent data"); } } catch (IOException e) { - logError("TCPTransport.sendBytesOverTransport: error during sending data: " + e.getMessage()); + logError(TAG, "TCPTransport.sendBytesOverTransport: error during sending data: " + e.getMessage()); } } else { if (isHalted) { - logError("TCPTransport: sendBytesOverTransport request accepted, thread is cancelled"); + logError(TAG, "TCPTransport: sendBytesOverTransport request accepted, thread is cancelled"); } else { - logError("TCPTransport: sendBytesOverTransport request accepted, but output stream is null"); + logError(TAG, "TCPTransport: sendBytesOverTransport request accepted, but output stream is null"); } } @@ -418,13 +418,13 @@ public class MultiplexTcpTransport extends MultiplexBaseTransport { try { mOutputStream.flush(); } catch (IOException e) { - logError("TCPTransport flushing output stream failed: " + e.getMessage()); + logError(TAG, "TCPTransport flushing output stream failed: " + e.getMessage()); } try { mOutputStream.close(); } catch (IOException e) { - logError("TCPTransport closing output stream failed: " + e.getMessage()); + logError(TAG, "TCPTransport closing output stream failed: " + e.getMessage()); } mOutputStream = null; } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransport.java index eac5a27e0..0bacd3a2f 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexTransport.java @@ -38,13 +38,13 @@ import android.content.Context; import android.os.Build; import android.os.Looper; import android.os.Parcelable; -import android.util.Log; import com.smartdevicelink.SdlConnection.SdlConnection; import com.smartdevicelink.exception.SdlException; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.transport.utl.TransportRecord; +import com.smartdevicelink.util.DebugTool; import java.util.List; @@ -122,7 +122,7 @@ public class MultiplexTransport extends SdlTransport{ @Override public void openConnection() throws SdlException { - Log.d(TAG, "Open connection"); + DebugTool.logInfo(TAG, "Open connection"); if(brokerThread!=null){ brokerThread.startConnection(); }//else should log out @@ -134,7 +134,7 @@ public class MultiplexTransport extends SdlTransport{ if(isDisconnecting){ return; } - Log.d(TAG, "Close connection"); + DebugTool.logInfo(TAG, "Close connection"); this.isDisconnecting= true; if(brokerThread!= null){ brokerThread.cancel(); @@ -275,7 +275,7 @@ public class MultiplexTransport extends SdlTransport{ @Override public boolean onHardwareConnected(TransportType type) { if(super.onHardwareConnected(type)){ - Log.d(TAG, "On transport connected..."); + DebugTool.logInfo(TAG, "On transport connected..."); if(!connected){ connected = true; handleTransportConnected(); @@ -299,17 +299,17 @@ public class MultiplexTransport extends SdlTransport{ public void onHardwareDisconnected(TransportType type) { super.onHardwareDisconnected(type); if(connected){ - Log.d(TAG, "Handling disconnect"); + DebugTool.logInfo(TAG, "Handling disconnect"); connected = false; SdlConnection.enableLegacyMode(isLegacyModeEnabled(), TransportType.BLUETOOTH); if(isLegacyModeEnabled()){ - Log.d(TAG, "Handle transport disconnect, legacy mode enabled"); + DebugTool.logInfo(TAG, "Handle transport disconnect, legacy mode enabled"); this.stop(); isDisconnecting = true; //handleTransportDisconnected(""); handleTransportError("",null); //This seems wrong, but it works }else{ - Log.d(TAG, "Handle transport Error"); + DebugTool.logInfo(TAG, "Handle transport Error"); isDisconnecting = true; handleTransportError("",null); //This seems wrong, but it works } @@ -321,7 +321,7 @@ public class MultiplexTransport extends SdlTransport{ super.onLegacyModeEnabled(); SdlConnection.enableLegacyMode(isLegacyModeEnabled(), TransportType.BLUETOOTH); if(isLegacyModeEnabled()){ - Log.d(TAG, "Handle on legacy mode enabled"); + DebugTool.logInfo(TAG, "Handle on legacy mode enabled"); this.stop(); isDisconnecting = true; //handleTransportDisconnected(""); diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java index d72987a88..42bbc29a4 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/MultiplexUsbTransport.java @@ -36,10 +36,10 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.ParcelFileDescriptor; -import android.util.Log; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.util.DebugTool; import java.io.FileDescriptor; import java.io.FileInputStream; @@ -68,7 +68,7 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{ MultiplexUsbTransport(ParcelFileDescriptor parcelFileDescriptor, Handler handler, Bundle bundle){ super(handler, TransportType.USB); if(parcelFileDescriptor == null){ - Log.e(TAG, "Error with object"); + DebugTool.logError(TAG, "Error with object"); this.parcelFileDescriptor = null; throw new ExceptionInInitializerError("ParcelFileDescriptor can't be null"); }else{ @@ -101,7 +101,7 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{ setState(STATE_CONNECTING); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); if(fileDescriptor == null || !fileDescriptor.valid()){ - Log.e(TAG, "USB FD was null or not valid,"); + DebugTool.logError(TAG, "USB FD was null or not valid,"); setState(STATE_NONE); return; } @@ -228,15 +228,15 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{ bytesRead = inputStream.read(buffer); if (bytesRead == -1) { if (isInterrupted()) { - Log.e(TAG,"EOF reached, and thread is interrupted"); + DebugTool.logError(TAG,"EOF reached, and thread is interrupted"); } else { - Log.i(TAG,"EOF reached, disconnecting!"); + DebugTool.logInfo(TAG,"EOF reached, disconnecting!"); connectionLost(); } return; } if (isInterrupted()) { - Log.w(TAG,"Read some data, but thread is interrupted"); + DebugTool.logWarning(TAG,"Read some data, but thread is interrupted"); return; } if(connectionSuccessful != null && connectionSuccessful == false){ @@ -268,9 +268,9 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{ } } catch (IOException e) { if (isInterrupted()) { - Log.w(TAG,"Can't read data, and thread is interrupted"); + DebugTool.logWarning(TAG,"Can't read data, and thread is interrupted"); } else { - Log.w(TAG,"Can't read data, disconnecting!"); + DebugTool.logWarning(TAG,"Can't read data, disconnecting!"); connectionLost(); } return; @@ -319,7 +319,7 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{ public void write(byte[] buffer, int offset, int count) { try { if(buffer==null){ - Log.w(TAG, "Can't write to device, nothing to send"); + DebugTool.logWarning(TAG, "Can't write to device, nothing to send"); return; } //This would be a good spot to log out all bytes received @@ -331,7 +331,7 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{ } catch (IOException|NullPointerException e) { // STRICTLY to catch mmOutStream NPE // Exception during write //OMG! WE MUST NOT BE CONNECTED ANYMORE! LET THE USER KNOW - Log.e(TAG, "Error sending bytes to connected device!"); + DebugTool.logError(TAG, "Error sending bytes to connected device!"); connectionLost(); } } @@ -345,7 +345,7 @@ public class MultiplexUsbTransport extends MultiplexBaseTransport{ } } catch (IOException e) { // close() of connect socket failed - Log.d(TAG, "Write Thread: " + e.getMessage()); + DebugTool.logInfo(TAG, "Write Thread: " + e.getMessage()); } } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java index 227b0b894..a9aca1ff4 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/RouterServiceValidator.java @@ -48,7 +48,6 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; -import android.util.Log; import com.smartdevicelink.util.AndroidTools; import com.smartdevicelink.util.DebugTool; @@ -172,11 +171,11 @@ public class RouterServiceValidator { String packageName = null; if(this.service != null){ - Log.d(TAG, "Supplied service name of " + this.service.getClassName()); + DebugTool.logInfo(TAG, "Supplied service name of " + this.service.getClassName()); if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O && !isServiceRunning(context,this.service)){ //This means our service isn't actually running, so set to null. Hopefully we can find a real router service after this. service = null; - Log.w(TAG, "Supplied service is not actually running."); + DebugTool.logWarning(TAG, "Supplied service is not actually running."); } else { // If the running router service is created by this app, the validation is good by default if (this.service.getPackageName().equals(context.getPackageName())) { @@ -227,11 +226,11 @@ public class RouterServiceValidator { //Grab the package for the currently running router service. We need this call regardless of if we are in debug mode or not. if(this.service != null){ - DebugTool.logInfo("Supplied service name of " + this.service.getClassName()); + DebugTool.logInfo(TAG, "Supplied service name of " + this.service.getClassName()); if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O && !isServiceRunning(context,this.service)){ //This means our service isn't actually running, so set to null. Hopefully we can find a real router service after this. service = null; - DebugTool.logWarning("Supplied service is not actually running."); + DebugTool.logWarning(TAG, "Supplied service is not actually running."); } else { // If the running router service is created by this app, the validation is good by default if (this.service.getPackageName().equals(context.getPackageName()) && callback != null) { @@ -242,17 +241,17 @@ public class RouterServiceValidator { } if(this.service == null){ - DebugTool.logInfo("about finding the best Router by using retrieveBestRouterServiceName"); + DebugTool.logInfo(TAG, "about finding the best Router by using retrieveBestRouterServiceName"); new FindRouterTask(new FindConnectedRouterCallback() { @Override public void onFound(ComponentName component) { - DebugTool.logInfo("FindConnectedRouterCallback.onFound got called. Package=" + component); + DebugTool.logInfo(TAG, "FindConnectedRouterCallback.onFound got called. Package=" + component); checkTrustedRouter(callback, pm, component); } @Override public void onFailed() { - DebugTool.logInfo("FindConnectedRouterCallback.onFailed was called"); + DebugTool.logInfo(TAG, "FindConnectedRouterCallback.onFailed was called"); if (callback != null) { callback.onFinishedValidation(false, null); } @@ -342,17 +341,17 @@ public class RouterServiceValidator { public void run() { _counter.incrementAndGet(); if (connected) { - DebugTool.logInfo("We found the connected service (" + service + "); currentThread is " + Thread.currentThread().getName()); + DebugTool.logInfo(TAG, "We found the connected service (" + service + "); currentThread is " + Thread.currentThread().getName()); serviceQueue.add(service); } else if (_counter.get() == numServices) { - DebugTool.logInfo("SdlRouterStatusProvider returns service=" + service + "; connected=" + connected); + DebugTool.logInfo(TAG, "SdlRouterStatusProvider returns service=" + service + "; connected=" + connected); _currentThread.interrupt(); } } }); } }); - DebugTool.logInfo("about checkIsConnected; thread=" + Thread.currentThread().getName()); + DebugTool.logInfo(TAG, "about checkIsConnected; thread=" + Thread.currentThread().getName()); provider.checkIsConnected(); } } @@ -362,14 +361,14 @@ public class RouterServiceValidator { ComponentName found = serviceQueue.poll(TIMEOUT_MSEC, TimeUnit.MILLISECONDS); return found; } catch(InterruptedException e) { - DebugTool.logInfo("FindRouterTask was interrupted because connected Router cannot be found"); + DebugTool.logInfo(TAG,"FindRouterTask was interrupted because connected Router cannot be found"); } return null; } @Override protected void onPostExecute(ComponentName componentName) { - DebugTool.logInfo("onPostExecute componentName=" + componentName); + DebugTool.logInfo(TAG,"onPostExecute componentName=" + componentName); super.onPostExecute(componentName); if (mCallback != null) { if (componentName != null && componentName.getPackageName() != null && componentName.getPackageName().length() != 0) { @@ -622,7 +621,7 @@ public class RouterServiceValidator { return apps; }else{ - Log.i(TAG, "No SDL apps, list was null"); + DebugTool.logInfo(TAG, "No SDL apps, list was null"); return null; } } @@ -635,7 +634,7 @@ public class RouterServiceValidator { public static boolean createTrustedListRequest(final Context context, boolean forceRefresh){ return createTrustedListRequest(context,forceRefresh,null,null); } - public static boolean createTrustedListRequest(final Context context, boolean forceRefresh, TrustedListCallback listCallback){Log.d(TAG,"Checking to make sure we have a list"); + public static boolean createTrustedListRequest(final Context context, boolean forceRefresh, TrustedListCallback listCallback){DebugTool.logInfo(TAG,"Checking to make sure we have a list"); return createTrustedListRequest(context,forceRefresh,null,listCallback); } @@ -691,7 +690,7 @@ public class RouterServiceValidator { } return false; }else{ - Log.d(TAG, "Sdl apps have changed. Need to request new trusted router service list."); + DebugTool.logInfo(TAG, "Sdl apps have changed. Need to request new trusted router service list."); } } @@ -710,7 +709,7 @@ public class RouterServiceValidator { @Override public void httpFailure(int statusCode) { - Log.e(TAG, "Error while requesting trusted app list: " + DebugTool.logError(TAG, "Error while requesting trusted app list: " + statusCode); pendingListRefresh = false; if(listCallback!=null){listCallback.onListObtained(false);} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java index ba1cc80a0..dff9efb0d 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlBroadcastReceiver.java @@ -48,11 +48,11 @@ import android.os.Build; import android.os.Looper; import android.os.Parcelable; import android.util.AndroidRuntimeException; -import android.util.Log; import com.smartdevicelink.R; import com.smartdevicelink.transport.RouterServiceValidator.TrustedListCallback; import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.transport.utl.SdlDeviceListener; import com.smartdevicelink.util.AndroidTools; import com.smartdevicelink.util.DebugTool; import com.smartdevicelink.util.SdlAppInfo; @@ -85,6 +85,8 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ private static final Object QUEUED_SERVICE_LOCK = new Object(); private static ComponentName queuedService = null; private static Thread.UncaughtExceptionHandler foregroundExceptionHandler = null; + private static final Object DEVICE_LISTENER_LOCK = new Object(); + private static SdlDeviceListener sdlDeviceListener; public int getRouterServiceVersion(){ return SdlRouterService.ROUTER_SERVICE_VERSION_NUMBER; @@ -116,7 +118,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ } if(action.equalsIgnoreCase(USBTransport.ACTION_USB_ACCESSORY_ATTACHED)){ - Log.d(TAG, "Usb connected"); + DebugTool.logInfo(TAG,"Usb connected"); intent.setAction(null); onSdlEnabled(context, intent); return; @@ -143,23 +145,23 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ } } if (!serviceFilterHasAction){ - Log.e(TAG, "WARNING: This application has not specified its intent-filter for the SdlRouterService. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); + DebugTool.logError(TAG, "WARNING: This application has not specified its intent-filter for the SdlRouterService. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); } // Check if the service declaration in AndroidManifest has the router service version metadata specified correctly ResolveInfo info = context.getPackageManager().resolveService(new Intent(context, localRouterClass), PackageManager.GET_META_DATA); if (info != null) { if (info.serviceInfo.metaData == null || !info.serviceInfo.metaData.containsKey(context.getString(R.string.sdl_router_service_version_name))) { - Log.e(TAG, "WARNING: This application has not specified its metadata tags for the SdlRouterService. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); + DebugTool.logError(TAG, "WARNING: This application has not specified its metadata tags for the SdlRouterService. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); } } else { - Log.e(TAG, "WARNING: This application has not specified its SdlRouterService correctly in the manifest. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); + DebugTool.logError(TAG, "WARNING: This application has not specified its SdlRouterService correctly in the manifest. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); } } } if(localRouterClass != null && localRouterClass.getName().equalsIgnoreCase(com.smartdevicelink.transport.SdlRouterService.class.getName())){ - Log.e(TAG, "You cannot use the default SdlRouterService class, it must be extended in your project. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); + DebugTool.logError(TAG, "You cannot use the default SdlRouterService class, it must be extended in your project. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); } //This will only be true if we are being told to reopen our SDL service because SDL is enabled @@ -189,10 +191,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ }); } - - }else{ - //This was previously not hooked up, so let's leave it commented out - //onSdlDisabled(context); + } return; }else if(intent.getBooleanExtra(TransportConstants.PING_ROUTER_SERVICE_EXTRA, false)){ @@ -204,10 +203,10 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ } - Log.d(TAG, "Check for local router"); + DebugTool.logInfo(TAG, "Check for local router"); if(localRouterClass!=null){ //If there is a supplied router service lets run some logic regarding starting one - if(!didStart){Log.d(TAG, "attempting to wake up router service"); + if(!didStart){DebugTool.logInfo(TAG, "attempting to wake up router service"); didStart = wakeUpRouterService(context, true,false, device); } @@ -223,8 +222,57 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ } } + /** + * This method will attempt to start the router service. + * @param context to be used to start the service and send broadcasts + * @param componentName the router service that should be started + * @param altTransportWake if the alt transport flag should be set. Only used in debug + * @param device the connected bluetooth device + */ + private static void startRouterService(Context context, ComponentName componentName, boolean altTransportWake, BluetoothDevice device, boolean confirmedDevice) { + if (componentName == null) { + return; + } + + Intent serviceIntent = new Intent(); + serviceIntent.setComponent(componentName); + + if (altTransportWake) { + serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT); + } + + if (device != null) { + serviceIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + } + + if (confirmedDevice) { + serviceIntent.putExtra(TransportConstants.CONFIRMED_SDL_DEVICE, confirmedDevice); + } + + try { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + context.startService(serviceIntent); + } else { + serviceIntent.putExtra(FOREGROUND_EXTRA, true); + DebugTool.logInfo("Attempting to startForegroundService - " + System.currentTimeMillis()); + setForegroundExceptionHandler(); //Prevent ANR in case the OS takes too long to start the service + context.startForegroundService(serviceIntent); + + } + //Make sure to send this out for old apps to close down + SdlRouterService.LocalRouterService self = SdlRouterService.getLocalRouterService(serviceIntent, serviceIntent.getComponent()); + Intent restart = new Intent(SdlRouterService.REGISTER_NEWER_SERVER_INSTANCE_ACTION); + restart.putExtra(LOCAL_ROUTER_SERVICE_EXTRA, self); + restart.putExtra(LOCAL_ROUTER_SERVICE_DID_START_OWN, true); + context.sendBroadcast(restart); + + } catch (SecurityException e) { + DebugTool.logError(TAG, "Security exception, process is bad"); + } + } + private boolean wakeUpRouterService(final Context context, final boolean ping, final boolean altTransportWake, final BluetoothDevice device){ - new ServiceFinder(context, context.getPackageName(), new ServiceFinder.ServiceFinderCallback() { + new ServiceFinder(context, context.getPackageName(), new ServiceFinder.ServiceFinderCallback() { @Override public void onComplete(Vector<ComponentName> routerServices) { runningBluetoothServicePackage = new Vector<ComponentName>(); @@ -232,43 +280,43 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ if (runningBluetoothServicePackage.isEmpty()) { //If there isn't a service running we should try to start one //We will try to sort the SDL enabled apps and find the one that's been installed the longest - Intent serviceIntent; - List<SdlAppInfo> sdlAppInfoList = AndroidTools.querySdlAppInfo(context, new SdlAppInfo.BestRouterComparator()); + final List<SdlAppInfo> sdlAppInfoList = AndroidTools.querySdlAppInfo(context, new SdlAppInfo.BestRouterComparator()); + synchronized (DEVICE_LISTENER_LOCK) { + final boolean sdlDeviceListenerEnabled = SdlDeviceListener.isFeatureSupported(sdlAppInfoList); + if (sdlDeviceListenerEnabled) { + String myPackage = context.getPackageName(); + String routerServicePackage = null; + if (sdlAppInfoList != null && !sdlAppInfoList.isEmpty() && sdlAppInfoList.get(0).getRouterServiceComponentName() != null) { + routerServicePackage = sdlAppInfoList.get(0).getRouterServiceComponentName().getPackageName(); + } + DebugTool.logInfo(TAG, ": This app's package: " + myPackage); + DebugTool.logInfo(TAG, ": Router service app's package: " + routerServicePackage); + if (myPackage != null && myPackage.equalsIgnoreCase(routerServicePackage)) { + SdlDeviceListener sdlDeviceListener = getSdlDeviceListener(context, device); + if (!sdlDeviceListener.isRunning()) { + sdlDeviceListener.start(); + } + } else { + DebugTool.logInfo(TAG, ": Not the app to start the router service nor device listener"); + } + return; + } + } + if (sdlAppInfoList != null && !sdlAppInfoList.isEmpty()) { - serviceIntent = new Intent(); - serviceIntent.setComponent(sdlAppInfoList.get(0).getRouterServiceComponentName()); + startRouterService(context, sdlAppInfoList.get(0).getRouterServiceComponentName(), altTransportWake, device, false); } else{ - Log.d(TAG, "No SDL Router Services found"); - Log.d(TAG, "WARNING: This application has not specified its SdlRouterService correctly in the manifest. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); + DebugTool.logInfo(TAG, "No SDL Router Services found"); + DebugTool.logInfo(TAG, "WARNING: This application has not specified its SdlRouterService correctly in the manifest. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!"); return; } - if (altTransportWake) { - serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT); - } - if(device != null){ - serviceIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - } - try { - if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - context.startService(serviceIntent); - }else { - serviceIntent.putExtra(FOREGROUND_EXTRA, true); - DebugTool.logInfo("Attempting to startForegroundService - " + System.currentTimeMillis()); - setForegroundExceptionHandler(); //Prevent ANR in case the OS takes too long to start the service - context.startForegroundService(serviceIntent); + } else { //There are currently running services + if(DebugTool.isDebugEnabled()){ + for(ComponentName service : runningBluetoothServicePackage){ + DebugTool.logInfo("Currently running router service: " + service.getPackageName()); } - //Make sure to send this out for old apps to close down - SdlRouterService.LocalRouterService self = SdlRouterService.getLocalRouterService(serviceIntent, serviceIntent.getComponent()); - Intent restart = new Intent(SdlRouterService.REGISTER_NEWER_SERVER_INSTANCE_ACTION); - restart.putExtra(LOCAL_ROUTER_SERVICE_EXTRA, self); - restart.putExtra(LOCAL_ROUTER_SERVICE_DID_START_OWN, true); - context.sendBroadcast(restart); - - } catch (SecurityException e) { - Log.e(TAG, "Security exception, process is bad"); } - } else { if (altTransportWake) { wakeRouterServiceAltTransport(context); return; @@ -281,7 +329,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ } } }); - return true; + return true; } private void wakeRouterServiceAltTransport(Context context){ @@ -289,7 +337,11 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ serviceIntent.setAction(TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT); for (ComponentName compName : runningBluetoothServicePackage) { serviceIntent.setComponent(compName); - context.startService(serviceIntent); + try{ + context.startService(serviceIntent); + } catch (Exception e){ + DebugTool.logError(TAG, "Can't start router service for alt transport"); + } } } @@ -314,7 +366,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ && "android.app.RemoteServiceException".equals(e.getClass().getName()) //android.app.RemoteServiceException is a private class && e.getMessage().contains("SdlRouterService")) { - Log.i(TAG, "Handling failed startForegroundService call"); + DebugTool.logInfo(TAG, "Handling failed startForegroundService call"); Looper.loop(); } else if (defaultUncaughtExceptionHandler != null) { //No other exception should be handled defaultUncaughtExceptionHandler.uncaughtException(t, e); @@ -329,12 +381,11 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ * Determines if an instance of the Router Service is currently running on the device.<p> * <b>Note:</b> This method no longer works on Android Oreo or newer * @param context A context to access Android system services through. - * @param pingService Set this to true if you want to make sure the service is up and listening to bluetooth * @return True if a SDL Router Service is currently running, false otherwise. */ - private static boolean isRouterServiceRunning(Context context, boolean pingService){ + private static boolean isRouterServiceRunning(Context context){ if(context == null){ - Log.e(TAG, "Can't look for router service, context supplied was null"); + DebugTool.logError(TAG, "Can't look for router service, context supplied was null"); return false; } if (runningBluetoothServicePackage == null) { @@ -348,7 +399,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ try { runningServices = manager.getRunningServices(Integer.MAX_VALUE); } catch (NullPointerException e) { - Log.e(TAG, "Can't get list of running services"); + DebugTool.logError(TAG, "Can't get list of running services"); return false; } for (RunningServiceInfo service : runningServices) { @@ -356,9 +407,6 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ //Log.d(TAG, "Found Service: "+ service.service.getClassName()); if ((service.service.getClassName()).toLowerCase(Locale.US).contains(SDL_ROUTER_SERVICE_CLASS_NAME) && AndroidTools.isServiceExported(context, service.service)) { runningBluetoothServicePackage.add(service.service); //Store which instance is running - if (pingService) { - pingRouterService(context, service.service.getPackageName(), service.service.getClassName()); - } } } return runningBluetoothServicePackage.size() > 0; @@ -366,7 +414,8 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ } /** - * Attempts to ping a running router service + * Attempts to ping a running router service. It does call startForegroundService so it is + * important to only call this as a ping if the service is already started. * @param context A context to access Android system services through. * @param packageName Package name for service to ping * @param className Class name for service to ping @@ -381,14 +430,14 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ intent.putExtra(TransportConstants.PING_ROUTER_SERVICE_EXTRA, true); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ intent.putExtra(FOREGROUND_EXTRA, true); - DebugTool.logInfo("Attempting to startForegroundService - " + System.currentTimeMillis()); + DebugTool.logInfo(TAG, "Attempting to startForegroundService - " + System.currentTimeMillis()); setForegroundExceptionHandler(); //Prevent ANR in case the OS takes too long to start the service context.startForegroundService(intent); }else { context.startService(intent); } }catch(SecurityException e){ - Log.e(TAG, "Security exception, process is bad"); + DebugTool.logError(TAG, "Security exception, process is bad"); // This service could not be started } } @@ -431,7 +480,7 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ } return; } - if((!lookForServices || isRouterServiceRunning(context,false)) && !runningBluetoothServicePackage.isEmpty()){ //So there is a service up, let's see if it's connected + if((!lookForServices || isRouterServiceRunning(context)) && !runningBluetoothServicePackage.isEmpty()){ //So there is a service up, let's see if it's connected final ConcurrentLinkedQueue<ComponentName> list = new ConcurrentLinkedQueue<ComponentName>(runningBluetoothServicePackage); final SdlRouterStatusProvider.ConnectedStatusCallback sdlBrCallback = new SdlRouterStatusProvider.ConnectedStatusCallback() { @@ -443,9 +492,9 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ provider.checkIsConnected(); }else{ if(service!=null){ - Log.d(TAG, service.getPackageName() + " is connected = " + connected); + DebugTool.logInfo(TAG, service.getPackageName() + " is connected = " + connected); }else{ - Log.d(TAG,"No service is connected/running"); + DebugTool.logInfo(TAG, "No service is connected/running"); } if(callback!=null){ callback.onConnectionStatusUpdate(connected, service,context); @@ -469,14 +518,15 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ }); }else{ - Log.w(TAG, "Router service isn't running, returning false."); + DebugTool.logWarning(TAG, "Router service isn't running, returning false."); if(isBluetoothConnected()){ - Log.d(TAG, "Bluetooth is connected. Attempting to start Router Service"); + DebugTool.logInfo(TAG, "Bluetooth is connected. Attempting to ping Router Service"); Intent serviceIntent = new Intent(); serviceIntent.setAction(TransportConstants.START_ROUTER_SERVICE_ACTION); serviceIntent.putExtra(TransportConstants.PING_ROUTER_SERVICE_EXTRA, true); - AndroidTools.sendExplicitBroadcast(context,serviceIntent,null); + AndroidTools.sendExplicitBroadcast(context, serviceIntent,null); } + if(callback!=null){ callback.onConnectionStatusUpdate(false, null,context); } @@ -500,6 +550,49 @@ public abstract class SdlBroadcastReceiver extends BroadcastReceiver{ return false; } + + private static SdlDeviceListener getSdlDeviceListener(Context context, BluetoothDevice bluetoothDevice){ + + synchronized (DEVICE_LISTENER_LOCK){ + if (sdlDeviceListener == null){ + sdlDeviceListener = new SdlDeviceListener(context, bluetoothDevice, new SdlDeviceListener.Callback() { + @Override + public boolean onTransportConnected(Context context, BluetoothDevice bluetoothDevice) { + + synchronized (DEVICE_LISTENER_LOCK){ + sdlDeviceListener = null; + if(context != null) { + final List<SdlAppInfo> sdlAppInfoList = AndroidTools.querySdlAppInfo(context, new SdlAppInfo.BestRouterComparator()); + if(sdlAppInfoList != null && !sdlAppInfoList.isEmpty()) { + ComponentName routerService = sdlAppInfoList.get(0).getRouterServiceComponentName(); + startRouterService(context, routerService, false, bluetoothDevice, true); + } + } + } + + return false; + } + + @Override + public void onTransportDisconnected(BluetoothDevice bluetoothDevice) { + synchronized (DEVICE_LISTENER_LOCK){ + sdlDeviceListener = null; + } + } + + @Override + public void onTransportError(BluetoothDevice bluetoothDevice) { + synchronized (DEVICE_LISTENER_LOCK){ + sdlDeviceListener = null; + } + } + }); + } + } + + return sdlDeviceListener; + } + public static ComponentName consumeQueuedRouterService(){ synchronized(QUEUED_SERVICE_LOCK){ ComponentName retVal = queuedService; diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java index 77fecccad..5168bf50b 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java @@ -73,7 +73,6 @@ import android.os.RemoteException; import android.support.annotation.NonNull; import android.support.v4.app.NotificationCompat; import android.util.AndroidRuntimeException; -import android.util.Log; import android.util.SparseArray; import android.util.SparseIntArray; @@ -140,7 +139,7 @@ public class SdlRouterService extends Service{ /** * <b> NOTE: DO NOT MODIFY THIS UNLESS YOU KNOW WHAT YOU'RE DOING.</b> */ - protected static final int ROUTER_SERVICE_VERSION_NUMBER = 12; + protected static final int ROUTER_SERVICE_VERSION_NUMBER = 13; private static final String ROUTER_SERVICE_PROCESS = "com.smartdevicelink.router"; @@ -212,7 +211,7 @@ public class SdlRouterService extends Service{ private SparseIntArray sessionHashIdMap; private SparseIntArray cleanedSessionMap; private final Object SESSION_LOCK = new Object(), REGISTERED_APPS_LOCK = new Object(), - PING_COUNT_LOCK = new Object(), NOTIFICATION_LOCK = new Object(); + PING_COUNT_LOCK = new Object(), FOREGROUND_NOTIFICATION_LOCK = new Object(); private static Messenger altTransportService = null; @@ -276,16 +275,16 @@ public class SdlRouterService extends Service{ if(startSequenceComplete && !connectAsClient && (bluetoothTransport ==null || bluetoothTransport.getState() == MultiplexBluetoothTransport.STATE_NONE)){ - Log.e(TAG, "Serial service not initialized while registering app"); + DebugTool.logError(TAG, "Serial service not initialized while registering app"); //Maybe we should try to do a connect here instead - Log.d(TAG, "Serial service being restarted"); + DebugTool.logInfo(TAG, "Serial service being restarted"); initBluetoothSerialService(); } } - Log.i(TAG, app.appId + " has just been registered with SDL Router Service"); + DebugTool.logInfo(TAG, app.appId + " has just been registered with SDL Router Service"); } /** @@ -300,9 +299,9 @@ public class SdlRouterService extends Service{ { String action = intent.getAction(); if(action == null){ - Log.d(TAG, "Disconnect received with no action."); + DebugTool.logInfo(TAG, "Disconnect received with no action."); }else { - Log.d(TAG, "Disconnect received. Action: " + intent.getAction()); + DebugTool.logInfo(TAG, "Disconnect received. Action: " + intent.getAction()); if(action.equalsIgnoreCase(BluetoothAdapter.ACTION_STATE_CHANGED)){ int bluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); @@ -313,7 +312,7 @@ public class SdlRouterService extends Service{ return; case BluetoothAdapter.STATE_TURNING_OFF: case BluetoothAdapter.STATE_OFF: - Log.d(TAG, "Bluetooth is shutting off, SDL Router Service is closing."); + DebugTool.logInfo(TAG, "Bluetooth is shutting off, SDL Router Service is closing."); connectAsClient = false; if(!shouldServiceRemainOpen(intent)){ closeSelf(); @@ -326,7 +325,7 @@ public class SdlRouterService extends Service{ //Otherwise connectAsClient = false; if (legacyModeEnabled) { - Log.d(TAG, "Legacy mode enabled and bluetooth d/c'ed, restarting router service bluetooth."); + DebugTool.logInfo(TAG, "Legacy mode enabled and bluetooth d/c'ed, restarting router service bluetooth."); enableLegacyMode(false); onTransportDisconnected(new TransportRecord(TransportType.BLUETOOTH,null)); initBluetoothSerialService(); @@ -377,7 +376,7 @@ public class SdlRouterService extends Service{ BluetoothDevice device = receivedBundle.getParcelable(BluetoothDevice.EXTRA_DEVICE); connectAsClient = true; if(device==null || !service.bluetoothConnect(device)){ - Log.e(TAG, "Unable to connect to bluetooth device"); + DebugTool.logError(TAG, "Unable to connect to bluetooth device"); connectAsClient = false; } } @@ -392,7 +391,7 @@ public class SdlRouterService extends Service{ appId = "" + receivedBundle.getLong(TransportConstants.APP_ID_EXTRA, -1); } if(appId.length()<=0 || msg.replyTo == null){ - Log.w(TAG, "Unable to register app as no id or messenger was included"); + DebugTool.logWarning(TAG, "Unable to register app as no id or messenger was included"); if(msg.replyTo!=null){ message.arg1 = TransportConstants.REGISTRATION_RESPONSE_DENIED_APP_ID_NOT_INCLUDED; try { @@ -404,7 +403,7 @@ public class SdlRouterService extends Service{ break; } if(service.legacyModeEnabled){ - Log.w(TAG, "Unable to register app as legacy mode is enabled"); + DebugTool.logWarning(TAG, "Unable to register app as legacy mode is enabled"); if(msg.replyTo!=null){ message.arg1 = TransportConstants.REGISTRATION_RESPONSE_DENIED_LEGACY_MODE_ENABLED; try { @@ -423,7 +422,7 @@ public class SdlRouterService extends Service{ synchronized(service.REGISTERED_APPS_LOCK){ RegisteredApp old = registeredApps.put(app.getAppId(), app); if(old!=null){ - Log.w(TAG, "Replacing already existing app with this app id"); + DebugTool.logWarning(TAG, "Replacing already existing app with this app id"); service.removeAllSessionsForApp(old, true); old.close(); } @@ -460,7 +459,7 @@ public class SdlRouterService extends Service{ if(appIdToUnregister == null){ appIdToUnregister = "" + receivedBundle.getLong(TransportConstants.APP_ID_EXTRA, -1); } - Log.i(TAG, "Unregistering client: " + appIdToUnregister); + DebugTool.logInfo(TAG, "Unregistering client: " + appIdToUnregister); RegisteredApp unregisteredApp; synchronized(service.REGISTERED_APPS_LOCK){ unregisteredApp = registeredApps.remove(appIdToUnregister); @@ -474,14 +473,14 @@ public class SdlRouterService extends Service{ response.arg1 = TransportConstants.UNREGISTRATION_RESPONSE_SUCESS; service.removeAllSessionsForApp(unregisteredApp,false); } - Log.i(TAG, "Unregistering client response: " + response.arg1 ); + DebugTool.logInfo(TAG, "Unregistering client response: " + response.arg1 ); try { msg.replyTo.send(response); //We do this because we aren't guaranteed to find the correct registeredApp to send the message through } catch (RemoteException e) { e.printStackTrace(); }catch(NullPointerException e2){ - Log.e(TAG, "No reply address included, can't send a reply"); + DebugTool.logError(TAG, "No reply address included, can't send a reply"); } break; @@ -521,7 +520,7 @@ public class SdlRouterService extends Service{ // This means no transport is connected. Likely the // router service has already disconnected and this // is now just executing. - DebugTool.logError("Can't send packet, no transport specified and none are connected."); + DebugTool.logError(TAG, "Can't send packet, no transport specified and none are connected."); return; } //Log.d(TAG, "Transport type was null, so router set it to " + transportType.name()); @@ -587,7 +586,7 @@ public class SdlRouterService extends Service{ } catch (RemoteException e) { e.printStackTrace(); }catch(NullPointerException e2){ - Log.e(TAG, "No reply address included, can't send a reply"); + DebugTool.logError(TAG, "No reply address included, can't send a reply"); } break; case TransportConstants.ROUTER_REMOVE_SESSION: @@ -628,7 +627,7 @@ public class SdlRouterService extends Service{ } catch (RemoteException e) { e.printStackTrace(); }catch(NullPointerException e2){ - Log.e(TAG, "No reply address included, can't send a reply"); + DebugTool.logError(TAG, "No reply address included, can't send a reply"); } break; case TransportConstants.ROUTER_REQUEST_SECONDARY_TRANSPORT_CONNECTION: @@ -721,7 +720,7 @@ public class SdlRouterService extends Service{ Message retMsg = Message.obtain(); retMsg.what = TransportConstants.ROUTER_REGISTER_ALT_TRANSPORT_RESPONSE; if(altTransportService == null){ //Ok no other transport is connected, this is good - Log.d(TAG, "Alt transport connected."); + DebugTool.logInfo(TAG, "Alt transport connected."); if(msg.replyTo == null){ break; } @@ -754,13 +753,13 @@ public class SdlRouterService extends Service{ if(packet!=null){ service.onPacketRead(packet); }else{ - Log.w(TAG, "Received null packet from alt transport service"); + DebugTool.logWarning(TAG, "Received null packet from alt transport service"); } }else{ - Log.w(TAG, "False positive packet reception"); + DebugTool.logWarning(TAG, "False positive packet reception"); } }else{ - Log.e(TAG, "Bundle was null while sending packet to router service from alt transport"); + DebugTool.logError(TAG, "Bundle was null while sending packet to router service from alt transport"); } break; default: @@ -813,7 +812,7 @@ public class SdlRouterService extends Service{ } break; default: - Log.w(TAG, "Unsupported request: " + msg.what); + DebugTool.logWarning(TAG, "Unsupported request: " + msg.what); break; } } @@ -905,7 +904,7 @@ public class SdlRouterService extends Service{ case TransportConstants.ALT_TRANSPORT_CONNECTED: break; default: - Log.w(TAG, "Unsupported request: " + msg.what); + DebugTool.logWarning(TAG, "Unsupported request: " + msg.what); break; } } @@ -920,7 +919,7 @@ public class SdlRouterService extends Service{ //Check intent to send back the correct binder (client binding vs alt transport) if(intent!=null){ if(closing){ - Log.w(TAG, "Denying bind request due to service shutting down."); + DebugTool.logWarning(TAG, "Denying bind request due to service shutting down."); return null; } String requestType = intent.getAction();//intent.getIntExtra(TransportConstants.ROUTER_BIND_REQUEST_TYPE_EXTRA, TransportConstants.BIND_REQUEST_TYPE_CLIENT); @@ -935,7 +934,7 @@ public class SdlRouterService extends Service{ }else if(TransportConstants.BIND_REQUEST_TYPE_USB_PROVIDER.equals(requestType)){ return this.usbTransferMessenger.getBinder(); }else{ - Log.w(TAG, "Unknown bind request type"); + DebugTool.logWarning(TAG, "Unknown bind request type"); } } @@ -946,17 +945,17 @@ public class SdlRouterService extends Service{ @Override public boolean onUnbind(Intent intent) { - Log.d(TAG, "Unbind being called."); + DebugTool.logInfo(TAG, "Unbind being called."); return super.onUnbind(intent); } private void notifyClients(final Message message){ if(message==null){ - Log.w(TAG, "Can't notify clients, message was null"); + DebugTool.logWarning(TAG, "Can't notify clients, message was null"); return; } - Log.d(TAG, "Notifying "+ registeredApps.size()+ " clients"); + DebugTool.logInfo(TAG, "Notifying "+ registeredApps.size()+ " clients"); int result; synchronized(REGISTERED_APPS_LOCK){ Collection<RegisteredApp> apps = registeredApps.values(); @@ -1028,7 +1027,7 @@ public class SdlRouterService extends Service{ @SuppressWarnings("unused") private void pingClients(){ Message message = Message.obtain(); - Log.d(TAG, "Pinging "+ registeredApps.size()+ " clients"); + DebugTool.logInfo(TAG, "Pinging "+ registeredApps.size()+ " clients"); int result; synchronized(REGISTERED_APPS_LOCK){ Collection<RegisteredApp> apps = registeredApps.values(); @@ -1088,16 +1087,16 @@ public class SdlRouterService extends Service{ */ private boolean initCheck(){ if(!processCheck()){ - Log.e(TAG, "Not using correct process. Shutting down"); + DebugTool.logError(TAG, "Not using correct process. Shutting down"); wrongProcess = true; return false; } if(!permissionCheck(Manifest.permission.BLUETOOTH)){ - Log.e(TAG, "Bluetooth Permission is not granted. Shutting down"); + DebugTool.logError(TAG, "Bluetooth Permission is not granted. Shutting down"); return false; } if(!AndroidTools.isServiceExported(this, new ComponentName(this, this.getClass()))){ //We want to check to see if our service is actually exported - Log.e(TAG, "Service isn't exported. Shutting down"); + DebugTool.logError(TAG, "Service isn't exported. Shutting down"); return false; } return true; @@ -1163,7 +1162,7 @@ public class SdlRouterService extends Service{ try{ startForegroundService(serviceIntent); }catch (Exception e){ - Log.e(TAG, "Unable to start next SDL router service. " + e.getMessage()); + DebugTool.logError(TAG, "Unable to start next SDL router service. " + e.getMessage()); } } break; @@ -1171,7 +1170,7 @@ public class SdlRouterService extends Service{ } } } else{ - Log.d(TAG, "No sdl apps found"); + DebugTool.logInfo(TAG, "No sdl apps found"); return; } closing = true; @@ -1259,7 +1258,9 @@ public class SdlRouterService extends Service{ address = device.getAddress(); } } - int timeout = getNotificationTimeout(address); + boolean confirmedDevice = intent.getBooleanExtra(TransportConstants.CONFIRMED_SDL_DEVICE, false); + int timeout = getNotificationTimeout(address, confirmedDevice); + enterForeground("Waiting for connection...", timeout, false); resetForegroundTimeOut(timeout); } else { @@ -1272,7 +1273,7 @@ public class SdlRouterService extends Service{ if(intent.hasExtra(TransportConstants.PING_ROUTER_SERVICE_EXTRA)){ //Make sure we are listening on RFCOMM if(startSequenceComplete){ //We only check if we are sure we are already through the start up process - Log.i(TAG, "Received ping, making sure we are listening to bluetooth rfcomm"); + DebugTool.logInfo(TAG, "Received ping, making sure we are listening to bluetooth rfcomm"); initBluetoothSerialService(); } } @@ -1300,7 +1301,7 @@ public class SdlRouterService extends Service{ altTransportTimerHandler = null; } - Log.w(TAG, "Sdl Router Service Destroyed"); + DebugTool.logWarning(TAG, "Sdl Router Service Destroyed"); closing = true; //No need for this Broadcast Receiver anymore unregisterAllReceivers(); @@ -1383,9 +1384,9 @@ public class SdlRouterService extends Service{ * @return the amount of time for a timeout handler to remove the notification. */ @SuppressLint("MissingPermission") - private int getNotificationTimeout(String address){ + private int getNotificationTimeout(String address, boolean confirmedDevice){ if(address != null){ - if(hasSDLConnected(address)){ + if(confirmedDevice || hasSDLConnected(address)){ return FOREGROUND_TIMEOUT * 2; }else if(this.isFirstStatusCheck(address)) { // If this is the first time the service has ever connected to this device we want @@ -1403,7 +1404,7 @@ public class SdlRouterService extends Service{ if(android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2){ return; } - synchronized (NOTIFICATION_LOCK) { + synchronized (FOREGROUND_NOTIFICATION_LOCK) { if (foregroundTimeoutHandler == null) { foregroundTimeoutHandler = new Handler(); } @@ -1430,7 +1431,7 @@ public class SdlRouterService extends Service{ } public void cancelForegroundTimeOut(){ - synchronized (NOTIFICATION_LOCK) { + synchronized (FOREGROUND_NOTIFICATION_LOCK) { if (foregroundTimeoutHandler != null && foregroundTimeoutRunnable != null) { foregroundTimeoutHandler.removeCallbacks(foregroundTimeoutRunnable); } @@ -1441,9 +1442,9 @@ public class SdlRouterService extends Service{ @SuppressLint("NewApi") @SuppressWarnings("deprecation") private void enterForeground(String content, long chronometerLength, boolean ongoing) { - DebugTool.logInfo("Attempting to enter the foreground - " + System.currentTimeMillis()); + DebugTool.logInfo(TAG, "Attempting to enter the foreground - " + System.currentTimeMillis()); if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB){ - Log.w(TAG, "Unable to start service as foreground due to OS SDK version being lower than 11"); + DebugTool.logWarning(TAG, "Unable to start service as foreground due to OS SDK version being lower than 11"); isForeground = false; return; } @@ -1499,7 +1500,7 @@ public class SdlRouterService extends Service{ builder.setUsesChronometer(true); builder.setChronometerCountDown(true); } - synchronized (NOTIFICATION_LOCK) { + synchronized (FOREGROUND_NOTIFICATION_LOCK) { Notification notification; if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { notification = builder.getNotification(); @@ -1514,7 +1515,7 @@ public class SdlRouterService extends Service{ notificationChannel.enableVibration(false); notificationManager.createNotificationChannel(notificationChannel); } else { - Log.e(TAG, "Unable to retrieve notification Manager service"); + DebugTool.logError(TAG, "Unable to retrieve notification Manager service"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { safeStartForeground(FOREGROUND_SERVICE_ID, builder.build()); stopSelf(); //A valid notification channel must be supplied for SDK 27+ @@ -1556,16 +1557,16 @@ public class SdlRouterService extends Service{ notification = builder.build(); } startForeground(id, notification); - DebugTool.logInfo("Entered the foreground - " + System.currentTimeMillis()); + DebugTool.logInfo(TAG, "Entered the foreground - " + System.currentTimeMillis()); }catch (Exception e){ - DebugTool.logError("Unable to start service in foreground", e); + DebugTool.logError(TAG, "Unable to start service in foreground", e); } } private void exitForeground(){ - synchronized (NOTIFICATION_LOCK) { + synchronized (FOREGROUND_NOTIFICATION_LOCK) { if (isForeground && !isPrimaryTransportConnected()) { //Ensure that the service is in the foreground and no longer connected to a transport - DebugTool.logInfo("SdlRouterService to exit foreground"); + DebugTool.logInfo(TAG, "SdlRouterService to exit foreground"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { this.stopForeground(Service.STOP_FOREGROUND_DETACH); }else{ @@ -1574,12 +1575,12 @@ public class SdlRouterService extends Service{ NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager!= null){ try { - notificationManager.cancelAll(); + notificationManager.cancel(FOREGROUND_SERVICE_ID); if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !getBooleanPref(KEY_AVOID_NOTIFICATION_CHANNEL_DELETE,false)) { notificationManager.deleteNotificationChannel(SDL_NOTIFICATION_CHANNEL_ID); } } catch (Exception e) { - DebugTool.logError("Issue when removing notification and channel", e); + DebugTool.logError(TAG, "Issue when removing notification and channel", e); } } isForeground = false; @@ -1686,24 +1687,24 @@ public class SdlRouterService extends Service{ ArrayList<TransportRecord> connectedTransports = getConnectedTransports(); if(connectedTransports != null && !connectedTransports.isEmpty()){ // stay open if we have any transports connected - Log.d(TAG, "1 or more transports connected, remaining open"); + DebugTool.logInfo(TAG, "1 or more transports connected, remaining open"); return true; }else if(altTransportService!=null || altTransportTimerHandler !=null){ //We have been started by an alt transport, we must remain open. "My life for Auir...." - Log.d(TAG, "Alt Transport connected, remaining open"); + DebugTool.logInfo(TAG, "Alt Transport connected, remaining open"); return true; }else if(intent!=null && TransportConstants.BIND_REQUEST_TYPE_ALT_TRANSPORT.equals(intent.getAction())){ - Log.i(TAG, "Received start intent with alt transport request."); + DebugTool.logInfo(TAG, "Received start intent with alt transport request."); startAltTransportTimer(); return true; }else if(!bluetoothAvailable()){//If bluetooth isn't on...there's nothing to see here //Bluetooth is off, we should shut down - Log.d(TAG, "Bluetooth not available, shutting down service"); + DebugTool.logInfo(TAG, "Bluetooth not available, shutting down service"); return connectedTransports != null && connectedTransports.size() > 0; //If a transport is connected the list will be >0 }else{ - Log.d(TAG, "Service to remain open"); + DebugTool.logInfo(TAG, "Service to remain open"); return true; } } @@ -1729,7 +1730,7 @@ public class SdlRouterService extends Service{ } private synchronized void initBluetoothSerialService(){ if(legacyModeEnabled){ - Log.d(TAG, "Not starting own bluetooth during legacy mode"); + DebugTool.logInfo(TAG, "Not starting own bluetooth during legacy mode"); return; } //init serial service @@ -1740,7 +1741,7 @@ public class SdlRouterService extends Service{ // Only if the state is STATE_NONE, do we know that we haven't started already if (bluetoothTransport.getState() == MultiplexBluetoothTransport.STATE_NONE) { // Start the Bluetooth services - Log.i(TAG, "Starting bluetooth transport"); + DebugTool.logInfo(TAG, "Starting bluetooth transport"); bluetoothTransport.start(); } @@ -1912,7 +1913,7 @@ public class SdlRouterService extends Service{ return; } - Log.e(TAG, "Notifying client service of hardware disconnect."); + DebugTool.logError(TAG, "Notifying client service of hardware disconnect."); //We've notified our clients, less clean up the mess now. @@ -1929,16 +1930,24 @@ public class SdlRouterService extends Service{ @Deprecated public void onTransportError(TransportType transportType){ - onTransportError(new TransportRecord(transportType,null)); - } + onTransportError(new TransportRecord(transportType,null), null); + } + + @Deprecated + public void onTransportError(TransportRecord record) { + onTransportError(record, null); + } - public void onTransportError(TransportRecord transport){ + public void onTransportError(TransportRecord transport, Bundle errorBundle){ switch (transport.getType()){ case BLUETOOTH: if(bluetoothTransport !=null){ bluetoothTransport.setStateManually(MultiplexBluetoothTransport.STATE_NONE); bluetoothTransport = null; } + if (errorBundle != null && errorBundle.getByte(MultiplexBaseTransport.ERROR_REASON_KEY) == MultiplexBaseTransport.REASON_SPP_ERROR) { + notifySppError(); + } break; case USB: break; @@ -2007,9 +2016,9 @@ public class SdlRouterService extends Service{ // We've just lost the connection service.onTransportDisconnected(transportRecord); break; - case MultiplexBaseTransport.STATE_ERROR: - service.onTransportError(transportRecord); - break; + case MultiplexBaseTransport.STATE_ERROR: + service.onTransportError(transportRecord, msg.getData()); + break; } break; @@ -2027,7 +2036,7 @@ public class SdlRouterService extends Service{ } byte[] packet = bundle.getByteArray(TransportConstants.BYTES_TO_SEND_EXTRA_NAME); if(packet==null) { - Log.w(TAG, "Ignoring null packet"); + DebugTool.logWarning(TAG, "Ignoring null packet"); return false; } int offset = bundle.getInt(TransportConstants.BYTES_TO_SEND_EXTRA_OFFSET, 0); //If nothing, start at the beginning of the array @@ -2056,7 +2065,7 @@ public class SdlRouterService extends Service{ } } } - Log.e(TAG, "Can't send data, no transport of specified type connected"); + DebugTool.logError(TAG, "Can't send data, no transport of specified type connected"); return false; } @@ -2097,12 +2106,12 @@ public class SdlRouterService extends Service{ try { altTransportService.send(msg); } catch (RemoteException e) { - Log.e(TAG, "Unable to send through alt transport!"); + DebugTool.logError(TAG, "Unable to send through alt transport!"); e.printStackTrace(); } return true; }else{ - Log.w(TAG, "Unable to send packet through alt transport, it was null"); + DebugTool.logWarning(TAG, "Unable to send packet through alt transport, it was null"); } return false; } @@ -2124,12 +2133,12 @@ public class SdlRouterService extends Service{ try { altTransportService.send(msg); } catch (RemoteException e) { - Log.e(TAG, "Unable to send through alt transport!"); + DebugTool.logError(TAG, "Unable to send through alt transport!"); e.printStackTrace(); } return true; }else{ - Log.w(TAG, "Unable to send packet through alt transport, it was null"); + DebugTool.logWarning(TAG, "Unable to send packet through alt transport, it was null"); } return false; } @@ -2163,7 +2172,7 @@ public class SdlRouterService extends Service{ } if(app == null){ - Log.e(TAG, "No app found for app id " + appid + " Removing session mapping and sending unregisterAI to head unit."); + DebugTool.logError(TAG, "No app found for app id " + appid + " Removing session mapping and sending unregisterAI to head unit."); //We have no app to match the app id tied to this session removeSessionFromMap(session, Collections.singletonList(packet.getTransportRecord().getType())); @@ -2187,7 +2196,7 @@ public class SdlRouterService extends Service{ byte[] stopService = SdlPacketFactory.createEndSession(SessionType.RPC, (byte)session, 0, (byte)packet.getVersion(), hashId).constructPacket(); manuallyWriteBytes(packet.getTransportRecord().getType(), stopService,0,stopService.length); }else{ - Log.w(TAG, "No where to send a packet from what appears to be a non primary transport"); + DebugTool.logWarning(TAG, "No where to send a packet from what appears to be a non primary transport"); } return false; @@ -2204,7 +2213,7 @@ public class SdlRouterService extends Service{ this.sessionHashIdMap.put(session, hashId); } } else { - Log.w(TAG, "Hash ID not found in V5 start service ACK frame for session " + session); + DebugTool.logWarning(TAG, "Hash ID not found in V5 start service ACK frame for session " + session); } } else { if (packet.getPayload() != null && packet.getDataSize() == 4){ //hashid will be 4 bytes in length @@ -2220,7 +2229,7 @@ public class SdlRouterService extends Service{ if(packet.getFrameType() == FrameType.Single && packet.getServiceType() == SdlPacket.SERVICE_TYPE_RPC) { BinaryFrameHeader binFrameHeader = BinaryFrameHeader.parseBinaryHeader(packet.getPayload()); if (binFrameHeader != null && FunctionID.UNREGISTER_APP_INTERFACE.getId() == binFrameHeader.getFunctionID()) { - Log.d(TAG, "Received an unregister app interface. Checking session hash before sending"); + DebugTool.logInfo(TAG, "Received an unregister app interface. Checking session hash before sending"); // make sure that we don't try to unregister a recently added app that might have a // session ID of a removed app whose UAI was delayed int hashOfRemoved = this.cleanedSessionMap.get(session, -1); @@ -2229,7 +2238,7 @@ public class SdlRouterService extends Service{ // Current session contains key that was held before if (hashOfRemoved != currentHash) { // App assigned same session id but is a different app. Keep this from being killed - Log.d(TAG, "same session id for different apps found, dropping packet"); + DebugTool.logInfo(TAG, "same session id for different apps found, dropping packet"); this.cleanedSessionMap.delete(session); return false; } @@ -2276,14 +2285,14 @@ public class SdlRouterService extends Service{ message.setData(bundle); //Log.d(TAG, "First packet before sending: " + message.getData().toString()); if(!sendPacketMessageToClient(app, message, version)){ - Log.w(TAG, "Error sending first message of split packet to client " + app.appId); + DebugTool.logWarning(TAG, "Error sending first message of split packet to client " + app.appId); return false; } //Log.w(TAG, "Message too big for single IPC transaction. Breaking apart. Size - " + packet.getDataSize()); ByteArrayMessageSpliter splitter = new ByteArrayMessageSpliter(appid,TransportConstants.ROUTER_RECEIVED_PACKET,bytes,0); while(splitter.isActive()){ if(!sendPacketMessageToClient(app,splitter.nextMessage(),version)){ - Log.w(TAG, "Error sending first message of split packet to client " + app.appId); + DebugTool.logWarning(TAG, "Error sending first message of split packet to client " + app.appId); splitter.close(); return false; } @@ -2292,24 +2301,24 @@ public class SdlRouterService extends Service{ } }else{ //If we can't find a session for this packet we just drop the packet - Log.e(TAG, "App Id was NULL for session! " + session); + DebugTool.logError(TAG, "App Id was NULL for session! " + session); TransportType transportType = packet.getTransportRecord().getType(); if(removeSessionFromMap(session, Collections.singletonList(transportType))){ //If we found the session id still tied to an app in our map we need to remove it and send the proper shutdown sequence. - Log.i(TAG, "Removed session from map. Sending unregister request to module."); + DebugTool.logInfo(TAG, "Removed session from map. Sending unregister request to module."); attemptToCleanUpModule(session, packet.getVersion(), transportType); }else{ //There was no mapping so let's try to resolve this if(packet.getFrameType() == FrameType.Single && packet.getServiceType() == SdlPacket.SERVICE_TYPE_RPC){ BinaryFrameHeader binFrameHeader = BinaryFrameHeader.parseBinaryHeader(packet.getPayload()); if(binFrameHeader!=null && FunctionID.UNREGISTER_APP_INTERFACE.getId() == binFrameHeader.getFunctionID()){ - Log.d(TAG, "Received an unregister app interface with no where to send it, dropping the packet."); + DebugTool.logInfo(TAG, "Received an unregister app interface with no where to send it, dropping the packet."); }else{ attemptToCleanUpModule(session, packet.getVersion(),transportType); } }else if((packet.getFrameType() == FrameType.Control && (packet.getFrameInfo() == SdlPacket.FRAME_INFO_END_SERVICE_ACK || packet.getFrameInfo() == SdlPacket.FRAME_INFO_END_SERVICE_NAK))){ //We want to ignore this - Log.d(TAG, "Received a stop service ack/nak with no where to send it, dropping the packet."); + DebugTool.logInfo(TAG, "Received a stop service ack/nak with no where to send it, dropping the packet."); }else{ attemptToCleanUpModule(session, packet.getVersion(),transportType); } @@ -2326,7 +2335,7 @@ public class SdlRouterService extends Service{ * @param version the last known version that this session was operating with */ private void attemptToCleanUpModule(int session, int version, TransportType primaryTransport){ - Log.i(TAG, "Attempting to stop session " + session); + DebugTool.logInfo(TAG, "Attempting to stop session " + session); byte[] uai = createForceUnregisterApp((byte)session, (byte)version); manuallyWriteBytes(primaryTransport,uai,0,uai.length); int hashId = 0; @@ -2344,7 +2353,7 @@ public class SdlRouterService extends Service{ private boolean sendPacketMessageToClient(RegisteredApp app, Message message, byte version){ int result = app.sendMessage(message); if(result == RegisteredApp.SEND_MESSAGE_ERROR_MESSENGER_DEAD_OBJECT){ - Log.d(TAG, "Dead object, removing app and sessions"); + DebugTool.logInfo(TAG, "Dead object, removing app and sessions"); //Get all their sessions and send out unregister info //Use the version in this packet as a best guess app.close(); @@ -2398,7 +2407,7 @@ public class SdlRouterService extends Service{ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if(adapter != null && adapter.isEnabled()){ Set<BluetoothDevice> pairedBT= adapter.getBondedDevices(); - Log.d(TAG, "Query Bluetooth paired devices"); + DebugTool.logInfo(TAG, "Query Bluetooth paired devices"); if (pairedBT.size() > 0) { for (BluetoothDevice device : pairedBT) { String name = device.getName().toLowerCase(Locale.US); @@ -2409,14 +2418,14 @@ public class SdlRouterService extends Service{ } } }else{ - Log.e(TAG, "There was an issue with connecting as client"); + DebugTool.logError(TAG, "There was an issue with connecting as client"); } return false; } @SuppressWarnings("MissingPermission") private synchronized boolean bluetoothConnect(BluetoothDevice device){ - Log.d(TAG,"Connecting to device: " + device.getName()); + DebugTool.logInfo(TAG,"Connecting to device: " + device.getName()); if(bluetoothTransport == null || !bluetoothTransport.isConnected()) { // Set up the Bluetooth serial object bluetoothTransport = new MultiplexBluetoothTransport(bluetoothHandler); @@ -2429,7 +2438,7 @@ public class SdlRouterService extends Service{ } } - Log.d(TAG, "Bluetooth SPP Connect Attempt Completed"); + DebugTool.logInfo(TAG, "Bluetooth SPP Connect Attempt Completed"); return false; } @@ -2447,7 +2456,7 @@ public class SdlRouterService extends Service{ @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated public static void setBluetoothPrefs (int level, String prefLocation) { - Log.w(TAG, "This method is deprecated and will not take any action"); + DebugTool.logWarning(TAG, "This method is deprecated and will not take any action"); } /** @@ -2502,7 +2511,7 @@ public class SdlRouterService extends Service{ SharedPreferences.Editor editor = preferences.edit(); editor.putBoolean(key,value); editor.commit(); - Log.d(TAG, "Preference set: " + key + " : " + value); + DebugTool.logInfo(TAG, "Preference set: " + key + " : " + value); } /** @@ -2529,10 +2538,10 @@ public class SdlRouterService extends Service{ @Deprecated protected static LocalRouterService getLocalRouterService(Intent launchIntent, ComponentName name){ if(launchIntent == null){ - Log.w(TAG, "Supplied intent was null, local router service will not contain intent"); + DebugTool.logWarning(TAG, "Supplied intent was null, local router service will not contain intent"); } if(name == null){ - Log.e(TAG, "Unable to create local router service object because component name was null"); + DebugTool.logError(TAG, "Unable to create local router service object because component name was null"); return null; } //noinspection deprecation @@ -2731,7 +2740,7 @@ public class SdlRouterService extends Service{ app.registerTransport(sessionId, transportType); sessionMap.put(sessionId,appId); }else{ - Log.w(TAG, "No registered app found when register secondary transport"); + DebugTool.logWarning(TAG, "No registered app found when register secondary transport"); } } } @@ -2749,7 +2758,7 @@ public class SdlRouterService extends Service{ private boolean legacyModeEnabled = false; private void enableLegacyMode(boolean enable){ - Log.d(TAG, "Enable legacy mode: " + enable); + DebugTool.logInfo(TAG, "Enable legacy mode: " + enable); legacyModeEnabled = enable; //We put this at the end to avoid a race condition between the bluetooth d/c and notify of legacy mode enabled if(legacyModeEnabled){ @@ -2771,13 +2780,13 @@ public class SdlRouterService extends Service{ //DEBUG if(bytes[0] != 0x00){ - Log.d(TAG, "Writing packet with header: " + BitConverter.bytesToHex(bytes, 12)); //just want the header + DebugTool.logInfo(TAG, "Writing packet with header: " + BitConverter.bytesToHex(bytes, 12)); //just want the header }else{ //Log.d(TAG, "Writing packet with binary header: " + BitConverter.bytesToHex(bytes, 12)); //just want the header //int length = bytes.length-12; if(bytes.length<=8){ - Log.w(TAG, "No payload to debug or too small"); + DebugTool.logWarning(TAG, "No payload to debug or too small"); return; } //Check first byte if 0, make to json @@ -2788,7 +2797,7 @@ public class SdlRouterService extends Service{ try { JSONObject object = new JSONObject(new String(buffer)); - Log.d(TAG, "JSON: " + object.toString()); + DebugTool.logInfo(TAG, "JSON: " + object.toString()); } catch (JSONException e) { e.printStackTrace(); } @@ -2882,7 +2891,7 @@ public class SdlRouterService extends Service{ return; } if(isPingingClients){ - Log.w(TAG, "Already pinging clients. Resting count"); + DebugTool.logWarning(TAG, "Already pinging clients. Resting count"); synchronized(PING_COUNT_LOCK){ pingCount = 0; } @@ -2901,7 +2910,7 @@ public class SdlRouterService extends Service{ @Override public void run() { if(getPingCount()>=10){ - Log.d(TAG, "Hit ping limit"); + DebugTool.logInfo(TAG, "Hit ping limit"); stopClientPings(); return; } @@ -3397,7 +3406,7 @@ public class SdlRouterService extends Service{ } if(buffer != null){ if (!buffer.handleMessage(flags, packet)) { //If this returns false - Log.e(TAG, "Error handling bytes"); + DebugTool.logError(TAG, "Error handling bytes"); } if (buffer.isFinished()) { //We are finished building the buffer so we should write the bytes out byte[] bytes = buffer.getBytes(); @@ -3441,7 +3450,7 @@ public class SdlRouterService extends Service{ if(queue!=null && queue.peek().priorityCoefficient>0){ //If this has any sort of priority coefficient we want to make it wait. //Flag to wait if(queueWaitHandler == null){ - Log.e(TAG, "Unable to pause queue, handler was null"); + DebugTool.logError(TAG, "Unable to pause queue, handler was null"); } if(queueWaitRunnable == null){ queueWaitRunnable = new Runnable(){ @@ -3480,7 +3489,7 @@ public class SdlRouterService extends Service{ @Override public void binderDied() { synchronized(deathLock){ - Log.w(TAG, "Binder died for app " + RegisteredApp.this.appId); + DebugTool.logWarning(TAG, "Binder died for app " + RegisteredApp.this.appId); if(messenger.getBinder()!=null){ messenger.getBinder().unlinkToDeath(this, 0); } @@ -3781,5 +3790,54 @@ public class SdlRouterService extends Service{ } } - + /** + * notifySppError: utilize notification channel to notify the SPP out-of-resource error. + */ + @TargetApi(11) + @SuppressLint("NewApi") + private void notifySppError() { + Notification.Builder builder; + if(android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O){ + builder = new Notification.Builder(getApplicationContext()); + } else { + builder = new Notification.Builder(getApplicationContext(), TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID); + } + ComponentName name = new ComponentName(this, this.getClass()); + if(0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) { //If we are in debug mode, include what app has the router service open + builder.setContentTitle("SDL: " + name.getPackageName()); + } else { + builder.setContentTitle(getString(R.string.notification_title)); + } + builder.setTicker(getString(R.string.sdl_error_notification_channel_name)); + builder.setContentText(getString(R.string.spp_out_of_resource)); + + //We should use icon from library resources if available + int trayId = getResources().getIdentifier("sdl_tray_icon", "drawable", getPackageName()); + + builder.setSmallIcon(trayId); + Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.spp_error); + builder.setLargeIcon(icon); + + builder.setOngoing(false); + + DebugTool.logError(TAG, "Notification: notifySppError entering"); + final String tag = "SDL"; + //Now we need to add a notification channel + final NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager != null) { + notificationManager.cancel(tag, TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID_INT); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel notificationChannel = new NotificationChannel(TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID, getString(R.string.sdl_error_notification_channel_name), NotificationManager.IMPORTANCE_HIGH); + notificationChannel.enableLights(true); + notificationChannel.enableVibration(true); + notificationChannel.setShowBadge(false); + notificationManager.createNotificationChannel(notificationChannel); + builder.setChannelId(notificationChannel.getId()); + } + Notification notification = builder.build(); + notificationManager.notify(tag, TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID_INT, notification); + } else { + DebugTool.logError(TAG, "notifySppError: Unable to retrieve notification Manager service"); + } + } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java index 53e1dbbed..6a7230fcd 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterStatusProvider.java @@ -42,9 +42,9 @@ import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; -import android.util.Log; import com.smartdevicelink.util.AndroidTools; +import com.smartdevicelink.util.DebugTool; import java.lang.ref.WeakReference; @@ -66,7 +66,7 @@ public class SdlRouterStatusProvider { private ServiceConnection routerConnection= new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Bound to service " + className.toString()); + DebugTool.logInfo(TAG, "Bound to service " + className.toString()); routerServiceMessenger = new Messenger(service); isBound = true; //So we just established our connection @@ -86,7 +86,7 @@ public class SdlRouterStatusProvider { } public void onServiceDisconnected(ComponentName className) { - Log.d(TAG, "UN-Bound from service " + className.getClassName()); + DebugTool.logInfo(TAG, "UN-Bound from service " + className.getClassName()); routerServiceMessenger = null; isBound = false; } @@ -146,7 +146,7 @@ public class SdlRouterStatusProvider { if(context!=null && routerConnection!=null){ context.unbindService(routerConnection); }else{ - Log.w(TAG, "Unable to unbind from router service, context was null"); + DebugTool.logWarning(TAG, "Unable to unbind from router service, context was null"); } }catch(IllegalArgumentException e){ diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlTransport.java index 0fa64d7f5..32fe26fee 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlTransport.java @@ -39,6 +39,7 @@ import com.smartdevicelink.transport.enums.TransportType; import com.smartdevicelink.util.DebugTool; public abstract class SdlTransport { + private static final String TAG = "SdlTransport"; private static final String SDL_LIB_TRACE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66"; private final static String FailurePropagating_Msg = "Failure propagating "; @@ -73,7 +74,7 @@ public abstract class SdlTransport { _transportListener.onTransportPacketReceived(packet); } // end-if } catch (Exception excp) { - DebugTool.logError(FailurePropagating_Msg + "handleBytesFromTransport: " + excp.toString(), excp); + DebugTool.logError(TAG, FailurePropagating_Msg + "handleBytesFromTransport: " + excp.toString(), excp); handleTransportError(FailurePropagating_Msg, excp); } // end-catch } // end-method @@ -113,7 +114,7 @@ public abstract class SdlTransport { SdlTrace.logTransportEvent("Transport.connected", null, InterfaceActivityDirection.Receive, null, 0, SDL_LIB_TRACE_KEY); _transportListener.onTransportConnected(); } catch (Exception excp) { - DebugTool.logError(FailurePropagating_Msg + "onTransportConnected: " + excp.toString(), excp); + DebugTool.logError(TAG, FailurePropagating_Msg + "onTransportConnected: " + excp.toString(), excp); handleTransportError(FailurePropagating_Msg + "onTransportConnected", excp); } // end-catch } // end-method @@ -127,7 +128,7 @@ public abstract class SdlTransport { SdlTrace.logTransportEvent("Transport.disconnect: " + info, null, InterfaceActivityDirection.Transmit, null, 0, SDL_LIB_TRACE_KEY); _transportListener.onTransportDisconnected(info); } catch (Exception excp) { - DebugTool.logError(FailurePropagating_Msg + "onTransportDisconnected: " + excp.toString(), excp); + DebugTool.logError(TAG, FailurePropagating_Msg + "onTransportDisconnected: " + excp.toString(), excp); } // end-catch } // end-method diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransport.java index 4ae010a8c..3629e883c 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransport.java @@ -35,12 +35,12 @@ import android.annotation.SuppressLint; import android.annotation.TargetApi;
import android.os.Build;
import android.os.NetworkOnMainThreadException;
-import android.util.Log;
import com.smartdevicelink.exception.SdlException;
import com.smartdevicelink.exception.SdlExceptionCause;
import com.smartdevicelink.protocol.SdlPacket;
import com.smartdevicelink.transport.enums.TransportType;
+import com.smartdevicelink.util.DebugTool;
import java.io.IOException;
import java.io.InputStream;
@@ -77,7 +77,7 @@ import java.net.Socket; * Class that implements TCP transport
*/
public class TCPTransport extends SdlTransport {
-
+ private static final String TAG = "TCPTransport";
/**
* Size of the read buffer.
*/
@@ -293,7 +293,7 @@ public class TCPTransport extends SdlTransport { * @param message Message to log
*/
protected void logInfo(String message) {
- Log.i(getClass().getName(), message);
+ DebugTool.logInfo(TAG, message);
}
/**
@@ -301,7 +301,7 @@ public class TCPTransport extends SdlTransport { * @param message Message to log
*/
protected void logError(String message) {
- Log.e(getClass().getName(), message);
+ DebugTool.logError(TAG, message);
}
/**
@@ -309,7 +309,7 @@ public class TCPTransport extends SdlTransport { * @param message Message to log
*/
protected void logWarning(String message) {
- Log.w(getClass().getName(), message);
+ DebugTool.logWarning(TAG, message);
}
/**
@@ -318,7 +318,7 @@ public class TCPTransport extends SdlTransport { * @param throwable Exception, that was the main reason for logged error message
*/
protected void logError(String message, Throwable throwable) {
- Log.e(getClass().getName(), message, throwable);
+ DebugTool.logError(TAG, message, throwable);
}
/**
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java index 29e0c3aa1..aca8789ac 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TCPTransportManager.java @@ -2,7 +2,6 @@ package com.smartdevicelink.transport; import android.os.Handler; import android.os.Message; -import android.util.Log; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.transport.enums.TransportType; @@ -21,7 +20,7 @@ public class TCPTransportManager extends TransportManagerBase{ public TCPTransportManager(TCPTransportConfig config, TransportEventListener transportEventListener){ super(config,transportEventListener); - Log.d(TAG, "USING THE TCP TRANSPORT MANAGER"); + DebugTool.logInfo(TAG, "USING THE TCP TRANSPORT MANAGER"); this.config = config; tcpHandler = new TCPHandler(this); transport = new MultiplexTcpTransport(config.getPort(), config.getIPAddress(),config.getAutoReconnect(),tcpHandler, null); @@ -98,7 +97,7 @@ public class TCPTransportManager extends TransportManagerBase{ service.transportStatus.clear(); service.transportStatus.add(service.transport.getTransportRecord()); } - DebugTool.logInfo("TCP transport has connected"); + DebugTool.logInfo(TAG, "TCP transport has connected"); service.transportListener.onTransportConnected(service.transportStatus); break; case MultiplexBaseTransport.STATE_CONNECTING: @@ -120,7 +119,7 @@ public class TCPTransportManager extends TransportManagerBase{ } break; case MultiplexBaseTransport.STATE_ERROR: - Log.d(TAG, "TCP transport encountered an error"); + DebugTool.logInfo(TAG, "TCP transport encountered an error"); service.transportListener.onError("TCP transport encountered an error" ); break; } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java index 710e9d610..becbdcbb4 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportBroker.java @@ -48,7 +48,6 @@ import android.os.Messenger; import android.os.Parcelable; import android.os.RemoteException; import android.os.TransactionTooLargeException; -import android.util.Log; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.transport.enums.TransportType; @@ -86,8 +85,7 @@ public class TransportBroker { private Context currentContext = null; private final Object INIT_LOCK = new Object(); - - private TransportType queuedOnTransportConnect = null; + private final Object MESSAGE_SEND_LOCK = new Object(); Messenger routerServiceMessenger = null; final Messenger clientMessenger; @@ -108,7 +106,7 @@ public class TransportBroker { routerConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Bound to service " + className.toString()); + DebugTool.logInfo(TAG, "Bound to service " + className.toString()); routerServiceMessenger = new Messenger(service); isBound = true; //So we just established our connection @@ -117,7 +115,7 @@ public class TransportBroker { } public void onServiceDisconnected(ComponentName className) { - Log.d(TAG, "Unbound from service " + className.getClassName()); + DebugTool.logInfo(TAG, "Unbound from service " + className.getClassName()); routerServiceMessenger = null; registeredWithRouterService = false; isBound = false; @@ -126,59 +124,55 @@ public class TransportBroker { }; } - protected synchronized boolean sendMessageToRouterService(Message message) { + protected boolean sendMessageToRouterService(Message message) { return sendMessageToRouterService(message, 0); } - protected synchronized boolean sendMessageToRouterService(Message message, int retryCount) { - if (message == null) { - Log.w(TAG, "Attempted to send null message"); - return false; - } - //Log.i(TAG, "Attempting to send message type - " + message.what); - if (isBound && routerServiceMessenger != null) { - if (registeredWithRouterService - || message.what == TransportConstants.ROUTER_REGISTER_CLIENT) { //We can send a message if we are registered or are attempting to register - try { - routerServiceMessenger.send(message); - return true; - } catch (RemoteException e) { - e.printStackTrace(); - //Let's check to see if we should retry - if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && e instanceof TransactionTooLargeException ) - || (retryCount < 5 && routerServiceMessenger.getBinder().isBinderAlive() && routerServiceMessenger.getBinder().pingBinder())) { //We probably just failed on a small transaction =\ - try { - Thread.sleep(100); - } catch (InterruptedException e1) { - e1.printStackTrace(); + protected boolean sendMessageToRouterService(Message message, int retryCount) { + synchronized (MESSAGE_SEND_LOCK) { + if (message == null) { + DebugTool.logWarning(TAG, "Attempted to send null message"); + return false; + } + //Log.i(TAG, "Attempting to send message type - " + message.what); + if (isBound && routerServiceMessenger != null && routerServiceMessenger.getBinder() != null && routerServiceMessenger.getBinder().isBinderAlive()) { + if (registeredWithRouterService + || message.what == TransportConstants.ROUTER_REGISTER_CLIENT) { //We can send a message if we are registered or are attempting to register + try { + routerServiceMessenger.send(message); + return true; + } catch (RemoteException e) { + e.printStackTrace(); + //Let's check to see if we should retry + if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && e instanceof TransactionTooLargeException) + || (retryCount < 5 && routerServiceMessenger.getBinder().isBinderAlive() && routerServiceMessenger.getBinder().pingBinder())) { //We probably just failed on a small transaction =\ + try { + Thread.sleep(100); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + return sendMessageToRouterService(message, retryCount++); + } else { + //DeadObject, time to kill our connection + DebugTool.logInfo(TAG, "Dead object while attempting to send packet"); + stop(); + onHardwareDisconnected(null, null); + return false; } - return sendMessageToRouterService(message, retryCount++); - } else { - //DeadObject, time to kill our connection - Log.d(TAG, "Dead object while attempting to send packet"); - routerServiceMessenger = null; - registeredWithRouterService = false; - unBindFromRouterService(); - isBound = false; + } catch (NullPointerException e) { + DebugTool.logInfo(TAG, "Null messenger while attempting to send packet"); // NPE, routerServiceMessenger is null + stop(); onHardwareDisconnected(null, null); return false; } - } catch (NullPointerException e) { - Log.d(TAG, "Null messenger while attempting to send packet"); // NPE, routerServiceMessenger is null - routerServiceMessenger = null; - registeredWithRouterService = false; - unBindFromRouterService(); - isBound = false; - onHardwareDisconnected(null, null); + } else { + DebugTool.logError(TAG, "Unable to send message to router service. Not registered."); return false; } } else { - Log.e(TAG, "Unable to send message to router service. Not registered."); + DebugTool.logError(TAG, "Unable to send message to router service. Not bound."); return false; } - } else { - Log.e(TAG, "Unable to send message to router service. Not bound."); - return false; } } @@ -199,7 +193,7 @@ public class TransportBroker { public void handleMessage(Message msg) { TransportBroker broker = provider.get(); if (broker == null) { - Log.e(TAG, "Broker object null, unable to process message"); + DebugTool.logError(TAG, "Broker object null, unable to process message"); return; } Bundle bundle = msg.getData(); @@ -238,7 +232,7 @@ public class TransportBroker { } break; case TransportConstants.REGISTRATION_RESPONSE_DENIED_LEGACY_MODE_ENABLED: - Log.d(TAG, "Denied registration because router is in legacy mode"); + DebugTool.logInfo(TAG, "Denied registration because router is in legacy mode"); broker.registeredWithRouterService = false; broker.enableLegacyMode(true); //We call this so we can start the process of legacy connection @@ -247,7 +241,7 @@ public class TransportBroker { break; default: broker.registeredWithRouterService = false; - Log.w(TAG, "Registration denied from router service. Reason - " + msg.arg1); + DebugTool.logWarning(TAG, "Registration denied from router service. Reason - " + msg.arg1); break; } ; @@ -260,14 +254,14 @@ public class TransportBroker { } else { //We were denied our unregister request to the router service, let's see why - Log.w(TAG, "Unregister request denied from router service. Reason - " + msg.arg1); + DebugTool.logWarning(TAG, "Unregister request denied from router service. Reason - " + msg.arg1); //Do we care? } break; case TransportConstants.ROUTER_RECEIVED_PACKET: if(bundle == null){ - DebugTool.logWarning("Received packet message from router service with no bundle"); + DebugTool.logWarning(TAG, "Received packet message from router service with no bundle"); return; } //So the intent has a packet with it. PEFRECT! Let's send it through the library @@ -288,7 +282,7 @@ public class TransportBroker { broker.onPacketReceived(packet); } else { - Log.w(TAG, "Received null packet from router service, not passing along"); + DebugTool.logWarning(TAG, "Received null packet from router service, not passing along"); } } else if (flags == TransportConstants.BYTES_TO_SEND_FLAG_SDL_PACKET_INCLUDED) { broker.bufferedPacket = (SdlPacket) packet; @@ -306,7 +300,7 @@ public class TransportBroker { byte[] chunk = bundle.getByteArray(TransportConstants.BYTES_TO_SEND_EXTRA_NAME); if (!broker.bufferedPayloadAssembler.handleMessage(flags, chunk)) { //If there was a problem - Log.e(TAG, "Error handling bytes for split packet"); + DebugTool.logError(TAG, "Error handling bytes for split packet"); } if (broker.bufferedPayloadAssembler.isFinished()) { broker.bufferedPacket.setPayload(broker.bufferedPayloadAssembler.getBytes()); @@ -320,18 +314,18 @@ public class TransportBroker { //} //} } else { - Log.w(TAG, "Flase positive packet reception"); + DebugTool.logWarning(TAG, "Flase positive packet reception"); } break; case TransportConstants.HARDWARE_CONNECTION_EVENT: if(bundle == null){ - DebugTool.logWarning("Received hardware connection message from router service with no bundle"); + DebugTool.logWarning(TAG, "Received hardware connection message from router service with no bundle"); return; } if (bundle.containsKey(TransportConstants.TRANSPORT_DISCONNECTED) || bundle.containsKey(TransportConstants.HARDWARE_DISCONNECTED)) { //We should shut down, so call - Log.d(TAG, "Hardware disconnected"); + DebugTool.logInfo(TAG, "Hardware disconnected"); if (isLegacyModeEnabled()) { broker.onLegacyModeEnabled(); } else { @@ -416,7 +410,6 @@ public class TransportBroker { } //this.appId = appId.concat(timeStamp); this.appId = appId; - queuedOnTransportConnect = null; currentContext = context; //Log.d(TAG, "Registering our reply receiver: " + whereToReply); this.routerService = service; @@ -448,7 +441,6 @@ public class TransportBroker { synchronized (INIT_LOCK) { unregisterWithRouterService(); routerServiceMessenger = null; - queuedOnTransportConnect = null; unBindFromRouterService(); isBound = false; } @@ -458,24 +450,23 @@ public class TransportBroker { * This method will end our communication with the router service. */ public void stop() { - DebugTool.logInfo("Stopping transport broker for " + whereToReply); + DebugTool.logInfo(TAG, "Stopping transport broker for " + whereToReply); synchronized (INIT_LOCK) { unregisterWithRouterService(); unBindFromRouterService(); routerServiceMessenger = null; - queuedOnTransportConnect = null; currentContext = null; } } - private synchronized void unBindFromRouterService() { + private void unBindFromRouterService() { try { getContext().unbindService(routerConnection); } catch (Exception e) { //This is ok - Log.w(TAG, "Unable to unbind from router service. bound? " + isBound + " context? " + (getContext()!=null) + " router connection?" + (routerConnection != null)); + DebugTool.logWarning(TAG, "Unable to unbind from router service. bound? " + isBound + " context? " + (getContext()!=null) + " router connection?" + (routerConnection != null)); }finally { isBound = false; } @@ -487,27 +478,17 @@ public class TransportBroker { public void onServiceUnregsiteredFromRouterService(int unregisterCode) { - queuedOnTransportConnect = null; } @Deprecated public void onHardwareDisconnected(TransportType type) { - routerServiceDisconnect(); + stop(); } public void onHardwareDisconnected(TransportRecord record, List<TransportRecord> connectedTransports) { } - private void routerServiceDisconnect() { - synchronized (INIT_LOCK) { - unBindFromRouterService(); - routerServiceMessenger = null; - routerConnection = null; - queuedOnTransportConnect = null; - } - } - /** * WILL NO LONGER BE CALLED * @@ -518,7 +499,6 @@ public class TransportBroker { public boolean onHardwareConnected(TransportType type) { synchronized (INIT_LOCK) { if (routerServiceMessenger == null) { - queuedOnTransportConnect = type; return false; } return true; @@ -528,7 +508,6 @@ public class TransportBroker { public boolean onHardwareConnected(List<TransportRecord> transports) { synchronized (INIT_LOCK) { if (routerServiceMessenger == null && transports != null && transports.size() > 0) { - queuedOnTransportConnect = transports.get(transports.size() - 1).getType(); return false; } return true; @@ -575,14 +554,14 @@ public class TransportBroker { //Log.d(TAG,whereToReply + "Sending packet to router service"); if (routerServiceMessenger == null) { - Log.d(TAG, whereToReply + " tried to send packet, but no where to send"); + DebugTool.logInfo(TAG, whereToReply + " tried to send packet, but no where to send"); return false; } if (packet == null //|| offset<0 //|| count<0 ) {//|| count>(bytes.length-offset)){ - Log.w(TAG, whereToReply + "incorrect params supplied"); + DebugTool.logWarning(TAG, whereToReply + "incorrect params supplied"); return false; } byte[] bytes = packet.constructPacket(); @@ -616,7 +595,7 @@ public class TransportBroker { ByteArrayMessageSpliter splitter = new ByteArrayMessageSpliter(appId, TransportConstants.ROUTER_SEND_PACKET, bytes, packet.getPrioirtyCoefficient()); splitter.setRouterServiceVersion(routerServiceVersion); splitter.setTransportRecord(packet.getTransportRecord()); - while (splitter.isActive()) { + while (splitter.isActive() && routerServiceMessenger != null) { sendMessageToRouterService(splitter.nextMessage()); } return splitter.close(); @@ -629,18 +608,18 @@ public class TransportBroker { */ private boolean registerWithRouterService() { if (getContext() == null) { - Log.e(TAG, "Context set to null, failing out"); + DebugTool.logError(TAG, "Context set to null, failing out"); return false; } if (routerServiceMessenger != null) { - Log.w(TAG, "Already registered with router service"); + DebugTool.logWarning(TAG, "Already registered with router service"); return false; } //Make sure we know where to bind to if (this.routerService == null) { if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.O) && !isRouterServiceRunning(getContext())) {//We should be able to ignore this case because of the validation now - Log.d(TAG, whereToReply + " found no router service. Shutting down."); + DebugTool.logInfo(TAG, whereToReply + " found no router service. Shutting down."); this.onHardwareDisconnected(null); return false; } @@ -650,7 +629,7 @@ public class TransportBroker { } if (!sendBindingIntent()) { - Log.e(TAG, "Something went wrong while trying to bind with the router service."); + DebugTool.logError(TAG, "Something went wrong while trying to bind with the router service."); SdlBroadcastReceiver.queryForConnectedService(currentContext); return false; } @@ -661,11 +640,11 @@ public class TransportBroker { @SuppressLint("InlinedApi") private boolean sendBindingIntent() { if(this.isBound){ - Log.e(TAG, "Already bound"); + DebugTool.logError(TAG, "Already bound"); return false; } if (this.routerPackage != null && this.routerClassName != null) { - Log.d(TAG, "Sending bind request to " + this.routerPackage + " - " + this.routerClassName); + DebugTool.logInfo(TAG, "Sending bind request to " + this.routerPackage + " - " + this.routerClassName); Intent bindingIntent = new Intent(); bindingIntent.setClassName(this.routerPackage, this.routerClassName);//This sets an explicit intent //Quickly make sure it's just up and running @@ -690,7 +669,7 @@ public class TransportBroker { } private void unregisterWithRouterService() { - Log.i(TAG, "Attempting to unregister with Sdl Router Service"); + DebugTool.logInfo(TAG, "Attempting to unregister with Sdl Router Service"); if (isBound && routerServiceMessenger != null) { Message msg = Message.obtain(); msg.what = TransportConstants.ROUTER_UNREGISTER_CLIENT; @@ -703,7 +682,7 @@ public class TransportBroker { msg.setData(bundle); sendMessageToRouterService(msg); } else { - Log.w(TAG, "Unable to unregister, not bound to router service"); + DebugTool.logWarning(TAG, "Unable to unregister, not bound to router service"); } routerServiceMessenger = null; diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java index 1a0951503..5039b0e0e 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/TransportManager.java @@ -44,11 +44,11 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Parcelable; -import android.util.Log; import com.smartdevicelink.protocol.SdlPacket; import com.smartdevicelink.protocol.enums.ControlFrameTags; import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.transport.utl.SdlDeviceListener; import com.smartdevicelink.transport.utl.TransportRecord; import com.smartdevicelink.util.DebugTool; @@ -96,11 +96,11 @@ public class TransportManager extends TransportManagerBase{ validator.validateAsync(new RouterServiceValidator.ValidationStatusCallback() { @Override public void onFinishedValidation(boolean valid, ComponentName name) { - DebugTool.logInfo("onFinishedValidation valid=" + valid + "; name=" + ((name == null)? "null" : name.getPackageName())); + DebugTool.logInfo(TAG, "onFinishedValidation valid=" + valid + "; name=" + ((name == null)? "null" : name.getPackageName())); if (valid) { mConfig.service = name; transport = new TransportBrokerImpl(contextWeakReference.get(), mConfig.appId, mConfig.service); - DebugTool.logInfo("TransportManager start got called; transport=" + transport); + DebugTool.logInfo(TAG, "TransportManager start was called; transport=" + transport); if(transport != null){ transport.start(); } @@ -245,7 +245,7 @@ public class TransportManager extends TransportManagerBase{ if(transport != null){ transport.requestNewSession(transportRecord); }else if(legacyBluetoothTransport != null){ - Log.w(TAG, "Session requested for non-bluetooth transport while in legacy mode"); + DebugTool.logWarning(TAG, "Session requested for non-bluetooth transport while in legacy mode"); } } @@ -294,7 +294,7 @@ public class TransportManager extends TransportManagerBase{ @Override public synchronized boolean onHardwareConnected(List<TransportRecord> transports) { super.onHardwareConnected(transports); - DebugTool.logInfo("OnHardwareConnected"); + DebugTool.logInfo(TAG, "OnHardwareConnected"); if(shuttingDown){ return false; } @@ -302,6 +302,16 @@ public class TransportManager extends TransportManagerBase{ transportStatus.clear(); transportStatus.addAll(transports); } + //If a bluetooth device has connected, make sure to save the mac address in the case + //this app is asked to host the router service, the app knows to do so immediately on connection. + if(transports != null && transports.size() > 0) { + for (TransportRecord record : transports) { + if(record != null && TransportType.BLUETOOTH.equals(record.getType())) { + SdlDeviceListener.setSDLConnectedStatus(contextWeakReference.get(), record.getAddress(),true); + } + } + } + transportListener.onTransportConnected(transports); return true; } @@ -310,9 +320,9 @@ public class TransportManager extends TransportManagerBase{ @Override public synchronized void onHardwareDisconnected(TransportRecord record, List<TransportRecord> connectedTransports) { if(record != null){ - Log.d(TAG, "Transport disconnected - " + record); + DebugTool.logInfo(TAG, "Transport disconnected - " + record); }else{ - Log.d(TAG, "Transport disconnected"); + DebugTool.logInfo(TAG, "Transport disconnected"); } if(shuttingDown){ @@ -344,7 +354,7 @@ public class TransportManager extends TransportManagerBase{ if (foundMatch) { //Remove item after the loop to avoid concurrent modifications TransportManager.this.transportStatus.remove(record); - Log.d(TAG, "Handling corner case of transport disconnect mismatch"); + DebugTool.logInfo(TAG, "Handling corner case of transport disconnect mismatch"); } } } @@ -471,7 +481,7 @@ public class TransportManager extends TransportManagerBase{ }else if(action.equalsIgnoreCase(BluetoothAdapter.ACTION_STATE_CHANGED)){ int bluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); if(bluetoothState == BluetoothAdapter.STATE_TURNING_OFF || bluetoothState == BluetoothAdapter.STATE_OFF){ - Log.d(TAG, "Bluetooth is shutting off, exiting legacy mode."); + DebugTool.logInfo(TAG, "Bluetooth is shutting off, exiting legacy mode."); exitLegacyMode("Bluetooth adapter shutting off"); } } @@ -519,7 +529,7 @@ public class TransportManager extends TransportManagerBase{ service.exitLegacyMode("Lost connection"); break; case MultiplexBaseTransport.STATE_ERROR: - Log.d(TAG, "Bluetooth serial server error received, setting state to none, and clearing local copy"); + DebugTool.logInfo(TAG, "Bluetooth serial server error received, setting state to none, and clearing local copy"); service.exitLegacyMode("Transport error"); break; } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java index b724377ed..419ba6ca3 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBAccessoryAttachmentActivity.java @@ -42,7 +42,6 @@ import android.os.Build; import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.RequiresApi;
-import android.util.Log;
import com.smartdevicelink.util.AndroidTools;
import com.smartdevicelink.util.DebugTool;
@@ -118,7 +117,7 @@ public class USBAccessoryAttachmentActivity extends Activity { }
final Intent intent = getIntent();
String action = intent.getAction();
- Log.d(TAG, "Received intent with action: " + action);
+ DebugTool.logInfo(TAG, "Received intent with action: " + action);
if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
usbAccessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
@@ -164,8 +163,8 @@ public class USBAccessoryAttachmentActivity extends Activity { serviceIntent = new Intent();
serviceIntent.setComponent(optimalRouterService.getRouterServiceComponentName());
} else{
- Log.d(TAG, "No SDL Router Services found");
- Log.d(TAG, "WARNING: This application has not specified its SdlRouterService correctly in the manifest. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!");
+ DebugTool.logInfo(TAG, "No SDL Router Services found");
+ DebugTool.logInfo(TAG, "WARNING: This application has not specified its SdlRouterService correctly in the manifest. THIS WILL THROW AN EXCEPTION IN FUTURE RELEASES!!");
// At this point to ensure that USB connection is still possible it might be
// worth trying to use the legacy USB transport scheme
attemptLegacyUsbConnection(usbAccessory);
@@ -184,7 +183,7 @@ public class USBAccessoryAttachmentActivity extends Activity { if(startedService == null){
// A router service was not started or is not running.
- DebugTool.logError(TAG + " - Error starting router service. Attempting legacy connection ");
+ DebugTool.logError(TAG, " - Error starting router service. Attempting legacy connection ");
attemptLegacyUsbConnection(usbAccessory);
return;
}
@@ -207,7 +206,7 @@ public class USBAccessoryAttachmentActivity extends Activity { }
} catch (SecurityException e) {
- Log.e(TAG, "Security exception, process is bad");
+ DebugTool.logError(TAG, "Security exception, process is bad");
}
} else {
if (usbAccessory!=null) {
@@ -226,13 +225,13 @@ public class USBAccessoryAttachmentActivity extends Activity { private void attemptLegacyUsbConnection(UsbAccessory usbAccessory){
if(usbAccessory != null) {
- DebugTool.logInfo("Attempting to send USB connection intent using legacy method");
+ DebugTool.logInfo(TAG, "Attempting to send USB connection intent using legacy method");
Intent usbAccessoryAttachedIntent = new Intent(USBTransport.ACTION_USB_ACCESSORY_ATTACHED);
usbAccessoryAttachedIntent.putExtra(UsbManager.EXTRA_ACCESSORY, usbAccessory);
usbAccessoryAttachedIntent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, permissionGranted);
AndroidTools.sendExplicitBroadcast(getApplicationContext(), usbAccessoryAttachedIntent, null);
}else{
- DebugTool.logError("Unable to start legacy USB mode as the accessory was null");
+ DebugTool.logError(TAG, "Unable to start legacy USB mode as the accessory was null");
}
finish();
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransport.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransport.java index 698396ae1..0ab2f2fcf 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransport.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/USBTransport.java @@ -341,7 +341,7 @@ public class USBTransport extends SdlTransport { */
//@Override
public void stopReading() {
- DebugTool.logInfo("USBTransport: stop reading requested, doing nothing");
+ DebugTool.logInfo(TAG, "USBTransport: stop reading requested, doing nothing");
// TODO - put back stopUSBReading(); @see <a href="https://adc.luxoft.com/jira/browse/SmartDeviceLink-3450">SmartDeviceLink-3450</a>
}
@@ -632,7 +632,7 @@ public class USBTransport extends SdlTransport { * @param tr throwable to log
*/
private void logE(String s, Throwable tr) {
- DebugTool.logError(s, tr);
+ DebugTool.logError(TAG, s, tr);
}
/**
@@ -641,7 +641,7 @@ public class USBTransport extends SdlTransport { * @param s string to log
*/
private void logW(String s) {
- DebugTool.logWarning(s);
+ DebugTool.logWarning(TAG, s);
}
/**
@@ -665,7 +665,7 @@ public class USBTransport extends SdlTransport { * @param s string to log
*/
private void logI(String s) {
- DebugTool.logInfo(s);
+ DebugTool.logInfo(TAG, s);
}
/**
@@ -675,7 +675,7 @@ public class USBTransport extends SdlTransport { */
private void logD(String s) {
// DebugTool doesn't support DEBUG level, so we use INFO instead
- DebugTool.logInfo(DEBUG_PREFIX + s);
+ DebugTool.logInfo(TAG, DEBUG_PREFIX + s);
}
/**
@@ -882,15 +882,15 @@ public class USBTransport extends SdlTransport { // Log functions
private void logD(String s) {
- DebugTool.logInfo(DEBUG_PREFIX + s);
+ DebugTool.logInfo(TAG, DEBUG_PREFIX + s);
}
private void logI(String s) {
- DebugTool.logInfo(s);
+ DebugTool.logInfo(TAG, s);
}
private void logW(String s) {
- DebugTool.logWarning(s);
+ DebugTool.logWarning(TAG, s);
}
private void logW(String s, Throwable tr) {
@@ -903,7 +903,7 @@ public class USBTransport extends SdlTransport { }
private void logE(String s, Throwable tr) {
- DebugTool.logError(s, tr);
+ DebugTool.logError(TAG, s, tr);
}
}
diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/UsbTransferProvider.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/UsbTransferProvider.java index 6fb17172a..cd351a622 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/UsbTransferProvider.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/UsbTransferProvider.java @@ -48,9 +48,9 @@ import android.os.Message; import android.os.Messenger; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.util.Log; import com.smartdevicelink.util.AndroidTools; +import com.smartdevicelink.util.DebugTool; import java.io.IOException; import java.lang.ref.WeakReference; @@ -74,7 +74,7 @@ public class UsbTransferProvider { private ServiceConnection routerConnection= new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Bound to service " + className.toString()); + DebugTool.logInfo(TAG, "Bound to service " + className.toString()); routerServiceMessenger = new Messenger(service); isBound = true; //So we just established our connection @@ -95,7 +95,7 @@ public class UsbTransferProvider { } public void onServiceDisconnected(ComponentName className) { - Log.d(TAG, "UN-Bound from service " + className.getClassName()); + DebugTool.logInfo(TAG, "UN-Bound from service " + className.getClassName()); routerServiceMessenger = null; isBound = false; } @@ -121,7 +121,7 @@ public class UsbTransferProvider { usbInfoBundle.putString(MultiplexUsbTransport.DESCRIPTION, usbAccessory.getDescription()); checkIsConnected(); }else{ - Log.e(TAG, "Unable to open accessory"); + DebugTool.logError(TAG, "Unable to open accessory"); clientMessenger = null; if(callback != null){ callback.onUsbTransferUpdate(false); @@ -152,7 +152,7 @@ public class UsbTransferProvider { public void checkIsConnected(){ if(!AndroidTools.isServiceExported(context,routerService) || !bindToService()){ //We are unable to bind to service - Log.e(TAG, "Unable to bind to service"); + DebugTool.logError(TAG, "Unable to bind to service"); unBindFromService(); } } @@ -183,7 +183,7 @@ public class UsbTransferProvider { if(context!=null && routerConnection!=null){ context.unbindService(routerConnection); }else{ - Log.w(TAG, "Unable to unbind from router service, context was null"); + DebugTool.logWarning(TAG, "Unable to unbind from router service, context was null"); } }catch(IllegalArgumentException e){ @@ -222,7 +222,7 @@ public class UsbTransferProvider { } switch (msg.what) { case TransportConstants.ROUTER_USB_ACC_RECEIVED: - Log.d(TAG, "Successful USB transfer"); + DebugTool.logInfo(TAG, "Successful USB transfer"); provider.get().finish(); break; default: diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteAraryMessageAssembler.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteAraryMessageAssembler.java index 4f9c5096e..163b2268b 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteAraryMessageAssembler.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteAraryMessageAssembler.java @@ -31,10 +31,9 @@ */ package com.smartdevicelink.transport.utl; -import android.util.Log; - import com.smartdevicelink.transport.TransportConstants; import com.smartdevicelink.transport.enums.TransportType; +import com.smartdevicelink.util.DebugTool; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -92,8 +91,8 @@ public class ByteAraryMessageAssembler { append(packet); this.isFinished = true; break; - default: - Log.e(TAG, "Error handling message"); + default: + DebugTool.logError(TAG, "Error handling message"); return false; } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteArrayMessageSpliter.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteArrayMessageSpliter.java index 107901ccb..c7333fb08 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteArrayMessageSpliter.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/ByteArrayMessageSpliter.java @@ -33,10 +33,10 @@ package com.smartdevicelink.transport.utl; import android.os.Bundle; import android.os.Message; -import android.util.Log; import com.smartdevicelink.transport.TransportBroker; import com.smartdevicelink.transport.TransportConstants; +import com.smartdevicelink.util.DebugTool; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -151,7 +151,7 @@ public class ByteArrayMessageSpliter { } bundle.putString(TransportConstants.APP_ID_EXTRA_STRING, appId); message.setData(bundle); - Log.i(TAG, ((100 - ((stream.available()*100)/orginalSize) ))+ " percent complete."); + DebugTool.logInfo(TAG, ((100 - ((stream.available()*100)/orginalSize) ))+ " percent complete."); return message; } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/SdlDeviceListener.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/SdlDeviceListener.java new file mode 100644 index 000000000..488a117b4 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/SdlDeviceListener.java @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2020 Livio, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Livio Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +package com.smartdevicelink.transport.utl; + +import android.bluetooth.BluetoothDevice; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.support.annotation.NonNull; + +import com.smartdevicelink.transport.MultiplexBaseTransport; +import com.smartdevicelink.transport.MultiplexBluetoothTransport; +import com.smartdevicelink.transport.SdlRouterService; +import com.smartdevicelink.util.DebugTool; +import com.smartdevicelink.util.SdlAppInfo; + +import java.lang.ref.WeakReference; +import java.util.List; + + +public class SdlDeviceListener { + + private static final String TAG = "SdlListener"; + private static final int MIN_VERSION_REQUIRED = 13; + private static final String SDL_DEVICE_STATUS_SHARED_PREFS = "sdl.device.status"; + private static final Object LOCK = new Object(), RUNNING_LOCK = new Object(); + + private final WeakReference<Context> contextWeakReference; + private final Callback callback; + private final BluetoothDevice connectedDevice; + private MultiplexBluetoothTransport bluetoothTransport; + private TransportHandler bluetoothHandler; + private Handler timeoutHandler; + private Runnable timeoutRunner; + private boolean isRunning = false; + + + public SdlDeviceListener(Context context, BluetoothDevice device, Callback callback) { + this.contextWeakReference = new WeakReference<>(context); + this.connectedDevice = device; + this.callback = callback; + } + + /** + * This will start the SDL Device Listener with two paths. The first path will be a check + * against the supplied bluetooth device to see if it has already successfully connected as an + * SDL device. If it has, the supplied callback will be called immediately. If the device hasn't + * connected as an SDL device before, the SDL Device Listener will then open up an RFCOMM channel + * using the SDL UUID and await a potential connection. A timeout is used to ensure this only + * listens for a finite amount of time. If this is the first time the device has been seen, this + * will listen for 30 seconds, if it is not, this will listen for 15 seconds instead. + */ + public void start() { + if(connectedDevice == null) { + DebugTool.logInfo(TAG, ": No supplied bluetooth device"); + if(callback != null){ + callback.onTransportError(null); + } + return; + } + + if (hasSDLConnected(contextWeakReference.get(), connectedDevice.getAddress())) { + DebugTool.logInfo(TAG, ": Confirmed SDL device, should start router service"); + //This device has connected to SDL previously, it is ok to start the RS right now + callback.onTransportConnected(contextWeakReference.get(), connectedDevice); + return; + } + synchronized (RUNNING_LOCK) { + isRunning = true; + // set timeout = if first time seeing BT device, 30s, if not 15s + int timeout = isFirstStatusCheck(connectedDevice.getAddress()) ? 30000 : 15000; + //Set our preference as false for this device for now + setSDLConnectedStatus(contextWeakReference.get(), connectedDevice.getAddress(), false); + bluetoothHandler = new TransportHandler(this); + bluetoothTransport = new MultiplexBluetoothTransport(bluetoothHandler); + bluetoothTransport.start(); + timeoutRunner = new Runnable() { + @Override + public void run() { + if (bluetoothTransport != null) { + int state = bluetoothTransport.getState(); + if (state != MultiplexBluetoothTransport.STATE_CONNECTED) { + DebugTool.logInfo(TAG, ": No bluetooth connection made"); + bluetoothTransport.stop(); + } //else BT is connected; it will close itself through callbacks + } + } + }; + timeoutHandler = new Handler(Looper.getMainLooper()); + timeoutHandler.postDelayed(timeoutRunner, timeout); + } + } + + /** + * Check to see if this instance is in the middle of running or not + * + * @return if this is already in the process of running + */ + public boolean isRunning() { + synchronized (RUNNING_LOCK) { + return isRunning; + } + } + + private static class TransportHandler extends Handler { + + final WeakReference<SdlDeviceListener> provider; + + TransportHandler(SdlDeviceListener provider) { + this.provider = new WeakReference<>(provider); + } + + @Override + public void handleMessage(@NonNull Message msg) { + if (this.provider.get() == null) { + return; + } + SdlDeviceListener sdlListener = this.provider.get(); + switch (msg.what) { + + case SdlRouterService.MESSAGE_STATE_CHANGE: + switch (msg.arg1) { + case MultiplexBaseTransport.STATE_CONNECTED: + sdlListener.setSDLConnectedStatus(sdlListener.contextWeakReference.get(), sdlListener.connectedDevice.getAddress(), true); + boolean keepConnectionOpen = sdlListener.callback.onTransportConnected(sdlListener.contextWeakReference.get(), sdlListener.connectedDevice); + if (!keepConnectionOpen) { + sdlListener.bluetoothTransport.stop(); + sdlListener.bluetoothTransport = null; + sdlListener.timeoutHandler.removeCallbacks(sdlListener.timeoutRunner); + } + break; + case MultiplexBaseTransport.STATE_NONE: + // We've just lost the connection + sdlListener.callback.onTransportDisconnected(sdlListener.connectedDevice); + break; + case MultiplexBaseTransport.STATE_ERROR: + sdlListener.callback.onTransportError(sdlListener.connectedDevice); + break; + } + break; + + case com.smartdevicelink.transport.SdlRouterService.MESSAGE_READ: + break; + } + } + } + + + /** + * Set the connection establishment status of the particular device + * + * @param address address of the device in question + * @param hasSDLConnected true if a connection has been established, false if not + */ + public static void setSDLConnectedStatus(Context context, String address, boolean hasSDLConnected) { + synchronized (LOCK) { + if (context != null) { + DebugTool.logInfo(TAG, ": Saving connected status - " + address + " : " + hasSDLConnected); + SharedPreferences preferences = context.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE); + if (preferences.contains(address) && hasSDLConnected == preferences.getBoolean(address, false)) { + //The same key/value exists in our shared preferences. No reason to write again. + return; + } + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean(address, hasSDLConnected); + editor.commit(); + } + } + } + + /** + * Checks to see if a device address has connected to SDL before. + * + * @param address the mac address of the device in question + * @return if this is the first status check of this device + */ + private boolean isFirstStatusCheck(String address) { + synchronized (LOCK) { + Context context = contextWeakReference.get(); + if (context != null) { + SharedPreferences preferences = context.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE); + return !preferences.contains(address); + } + return false; + } + } + + /** + * Checks to see if a device address has connected to SDL before. + * + * @param address the mac address of the device in question + * @return if an SDL connection has ever been established with this device + */ + public static boolean hasSDLConnected(Context context, String address) { + synchronized (LOCK) { + if (context != null) { + SharedPreferences preferences = context.getSharedPreferences(SDL_DEVICE_STATUS_SHARED_PREFS, Context.MODE_PRIVATE); + return preferences.contains(address) && preferences.getBoolean(address, false); + } + return false; + } + } + + /** + * This method will check the current device and list of SDL enabled apps to derive if the + * feature can be supported. Due to older libraries sending their intents to start the router + * service right at the bluetooth A2DP/HFS connections, this feature can't be used until all + * applications are updated to the point they include the feature. + * + * @param sdlAppInfoList current list of SDL enabled applications on the device + * @return if this feature is supported or not. If it is not, the caller should follow the + * previously used flow, ie start the router service. + */ + public static boolean isFeatureSupported(List<SdlAppInfo> sdlAppInfoList) { + + SdlAppInfo appInfo; + for (int i = sdlAppInfoList.size() - 1; i >= 0; i--) { + appInfo = sdlAppInfoList.get(i); + if (appInfo != null + && !appInfo.isCustomRouterService() + && appInfo.getRouterServiceVersion() < MIN_VERSION_REQUIRED) { + return false; + } + } + + return true; + } + + /** + * Callback for the SdlDeviceListener. It will return if the supplied device makes a bluetooth + * connection on the SDL UUID RFCOMM chanel or not. Most of the time the only callback that + * matters will be the onTransportConnected. + */ + public interface Callback { + /** + * @param bluetoothDevice the BT device that successfully connected to SDL's UUID + * @return if the RFCOMM connection should stay open. In most cases this should be false + */ + boolean onTransportConnected(Context context, BluetoothDevice bluetoothDevice); + + void onTransportDisconnected(BluetoothDevice bluetoothDevice); + + void onTransportError(BluetoothDevice bluetoothDevice); + } +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/TransportRecord.java b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/TransportRecord.java new file mode 100644 index 000000000..bd31e746e --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/transport/utl/TransportRecord.java @@ -0,0 +1,56 @@ +package com.smartdevicelink.transport.utl; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.smartdevicelink.transport.enums.TransportType; + +public class TransportRecord extends BaseTransportRecord implements Parcelable { + + public TransportRecord(TransportType transportType, String address) { + super(transportType, address); + } + + public TransportRecord(Parcel p) { + if (p.readInt() == 1) { //We should have a transport type attached + String transportName = p.readString(); + if(transportName != null){ + this.type = TransportType.valueOf(transportName); + } + } + + if (p.readInt() == 1) { //We should have a transport address attached + address = p.readString(); + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(type!=null? 1 : 0); + if(type != null){ + dest.writeString(type.name()); + } + + dest.writeInt(address !=null? 1 : 0); + if(address != null){ + dest.writeString(address); + } + } + + public static final Parcelable.Creator<TransportRecord> CREATOR = new Parcelable.Creator<TransportRecord>() { + public TransportRecord createFromParcel(Parcel in) { + return new TransportRecord(in); + } + + @Override + public TransportRecord[] newArray(int size) { + return new TransportRecord[size]; + } + + }; +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/util/HttpRequestTask.java b/android/sdl_android/src/main/java/com/smartdevicelink/util/HttpRequestTask.java new file mode 100644 index 000000000..44125dff2 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/util/HttpRequestTask.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2017 - 2019, SmartDeviceLink Consortium, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the SmartDeviceLink Consortium, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.smartdevicelink.util; + +import android.os.AsyncTask; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.HttpURLConnection; +import java.net.URL; + +public class HttpRequestTask extends AsyncTask<String, String, String> { + private static final String TAG = "Http Request Task"; + + public static final String REQUEST_TYPE_POST = "POST"; + public static final String REQUEST_TYPE_GET = "GET"; + public static final String REQUEST_TYPE_DELETE = "DELETE"; + + HttpRequestTaskCallback cb; + + /** + * @param hcb callback for when this task finishes + * <br><br><b> - When calling execute, params as followed: </b><br> + * 1. Url String<br> + * 2. Request type (Defined in this class) REQUEST_TYPE_POST, REQUEST_TYPE_GET, REQUEST_TYPE_DELETE<br> + * 3. (Optional) Data to be sent. <br> + * 4. (Optional) Content Type Default will be application/json<br> + * 5. (Optional) Accept Type default will be application/json + * + */ + public HttpRequestTask( HttpRequestTaskCallback hcb){ + this.cb = hcb; + } + + @Override + protected String doInBackground(String... params) { + int length = params.length; + String urlString = params[0]; + String request_type = params[1]; + + //Grab and set data to be written if included + String data; + if(length>2){ + data = params[2]; + }else{ + data = null; + } + + //Grab and set content type for the header if included + String contentType; + if(length>3){ + contentType = params[3]; + }else{ + contentType = "application/json"; + } + //Grab and set accept type for the header if included + String acceptType; + if(length>4){ + acceptType = params[4]; + }else{ + acceptType = "application/json"; + } + + if(urlString == null || request_type == null){ + DebugTool.logError(TAG, "Can't process request, param error"); + if(cb!=null){ + cb.httpFailure(-1); + cb = null; + } + return "Error"; + } + + HttpURLConnection urlConnection = null; + BufferedReader reader = null; + try { + URL url = new URL(urlString); + urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setDoOutput(true); + urlConnection.setRequestMethod(request_type); + urlConnection.setRequestProperty("Content-Type", contentType); + urlConnection.setRequestProperty("Accept", acceptType); + //If we have data, we should write it out + if(data !=null){ + Writer writer = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8")); + writer.write(data); + writer.close(); + } + InputStream inputStream = urlConnection.getInputStream(); + + int responseCode = urlConnection.getResponseCode(); + if (responseCode == 200) { //Success + //input stream + StringBuffer buffer = new StringBuffer(); + if (inputStream == null) { + // Nothing to do. + if(cb!=null){ + cb.httpCallComplete(null); + cb = null; + } + return null; + } + reader = new BufferedReader(new InputStreamReader(inputStream)); + + String inputLine; + while ((inputLine = reader.readLine()) != null) + buffer.append(inputLine).append("\n"); + if (buffer.length() == 0) { + // Stream was empty. No point in parsing. + if(cb!=null){ + cb.httpCallComplete(null); + cb = null; + } + return null; + } + String response = null; + + response = buffer.toString(); + //send to post execute + if(cb!=null){ + cb.httpCallComplete(response); + cb = null; + } + return response; + }else{ + if(cb!=null){ + cb.httpFailure(responseCode); + cb = null; + } + DebugTool.logError(TAG, "Failed to download file - " + responseCode); + return null; + } + + + } catch (IOException e) { + e.printStackTrace(); + } catch (NullPointerException e){ // Only to catch error in urlConnection.getOutputStream() - when servers are down + e.printStackTrace(); + urlConnection = null; + } + finally { + if (urlConnection != null) { + urlConnection.disconnect(); + } + if (reader != null) { + try { + reader.close(); + } catch (final IOException e) { + DebugTool.logError(TAG, "Error closing stream", e); + } + } + if(cb!=null){ + cb.httpFailure(-1); + } + } + return null; + } + + /** + * Callback interface for HTTP requests. + * @author Joey Grover + * + */ + public interface HttpRequestTaskCallback{ + /** + * Called when HTTP request is successfully completed. + * @param response The response to the HTTP request. + */ + public abstract void httpCallComplete(String response); + /** + * Called when HTTP request failed. + * @param statusCode The HTTP failure code. + */ + public abstract void httpFailure(int statusCode); + } + +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/util/Log.java b/android/sdl_android/src/main/java/com/smartdevicelink/util/Log.java new file mode 100644 index 000000000..c6f2d2649 --- /dev/null +++ b/android/sdl_android/src/main/java/com/smartdevicelink/util/Log.java @@ -0,0 +1,19 @@ +package com.smartdevicelink.util; + +public class Log { + public static void i(String tag, String message) { + android.util.Log.i(tag, message); + } + + public static void w(String tag, String message) { + android.util.Log.w(tag, message); + } + + public static void e(String tag, String message, Throwable t) { + if (t != null) { + android.util.Log.e(tag, message, t); + } else { + android.util.Log.e(tag, message); + } + } +}
\ No newline at end of file diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/util/MediaStreamingStatus.java b/android/sdl_android/src/main/java/com/smartdevicelink/util/MediaStreamingStatus.java index be55e1102..b74c7aac9 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/util/MediaStreamingStatus.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/util/MediaStreamingStatus.java @@ -59,6 +59,7 @@ import java.util.List; */ public class MediaStreamingStatus { + private static final String TAG = "MediaStreamingStatus"; private static final Object BROADCAST_RECEIVER_LOCK = new Object(); private boolean broadcastReceiverValid = true; @@ -137,7 +138,7 @@ public class MediaStreamingStatus { * @return */ boolean isSupportedAudioDevice(int audioDevice){ - DebugTool.logInfo("Audio device connected: " + audioDevice); + DebugTool.logInfo(TAG, "Audio device connected: " + audioDevice); switch (audioDevice){ case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP: if(isBluetoothActuallyAvailable()) { diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/util/SdlAppInfo.java b/android/sdl_android/src/main/java/com/smartdevicelink/util/SdlAppInfo.java index d90045371..8dc481323 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/util/SdlAppInfo.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/util/SdlAppInfo.java @@ -37,7 +37,6 @@ import android.content.pm.PackageInfo; import android.content.pm.ResolveInfo; import android.os.Build; import android.os.Bundle; -import android.util.Log; import java.util.Comparator; @@ -77,7 +76,7 @@ public class SdlAppInfo { this.isCustomRouterService = metadata.getBoolean(SDL_CUSTOM_ROUTER_METADATA); } } else { - Log.w(TAG, packageName + " has not supplied metadata with their router service!"); + DebugTool.logWarning(TAG, packageName + " has not supplied metadata with their router service!"); } } diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java b/android/sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java index 6f1740878..5ce18165f 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/util/ServiceFinder.java @@ -40,7 +40,6 @@ import android.content.pm.ResolveInfo; import android.os.Build; import android.os.Handler; import android.os.Looper; -import android.util.Log; import com.smartdevicelink.transport.SdlRouterService; @@ -98,11 +97,11 @@ public class ServiceFinder { @Override public void onReceive(Context context, Intent intent) { - Log.d(TAG, "Received intent " + intent); + DebugTool.logInfo(TAG, "Received intent " + intent); if (intent != null) { String packageName = intent.getStringExtra(BIND_LOCATION_PACKAGE_NAME_EXTRA); String className = intent.getStringExtra(BIND_LOCATION_CLASS_NAME_EXTRA); - Log.d(TAG, "Received intent from package: " + packageName + ". Classname: " + className); + DebugTool.logInfo(TAG, "Received intent from package: " + packageName + ". Classname: " + className); synchronized (LIST_LOCK) { //Add to running services services.add(new ComponentName(packageName, className)); diff --git a/android/sdl_android/src/main/res/drawable-hdpi/sdl_lockscreen_icon.png b/android/sdl_android/src/main/res/drawable-hdpi/sdl_lockscreen_icon.png Binary files differindex 625eb35ea..a5fa05f58 100644 --- a/android/sdl_android/src/main/res/drawable-hdpi/sdl_lockscreen_icon.png +++ b/android/sdl_android/src/main/res/drawable-hdpi/sdl_lockscreen_icon.png diff --git a/android/sdl_android/src/main/res/drawable-hdpi/spp_error.png b/android/sdl_android/src/main/res/drawable-hdpi/spp_error.png Binary files differnew file mode 100644 index 000000000..608127178 --- /dev/null +++ b/android/sdl_android/src/main/res/drawable-hdpi/spp_error.png diff --git a/android/sdl_android/src/main/res/drawable-mdpi/sdl_lockscreen_icon.png b/android/sdl_android/src/main/res/drawable-mdpi/sdl_lockscreen_icon.png Binary files differindex d13a55e0b..a254d37ec 100644 --- a/android/sdl_android/src/main/res/drawable-mdpi/sdl_lockscreen_icon.png +++ b/android/sdl_android/src/main/res/drawable-mdpi/sdl_lockscreen_icon.png diff --git a/android/sdl_android/src/main/res/drawable-mdpi/spp_error.png b/android/sdl_android/src/main/res/drawable-mdpi/spp_error.png Binary files differnew file mode 100644 index 000000000..f89acfd1f --- /dev/null +++ b/android/sdl_android/src/main/res/drawable-mdpi/spp_error.png diff --git a/android/sdl_android/src/main/res/drawable-xhdpi/sdl_lockscreen_icon.png b/android/sdl_android/src/main/res/drawable-xhdpi/sdl_lockscreen_icon.png Binary files differindex d7de7cabe..ef2574797 100644 --- a/android/sdl_android/src/main/res/drawable-xhdpi/sdl_lockscreen_icon.png +++ b/android/sdl_android/src/main/res/drawable-xhdpi/sdl_lockscreen_icon.png diff --git a/android/sdl_android/src/main/res/drawable-xhdpi/spp_error.png b/android/sdl_android/src/main/res/drawable-xhdpi/spp_error.png Binary files differnew file mode 100644 index 000000000..5d3a64c81 --- /dev/null +++ b/android/sdl_android/src/main/res/drawable-xhdpi/spp_error.png diff --git a/android/sdl_android/src/main/res/drawable-xxhdpi/sdl_lockscreen_icon.png b/android/sdl_android/src/main/res/drawable-xxhdpi/sdl_lockscreen_icon.png Binary files differindex bd0c40e67..f03e41322 100644 --- a/android/sdl_android/src/main/res/drawable-xxhdpi/sdl_lockscreen_icon.png +++ b/android/sdl_android/src/main/res/drawable-xxhdpi/sdl_lockscreen_icon.png diff --git a/android/sdl_android/src/main/res/drawable-xxhdpi/spp_error.png b/android/sdl_android/src/main/res/drawable-xxhdpi/spp_error.png Binary files differnew file mode 100644 index 000000000..9a2adc83f --- /dev/null +++ b/android/sdl_android/src/main/res/drawable-xxhdpi/spp_error.png diff --git a/android/sdl_android/src/main/res/drawable-xxxhdpi/sdl_lockscreen_icon.png b/android/sdl_android/src/main/res/drawable-xxxhdpi/sdl_lockscreen_icon.png Binary files differindex 21962c148..7a1cde649 100644 --- a/android/sdl_android/src/main/res/drawable-xxxhdpi/sdl_lockscreen_icon.png +++ b/android/sdl_android/src/main/res/drawable-xxxhdpi/sdl_lockscreen_icon.png diff --git a/android/sdl_android/src/main/res/drawable-xxxhdpi/spp_error.png b/android/sdl_android/src/main/res/drawable-xxxhdpi/spp_error.png Binary files differnew file mode 100644 index 000000000..dbcbd7aaf --- /dev/null +++ b/android/sdl_android/src/main/res/drawable-xxxhdpi/spp_error.png diff --git a/android/sdl_android/src/main/res/layout/activity_sdllock_screen.xml b/android/sdl_android/src/main/res/layout/activity_sdllock_screen.xml index 43b5e6840..ce287ed04 100644 --- a/android/sdl_android/src/main/res/layout/activity_sdllock_screen.xml +++ b/android/sdl_android/src/main/res/layout/activity_sdllock_screen.xml @@ -1,8 +1,7 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lockscreen_relative_layout" android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:background="#2c3d4d"> + android:layout_height="fill_parent"> <LinearLayout android:id="@+id/lockscreen_linear_layout" @@ -13,12 +12,21 @@ <ImageView android:id="@+id/lockscreen_image" + android:layout_width="187dp" + android:layout_height="78dp" + android:scaleType="fitXY" + android:layout_gravity="center_horizontal" + android:contentDescription="@string/lockscreen_image_description" + android:adjustViewBounds="true" /> + + <ImageView + android:id="@+id/appIcon" android:layout_width="120dp" android:layout_height="120dp" android:scaleType="fitXY" android:layout_gravity="center_horizontal" android:contentDescription="@string/lockscreen_image_description" - android:background="@drawable/sdl_lockscreen_icon"/> + android:visibility="gone"/> <ImageView android:id="@+id/device_image" diff --git a/android/sdl_android/src/main/res/values-ar/strings.xml b/android/sdl_android/src/main/res/values-ar/strings.xml new file mode 100644 index 000000000..9d7d5e3ef --- /dev/null +++ b/android/sdl_android/src/main/res/values-ar/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">تستخدم تطبيقات كثيرة بلوتوث</string> + <string name="sdl_error_notification_channel_name">خطأ SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-cs/strings.xml b/android/sdl_android/src/main/res/values-cs/strings.xml new file mode 100644 index 000000000..73c487c29 --- /dev/null +++ b/android/sdl_android/src/main/res/values-cs/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Bluetooth používá příliš mnoho aplikací</string> + <string name="sdl_error_notification_channel_name">Chyba SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-da/strings.xml b/android/sdl_android/src/main/res/values-da/strings.xml new file mode 100644 index 000000000..20c8a4f1b --- /dev/null +++ b/android/sdl_android/src/main/res/values-da/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">For mange apps bruger Bluetooth</string> + <string name="sdl_error_notification_channel_name">SDL-fejl</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-de/strings.xml b/android/sdl_android/src/main/res/values-de/strings.xml new file mode 100644 index 000000000..b4b132990 --- /dev/null +++ b/android/sdl_android/src/main/res/values-de/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Zu viele Apps verwenden Bluetooth</string> + <string name="sdl_error_notification_channel_name">SDL-Fehler</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-el/strings.xml b/android/sdl_android/src/main/res/values-el/strings.xml new file mode 100644 index 000000000..1de0be9f9 --- /dev/null +++ b/android/sdl_android/src/main/res/values-el/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Πάρα πολλές εφαρμογές χρησιμοποιούν Bluetooth</string> + <string name="sdl_error_notification_channel_name">Σφάλμα SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-es/strings.xml b/android/sdl_android/src/main/res/values-es/strings.xml new file mode 100644 index 000000000..e73c2f8b8 --- /dev/null +++ b/android/sdl_android/src/main/res/values-es/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Demasiadas aplicaciones usan Bluetooth</string> + <string name="sdl_error_notification_channel_name">Error de SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-fi/strings.xml b/android/sdl_android/src/main/res/values-fi/strings.xml new file mode 100644 index 000000000..e4fd37034 --- /dev/null +++ b/android/sdl_android/src/main/res/values-fi/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Liian monet sovellukset käyttävät Bluetoothia</string> + <string name="sdl_error_notification_channel_name">SDL-virhe</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-fr/strings.xml b/android/sdl_android/src/main/res/values-fr/strings.xml new file mode 100644 index 000000000..1336b8ce4 --- /dev/null +++ b/android/sdl_android/src/main/res/values-fr/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Trop d\'applications utilisent Bluetooth</string> + <string name="sdl_error_notification_channel_name">Erreur SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-he/strings.xml b/android/sdl_android/src/main/res/values-he/strings.xml new file mode 100644 index 000000000..78a7ceb25 --- /dev/null +++ b/android/sdl_android/src/main/res/values-he/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">יותר מדי יישומים משתמשים ב- Bluetooth</string> + <string name="sdl_error_notification_channel_name">שגיאת SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-hi/strings.xml b/android/sdl_android/src/main/res/values-hi/strings.xml new file mode 100644 index 000000000..edef28c00 --- /dev/null +++ b/android/sdl_android/src/main/res/values-hi/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">बहुत से ऐप ब्लूटूथ का उपयोग कर रहे हैं</string> + <string name="sdl_error_notification_channel_name">SDL त्रुटि</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-hu/strings.xml b/android/sdl_android/src/main/res/values-hu/strings.xml new file mode 100644 index 000000000..b459421be --- /dev/null +++ b/android/sdl_android/src/main/res/values-hu/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Túl sok alkalmazás használja a Bluetooth-ot</string> + <string name="sdl_error_notification_channel_name">SDL hiba</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-in/strings.xml b/android/sdl_android/src/main/res/values-in/strings.xml new file mode 100644 index 000000000..8b62f2aad --- /dev/null +++ b/android/sdl_android/src/main/res/values-in/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Terlalu banyak aplikasi menggunakan Bluetooth</string> + <string name="sdl_error_notification_channel_name">Kesalahan SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-it/strings.xml b/android/sdl_android/src/main/res/values-it/strings.xml new file mode 100644 index 000000000..ef778cd99 --- /dev/null +++ b/android/sdl_android/src/main/res/values-it/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Troppe app utilizzano il Bluetooth</string> + <string name="sdl_error_notification_channel_name">Errore SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-iw/strings.xml b/android/sdl_android/src/main/res/values-iw/strings.xml new file mode 100644 index 000000000..78a7ceb25 --- /dev/null +++ b/android/sdl_android/src/main/res/values-iw/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">יותר מדי יישומים משתמשים ב- Bluetooth</string> + <string name="sdl_error_notification_channel_name">שגיאת SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-ja/strings.xml b/android/sdl_android/src/main/res/values-ja/strings.xml new file mode 100644 index 000000000..e91c92b9d --- /dev/null +++ b/android/sdl_android/src/main/res/values-ja/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Bluetoothの使用アプリが多すぎます</string> + <string name="sdl_error_notification_channel_name">SDL エラー</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-ko/strings.xml b/android/sdl_android/src/main/res/values-ko/strings.xml new file mode 100644 index 000000000..1eec31a11 --- /dev/null +++ b/android/sdl_android/src/main/res/values-ko/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">너무 많은 앱이 블루투스를 사용하고 있습니다</string> + <string name="sdl_error_notification_channel_name">SDL 오류</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-ms/strings.xml b/android/sdl_android/src/main/res/values-ms/strings.xml new file mode 100644 index 000000000..7667e75ed --- /dev/null +++ b/android/sdl_android/src/main/res/values-ms/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Terlalu banyak aplikasi yang menggunakan Bluetooth</string> + <string name="sdl_error_notification_channel_name">Ralat SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-nb/strings.xml b/android/sdl_android/src/main/res/values-nb/strings.xml new file mode 100644 index 000000000..6e3b6401a --- /dev/null +++ b/android/sdl_android/src/main/res/values-nb/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">For mange apper bruker Bluetooth</string> + <string name="sdl_error_notification_channel_name">SDL-feil</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-nl/strings.xml b/android/sdl_android/src/main/res/values-nl/strings.xml new file mode 100644 index 000000000..8b44d7029 --- /dev/null +++ b/android/sdl_android/src/main/res/values-nl/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Te veel apps gebruiken Bluetooth</string> + <string name="sdl_error_notification_channel_name">SDL-fout</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-pl/strings.xml b/android/sdl_android/src/main/res/values-pl/strings.xml new file mode 100644 index 000000000..e9519b06f --- /dev/null +++ b/android/sdl_android/src/main/res/values-pl/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Zbyt wiele aplikacji korzysta z Bluetooth</string> + <string name="sdl_error_notification_channel_name">Błąd SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-pt/strings.xml b/android/sdl_android/src/main/res/values-pt/strings.xml new file mode 100644 index 000000000..43af897c5 --- /dev/null +++ b/android/sdl_android/src/main/res/values-pt/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Muitos aplicativos estão usando Bluetooth</string> + <string name="sdl_error_notification_channel_name">Erro SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-ro/strings.xml b/android/sdl_android/src/main/res/values-ro/strings.xml new file mode 100644 index 000000000..9846cebe4 --- /dev/null +++ b/android/sdl_android/src/main/res/values-ro/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Prea multe aplicații folosesc Bluetooth</string> + <string name="sdl_error_notification_channel_name">Eroare SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-ru/strings.xml b/android/sdl_android/src/main/res/values-ru/strings.xml new file mode 100644 index 000000000..81ae10b93 --- /dev/null +++ b/android/sdl_android/src/main/res/values-ru/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Слишком много приложений используют Bluetooth</string> + <string name="sdl_error_notification_channel_name">Ошибка SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-sk/strings.xml b/android/sdl_android/src/main/res/values-sk/strings.xml new file mode 100644 index 000000000..2580fcfc1 --- /dev/null +++ b/android/sdl_android/src/main/res/values-sk/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Bluetooth používa príliš veľa aplikácií</string> + <string name="sdl_error_notification_channel_name">Chyba SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-sv/strings.xml b/android/sdl_android/src/main/res/values-sv/strings.xml new file mode 100644 index 000000000..df2970e05 --- /dev/null +++ b/android/sdl_android/src/main/res/values-sv/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">För många appar använder Bluetooth</string> + <string name="sdl_error_notification_channel_name">SDL-fel</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-th/strings.xml b/android/sdl_android/src/main/res/values-th/strings.xml new file mode 100644 index 000000000..c5141a5e6 --- /dev/null +++ b/android/sdl_android/src/main/res/values-th/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">มีแอปมากเกินไปที่ใช้บลูทู ธ</string> + <string name="sdl_error_notification_channel_name">ข้อผิดพลาด SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-tr/strings.xml b/android/sdl_android/src/main/res/values-tr/strings.xml new file mode 100644 index 000000000..85a645b88 --- /dev/null +++ b/android/sdl_android/src/main/res/values-tr/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Çok fazla uygulama Bluetooth kullanıyor</string> + <string name="sdl_error_notification_channel_name">SDL Hatası</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-uk/strings.xml b/android/sdl_android/src/main/res/values-uk/strings.xml new file mode 100644 index 000000000..466b3cf05 --- /dev/null +++ b/android/sdl_android/src/main/res/values-uk/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Надто багато додатків використовують Bluetooth</string> + <string name="sdl_error_notification_channel_name">Помилка SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-vi/strings.xml b/android/sdl_android/src/main/res/values-vi/strings.xml new file mode 100644 index 000000000..483bfada6 --- /dev/null +++ b/android/sdl_android/src/main/res/values-vi/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">Quá nhiều ứng dụng đang sử dụng Bluetooth</string> + <string name="sdl_error_notification_channel_name">Lỗi SDL</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-zh-rCN/strings.xml b/android/sdl_android/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..543ccd7c8 --- /dev/null +++ b/android/sdl_android/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">太多的应用程序正在使用蓝牙</string> + <string name="sdl_error_notification_channel_name">SDL错误</string> +</resources> diff --git a/android/sdl_android/src/main/res/values-zh-rTW/strings.xml b/android/sdl_android/src/main/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000..747d9b6a8 --- /dev/null +++ b/android/sdl_android/src/main/res/values-zh-rTW/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="spp_out_of_resource">太多的應用程序正在使用藍牙</string> + <string name="sdl_error_notification_channel_name">SDL錯誤</string> +</resources> diff --git a/android/sdl_android/src/main/res/values/sdl.xml b/android/sdl_android/src/main/res/values/sdl.xml index e2a20bff8..bc83d733e 100644 --- a/android/sdl_android/src/main/res/values/sdl.xml +++ b/android/sdl_android/src/main/res/values/sdl.xml @@ -2,7 +2,7 @@ <resources> <string name="sdl_router_service_version_name" translatable="false">sdl_router_version</string> - <integer name="sdl_router_service_version_value">12</integer> + <integer name="sdl_router_service_version_value">13</integer> <string name="sdl_router_service_is_custom_name" translatable="false">sdl_custom_router</string> </resources> diff --git a/android/sdl_android/src/main/res/values/strings.xml b/android/sdl_android/src/main/res/values/strings.xml index f74ce713b..89322299f 100644 --- a/android/sdl_android/src/main/res/values/strings.xml +++ b/android/sdl_android/src/main/res/values/strings.xml @@ -4,4 +4,7 @@ <string name="lockscreen_image_description">SDL Icon</string> <string name="lockscreen_device_image_description">Device Icon</string> <string name="default_lockscreen_warning_message">Swipe down to dismiss, acknowledging that you are not the driver.</string> + <string name="spp_out_of_resource">Too many apps are using Bluetooth</string> + <string name="notification_title">SmartDeviceLink</string> + <string name="sdl_error_notification_channel_name">SDL Error</string> </resources>
\ No newline at end of file |