Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +41 −8 Original line number Diff line number Diff line Loading @@ -254,6 +254,7 @@ public class GsmCdmaPhone extends Phone { CellBroadcastConfigTracker.make(this, null, true); private boolean mIsNullCipherAndIntegritySupported = false; private boolean mIsIdentifierDisclosureTransparencySupported = false; // Create Cfu (Call forward unconditional) so that dialing number & // mOnComplete (Message object passed by client) can be packed & Loading Loading @@ -3144,6 +3145,7 @@ public class GsmCdmaPhone extends Phone { mCi.areUiccApplicationsEnabled(obtainMessage(EVENT_GET_UICC_APPS_ENABLEMENT_DONE)); handleNullCipherEnabledChange(); handleIdentifierDisclosureNotificationPreferenceChange(); } private void handleRadioOn() { Loading Loading @@ -3610,14 +3612,7 @@ public class GsmCdmaPhone extends Phone { case EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE: logd("EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE"); ar = (AsyncResult) msg.obj; // Only test for a success here in order to flip the support flag. // Testing for the negative case, e.g. REQUEST_NOT_SUPPORTED, is insufficient // because the modem or the RIL could still return exceptions for temporary // failures even when the feature is unsupported. if (ar == null || ar.exception == null) { mIsNullCipherAndIntegritySupported = true; return; } mIsNullCipherAndIntegritySupported = doesResultIndicateModemSupport(ar); break; case EVENT_IMS_DEREGISTRATION_TRIGGERED: Loading Loading @@ -3701,11 +3696,25 @@ public class GsmCdmaPhone extends Phone { } break; case EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE: logd("EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE"); ar = (AsyncResult) msg.obj; mIsIdentifierDisclosureTransparencySupported = doesResultIndicateModemSupport(ar); break; default: super.handleMessage(msg); } } private boolean doesResultIndicateModemSupport(AsyncResult ar) { // We can only say that the modem supports a call without ambiguity if there // is no exception set on the response. Testing for REQUEST_NOT_SUPPORTED, is // insufficient because the modem or the RIL could still return exceptions for temporary // failures even when the feature is unsupported. return (ar == null || ar.exception == null); } private void parseImeiInfo(Message msg) { AsyncResult ar = (AsyncResult)msg.obj; if (ar.exception != null || ar.result == null) { Loading Loading @@ -5297,8 +5306,32 @@ public class GsmCdmaPhone extends Phone { obtainMessage(EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE)); } @Override public void handleIdentifierDisclosureNotificationPreferenceChange() { if (!mFeatureFlags.enableIdentifierDisclosureTransparency()) { logi("Not handling identifier disclosure preference change. Feature flag " + "ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY disabled"); return; } boolean prefEnabled = getIdentifierDisclosureNotificationsPreferenceEnabled(); if (prefEnabled) { mIdentifierDisclosureNotifier.enable(); } else { mIdentifierDisclosureNotifier.disable(); } mCi.setCellularIdentifierTransparencyEnabled(prefEnabled, obtainMessage(EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE)); } @Override public boolean isNullCipherAndIntegritySupported() { return mIsNullCipherAndIntegritySupported; } @Override public boolean isIdentifierDisclosureTransparencySupported() { return mIsIdentifierDisclosureTransparencySupported; } } src/java/com/android/internal/telephony/Phone.java +27 −1 Original line number Diff line number Diff line Loading @@ -255,7 +255,8 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected static final int EVENT_SET_N1_MODE_ENABLED_DONE = 70; protected static final int EVENT_IMEI_MAPPING_CHANGED = 71; protected static final int EVENT_CELL_IDENTIFIER_DISCLOSURE = 72; protected static final int EVENT_LAST = EVENT_CELL_IDENTIFIER_DISCLOSURE; protected static final int EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE = 73; protected static final int EVENT_LAST = EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE; // For shared prefs. private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_"; Loading Loading @@ -286,6 +287,9 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { "pref_null_cipher_and_integrity_enabled"; private final TelephonyAdminReceiver m2gAdminUpdater; public static final String PREF_IDENTIFIER_DISCLOSURE_NOTIFICATIONS_ENABLED = "pref_identifier_disclosure_notifications_enabled"; protected final FeatureFlags mFeatureFlags; /** Loading Loading @@ -5148,6 +5152,28 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { public void handleNullCipherEnabledChange() { } /** * @return whether or not this Phone interacts with a modem that supports the cellular * identifier disclosure transparency feature. */ public boolean isIdentifierDisclosureTransparencySupported() { return false; } /** * @return global cellular identifier disclosure transparency enabled preference */ public boolean getIdentifierDisclosureNotificationsPreferenceEnabled() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); return sp.getBoolean(PREF_IDENTIFIER_DISCLOSURE_NOTIFICATIONS_ENABLED, false); } /** * Override to handle an update to the cellular identifier disclosure transparency preference. */ public void handleIdentifierDisclosureNotificationPreferenceChange() { } /** * Notifies the IMS call status to the modem. * Loading src/java/com/android/internal/telephony/security/CellularIdentifierDisclosureNotifier.java +24 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ public class CellularIdentifierDisclosureNotifier { private static final String TAG = "CellularIdentifierDisclosureNotifier"; private static CellularIdentifierDisclosureNotifier sInstance = null; private boolean mEnabled = false; @VisibleForTesting public CellularIdentifierDisclosureNotifier() {} Loading @@ -59,4 +60,27 @@ public class CellularIdentifierDisclosureNotifier { return sInstance; } /** * Re-enable if previously disabled. This means that {@code addDisclsoure} will start tracking * disclosures again and potentially emitting notifications. */ public void enable() { Rlog.d(TAG, "enabled"); mEnabled = true; } /** * Clear all internal state and prevent further notifications until optionally re-enabled. * This can be used to in response to a user disabling the feature to emit notifications. * If {@code addDisclosure} is called while in a disabled state, disclosures will be dropped. */ public void disable() { Rlog.d(TAG, "disabled"); mEnabled = false; } public boolean isEnabled() { return mEnabled; } } tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java +79 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDI import static com.android.internal.telephony.Phone.EVENT_ICC_CHANGED; import static com.android.internal.telephony.Phone.EVENT_IMS_DEREGISTRATION_TRIGGERED; import static com.android.internal.telephony.Phone.EVENT_RADIO_AVAILABLE; import static com.android.internal.telephony.Phone.EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE; import static com.android.internal.telephony.Phone.EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE; import static com.android.internal.telephony.Phone.EVENT_SRVCC_STATE_CHANGED; import static com.android.internal.telephony.Phone.EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED; Loading Loading @@ -2858,4 +2859,82 @@ public class GsmCdmaPhoneTest extends TelephonyTest { verify(mIdentifierDisclosureNotifier, never()) .addDisclosure(any(CellularIdentifierDisclosure.class)); } @Test public void testCellularIdentifierDisclosure_noModemCallOnRadioAvailable_FlagOff() { when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(false); GsmCdmaPhone phoneUT = makeNewPhoneUT(); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); sendRadioAvailableToPhone(phoneUT); verify(mMockCi, never()).setCellularIdentifierTransparencyEnabled(anyBoolean(), any(Message.class)); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); } @Test public void testCellularIdentifierDisclosure_unsupportedByModemOnRadioAvailable() { when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(true); GsmCdmaPhone phoneUT = makeNewPhoneUT(); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); // The following block emulates incoming messages from the modem in the case that // the modem does not support the new HAL APIs. We expect the phone instance to attempt // to set cipher-identifier-transparency-enabled state when the radio becomes available. sendRadioAvailableToPhone(phoneUT); verify(mMockCi, times(1)).setCellularIdentifierTransparencyEnabled(anyBoolean(), any(Message.class)); sendRequestNotSupportedToPhone(phoneUT, EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); } @Test public void testCellularIdentifierDisclosure_supportedByModem() { when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(true); GsmCdmaPhone phoneUT = makeNewPhoneUT(); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); // The following block emulates incoming messages from the modem in the case that // the modem supports the new HAL APIs. We expect the phone instance to attempt // to set cipher-identifier-transparency-enabled state when the radio becomes available. sendRadioAvailableToPhone(phoneUT); verify(mMockCi, times(1)).setCellularIdentifierTransparencyEnabled(anyBoolean(), any(Message.class)); sendIdentifierDisclosureEnabledSuccessToPhone(phoneUT); assertTrue(phoneUT.isIdentifierDisclosureTransparencySupported()); } private void sendRadioAvailableToPhone(GsmCdmaPhone phone) { phone.sendMessage(phone.obtainMessage(EVENT_RADIO_AVAILABLE, new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null))); processAllMessages(); } private void sendRequestNotSupportedToPhone(GsmCdmaPhone phone, int eventId) { phone.sendMessage(phone.obtainMessage(eventId, new AsyncResult(null, null, new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))); processAllMessages(); } private void sendIdentifierDisclosureEnabledSuccessToPhone(GsmCdmaPhone phone) { phone.sendMessage(phone.obtainMessage(EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE, new AsyncResult(null, null, null))); processAllMessages(); } private GsmCdmaPhone makeNewPhoneUT() { return new GsmCdmaPhone( mContext, mMockCi, mNotifier, true, 0, PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager, mFeatureFlags); } } Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +41 −8 Original line number Diff line number Diff line Loading @@ -254,6 +254,7 @@ public class GsmCdmaPhone extends Phone { CellBroadcastConfigTracker.make(this, null, true); private boolean mIsNullCipherAndIntegritySupported = false; private boolean mIsIdentifierDisclosureTransparencySupported = false; // Create Cfu (Call forward unconditional) so that dialing number & // mOnComplete (Message object passed by client) can be packed & Loading Loading @@ -3144,6 +3145,7 @@ public class GsmCdmaPhone extends Phone { mCi.areUiccApplicationsEnabled(obtainMessage(EVENT_GET_UICC_APPS_ENABLEMENT_DONE)); handleNullCipherEnabledChange(); handleIdentifierDisclosureNotificationPreferenceChange(); } private void handleRadioOn() { Loading Loading @@ -3610,14 +3612,7 @@ public class GsmCdmaPhone extends Phone { case EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE: logd("EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE"); ar = (AsyncResult) msg.obj; // Only test for a success here in order to flip the support flag. // Testing for the negative case, e.g. REQUEST_NOT_SUPPORTED, is insufficient // because the modem or the RIL could still return exceptions for temporary // failures even when the feature is unsupported. if (ar == null || ar.exception == null) { mIsNullCipherAndIntegritySupported = true; return; } mIsNullCipherAndIntegritySupported = doesResultIndicateModemSupport(ar); break; case EVENT_IMS_DEREGISTRATION_TRIGGERED: Loading Loading @@ -3701,11 +3696,25 @@ public class GsmCdmaPhone extends Phone { } break; case EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE: logd("EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE"); ar = (AsyncResult) msg.obj; mIsIdentifierDisclosureTransparencySupported = doesResultIndicateModemSupport(ar); break; default: super.handleMessage(msg); } } private boolean doesResultIndicateModemSupport(AsyncResult ar) { // We can only say that the modem supports a call without ambiguity if there // is no exception set on the response. Testing for REQUEST_NOT_SUPPORTED, is // insufficient because the modem or the RIL could still return exceptions for temporary // failures even when the feature is unsupported. return (ar == null || ar.exception == null); } private void parseImeiInfo(Message msg) { AsyncResult ar = (AsyncResult)msg.obj; if (ar.exception != null || ar.result == null) { Loading Loading @@ -5297,8 +5306,32 @@ public class GsmCdmaPhone extends Phone { obtainMessage(EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE)); } @Override public void handleIdentifierDisclosureNotificationPreferenceChange() { if (!mFeatureFlags.enableIdentifierDisclosureTransparency()) { logi("Not handling identifier disclosure preference change. Feature flag " + "ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY disabled"); return; } boolean prefEnabled = getIdentifierDisclosureNotificationsPreferenceEnabled(); if (prefEnabled) { mIdentifierDisclosureNotifier.enable(); } else { mIdentifierDisclosureNotifier.disable(); } mCi.setCellularIdentifierTransparencyEnabled(prefEnabled, obtainMessage(EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE)); } @Override public boolean isNullCipherAndIntegritySupported() { return mIsNullCipherAndIntegritySupported; } @Override public boolean isIdentifierDisclosureTransparencySupported() { return mIsIdentifierDisclosureTransparencySupported; } }
src/java/com/android/internal/telephony/Phone.java +27 −1 Original line number Diff line number Diff line Loading @@ -255,7 +255,8 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { protected static final int EVENT_SET_N1_MODE_ENABLED_DONE = 70; protected static final int EVENT_IMEI_MAPPING_CHANGED = 71; protected static final int EVENT_CELL_IDENTIFIER_DISCLOSURE = 72; protected static final int EVENT_LAST = EVENT_CELL_IDENTIFIER_DISCLOSURE; protected static final int EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE = 73; protected static final int EVENT_LAST = EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE; // For shared prefs. private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_"; Loading Loading @@ -286,6 +287,9 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { "pref_null_cipher_and_integrity_enabled"; private final TelephonyAdminReceiver m2gAdminUpdater; public static final String PREF_IDENTIFIER_DISCLOSURE_NOTIFICATIONS_ENABLED = "pref_identifier_disclosure_notifications_enabled"; protected final FeatureFlags mFeatureFlags; /** Loading Loading @@ -5148,6 +5152,28 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { public void handleNullCipherEnabledChange() { } /** * @return whether or not this Phone interacts with a modem that supports the cellular * identifier disclosure transparency feature. */ public boolean isIdentifierDisclosureTransparencySupported() { return false; } /** * @return global cellular identifier disclosure transparency enabled preference */ public boolean getIdentifierDisclosureNotificationsPreferenceEnabled() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); return sp.getBoolean(PREF_IDENTIFIER_DISCLOSURE_NOTIFICATIONS_ENABLED, false); } /** * Override to handle an update to the cellular identifier disclosure transparency preference. */ public void handleIdentifierDisclosureNotificationPreferenceChange() { } /** * Notifies the IMS call status to the modem. * Loading
src/java/com/android/internal/telephony/security/CellularIdentifierDisclosureNotifier.java +24 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ public class CellularIdentifierDisclosureNotifier { private static final String TAG = "CellularIdentifierDisclosureNotifier"; private static CellularIdentifierDisclosureNotifier sInstance = null; private boolean mEnabled = false; @VisibleForTesting public CellularIdentifierDisclosureNotifier() {} Loading @@ -59,4 +60,27 @@ public class CellularIdentifierDisclosureNotifier { return sInstance; } /** * Re-enable if previously disabled. This means that {@code addDisclsoure} will start tracking * disclosures again and potentially emitting notifications. */ public void enable() { Rlog.d(TAG, "enabled"); mEnabled = true; } /** * Clear all internal state and prevent further notifications until optionally re-enabled. * This can be used to in response to a user disabling the feature to emit notifications. * If {@code addDisclosure} is called while in a disabled state, disclosures will be dropped. */ public void disable() { Rlog.d(TAG, "disabled"); mEnabled = false; } public boolean isEnabled() { return mEnabled; } }
tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java +79 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDI import static com.android.internal.telephony.Phone.EVENT_ICC_CHANGED; import static com.android.internal.telephony.Phone.EVENT_IMS_DEREGISTRATION_TRIGGERED; import static com.android.internal.telephony.Phone.EVENT_RADIO_AVAILABLE; import static com.android.internal.telephony.Phone.EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE; import static com.android.internal.telephony.Phone.EVENT_SET_NULL_CIPHER_AND_INTEGRITY_DONE; import static com.android.internal.telephony.Phone.EVENT_SRVCC_STATE_CHANGED; import static com.android.internal.telephony.Phone.EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED; Loading Loading @@ -2858,4 +2859,82 @@ public class GsmCdmaPhoneTest extends TelephonyTest { verify(mIdentifierDisclosureNotifier, never()) .addDisclosure(any(CellularIdentifierDisclosure.class)); } @Test public void testCellularIdentifierDisclosure_noModemCallOnRadioAvailable_FlagOff() { when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(false); GsmCdmaPhone phoneUT = makeNewPhoneUT(); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); sendRadioAvailableToPhone(phoneUT); verify(mMockCi, never()).setCellularIdentifierTransparencyEnabled(anyBoolean(), any(Message.class)); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); } @Test public void testCellularIdentifierDisclosure_unsupportedByModemOnRadioAvailable() { when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(true); GsmCdmaPhone phoneUT = makeNewPhoneUT(); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); // The following block emulates incoming messages from the modem in the case that // the modem does not support the new HAL APIs. We expect the phone instance to attempt // to set cipher-identifier-transparency-enabled state when the radio becomes available. sendRadioAvailableToPhone(phoneUT); verify(mMockCi, times(1)).setCellularIdentifierTransparencyEnabled(anyBoolean(), any(Message.class)); sendRequestNotSupportedToPhone(phoneUT, EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); } @Test public void testCellularIdentifierDisclosure_supportedByModem() { when(mFeatureFlags.enableIdentifierDisclosureTransparency()).thenReturn(true); GsmCdmaPhone phoneUT = makeNewPhoneUT(); assertFalse(phoneUT.isIdentifierDisclosureTransparencySupported()); // The following block emulates incoming messages from the modem in the case that // the modem supports the new HAL APIs. We expect the phone instance to attempt // to set cipher-identifier-transparency-enabled state when the radio becomes available. sendRadioAvailableToPhone(phoneUT); verify(mMockCi, times(1)).setCellularIdentifierTransparencyEnabled(anyBoolean(), any(Message.class)); sendIdentifierDisclosureEnabledSuccessToPhone(phoneUT); assertTrue(phoneUT.isIdentifierDisclosureTransparencySupported()); } private void sendRadioAvailableToPhone(GsmCdmaPhone phone) { phone.sendMessage(phone.obtainMessage(EVENT_RADIO_AVAILABLE, new AsyncResult(null, new int[]{ServiceState.RIL_RADIO_TECHNOLOGY_GSM}, null))); processAllMessages(); } private void sendRequestNotSupportedToPhone(GsmCdmaPhone phone, int eventId) { phone.sendMessage(phone.obtainMessage(eventId, new AsyncResult(null, null, new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))); processAllMessages(); } private void sendIdentifierDisclosureEnabledSuccessToPhone(GsmCdmaPhone phone) { phone.sendMessage(phone.obtainMessage(EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE, new AsyncResult(null, null, null))); processAllMessages(); } private GsmCdmaPhone makeNewPhoneUT() { return new GsmCdmaPhone( mContext, mMockCi, mNotifier, true, 0, PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager, mFeatureFlags); } }