Merge "DO NOT MERGE Add API for file origin policy."
diff --git a/api/current.txt b/api/current.txt
index d270ae0..b06a51d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19290,6 +19290,7 @@
   public class CdmaCellLocation extends android.telephony.CellLocation {
     ctor public CdmaCellLocation();
     ctor public CdmaCellLocation(android.os.Bundle);
+    method public static double convertQuartSecToDecDegrees(int);
     method public void fillInNotifierBundle(android.os.Bundle);
     method public int getBaseStationId();
     method public int getBaseStationLatitude();
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index f277339..3e722ea 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -34,6 +34,12 @@
 LOCAL_STATIC_LIBRARIES := \
     libdiskusage
 
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_CFLAGS := -DHAVE_SELINUX
+endif # HAVE_SELINUX
+
 LOCAL_MODULE := installd
 
 LOCAL_MODULE_TAGS := optional
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index dd92bbe..0dd8156 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -17,6 +17,10 @@
 #include "installd.h"
 #include <diskusage/dirsize.h>
 
+#ifdef HAVE_SELINUX
+#include <selinux/android.h>
+#endif
+
 /* Directory records that are used in execution of commands. */
 dir_rec_t android_data_dir;
 dir_rec_t android_asec_dir;
@@ -58,6 +62,15 @@
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     if (mkdir(libdir, 0755) < 0) {
         ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
         unlink(pkgdir);
@@ -75,6 +88,16 @@
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(libdir, pkgname, AID_SYSTEM) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", libdir, strerror(errno));
+        unlink(libdir);
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     return 0;
 }
 
@@ -135,6 +158,15 @@
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     return 0;
 }
 
@@ -284,12 +316,18 @@
         ALOGE("failed to chgrp '%s': %s\n", pkgpath, strerror(errno));
         return -1;
     }
