diff options
author | chenyu@chromium.org <chenyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-07 11:03:11 +0000 |
---|---|---|
committer | chenyu@chromium.org <chenyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-07 11:03:11 +0000 |
commit | e16e873805f04e74f89833dbb5a500f55fde04ba (patch) | |
tree | 6b2ef17a08f84d673353e24d7825ad7d217deae6 /base/ios | |
parent | d2cdf34bb789c9194e053509bae1c3df66ab8c33 (diff) | |
download | chromium_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.h | 65 | ||||
-rw-r--r-- | base/ios/device_util.mm | 126 | ||||
-rw-r--r-- | base/ios/device_util_unittest.mm | 53 |
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 |