am 59c73b92: Merge "Convert soft ap config store to state machine" into ics-mr1

* commit '59c73b92a9ef8df5d4873bc36f05b776c3a476bc':
  Convert soft ap config store to state machine
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index bf19040..640e9fa 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -381,7 +381,7 @@
         LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
     }
 
-    entry->mNotifyConsumed->setInt32("render", true);
+    entry->mNotifyConsumed->setInt32("render", !tooLate);
     entry->mNotifyConsumed->post();
     mVideoQueue.erase(mVideoQueue.begin());
     entry = NULL;
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 81e1901..0f21bdb 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -360,8 +360,7 @@
                 mHasOverlay = true;
 
                 // Continue showing FaceLock area until dialer comes up or call is resumed
-                if (mLockPatternUtils.usingBiometricWeak() &&
-                        mLockPatternUtils.isBiometricWeakInstalled() && mFaceLockServiceRunning) {
+                if (usingFaceLock() && mFaceLockServiceRunning) {
                     showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
                 }
 
@@ -582,8 +581,7 @@
             bindToFaceLock();
             // Show FaceLock area, but only for a little bit so lockpattern will become visible if
             // FaceLock fails to start or crashes
-            if (mLockPatternUtils.usingBiometricWeak() &&
-                    mLockPatternUtils.isBiometricWeakInstalled()) {
+            if (usingFaceLock()) {
                 showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
             }
         } else {
@@ -653,11 +651,10 @@
             ((KeyguardScreen) mUnlockScreen).onResume();
         }
 
-        if (mLockPatternUtils.usingBiometricWeak() &&
-            mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) {
+        if (usingFaceLock() && !mHasOverlay) {
             // Note that show() gets called before the screen turns off to set it up for next time
             // it is turned on.  We don't want to set a timeout on the FaceLock area here because it
-            // may be gone by the time the screen is turned on again.  We set the timout when the
+            // may be gone by the time the screen is turned on again.  We set the timeout when the
             // screen turns on instead.
             showFaceLockArea();
         } else {
@@ -854,7 +851,9 @@
         if (mode == Mode.UnlockScreen) {
             final UnlockMode unlockMode = getUnlockMode();
             if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
+                boolean restartFaceLock = stopFaceLockIfRunning();
                 recreateUnlockScreen(unlockMode);
+                if (restartFaceLock) activateFaceLockIfAble();
             }
         }
 
@@ -1147,28 +1146,33 @@
 
     // Everything below pertains to FaceLock - might want to separate this out
 
-    // Take care of FaceLock area when layout is created
+    // Indicates whether FaceLock is in use
+    private boolean usingFaceLock() {
+        return (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled());
+    }
+
+    // Takes care of FaceLock area when layout is created
     private void initializeFaceLockAreaView(View view) {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
             if (mFaceLockAreaView == null) {
                 Log.e(TAG, "Layout does not have faceLockAreaView and FaceLock is enabled");
-            } else {
-                if (mBoundToFaceLockService) {
-                    // If we are creating a layout when we are already bound to FaceLock, then we
-                    // are undergoing an orientation change.  Stop FaceLock and restart it in the
-                    // new location.
-                    if (DEBUG) Log.d(TAG, "Restarting FL - creating view while already bound");
-                    stopAndUnbindFromFaceLock();
-                    activateFaceLockIfAble();
-                }
             }
         } else {
             mFaceLockAreaView = null; // Set to null if not using FaceLock
         }
     }
 
+    // Stops FaceLock if it is running and reports back whether it was running or not
+    private boolean stopFaceLockIfRunning() {
+        if (usingFaceLock() && mBoundToFaceLockService) {
+            stopAndUnbindFromFaceLock();
+            return true;
+        }
+        return false;
+    }
+
     // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
     // This needs to be done in a handler because the call could be coming from a callback from the
     // FaceLock service that is in a thread that can't modify the UI
@@ -1221,8 +1225,7 @@
     // Binds to FaceLock service.  This call does not tell it to start, but it causes the service
     // to call the onServiceConnected callback, which then starts FaceLock.
     public void bindToFaceLock() {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             if (!mBoundToFaceLockService) {
                 if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
                 mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
@@ -1238,8 +1241,7 @@
 
     // Tells FaceLock to stop and then unbinds from the FaceLock service
     public void stopAndUnbindFromFaceLock() {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             stopFaceLock();
 
             if (mBoundToFaceLockService) {
@@ -1300,8 +1302,7 @@
     // Tells the FaceLock service to start displaying its UI and perform recognition
     public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
     {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             synchronized (mFaceLockServiceRunningLock) {
                 if (!mFaceLockServiceRunning) {
                     if (DEBUG) Log.d(TAG, "Starting FaceLock");
@@ -1322,8 +1323,7 @@
     // Tells the FaceLock service to stop displaying its UI and stop recognition
     public void stopFaceLock()
     {
-        if (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled()) {
+        if (usingFaceLock()) {
             // Note that attempting to stop FaceLock when it's not running is not an issue.
             // FaceLock can return, which stops it and then we try to stop it when the
             // screen is turned off.  That's why we check.
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index fc8a145..1410747 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -291,12 +291,31 @@
         // flexibly...
 
         int limit;
-        if (ted.msgCount > 1) {
-            limit = (ted.codeUnitSize == ENCODING_7BIT) ?
-                MAX_USER_DATA_SEPTETS_WITH_HEADER : MAX_USER_DATA_BYTES_WITH_HEADER;
+        if (ted.codeUnitSize == ENCODING_7BIT) {
+            int udhLength;
+            if (ted.languageTable != 0 && ted.languageShiftTable != 0) {
+                udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES;
+            } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) {
+                udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE;
+            } else {
+                udhLength = 0;
+            }
+
+            if (ted.msgCount > 1) {
+                udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE;
+            }
+
+            if (udhLength != 0) {
+                udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH;
+            }
+
+            limit = MAX_USER_DATA_SEPTETS - udhLength;
         } else {
-            limit = (ted.codeUnitSize == ENCODING_7BIT) ?
-                MAX_USER_DATA_SEPTETS : MAX_USER_DATA_BYTES;
+            if (ted.msgCount > 1) {
+                limit = MAX_USER_DATA_BYTES_WITH_HEADER;
+            } else {
+                limit = MAX_USER_DATA_BYTES;
+            }
         }
 
         int pos = 0;  // Index in code units.
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 2e99849..25647ac 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -60,25 +60,25 @@
      * all combinations of header elements below will have at least one free bit
      * when padding to the nearest septet boundary.
      */
-    private static final int UDH_SEPTET_COST_LENGTH = 1;
+    public static final int UDH_SEPTET_COST_LENGTH = 1;
 
     /**
      * Using a non-default language locking shift table OR single shift table
      * requires a user data header of 3 octets, or 4 septets, plus UDH length.
      */
-    private static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4;
+    public static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4;
 
     /**
      * Using a non-default language locking shift table AND single shift table
      * requires a user data header of 6 octets, or 7 septets, plus UDH length.
      */
-    private static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7;
+    public static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7;
 
     /**
      * Multi-part messages require a user data header of 5 octets, or 6 septets,
      * plus UDH length.
      */
-    private static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
+    public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
 
     /**
      * Converts a char to a GSM 7 bit table index.
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
index 41a719e..5950669 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
@@ -16,11 +16,14 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
 import com.android.internal.telephony.gsm.SmsMessage;
 import com.android.internal.util.HexDump;
 
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import java.util.ArrayList;
 
 public class GsmSmsTest extends AndroidTestCase {
 
@@ -232,6 +235,110 @@
     };
 
     @SmallTest
+    public void testFragmentText() throws Exception {
+        boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
+                TelephonyManager.PHONE_TYPE_GSM);
+
+        // Valid 160 character 7-bit text.
+        String text = "123456789012345678901234567890123456789012345678901234567890" +
+                "1234567890123456789012345678901234567890123456789012345678901234567890" +
+                "123456789012345678901234567890";
+        SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
+        assertEquals(1, ted.msgCount);
+        assertEquals(160, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(0, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(1, fragments.size());
+        }
+
+        // Valid 161 character 7-bit text.
+        text = "123456789012345678901234567890123456789012345678901234567890" +
+                "1234567890123456789012345678901234567890123456789012345678901234567890" +
+                "1234567890123456789012345678901";
+        ted = SmsMessage.calculateLength(text, false);
+        assertEquals(2, ted.msgCount);
+        assertEquals(161, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(0, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(2, fragments.size());
+            assertEquals(text, fragments.get(0) + fragments.get(1));
+            assertEquals(153, fragments.get(0).length());
+            assertEquals(8, fragments.get(1).length());
+        }
+    }
+
+    @SmallTest
+    public void testFragmentTurkishText() throws Exception {
+        boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
+                TelephonyManager.PHONE_TYPE_GSM);
+
+        int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables();
+        int[] turkishTable = { 1 };
+        GsmAlphabet.setEnabledSingleShiftTables(turkishTable);
+
+        // Valid 77 character text with Turkish characters.
+        String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
+                "ĞŞİğşıĞŞİğşıĞŞİğş";
+        SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
+        assertEquals(1, ted.msgCount);
+        assertEquals(154, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(1, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(1, fragments.size());
+            assertEquals(text, fragments.get(0));
+            assertEquals(77, fragments.get(0).length());
+        }
+
+        // Valid 78 character text with Turkish characters.
+        text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
+                "ĞŞİğşıĞŞİğşıĞŞİğşı";
+        ted = SmsMessage.calculateLength(text, false);
+        assertEquals(2, ted.msgCount);
+        assertEquals(156, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(1, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(2, fragments.size());
+            assertEquals(text, fragments.get(0) + fragments.get(1));
+            assertEquals(74, fragments.get(0).length());
+            assertEquals(4, fragments.get(1).length());
+        }
+
+        // Valid 160 character text with Turkish characters.
+        text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
+                "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" +
+                "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı";
+        ted = SmsMessage.calculateLength(text, false);
+        assertEquals(3, ted.msgCount);
+        assertEquals(320, ted.codeUnitCount);
+        assertEquals(1, ted.codeUnitSize);
+        assertEquals(0, ted.languageTable);
+        assertEquals(1, ted.languageShiftTable);
+        if (isGsmPhone) {
+            ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
+            assertEquals(3, fragments.size());
+            assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2));
+            assertEquals(74, fragments.get(0).length());
+            assertEquals(74, fragments.get(1).length());
+            assertEquals(12, fragments.get(2).length());
+        }
+
+        GsmAlphabet.setEnabledSingleShiftTables(oldTables);
+    }
+
+
+    @SmallTest
     public void testDecode() throws Exception {
         decodeSingle(0);    // default table
         decodeSingle(1);    // Turkish locking shift table