Merge "Fix tiling on QCOM GPU"
diff --git a/api/current.txt b/api/current.txt
index ab91974..b38fd60 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -728,6 +728,7 @@
     field public static final int minSdkVersion = 16843276; // 0x101020c
     field public static final int minWidth = 16843071; // 0x101013f
     field public static final int mipMap = 16843725; // 0x10103cd
+    field public static final int mirrorForRtl = 16843726; // 0x10103ce
     field public static final int mode = 16843134; // 0x101017e
     field public static final int moreIcon = 16843061; // 0x1010135
     field public static final int multiprocess = 16842771; // 0x1010013
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 2dc0501..ef7186b 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -149,8 +149,13 @@
      * accessibility service that has this flag set. Hence, clearing this
      * flag does not guarantee that the device will not be in touch exploration
      * mode since there may be another enabled service that requested it.
+     * <p>
+     * Clients that want to set this flag have to request the
+     * {@link android.Manifest.permission#CAN_REQUEST_TOUCH_EXPLORATION_MODE}
+     * permission or the flag will be ignored.
+     * </p>
      */
-    public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE= 0x0000004;
+    public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
 
     /**
      * This flag requests from the system to enable web accessibility enhancing
@@ -161,6 +166,11 @@
      * that has this flag set. Hence, clearing this flag does not guarantee that the
      * device will not have enhanced web accessibility enabled since there may be
      * another enabled service that requested it.
+     * <p>
+     * Clients that want to set this flag have to request the
+     * {@link android.Manifest.permission#CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY}
+     * permission or the flag will be ignored.
+     * </p>
      */
     public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
 
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 262d87d..6b00c58 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -212,8 +212,10 @@
                 } catch (RemoteException ex) {
                     throw new RuntimeException("Could not get input device information.", ex);
                 }
+                if (inputDevice != null) {
+                    mInputDevices.setValueAt(index, inputDevice);
+                }
             }
-            mInputDevices.setValueAt(index, inputDevice);
             return inputDevice;
         }
     }
@@ -241,6 +243,8 @@
                         inputDevice = mIm.getInputDevice(id);
                     } catch (RemoteException ex) {
                         // Ignore the problem for the purposes of this method.
+                    }
+                    if (inputDevice == null) {
                         continue;
                     }
                     mInputDevices.setValueAt(i, inputDevice);
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 3b5e75b..7674837 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -305,7 +305,7 @@
         }
         
         // Canvas will be translated, so 0,0 is where we start drawing
-        final int left = isLayoutRtl() ? available - thumbPos : thumbPos;
+        final int left = (isLayoutRtl() && mMirrorForRtl) ? available - thumbPos : thumbPos;
         thumb.setBounds(left, topBound, left + thumbWidth, bottomBound);
     }
 
@@ -426,7 +426,7 @@
         int x = (int)event.getX();
         float scale;
         float progress = 0;
-        if (isLayoutRtl()) {
+        if (isLayoutRtl() && mMirrorForRtl) {
             if (x > width - mPaddingRight) {
                 scale = 0.0f;
             } else if (x < mPaddingLeft) {
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index f2d2c65..d816200 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -223,6 +223,8 @@
     private boolean mAttached;
     private boolean mRefreshIsPosted;
 
+    boolean mMirrorForRtl = false;
+
     private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
 
     private AccessibilityEventSender mAccessibilityEventSender;
@@ -302,6 +304,8 @@
         setIndeterminate(mOnlyIndeterminate || a.getBoolean(
                 R.styleable.ProgressBar_indeterminate, mIndeterminate));
 
+        mMirrorForRtl = a.getBoolean(R.styleable.ProgressBar_mirrorForRtl, mMirrorForRtl);
+
         a.recycle();
     }
 
@@ -1004,7 +1008,7 @@
                     }
                 }
             }
