diff options
author | michaelbai@google.com <michaelbai@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-21 22:34:50 +0000 |
---|---|---|
committer | michaelbai@google.com <michaelbai@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-21 22:34:50 +0000 |
commit | f7d6997f6253e4c7645859757bc824c4164a9a7e (patch) | |
tree | 3183103533b527bb8b436aed5412b7bf00207e94 | |
parent | 559c4e3eee40f9f3a127ba792a2ef0bcd217b543 (diff) | |
download | chromium_src-f7d6997f6253e4c7645859757bc824c4164a9a7e.zip chromium_src-f7d6997f6253e4c7645859757bc824c4164a9a7e.tar.gz chromium_src-f7d6997f6253e4c7645859757bc824c4164a9a7e.tar.bz2 |
Upstream android file related code.
Implemented file related features
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/7184032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89914 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/DEPS | 1 | ||||
-rw-r--r-- | base/base_paths_android.cc | 59 | ||||
-rw-r--r-- | base/file_util_android.cc | 16 | ||||
-rw-r--r-- | base/file_util_posix.cc | 20 | ||||
-rw-r--r-- | base/os_compat_android.cc | 18 | ||||
-rw-r--r-- | base/os_compat_android.h | 26 | ||||
-rw-r--r-- | base/path_service.cc | 18 | ||||
-rw-r--r-- | base/platform_file_posix.cc | 4 | ||||
-rw-r--r-- | base/shared_memory_android.cc | 53 | ||||
-rw-r--r-- | base/shared_memory_posix.cc | 28 | ||||
-rw-r--r-- | base/sys_info_posix.cc | 10 |
11 files changed, 247 insertions, 6 deletions
@@ -1,4 +1,5 @@ include_rules = [ + "+third_party/ashmem", "+third_party/apple_apsl", "+third_party/libevent", "+third_party/dmg_fp", diff --git a/base/base_paths_android.cc b/base/base_paths_android.cc new file mode 100644 index 0000000..5a03cc0 --- /dev/null +++ b/base/base_paths_android.cc @@ -0,0 +1,59 @@ +// Copyright (c) 2011 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/base_paths.h" + +#include <unistd.h> + +#include "base/logging.h" +#include "base/android_os.h" + +namespace base { + +const char kSelfExe[] = "/proc/self/exe"; + +bool PathProviderAndroid(int key, FilePath* result) { + switch (key) { + case base::FILE_EXE: { + char bin_dir[PATH_MAX + 1]; + int bin_dir_size = readlink(kSelfExe, bin_dir, PATH_MAX); + if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) { + NOTREACHED() << "Unable to resolve " << kSelfExe << "."; + return false; + } + bin_dir[bin_dir_size] = 0; + *result = FilePath(bin_dir); + return true; + } + case base::FILE_MODULE: + // TODO(port): Find out whether we can use dladdr to implement this, and + // then use DIR_MODULE's default implementation in base_file.cc. + NOTIMPLEMENTED(); + return false; + case base::DIR_MODULE: { + AndroidOS* aos = AndroidOS::GetSharedInstance(); + DCHECK(aos); + *result = aos->GetLibDirectory(); + return true; + } + case base::DIR_SOURCE_ROOT: + // This const is only used for tests. Files in this directory are pushed + // to the device via test script. + *result = FilePath(FILE_PATH_LITERAL("/data/local/tmp/")); + return true; + case base::DIR_CACHE: { + AndroidOS* aos = AndroidOS::GetSharedInstance(); + DCHECK(aos); + *result = aos->GetCacheDirectory(); + return true; + } + default: + // Note: the path system expects this function to override the default + // behavior. So no need to log an error if we don't support a given + // path. The system will just use the default. + return false; + } +} + +} // namespace base diff --git a/base/file_util_android.cc b/base/file_util_android.cc new file mode 100644 index 0000000..eff3a46 --- /dev/null +++ b/base/file_util_android.cc @@ -0,0 +1,16 @@ +// Copyright (c) 2011 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/file_util.h" + +#include "base/file_path.h" + +namespace file_util { + +bool GetShmemTempDir(FilePath* path) { + *path = FilePath("/data/local/tmp"); + return true; +} + +} // namespace file_util diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 89487d4..2e7c91e 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -25,7 +25,7 @@ #if defined(OS_MACOSX) #include <AvailabilityMacros.h> #include "base/mac/foundation_util.h" -#else +#elif !defined(OS_ANDROID) #include <glib.h> #endif @@ -44,6 +44,10 @@ #include "base/time.h" #include "base/utf_string_conversions.h" +#if defined(OS_ANDROID) +#include "base/os_compat_android.h" +#endif + namespace file_util { namespace { @@ -106,7 +110,7 @@ int CountFilesCreatedAfter(const FilePath& path, DIR* dir = opendir(path.value().c_str()); if (dir) { #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \ - !defined(OS_OPENBSD) && !defined(OS_SOLARIS) + !defined(OS_OPENBSD) && !defined(OS_SOLARIS) && !defined(OS_ANDROID) #error Port warning: depending on the definition of struct dirent, \ additional space for pathname may be needed #endif @@ -739,7 +743,7 @@ bool FileEnumerator::ReadDirectory(std::vector<DirectoryEntryInfo>* entries, return false; #if !defined(OS_LINUX) && !defined(OS_MACOSX) && !defined(OS_FREEBSD) && \ - !defined(OS_OPENBSD) && !defined(OS_SOLARIS) + !defined(OS_OPENBSD) && !defined(OS_SOLARIS) && !defined(OS_ANDROID) #error Port warning: depending on the definition of struct dirent, \ additional space for pathname may be needed #endif @@ -839,26 +843,36 @@ bool GetTempDir(FilePath* path) { if (tmp) *path = FilePath(tmp); else +#if defined(OS_ANDROID) + *path = FilePath("/data/local/tmp"); +#else *path = FilePath("/tmp"); +#endif return true; } +#if !defined(OS_ANDROID) bool GetShmemTempDir(FilePath* path) { *path = FilePath("/dev/shm"); return true; } +#endif FilePath GetHomeDir() { const char* home_dir = getenv("HOME"); if (home_dir && home_dir[0]) return FilePath(home_dir); +#if defined(OS_ANDROID) + LOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; +#else // g_get_home_dir calls getpwent, which can fall through to LDAP calls. base::ThreadRestrictions::AssertIOAllowed(); home_dir = g_get_home_dir(); if (home_dir && home_dir[0]) return FilePath(home_dir); +#endif FilePath rv; if (file_util::GetTempDir(&rv)) diff --git a/base/os_compat_android.cc b/base/os_compat_android.cc new file mode 100644 index 0000000..5c4f2ab --- /dev/null +++ b/base/os_compat_android.cc @@ -0,0 +1,18 @@ +// Copyright (c) 2011 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/os_compat_android.h" + +#include "base/string_util.h" + +// There is no futimes() avaiable in Bionic, so we provide our own +// implementation until it is there. +extern "C" { + +int futimes(int fd, const struct timeval tv[2]) { + const std::string fd_path = StringPrintf("/proc/self/fd/%d", fd); + return utimes(fd_path.c_str(), tv); +} + +} // extern "C" diff --git a/base/os_compat_android.h b/base/os_compat_android.h new file mode 100644 index 0000000..fb69efa --- /dev/null +++ b/base/os_compat_android.h @@ -0,0 +1,26 @@ +// Copyright (c) 2011 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_OS_COMPAT_ANDROID_H_ +#define BASE_OS_COMPAT_ANDROID_H_ +#pragma once + +#include <fcntl.h> +#include <sys/types.h> +#include <utime.h> + +// Not implemented in Bionic. See platform_file_android.cc. +extern "C" int futimes(int fd, const struct timeval tv[2]); + +// The prototype of mkdtemp is missing. +extern "C" char* mkdtemp(char* path); + +// The lockf() function is not available on Android; we translate to flock(). +#define F_LOCK LOCK_EX +#define F_ULOCK LOCK_UN +inline int lockf(int fd, int cmd, off_t ignored_len) { + return flock(fd, cmd); +} + +#endif // BASE_OS_COMPAT_ANDROID_H_ diff --git a/base/path_service.cc b/base/path_service.cc index e72ae7d..21eea9c 100644 --- a/base/path_service.cc +++ b/base/path_service.cc @@ -23,6 +23,8 @@ namespace base { bool PathProviderWin(int key, FilePath* result); #elif defined(OS_MACOSX) bool PathProviderMac(int key, FilePath* result); +#elif defined(OS_ANDROID) + bool PathProviderAndroid(int key, FilePath* result); #elif defined(OS_POSIX) bool PathProviderPosix(int key, FilePath* result); #endif @@ -78,7 +80,19 @@ static Provider base_provider_mac = { }; #endif -#if defined(OS_POSIX) && !defined(OS_MACOSX) +#if defined(OS_ANDROID) +static Provider base_provider_android = { + base::PathProviderAndroid, + &base_provider, +#ifndef NDEBUG + 0, + 0, +#endif + true +}; +#endif + +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) static Provider base_provider_posix = { base::PathProviderPosix, &base_provider, @@ -102,6 +116,8 @@ struct PathData { providers = &base_provider_win; #elif defined(OS_MACOSX) providers = &base_provider_mac; +#elif defined(OS_ANDROID) + providers = &base_provider_android; #elif defined(OS_POSIX) providers = &base_provider_posix; #endif diff --git a/base/platform_file_posix.cc b/base/platform_file_posix.cc index 26c52d4..ab33448 100644 --- a/base/platform_file_posix.cc +++ b/base/platform_file_posix.cc @@ -14,6 +14,10 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" +#if defined(OS_ANDROID) +#include "base/os_compat_android.h" +#endif + namespace base { #if defined(OS_OPENBSD) || defined(OS_FREEBSD) || \ diff --git a/base/shared_memory_android.cc b/base/shared_memory_android.cc new file mode 100644 index 0000000..c2f3315 --- /dev/null +++ b/base/shared_memory_android.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2011 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/shared_memory.h" + +#include <sys/mman.h> + +#include "base/logging.h" +#include "third_party/ashmem/ashmem.h" + +namespace base { + +// For Android, we use ashmem to implement SharedMemory. ashmem_create_region +// will automatically pin the region. We never explicitly call pin/unpin. When +// all the file descriptors from different processes associated with the region +// are closed, the memory buffer will go away. + +bool SharedMemory::CreateNamed(const std::string& name, + bool open_existing, uint32 size) { + DCHECK_EQ(-1, mapped_file_ ); + + // "name" is just a label in ashmem. It is visible in /proc/pid/maps. + mapped_file_ = ashmem_create_region(name.c_str(), size); + if (-1 == mapped_file_) { + DLOG(ERROR) << "Shared memory creation failed"; + return false; + } + + int err = ashmem_set_prot_region(mapped_file_, + PROT_READ | PROT_WRITE | PROT_EXEC); + if (err < 0) { + DLOG(ERROR) << "Error " << err << " when setting protection of ashmem"; + return false; + } + created_size_ = size; + + return true; +} + +bool SharedMemory::Delete(const std::string& name) { + // ashmem doesn't support name mapping + NOTIMPLEMENTED(); + return false; +} + +bool SharedMemory::Open(const std::string& name, bool read_only) { + // ashmem doesn't support name mapping + NOTIMPLEMENTED(); + return false; +} + +} // namespace base diff --git a/base/shared_memory_posix.cc b/base/shared_memory_posix.cc index 7a238ed..1580487 100644 --- a/base/shared_memory_posix.cc +++ b/base/shared_memory_posix.cc @@ -21,12 +21,19 @@ #include "base/mac/foundation_util.h" #endif // OS_MACOSX +#if defined(OS_ANDROID) +#include "base/os_compat_android.h" +#include "third_party/ashmem/ashmem.h" +#endif + namespace base { namespace { + // Paranoia. Semaphores and shared memory segments should live in different // namespaces, but who knows what's out there. const char kSemaphoreSuffix[] = "-sem"; + } SharedMemory::SharedMemory() @@ -95,6 +102,7 @@ bool SharedMemory::CreateAnonymous(uint32 size) { return CreateNamed("", false, size); } +#if !defined(OS_ANDROID) // Chromium mostly only uses the unique/private shmem as specified by // "name == L"". The exception is in the StatsTable. // TODO(jrg): there is no way to "clean up" all unused named shmem if @@ -201,10 +209,28 @@ bool SharedMemory::Open(const std::string& name, bool read_only) { return PrepareMapFile(fp); } +#endif // !defined(OS_ANDROID) + bool SharedMemory::Map(uint32 bytes) { if (mapped_file_ == -1) return false; +#if defined(OS_ANDROID) + if (bytes == 0) { + int ashmem_bytes = ashmem_get_size_region(); + if (ashmem_bytes < 0) + return false; + + DCHECK_GE(static_cast<uint32>(ashmem_bytes), bytes); + // The caller wants to determine the map region size from ashmem. + bytes = ashmem_bytes; + // TODO(port): we set the created size here so that it is available in + // transport_dib_android.cc. We should use ashmem_get_size_region() + // in transport_dib_android.cc. + created_size_ = bytes; + } +#endif + memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), MAP_SHARED, mapped_file_, 0); @@ -248,6 +274,7 @@ void SharedMemory::Unlock() { LockOrUnlockCommon(F_ULOCK); } +#if !defined(OS_ANDROID) bool SharedMemory::PrepareMapFile(FILE *fp) { DCHECK_EQ(-1, mapped_file_); if (fp == NULL) return false; @@ -276,6 +303,7 @@ bool SharedMemory::PrepareMapFile(FILE *fp) { return true; } +#endif // For the given shmem named |mem_name|, return a filename to mmap() // (and possibly create). Modifies |filename|. Return false on diff --git a/base/sys_info_posix.cc b/base/sys_info_posix.cc index d635eb4..a6b88a8 100644 --- a/base/sys_info_posix.cc +++ b/base/sys_info_posix.cc @@ -7,8 +7,6 @@ #include <errno.h> #include <string.h> #include <sys/param.h> -#include <sys/statvfs.h> -#include <sys/sysctl.h> #include <sys/utsname.h> #include <unistd.h> @@ -17,6 +15,14 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" +#if defined(OS_ANDROID) +#include <sys/vfs.h> +#define statvfs statfs // Android uses a statvfs-like statfs struct and call. +#else +#include <sys/statvfs.h> +#include <sys/sysctl.h> +#endif + namespace base { #if !defined(OS_OPENBSD) |