mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Stats: Unique Machine ID
This commit is contained in:
parent
4418376335
commit
6bd1582b47
9 changed files with 201 additions and 14 deletions
|
|
@ -47,6 +47,22 @@ namespace AndroidStatsHelpers
|
|||
javaString (name).get())));
|
||||
}
|
||||
|
||||
static String getAndroidID()
|
||||
{
|
||||
auto* env = getEnv();
|
||||
|
||||
if (auto settings = (jclass) env->FindClass ("android/provider/Settings$Secure"))
|
||||
{
|
||||
if (auto fId = env->GetStaticFieldID (settings, "ANDROID_ID", "Ljava/lang/String;"))
|
||||
{
|
||||
auto androidID = (jstring) env->GetStaticObjectField (settings, fId);
|
||||
return juceString (LocalRef<jstring> (androidID));
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static String getLocaleValue (bool isRegion)
|
||||
{
|
||||
auto* env = getEnv();
|
||||
|
|
@ -170,6 +186,15 @@ String SystemStats::getUserLanguage() { return AndroidStatsHelpers::getLocale
|
|||
String SystemStats::getUserRegion() { return AndroidStatsHelpers::getLocaleValue (true); }
|
||||
String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getUserRegion(); }
|
||||
|
||||
String SystemStats::getUniqueDeviceID()
|
||||
{
|
||||
auto id = String ((uint64_t) AndroidStatsHelpers::getAndroidID().hashCode64());
|
||||
|
||||
// Please tell someone at JUCE if this occurs
|
||||
jassert (id.isNotEmpty());
|
||||
return id;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void CPUInformation::initialise() noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -304,6 +304,64 @@ void CPUInformation::initialise() noexcept
|
|||
#endif
|
||||
}
|
||||
|
||||
String SystemStats::getUniqueDeviceID()
|
||||
{
|
||||
static const auto deviceId = []()
|
||||
{
|
||||
const auto call = [] (auto command) -> String
|
||||
{
|
||||
ChildProcess proc;
|
||||
|
||||
if (proc.start (command, ChildProcess::wantStdOut))
|
||||
return proc.readAllProcessOutput();
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
auto data = call ("cat /sys/class/dmi/id/board_serial");
|
||||
|
||||
// 'board_serial' is enough on its own, fallback to bios stuff if we can't find it.
|
||||
if (data.isEmpty())
|
||||
{
|
||||
data = call ("cat /sys/class/dmi/id/bios_date")
|
||||
+ call ("cat /sys/class/dmi/id/bios_release")
|
||||
+ call ("cat /sys/class/dmi/id/bios_vendor")
|
||||
+ call ("cat /sys/class/dmi/id/bios_version");
|
||||
}
|
||||
|
||||
auto cpuData = call ("lscpu");
|
||||
|
||||
if (cpuData.isNotEmpty())
|
||||
{
|
||||
auto getCpuInfo = [&cpuData] (auto key) -> String
|
||||
{
|
||||
auto index = cpuData.indexOf (key);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
auto start = cpuData.indexOf (index, ":");
|
||||
auto end = cpuData.indexOf (start, "\n");
|
||||
|
||||
return cpuData.substring (start + 1, end).trim();
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
data += getCpuInfo ("CPU family:");
|
||||
data += getCpuInfo ("Model:");
|
||||
data += getCpuInfo ("Model name:");
|
||||
data += getCpuInfo ("Vendor ID:");
|
||||
}
|
||||
|
||||
return String ((uint64_t) data.hashCode64());
|
||||
}();
|
||||
|
||||
// Please tell someone at JUCE if this occurs
|
||||
jassert (deviceId.isNotEmpty());
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
uint32 juce_millisecondsSinceStartup() noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -351,4 +351,34 @@ int SystemStats::getPageSize()
|
|||
return (int) NSPageSize();
|
||||
}
|
||||
|
||||
String SystemStats::getUniqueDeviceID()
|
||||
{
|
||||
static const auto deviceId = []
|
||||
{
|
||||
ChildProcess proc;
|
||||
|
||||
if (proc.start ("ioreg -rd1 -c IOPlatformExpertDevice", ChildProcess::wantStdOut))
|
||||
{
|
||||
constexpr const char key[] = "\"IOPlatformUUID\"";
|
||||
constexpr const auto keyLen = (int) sizeof (key);
|
||||
|
||||
auto output = proc.readAllProcessOutput();
|
||||
auto index = output.indexOf (key);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
auto start = output.indexOf (index + keyLen, "\"");
|
||||
auto end = output.indexOf (start + 1, "\"");
|
||||
return output.substring (start + 1, end).replace("-", "");
|
||||
}
|
||||
}
|
||||
|
||||
return String();
|
||||
}();
|
||||
|
||||
// Please tell someone at JUCE if this occurs
|
||||
jassert (deviceId.isNotEmpty());
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -592,4 +592,33 @@ String SystemStats::getDisplayLanguage()
|
|||
return languagesBuffer.data();
|
||||
}
|
||||
|
||||
String SystemStats::getUniqueDeviceID()
|
||||
{
|
||||
#define PROVIDER(string) (DWORD) (string[0] << 24 | string[1] << 16 | string[2] << 8 | string[3])
|
||||
|
||||
auto bufLen = GetSystemFirmwareTable (PROVIDER ("RSMB"), PROVIDER ("RSDT"), nullptr, 0);
|
||||
|
||||
if (bufLen > 0)
|
||||
{
|
||||
HeapBlock<uint8_t> buffer { bufLen };
|
||||
GetSystemFirmwareTable (PROVIDER ("RSMB"), PROVIDER ("RSDT"), (void*) buffer.getData(), bufLen);
|
||||
|
||||
return [&]
|
||||
{
|
||||
uint64_t hash = 0;
|
||||
const auto start = buffer.getData();
|
||||
const auto end = start + jmin (1024, (int) bufLen);
|
||||
|
||||
for (auto dataPtr = start; dataPtr != end; ++dataPtr)
|
||||
hash = hash * (uint64_t) 101 + *dataPtr;
|
||||
|
||||
return String (hash);
|
||||
}();
|
||||
}
|
||||
|
||||
// Please tell someone at JUCE if this occurs
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -253,4 +253,25 @@ bool SystemStats::isRunningInAppExtensionSandbox() noexcept
|
|||
#endif
|
||||
}
|
||||
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
class UniqueHardwareIDTest : public UnitTest
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
UniqueHardwareIDTest() : UnitTest ("UniqueHardwareID", UnitTestCategories::analytics) {}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("getUniqueDeviceID returns usable data.");
|
||||
{
|
||||
expect (SystemStats::getUniqueDeviceID().isNotEmpty());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static UniqueHardwareIDTest uniqueHardwareIDTest;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
|
|
@ -145,8 +145,17 @@ public:
|
|||
The first choice for an ID is a filesystem ID for the user's home folder or
|
||||
windows directory. If that fails then this function returns the MAC addresses.
|
||||
*/
|
||||
[[deprecated ("The identifiers produced by this function are not reliable. Use getUniqueDeviceID() instead.")]]
|
||||
static StringArray getDeviceIdentifiers();
|
||||
|
||||
/** This method returns a machine unique ID unaffected by storage or peripheral
|
||||
changes.
|
||||
|
||||
This ID will be invalidated by changes to the motherboard and CPU on non-mobile
|
||||
platforms, or resetting an Android device.
|
||||
*/
|
||||
static String getUniqueDeviceID();
|
||||
|
||||
//==============================================================================
|
||||
// CPU and memory information..
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ namespace UnitTestCategories
|
|||
static const String cryptography { "Cryptography" };
|
||||
static const String dsp { "DSP" };
|
||||
static const String files { "Files" };
|
||||
static const String function { "Function" };
|
||||
static const String graphics { "Graphics" };
|
||||
static const String gui { "GUI" };
|
||||
static const String json { "JSON" };
|
||||
|
|
|
|||
|
|
@ -314,6 +314,14 @@ void OnlineUnlockStatus::MachineIDUtilities::addMACAddressesToList (StringArray&
|
|||
ids.add (getEncodedIDString (address.toString()));
|
||||
}
|
||||
|
||||
String OnlineUnlockStatus::MachineIDUtilities::getUniqueMachineID()
|
||||
{
|
||||
return getEncodedIDString (SystemStats::getUniqueDeviceID());
|
||||
}
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
|
||||
|
||||
StringArray OnlineUnlockStatus::MachineIDUtilities::getLocalMachineIDs()
|
||||
{
|
||||
auto identifiers = SystemStats::getDeviceIdentifiers();
|
||||
|
|
@ -329,6 +337,9 @@ StringArray OnlineUnlockStatus::getLocalMachineIDs()
|
|||
return MachineIDUtilities::getLocalMachineIDs();
|
||||
}
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
void OnlineUnlockStatus::userCancelled()
|
||||
{
|
||||
}
|
||||
|
|
@ -378,22 +389,19 @@ bool OnlineUnlockStatus::applyKeyFile (String keyFileContent)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool canConnectToWebsite (const URL& url)
|
||||
{
|
||||
return url.createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
|
||||
.withConnectionTimeoutMs (2000)) != nullptr;
|
||||
}
|
||||
|
||||
static bool areMajorWebsitesAvailable()
|
||||
{
|
||||
const char* urlsToTry[] = { "http://google.com", "http://bing.com", "http://amazon.com",
|
||||
"https://google.com", "https://bing.com", "https://amazon.com", nullptr};
|
||||
static constexpr const char* const urlsToTry[] = { "http://google.com", "http://bing.com", "http://amazon.com",
|
||||
"https://google.com", "https://bing.com", "https://amazon.com" };
|
||||
const auto canConnectToWebsite = [] (auto url)
|
||||
{
|
||||
return URL (url).createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
|
||||
.withConnectionTimeoutMs (2000)) != nullptr;
|
||||
};
|
||||
|
||||
for (const char** url = urlsToTry; *url != nullptr; ++url)
|
||||
if (canConnectToWebsite (URL (*url)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return std::any_of (std::begin (urlsToTry),
|
||||
std::end (urlsToTry),
|
||||
canConnectToWebsite);
|
||||
}
|
||||
|
||||
OnlineUnlockStatus::UnlockResult OnlineUnlockStatus::handleXmlReply (XmlElement xml)
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ public:
|
|||
/** Utility function that you may want to use in your machine-ID generation code.
|
||||
This adds some ID strings to the given array which represent each MAC address of the machine.
|
||||
*/
|
||||
[[deprecated ("MAC addresses are no longer reliable methods of ID generation. You should use getUniqueMachineID() instead, You can still get a list of this device's MAC addresses with MACAddress::findAllAddresses().")]]
|
||||
static void addMACAddressesToList (StringArray& result);
|
||||
|
||||
/** This method calculates some machine IDs based on things like network
|
||||
|
|
@ -259,7 +260,14 @@ public:
|
|||
registration on machines which have had hardware added/removed
|
||||
since the product was first registered.
|
||||
*/
|
||||
[[deprecated ("The identifiers generated by this function are no longer reliable. Use getUniqueMachineID() instead.")]]
|
||||
static StringArray getLocalMachineIDs();
|
||||
|
||||
/** Returns an encoded unique machine ID.
|
||||
|
||||
@see SystemStats::getUniqueDeviceID
|
||||
*/
|
||||
static String getUniqueMachineID();
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue