mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 11:33:06 +00:00
Merge branch 'master' into root
Conflicts: libs/limelight-common.jar
This commit is contained in:
commit
f07e927103
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -23,15 +23,16 @@ import java.security.spec.InvalidKeySpecException;
|
|||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.bouncycastle.asn1.x500.X500Name;
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
import org.bouncycastle.asn1.x500.X500NameBuilder;
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle;
|
import org.bouncycastle.asn1.x500.style.BCStyle;
|
||||||
|
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
|
||||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.bouncycastle.openssl.PEMWriter;
|
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
|
||||||
import org.bouncycastle.operator.ContentSigner;
|
import org.bouncycastle.operator.ContentSigner;
|
||||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||||
|
|
||||||
@ -152,7 +153,8 @@ public class AndroidCryptoProvider implements LimelightCryptoProvider {
|
|||||||
nameBuilder.addRDN(BCStyle.CN, "NVIDIA GameStream Client");
|
nameBuilder.addRDN(BCStyle.CN, "NVIDIA GameStream Client");
|
||||||
X500Name name = nameBuilder.build();
|
X500Name name = nameBuilder.build();
|
||||||
|
|
||||||
X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(name, serial, now, expirationDate, name, keyPair.getPublic());
|
X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(name, serial, now, expirationDate, Locale.ENGLISH, name,
|
||||||
|
SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BouncyCastleProvider.PROVIDER_NAME).build(keyPair.getPrivate());
|
ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BouncyCastleProvider.PROVIDER_NAME).build(keyPair.getPrivate());
|
||||||
@ -179,7 +181,7 @@ public class AndroidCryptoProvider implements LimelightCryptoProvider {
|
|||||||
|
|
||||||
// Write the certificate in OpenSSL PEM format (important for the server)
|
// Write the certificate in OpenSSL PEM format (important for the server)
|
||||||
StringWriter strWriter = new StringWriter();
|
StringWriter strWriter = new StringWriter();
|
||||||
PEMWriter pemWriter = new PEMWriter(strWriter);
|
JcaPEMWriter pemWriter = new JcaPEMWriter(strWriter);
|
||||||
pemWriter.writeObject(cert);
|
pemWriter.writeObject(cert);
|
||||||
pemWriter.close();
|
pemWriter.close();
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package com.limelight.binding.input.evdev;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ public class EvdevReader {
|
|||||||
|
|
||||||
OutputStream stdin = p.getOutputStream();
|
OutputStream stdin = p.getOutputStream();
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
stdin.write(String.format("chmod %o %s\n", octalPermissions, file).getBytes("UTF-8"));
|
stdin.write(String.format((Locale)null, "chmod %o %s\n", octalPermissions, file).getBytes("UTF-8"));
|
||||||
}
|
}
|
||||||
stdin.write("exit\n".getBytes("UTF-8"));
|
stdin.write("exit\n".getBytes("UTF-8"));
|
||||||
stdin.flush();
|
stdin.flush();
|
||||||
|
@ -3,6 +3,7 @@ package com.limelight.binding.video;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.concurrent.locks.LockSupport;
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import org.jcodec.codecs.h264.io.model.SeqParameterSet;
|
import org.jcodec.codecs.h264.io.model.SeqParameterSet;
|
||||||
@ -53,9 +54,6 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
preferredDecoders = new LinkedList<String>();
|
preferredDecoders = new LinkedList<String>();
|
||||||
|
|
||||||
// This is the most reliable of Samsung's decoders
|
|
||||||
preferredDecoders.add("OMX.SEC.AVC.Decoder");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -317,21 +315,62 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
BufferInfo info = new BufferInfo();
|
BufferInfo info = new BufferInfo();
|
||||||
DecodeUnit du;
|
DecodeUnit du = null;
|
||||||
|
int inputIndex = -1;
|
||||||
while (!isInterrupted())
|
while (!isInterrupted())
|
||||||
{
|
{
|
||||||
du = depacketizer.pollNextDecodeUnit();
|
// In order to get as much data to the decoder as early as possible,
|
||||||
if (du != null) {
|
// try to submit up to 5 decode units at once without blocking.
|
||||||
if (!submitDecodeUnit(du)) {
|
if (inputIndex == -1 && du == null) {
|
||||||
// Thread was interrupted
|
for (int i = 0; i < 5; i++) {
|
||||||
depacketizer.freeDecodeUnit(du);
|
inputIndex = videoDecoder.dequeueInputBuffer(0);
|
||||||
return;
|
du = depacketizer.pollNextDecodeUnit();
|
||||||
}
|
|
||||||
else {
|
// Stop if we can't get a DU or input buffer
|
||||||
depacketizer.freeDecodeUnit(du);
|
if (du == null || inputIndex == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
submitDecodeUnit(du, inputIndex);
|
||||||
|
|
||||||
|
du = null;
|
||||||
|
inputIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Grab an input buffer if we don't have one already.
|
||||||
|
// This way we can have one ready hopefully by the time
|
||||||
|
// the depacketizer is done with this frame. It's important
|
||||||
|
// that this can timeout because it's possible that we could exhaust
|
||||||
|
// the decoder's input buffers and deadlocks because aren't pulling
|
||||||
|
// frames out of the other end.
|
||||||
|
if (inputIndex == -1) {
|
||||||
|
try {
|
||||||
|
// If we've got a DU waiting to be given to the decoder,
|
||||||
|
// wait a full 3 ms for an input buffer. Otherwise
|
||||||
|
// just see if we can get one immediately.
|
||||||
|
inputIndex = videoDecoder.dequeueInputBuffer(du != null ? 3000 : 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RendererException(MediaCodecDecoderRenderer.this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab a decode unit if we don't have one already
|
||||||
|
if (du == null) {
|
||||||
|
du = depacketizer.pollNextDecodeUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've got both a decode unit and an input buffer, we'll
|
||||||
|
// submit now. Otherwise, we wait until we have one.
|
||||||
|
if (du != null && inputIndex >= 0) {
|
||||||
|
submitDecodeUnit(du, inputIndex);
|
||||||
|
|
||||||
|
// DU and input buffer have both been consumed
|
||||||
|
du = null;
|
||||||
|
inputIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to output a frame
|
||||||
try {
|
try {
|
||||||
int outIndex = videoDecoder.dequeueOutputBuffer(info, 0);
|
int outIndex = videoDecoder.dequeueOutputBuffer(info, 0);
|
||||||
|
|
||||||
@ -358,7 +397,11 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
} else {
|
} else {
|
||||||
switch (outIndex) {
|
switch (outIndex) {
|
||||||
case MediaCodec.INFO_TRY_AGAIN_LATER:
|
case MediaCodec.INFO_TRY_AGAIN_LATER:
|
||||||
LockSupport.parkNanos(1);
|
// Getting an input buffer may already block
|
||||||
|
// so don't park if we still need to do that
|
||||||
|
if (inputIndex >= 0) {
|
||||||
|
LockSupport.parkNanos(1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
|
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
|
||||||
LimeLog.info("Output buffers changed");
|
LimeLog.info("Output buffers changed");
|
||||||
@ -414,22 +457,8 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean submitDecodeUnit(DecodeUnit decodeUnit) {
|
private void submitDecodeUnit(DecodeUnit decodeUnit, int inputBufferIndex) {
|
||||||
int inputIndex;
|
ByteBuffer buf = videoDecoderInputBuffers[inputBufferIndex];
|
||||||
|
|
||||||
do {
|
|
||||||
if (Thread.interrupted()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
inputIndex = videoDecoder.dequeueInputBuffer(100000);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RendererException(this, e);
|
|
||||||
}
|
|
||||||
} while (inputIndex < 0);
|
|
||||||
|
|
||||||
ByteBuffer buf = videoDecoderInputBuffers[inputIndex];
|
|
||||||
|
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
||||||
@ -492,13 +521,15 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
sps.write(buf);
|
sps.write(buf);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
videoDecoder.queueInputBuffer(inputIndex,
|
videoDecoder.queueInputBuffer(inputBufferIndex,
|
||||||
0, buf.position(),
|
0, buf.position(),
|
||||||
currentTime * 1000, codecFlags);
|
currentTime * 1000, codecFlags);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RendererException(this, e, buf, codecFlags);
|
throw new RendererException(this, e, buf, codecFlags);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
depacketizer.freeDecodeUnit(decodeUnit);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else if (header.data[header.offset+4] == 0x68) {
|
} else if (header.data[header.offset+4] == 0x68) {
|
||||||
numPpsIn++;
|
numPpsIn++;
|
||||||
@ -512,14 +543,15 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
videoDecoder.queueInputBuffer(inputIndex,
|
videoDecoder.queueInputBuffer(inputBufferIndex,
|
||||||
0, decodeUnit.getDataLength(),
|
0, decodeUnit.getDataLength(),
|
||||||
currentTime * 1000, codecFlags);
|
currentTime * 1000, codecFlags);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RendererException(this, e, buf, codecFlags);
|
throw new RendererException(this, e, buf, codecFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
depacketizer.freeDecodeUnit(decodeUnit);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -575,7 +607,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
str += "Current buffer: ";
|
str += "Current buffer: ";
|
||||||
currentBuffer.flip();
|
currentBuffer.flip();
|
||||||
while (currentBuffer.hasRemaining() && currentBuffer.position() < 10) {
|
while (currentBuffer.hasRemaining() && currentBuffer.position() < 10) {
|
||||||
str += String.format("%02x ", currentBuffer.get());
|
str += String.format((Locale)null, "%02x ", currentBuffer.get());
|
||||||
}
|
}
|
||||||
str += "\n";
|
str += "\n";
|
||||||
str += "Buffer codec flags: "+currentCodecFlags+"\n";
|
str += "Buffer codec flags: "+currentCodecFlags+"\n";
|
||||||
|
@ -4,6 +4,7 @@ import java.net.InetAddress;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
@ -44,7 +45,7 @@ public class ComputerDatabaseManager {
|
|||||||
|
|
||||||
private void initializeDb() {
|
private void initializeDb() {
|
||||||
// Create tables if they aren't already there
|
// Create tables if they aren't already there
|
||||||
computerDb.execSQL(String.format("CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY," +
|
computerDb.execSQL(String.format((Locale)null, "CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY," +
|
||||||
" %s TEXT NOT NULL, %s TEXT NOT NULL, %s TEXT NOT NULL, %s TEXT NOT NULL)",
|
" %s TEXT NOT NULL, %s TEXT NOT NULL, %s TEXT NOT NULL, %s TEXT NOT NULL)",
|
||||||
COMPUTER_TABLE_NAME,
|
COMPUTER_TABLE_NAME,
|
||||||
COMPUTER_NAME_COLUMN_NAME, COMPUTER_UUID_COLUMN_NAME, LOCAL_IP_COLUMN_NAME,
|
COMPUTER_NAME_COLUMN_NAME, COMPUTER_UUID_COLUMN_NAME, LOCAL_IP_COLUMN_NAME,
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
package com.limelight.computers;
|
package com.limelight.computers;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InterfaceAddress;
|
|
||||||
import java.net.NetworkInterface;
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
@ -24,11 +19,8 @@ import com.limelight.nvstream.mdns.MdnsDiscoveryListener;
|
|||||||
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
|
||||||
@ -234,93 +226,6 @@ public class ComputerManagerService extends Service {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getActiveNetworkType() {
|
|
||||||
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo();
|
|
||||||
if (activeNetworkInfo == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return activeNetworkInfo.getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
private InterfaceAddress getActiveInterfaceAddress() {
|
|
||||||
String matchingPrefix;
|
|
||||||
|
|
||||||
switch (getActiveNetworkType())
|
|
||||||
{
|
|
||||||
case ConnectivityManager.TYPE_ETHERNET:
|
|
||||||
matchingPrefix = "eth";
|
|
||||||
break;
|
|
||||||
case ConnectivityManager.TYPE_WIFI:
|
|
||||||
matchingPrefix = "wlan";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Must be on Ethernet or Wifi to consider that we can send large packets
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find the interface that corresponds to the active network
|
|
||||||
try {
|
|
||||||
Enumeration<NetworkInterface> ifaceList = NetworkInterface.getNetworkInterfaces();
|
|
||||||
while (ifaceList.hasMoreElements()) {
|
|
||||||
NetworkInterface iface = ifaceList.nextElement();
|
|
||||||
|
|
||||||
// Look for an interface that matches the prefix we expect
|
|
||||||
if (iface.isUp() && iface.getName().startsWith(matchingPrefix)) {
|
|
||||||
// Find the IPv4 address for the interface
|
|
||||||
for (InterfaceAddress addr : iface.getInterfaceAddresses()) {
|
|
||||||
if (!(addr.getAddress() instanceof Inet4Address)) {
|
|
||||||
// Skip non-IPv4 addresses
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Found the right address on the right interface
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SocketException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We didn't find the interface or something else went wrong
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOnSameSubnet(InetAddress targetAddress, InetAddress localAddress, short networkPrefixLength) {
|
|
||||||
byte[] targetBytes = targetAddress.getAddress();
|
|
||||||
byte[] localBytes = localAddress.getAddress();
|
|
||||||
|
|
||||||
for (int byteIndex = 0; networkPrefixLength > 0; byteIndex++) {
|
|
||||||
byte target = targetBytes[byteIndex];
|
|
||||||
byte local = localBytes[byteIndex];
|
|
||||||
|
|
||||||
if (networkPrefixLength >= 8) {
|
|
||||||
// Do a full byte comparison
|
|
||||||
if (target != local) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
networkPrefixLength -= 8;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
target &= (byte)(0xFF << (8 - networkPrefixLength));
|
|
||||||
local &= (byte)(0xFF << (8 - networkPrefixLength));
|
|
||||||
|
|
||||||
// Do a masked comparison
|
|
||||||
if (target != local) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
networkPrefixLength = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ComputerDetails tryPollIp(InetAddress ipAddr) {
|
private ComputerDetails tryPollIp(InetAddress ipAddr) {
|
||||||
try {
|
try {
|
||||||
NvHTTP http = new NvHTTP(ipAddr, idManager.getUniqueId(),
|
NvHTTP http = new NvHTTP(ipAddr, idManager.getUniqueId(),
|
||||||
@ -373,26 +278,7 @@ public class ComputerManagerService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean doPollMachine(ComputerDetails details) {
|
private boolean doPollMachine(ComputerDetails details) {
|
||||||
// Get the network type
|
return pollComputer(details, true);
|
||||||
int networkType = getActiveNetworkType();
|
|
||||||
switch (networkType) {
|
|
||||||
// We'll check local first on these if we find
|
|
||||||
// we're on the same subnet
|
|
||||||
case ConnectivityManager.TYPE_ETHERNET:
|
|
||||||
case ConnectivityManager.TYPE_WIFI:
|
|
||||||
InterfaceAddress ifaceAddr = getActiveInterfaceAddress();
|
|
||||||
if (ifaceAddr != null) {
|
|
||||||
if (isOnSameSubnet(details.localIp, ifaceAddr.getAddress(), ifaceAddr.getNetworkPrefixLength())) {
|
|
||||||
// It's on the same subnet, so poll local first
|
|
||||||
LimeLog.info("Machine looks local; trying local IP first");
|
|
||||||
return pollComputer(details, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Fall through to remote first
|
|
||||||
default:
|
|
||||||
LimeLog.info("Machine looks remote; trying remote IP first");
|
|
||||||
return pollComputer(details, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable getPollingRunnable(final ComputerDetails details) {
|
private Runnable getPollingRunnable(final ComputerDetails details) {
|
||||||
|
@ -4,6 +4,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
@ -61,7 +62,7 @@ public class IdentityManager {
|
|||||||
private static String generateNewUniqueId(Context c) {
|
private static String generateNewUniqueId(Context c) {
|
||||||
// Generate a new UID hex string
|
// Generate a new UID hex string
|
||||||
LimeLog.info("Generating new UID");
|
LimeLog.info("Generating new UID");
|
||||||
String uidStr = String.format("%016x", new Random().nextLong());
|
String uidStr = String.format((Locale)null, "%016x", new Random().nextLong());
|
||||||
|
|
||||||
OutputStreamWriter writer = null;
|
OutputStreamWriter writer = null;
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user