-            if (isLayoutRtl()) {
+            if (isLayoutRtl() && mMirrorForRtl) {
                 int tempLeft = left;
                 left = w - right;
                 right = w - tempLeft;
@@ -1026,7 +1030,7 @@
             // Translate canvas so a indeterminate circular progress bar with padding
             // rotates properly in its animation
             canvas.save();
-            if(isLayoutRtl()) {
+            if(isLayoutRtl() && mMirrorForRtl) {
                 canvas.translate(getWidth() - mPaddingRight, mPaddingTop);
                 canvas.scale(-1.0f, 1.0f);
             } else {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 692c17c..e5aca48 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2290,6 +2290,12 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.updates.TZInfoInstallReceiver" >
+            <intent-filter>
+                <action android:name="android.intent.action.UPDATE_TZINFO" />
+            </intent-filter>
+        </receiver>
+
         <receiver android:name="com.android.server.MasterClearReceiver"
             android:permission="android.permission.MASTER_CLEAR"
             android:priority="100" >
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index ab2bd3a..cdf0d7e 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2962,6 +2962,9 @@
         <!-- Timeout between frames of animation in milliseconds
              {@deprecated Not used by the framework.} -->
         <attr name="animationResolution" format="integer" />
+        <!-- Defines if the associated drawables need to be mirrored when in RTL mode.
+             Default is false -->
+        <attr name="mirrorForRtl" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="SeekBar">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 49b536d..0d80082 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2034,5 +2034,6 @@
   <eat-comment />
 
   <public type="attr" name="mipMap" id="0x010103cd" />
+  <public type="attr" name="mirrorForRtl" id="0x010103ce" />
 
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f489786..56c2235 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -370,6 +370,7 @@
         <item name="android:maxWidth">48dip</item>
         <item name="android:minHeight">48dip</item>
         <item name="android:maxHeight">48dip</item>
+        <item name="android:mirrorForRtl">false</item>
     </style>
 
     <style name="Widget.ProgressBar.Large">
@@ -410,6 +411,7 @@
         <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
         <item name="android:minHeight">20dip</item>
         <item name="android:maxHeight">20dip</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.SeekBar">
@@ -421,6 +423,7 @@
         <item name="android:thumb">@android:drawable/seek_thumb</item>
         <item name="android:thumbOffset">8dip</item>
         <item name="android:focusable">true</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.RatingBar">
@@ -430,6 +433,7 @@
         <item name="android:minHeight">57dip</item>
         <item name="android:maxHeight">57dip</item>
         <item name="android:thumb">@null</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.RatingBar.Indicator">
@@ -1745,6 +1749,7 @@
         <item name="android:focusable">true</item>
         <item name="android:paddingStart">16dip</item>
         <item name="android:paddingEnd">16dip</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.Holo.RatingBar" parent="Widget.RatingBar">
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 772cb4c..5383d08 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -290,6 +290,10 @@
             mChannelCount = 2;
             mChannels = AudioFormat.CHANNEL_IN_STEREO;
             break;
+        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
+            mChannelCount = 2;
+            mChannels = channelConfig;
+            break;
         default:
             mChannelCount = 0;
             mChannels = AudioFormat.CHANNEL_INVALID;
@@ -464,6 +468,7 @@
             break;
         case AudioFormat.CHANNEL_IN_STEREO:
         case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
             channelCount = 2;
             break;
         case AudioFormat.CHANNEL_INVALID:
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index 4480151..b065310 100644
--- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -77,7 +77,7 @@
                     // get the certificate from Settings.Secure
                     X509Certificate cert = getCert(context.getContentResolver());
                     // get the content path from the extras
-                    String altContent = getAltContent(intent);
+                    byte[] altContent = getAltContent(intent);
                     // get the version from the extras
                     int altVersion = getVersionFromIntent(intent);
                     // get the previous value from the extras
@@ -172,28 +172,26 @@
         }
     }
 
-    private String getAltContent(Intent i) throws IOException {
-        String contents = IoUtils.readFileAsString(getContentFromIntent(i));
-        return contents.trim();
+    private byte[] getAltContent(Intent i) throws IOException {
+        return IoUtils.readFileAsByteArray(getContentFromIntent(i));
     }
 
-    private String getCurrentContent() {
+    private byte[] getCurrentContent() {
         try {
-            return IoUtils.readFileAsString(updateContent.getCanonicalPath()).trim();
+            return IoUtils.readFileAsByteArray(updateContent.getCanonicalPath());
         } catch (IOException e) {
             Slog.i(TAG, "Failed to read current content, assuming first update!");
             return null;
         }
     }
 
-    private static String getCurrentHash(String content) {
+    private static String getCurrentHash(byte[] content) {
         if (content == null) {
             return "0";
         }
         try {
             MessageDigest dgst = MessageDigest.getInstance("SHA512");
-            byte[] encoded = content.getBytes();
-            byte[] fingerprint = dgst.digest(encoded);
+            byte[] fingerprint = dgst.digest(content);
             return IntegralToString.bytesToHexString(fingerprint, false);
         } catch (NoSuchAlgorithmException e) {
             throw new AssertionError(e);
@@ -213,17 +211,17 @@
         return current.equals(required);
     }
 
-    private boolean verifySignature(String content, int version, String requiredPrevious,
+    private boolean verifySignature(byte[] content, int version, String requiredPrevious,
                                    String signature, X509Certificate cert) throws Exception {
         Signature signer = Signature.getInstance("SHA512withRSA");
         signer.initVerify(cert);
-        signer.update(content.getBytes());
+        signer.update(content);
         signer.update(Long.toString(version).getBytes());
         signer.update(requiredPrevious.getBytes());
         return signer.verify(Base64.decode(signature.getBytes(), Base64.DEFAULT));
     }
 
-    private void writeUpdate(File dir, File file, String content) throws IOException {
+    private void writeUpdate(File dir, File file, byte[] content) throws IOException {
         FileOutputStream out = null;
         File tmp = null;
         try {
@@ -240,7 +238,7 @@
             tmp.setReadable(true, false);
             // write to it
             out = new FileOutputStream(tmp);
-            out.write(content.getBytes());
+            out.write(content);
             // sync to disk
             out.getFD().sync();
             // atomic rename
@@ -255,8 +253,8 @@
         }
     }
 
-    private void install(String content, int version) throws IOException {
+    protected void install(byte[] content, int version) throws IOException {
         writeUpdate(updateDir, updateContent, content);
-        writeUpdate(updateDir, updateVersion, Long.toString(version));
+        writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
     }
 }
diff --git a/services/java/com/android/server/updates/TZInfoInstallReceiver.java b/services/java/com/android/server/updates/TZInfoInstallReceiver.java
new file mode 100644
index 0000000..83adbdb
--- /dev/null
+++ b/services/java/com/android/server/updates/TZInfoInstallReceiver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 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 com.android.server.updates;
+
+import android.util.Base64;
+import android.util.Slog;
+
+import java.io.IOException;
+
+public class TZInfoInstallReceiver extends ConfigUpdateInstallReceiver {
+
+    public TZInfoInstallReceiver() {
+        super("/data/misc/zoneinfo/", "tzdata", "metadata/", "version");
+    }
+
+    @Override
+    protected void install(byte[] encodedContent, int version) throws IOException {
+        super.install(Base64.decode(encodedContent, Base64.DEFAULT), version);
+    }
+}