Merge "Do not call RecoverySystem with DPMS lock held" into nyc-mr2-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index d74526b..fcbd1b5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -9790,6 +9790,7 @@
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract boolean hasSystemFeature(java.lang.String);
     method public abstract boolean hasSystemFeature(java.lang.String, int);
+    method public abstract boolean isPermissionReviewModeEnabled();
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -38217,6 +38218,7 @@
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public boolean hasSystemFeature(java.lang.String);
     method public boolean hasSystemFeature(java.lang.String, int);
+    method public boolean isPermissionReviewModeEnabled();
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 37faa2e..c44cdb2 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -292,6 +292,12 @@
     }
 
     @Override
+    public boolean isPermissionReviewModeEnabled() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_permissionReviewRequired);
+    }
+
+    @Override
     public PermissionGroupInfo getPermissionGroupInfo(String name,
             int flags) throws NameNotFoundException {
         try {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 39133b8..3496843 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2826,6 +2826,14 @@
             @PermissionInfoFlags int flags) throws NameNotFoundException;
 
     /**
+     * Returns true if Permission Review Mode is enabled, false otherwise.
+     *
+     * @hide
+     */
+    @TestApi
+    public abstract boolean isPermissionReviewModeEnabled();
+
+    /**
      * Retrieve all of the information we know about a particular group of
      * permissions.
      *
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_r.xml b/packages/SystemUI/res/drawable/ic_qs_signal_r.xml
deleted file mode 100644
index 66f64c9..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_r.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="8.0dp"
-        android:height="32dp"
-        android:viewportWidth="6.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M2.800000,7.900000l-1.000000,0.000000L1.800000,11.000000L0.200000,11.000000L0.200000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S4.800000,7.200000 4.400000,7.400000l1.500000,3.500000L5.900000,11.000000L4.100000,11.000000L2.800000,7.900000zM1.800000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000S4.000000,5.600000 4.000000,5.200000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S3.300000,3.800000 2.900000,3.800000L1.800000,3.800000L1.800000,6.500000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_roam.xml b/packages/SystemUI/res/drawable/stat_sys_roaming.xml
similarity index 95%
rename from packages/SystemUI/res/drawable/stat_sys_data_fully_connected_roam.xml
rename to packages/SystemUI/res/drawable/stat_sys_roaming.xml
index 363e231..4baa472 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_roam.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_roaming.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="4.25dp"
+        android:width="8.5dp"
         android:height="17dp"
         android:viewportWidth="6.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.800000,7.900000l-1.000000,0.000000L1.800000,11.000000L0.200000,11.000000L0.200000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S4.800000,7.200000 4.400000,7.400000l1.500000,3.500000L5.900000,11.000000L4.100000,11.000000L2.800000,7.900000zM1.800000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000S4.000000,5.600000 4.000000,5.200000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S3.300000,3.800000 2.900000,3.800000L1.800000,3.800000L1.800000,6.500000z"/>
diff --git a/packages/SystemUI/res/layout/data_usage.xml b/packages/SystemUI/res/layout/data_usage.xml
index c943f3d..fdc6f14 100644
--- a/packages/SystemUI/res/layout/data_usage.xml
+++ b/packages/SystemUI/res/layout/data_usage.xml
@@ -59,6 +59,7 @@
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:textAppearance="@style/TextAppearance.QS.DataUsage" />
+
     </LinearLayout>
 
     <LinearLayout
@@ -82,4 +83,13 @@
             android:textAppearance="@style/TextAppearance.QS.DataUsage.Secondary" />
     </LinearLayout>
 
-</com.android.systemui.qs.tiles.DataUsageDetailView>
\ No newline at end of file
+    <TextView
+        android:id="@+id/roaming_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingTop="16dp"
+        android:text="@string/accessibility_data_connection_roaming"
+        android:textAppearance="@style/TextAppearance.QS.DataUsage.Secondary"
+        android:visibility="gone" />
+
+</com.android.systemui.qs.tiles.DataUsageDetailView>
diff --git a/packages/SystemUI/res/layout/mobile_signal_group.xml b/packages/SystemUI/res/layout/mobile_signal_group.xml
index a20ec8e..8b10074 100644
--- a/packages/SystemUI/res/layout/mobile_signal_group.xml
+++ b/packages/SystemUI/res/layout/mobile_signal_group.xml
@@ -43,4 +43,15 @@
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         />
+    <ImageView
+        android:id="@+id/mobile_roaming"
+        android:layout_width="wrap_content"
+        android:layout_height="17dp"
+        android:paddingStart="22dp"
+        android:paddingTop="1.5dp"
+        android:paddingBottom="3dp"
+        android:scaleType="fitCenter"
+        android:src="@drawable/stat_sys_roaming"
+        android:contentDescription="@string/accessibility_data_connection_roaming"
+        android:visibility="gone" />
 </FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 5c8a6e2..619f539 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -189,8 +189,8 @@
                 translationXBuilder.addFloat(label, "translationX", -xDiff, 0);
                 translationYBuilder.addFloat(label, "translationY", -yDiff, 0);
 
-                mTopFiveQs.add(tileIcon);
-                mAllViews.add(tileIcon);
+                mTopFiveQs.add(tileView.getIcon());
+                mAllViews.add(tileView.getIcon());
                 mAllViews.add(quickTileView);
             } else if (mFullRows && isIconInAnimatedRow(count)) {
                 // TODO: Refactor some of this, it shares a lot with the above block.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 0de5105..b34e881 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -35,7 +35,7 @@
 import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.SignalCallbackAdapter;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 
 /** Quick settings tile: Cellular **/
 public class CellularTile extends QSTile<QSTile.SignalState> {
@@ -183,9 +183,10 @@
         String enabledDesc;
         boolean noSim;
         boolean isDataTypeIconWide;
+        boolean roaming;
     }
 
-    private final class CellSignalCallback extends SignalCallbackAdapter {
+    private final class CellSignalCallback implements SignalCallback {
         private final CallbackInfo mInfo = new CallbackInfo();
         @Override
         public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
@@ -197,7 +198,7 @@
         @Override
         public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
                 int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
-                String description, boolean isWide, int subId) {
+                String description, boolean isWide, int subId, boolean roaming) {
             if (qsIcon == null) {
                 // Not data sim, don't display.
                 return;
@@ -211,6 +212,7 @@
             mInfo.activityOut = activityOut;
             mInfo.enabledDesc = description;
             mInfo.isDataTypeIconWide = qsType != 0 && isWide;
+            mInfo.roaming = roaming;
             refreshState(mInfo);
         }
 
@@ -280,6 +282,8 @@
             final DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo();
             if (info == null) return v;
             v.bind(info);
+            v.findViewById(R.id.roaming_text).setVisibility(mSignalCallback.mInfo.roaming
+                    ? View.VISIBLE : View.INVISIBLE);
             return v;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 9ce1f31..2e922e9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -39,7 +39,7 @@
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.SignalCallbackAdapter;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 
 import java.util.List;
 
@@ -245,7 +245,7 @@
         }
     }
 
-    protected final class WifiSignalCallback extends SignalCallbackAdapter {
+    protected final class WifiSignalCallback implements SignalCallback {
         final CallbackInfo mInfo = new CallbackInfo();
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 74caa53..13253b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -271,7 +271,7 @@
     @Override
     public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
             int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
-            String description, boolean isWide, int subId) {
+            String description, boolean isWide, int subId, boolean roaming) {
         PhoneState state = getState(subId);
         if (state == null) {
             return;
@@ -282,6 +282,7 @@
         state.mMobileDescription = statusIcon.contentDescription;
         state.mMobileTypeDescription = typeContentDescription;
         state.mIsMobileTypeIconWide = statusType != 0 && isWide;
+        state.mRoaming = roaming;
 
         apply();
     }
@@ -591,7 +592,8 @@
         private String mMobileDescription, mMobileTypeDescription;
 
         private ViewGroup mMobileGroup;
-        private ImageView mMobile, mMobileDark, mMobileType;
+        private ImageView mMobile, mMobileDark, mMobileType, mMobileRoaming;
+        public boolean mRoaming;
 
         public PhoneState(int subId, Context context) {
             ViewGroup root = (ViewGroup) LayoutInflater.from(context)
@@ -605,6 +607,7 @@
             mMobile         = (ImageView) root.findViewById(R.id.mobile_signal);
             mMobileDark     = (ImageView) root.findViewById(R.id.mobile_signal_dark);
             mMobileType     = (ImageView) root.findViewById(R.id.mobile_type);
+            mMobileRoaming  = (ImageView) root.findViewById(R.id.mobile_roaming);
         }
 
         public boolean apply(boolean isSecondaryIcon) {
@@ -640,6 +643,7 @@
                         (mMobileVisible ? "VISIBLE" : "GONE"), mMobileStrengthId, mMobileTypeId));
 
             mMobileType.setVisibility(mMobileTypeId != 0 ? View.VISIBLE : View.GONE);
+            mMobileRoaming.setVisibility(mRoaming ? View.VISIBLE : View.GONE);
 
             return mMobileVisible;
         }
@@ -699,6 +703,8 @@
                     StatusBarIconController.getDarkIntensity(tintArea, mMobile, darkIntensity),
                     mMobile, mMobileDark);
             setTint(mMobileType, StatusBarIconController.getTint(tintArea, mMobileType, tint));