-
     if (chmod(pkgpath, S_IRUSR|S_IWUSR|S_IRGRP) < 0) {
         ALOGE("failed to chmod '%s': %s\n", pkgpath, strerror(errno));
         return -1;
     }
 
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgpath, pkgname, s.st_uid) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", pkgpath, strerror(errno));
+        return -1;
+    }
+#endif
+
     return 0;
 }
 
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index dd9ea26..3a67cec 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -64,11 +64,12 @@
     }
 
     /**
-     * Called when the application is starting, before any other application
-     * objects have been created.  Implementations should be as quick as
-     * possible (for example using lazy initialization of state) since the time
-     * spent in this function directly impacts the performance of starting the
-     * first activity, service, or receiver in a process.
+     * Called when the application is starting, before any activity, service,
+     * or receiver objects (excluding content providers) have been created.
+     * Implementations should be as quick as possible (for example using 
+     * lazy initialization of state) since the time spent in this function
+     * directly impacts the performance of starting the first activity,
+     * service, or receiver in a process.
      * If you override this method, be sure to call super.onCreate().
      */
     public void onCreate() {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index c4a4fea..310d033 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -369,6 +369,7 @@
 
         case SCHEDULE_LOW_MEMORY_TRANSACTION:
         {
+            data.enforceInterface(IApplicationThread.descriptor);
             scheduleLowMemory();
             return true;
         }
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
new file mode 100644
index 0000000..90cfa37
--- /dev/null
+++ b/core/java/android/os/SELinux.java
@@ -0,0 +1,105 @@
+package android.os;
+
+import java.io.FileDescriptor;
+
+/**
+ * This class provides access to the centralized jni bindings for
+ * SELinux interaction.
+ * {@hide}
+ */
+public class SELinux {
+
+    /**
+     * Determine whether SELinux is disabled or enabled.
+     * @return a boolean indicating whether SELinux is enabled.
+     */
+    public static final native boolean isSELinuxEnabled();
+
+    /**
+     * Determine whether SELinux is permissive or enforcing.
+     * @return a boolean indicating whether SELinux is enforcing.
+     */
+    public static final native boolean isSELinuxEnforced();
+
+    /**
+     * Set whether SELinux is permissive or enforcing.
+     * @param boolean representing whether to set SELinux to enforcing
+     * @return a boolean representing whether the desired mode was set
+     */
+    public static final native boolean setSELinuxEnforce(boolean value);
+
+    /**
+     * Sets the security context for newly created file objects.
+     * @param context a security context given as a String.
+     * @return a boolean indicating whether the operation succeeded.
+     */
+    public static final native boolean setFSCreateContext(String context);
+
+    /**
+     * Change the security context of an existing file object.
+     * @param path representing the path of file object to relabel.
+     * @param con new security context given as a String.
+     * @return a boolean indicating whether the operation succeeded.
+     */
+    public static final native boolean setFileContext(String path, String context);
+
+    /**
+     * Get the security context of a file object.
+     * @param path the pathname of the file object.
+     * @return a security context given as a String.
+     */
+    public static final native String getFileContext(String path);
+
+    /**
+     * Get the security context of a peer socket.
+     * @param fd FileDescriptor class of the peer socket.
+     * @return a String representing the peer socket security context.
+     */
+    public static final native String getPeerContext(FileDescriptor fd);
+
+    /**
+     * Gets the security context of the current process.
+     * @return a String representing the security context of the current process.
+     */
+    public static final native String getContext();
+
+    /**
+     * Gets the security context of a given process id.
+     * Use of this function is discouraged for Binder transactions.
+     * Use Binder.getCallingSecctx() instead.
+     * @param pid an int representing the process id to check.
+     * @return a String representing the security context of the given pid.
+     */
+    public static final native String getPidContext(int pid);
+
+    /**
+     * Gets a list of the SELinux boolean names.
+     * @return an array of strings containing the SELinux boolean names.
+     */
+    public static final native String[] getBooleanNames();
+
+    /**
+     * Gets the value for the given SELinux boolean name.
+     * @param String The name of the SELinux boolean.
+     * @return a boolean indicating whether the SELinux boolean is set.
+     */
+    public static final native boolean getBooleanValue(String name);
+
+    /**
+     * Sets the value for the given SELinux boolean name.
+     * @param String The name of the SELinux boolean.
+     * @param Boolean The new value of the SELinux boolean.
+     * @return a boolean indicating whether or not the operation succeeded.
+     */
+    public static final native boolean setBooleanValue(String name, boolean value);
+
+    /**
+     * Check permissions between two security contexts.
+     * @param scon The source or subject security context.
+     * @param tcon The target or object security context.
+     * @param tclass The object security class name.
+     * @param perm The permission name.
+     * @return a boolean indicating whether permission was granted.
+     */
+    public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm);
+}
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 77d0c97..96a6428 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -76,6 +76,8 @@
     private PowerManager.WakeLock mCpuWakeLock;
     private PowerManager.WakeLock mScreenWakeLock;
     private Handler mHandler;
+
+    private static AlertDialog sConfirmDialog;
     
     private ShutdownThread() {
     }
@@ -108,7 +110,10 @@
 
         if (confirm) {
             final CloseDialogReceiver closer = new CloseDialogReceiver(context);
-            final AlertDialog dialog = new AlertDialog.Builder(context)
+            if (sConfirmDialog != null) {
+                sConfirmDialog.dismiss();
+            }
+            sConfirmDialog = new AlertDialog.Builder(context)
                     .setTitle(com.android.internal.R.string.power_off)
                     .setMessage(resourceId)
                     .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
@@ -118,10 +123,10 @@
                     })
                     .setNegativeButton(com.android.internal.R.string.no, null)
                     .create();
-            closer.dialog = dialog;
-            dialog.setOnDismissListener(closer);
-            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-            dialog.show();
+            closer.dialog = sConfirmDialog;
+            sConfirmDialog.setOnDismissListener(closer);
+            sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            sConfirmDialog.show();
         } else {
             beginShutdownSequence(context);
         }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 71c5d26..0b6a3a6 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -66,6 +66,7 @@
 	android_os_MessageQueue.cpp \
 	android_os_ParcelFileDescriptor.cpp \
 	android_os_Power.cpp \
