summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/SharedPreferencesImpl.java12
-rw-r--r--core/java/android/app/backup/BackupAgent.java15
-rw-r--r--core/java/android/app/backup/FullBackup.java7
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java12
-rw-r--r--core/java/android/content/pm/PackageManager.java19
-rw-r--r--core/java/android/ddm/DdmHandleHeap.java2
-rw-r--r--core/java/android/net/LinkAddress.java14
-rw-r--r--core/java/android/net/LocalSocketImpl.java10
-rw-r--r--core/java/android/net/http/CertificateChainValidator.java11
-rw-r--r--core/java/android/net/http/X509TrustManagerExtensions.java3
-rw-r--r--core/java/android/os/Build.java9
-rw-r--r--core/java/android/os/CommonClock.java2
-rw-r--r--core/java/android/os/CommonTimeUtils.java2
-rw-r--r--core/java/android/os/FileUtils.java16
-rw-r--r--core/java/android/os/MemoryFile.java9
-rw-r--r--core/java/android/os/ParcelFileDescriptor.java47
-rw-r--r--core/java/android/os/Process.java334
-rw-r--r--core/java/android/os/StatFs.java8
-rw-r--r--core/java/android/provider/DocumentsContract.java10
-rw-r--r--core/java/android/util/EventLog.java24
-rw-r--r--core/java/android/util/Log.java1
-rw-r--r--core/java/android/view/LayoutInflater.java1
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--core/java/android/webkit/ClientCertRequest.java80
-rw-r--r--core/java/android/webkit/WebViewClient.java24
-rw-r--r--core/java/android/widget/NumberPicker.java11
-rw-r--r--core/java/android/widget/TextView.java8
27 files changed, 484 insertions, 211 deletions
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index a292ecb..a8896c2 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -19,6 +19,9 @@ package android.app;
import android.content.SharedPreferences;
import android.os.FileUtils;
import android.os.Looper;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStat;
import android.util.Log;
import com.google.android.collect.Maps;
@@ -44,10 +47,7 @@ import java.util.WeakHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
-import libcore.io.Libcore;
-import libcore.io.StructStat;
final class SharedPreferencesImpl implements SharedPreferences {
private static final String TAG = "SharedPreferencesImpl";
@@ -111,7 +111,7 @@ final class SharedPreferencesImpl implements SharedPreferences {
Map map = null;
StructStat stat = null;
try {
- stat = Libcore.os.stat(mFile.getPath());
+ stat = Os.stat(mFile.getPath());
if (mFile.canRead()) {
BufferedInputStream str = null;
try {
@@ -173,7 +173,7 @@ final class SharedPreferencesImpl implements SharedPreferences {
* violation, but we explicitly want this one.
*/
BlockGuard.getThreadPolicy().onReadFromDisk();
- stat = Libcore.os.stat(mFile.getPath());
+ stat = Os.stat(mFile.getPath());
} catch (ErrnoException e) {
return true;
}
@@ -600,7 +600,7 @@ final class SharedPreferencesImpl implements SharedPreferences {
str.close();
ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
try {
- final StructStat stat = Libcore.os.stat(mFile.getPath());
+ final StructStat stat = Os.stat(mFile.getPath());
synchronized (this) {
mStatTimestamp = stat.st_mtime;
mStatSize = stat.st_size;
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 67c772b..70a3797 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -29,6 +29,10 @@ import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
import android.util.Log;
import java.io.File;
@@ -38,11 +42,6 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.concurrent.CountDownLatch;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.OsConstants;
-import libcore.io.StructStat;
-
/**
* Provides the central interface between an
* application and Android's data backup infrastructure. An application that wishes
@@ -191,7 +190,7 @@ public abstract class BackupAgent extends ContextWrapper {
* the key supplied as part of the entity. Writing an entity with a negative
* data size instructs the transport to delete whatever entity currently exists
* under that key from the remote data set.
- *
+ *
* @param oldState An open, read-only ParcelFileDescriptor pointing to the
* last backup state provided by the application. May be
* <code>null</code>, in which case no prior state is being
@@ -222,7 +221,7 @@ public abstract class BackupAgent extends ContextWrapper {
* onRestore() throws an exception, the OS will assume that the
* application's data may now be in an incoherent state, and will clear it
* before proceeding.
- *
+ *
* @param data A structured wrapper around an open, read-only
* file descriptor pointing to a full snapshot of the
* application's data. The application should consume every
@@ -412,7 +411,7 @@ public abstract class BackupAgent extends ContextWrapper {
}
// If it's a directory, enqueue its contents for scanning.
- StructStat stat = Libcore.os.lstat(filePath);
+ StructStat stat = Os.lstat(filePath);
if (OsConstants.S_ISLNK(stat.st_mode)) {
if (DEBUG) Log.i(TAG, "Symlink (skipping)!: " + file);
continue;
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index cb0737e..477285d 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -20,6 +20,8 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
import android.util.Log;
import java.io.File;
@@ -27,9 +29,6 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-
/**
* Global constant definitions et cetera related to the full-backup-to-fd
* binary format. Nothing in this namespace is part of any API; it's all
@@ -150,7 +149,7 @@ public class FullBackup {
try {
// explicitly prevent emplacement of files accessible by outside apps
mode &= 0700;
- Libcore.os.chmod(outFile.getPath(), (int)mode);
+ Os.chmod(outFile.getPath(), (int)mode);
} catch (ErrnoException e) {
e.rethrowAsIOException();
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 9c46d96..1a1610d 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -441,6 +441,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public String nativeLibraryDir;
/**
+ * The ABI that this application requires, This is inferred from the ABIs
+ * of the native JNI libraries the application bundles. Will be {@code null}
+ * if this application does not require any particular ABI.
+ *
+ * {@hide}
+ */
+ public String requiredCpuAbi;
+
+ /**
* The kernel user-ID that has been assigned to this application;
* currently this is not a unique ID (multiple applications can have
* the same uid).
@@ -570,6 +579,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
sourceDir = orig.sourceDir;
publicSourceDir = orig.publicSourceDir;
nativeLibraryDir = orig.nativeLibraryDir;
+ requiredCpuAbi = orig.requiredCpuAbi;
resourceDirs = orig.resourceDirs;
seinfo = orig.seinfo;
sharedLibraryFiles = orig.sharedLibraryFiles;
@@ -610,6 +620,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeString(sourceDir);
dest.writeString(publicSourceDir);
dest.writeString(nativeLibraryDir);
+ dest.writeString(requiredCpuAbi);
dest.writeStringArray(resourceDirs);
dest.writeString(seinfo);
dest.writeStringArray(sharedLibraryFiles);
@@ -649,6 +660,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
sourceDir = source.readString();
publicSourceDir = source.readString();
nativeLibraryDir = source.readString();
+ requiredCpuAbi = source.readString();
resourceDirs = source.readStringArray();
seinfo = source.readString();
sharedLibraryFiles = source.readStringArray();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c97c2b8..8ce7e97 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -675,6 +675,25 @@ public abstract class PackageManager {
public static final int INSTALL_FAILED_USER_RESTRICTED = -111;
/**
+ * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the system failed to install the package because its packaged native code did not
+ * match any of the ABIs supported by the system.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FAILED_NO_MATCHING_ABIS = -112;
+
+ /**
+ * Internal return code for NativeLibraryHelper methods to indicate that the package
+ * being processed did not contain any native code. This is placed here only so that
+ * it can belong to the same value space as the other install failure codes.
+ *
+ * @hide
+ */
+ public static final int NO_NATIVE_LIBRARIES = -113;
+
+ /**
* Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
* package's data directory.
*
diff --git a/core/java/android/ddm/DdmHandleHeap.java b/core/java/android/ddm/DdmHandleHeap.java
index cece556..e24aeb2 100644
--- a/core/java/android/ddm/DdmHandleHeap.java
+++ b/core/java/android/ddm/DdmHandleHeap.java
@@ -219,7 +219,7 @@ public class DdmHandleHeap extends ChunkHandler {
if (false)
Log.d("ddm-heap", "Heap GC request");
- System.gc();
+ Runtime.getRuntime().gc();
return null; // empty response
}
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index 22543e3..a725bec 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -24,13 +24,13 @@ import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.UnknownHostException;
-import static libcore.io.OsConstants.IFA_F_DADFAILED;
-import static libcore.io.OsConstants.IFA_F_DEPRECATED;
-import static libcore.io.OsConstants.IFA_F_TENTATIVE;
-import static libcore.io.OsConstants.RT_SCOPE_HOST;
-import static libcore.io.OsConstants.RT_SCOPE_LINK;
-import static libcore.io.OsConstants.RT_SCOPE_SITE;
-import static libcore.io.OsConstants.RT_SCOPE_UNIVERSE;
+import static android.system.OsConstants.IFA_F_DADFAILED;
+import static android.system.OsConstants.IFA_F_DEPRECATED;
+import static android.system.OsConstants.IFA_F_TENTATIVE;
+import static android.system.OsConstants.RT_SCOPE_HOST;
+import static android.system.OsConstants.RT_SCOPE_LINK;
+import static android.system.OsConstants.RT_SCOPE_SITE;
+import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
/**
* Identifies an IP address on a network link.
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index 119e533..643e8c2 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -22,9 +22,9 @@ import java.io.InputStream;
import java.io.FileDescriptor;
import java.net.SocketOptions;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.OsConstants;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
/**
* Socket implementation used for android.net.LocalSocket and
@@ -248,7 +248,7 @@ class LocalSocketImpl
throw new IllegalStateException("unknown sockType");
}
try {
- fd = Libcore.os.socket(OsConstants.AF_UNIX, osType, 0);
+ fd = Os.socket(OsConstants.AF_UNIX, osType, 0);
mFdCreatedInternally = true;
} catch (ErrnoException e) {
e.rethrowAsIOException();
@@ -268,7 +268,7 @@ class LocalSocketImpl
return;
}
try {
- Libcore.os.close(fd);
+ Os.close(fd);
} catch (ErrnoException e) {
e.rethrowAsIOException();
}
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index a28b5a7..d06355d 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -22,6 +22,8 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
@@ -74,13 +76,16 @@ public class CertificateChainValidator {
private CertificateChainValidator() {
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X.509");
+ tmf.init((KeyStore) null);
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509ExtendedTrustManager) {
mTrustManager = (X509ExtendedTrustManager) tm;
}
}
} catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("X.509 TrustManager factory must be available", e);
+ throw new RuntimeException("X.509 TrustManagerFactory must be available", e);
+ } catch (KeyStoreException e) {
+ throw new RuntimeException("X.509 TrustManagerFactory cannot be initialized", e);
}
if (mTrustManager == null) {
@@ -166,9 +171,13 @@ public class CertificateChainValidator {
TrustManagerFactory tmf;
try {
tmf = TrustManagerFactory.getInstance("X.509");
+ tmf.init((KeyStore) null);
} catch (NoSuchAlgorithmException e) {
Slog.w(TAG, "Couldn't find default X.509 TrustManagerFactory");
return;
+ } catch (KeyStoreException e) {
+ Slog.w(TAG, "Couldn't initialize default X.509 TrustManagerFactory", e);
+ return;
}
TrustManager[] tms = tmf.getTrustManagers();
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index 666832a..d730a7b 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -56,7 +56,8 @@ public class X509TrustManagerExtensions {
if (tm instanceof TrustManagerImpl) {
mDelegate = (TrustManagerImpl) tm;
} else {
- throw new IllegalArgumentException("tm is not a supported type of X509TrustManager");
+ throw new IllegalArgumentException("tm is an instance of " + tm.getClass().getName() +
+ " which is not a supported type of X509TrustManager");
}
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 22e1476..b2e0b29 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -74,7 +74,14 @@ public class Build {
/** A hardware serial number, if available. Alphanumeric only, case-insensitive. */
public static final String SERIAL = getString("ro.serialno");
-
+
+ /**
+ * A list of ABIs (in priority) order supported by this device.
+ *
+ * @hide
+ */
+ public static final String[] SUPPORTED_ABIS = getString("ro.product.cpu.abilist").split(",");
+
/** Various version strings. */
public static class VERSION {
/**
diff --git a/core/java/android/os/CommonClock.java b/core/java/android/os/CommonClock.java
index 3a1da97..7f41c5d 100644
--- a/core/java/android/os/CommonClock.java
+++ b/core/java/android/os/CommonClock.java
@@ -20,7 +20,6 @@ import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
import java.util.NoSuchElementException;
-import static libcore.io.OsConstants.*;
import android.content.ComponentName;
import android.content.Context;
@@ -32,6 +31,7 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
+import static android.system.OsConstants.*;
/**
* Used for accessing the android common time service's common clock and receiving notifications
diff --git a/core/java/android/os/CommonTimeUtils.java b/core/java/android/os/CommonTimeUtils.java
index 20755d9..ba060b8 100644
--- a/core/java/android/os/CommonTimeUtils.java
+++ b/core/java/android/os/CommonTimeUtils.java
@@ -20,7 +20,7 @@ import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
import java.util.Locale;
-import static libcore.io.OsConstants.*;
+import static android.system.OsConstants.*;
class CommonTimeUtils {
/**
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index ff3e277..411783d 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,13 +16,13 @@
package android.os;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
import android.util.Log;
import android.util.Slog;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
-import libcore.io.Libcore;
-import libcore.io.OsConstants;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
@@ -87,7 +87,7 @@ public class FileUtils {
*/
public static int setPermissions(String path, int mode, int uid, int gid) {
try {
- Libcore.os.chmod(path, mode);
+ Os.chmod(path, mode);
} catch (ErrnoException e) {
Slog.w(TAG, "Failed to chmod(" + path + "): " + e);
return e.errno;
@@ -95,7 +95,7 @@ public class FileUtils {
if (uid >= 0 || gid >= 0) {
try {
- Libcore.os.chown(path, uid, gid);
+ Os.chown(path, uid, gid);
} catch (ErrnoException e) {
Slog.w(TAG, "Failed to chown(" + path + "): " + e);
return e.errno;
@@ -115,7 +115,7 @@ public class FileUtils {
*/
public static int setPermissions(FileDescriptor fd, int mode, int uid, int gid) {
try {
- Libcore.os.fchmod(fd, mode);
+ Os.fchmod(fd, mode);
} catch (ErrnoException e) {
Slog.w(TAG, "Failed to fchmod(): " + e);
return e.errno;
@@ -123,7 +123,7 @@ public class FileUtils {
if (uid >= 0 || gid >= 0) {
try {
- Libcore.os.fchown(fd, uid, gid);
+ Os.fchown(fd, uid, gid);
} catch (ErrnoException e) {
Slog.w(TAG, "Failed to fchown(): " + e);
return e.errno;
@@ -138,7 +138,7 @@ public class FileUtils {
*/
public static int getUid(String path) {
try {
- return Libcore.os.stat(path).st_uid;
+ return Os.stat(path).st_uid;
} catch (ErrnoException e) {
return -1;
}
diff --git a/core/java/android/os/MemoryFile.java b/core/java/android/os/MemoryFile.java
index ee7a4c6..6cec55a 100644
--- a/core/java/android/os/MemoryFile.java
+++ b/core/java/android/os/MemoryFile.java
@@ -63,12 +63,17 @@ public class MemoryFile
* Allocates a new ashmem region. The region is initially not purgable.
*
* @param name optional name for the file (can be null).
- * @param length of the memory file in bytes.
+ * @param length of the memory file in bytes, must be non-negative.
* @throws IOException if the memory file could not be created.
*/
public MemoryFile(String name, int length) throws IOException {
mLength = length;
- mFD = native_open(name, length);
+ if (length >= 0) {
+ mFD = native_open(name, length);
+ } else {
+ throw new IOException("Invalid length: " + length);
+ }
+
if (length > 0) {
mAddress = native_mmap(mFD, length, PROT_READ | PROT_WRITE);
} else {
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 5273c20..59795da 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -16,24 +16,24 @@
package android.os;
-import static libcore.io.OsConstants.AF_UNIX;
-import static libcore.io.OsConstants.SEEK_SET;
-import static libcore.io.OsConstants.SOCK_STREAM;
-import static libcore.io.OsConstants.S_ISLNK;
-import static libcore.io.OsConstants.S_ISREG;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.SEEK_SET;
+import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.S_ISLNK;
+import static android.system.OsConstants.S_ISREG;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
import android.util.Log;
import dalvik.system.CloseGuard;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
-import libcore.io.Libcore;
import libcore.io.Memory;
-import libcore.io.OsConstants;
-import libcore.io.StructStat;
import java.io.Closeable;
import java.io.File;
@@ -42,6 +42,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InterruptedIOException;
import java.net.DatagramSocket;
import java.net.Socket;
import java.nio.ByteOrder;
@@ -260,7 +261,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
*/
public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException {
try {
- final FileDescriptor fd = Libcore.os.dup(orig);
+ final FileDescriptor fd = Os.dup(orig);
return new ParcelFileDescriptor(fd);
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
@@ -296,7 +297,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
original.setInt$(fd);
try {
- final FileDescriptor dup = Libcore.os.dup(original);
+ final FileDescriptor dup = Os.dup(original);
return new ParcelFileDescriptor(dup);
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
@@ -358,7 +359,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
*/
public static ParcelFileDescriptor[] createPipe() throws IOException {
try {
- final FileDescriptor[] fds = Libcore.os.pipe();
+ final FileDescriptor[] fds = Os.pipe();
return new ParcelFileDescriptor[] {
new ParcelFileDescriptor(fds[0]),
new ParcelFileDescriptor(fds[1]) };
@@ -380,7 +381,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
public static ParcelFileDescriptor[] createReliablePipe() throws IOException {
try {
final FileDescriptor[] comm = createCommSocketPair();
- final FileDescriptor[] fds = Libcore.os.pipe();
+ final FileDescriptor[] fds = Os.pipe();
return new ParcelFileDescriptor[] {
new ParcelFileDescriptor(fds[0], comm[0]),
new ParcelFileDescriptor(fds[1], comm[1]) };
@@ -397,7 +398,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
try {
final FileDescriptor fd0 = new FileDescriptor();
final FileDescriptor fd1 = new FileDescriptor();
- Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+ Os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
return new ParcelFileDescriptor[] {
new ParcelFileDescriptor(fd0),
new ParcelFileDescriptor(fd1) };
@@ -420,7 +421,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
final FileDescriptor[] comm = createCommSocketPair();
final FileDescriptor fd0 = new FileDescriptor();
final FileDescriptor fd1 = new FileDescriptor();
- Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+ Os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
return new ParcelFileDescriptor[] {
new ParcelFileDescriptor(fd0, comm[0]),
new ParcelFileDescriptor(fd1, comm[1]) };
@@ -433,7 +434,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
try {
final FileDescriptor comm1 = new FileDescriptor();
final FileDescriptor comm2 = new FileDescriptor();
- Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2);
+ Os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2);
IoUtils.setBlocking(comm1, false);
IoUtils.setBlocking(comm2, false);
return new FileDescriptor[] { comm1, comm2 };
@@ -519,7 +520,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
return mWrapped.getStatSize();
} else {
try {
- final StructStat st = Libcore.os.fstat(mFd);
+ final StructStat st = Os.fstat(mFd);
if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
return st.st_size;
} else {
@@ -542,7 +543,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
return mWrapped.seekTo(pos);
} else {
try {
- return Libcore.os.lseek(mFd, pos, SEEK_SET);
+ return Os.lseek(mFd, pos, SEEK_SET);
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
}
@@ -694,10 +695,13 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
writePtr += len;
}
- Libcore.os.write(mCommFd, buf, 0, writePtr);
+ Os.write(mCommFd, buf, 0, writePtr);
} catch (ErrnoException e) {
// Reporting status is best-effort
Log.w(TAG, "Failed to report status: " + e);
+ } catch (InterruptedIOException e) {
+ // Reporting status is best-effort
+ Log.w(TAG, "Failed to report status: " + e);
}
} finally {
@@ -708,7 +712,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
private static Status readCommStatus(FileDescriptor comm, byte[] buf) {
try {
- final int n = Libcore.os.read(comm, buf, 0, buf.length);
+ final int n = Os.read(comm, buf, 0, buf.length);
if (n == 0) {
// EOF means they're dead
return new Status(Status.DEAD);
@@ -728,6 +732,9 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
Log.d(TAG, "Failed to read status; assuming dead: " + e);
return new Status(Status.DEAD);
}
+ } catch (InterruptedIOException e) {
+ Log.d(TAG, "Failed to read status; assuming dead: " + e);
+ return new Status(Status.DEAD);
}
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 631edd6..5dc4058 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -16,18 +16,19 @@
package android.os;
-import android.net.LocalSocketAddress;
import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.system.Os;
import android.util.Log;
-import dalvik.system.Zygote;
-
+import com.android.internal.os.Zygote;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-
-import libcore.io.Libcore;
+import java.util.Arrays;
+import java.util.List;
/*package*/ class ZygoteStartFailedEx extends Exception {
/**
@@ -47,17 +48,7 @@ public class Process {
private static final String ZYGOTE_SOCKET = "zygote";
- /**
- * Name of a process for running the platform's media services.
- * {@hide}
- */
- public static final String ANDROID_SHARED_MEDIA = "com.android.process.media";
-
- /**
- * Name of the process that Google content providers can share.
- * {@hide}
- */
- public static final String GOOGLE_SHARED_APP_CONTENT = "com.google.process.content";
+ private static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary";
/**
* Defines the UID/GID under which system code runs.
@@ -344,15 +335,112 @@ public class Process {
public static final int SIGNAL_QUIT = 3;
public static final int SIGNAL_KILL = 9;
public static final int SIGNAL_USR1 = 10;
-
- // State for communicating with zygote process
- static LocalSocket sZygoteSocket;
- static DataInputStream sZygoteInputStream;
- static BufferedWriter sZygoteWriter;
+ /**
+ * State for communicating with the zygote process.
+ */
+ static class ZygoteState {
+ final LocalSocket socket;
+ final DataInputStream inputStream;
+ final BufferedWriter writer;
+ final List<String> abiList;
- /** true if previous zygote open failed */
- static boolean sPreviousZygoteOpenFailed;
+ boolean mClosed;
+
+ private ZygoteState(LocalSocket socket, DataInputStream inputStream,
+ BufferedWriter writer, List<String> abiList) {
+ this.socket = socket;
+ this.inputStream = inputStream;
+ this.writer = writer;
+ this.abiList = abiList;
+ }
+
+ static ZygoteState connect(String socketAddress, int tries) throws ZygoteStartFailedEx {
+ LocalSocket zygoteSocket = null;
+ DataInputStream zygoteInputStream = null;
+ BufferedWriter zygoteWriter = null;
+
+ /*
+ * See bug #811181: Sometimes runtime can make it up before zygote.
+ * Really, we'd like to do something better to avoid this condition,
+ * but for now just wait a bit...
+ *
+ * TODO: This bug was filed in 2007. Get rid of this code. The zygote
+ * forks the system_server so it shouldn't be possible for the zygote
+ * socket to be brought up after the system_server is.
+ */
+ for (int i = 0; i < tries; i++) {
+ if (i > 0) {
+ try {
+ Log.i(LOG_TAG, "Zygote not up yet, sleeping...");
+ Thread.sleep(ZYGOTE_RETRY_MILLIS);
+ } catch (InterruptedException ex) {
+ throw new ZygoteStartFailedEx(ex);
+ }
+ }
+
+ try {
+ zygoteSocket = new LocalSocket();
+ zygoteSocket.connect(new LocalSocketAddress(socketAddress,
+ LocalSocketAddress.Namespace.RESERVED));
+
+ zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
+
+ zygoteWriter = new BufferedWriter(new OutputStreamWriter(
+ zygoteSocket.getOutputStream()), 256);
+ break;
+ } catch (IOException ex) {
+ if (zygoteSocket != null) {
+ try {
+ zygoteSocket.close();
+ } catch (IOException ex2) {
+ Log.e(LOG_TAG,"I/O exception on close after exception", ex2);
+ }
+ }
+
+ zygoteSocket = null;
+ }
+ }
+
+ if (zygoteSocket == null) {
+ throw new ZygoteStartFailedEx("connect failed");
+ }
+
+ String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
+ Log.i("Zygote", "Process: zygote socket opened, supported ABIS: " + abiListString);
+
+ return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
+ Arrays.asList(abiListString.split(",")));
+ }
+
+ boolean matches(String abi) {
+ return abiList.contains(abi);
+ }
+
+ void close() {
+ try {
+ socket.close();
+ } catch (IOException ex) {
+ Log.e(LOG_TAG,"I/O exception on routine close", ex);
+ }
+
+ mClosed = true;
+ }
+
+ boolean isClosed() {
+ return mClosed;
+ }
+ }
+
+ /**
+ * The state of the connection to the primary zygote.
+ */
+ static ZygoteState primaryZygoteState;
+
+ /**
+ * The state of the connection to the secondary zygote.
+ */
+ static ZygoteState secondaryZygoteState;
/**
* Start a new process.
@@ -378,6 +466,7 @@ public class Process {
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
+ * @param abi non-null the ABI this app should be started with.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
@@ -391,10 +480,12 @@ public class Process {
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
+ String abi,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
- debugFlags, mountExternal, targetSdkVersion, seInfo, zygoteArgs);
+ debugFlags, mountExternal, targetSdkVersion, seInfo,
+ abi, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -407,78 +498,31 @@ public class Process {
static final int ZYGOTE_RETRY_MILLIS = 500;
/**
- * Tries to open socket to Zygote process if not already open. If
- * already open, does nothing. May block and retry.
+ * Queries the zygote for the list of ABIS it supports.
+ *
+ * @throws ZygoteStartFailedEx if the query failed.
*/
- private static void openZygoteSocketIfNeeded()
+ private static String getAbiList(BufferedWriter writer, DataInputStream inputStream)
throws ZygoteStartFailedEx {
+ try {
- int retryCount;
-
- if (sPreviousZygoteOpenFailed) {
- /*
- * If we've failed before, expect that we'll fail again and
- * don't pause for retries.
- */
- retryCount = 0;
- } else {
- retryCount = 10;
- }
-
- /*
- * See bug #811181: Sometimes runtime can make it up before zygote.
- * Really, we'd like to do something better to avoid this condition,
- * but for now just wait a bit...
- */
- for (int retry = 0
- ; (sZygoteSocket == null) && (retry < (retryCount + 1))
- ; retry++ ) {
-
- if (retry > 0) {
- try {
- Log.i("Zygote", "Zygote not up yet, sleeping...");
- Thread.sleep(ZYGOTE_RETRY_MILLIS);
- } catch (InterruptedException ex) {
- // should never happen
- }
- }
-
- try {
- sZygoteSocket = new LocalSocket();
-
- sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,
- LocalSocketAddress.Namespace.RESERVED));
-
- sZygoteInputStream
- = new DataInputStream(sZygoteSocket.getInputStream());
-
- sZygoteWriter =
- new BufferedWriter(
- new OutputStreamWriter(
- sZygoteSocket.getOutputStream()),
- 256);
-
- Log.i("Zygote", "Process: zygote socket opened");
-
- sPreviousZygoteOpenFailed = false;
- break;
- } catch (IOException ex) {
- if (sZygoteSocket != null) {
- try {
- sZygoteSocket.close();
- } catch (IOException ex2) {
- Log.e(LOG_TAG,"I/O exception on close after exception",
- ex2);
- }
- }
-
- sZygoteSocket = null;
- }
- }
-
- if (sZygoteSocket == null) {
- sPreviousZygoteOpenFailed = true;
- throw new ZygoteStartFailedEx("connect failed");
+ // Each query starts with the argument count (1 in this case)
+ writer.write("1");
+ // ... followed by a new-line.
+ writer.newLine();
+ // ... followed by our only argument.
+ writer.write("--query-abi-list");
+ writer.newLine();
+ writer.flush();
+
+ // The response is a length prefixed stream of ASCII bytes.
+ int numBytes = inputStream.readInt();
+ byte[] bytes = new byte[numBytes];
+ inputStream.readFully(bytes);
+
+ return new String(bytes, StandardCharsets.US_ASCII);
+ } catch (IOException ioe) {
+ throw new ZygoteStartFailedEx(ioe);
}
}
@@ -486,14 +530,12 @@ public class Process {
* Sends an argument list to the zygote process, which starts a new child
* and returns the child's pid. Please note: the present implementation
* replaces newlines in the argument list with spaces.
- * @param args argument list
- * @return An object that describes the result of the attempt to start the process.
+ *
* @throws ZygoteStartFailedEx if process start failed for any reason
*/
- private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)
+ private static ProcessStartResult zygoteSendArgsAndGetResult(
+ ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
- openZygoteSocketIfNeeded();
-
try {
/**
* See com.android.internal.os.ZygoteInit.readArgumentList()
@@ -505,9 +547,11 @@ public class Process {
* the child or -1 on failure, followed by boolean to
* indicate whether a wrapper process was used.
*/
+ final BufferedWriter writer = zygoteState.writer;
+ final DataInputStream inputStream = zygoteState.inputStream;
- sZygoteWriter.write(Integer.toString(args.size()));
- sZygoteWriter.newLine();
+ writer.write(Integer.toString(args.size()));
+ writer.newLine();
int sz = args.size();
for (int i = 0; i < sz; i++) {
@@ -516,32 +560,22 @@ public class Process {
throw new ZygoteStartFailedEx(
"embedded newlines not allowed");
}
- sZygoteWriter.write(arg);
- sZygoteWriter.newLine();
+ writer.write(arg);
+ writer.newLine();
}
- sZygoteWriter.flush();
+ writer.flush();
// Should there be a timeout on this?
ProcessStartResult result = new ProcessStartResult();
- result.pid = sZygoteInputStream.readInt();
+ result.pid = inputStream.readInt();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
- result.usingWrapper = sZygoteInputStream.readBoolean();
+ result.usingWrapper = inputStream.readBoolean();
return result;
} catch (IOException ex) {
- try {
- if (sZygoteSocket != null) {
- sZygoteSocket.close();
- }
- } catch (IOException ex2) {
- // we're going to fail anyway
- Log.e(LOG_TAG,"I/O exception on routine close", ex2);
- }
-
- sZygoteSocket = null;
-
+ zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
@@ -558,6 +592,7 @@ public class Process {
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
+ * @param abi the ABI the process should use.
* @param extraArgs Additional arguments to supply to the zygote process.
* @return An object that describes the result of the attempt to start the process.
* @throws ZygoteStartFailedEx if process start failed for any reason
@@ -569,6 +604,7 @@ public class Process {
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
+ String abi,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
@@ -636,10 +672,64 @@ public class Process {
}
}
- return zygoteSendArgsAndGetResult(argsForZygote);
+ return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
-
+
+ /**
+ * Returns the number of times we attempt a connection to the zygote. We
+ * sleep for {@link #ZYGOTE_RETRY_MILLIS} milliseconds between each try.
+ *
+ * This could probably be removed, see TODO in {@code ZygoteState#connect}.
+ */
+ private static int getNumTries(ZygoteState state) {
+ // Retry 10 times for the first connection to each zygote.
+ if (state == null) {
+ return 11;
+ }
+
+ // This means the connection has already been established, but subsequently
+ // closed, possibly due to an IOException. We retry just once if that's the
+ // case.
+ return 1;
+ }
+
+ /**
+ * Tries to open socket to Zygote process if not already open. If
+ * already open, does nothing. May block and retry.
+ */
+ private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
+ if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
+ primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET, getNumTries(primaryZygoteState));
+ }
+
+ if (primaryZygoteState.matches(abi)) {
+ return primaryZygoteState;
+ }
+
+ // TODO: Get rid of this. This is a temporary workaround until all the
+ // compilation related pieces for the dual zygote stack are ready.
+ // b/3647418.
+ if (System.getenv("ANDROID_SOCKET_" + SECONDARY_ZYGOTE_SOCKET) == null) {
+ Log.e(LOG_TAG, "Forcing app to primary zygote, secondary unavailable (ABI= " + abi + ")");
+ // Should be :
+ // throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
+ return primaryZygoteState;
+ }
+
+ // The primary zygote didn't match. Try the secondary.
+ if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
+ secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET,
+ getNumTries(secondaryZygoteState));
+ }
+
+ if (secondaryZygoteState.matches(abi)) {
+ return secondaryZygoteState;
+ }
+
+ throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
+ }
+
/**
* Returns elapsed milliseconds of the time this process has run.
* @return Returns the number of milliseconds this process has return.
@@ -651,7 +741,7 @@ public class Process {
* {@link #killProcess} and {@link #sendSignal}.
*/
public static final int myPid() {
- return Libcore.os.getpid();
+ return Os.getpid();
}
/**
@@ -659,7 +749,7 @@ public class Process {
* @hide
*/
public static final int myPpid() {
- return Libcore.os.getppid();
+ return Os.getppid();
}
/**
@@ -667,7 +757,7 @@ public class Process {
* {@link #setThreadPriority(int, int)}.
*/
public static final int myTid() {
- return Libcore.os.gettid();
+ return Os.gettid();
}
/**
@@ -677,7 +767,7 @@ public class Process {
* a uid identifies a specific app sandbox in a specific user.
*/
public static final int myUid() {
- return Libcore.os.getuid();
+ return Os.getuid();
}
/**
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 9e9521a..13e9a15 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -16,9 +16,9 @@
package android.os;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.StructStatVfs;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStatVfs;
/**
* Retrieve overall information about the space on a filesystem. This is a
@@ -41,7 +41,7 @@ public class StatFs {
private static StructStatVfs doStat(String path) {
try {
- return Libcore.os.statvfs(path);
+ return Os.statvfs(path);
} catch (ErrnoException e) {
throw new IllegalArgumentException("Invalid path: " + path, e);
}
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index f0520b5..6519f7e 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -17,7 +17,7 @@
package android.provider;
import static android.net.TrafficStats.KB_IN_BYTES;
-import static libcore.io.OsConstants.SEEK_SET;
+import static android.system.OsConstants.SEEK_SET;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -38,11 +38,11 @@ import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.OnCloseListener;
import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
import android.util.Log;
-import libcore.io.ErrnoException;
import libcore.io.IoUtils;
-import libcore.io.Libcore;
import java.io.BufferedInputStream;
import java.io.File;
@@ -697,7 +697,7 @@ public final class DocumentsContract {
// optimal decode path; otherwise fall back to buffering.
BufferedInputStream is = null;
try {
- Libcore.os.lseek(fd, offset, SEEK_SET);
+ Os.lseek(fd, offset, SEEK_SET);
} catch (ErrnoException e) {
is = new BufferedInputStream(new FileInputStream(fd), THUMBNAIL_BUFFER_SIZE);
is.mark(THUMBNAIL_BUFFER_SIZE);
@@ -723,7 +723,7 @@ public final class DocumentsContract {
bitmap = BitmapFactory.decodeStream(is, null, opts);
} else {
try {
- Libcore.os.lseek(fd, offset, SEEK_SET);
+ Os.lseek(fd, offset, SEEK_SET);
} catch (ErrnoException e) {
e.rethrowAsIOException();
}
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 29c0ba2..aefced8 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -56,16 +56,18 @@ public class EventLog {
public static final class Event {
private final ByteBuffer mBuffer;
- // Layout of event log entry received from kernel.
+ // Layout of event log entry received from Android logger.
+ // see system/core/include/log/logger.h
private static final int LENGTH_OFFSET = 0;
+ private static final int HEADER_SIZE_OFFSET = 2;
private static final int PROCESS_OFFSET = 4;
private static final int THREAD_OFFSET = 8;
private static final int SECONDS_OFFSET = 12;
private static final int NANOSECONDS_OFFSET = 16;
- private static final int PAYLOAD_START = 20;
- private static final int TAG_OFFSET = 20;
- private static final int DATA_START = 24;
+ // Layout for event log v1 format, v2 and v3 use HEADER_SIZE_OFFSET
+ private static final int V1_PAYLOAD_START = 20;
+ private static final int DATA_OFFSET = 4;
// Value types
private static final byte INT_TYPE = 0;
@@ -97,14 +99,22 @@ public class EventLog {
/** @return the type tag code of the entry */
public int getTag() {
- return mBuffer.getInt(TAG_OFFSET);
+ int offset = mBuffer.getShort(HEADER_SIZE_OFFSET);
+ if (offset == 0) {
+ offset = V1_PAYLOAD_START;
+ }
+ return mBuffer.getInt(offset);
}
/** @return one of Integer, Long, String, null, or Object[] of same. */
public synchronized Object getData() {
try {
- mBuffer.limit(PAYLOAD_START + mBuffer.getShort(LENGTH_OFFSET));
- mBuffer.position(DATA_START); // Just after the tag.
+ int offset = mBuffer.getShort(HEADER_SIZE_OFFSET);
+ if (offset == 0) {
+ offset = V1_PAYLOAD_START;
+ }
+ mBuffer.limit(offset + mBuffer.getShort(LENGTH_OFFSET));
+ mBuffer.position(offset + DATA_OFFSET); // Just after the tag.
return decodeObject();
} catch (IllegalArgumentException e) {
Log.wtf(TAG, "Illegal entry payload: tag=" + getTag(), e);
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index abd173a..2b81072 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -352,6 +352,7 @@ public final class Log {
/** @hide */ public static final int LOG_ID_RADIO = 1;
/** @hide */ public static final int LOG_ID_EVENTS = 2;
/** @hide */ public static final int LOG_ID_SYSTEM = 3;
+ /** @hide */ public static final int LOG_ID_CRASH = 4;
/** @hide */ public static native int println_native(int bufID,
int priority, String tag, String msg);
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index aa43bad..cd905fa 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -591,6 +591,7 @@ public abstract class LayoutInflater {
Object[] args = mConstructorArgs;
args[1] = attrs;
+ constructor.setAccessible(true);
final View view = constructor.newInstance(args);
if (view instanceof ViewStub) {
// always use ourselves when inflating ViewStub later
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d779628..5b2a452 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -656,7 +656,7 @@ public final class ViewRootImpl implements ViewParent,
mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(MSG_FLUSH_LAYER_UPDATES));
}
- public boolean attachFunctor(int functor) {
+ public boolean attachFunctor(long functor) {
//noinspection SimplifiableIfStatement
if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
return mAttachInfo.mHardwareRenderer.attachFunctor(mAttachInfo, functor);
@@ -664,7 +664,7 @@ public final class ViewRootImpl implements ViewParent,
return false;
}
- public void detachFunctor(int functor) {
+ public void detachFunctor(long functor) {
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.detachFunctor(functor);
}
diff --git a/core/java/android/webkit/ClientCertRequest.java b/core/java/android/webkit/ClientCertRequest.java
new file mode 100644
index 0000000..8951786
--- /dev/null
+++ b/core/java/android/webkit/ClientCertRequest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+/**
+ * ClientCertRequest: The user receives an instance of this class as
+ * a parameter of {@link WebViewClient#onReceivedClientCertRequest}.
+ * The request includes the parameters to choose the client certificate,
+ * such as the host name and the port number requesting the cert, the acceptable
+ * key types and the principals.
+ *
+ * The user should call one of the interface methods to indicate how to deal
+ * with the client certificate request. All methods should be called on
+ * UI thread.
+ *
+ * WebView caches the {@link #proceed} and {@link #cancel} responses in memory
+ * and uses them to handle future client certificate requests for the same
+ * host/port pair. The user can clear the cached data using
+ * {@link WebView#clearClientCertPreferences}.
+ *
+ * TODO(sgurun) unhide
+ * @hide
+ */
+public interface ClientCertRequest {
+ /**
+ * Returns the acceptable types of asymmetric keys (can be null).
+ */
+ public String[] getKeyTypes();
+
+ /**
+ * Returns the acceptable certificate issuers for the certificate
+ * matching the private key (can be null).
+ */
+ public Principal[] getPrincipals();
+
+ /**
+ * Returns the host name of the server requesting the certificate.
+ */
+ public String getHost();
+
+ /**
+ * Returns the port number of the server requesting the certificate.
+ */
+ public int getPort();
+
+ /**
+ * Proceed with the specified private key and client certificate chain.
+ * Remember the user's positive choice and use it for future requests.
+ */
+ public void proceed(PrivateKey privateKey, X509Certificate[] chain);
+
+ /**
+ * Ignore the request for now. Do not remember user's choice.
+ */
+ public void ignore();
+
+ /**
+ * Cancel this request. Remember the user's choice and use it for
+ * future requests.
+ */
+ public void cancel();
+}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index e8974c6..fb842ff 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -204,6 +204,30 @@ public class WebViewClient {
handler.cancel();
}
+ /**
+ * Notify the host application to handle a SSL client certificate
+ * request. The host application is responsible for showing the UI
+ * if desired and providing the keys. There are three ways to
+ * respond: proceed(), cancel() or ignore(). Webview remembers the
+ * response if proceed() or cancel() is called and does not
+ * call onReceivedClientCertRequest() again for the same host and port
+ * pair. Webview does not remember the response if ignore() is called.
+ *
+ * This method is called on the UI thread. During the callback, the
+ * connection is suspended.
+ *
+ * The default behavior is to cancel, returning no client certificate.
+ *
+ * @param view The WebView that is initiating the callback
+ * @param request An instance of a {@link ClientCertRequest}
+ *
+ * TODO(sgurun) unhide
+ * @hide
+ */
+ public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
+ request.cancel();
+ }
+
/**
* Notifies the host application that the WebView received an HTTP
* authentication request. The host application can use the supplied
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index c0fde2e..26c5732 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1944,7 +1944,16 @@ public class NumberPicker extends LinearLayout {
, '\u0669',
// Extended Arabic-Indic
'\u06f0', '\u06f1', '\u06f2', '\u06f3', '\u06f4', '\u06f5', '\u06f6', '\u06f7', '\u06f8'
- , '\u06f9'
+ , '\u06f9',
+ // Hindi and Marathi (Devanagari script)
+ '\u0966', '\u0967', '\u0968', '\u0969', '\u096a', '\u096b', '\u096c', '\u096d', '\u096e'
+ , '\u096f',
+ // Bengali
+ '\u09e6', '\u09e7', '\u09e8', '\u09e9', '\u09ea', '\u09eb', '\u09ec', '\u09ed', '\u09ee'
+ , '\u09ef',
+ // Kannada
+ '\u0ce6', '\u0ce7', '\u0ce8', '\u0ce9', '\u0cea', '\u0ceb', '\u0cec', '\u0ced', '\u0cee'
+ , '\u0cef'
};
/**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 37121e2..5ece016 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5147,12 +5147,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int width = mRight - mLeft;
final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight();
final float dx = mLayout.getLineRight(0) - (width - padding);
- canvas.translate(isLayoutRtl ? -dx : +dx, 0.0f);
+ canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
}
if (mMarquee != null && mMarquee.isRunning()) {
final float dx = -mMarquee.getScroll();
- canvas.translate(isLayoutRtl ? -dx : +dx, 0.0f);
+ canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
}
}
@@ -5166,8 +5166,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (mMarquee != null && mMarquee.shouldDrawGhost()) {
- final int dx = (int) mMarquee.getGhostOffset();
- canvas.translate(isLayoutRtl ? -dx : dx, 0.0f);
+ final float dx = mMarquee.getGhostOffset();
+ canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
}