+            setTint(mMobileRoaming, StatusBarIconController.getTint(tintArea, mMobileRoaming,
+                    tint));
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index e4991d5..cbef76c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -25,6 +25,7 @@
 import android.graphics.drawable.RippleDrawable;
 import android.os.UserManager;
 import android.util.AttributeSet;
+import android.util.SparseBooleanArray;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
@@ -43,6 +44,10 @@
 import com.android.systemui.qs.TouchAnimator;
 import com.android.systemui.qs.TouchAnimator.Builder;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
 import com.android.systemui.statusbar.policy.UserInfoController;
@@ -50,7 +55,8 @@
 import com.android.systemui.tuner.TunerService;
 
 public class QuickStatusBarHeader extends BaseStatusBarHeader implements
-        NextAlarmChangeCallback, OnClickListener, OnUserInfoChangedListener {
+        NextAlarmChangeCallback, OnClickListener, OnUserInfoChangedListener, EmergencyListener,
+        SignalCallback {
 
     private static final String TAG = "QuickStatusBarHeader";
 
@@ -91,6 +97,8 @@
     private View mEdit;
     private boolean mShowFullAlarm;
     private float mDateTimeTranslation;
+    private SparseBooleanArray mRoamingsBySubId = new SparseBooleanArray();
+    private boolean mIsRoaming;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -265,7 +273,7 @@
     protected void updateVisibilities() {
         updateAlarmVisibilities();
         updateDateTimePosition();
-        mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
+        mEmergencyOnly.setVisibility(mExpanded && (mShowEmergencyCallsOnly || mIsRoaming)
                 ? View.VISIBLE : View.INVISIBLE);
         mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
                 TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
@@ -276,15 +284,21 @@
     }
 
     private void updateDateTimePosition() {
-        mDateTimeAlarmGroup.setTranslationY(mShowEmergencyCallsOnly
+        mDateTimeAlarmGroup.setTranslationY(mShowEmergencyCallsOnly || mIsRoaming
                 ? mExpansionAmount * mDateTimeTranslation : 0);
     }
 
     private void updateListeners() {
         if (mListening) {
             mNextAlarmController.addStateChangedCallback(this);
+            if (mHost.getNetworkController().hasVoiceCallingFeature()) {
+                mHost.getNetworkController().addEmergencyListener(this);
+                mHost.getNetworkController().addSignalCallback(this);
+            }
         } else {
             mNextAlarmController.removeStateChangedCallback(this);
+            mHost.getNetworkController().removeEmergencyListener(this);
+            mHost.getNetworkController().removeSignalCallback(this);
         }
     }
 
@@ -384,6 +398,29 @@
     }
 
     @Override
+    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
+            int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
+            String description, boolean isWide, int subId, boolean roaming) {
+        mRoamingsBySubId.put(subId, roaming);
+        boolean isRoaming = calculateRoaming();
+        if (mIsRoaming != isRoaming) {
+            mIsRoaming = isRoaming;
+            mEmergencyOnly.setText(mIsRoaming ? R.string.accessibility_data_connection_roaming
+                    : com.android.internal.R.string.emergency_calls_only);
+            if (mExpanded) {
+                updateEverything();
+            }
+        }
+    }
+
+    private boolean calculateRoaming() {
+        for (int i = 0; i < mRoamingsBySubId.size(); i++) {
+            if (mRoamingsBySubId.valueAt(i)) return true;
+        }
+        return false;
+    }
+
+    @Override
     public void onUserInfoChanged(String name, Drawable picture) {
         mMultiUserAvatar.setImageDrawable(picture);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
index 3142ddf..616d210 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
@@ -125,14 +125,14 @@
     public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon,
             final int statusType, final int qsType,final boolean activityIn,
             final boolean activityOut, final String typeContentDescription,
-            final String description, final boolean isWide, final int subId) {
+            final String description, final boolean isWide, final int subId, boolean roaming) {
         post(new Runnable() {
             @Override
             public void run() {
                 for (SignalCallback signalCluster : mSignalCallbacks) {
                     signalCluster.setMobileDataIndicators(statusIcon, qsIcon, statusType, qsType,
                             activityIn, activityOut, typeContentDescription, description, isWide,
-                            subId);
+                            subId, roaming);
                 }
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 83463e2..03c46e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -226,10 +226,8 @@
         final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
                 && mCurrentState.userSetup;
 
-        // Show icon in QS when we are connected or need to show roaming or data is disabled.
-        boolean showDataIcon = mCurrentState.dataConnected
-                || mCurrentState.iconGroup == TelephonyIcons.ROAMING
-                || dataDisabled;
+        // Show icon in QS when we are connected or data is disabled.
+        boolean showDataIcon = mCurrentState.dataConnected || dataDisabled;
         IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
                 getCurrentIconId(), contentDescription);
 
@@ -249,13 +247,11 @@
         boolean activityOut = mCurrentState.dataConnected
                         && !mCurrentState.carrierNetworkChangeMode
                         && mCurrentState.activityOut;
-        showDataIcon &= mCurrentState.isDefault
-                || mCurrentState.iconGroup == TelephonyIcons.ROAMING
-                || dataDisabled;
+        showDataIcon &= mCurrentState.isDefault || dataDisabled;
         int typeIcon = showDataIcon ? icons.mDataType : 0;
         callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
                 activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
-                mSubscriptionInfo.getSubscriptionId());
+                mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming);
     }
 
     @Override
