Merge "s/should/can"
diff --git a/core/java/android/webkit/JniUtil.java b/core/java/android/webkit/JniUtil.java
index 7759ff3..4662040 100644
--- a/core/java/android/webkit/JniUtil.java
+++ b/core/java/android/webkit/JniUtil.java
@@ -22,6 +22,7 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import java.io.File;
 import java.io.InputStream;
 
 class JniUtil {
@@ -79,7 +80,12 @@
         checkInitialized();
 
         if (sCacheDirectory == null) {
-            sCacheDirectory = sContext.getCacheDir().getAbsolutePath();
+            File cacheDir = sContext.getCacheDir();
+            if (cacheDir == null) {
+                sCacheDirectory = "";
+            } else {
+                sCacheDirectory = cacheDir.getAbsolutePath();
+            }
         }
 
         return sCacheDirectory;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index f1c2bde..f240a2e 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -777,7 +777,7 @@
     public void setDoubleTapZoom(int doubleTapZoom) {
         if (mDoubleTapZoom != doubleTapZoom) {
             mDoubleTapZoom = doubleTapZoom;
-            mWebView.updateDoubleTapZoom();
+            mWebView.updateDoubleTapZoom(doubleTapZoom);
         }
     }
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 71ba7eb..a814b12 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2995,8 +2995,8 @@
     /**
      * Update the double-tap zoom.
      */
-    /* package */ void updateDoubleTapZoom() {
-        mZoomManager.updateDoubleTapZoom();
+    /* package */ void updateDoubleTapZoom(int doubleTapZoom) {
+        mZoomManager.updateDoubleTapZoom(doubleTapZoom);
     }
 
     private int computeRealHorizontalScrollRange() {
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 9151fdd..7d3cf8e 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -152,6 +152,12 @@
     private float mDisplayDensity;
 
     /*
+     * The factor that is used to tweak the zoom scale on a double-tap,
+     * and can be changed via WebSettings. Range is from 0.75f to 1.25f.
+     */
+    private float mDoubleTapZoomFactor = 1.0f;
+
+    /*
      * The scale factor that is used as the minimum increment when going from
      * overview to reading level on a double tap.
      */
@@ -314,10 +320,7 @@
      * Returns the zoom scale used for reading text on a double-tap.
      */
     public final float getReadingLevelScale() {
-        WebSettings settings = mWebView.getSettings();
-        final float doubleTapZoomFactor = settings != null
-            ? settings.getDoubleTapZoom() / 100.f : 1.0f;
-        return mDisplayDensity * doubleTapZoomFactor;
+        return mDisplayDensity * mDoubleTapZoomFactor;
     }
 
     public final float getInvDefaultScale() {
@@ -516,8 +519,9 @@
         return mZoomScale != 0 || mInHWAcceleratedZoom;
     }
 
-    public void updateDoubleTapZoom() {
+    public void updateDoubleTapZoom(int doubleTapZoom) {
         if (mInZoomOverview) {
+            mDoubleTapZoomFactor = doubleTapZoom / 100.0f;
             mTextWrapScale = getReadingLevelScale();
             refreshZoomScale(true);
         }
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 0b53850..c207150 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -534,7 +534,7 @@
 #if DEBUG_GLYPHS
     LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs,
             shaperItem.kerning_applied);
-    LOGD("         -- string= '%s'", String8(chars + start, count).string());
+    LOGD("         -- string= '%s'", String8(shaperItem.string + start, count).string());
     LOGD("         -- isDevKernText=%d", paint->isDevKernText());
 
     logGlyphs(shaperItem);
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index f7dacae..47a2c99 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -157,14 +157,17 @@
 
     for (uint32_t i = 0; i < mYCount; i++) {
         float stepY = mYDivs[i];
+        const float segment = stepY - previousStepY;
 
         if (i & 1) {
-            const float segment = stepY - previousStepY;
             y2 = y1 + floorf(segment * stretchY + 0.5f);
         } else {
-            y2 = y1 + stepY - previousStepY;
+            y2 = y1 + segment;
         }
-        float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
+
+        float vOffset = y1 == y2 ? 0.0f : 0.5 - (0.5 * segment / (y2 - y1));
+        float v2 = fmax(0.0f, stepY - vOffset) / bitmapHeight;
+        v1 += vOffset / bitmapHeight;
 
         if (stepY > 0.0f) {
 #if DEBUG_EXPLODE_PATCHES
@@ -179,7 +182,7 @@
         }
 
         y1 = y2;
-        v1 = (stepY + 0.5f) / bitmapHeight;
+        v1 = stepY / bitmapHeight;
 
         previousStepY = stepY;
     }
@@ -190,8 +193,7 @@
         y1 += mYCount * EXPLODE_GAP;
         y2 += mYCount * EXPLODE_GAP;
 #endif
-        generateRow(vertex, y1, y2, v1, 1.0f, stretchX, right - left,
-                bitmapWidth, quadCount);
+        generateRow(vertex, y1, y2, v1, 1.0f, stretchX, right - left, bitmapWidth, quadCount);
     }
 
     if (verticesCount > 0) {
@@ -220,14 +222,17 @@
     // Generate the row quad by quad
     for (uint32_t i = 0; i < mXCount; i++) {
         float stepX = mXDivs[i];
+        const float segment = stepX - previousStepX;
 
         if (i & 1) {
-            const float segment = stepX - previousStepX;
             x2 = x1 + floorf(segment * stretchX + 0.5f);
         } else {
-            x2 = x1 + stepX - previousStepX;
+            x2 = x1 + segment;
         }
-        float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
+
+        float uOffset = x1 == x2 ? 0.0f : 0.5 - (0.5 * segment / (x2 - x1));
+        float u2 = fmax(0.0f, stepX - uOffset) / bitmapWidth;
+        u1 += uOffset / bitmapWidth;
 
         if (stepX > 0.0f) {
 #if DEBUG_EXPLODE_PATCHES
@@ -241,7 +246,7 @@
         }
 
         x1 = x2;
-        u1 = (stepX + 0.5f) / bitmapWidth;
+        u1 = stepX / bitmapWidth;
 
         previousStepX = stepX;
     }
@@ -265,8 +270,8 @@
     if ((mColorKey >> oldQuadCount) & 0x1) {
 #if DEBUG_PATCHES_EMPTY_VERTICES
         PATCH_LOGD("    quad %d (empty)", oldQuadCount);
-        PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1);
-        PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.2f, %.2f", x2, y2, u2, v2);
+        PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1);
+        PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2);
 #endif
         return;
     }
@@ -294,8 +299,8 @@
 
 #if DEBUG_PATCHES_VERTICES
     PATCH_LOGD("    quad %d", oldQuadCount);
-    PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1);
-    PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.2f, %.2f", x2, y2, u2, v2);
+    PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1);
+    PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2);
 #endif
 }
 
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index de156c9..26bd697 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -47,29 +47,34 @@
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager = null;
 
