diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1845faacc891e..529db3f53b420 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -58,6 +58,7 @@
- @string/status_bar_hotspot
- @string/status_bar_mobile
- @string/status_bar_airplane
+ - @string/status_bar_no_calling
- @string/status_bar_battery
- @string/status_bar_sensors_off
@@ -94,6 +95,7 @@
microphone
camera
airplane
+ no_calling
sensors_off
screen_record
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c72a0cd63b36d..12acfd7cf8304 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2947,6 +2947,7 @@
+
diff --git a/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml b/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml
new file mode 100644
index 0000000000000..3d6ca7acda870
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index f0efed332c7fa..00acd7bb67071 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.StatusBarMobileView;
import com.android.systemui.statusbar.StatusBarWifiView;
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
+import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.NoCallingIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import java.util.List;
@@ -62,6 +63,10 @@ public interface StatusBarIconController {
public void setIcon(String slot, StatusBarIcon icon);
public void setSignalIcon(String slot, WifiIconState state);
public void setMobileIcons(String slot, List states);
+ /**
+ * Display the no calling & SMS icons.
+ */
+ void setNoCallingIcons(String slot, List states);
public void setIconVisibility(String slot, boolean b);
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 2870152ed8533..5e8d59041faba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -35,6 +35,7 @@ import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
+import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.NoCallingIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -216,6 +217,29 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
}
}
+ /**
+ * Accept a list of NoCallingIconStates, and show them in the same slot
+ * @param slot StatusBar slot
+ * @param states All of the no Calling & SMS icon states
+ */
+ @Override
+ public void setNoCallingIcons(String slot, List states) {
+ Slot noCallingSlot = getSlot(slot);
+ int slotIndex = getSlotIndex(slot);
+
+ for (NoCallingIconState state : states) {
+ StatusBarIconHolder holder = noCallingSlot.getHolderForTag(state.subId);
+ if (holder == null) {
+ holder = StatusBarIconHolder.fromNoCallingState(mContext, state);
+ holder.setVisible(state.visible);
+ setIcon(slotIndex, holder);
+ } else {
+ holder.setVisible(state.visible);
+ setIcon(slotIndex, holder);
+ }
+ }
+ }
+
@Override
public void setExternalIcon(String slot) {
int viewIndex = getViewIndex(getSlotIndex(slot), 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
index 88d0035b333d7..36a0e63db19fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
@@ -23,6 +23,7 @@ import android.os.UserHandle;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
+import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.NoCallingIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
/**
@@ -70,6 +71,18 @@ public class StatusBarIconHolder {
return holder;
}
+ /**
+ * Creates a new StatusBarIconHolder from a NoCallingIconState.
+ */
+ public static StatusBarIconHolder fromNoCallingState(
+ Context context, NoCallingIconState state) {
+ StatusBarIconHolder holder = new StatusBarIconHolder();
+ holder.mIcon = new StatusBarIcon(UserHandle.SYSTEM, context.getPackageName(),
+ Icon.createWithResource(context, state.resId), 0, 0, null);
+ holder.mTag = state.subId;
+ return holder;
+ }
+
public int getType() {
return mType;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 1fdd8161914af..d11e8641f987f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -46,6 +46,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
private final String mSlotWifi;
private final String mSlotEthernet;
private final String mSlotVpn;
+ private final String mSlotNoCalling;
private final Context mContext;
private final StatusBarIconController mIconController;
@@ -66,6 +67,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
private boolean mWifiVisible = false;
private ArrayList mMobileStates = new ArrayList();
+ private ArrayList mNoCallingStates = new ArrayList();
private WifiIconState mWifiIconState = new WifiIconState();
public StatusBarSignalPolicy(Context context, StatusBarIconController iconController) {
@@ -76,6 +78,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
mSlotWifi = mContext.getString(com.android.internal.R.string.status_bar_wifi);
mSlotEthernet = mContext.getString(com.android.internal.R.string.status_bar_ethernet);
mSlotVpn = mContext.getString(com.android.internal.R.string.status_bar_vpn);
+ mSlotNoCalling = mContext.getString(com.android.internal.R.string.status_bar_no_calling);
mActivityEnabled = mContext.getResources().getBoolean(R.bool.config_showActivity);
mIconController = iconController;
@@ -197,6 +200,22 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
}
}
+ @Override
+ public void setNoCallingStatus(boolean noCalling, int subId) {
+ if (DEBUG) {
+ Log.d(TAG, "setNoCallingStatus: "
+ + "noCalling = " + noCalling + ","
+ + "subId = " + subId);
+ }
+ NoCallingIconState state = getNoCallingState(subId);
+ if (state == null) {
+ return;
+ }
+ state.visible = noCalling;
+ mIconController.setNoCallingIcons(
+ mSlotNoCalling, NoCallingIconState.copyStates(mNoCallingStates));
+ }
+
@Override
public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
int qsType, boolean activityIn, boolean activityOut,
@@ -252,6 +271,16 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
}
}
+ private NoCallingIconState getNoCallingState(int subId) {
+ for (NoCallingIconState state : mNoCallingStates) {
+ if (state.subId == subId) {
+ return state;
+ }
+ }
+ Log.e(TAG, "Unexpected subscription " + subId);
+ return null;
+ }
+
private MobileIconState getState(int subId) {
for (MobileIconState state : mMobileStates) {
if (state.subId == subId) {
@@ -285,9 +314,11 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
mIconController.removeAllIconsForSlot(mSlotMobile);
mMobileStates.clear();
+ mNoCallingStates.clear();
final int n = subs.size();
for (int i = 0; i < n; i++) {
mMobileStates.add(new MobileIconState(subs.get(i).getSubscriptionId()));
+ mNoCallingStates.add(new NoCallingIconState(subs.get(i).getSubscriptionId()));
}
}
@@ -377,6 +408,53 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
// Don't care.
}
+ /**
+ * Stores the StatusBar state for no Calling & SMS.
+ */
+ public static class NoCallingIconState {
+ public boolean visible;
+ public int resId;
+ public int subId;
+
+ private NoCallingIconState(int subId) {
+ this.subId = subId;
+ this.resId = R.drawable.ic_qs_no_calling_sms;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ // Skipping reference equality bc this should be more of a value type
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ NoCallingIconState that = (NoCallingIconState) o;
+ return visible == that.visible
+ && resId == that.resId
+ && subId == that.subId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(visible, resId, subId);
+ }
+
+ private void copyTo(NoCallingIconState other) {
+ other.visible = visible;
+ other.resId = resId;
+ other.subId = subId;
+ }
+
+ private static List copyStates(List inStates) {
+ ArrayList outStates = new ArrayList<>();
+ for (NoCallingIconState state : inStates) {
+ NoCallingIconState copy = new NoCallingIconState(state.subId);
+ state.copyTo(copy);
+ outStates.add(copy);
+ }
+ return outStates;
+ }
+ }
+
private static abstract class SignalIconState {
public boolean visible;
public boolean activityOut;
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 1cc312adcbf03..5e88cd5c2423c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
@@ -145,6 +145,15 @@ public class CallbackHandler extends Handler implements EmergencyListener, Signa
});
}
+ @Override
+ public void setNoCallingStatus(boolean noCalling, int subId) {
+ post(() -> {
+ for (SignalCallback signalCluster : mSignalCallbacks) {
+ signalCluster.setNoCallingStatus(noCalling, subId);
+ }
+ });
+ }
+
@Override
public void setSubs(List subs) {
obtainMessage(MSG_SUBS_CHANGED, subs).sendToTarget();
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 101e3c6f1bc62..24b820669beb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -458,9 +458,23 @@ public class MobileSignalController extends SignalController, D
*/
default void setConnectivityStatus(boolean noDefaultNetwork, boolean noValidatedNetwork,
boolean noNetworksAvailable) {}
+
+ /**
+ * Callback for listeners to be able to update the no calling & SMS status
+ * @param noCalling whether the calling and SMS is not working.
+ * @param subId subscription ID for which to update the UI
+ */
+ default void setNoCallingStatus(boolean noCalling, int subId) {}
}
public interface EmergencyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
index a05fe1f1b0c26..554145e9773e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
@@ -167,6 +167,10 @@ public abstract class SignalController {
}
}
+ protected final void notifyNoCallingStatusChange(boolean noCalling, int subId) {
+ mCallbackHandler.setNoCallingStatus(noCalling, subId);
+ }
+
/**
* Returns the resource if resId is not 0, and an empty string otherwise.
*/
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
index 2e874a6c21401..c0af15b1f96dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
@@ -20,6 +20,7 @@ import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
+import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.NoCallingIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import java.util.List;
@@ -64,6 +65,10 @@ public class FakeStatusBarIconController extends BaseLeakChecker
public void setMobileIcons(String slot, List states) {
}
+ @Override
+ public void setNoCallingIcons(String slot, List states) {
+ }
+
@Override
public void setIconVisibility(String slotTty, boolean b) {
}