@@ -405,10 +401,9 @@
         mCurrentState.dataConnected = mCurrentState.connected
                 && mDataState == TelephonyManager.DATA_CONNECTED;
 
+        mCurrentState.roaming = isRoaming();
         if (isCarrierNetworkChangeActive()) {
             mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
-        } else if (isRoaming()) {
-            mCurrentState.iconGroup = TelephonyIcons.ROAMING;
         } else if (isDataDisabled()) {
             mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
         }
@@ -541,6 +536,7 @@
         boolean carrierNetworkChangeMode;
         boolean isDefault;
         boolean userSetup;
+        boolean roaming;
 
         @Override
         public void copyFrom(State s) {
@@ -555,6 +551,7 @@
             airplaneMode = state.airplaneMode;
             carrierNetworkChangeMode = state.carrierNetworkChangeMode;
             userSetup = state.userSetup;
+            roaming = state.roaming;
         }
 
         @Override
@@ -565,6 +562,7 @@
             builder.append("networkName=").append(networkName).append(',');
             builder.append("networkNameData=").append(networkNameData).append(',');
             builder.append("dataConnected=").append(dataConnected).append(',');
+            builder.append("roaming=").append(roaming).append(',');
             builder.append("isDefault=").append(isDefault).append(',');
             builder.append("isEmergency=").append(isEmergency).append(',');
             builder.append("airplaneMode=").append(airplaneMode).append(',');
