summaryrefslogtreecommitdiffstats
path: root/base/ios
diff options
context:
space:
mode:
authorchenyu@chromium.org <chenyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-07 11:03:11 +0000
committerchenyu@chromium.org <chenyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-07 11:03:11 +0000
commite16e873805f04e74f89833dbb5a500f55fde04ba (patch)
tree6b2ef17a08f84d673353e24d7825ad7d217deae6 /base/ios
parentd2cdf34bb789c9194e053509bae1c3df66ab8c33 (diff)
downloadchromium_src-e16e873805f04e74f89833dbb5a500f55fde04ba.zip
chromium_src-e16e873805f04e74f89833dbb5a500f55fde04ba.tar.gz
chromium_src-e16e873805f04e74f89833dbb5a500f55fde04ba.tar.bz2
Implements iOS device util methods.
Utility methods in this package provides IOS device-specific information. BUG=NONE TEST=NONE Review URL: https://chromiumcodereview.appspot.com/10818023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150324 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/ios')
-rw-r--r--base/ios/device_util.h65
-rw-r--r--base/ios/device_util.mm126
-rw-r--r--base/ios/device_util_unittest.mm53
3 files changed, 244 insertions, 0 deletions
diff --git a/base/ios/device_util.h b/base/ios/device_util.h
new file mode 100644
index 0000000..fe4833d
--- /dev/null
+++ b/base/ios/device_util.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_IOS_DEVICE_UTIL_H_
+#define BASE_IOS_DEVICE_UTIL_H_
+
+#include <string>
+
+namespace ios {
+namespace device_util {
+
+// Returns the hardware version of the device the app is running on.
+//
+// The returned string is the string returned by sysctlbyname() with name
+// "hw.machine". Possible (known) values include:
+//
+// iPhone1,1 -> iPhone 1G
+// iPhone1,2 -> iPhone 3G
+// iPhone2,1 -> iPhone 3GS
+// iPhone3,1 -> iPhone 4/AT&T
+// iPhone3,2 -> iPhone 4/Other Carrier?
+// iPhone3,3 -> iPhone 4/Other Carrier?
+// iPhone4,1 -> iPhone 4S
+//
+// iPod1,1 -> iPod touch 1G
+// iPod2,1 -> iPod touch 2G
+// iPod2,2 -> ?
+// iPod3,1 -> iPod touch 3G
+// iPod4,1 -> iPod touch 4G
+// iPod5,1 -> ?
+//
+// iPad1,1 -> iPad 1G, WiFi
+// iPad1,? -> iPad 1G, 3G <- needs 3G owner to test
+// iPad2,1 -> iPad 2G, WiFi
+//
+// AppleTV2,1 -> AppleTV 2
+//
+// i386 -> Simulator
+// x86_64 -> Simulator
+std::string GetPlatform();
+
+// Returns true if the application is running on a high-ram device. (>=250M).
+bool IsRunningOnHighRamDevice();
+
+// Returns true if the device has only one core.
+bool IsSingleCoreDevice();
+
+// Returns the MAC address of the interface with name |interface_name|.
+std::string GetMacAddress(const std::string& interface_name);
+
+// Returns a random UUID.
+std::string GetRandomId();
+
+// Returns an identifier for the device, using the given |salt|. A global
+// identifier is generated the first time this method is called, and the salt
+// is used to be able to generate distinct identifiers for the same device. If
+// |salt| is NULL, a default value is used. Unless you are using this value for
+// something that should be anonymous, you should probably pass NULL.
+std::string GetDeviceIdentifier(const char* salt);
+
+} // namespace device_util
+} // namespace ios
+
+#endif // BASE_IOS_DEVICE_UTIL_H_
diff --git a/base/ios/device_util.mm b/base/ios/device_util.mm
new file mode 100644
index 0000000..1d16de4b
--- /dev/null
+++ b/base/ios/device_util.mm
@@ -0,0 +1,126 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/ios/device_util.h"
+
+#include <CommonCrypto/CommonDigest.h>
+#import <Foundation/Foundation.h>
+
+#include <ifaddrs.h>
+#include <net/if_dl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/sys_string_conversions.h"
+
+namespace {
+
+// Client ID key in the user preferences.
+NSString* const kClientIdPreferenceKey = @"ChromiumClientID";
+// Default salt for device ids.
+const char kDefaultSalt[] = "Salt";
+
+} // namespace
+
+namespace ios {
+namespace device_util {
+
+std::string GetPlatform() {
+ std::string platform;
+ size_t size = 0;
+ sysctlbyname("hw.machine", NULL, &size, NULL, 0);
+ sysctlbyname("hw.machine", WriteInto(&platform, size), &size, NULL, 0);
+ return platform;
+}
+
+bool IsRunningOnHighRamDevice() {
+ uint64_t memory_size = 0;
+ size_t size = sizeof(memory_size);
+ if (sysctlbyname("hw.memsize", &memory_size, &size, NULL, 0) == 0) {
+ // Anything >= 250M, call high ram.
+ return memory_size >= 250 * 1024 * 1024;
+ }
+ return false;
+}
+
+bool IsSingleCoreDevice() {
+ uint64_t cpu_number = 0;
+ size_t sizes = sizeof(cpu_number);
+ sysctlbyname("hw.physicalcpu", &cpu_number, &sizes, NULL, 0);
+ return cpu_number == 1;
+}
+
+std::string GetMacAddress(const std::string& interface_name) {
+ std::string mac_string;
+ struct ifaddrs* addresses;
+ if (getifaddrs(&addresses) == 0) {
+ for (struct ifaddrs* address = addresses; address;
+ address = address->ifa_next) {
+ if ((address->ifa_addr->sa_family == AF_LINK) &&
+ strcmp(interface_name.c_str(), address->ifa_name) == 0) {
+ const struct sockaddr_dl* found_address_struct =
+ reinterpret_cast<const struct sockaddr_dl*>(address->ifa_addr);
+
+ // |found_address_struct->sdl_data| contains the interface name followed
+ // by the interface address. The address part can be accessed based on
+ // the length of the name, that is, |found_address_struct->sdl_nlen|.
+ const unsigned char* found_address =
+ reinterpret_cast<const unsigned char*>(
+ &found_address_struct->sdl_data[
+ found_address_struct->sdl_nlen]);
+
+ int found_address_length = found_address_struct->sdl_alen;
+ for (int i = 0; i < found_address_length; ++i) {
+ if (i != 0)
+ mac_string.push_back(':');
+ base::StringAppendF(&mac_string, "%02X", found_address[i]);
+ }
+ break;
+ }
+ }
+ freeifaddrs(addresses);
+ }
+ return mac_string;
+}
+
+std::string GetRandomId() {
+ base::mac::ScopedCFTypeRef<CFUUIDRef>
+ uuid_object(CFUUIDCreate(kCFAllocatorDefault));
+ base::mac::ScopedCFTypeRef<CFStringRef> uuid_string(
+ CFUUIDCreateString(kCFAllocatorDefault, uuid_object));
+ return base::SysCFStringRefToUTF8(uuid_string);
+}
+
+std::string GetDeviceIdentifier(const char* salt) {
+ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+ NSString* client_id = [defaults stringForKey:kClientIdPreferenceKey];
+
+ if (!client_id) {
+ client_id = base::SysUTF8ToNSString(GetRandomId());
+ [defaults setObject:client_id forKey:kClientIdPreferenceKey];
+ [defaults synchronize];
+ }
+
+ NSData* hash_data = [[NSString stringWithFormat:@"%@%s", client_id,
+ salt ? salt : kDefaultSalt] dataUsingEncoding:NSUTF8StringEncoding];
+
+ unsigned char hash[CC_SHA256_DIGEST_LENGTH];
+ CC_SHA256([hash_data bytes], [hash_data length], hash);
+ CFUUIDBytes* uuid_bytes = reinterpret_cast<CFUUIDBytes*>(hash);
+
+ base::mac::ScopedCFTypeRef<CFUUIDRef>
+ uuid_object(CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, *uuid_bytes));
+ base::mac::ScopedCFTypeRef<CFStringRef> device_id(
+ CFUUIDCreateString(kCFAllocatorDefault, uuid_object));
+ return base::SysCFStringRefToUTF8(device_id);
+}
+
+} // namespace device_util
+} // namespace ios
diff --git a/base/ios/device_util_unittest.mm b/base/ios/device_util_unittest.mm
new file mode 100644
index 0000000..34c2d9c
--- /dev/null
+++ b/base/ios/device_util_unittest.mm
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Foundation/Foundation.h>
+
+#include "base/ios/device_util.h"
+#include "base/sys_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+#include "testing/platform_test.h"
+
+namespace {
+// The behavior of most of these utility functions depends on what they are run
+// on, so there is not much to unittest them. The APIs are run to make sure they
+// don't choke. Additional checks are added for particular APIs when needed.
+
+typedef PlatformTest DeviceUtilTest;
+
+TEST_F(DeviceUtilTest, GetPlatform) {
+ GTEST_ASSERT_GT(ios::device_util::GetPlatform().length(), 0U);
+}
+
+TEST_F(DeviceUtilTest, IsRunningOnHighRamDevice) {
+ ios::device_util::IsRunningOnHighRamDevice();
+}
+
+TEST_F(DeviceUtilTest, IsSingleCoreDevice) {
+ ios::device_util::IsSingleCoreDevice();
+}
+
+TEST_F(DeviceUtilTest, GetMacAddress) {
+ GTEST_ASSERT_GT(ios::device_util::GetMacAddress("en0").length(), 0U);
+}
+
+TEST_F(DeviceUtilTest, GetRandomId) {
+ GTEST_ASSERT_GT(ios::device_util::GetRandomId().length(), 0U);
+}
+
+TEST_F(DeviceUtilTest, GetDeviceIdentifier) {
+ std::string default_id = ios::device_util::GetDeviceIdentifier(NULL);
+ std::string other_id = ios::device_util::GetDeviceIdentifier("ForTest");
+ EXPECT_NE(default_id, other_id);
+
+ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+ [defaults removeObjectForKey:@"ChromiumClientID"];
+ [defaults synchronize];
+
+ std::string new_default_id = ios::device_util::GetDeviceIdentifier(NULL);
+ EXPECT_NE(default_id, new_default_id);
+}
+
+} // namespace