Merge "Handle nested folder case"
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index d36d99d..01c0634 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -289,7 +289,7 @@
 
     /**
      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
-     * array of Intents to be supplied.  The first Intent in the array is
+     * array of Intents to be supplied.  The last Intent in the array is
      * taken as the primary key for the PendingIntent, like the single Intent
      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
      * the resulting PendingIntent, all of the Intents are started in the same
@@ -335,7 +335,7 @@
 
     /**
      * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
-     * array of Intents to be supplied.  The first Intent in the array is
+     * array of Intents to be supplied.  The last Intent in the array is
      * taken as the primary key for the PendingIntent, like the single Intent
      * given to {@link #getActivity(Context, int, Intent, int)}.  Upon sending
      * the resulting PendingIntent, all of the Intents are started in the same
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index cf0603e..89b1bbd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1950,7 +1950,7 @@
 
     /**
      * Broadcast Action:  External media is present, but not mounted at its mount point.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the unmounted media is contained in the Intent.mData field.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
@@ -1971,7 +1971,7 @@
 
     /**
      * Broadcast Action:  External media is present and mounted at its mount point.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the mounted media is contained in the Intent.mData field.
      * The Intent contains an extra with name "read-only" and Boolean value to indicate if the
      * media was mounted read only.
      */
@@ -2002,7 +2002,7 @@
 
     /**
      * Broadcast Action:  External media is present but cannot be mounted.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the unmountable media is contained in the Intent.mData field.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE";
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index fe6d4eb..5b60c0d 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -334,9 +334,11 @@
 
     /**
      * A distinguished name helper class: a 3-tuple of:
-     * - common name (CN),
-     * - organization (O),
-     * - organizational unit (OU)
+     * <ul>
+     *   <li>the most specific common name (CN)</li>
+     *   <li>the most specific organization (O)</li>
+     *   <li>the most specific organizational unit (OU)</li>
+     * <ul>
      */
     public class DName {
         /**
@@ -360,8 +362,15 @@
         private String mUName;
 
         /**
-         * Creates a new distinguished name
-         * @param dName The distinguished name
+         * Creates a new {@code DName} from a string. The attributes
+         * are assumed to come in most significant to least
+         * significant order which is true of human readable values
+         * returned by methods such as {@code X500Principal.getName()}.
+         * Be aware that the underlying sources of distinguished names
+         * such as instances of {@code X509Certificate} are encoded in
+         * least significant to most significant order, so make sure
+         * the value passed here has the expected ordering of
+         * attributes.
          */
         public DName(String dName) {
             if (dName != null) {
@@ -374,18 +383,24 @@
 
                     for (int i = 0; i < oid.size(); i++) {
                         if (oid.elementAt(i).equals(X509Name.CN)) {
-                            mCName = (String) val.elementAt(i);
+                            if (mCName == null) {
+                                mCName = (String) val.elementAt(i);
+                            }
                             continue;
                         }
 
                         if (oid.elementAt(i).equals(X509Name.O)) {
-                            mOName = (String) val.elementAt(i);
-                            continue;
+                            if (mOName == null) {
+                                mOName = (String) val.elementAt(i);
+                                continue;
+                            }
                         }
 
                         if (oid.elementAt(i).equals(X509Name.OU)) {
-                            mUName = (String) val.elementAt(i);
-                            continue;
+                            if (mUName == null) {
+                                mUName = (String) val.elementAt(i);
+                                continue;
+                            }
                         }
                     }
                 } catch (IllegalArgumentException ex) {
@@ -402,21 +417,21 @@
         }
 
         /**
-         * @return The Common-name (CN) component of this name
+         * @return The most specific Common-name (CN) component of this name
          */
         public String getCName() {
             return mCName != null ? mCName : "";
         }
 
         /**
-         * @return The Organization (O) component of this name
+         * @return The most specific Organization (O) component of this name
          */
         public String getOName() {
             return mOName != null ? mOName : "";
         }
 
         /**
-         * @return The Organizational Unit (OU) component of this name
+         * @return The most specific Organizational Unit (OU) component of this name
          */
         public String getUName() {
             return mUName != null ? mUName : "";
diff --git a/core/tests/coretests/src/android/net/http/SslCertificateTest.java b/core/tests/coretests/src/android/net/http/SslCertificateTest.java
index 147816b..6a30c6c 100644
--- a/core/tests/coretests/src/android/net/http/SslCertificateTest.java
+++ b/core/tests/coretests/src/android/net/http/SslCertificateTest.java
@@ -45,11 +45,70 @@
 
     @LargeTest
     public void testSslCertificateWithEmptyIssuer() throws Exception {
-        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
-        X509Certificate x509Certificate = (X509Certificate)
-            certificateFactory.generateCertificate(new ByteArrayInputStream(Issue1597Certificate.getBytes()));
-        assertEquals(x509Certificate.getIssuerDN().getName(), "");
+        X509Certificate x509Certificate = generateCertificate(Issue1597Certificate);
+        assertEquals("", x509Certificate.getSubjectDN().getName());
         SslCertificate sslCertificate = new SslCertificate(x509Certificate);
-        assertEquals(sslCertificate.getIssuedBy().getDName(), "");
+        assertEquals("", sslCertificate.getIssuedBy().getDName());
     }
+
+    /**
+     * Problematic certificate from Issue 41662
+     * http://code.google.com/p/android/issues/detail?id=41662
+     */
+    private static final String Issue41662Certificate =
+        "-----BEGIN CERTIFICATE-----\n"+
+        "MIIG6jCCBdKgAwIBAgIESPx/LDANBgkqhkiG9w0BAQUFADCBrjESMBAGCgmSJomT\n"+
+        "8ixkARkWAnJzMRUwEwYKCZImiZPyLGQBGRYFcG9zdGExEjAQBgoJkiaJk/IsZAEZ\n"+
+        "FgJjYTEWMBQGA1UEAxMNQ29uZmlndXJhdGlvbjERMA8GA1UEAxMIU2VydmljZXMx\n"+
+        "HDAaBgNVBAMTE1B1YmxpYyBLZXkgU2VydmljZXMxDDAKBgNVBAMTA0FJQTEWMBQG\n"+
+        "A1UEAxMNUG9zdGEgQ0EgUm9vdDAeFw0wODEwMjAxNDExMzBaFw0yODEwMTQyMjAw\n"+
+        "MDBaMIGrMRIwEAYKCZImiZPyLGQBGRYCcnMxFTATBgoJkiaJk/IsZAEZFgVwb3N0\n"+
+        "YTESMBAGCgmSJomT8ixkARkWAmNhMRYwFAYDVQQDEw1Db25maWd1cmF0aW9uMREw\n"+
+        "DwYDVQQDEwhTZXJ2aWNlczEcMBoGA1UEAxMTUHVibGljIEtleSBTZXJ2aWNlczEM\n"+
+        "MAoGA1UEAxMDQUlBMRMwEQYDVQQDEwpQb3N0YSBDQSAxMIIBIjANBgkqhkiG9w0B\n"+
+        "AQEFAAOCAQ8AMIIBCgKCAQEAl5msW5MdLW/2aDlezrjU3jW58MKrcMPHs2szlGdL\n"+
+        "nsAcSyYFF1JbyA8iuqLp7mhvcTz9m4jK82XBz/1mPq8wJMU9ekGnLhgbKLGKXRBA\n"+
+        "sY9wzCvwpweQV6ui4vr2eOkS1j9Mk7ikatH8tNiIzkNrTj3npDpZv1w4G37iwtpb\n"+
+        "yjg+lkNIDY2nWV9roBsAZM8Lvbyi4vxP41YEQZ3hxaGGG0/RKHbugvGatgckxfin\n"+
+        "4gpFG2mDhS9uafGgqnLHLwpxgBbi3g6+2TsxOKatTxwxx9/4MND1GjhxKTjDNYPl\n"+
+        "5JHUvr9fcvQMxP21/jbO4EsCWG+F38R90kT37hFL3l1qiQIDAQABo4IDDzCCAwsw\n"+
+        "DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgcwGA1UdIASBxDCBwTCB\n"+
+        "vgYLKwYBBAH6OAoyAQEwga4wMAYIKwYBBQUHAgEWJGh0dHA6Ly93d3cuY2EucG9z\n"+
+        "dGEucnMvZG9rdW1lbnRhY2lqYTB6BggrBgEFBQcCAjBuGmxPdm8gamUgZWxla3Ry\n"+
+        "b25za2kgc2VydGlmaWthdCBpemRhdmFja29nIChwcm9kdWtjaW9ub2cpIENBIHNl\n"+
+        "cnZlcmEgU2VydGlmaWthY2lvbm9nIHRlbGEgUG9zdGU6ICJQb3N0YSBDQSAxIi4w\n"+
+        "ggG8BgNVHR8EggGzMIIBrzCByaCBxqCBw6SBwDCBvTESMBAGCgmSJomT8ixkARkW\n"+
+        "AnJzMRUwEwYKCZImiZPyLGQBGRYFcG9zdGExEjAQBgoJkiaJk/IsZAEZFgJjYTEW\n"+
+        "MBQGA1UEAxMNQ29uZmlndXJhdGlvbjERMA8GA1UEAxMIU2VydmljZXMxHDAaBgNV\n"+
+        "BAMTE1B1YmxpYyBLZXkgU2VydmljZXMxDDAKBgNVBAMTA0FJQTEWMBQGA1UEAxMN\n"+
+        "UG9zdGEgQ0EgUm9vdDENMAsGA1UEAxMEQ1JMMTCB4KCB3aCB2oaBo2xkYXA6Ly9s\n"+
+        "ZGFwLmNhLnBvc3RhLnJzL2NuPVBvc3RhJTIwQ0ElMjBSb290LGNuPUFJQSxjbj1Q\n"+
+        "dWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxjbj1TZXJ2aWNlcyxjbj1Db25maWd1cmF0\n"+
+        "aW9uLGRjPWNhLGRjPXBvc3RhLGRjPXJzP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxp\n"+
+        "c3QlM0JiaW5hcnmGMmh0dHA6Ly9zZXJ0aWZpa2F0aS5jYS5wb3N0YS5ycy9jcmwv\n"+
+        "UG9zdGFDQVJvb3QuY3JsMB8GA1UdIwQYMBaAFPLLjeI17xBDxNp7yvrriQOhIq+4\n"+
+        "MB0GA1UdDgQWBBQuZ6cm1uhncOeq+pAsMLzXYWUfhjAZBgkqhkiG9n0HQQAEDDAK\n"+
+        "GwRWNy4xAwIAgTANBgkqhkiG9w0BAQUFAAOCAQEAjpmoaebsvfjgwgCYArou/s8k\n"+
+        "Tr50TUdcJYxAYmCFQp531E1F+qUCWM/7bZApqByR3+EUz8goI5O2Cp/6ISxTR1HC\n"+
+        "Dn71ESg7/c8Bs2Obx0LGYPnlRPvw7LH31dYXpj4EMNAamhOfBXgY2htXHCd7daIe\n"+
+        "thvNkqWGDzmcoaGw/2BMNadlYkdXxudDBaiPDFm27yR7fPRibjxwkQVknzFezX/y\n"+
+        "46j+20LoGJ/IpneT209XzytiaqtZBy3yqz2qImVDqvn5doHw63LOUqt8vfDS1sbd\n"+
+        "zi3acAmPK1nERdCMJYJEEGNiGbkbw2cghwLw/4eYGXlj1VLXD3GU42uBr8QftA==\n"+
+        "-----END CERTIFICATE-----\n";
+
+    @LargeTest
+    public void testSslCertificateWithMultipleCN() throws Exception {
+        X509Certificate x509Certificate = generateCertificate(Issue41662Certificate);
+        String dn = x509Certificate.getSubjectDN().getName();
+        assertTrue(dn, dn.contains("Posta CA 1"));
+        assertTrue(dn, dn.contains("Configuration"));
+        SslCertificate sslCertificate = new SslCertificate(x509Certificate);
+        assertEquals(dn, "Posta CA 1", sslCertificate.getIssuedTo().getCName());
+    }
+
+    private static X509Certificate generateCertificate(String pem) throws Exception {
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(pem.getBytes()));
+    }
+
 }
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 94e2286..52df8d0 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -77,6 +77,7 @@
     <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
     <bool name="def_lockscreen_disabled">false</bool>
     <bool name="def_device_provisioned">false</bool>
+    <integer name="def_dock_audio_media_enabled">1</integer>
 
     <!-- Notifications use ringer volume -->
     <bool name="def_notifications_use_ring_volume">true</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index b649b43..7864ec2 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2181,6 +2181,9 @@
             loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND,
                     R.string.def_car_undock_sound);
 
+            loadIntegerSetting(stmt, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED,
+                    R.integer.def_dock_audio_media_enabled);
+
             loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
             loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
                     PackageHelper.APP_INSTALL_AUTO);