@@ -584,7 +582,8 @@
                     && ((MobileState) o).airplaneMode == airplaneMode
                     && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
                     && ((MobileState) o).userSetup == userSetup
-                    && ((MobileState) o).isDefault == isDefault;
+                    && ((MobileState) o).isDefault == isDefault
+                    && ((MobileState) o).roaming == roaming;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 5f1b871..ad5f24b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -46,7 +46,7 @@
 
         default void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
                 int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
-                String description, boolean isWide, int subId) {}
+                String description, boolean isWide, int subId, boolean roaming) {}
         default void setSubs(List<SubscriptionInfo> subs) {}
         default void setNoSims(boolean show) {}
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 37e6a2a..622595f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -787,9 +787,11 @@
                             datatype.equals("h") ? TelephonyIcons.H :
                             datatype.equals("lte") ? TelephonyIcons.LTE :
                             datatype.equals("lte+") ? TelephonyIcons.LTE_PLUS :
-                            datatype.equals("roam") ? TelephonyIcons.ROAMING :
                             TelephonyIcons.UNKNOWN;
                 }
+                if (args.containsKey("roam")) {
+                    controller.getState().roaming = "show".equals(args.getString("roam"));
+                }
                 int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH;
                 String level = args.getString("level");
                 if (level != null) {
@@ -797,6 +799,10 @@
                             : Math.min(Integer.parseInt(level), icons[0].length - 1);
                     controller.getState().connected = controller.getState().level >= 0;
                 }
