diff options
7 files changed, 86 insertions, 5 deletions
diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 6af887d401f6..9cd7cc6aedcf 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -197,6 +197,9 @@ <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"> <new-permission name="android.permission.READ_EXTERNAL_STORAGE" /> </split-permission> + <split-permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"> + <new-permission name="android.permission.READ_PHONE_STATE" /> + </split-permission> <split-permission name="android.permission.READ_CONTACTS" targetSdk="16"> <new-permission name="android.permission.READ_CALL_LOG" /> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index a96ef91850df..b37400f691ae 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1664,6 +1664,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); mBroadcastDispatcher.registerReceiverWithHandler(mBroadcastReceiver, filter, mHandler); + // Since ACTION_SERVICE_STATE is being moved to a non-sticky broadcast, trigger the + // listener now with the service state from the default sub. + mBackgroundExecutor.execute(() -> { + int subId = SubscriptionManager.getDefaultSubscriptionId(); + ServiceState serviceState = mContext.getSystemService(TelephonyManager.class) + .getServiceStateForSubscriber(subId); + mHandler.sendMessage( + mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState)); + }); mHandler.post(this::registerRingerTracker); 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 a284335c972e..f41a27cf4c64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -329,7 +329,8 @@ public class NetworkControllerImpl extends BroadcastReceiver return mDataSaverController; } - private void registerListeners() { + @VisibleForTesting + void registerListeners() { for (int i = 0; i < mMobileSignalControllers.size(); i++) { MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i); mobileSignalController.registerListener(); @@ -364,6 +365,18 @@ public class NetworkControllerImpl extends BroadcastReceiver // Initial setup of WifiSignalController. Handled as if we had received a sticky broadcast // of WifiManager.WIFI_STATE_CHANGED_ACTION or WifiManager.NETWORK_STATE_CHANGED_ACTION mReceiverHandler.post(mWifiSignalController::fetchInitialState); + + // Initial setup of mLastServiceState. Only run if there is no service state yet. + // Each MobileSignalController will also get their corresponding + mReceiverHandler.post(() -> { + if (mLastServiceState == null) { + mLastServiceState = mPhone.getServiceState(); + if (mMobileSignalControllers.size() == 0) { + recalculateEmergency(); + } + } + }); + updateMobileControllers(); // Initial setup of emergency information. Handled as if we had received a sticky broadcast diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 6c00ecacf97d..c3106bb2e3f2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -70,6 +70,7 @@ import android.testing.TestableLooper; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; +import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.internal.telephony.TelephonyIntents; import com.android.keyguard.KeyguardUpdateMonitor.BiometricAuthenticated; import com.android.systemui.SysuiTestCase; @@ -87,6 +88,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.MockitoSession; import java.util.ArrayList; import java.util.List; @@ -134,16 +136,17 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Mock private BroadcastDispatcher mBroadcastDispatcher; @Mock + private TelephonyManager mTelephonyManager; + @Mock private RingerModeTracker mRingerModeTracker; @Mock private LiveData<Integer> mRingerModeLiveData; - @Mock - private TelephonyManager mTelephonyManager; // Direct executor private Executor mBackgroundExecutor = Runnable::run; private TestableLooper mTestableLooper; private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor; private TestableContext mSpiedContext; + private MockitoSession mMockitoSession; @Before public void setup() { @@ -165,6 +168,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { when(mStrongAuthTracker .isUnlockingWithBiometricAllowed(anyBoolean() /* isStrongBiometric */)) .thenReturn(true); + + when(mTelephonyManager.getServiceStateForSubscriber(anyInt())) + .thenReturn(new ServiceState()); mSpiedContext.addMockSystemService(TrustManager.class, mTrustManager); mSpiedContext.addMockSystemService(FingerprintManager.class, mFingerprintManager); mSpiedContext.addMockSystemService(BiometricManager.class, mBiometricManager); @@ -176,6 +182,11 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData); + mMockitoSession = ExtendedMockito.mockitoSession() + .spyStatic(SubscriptionManager.class).startMocking(); + ExtendedMockito.doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID) + .when(SubscriptionManager::getDefaultSubscriptionId); + mTestableLooper = TestableLooper.get(this); allowTestableLooperAsMainThread(); mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mSpiedContext); @@ -183,6 +194,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @After public void tearDown() { + mMockitoSession.finishMocking(); mKeyguardUpdateMonitor.destroy(); } 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 399b5c24431b..3b2743775721 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 @@ -25,6 +25,7 @@ import static org.mockito.Mockito.when; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; +import android.os.Handler; import android.os.Looper; import android.telephony.CellSignalStrength; import android.telephony.ServiceState; @@ -46,6 +47,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import java.util.ArrayList; +import java.util.Collections; import java.util.List; @SmallTest @@ -68,6 +70,28 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { } @Test + public void testServiceStateInitialState() throws Exception { + // Verify that NetworkControllerImpl pulls the service state from Telephony upon + // initialization rather than relying on the sticky behavior of ACTION_SERVICE_STATE + + when(mServiceState.isEmergencyOnly()).thenReturn(true); + when(mMockTm.getServiceState()).thenReturn(mServiceState); + when(mMockSm.getCompleteActiveSubscriptionInfoList()).thenReturn(Collections.emptyList()); + + mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, + mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler, + mock(AccessPointControllerImpl.class), mock(DataUsageController.class), + mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd); + mNetworkController.registerListeners(); + + // Wait for the main looper to execute the previous command + Handler mainThreadHandler = new Handler(Looper.getMainLooper()); + waitForIdleSync(mainThreadHandler); + + verifyEmergencyOnly(true); + } + + @Test public void testNoSimsIconPresent() { // No Subscriptions. mNetworkController.mMobileSignalControllers.clear(); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 97a5cfe6006d..1d40e2ee92f4 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -23,6 +23,7 @@ import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_VOI import static java.util.Arrays.copyOf; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -2459,7 +2460,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId); intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId); - mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE); } private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId, @@ -2584,7 +2585,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, ApnSetting.getApnTypesStringFromBitmask(apnType)); intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); - mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE); } private void enforceNotifyPermissionOrCarrierPrivilege(String method) { diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index 9051d85b2140..8f3bf39d4fc5 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -408,6 +408,25 @@ public final class DefaultPermissionGrantPolicy { } grantRuntimePermissionsForSystemPackage(pm, userId, pkg); } + + // Grant READ_PHONE_STATE to all system apps that have READ_PRIVILEGED_PHONE_STATE + for (PackageInfo pkg : packages) { + if (pkg == null + || !doesPackageSupportRuntimePermissions(pkg) + || ArrayUtils.isEmpty(pkg.requestedPermissions) + || !pkg.applicationInfo.isPrivilegedApp()) { + continue; + } + for (String permission : pkg.requestedPermissions) { + if (Manifest.permission.READ_PRIVILEGED_PHONE_STATE.equals(permission)) { + grantRuntimePermissions(pm, pkg, + Collections.singleton(Manifest.permission.READ_PHONE_STATE), + true, // systemFixed + userId); + } + } + } + } @SafeVarargs |