+	android_os_SELinux.cpp \
 	android_os_StatFs.cpp \
 	android_os_SystemClock.cpp \
 	android_os_SystemProperties.cpp \
@@ -216,7 +217,13 @@
 	libnfc_ndef \
 	libusbhost \
 	libharfbuzz \
-	libz \
+	libz
+
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_CFLAGS += -DHAVE_SELINUX
+endif # HAVE_SELINUX
 
 ifeq ($(USE_OPENGL_RENDERER),true)
 	LOCAL_SHARED_LIBRARIES += libhwui
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 1c0d7cf..31c1120 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -135,6 +135,7 @@
 extern int register_android_os_MessageQueue(JNIEnv* env);
 extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
 extern int register_android_os_Power(JNIEnv *env);
+extern int register_android_os_SELinux(JNIEnv* env);
 extern int register_android_os_StatFs(JNIEnv *env);
 extern int register_android_os_SystemProperties(JNIEnv *env);
 extern int register_android_os_SystemClock(JNIEnv* env);
@@ -1153,6 +1154,7 @@
     REG_JNI(register_android_os_MessageQueue),
     REG_JNI(register_android_os_ParcelFileDescriptor),
     REG_JNI(register_android_os_Power),
+    REG_JNI(register_android_os_SELinux),
     REG_JNI(register_android_os_StatFs),
     REG_JNI(register_android_os_UEventObserver),
     REG_JNI(register_android_net_LocalSocketImpl),
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
new file mode 100644
index 0000000..eb99d2b
--- /dev/null
+++ b/core/jni/android_os_SELinux.cpp
@@ -0,0 +1,502 @@
+#define LOG_TAG "SELinuxJNI"
+#include <utils/Log.h>
+
+#include "JNIHelp.h"
+#include "jni.h"
+#include "android_runtime/AndroidRuntime.h"
+#ifdef HAVE_SELINUX
+#include "selinux/selinux.h"
+#endif
+#include <errno.h>
+
+namespace android {
+
+  static jboolean isSELinuxDisabled = true;
+
+  static void throw_NullPointerException(JNIEnv *env, const char* msg) {
+    jclass clazz;
+    clazz = env->FindClass("java/lang/NullPointerException");
+    env->ThrowNew(clazz, msg);
+  }
+
+  /*
+   * Function: isSELinuxEnabled
+   * Purpose:  checks whether SELinux is enabled/disbaled
+   * Parameters: none
+   * Return value : true (enabled) or false (disabled)
+   * Exceptions: none
+   */
+  static jboolean isSELinuxEnabled(JNIEnv *env, jobject classz) {
+
+    return !isSELinuxDisabled;
+  }
+
+  /*
+   * Function: isSELinuxEnforced
+   * Purpose: return the current SELinux enforce mode
+   * Parameters: none
+   * Return value: true (enforcing) or false (permissive)
+   * Exceptions: none
+   */
+  static jboolean isSELinuxEnforced(JNIEnv *env, jobject clazz) {
+#ifdef HAVE_SELINUX
+    return (security_getenforce() == 1) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: setSELinuxEnforce
+   * Purpose: set the SE Linux enforcing mode
+   * Parameters: true (enforcing) or false (permissive)
+   * Return value: true (success) or false (fail)
+   * Exceptions: none
+   */
+  static jboolean setSELinuxEnforce(JNIEnv *env, jobject clazz, jboolean value) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    int enforce = (value) ? 1 : 0;
+
+    return (security_setenforce(enforce) != -1) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: getPeerCon
+   * Purpose: retrieves security context of peer socket
+   * Parameters:
+   *        fileDescriptor: peer socket file as a FileDescriptor object
+   * Returns: jstring representing the security_context of socket or NULL if error
+   * Exceptions: NullPointerException if fileDescriptor object is NULL
+   */
+  static jstring getPeerCon(JNIEnv *env, jobject clazz, jobject fileDescriptor) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    if (fileDescriptor == NULL) {
+      throw_NullPointerException(env, "Trying to check security context of a null peer socket.");
+      return NULL;
+    }
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+    if (env->ExceptionOccurred() != NULL) {
+      LOGE("There was an issue with retrieving the file descriptor");
+      goto bail;
+    }
+
+    if (getpeercon(fd, &context) == -1)
+      goto bail;
+
+    LOGV("getPeerCon: Successfully retrived context of peer socket '%s'", context);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: setFSCreateCon
+   * Purpose: set security context used for creating a new file system object
+   * Parameters:
+   *       context: security_context_t representing the new context of a file system object,
+   *                set to NULL to return to the default policy behavior
+   * Returns: true on success, false on error
+   * Exception: none
+   */
+  static jboolean setFSCreateCon(JNIEnv *env, jobject clazz, jstring context) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    char * securityContext = NULL;
+    const char *constant_securityContext = NULL;
+
+    if (context != NULL) {
+      constant_securityContext = env->GetStringUTFChars(context, NULL);
+
+      // GetStringUTFChars returns const char * yet setfscreatecon needs char *
+      securityContext = const_cast<char *>(constant_securityContext);
+    }
+
+    int ret;
+    if ((ret = setfscreatecon(securityContext)) == -1)
+      goto bail;
+
+    LOGV("setFSCreateCon: set new security context to '%s' ", context == NULL ? "default", context);
+
+  bail:
+    if (constant_securityContext != NULL)
+      env->ReleaseStringUTFChars(context, constant_securityContext);
+
+    return (ret == 0) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: setFileCon
+   * Purpose:  set the security context of a file object
+   * Parameters:
+   *       path: the location of the file system object
+   *       con: the new security context of the file system object
+   * Returns: true on success, false on error
+   * Exception: NullPointerException is thrown if either path or context strign are NULL
+   */
+  static jboolean setFileCon(JNIEnv *env, jobject clazz, jstring path, jstring con) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    if (path == NULL) {
+      throw_NullPointerException(env, "Trying to change the security context of a NULL file object.");
+      return false;
+    }
+
+    if (con == NULL) {
+      throw_NullPointerException(env, "Trying to set the security context of a file object with NULL.");
+      return false;
+    }
+
+    const char *objectPath = env->GetStringUTFChars(path, NULL);
+    const char *constant_con = env->GetStringUTFChars(con, NULL);
+
+    // GetStringUTFChars returns const char * yet setfilecon needs char *
+    char *newCon = const_cast<char *>(constant_con);
+
+    int ret;
+    if ((ret = setfilecon(objectPath, newCon)) == -1)
+      goto bail;
+
+    LOGV("setFileCon: Succesfully set security context '%s' for '%s'", newCon, objectPath);
+
+  bail:
+    env->ReleaseStringUTFChars(path, objectPath);
+    env->ReleaseStringUTFChars(con, constant_con);
+    return (ret == 0) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: getFileCon
+   * Purpose: retrieves the context associated with the given path in the file system
+   * Parameters:
+   *        path: given path in the file system
+   * Returns:
+   *        string representing the security context string of the file object
+   *        the string may be NULL if an error occured
+   * Exceptions: NullPointerException if the path object is null
+   */
+  static jstring getFileCon(JNIEnv *env, jobject clazz, jstring path) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    if (path == NULL) {
+      throw_NullPointerException(env, "Trying to check security context of a null path.");
+      return NULL;
+    }
+
+    const char *objectPath = env->GetStringUTFChars(path, NULL);
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    if (getfilecon(objectPath, &context) == -1)
+      goto bail;
+
+    LOGV("getFileCon: Successfully retrived context '%s' for file '%s'", context, objectPath);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    env->ReleaseStringUTFChars(path, objectPath);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getCon
+   * Purpose: Get the context of the current process.
+   * Parameters: none
+   * Returns: a jstring representing the security context of the process,
+   *          the jstring may be NULL if there was an error
+   * Exceptions: none
+   */
+  static jstring getCon(JNIEnv *env, jobject clazz) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    if (getcon(&context) == -1)
+      goto bail;
+
+    LOGV("getCon: Successfully retrieved context '%s'", context);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getPidCon
+   * Purpose: Get the context of a process identified by its pid
+   * Parameters:
+   *            pid: a jint representing the process
+   * Returns: a jstring representing the security context of the pid,
+   *          the jstring may be NULL if there was an error
+   * Exceptions: none
+   */
+  static jstring getPidCon(JNIEnv *env, jobject clazz, jint pid) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    security_context_t context = NULL;
+    jstring securityString = NULL;
+
+    pid_t checkPid = (pid_t)pid;
+
+    if (getpidcon(checkPid, &context) == -1)
+      goto bail;
+
+    LOGV("getPidCon: Successfully retrived context '%s' for pid '%d'", context, checkPid);
+
+    securityString = env->NewStringUTF(context);
+
+  bail:
+    if (context != NULL)
+      freecon(context);
+
+    return securityString;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getBooleanNames
+   * Purpose: Gets a list of the SELinux boolean names.
+   * Parameters: None
+   * Returns: an array of strings  containing the SELinux boolean names.
+   *          returns NULL string on error
+   * Exceptions: None
+   */
+  static jobjectArray getBooleanNames(JNIEnv *env, JNIEnv clazz) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return NULL;
+
+    char **list;
+    int i, len, ret;
+    jclass stringClass;
+    jobjectArray stringArray = NULL;
+
+    if (security_get_boolean_names(&list, &len) == -1)
+      return NULL;
+
+    stringClass = env->FindClass("java/lang/String");
+    stringArray = env->NewObjectArray(len, stringClass, env->NewStringUTF(""));
+    for (i = 0; i < len; i++) {
+      jstring obj;
+      obj = env->NewStringUTF(list[i]);
+      env->SetObjectArrayElement(stringArray, i, obj);
+      env->DeleteLocalRef(obj);
+      free(list[i]);
+    }
+    free(list);
+
+    return stringArray;
+#else
+    return NULL;
+#endif
+  }
+
+  /*
+   * Function: getBooleanValue
+   * Purpose: Gets the value for the given SELinux boolean name.
+   * Parameters:
+   *            String: The name of the SELinux boolean.
+   * Returns: a boolean: (true) boolean is set or (false) it is not.
+   * Exceptions: None
+   */
+  static jboolean getBooleanValue(JNIEnv *env, jobject clazz, jstring name) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    const char *boolean_name;
+    int ret;
+
+    if (name == NULL)
+      return false;
+    boolean_name = env->GetStringUTFChars(name, NULL);
+    ret = security_get_boolean_active(boolean_name);
+    env->ReleaseStringUTFChars(name, boolean_name);
+    return (ret == 1) ? true : false;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: setBooleanNames
+   * Purpose: Sets the value for the given SELinux boolean name.
+   * Parameters:
+   *            String: The name of the SELinux boolean.
+   *            Boolean: The new value of the SELinux boolean.
+   * Returns: a boolean indicating whether or not the operation succeeded.
+   * Exceptions: None
+   */
+  static jboolean setBooleanValue(JNIEnv *env, jobject clazz, jstring name, jboolean value) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return false;
+
+    const char *boolean_name = NULL;
+    int ret;
+
+    if (name == NULL)
+      return false;
+    boolean_name = env->GetStringUTFChars(name, NULL);
+    ret = security_set_boolean(boolean_name, (value) ? 1 : 0);
+    env->ReleaseStringUTFChars(name, boolean_name);
+    if (ret)
+      return false;
+
+    if (security_commit_booleans() == -1)
+      return false;
+
+    return true;
+#else
+    return false;
+#endif
+  }
+
+  /*
+   * Function: checkSELinuxAccess
+   * Purpose: Check permissions between two security contexts.
+   * Parameters: scon: subject security context as a string
+   *             tcon: object security context as a string
+   *             tclass: object's security class name as a string
+   *             perm: permission name as a string
+   * Returns: boolean: (true) if permission was granted, (false) otherwise
+   * Exceptions: None
+   */
+  static jboolean checkSELinuxAccess(JNIEnv *env, jobject clazz, jstring scon, jstring tcon, jstring tclass, jstring perm) {
+#ifdef HAVE_SELINUX
+    if (isSELinuxDisabled)
+      return true;
+
+    int accessGranted = -1;
+
+    const char *const_scon, *const_tcon, *mytclass, *myperm;
+    char *myscon, *mytcon;
+
+    if (scon == NULL || tcon == NULL || tclass == NULL || perm == NULL)
+      goto bail;
+
+    const_scon = env->GetStringUTFChars(scon, NULL);
+    const_tcon = env->GetStringUTFChars(tcon, NULL);
+    mytclass   = env->GetStringUTFChars(tclass, NULL);
+    myperm     = env->GetStringUTFChars(perm, NULL);
+
+    // selinux_check_access needs char* for some
+    myscon = const_cast<char *>(const_scon);
+    mytcon = const_cast<char *>(const_tcon);
+
+    accessGranted = selinux_check_access(myscon, mytcon, mytclass, myperm, NULL);
+
+    LOGV("selinux_check_access returned %d", accessGranted);
+
+    env->ReleaseStringUTFChars(scon, const_scon);
+    env->ReleaseStringUTFChars(tcon, const_tcon);
+    env->ReleaseStringUTFChars(tclass, mytclass);
+    env->ReleaseStringUTFChars(perm, myperm);
+
+  bail:
+    return (accessGranted == 0) ? true : false;
+
+#else
+    return true;
+#endif
+  }
+
+  /*
+   * JNI registration.
+   */
+  static JNINativeMethod method_table[] = {
+
+    /* name,                     signature,                    funcPtr */
+    { "checkSELinuxAccess"       , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess },
+    { "getBooleanNames"          , "()[Ljava/lang/String;"                        , (void*)getBooleanNames  },
+    { "getBooleanValue"          , "(Ljava/lang/String;)Z"                        , (void*)getBooleanValue  },
+    { "getContext"               , "()Ljava/lang/String;"                         , (void*)getCon           },
+    { "getFileContext"           , "(Ljava/lang/String;)Ljava/lang/String;"       , (void*)getFileCon       },
+    { "getPeerContext"           , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon       },
+    { "getPidContext"            , "(I)Ljava/lang/String;"                        , (void*)getPidCon        },
+    { "isSELinuxEnforced"        , "()Z"                                          , (void*)isSELinuxEnforced},
+    { "isSELinuxEnabled"         , "()Z"                                          , (void*)isSELinuxEnabled },
+    { "setBooleanValue"          , "(Ljava/lang/String;Z)Z"                       , (void*)setBooleanValue  },
+    { "setFileContext"           , "(Ljava/lang/String;Ljava/lang/String;)Z"      , (void*)setFileCon       },
+    { "setFSCreateContext"       , "(Ljava/lang/String;)Z"                        , (void*)setFSCreateCon   },
+    { "setSELinuxEnforce"        , "(Z)Z"                                         , (void*)setSELinuxEnforce},
+  };
+
+  static int log_callback(int type, const char *fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    LOG_PRI_VA(ANDROID_LOG_ERROR, "SELinux", fmt, ap);
+    va_end(ap);
+    return 0;
+  }
+
+  int register_android_os_SELinux(JNIEnv *env) {
+#ifdef HAVE_SELINUX
+    union selinux_callback cb;
+    cb.func_log = log_callback;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
+
+    isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false;
+
+#endif
+    return AndroidRuntime::registerNativeMethods(
+         env, "android/os/SELinux",
+         method_table, NELEM(method_table));
+  }
+}
diff --git a/core/tests/coretests/src/android/os/SELinuxTest.java b/core/tests/coretests/src/android/os/SELinuxTest.java
new file mode 100644
index 0000000..9b63a6b
--- /dev/null
+++ b/core/tests/coretests/src/android/os/SELinuxTest.java
@@ -0,0 +1,45 @@
+package android.os;
+
+import android.os.Process;
+import android.os.SELinux;
+import android.test.AndroidTestCase;
+import static junit.framework.Assert.assertEquals;
+
+public class SELinuxTest extends AndroidTestCase {
+
+    public void testgetFileCon() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String ctx = SELinux.getFileContext("/system/bin/toolbox");
+        assertEquals(ctx, "u:object_r:system_file:s0");
+    }
+
+    public void testgetCon() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String mycon = SELinux.getContext();
+        assertEquals(mycon, "u:r:untrusted_app:s0:c33");
+    }
+
+    public void testgetPidCon() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String mycon = SELinux.getPidContext(Process.myPid());
+        assertEquals(mycon, "u:r:untrusted_app:s0:c33");
+    }
+
+    public void testcheckSELinuxAccess() {
+        if(SELinux.isSELinuxEnabled() == false)
+            return;
+
+        String mycon = SELinux.getContext();
+        boolean ret;
+        ret = SELinux.checkSELinuxAccess(mycon, mycon, "process", "fork");
+        assertEquals(ret,"true");
+        ret = SELinux.checkSELinuxAccess(mycon, mycon, "memprotect", "mmap_zero");
+        assertEquals(ret,"true");
+    }
+}
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 3400e97..2480dec 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1047,10 +1047,11 @@
 {
   int32_t exception_code = readAligned<int32_t>();
   if (exception_code == EX_HAS_REPLY_HEADER) {
+    int32_t header_start = dataPosition();
     int32_t header_size = readAligned<int32_t>();
     // Skip over fat responses headers.  Not used (or propagated) in
     // native code
-    setDataPosition(dataPosition() + header_size);
+    setDataPosition(header_start + header_size);
     // And fat response headers are currently only used when there are no
     // exceptions, so return no error:
     return 0;
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index e275aa6..d674374 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -172,6 +172,7 @@
 
     static {
         addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
+        addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
         addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG);
         addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV);
         addFileType("AMR", FILE_TYPE_AMR, "audio/amr");
diff --git a/media/libstagefright/codecs/aacenc/src/aacenc.c b/media/libstagefright/codecs/aacenc/src/aacenc.c
index ad2f29a..d1c8621 100644
--- a/media/libstagefright/codecs/aacenc/src/aacenc.c
+++ b/media/libstagefright/codecs/aacenc/src/aacenc.c
@@ -357,9 +357,9 @@
 		if(config.sampleRate%8000 == 0)
 			tmp =480;
 		/* check the bitrate */
-		if(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) ||
+		if(config.bitRate!=0 && ((config.bitRate/config.nChannelsOut < 4000) ||
            (config.bitRate/config.nChannelsOut > 160000) ||
-		   (config.bitRate > config.sampleRate*6*config.nChannelsOut))
+		   (config.bitRate > config.sampleRate*6*config.nChannelsOut)))
 		{
 			config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
 
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index 07b33b7..ccfe883 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -20,13 +20,16 @@
 
 *******************************************************************************/
 
+/* Include system headers before local headers - the local headers
+ * redefine __inline, which can mess up definitions in libc headers if
+ * they happen to use __inline. */
+#include <string.h>
 #include "basic_op.h"
 #include "oper_32b.h"
 #include "adj_thr_data.h"
 #include "adj_thr.h"
 #include "qc_data.h"
 #include "line_pe.h"
-#include <string.h>
 
 
 #define  minSnrLimit    0x6666 /* 1 dB */
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 5425813..540dda4 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1218,6 +1218,7 @@
             for(MountServiceBinderListener bl : mListeners) {
                 if (bl.mListener == listener) {
                     mListeners.remove(mListeners.indexOf(bl));
+                    listener.asBinder().unlinkToDeath(bl, 0);
                     return;
                 }
             }
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 2a0d2a0..5848cc9 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1103,6 +1103,8 @@
                         ? "SCREEN_BRIGHT_BIT " : "")
                 + (((state & SCREEN_ON_BIT) != 0)
                         ? "SCREEN_ON_BIT " : "")