+                String activity = args.getString("activity");
+                if (activity != null) {
+                    controller.setActivity(Integer.parseInt(activity));
+                }
                 controller.getState().enabled = show;
                 controller.notifyListeners();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java
deleted file mode 100644
index dce889f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.statusbar.policy;
-
-import android.telephony.SubscriptionInfo;
-
-import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
-
-import java.util.List;
-
-
-/**
- * Provides empty implementations of SignalCallback for those that only want some of
- * the callbacks.
- */
-public class SignalCallbackAdapter implements SignalCallback {
-
-    @Override
-    public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
-            boolean activityIn, boolean activityOut, String description) {
-    }
-
-    @Override
-    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
-            int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
-            String description, boolean isWide, int subId) {
-    }
-
-    @Override
-    public void setSubs(List<SubscriptionInfo> subs) {
-    }
-
-    @Override
-    public void setNoSims(boolean show) {
-    }
-
-    @Override
-    public void setEthernetIndicators(IconState icon) {
-    }
-
-    @Override
-    public void setIsAirplaneMode(IconState icon) {
-    }
-
-    @Override
-    public void setMobileDataEnabled(boolean enabled) {
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index ed8c7ff..6b2361e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -95,8 +95,6 @@
           R.drawable.ic_qs_signal_carrier_network_change_animation }
     };
 
-    static final int QS_DATA_R = R.drawable.ic_qs_signal_r;
-
     //***** Data connection icons
 
     //GSM/UMTS
@@ -211,7 +209,7 @@
     static final int QS_DATA_LTE_PLUS = R.drawable.ic_qs_signal_lte_plus;
 
     static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode;
-    static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam;
+    static final int ROAMING_ICON = R.drawable.stat_sys_roaming;
     static final int ICON_LTE = R.drawable.stat_sys_data_fully_connected_lte;
     static final int ICON_LTE_PLUS = R.drawable.stat_sys_data_fully_connected_lte_plus;
     static final int ICON_G = R.drawable.stat_sys_data_fully_connected_g;
