Loading src/java/com/android/internal/telephony/RcsController.java 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.content.Context; import android.os.ServiceManager; import android.telephony.Rlog; /** Backing implementation of {@link android.telephony.RcsManager}. */ public class RcsController extends IRcs.Stub { private static final String TAG = "RcsController"; private static RcsController sInstance; private final Context mContext; /** Initialize the instance. Should only be called once. */ public static RcsController init(Context context) { synchronized (RcsController.class) { if (sInstance == null) { sInstance = new RcsController(context); } else { Rlog.e(TAG, "init() called multiple times! sInstance = " + sInstance); } } return sInstance; } private RcsController(Context context) { mContext = context; ServiceManager.addService("ircs", this); } @Override public void deleteThread(int threadId) { // TODO - add implementation } } src/java/com/android/internal/telephony/ServiceStateTracker.java +54 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.provider.Telephony.ServiceStateTable.getUriForSubscription import static com.android.internal.telephony.CarrierActionAgent.CARRIER_ACTION_SET_RADIO_ENABLED; import android.Manifest.permission; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; Loading Loading @@ -185,6 +186,10 @@ public class ServiceStateTracker extends Handler { private boolean mPendingRadioPowerOffAfterDataOff = false; private int mPendingRadioPowerOffAfterDataOffTag = 0; // This is a flag for debug purposes only. It it set once the RUIM_RECORDS_LOADED event is // received while the phone type is CDMA-LTE, and is never reset after that. private boolean mRuimRecordsLoaded = false; /** Signal strength poll rate. */ private static final int POLL_PERIOD_MILLIS = 20 * 1000; Loading Loading @@ -283,6 +288,7 @@ public class ServiceStateTracker extends Handler { private final LocalLog mPhoneTypeLog = new LocalLog(10); private final LocalLog mRatLog = new LocalLog(20); private final LocalLog mRadioPowerLog = new LocalLog(20); private final LocalLog mMdnLog = new LocalLog(20); private class SstSubscriptionsChangedListener extends OnSubscriptionsChangedListener { public final AtomicInteger mPreviousSubId = Loading Loading @@ -604,6 +610,7 @@ public class ServiceStateTracker extends Handler { mStartedGprsRegCheck = false; mReportedGprsNoReg = false; mMdn = null; logMdnChange("updatePhoneType: setting mMdn to null"); mMin = null; mPrlVersion = null; mIsMinInfoReady = false; Loading Loading @@ -965,6 +972,7 @@ public class ServiceStateTracker extends Handler { cancelAllNotifications(); // clear cached values on SIM removal mMdn = null; logMdnChange("EVENT_ICC_CHANGED: setting mMdn to null"); mMin = null; mIsMinInfoReady = false; } Loading Loading @@ -1313,6 +1321,8 @@ public class ServiceStateTracker extends Handler { String cdmaSubscription[] = (String[]) ar.result; if (cdmaSubscription != null && cdmaSubscription.length >= 5) { mMdn = cdmaSubscription[0]; logMdnChange("EVENT_POLL_STATE_CDMA_SUBSCRIPTION: setting mMdn to " + mMdn); parseSidNid(cdmaSubscription[1], cdmaSubscription[2]); mMin = cdmaSubscription[3]; Loading Loading @@ -1354,17 +1364,25 @@ public class ServiceStateTracker extends Handler { updateSpnDisplay(); } else { RuimRecords ruim = (RuimRecords) mIccRecords; mRuimRecordsLoaded = true; if (ruim != null) { if (ruim.isProvisioned()) { mMdn = ruim.getMdn(); logMdnChange("EVENT_RUIM_RECORDS_LOADED: setting mMdn to " + mMdn); mMin = ruim.getMin(); parseSidNid(ruim.getSid(), ruim.getNid()); mPrlVersion = ruim.getPrlVersion(); mIsMinInfoReady = true; } else { logMdnChange("EVENT_RUIM_RECORDS_LOADED: ruim not provisioned; " + "not updating mMdn " + mMdn); } updateOtaspState(); // Notify apps subscription info is ready notifyCdmaSubscriptionInfoReady(); } else { logMdnChange("EVENT_RUIM_RECORDS_LOADED: ruim is null; " + "not updating mMdn " + mMdn); } // SID/NID/PRL is loaded. Poll service state // again to update to the roaming state with Loading Loading @@ -1497,6 +1515,27 @@ public class ServiceStateTracker extends Handler { } public String getMdnNumber() { // if for CDMA-LTE phone MDN is null, and it has already been updated from RUIM, in some // unknown error scenario mMdn may still have been updated to null. Detect and fix that case if (mMdn == null && mRuimRecordsLoaded && mPhone.isPhoneTypeCdmaLte()) { // query RuimRecords to see if it's not null and the value from there can be used. This // should never be the case except in certain error scenarios/race conditions. RuimRecords ruim = (RuimRecords) mIccRecords; if (ruim != null) { if (ruim.isProvisioned() && ruim.getMdn() != null) { logeMdnChange("getMdnNumber: mMdn is null when RuimRecords.getMdn() is not"); // broadcast intent to indicate an error related to Line1Number has been // detected Intent intent = new Intent(TelephonyIntents.ACTION_LINE1_NUMBER_ERROR_DETECTED); mPhone.getContext().sendBroadcast(intent, permission.READ_PRIVILEGED_PHONE_STATE); // update mdn mMdn = ruim.getMdn(); } } } return mMdn; } Loading Loading @@ -2617,6 +2656,16 @@ public class ServiceStateTracker extends Handler { mRatLog.log(mSS.toString()); } private void logMdnChange(String msg) { mMdnLog.log(msg); log(msg); } private void logeMdnChange(String msg) { mMdnLog.log(msg); loge(msg); } protected final void log(String s) { Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + s); } Loading Loading @@ -4539,6 +4588,11 @@ public class ServiceStateTracker extends Handler { ipw.println(" Radio power Log:"); ipw.increaseIndent(); mRadioPowerLog.dump(fd, ipw, args); ipw.decreaseIndent(); ipw.println(" mMdn Log:"); ipw.increaseIndent(); mMdnLog.dump(fd, ipw, args); mNitzState.dumpLogs(fd, ipw, args); } Loading tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -1817,4 +1817,49 @@ public class ServiceStateTrackerTest extends TelephonyTest { waitForMs(200); assertTrue(Arrays.equals(new int[0], sst.mSS.getCellBandwidths())); } @Test @SmallTest public void testGetMdn() throws Exception { doReturn(false).when(mPhone).isPhoneTypeGsm(); doReturn(false).when(mPhone).isPhoneTypeCdma(); doReturn(true).when(mPhone).isPhoneTypeCdmaLte(); doReturn(CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM).when(mCdmaSSM) .getCdmaSubscriptionSource(); logd("Calling updatePhoneType"); // switch to CDMA sst.updatePhoneType(); // trigger RUIM_RECORDS_LOADED ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class); verify(mRuimRecords).registerForRecordsLoaded(eq(sst), integerArgumentCaptor.capture(), nullable(Object.class)); // response for mRuimRecords.registerForRecordsLoaded() Message msg = Message.obtain(); msg.what = integerArgumentCaptor.getValue(); msg.obj = new AsyncResult(null, null, null); sst.sendMessage(msg); // wait for RUIM_RECORDS_LOADED to be handled waitForHandlerAction(sst, 5000); // mdn should be null as nothing populated it assertEquals(null, sst.getMdnNumber()); // if ruim is provisioned, mdn should still be null doReturn(true).when(mRuimRecords).isProvisioned(); assertEquals(null, sst.getMdnNumber()); // if ruim is not provisioned, and mdn is non null, sst should still return null doReturn(false).when(mRuimRecords).isProvisioned(); String mockMdn = "mockMdn"; doReturn(mockMdn).when(mRuimRecords).getMdn(); assertEquals(null, sst.getMdnNumber()); // if ruim is provisioned, and mdn is non null, sst should also return the correct value doReturn(true).when(mRuimRecords).isProvisioned(); assertEquals(mockMdn, sst.getMdnNumber()); } } Loading
src/java/com/android/internal/telephony/RcsController.java 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.content.Context; import android.os.ServiceManager; import android.telephony.Rlog; /** Backing implementation of {@link android.telephony.RcsManager}. */ public class RcsController extends IRcs.Stub { private static final String TAG = "RcsController"; private static RcsController sInstance; private final Context mContext; /** Initialize the instance. Should only be called once. */ public static RcsController init(Context context) { synchronized (RcsController.class) { if (sInstance == null) { sInstance = new RcsController(context); } else { Rlog.e(TAG, "init() called multiple times! sInstance = " + sInstance); } } return sInstance; } private RcsController(Context context) { mContext = context; ServiceManager.addService("ircs", this); } @Override public void deleteThread(int threadId) { // TODO - add implementation } }
src/java/com/android/internal/telephony/ServiceStateTracker.java +54 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.provider.Telephony.ServiceStateTable.getUriForSubscription import static com.android.internal.telephony.CarrierActionAgent.CARRIER_ACTION_SET_RADIO_ENABLED; import android.Manifest.permission; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; Loading Loading @@ -185,6 +186,10 @@ public class ServiceStateTracker extends Handler { private boolean mPendingRadioPowerOffAfterDataOff = false; private int mPendingRadioPowerOffAfterDataOffTag = 0; // This is a flag for debug purposes only. It it set once the RUIM_RECORDS_LOADED event is // received while the phone type is CDMA-LTE, and is never reset after that. private boolean mRuimRecordsLoaded = false; /** Signal strength poll rate. */ private static final int POLL_PERIOD_MILLIS = 20 * 1000; Loading Loading @@ -283,6 +288,7 @@ public class ServiceStateTracker extends Handler { private final LocalLog mPhoneTypeLog = new LocalLog(10); private final LocalLog mRatLog = new LocalLog(20); private final LocalLog mRadioPowerLog = new LocalLog(20); private final LocalLog mMdnLog = new LocalLog(20); private class SstSubscriptionsChangedListener extends OnSubscriptionsChangedListener { public final AtomicInteger mPreviousSubId = Loading Loading @@ -604,6 +610,7 @@ public class ServiceStateTracker extends Handler { mStartedGprsRegCheck = false; mReportedGprsNoReg = false; mMdn = null; logMdnChange("updatePhoneType: setting mMdn to null"); mMin = null; mPrlVersion = null; mIsMinInfoReady = false; Loading Loading @@ -965,6 +972,7 @@ public class ServiceStateTracker extends Handler { cancelAllNotifications(); // clear cached values on SIM removal mMdn = null; logMdnChange("EVENT_ICC_CHANGED: setting mMdn to null"); mMin = null; mIsMinInfoReady = false; } Loading Loading @@ -1313,6 +1321,8 @@ public class ServiceStateTracker extends Handler { String cdmaSubscription[] = (String[]) ar.result; if (cdmaSubscription != null && cdmaSubscription.length >= 5) { mMdn = cdmaSubscription[0]; logMdnChange("EVENT_POLL_STATE_CDMA_SUBSCRIPTION: setting mMdn to " + mMdn); parseSidNid(cdmaSubscription[1], cdmaSubscription[2]); mMin = cdmaSubscription[3]; Loading Loading @@ -1354,17 +1364,25 @@ public class ServiceStateTracker extends Handler { updateSpnDisplay(); } else { RuimRecords ruim = (RuimRecords) mIccRecords; mRuimRecordsLoaded = true; if (ruim != null) { if (ruim.isProvisioned()) { mMdn = ruim.getMdn(); logMdnChange("EVENT_RUIM_RECORDS_LOADED: setting mMdn to " + mMdn); mMin = ruim.getMin(); parseSidNid(ruim.getSid(), ruim.getNid()); mPrlVersion = ruim.getPrlVersion(); mIsMinInfoReady = true; } else { logMdnChange("EVENT_RUIM_RECORDS_LOADED: ruim not provisioned; " + "not updating mMdn " + mMdn); } updateOtaspState(); // Notify apps subscription info is ready notifyCdmaSubscriptionInfoReady(); } else { logMdnChange("EVENT_RUIM_RECORDS_LOADED: ruim is null; " + "not updating mMdn " + mMdn); } // SID/NID/PRL is loaded. Poll service state // again to update to the roaming state with Loading Loading @@ -1497,6 +1515,27 @@ public class ServiceStateTracker extends Handler { } public String getMdnNumber() { // if for CDMA-LTE phone MDN is null, and it has already been updated from RUIM, in some // unknown error scenario mMdn may still have been updated to null. Detect and fix that case if (mMdn == null && mRuimRecordsLoaded && mPhone.isPhoneTypeCdmaLte()) { // query RuimRecords to see if it's not null and the value from there can be used. This // should never be the case except in certain error scenarios/race conditions. RuimRecords ruim = (RuimRecords) mIccRecords; if (ruim != null) { if (ruim.isProvisioned() && ruim.getMdn() != null) { logeMdnChange("getMdnNumber: mMdn is null when RuimRecords.getMdn() is not"); // broadcast intent to indicate an error related to Line1Number has been // detected Intent intent = new Intent(TelephonyIntents.ACTION_LINE1_NUMBER_ERROR_DETECTED); mPhone.getContext().sendBroadcast(intent, permission.READ_PRIVILEGED_PHONE_STATE); // update mdn mMdn = ruim.getMdn(); } } } return mMdn; } Loading Loading @@ -2617,6 +2656,16 @@ public class ServiceStateTracker extends Handler { mRatLog.log(mSS.toString()); } private void logMdnChange(String msg) { mMdnLog.log(msg); log(msg); } private void logeMdnChange(String msg) { mMdnLog.log(msg); loge(msg); } protected final void log(String s) { Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + s); } Loading Loading @@ -4539,6 +4588,11 @@ public class ServiceStateTracker extends Handler { ipw.println(" Radio power Log:"); ipw.increaseIndent(); mRadioPowerLog.dump(fd, ipw, args); ipw.decreaseIndent(); ipw.println(" mMdn Log:"); ipw.increaseIndent(); mMdnLog.dump(fd, ipw, args); mNitzState.dumpLogs(fd, ipw, args); } Loading
tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -1817,4 +1817,49 @@ public class ServiceStateTrackerTest extends TelephonyTest { waitForMs(200); assertTrue(Arrays.equals(new int[0], sst.mSS.getCellBandwidths())); } @Test @SmallTest public void testGetMdn() throws Exception { doReturn(false).when(mPhone).isPhoneTypeGsm(); doReturn(false).when(mPhone).isPhoneTypeCdma(); doReturn(true).when(mPhone).isPhoneTypeCdmaLte(); doReturn(CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM).when(mCdmaSSM) .getCdmaSubscriptionSource(); logd("Calling updatePhoneType"); // switch to CDMA sst.updatePhoneType(); // trigger RUIM_RECORDS_LOADED ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class); verify(mRuimRecords).registerForRecordsLoaded(eq(sst), integerArgumentCaptor.capture(), nullable(Object.class)); // response for mRuimRecords.registerForRecordsLoaded() Message msg = Message.obtain(); msg.what = integerArgumentCaptor.getValue(); msg.obj = new AsyncResult(null, null, null); sst.sendMessage(msg); // wait for RUIM_RECORDS_LOADED to be handled waitForHandlerAction(sst, 5000); // mdn should be null as nothing populated it assertEquals(null, sst.getMdnNumber()); // if ruim is provisioned, mdn should still be null doReturn(true).when(mRuimRecords).isProvisioned(); assertEquals(null, sst.getMdnNumber()); // if ruim is not provisioned, and mdn is non null, sst should still return null doReturn(false).when(mRuimRecords).isProvisioned(); String mockMdn = "mockMdn"; doReturn(mockMdn).when(mRuimRecords).getMdn(); assertEquals(null, sst.getMdnNumber()); // if ruim is provisioned, and mdn is non null, sst should also return the correct value doReturn(true).when(mRuimRecords).isProvisioned(); assertEquals(mockMdn, sst.getMdnNumber()); } }