+                + (((state & BUTTON_BRIGHT_BIT) != 0)
+                        ? "BUTTON_BRIGHT_BIT " : "")
                 + (((state & BATTERY_LOW_BIT) != 0)
                         ? "BATTERY_LOW_BIT " : "");
     }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3ae62ad..ce133f0 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -79,7 +79,7 @@
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
             SystemClock.uptimeMillis());
 
-        Looper.prepare();
+        Looper.prepareMainLooper();
 
         android.os.Process.setThreadPriority(
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index cffb391..6190a63 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1757,7 +1757,7 @@
                 if (cr.binding != null && cr.binding.service != null
                         && cr.binding.service.app != null
                         && cr.binding.service.app.lruSeq != mLruSeq) {
-                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
+                    updateLruProcessInternalLocked(cr.binding.service.app, false,
                             updateActivityTime, i+1);
                 }
             }
@@ -1765,7 +1765,7 @@
         if (app.conProviders.size() > 0) {
             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
                 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
-                    updateLruProcessInternalLocked(cpr.proc, oomAdj,
+                    updateLruProcessInternalLocked(cpr.proc, false,
                             updateActivityTime, i+1);
                 }
             }
diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java
index e3347cb..c5b1c7b 100644
--- a/services/java/com/android/server/am/UriPermission.java
+++ b/services/java/com/android/server/am/UriPermission.java
@@ -59,11 +59,11 @@
         if ((modeFlagsToClear&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
             globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
             modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
-            if (readOwners.size() > 0) {
+            if (writeOwners.size() > 0) {
                 for (UriPermissionOwner r : writeOwners) {
                     r.removeWritePermission(this);
                 }
-                readOwners.clear();
+                writeOwners.clear();
             }
         }
     }
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 84db830..6cfae6a 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -81,14 +81,26 @@
     }
 
     /**
-     * @return cdma base station latitude, Integer.MAX_VALUE if unknown
+     * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+     * It is represented in units of 0.25 seconds and ranges from -1296000
+     * to 1296000, both values inclusive (corresponding to a range of -90
+     * to +90 degrees). Integer.MAX_VALUE is considered invalid value.
+     *
+     * @return cdma base station latitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
      */
     public int getBaseStationLatitude() {
         return this.mBaseStationLatitude;
     }
 
     /**
-     * @return cdma base station longitude, Integer.MAX_VALUE if unknown
+     * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+     * It is represented in units of 0.25 seconds and ranges from -2592000
+     * to 2592000, both values inclusive (corresponding to a range of -180
+     * to +180 degrees). Integer.MAX_VALUE is considered invalid value.
+     *
+     * @return cdma base station longitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
      */
     public int getBaseStationLongitude() {
         return this.mBaseStationLongitude;
@@ -215,6 +227,22 @@
                 this.mNetworkId == -1);
     }
 
+    /**
+     * Converts latitude or longitude from 0.25 seconds (as defined in the
+     * 3GPP2 C.S0005-A v6.0 standard) to decimal degrees
+     *
+     * @param quartSec latitude or longitude in 0.25 seconds units
+     * @return latitude or longitude in decimal degrees units
+     * @throws IllegalArgumentException if value is less than -2592000,
+     *                                  greater than 2592000, or is not a number.
+     */
+    public static double convertQuartSecToDecDegrees(int quartSec) {
+        if(Double.isNaN(quartSec) || quartSec < -2592000 || quartSec > 2592000){
+            // Invalid value
+            throw new IllegalArgumentException("Invalid coordiante value:" + quartSec);
+        }
+        return ((double)quartSec) / (3600 * 4);
+    }
 
 }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index e1f4c4b..5c95e7d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -1240,7 +1240,7 @@
                 // If the radio shuts off or resets while one of these
                 // is pending, we need to clean up.
 
-                for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
+                for (int i = mPendingMMIs.size() - 1; i >= 0; i--) {
                     if (mPendingMMIs.get(i).isPendingUSSD()) {
                         mPendingMMIs.get(i).onUssdFinishedError();
                     }