@@ -410,21 +408,6 @@
             TelephonyIcons.QS_DATA_LTE_PLUS
             );
 
-    static final MobileIconGroup ROAMING = new MobileIconGroup(
-            "Roaming",
-            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING,
-            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
-            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
-            0, 0,
-            TelephonyIcons.TELEPHONY_NO_NETWORK,
-            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
-            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
-            R.string.accessibility_data_connection_roaming,
-            TelephonyIcons.ROAMING_ICON,
-            false,
-            TelephonyIcons.QS_DATA_R
-            );
-
     static final MobileIconGroup DATA_DISABLED = new MobileIconGroup(
             "DataDisabled",
             TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index 19cb243..d01ecb1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -31,6 +31,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.mockito.Matchers.eq;
+
 @SmallTest
 public class CallbackHandlerTest extends AndroidTestCase {
 
@@ -102,8 +104,9 @@
         int qsType = R.drawable.ic_qs_signal_1x;
         boolean wide = true;
         int subId = 5;
+        boolean roaming = true;
         mHandler.setMobileDataIndicators(status, qs, type, qsType, in, out, typeDescription,
-                description, wide, subId);
+                description, wide, subId, roaming);
         waitForCallbacks();
 
         ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class);
@@ -119,7 +122,7 @@
         Mockito.verify(mSignalCallback).setMobileDataIndicators(statusArg.capture(),
                 qsArg.capture(), typeIconArg.capture(), qsTypeIconArg.capture(), inArg.capture(),
                 outArg.capture(), typeContentArg.capture(), descArg.capture(), wideArg.capture(),
-                subIdArg.capture());
+                subIdArg.capture(), eq(roaming));
         assertEquals(status, statusArg.getValue());
         assertEquals(qs, qsArg.getValue());
         assertEquals(type, (int) typeIconArg.getValue());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 38cac1e..29b6976 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -43,6 +43,13 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -279,10 +286,7 @@
                     iconArg.capture(),
                     ArgumentCaptor.forClass(Integer.class).capture(),
                     typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(),
-                    ArgumentCaptor.forClass(String.class).capture(),
-                    ArgumentCaptor.forClass(String.class).capture(),
-                    ArgumentCaptor.forClass(Boolean.class).capture(),
-                    ArgumentCaptor.forClass(Integer.class).capture());
+                    anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean());
         IconState iconState = iconArg.getValue();
         assertEquals("Visibility in, quick settings", visible, iconState.visible);
         assertEquals("Signal icon in, quick settings", icon, iconState.icon);
@@ -294,21 +298,46 @@
     }
 
     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon) {
+        verifyLastMobileDataIndicators(visible, icon, typeIcon, false);
+    }
+
+    protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
+            boolean roaming) {
         ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
 
         // TODO: Verify all fields.
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
                 iconArg.capture(),
-                ArgumentCaptor.forClass(IconState.class).capture(),
+                any(),
                 typeIconArg.capture(),
-                ArgumentCaptor.forClass(Integer.class).capture(),
-                ArgumentCaptor.forClass(Boolean.class).capture(),
-                ArgumentCaptor.forClass(Boolean.class).capture(),
-                ArgumentCaptor.forClass(String.class).capture(),
-                ArgumentCaptor.forClass(String.class).capture(),
-                ArgumentCaptor.forClass(Boolean.class).capture(),
-                ArgumentCaptor.forClass(Integer.class).capture());
+                anyInt(), anyBoolean(), anyBoolean(), anyString(), anyString(), anyBoolean(),
+                anyInt(), eq(roaming));
+        IconState iconState = iconArg.getValue();
+
+        assertEquals("Signal icon in status bar", icon, iconState.icon);
+        assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue());
+        assertEquals("Visibility in status bar", visible, iconState.visible);
+    }
+
+    protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
+            boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut) {
+        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
+        ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<IconState> qsIconArg = ArgumentCaptor.forClass(IconState.class);
+        ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
+
+        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
+                iconArg.capture(),
+                qsIconArg.capture(),
+                typeIconArg.capture(),
+                qsTypeIconArg.capture(),
+                dataInArg.capture(),
+                dataOutArg.capture(),
+                anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean());
+
         IconState iconState = iconArg.getValue();
 
         assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 542c390..fce1172 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -17,18 +17,6 @@
                 TelephonyIcons.QS_DATA_3G);
     }
 