+    // This is a faster way to draw the background on devices without hardware acceleration
+    Drawable mBackgroundDrawable = new Drawable() {
+        @Override
+        public void draw(Canvas canvas) {
+            canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    };
+
     public KeyguardViewBase(Context context) {
         super(context);
+        resetBackground();
+    }
 
-        // This is a faster way to draw the background on devices without hardware acceleration
-        setBackgroundDrawable(new Drawable() {
-            @Override
-            public void draw(Canvas canvas) {
-                canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
-            }
-
-            @Override
-            public void setAlpha(int alpha) {
-            }
-
-            @Override
-            public void setColorFilter(ColorFilter cf) {
-            }
-
-            @Override
-            public int getOpacity() {
-                return PixelFormat.TRANSLUCENT;
-            }
-        });
+    public void resetBackground() {
+        setBackgroundDrawable(mBackgroundDrawable);
     }
 
     // used to inject callback
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 7a72dcf..b4db01d 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -254,7 +254,7 @@
 
             // TODO: examine all widgets to derive clock status
             mUpdateMonitor.reportClockVisible(true);
-            setBackgroundDrawable(null);
+            resetBackground();
         }
 
         public boolean isVisible(View self) {
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index a653322..1976eba 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -701,7 +701,7 @@
         public void onServiceDisconnected(ComponentName name) {
             synchronized(mSpellCheckerMap) {
                 final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
-                if (this == group.mInternalConnection) {
+                if (group != null && this == group.mInternalConnection) {
                     mSpellCheckerBindGroups.remove(mSciId);
                 }
             }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1905a68..dc47a03 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1560,8 +1560,15 @@
         result.append(buffer);
         snprintf(buffer, SIZE,
                 "  last eglSwapBuffers() time: %f us\n"
-                "  last transaction time     : %f us\n",
-                mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
+                "  last transaction time     : %f us\n"
+                "  refresh-rate              : %f fps\n"
+                "  x-dpi                     : %f\n"
+                "  y-dpi                     : %f\n",
+                mLastSwapBufferTime/1000.0,
+                mLastTransactionTime/1000.0,
+                hw.getRefreshRate(),
+                hw.getDpiX(),
+                hw.getDpiY());
         result.append(buffer);
 
         if (inSwapBuffersDuration || !locked) {
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 84bfc40..51ebd99 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -57,7 +57,6 @@
     protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
 
     protected String spn;
-    protected int spnDisplayCondition;
 
     // ***** Constants
 
diff --git a/telephony/java/com/android/internal/telephony/IccServiceTable.java b/telephony/java/com/android/internal/telephony/IccServiceTable.java
new file mode 100644
index 0000000..ed74a11
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IccServiceTable.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 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.internal.telephony;
+
+import android.util.Log;
+
+/**
+ * Wrapper class for an ICC EF containing a bit field of enabled services.
+ */
+public abstract class IccServiceTable {
+    protected final byte[] mServiceTable;
+
+    protected IccServiceTable(byte[] table) {
+        mServiceTable = table;
+    }
+
+    // Get the class name to use for log strings
+    protected abstract String getTag();
+
+    // Get the array of enums to use for toString
+    protected abstract Object[] getValues();
+
+    /**
+     * Returns if the specified service is available.
+     * @param service the service number as a zero-based offset (the enum ordinal)
+     * @return true if the service is available; false otherwise
+     */
+    protected boolean isAvailable(int service) {
+        int offset = service / 8;
+        if (offset >= mServiceTable.length) {
+            // Note: Enums are zero-based, but the TS service numbering is one-based
+            Log.e(getTag(), "isAvailable for service " + (service + 1) + " fails, max service is " +
+                    (mServiceTable.length * 8));
+            return false;
+        }
+        int bit = service % 8;
+        return (mServiceTable[offset] & (1 << bit)) != 0;
+    }
+
+    public String toString() {
+        Object[] values = getValues();
+        int numBytes = mServiceTable.length;
+        StringBuilder builder = new StringBuilder(getTag()).append('[')
+                .append(numBytes * 8).append("]={ ");
+
+        boolean addComma = false;
+        for (int i = 0; i < numBytes; i++) {
+            byte currentByte = mServiceTable[i];
+            for (int bit = 0; bit < 8; bit++) {
+                if ((currentByte & (1 << bit)) != 0) {
+                    if (addComma) {
+                        builder.append(", ");
+                    } else {
+                        addComma = true;
+                    }
+                    int ordinal = (i * 8) + bit;
+                    if (ordinal < values.length) {
+                        builder.append(values[ordinal]);
+                    } else {
+                        builder.append('#').append(ordinal + 1);    // service number (one-based)
+                    }
+                }
+            }
+        }
+        return builder.append(" }").toString();
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index 47c638f..0a285b9 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -282,6 +282,9 @@
                 obtainMessage(EVENT_GET_MSISDN_DONE));
         recordsToLoad++;
 
+        iccFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
+        recordsToLoad++;
+
         iccFh.loadEFTransparent(EF_CSIM_LI,
                 obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded()));
         recordsToLoad++;
@@ -384,12 +387,12 @@
 
     @Override
     protected void log(String s) {
-        if (DBG) Log.d(LOG_TAG, "[CSIM] " + s);
+        Log.d(LOG_TAG, "[CSIM] " + s);
     }
 
     @Override
     protected void loge(String s) {
-        if (DBG) Log.e(LOG_TAG, "[CSIM] " + s);
+        Log.e(LOG_TAG, "[CSIM] " + s);
     }
 
     public String getMdn() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 5d6f181..8e965a3 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -91,6 +91,8 @@
 
     String pnnHomeName = null;
 
+    UsimServiceTable mUsimServiceTable;
+
     // ***** Constants
 
     // Bitmasks for SPN display rules.
@@ -134,7 +136,7 @@
     private static final int EVENT_GET_SPDI_DONE = 13;
     private static final int EVENT_UPDATE_DONE = 14;
     private static final int EVENT_GET_PNN_DONE = 15;
-    private static final int EVENT_GET_SST_DONE = 17;
+    protected static final int EVENT_GET_SST_DONE = 17;
     private static final int EVENT_GET_ALL_SMS_DONE = 18;
     private static final int EVENT_MARK_SMS_READ_DONE = 19;
     private static final int EVENT_SET_MBDN_DONE = 20;
@@ -246,6 +248,10 @@
         return msisdn;
     }
 
+    public UsimServiceTable getUsimServiceTable() {
+        return mUsimServiceTable;
+    }
+
     /**
      * Set subscriber number to SIM record
      *
@@ -961,8 +967,9 @@
                     break;
                 }
 
-                //Log.d(LOG_TAG, "SST: " + IccUtils.bytesToHexString(data));
-            break;
+                mUsimServiceTable = new UsimServiceTable(data);
+                if (DBG) log("SST: " + mUsimServiceTable);
+                break;
 
             case EVENT_GET_INFO_CPHS_DONE:
                 isRecordLoadResponse = true;
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java b/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
new file mode 100644
index 0000000..3fe200b
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2011 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.internal.telephony.gsm;
+
+import com.android.internal.telephony.IccServiceTable;
+
+/**
+ * Wrapper class for the USIM Service Table EF.
+ * See 3GPP TS 31.102 Release 10 section 4.2.8
+ */
+public final class UsimServiceTable extends IccServiceTable {
+    public enum UsimService {
+        PHONEBOOK,
+        FDN,                                // Fixed Dialing Numbers
+        FDN_EXTENSION,                      // FDN extension data in EF_EXT2
+        SDN,                                // Service Dialing Numbers
+        SDN_EXTENSION,                      // SDN extension data in EF_EXT3
+        BDN,                                // Barred Dialing Numbers
+        BDN_EXTENSION,                      // BDN extension data in EF_EXT4
+        OUTGOING_CALL_INFO,
+        INCOMING_CALL_INFO,
+        SM_STORAGE,
+        SM_STATUS_REPORTS,
+        SM_SERVICE_PARAMS,
+        ADVICE_OF_CHARGE,
+        CAP_CONFIG_PARAMS_2,
+        CB_MESSAGE_ID,
+        CB_MESSAGE_ID_RANGES,
+        GROUP_ID_LEVEL_1,
+        GROUP_ID_LEVEL_2,
+        SPN,                                // Service Provider Name
+        USER_PLMN_SELECT,
+        MSISDN,
+        IMAGE,
+        LOCALISED_SERVICE_AREAS,
+        EMLPP,                              // Enhanced Multi-Level Precedence and Preemption
+        EMLPP_AUTO_ANSWER,
+        RFU,
+        GSM_ACCESS,
+        DATA_DL_VIA_SMS_PP,
+        DATA_DL_VIA_SMS_CB,
+        CALL_CONTROL_BY_USIM,
+        MO_SMS_CONTROL_BY_USIM,
+        RUN_AT_COMMAND,
+        IGNORED_1,
+        ENABLED_SERVICES_TABLE,
+        APN_CONTROL_LIST,
+        DEPERSONALISATION_CONTROL_KEYS,
+        COOPERATIVE_NETWORK_LIST,
+        GSM_SECURITY_CONTEXT,
+        CPBCCH_INFO,
+        INVESTIGATION_SCAN,
+        MEXE,
+        OPERATOR_PLMN_SELECT,
+        HPLMN_SELECT,
+        EXTENSION_5,                        // Extension data for ICI, OCI, MSISDN in EF_EXT5
+        PLMN_NETWORK_NAME,
+        OPERATOR_PLMN_LIST,
+        MBDN,                               // Mailbox Dialing Numbers
+        MWI_STATUS,                         // Message Waiting Indication status
+        CFI_STATUS,                         // Call Forwarding Indication status
+        IGNORED_2,
+        SERVICE_PROVIDER_DISPLAY_INFO,
+        MMS_NOTIFICATION,
+        MMS_NOTIFICATION_EXTENSION,         // MMS Notification extension data in EF_EXT8
+        GPRS_CALL_CONTROL_BY_USIM,
+        MMS_CONNECTIVITY_PARAMS,
+        NETWORK_INDICATION_OF_ALERTING,
+        VGCS_GROUP_ID_LIST,
+        VBS_GROUP_ID_LIST,
+        PSEUDONYM,
+        IWLAN_USER_PLMN_SELECT,
+        IWLAN_OPERATOR_PLMN_SELECT,
+        USER_WSID_LIST,
+        OPERATOR_WSID_LIST,
+        VGCS_SECURITY,
+        VBS_SECURITY,
+        WLAN_REAUTH_IDENTITY,
+        MM_STORAGE,
+        GBA,                                // Generic Bootstrapping Architecture
+        MBMS_SECURITY,
+        DATA_DL_VIA_USSD,
+        EQUIVALENT_HPLMN,
+        TERMINAL_PROFILE_AFTER_UICC_ACTIVATION,
+        EQUIVALENT_HPLMN_PRESENTATION,
+        LAST_RPLMN_SELECTION_INDICATION,
+        OMA_BCAST_PROFILE,
+        GBA_LOCAL_KEY_ESTABLISHMENT,
+        TERMINAL_APPLICATIONS,
+        SPN_ICON,
+        PLMN_NETWORK_NAME_ICON,
+        USIM_IP_CONNECTION_PARAMS,
+        IWLAN_HOME_ID_LIST,
+        IWLAN_EQUIVALENT_HPLMN_PRESENTATION,
+        IWLAN_HPLMN_PRIORITY_INDICATION,
+        IWLAN_LAST_REGISTERED_PLMN,
+        EPS_MOBILITY_MANAGEMENT_INFO,
+        ALLOWED_CSG_LISTS_AND_INDICATIONS,
+        CALL_CONTROL_ON_EPS_PDN_CONNECTION_BY_USIM,
+        HPLMN_DIRECT_ACCESS,
+        ECALL_DATA,
+        OPERATOR_CSG_LISTS_AND_INDICATIONS,
+        SM_OVER_IP,
+        CSG_DISPLAY_CONTROL,
+        IMS_COMMUNICATION_CONTROL_BY_USIM,
+        EXTENDED_TERMINAL_APPLICATIONS,
+        UICC_ACCESS_TO_IMS,
+        NAS_CONFIG_BY_USIM
+    }
+
+    public UsimServiceTable(byte[] table) {
+        super(table);
+    }
+
+    public boolean isAvailable(UsimService service) {
+        return super.isAvailable(service.ordinal());
+    }
+
+    @Override
+    protected String getTag() {
+        return "UsimServiceTable";
+    }
+
+    @Override
+    protected Object[] getValues() {
+        return UsimService.values();
+    }
+}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
new file mode 100644
index 0000000..c89f33a
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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.internal.telephony;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Test IccServiceTable class.
+ */
+public class IccServiceTableTest extends AndroidTestCase {
+
+    static class TestIccServiceTable extends IccServiceTable {
+        public enum TestIccService {
+            SERVICE1,
+            SERVICE2,
+            SERVICE3,
+            SERVICE4
+        }
+
+        public TestIccServiceTable(byte[] table) {
+            super(table);
+        }
+
+        public boolean isAvailable(TestIccService service) {
+            return super.isAvailable(service.ordinal());
+        }
+
+        @Override
+        protected String getTag() {
+            return "TestIccServiceTable";
+        }
+
+        @Override
+        protected Object[] getValues() {
+            return TestIccService.values();
+        }
+    }
+
+    @SmallTest
+    public void testIccServiceTable() {
+        byte[] noServices = {0x00};
+        byte[] service1 = {0x01};
+        byte[] service4 = {0x08};
+        byte[] allServices = {0x0f};
+
+        TestIccServiceTable testTable1 = new TestIccServiceTable(noServices);
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+
+        TestIccServiceTable testTable2 = new TestIccServiceTable(service1);
+        assertTrue(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+
+        TestIccServiceTable testTable3 = new TestIccServiceTable(service4);
+        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertTrue(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+
+        TestIccServiceTable testTable4 = new TestIccServiceTable(allServices);
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
+        assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
+    }
+}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
new file mode 100644
index 0000000..56854ed
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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.internal.telephony.gsm;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Test UsimServiceTable class.
+ */
+public class UsimServiceTableTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testUsimServiceTable() {
+        byte[] noServices = {0x00};
+        byte[] service1 = {0x01, 0x00};
+        byte[] service8 = {(byte) 0x80, 0x00, 0x00};
+        byte[] service8And9 = {(byte) 0x80, 0x01};
+        byte[] service28 = {0x00, 0x00, 0x00, 0x08};
+        byte[] service89To96 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, (byte) 0xff};
+
+        UsimServiceTable testTable1 = new UsimServiceTable(noServices);
+        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.FDN));
+        assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable2 = new UsimServiceTable(service1);
+        assertTrue(testTable2.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.FDN));
+        assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable3 = new UsimServiceTable(service8);
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
+        assertTrue(testTable3.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
+        assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable4 = new UsimServiceTable(service8And9);
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
+        assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
+        assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.SM_STORAGE));
+        assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable5 = new UsimServiceTable(service28);
+        assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertTrue(testTable5.isAvailable(UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP));
+        assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+
+        UsimServiceTable testTable6 = new UsimServiceTable(service89To96);
+        assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
+        assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.HPLMN_DIRECT_ACCESS));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.ECALL_DATA));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.SM_OVER_IP));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.UICC_ACCESS_TO_IMS));
+        assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
+    }
+}
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_focus.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_focus.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_focus.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_focus.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_press.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_press.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/appwidget_bg_press.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/appwidget_bg_press.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/green_gradient.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/green_gradient.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/green_gradient.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/green_gradient.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/patch.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/patch.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/patch.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/patch.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/patch2.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/patch2.9.png
new file mode 100644
index 0000000..f65a3559
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable-nodpi/patch2.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/widget_title_bg.9.png b/tests/HwAccelerationTest/res/drawable-nodpi/widget_title_bg.9.png
similarity index 100%
rename from tests/HwAccelerationTest/res/drawable-hdpi/widget_title_bg.9.png
rename to tests/HwAccelerationTest/res/drawable-nodpi/widget_title_bg.9.png
Binary files differ
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
index cfad6da..656f2b1 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ThinPatchesActivity.java
@@ -44,7 +44,7 @@
     }
 
     private class PatchView extends View {
-        private Drawable mPatch1, mPatch2;
+        private Drawable mPatch1, mPatch2, mPatch3;
         private Bitmap mTexture;
 
         public PatchView(Activity activity) {
@@ -53,6 +53,7 @@
             final Resources resources = activity.getResources();
             mPatch1 = resources.getDrawable(R.drawable.patch);
             mPatch2 = resources.getDrawable(R.drawable.btn_toggle_on);
+            mPatch3 = resources.getDrawable(R.drawable.patch2);
 
             mTexture = Bitmap.createBitmap(4, 3, Bitmap.Config.ARGB_8888);
             mTexture.setPixel(0, 0, 0xffff0000);
@@ -77,6 +78,14 @@
             final int left = (getWidth() - width) / 2;
             final int top  = (getHeight() - height) / 2;
 
+            canvas.save();
+            canvas.translate(0.0f, -height * 2 - 20.0f);
+
+            mPatch3.setBounds(left, top, left + height, top + width);
+            mPatch3.draw(canvas);
+            
+            canvas.restore();
+            
             mPatch1.setBounds(left, top, left + width, top + height);
             mPatch1.draw(canvas);