-    public void testRoamingDataIcon() {
-        setupDefaultSignal();
-        setGsmRoaming(true);
-
-        verifyLastMobileDataIndicators(true,
-                TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL],
-                TelephonyIcons.ROAMING_ICON);
-        verifyLastQsMobileDataIndicators(true,
-                TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL],
-                TelephonyIcons.QS_DATA_R, false, false);
-    }
-
     public void test2gDataIcon() {
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 08da382..1912bf0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -140,13 +140,12 @@
         for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
                 testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
             setupDefaultSignal();
-            setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
             setGsmRoaming(true);
             setLevel(testStrength);
 
             verifyLastMobileDataIndicators(true,
                     TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
-                    TelephonyIcons.ROAMING_ICON);
+                    DEFAULT_ICON, true);
         }
     }
 
@@ -160,7 +159,7 @@
 
             verifyLastMobileDataIndicators(true,
                     TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
-                    TelephonyIcons.ROAMING_ICON);
+                    TelephonyIcons.DATA_1X[1][0 /* No direction */], true);
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index d7c4e1e..15658a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -93,9 +93,10 @@
         setGsmRoaming(true);
         // Still be on wifi though.
         setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
         verifyLastMobileDataIndicators(true,
                 TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL],
-                TelephonyIcons.ROAMING_ICON);
+                0, true);
     }
 
     protected void setWifiActivity(int activity) {
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 921fd23..156e278 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1541,9 +1541,8 @@
             // used to verify this receiver is still current
             final private int mGenerationNumber;
 
-            // we're interested in edge-triggered LOADED notifications, so
-            // ignore LOADED unless we saw an ABSENT state first
-            private boolean mSimAbsentSeen = false;
+            // used to check the sim state transition from non-loaded to loaded
+            private boolean mSimNotLoadedSeen = false;
 
             public SimChangeBroadcastReceiver(int generationNumber) {
                 super();
@@ -1561,14 +1560,14 @@
                 final String state =
                         intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
 
-                Log.d(TAG, "got Sim changed to state " + state + ", mSimAbsentSeen=" +
-                        mSimAbsentSeen);
-                if (!mSimAbsentSeen && IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(state)) {
-                    mSimAbsentSeen = true;
+                Log.d(TAG, "got Sim changed to state " + state + ", mSimNotLoadedSeen=" +
+                        mSimNotLoadedSeen);
+                if (!mSimNotLoadedSeen && !IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(state)) {
+                    mSimNotLoadedSeen = true;
                 }
 
-                if (mSimAbsentSeen && IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(state)) {
-                    mSimAbsentSeen = false;
+                if (mSimNotLoadedSeen && IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(state)) {
+                    mSimNotLoadedSeen = false;
                     try {
                         if (mContext.getResources().getString(com.android.internal.R.string.
                                 config_mobile_hotspot_provision_app_no_ui).isEmpty() == false) {
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 330dbab..e3dabc8 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -140,6 +140,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public boolean isPermissionReviewModeEnabled() {
+        return false;
+    }
+
     @Override
     public PermissionGroupInfo getPermissionGroupInfo(String name,
             int flags) throws NameNotFoundException {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index b3ed9e1..8dbbd07 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -127,6 +127,11 @@
     }
 
     @Override
+    public boolean isPermissionReviewModeEnabled() {
+        return false;
+    }
+
+    @Override
     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
             throws NameNotFoundException {
         return null;