/** * Returns the neighboring cell information of the device. The getAllCellInfo is preferred and use * this only if getAllCellInfo return nulls or an empty list. * * <p>In the future this call will be deprecated. * * <p> * * @return List of NeighboringCellInfo or null if info unavailable. * <p>Requires Permission: (@link android.Manifest.permission#ACCESS_COARSE_UPDATES} */ public List<NeighboringCellInfo> getNeighboringCellInfo() { try { return getITelephony().getNeighboringCellInfo(mContext.getOpPackageName()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { return null; } }
private void initializeCarrierApps() { // Initialize carrier apps: // -Now (on system startup) // -Whenever new carrier privilege rules might change (new SIM is loaded) // -Whenever we switch to a new user mCurrentlyActiveUserId = 0; try { ActivityManagerNative.getDefault() .registerUserSwitchObserver( new IUserSwitchObserver.Stub() { @Override public void onUserSwitching(int newUserId, IRemoteCallback reply) throws RemoteException { mCurrentlyActiveUserId = newUserId; CarrierAppUtils.disableCarrierAppsUntilPrivileged( mContext.getOpPackageName(), mPackageManager, TelephonyManager.getDefault(), mCurrentlyActiveUserId); if (reply != null) { try { reply.sendResult(null); } catch (RemoteException e) { } } } @Override public void onUserSwitchComplete(int newUserId) { // Ignore. } @Override public void onForegroundProfileSwitch(int newProfileId) throws RemoteException { // Ignore. } }); mCurrentlyActiveUserId = ActivityManagerNative.getDefault().getCurrentUser().id; } catch (RemoteException e) { logd("Couldn't get current user ID; guessing it's 0: " + e.getMessage()); } CarrierAppUtils.disableCarrierAppsUntilPrivileged( mContext.getOpPackageName(), mPackageManager, TelephonyManager.getDefault(), mCurrentlyActiveUserId); }
/** * This function is called repeatedly after each asynchronous operation until all preconditions * for the connection have been satisfied and the connection is established (or not). */ private void updateConnection() { // Step 0. Stop scans if necessary to prevent interference while connected. // Resume scans later when no longer attempting to connect. updateScanState(); // Step 1. Before we try to connect to a new device, tell the system we // have disconnected from the old one. if ((mRemoteDisplay != null || mExtRemoteDisplay != null) && mConnectedDevice != mDesiredDevice) { Slog.i( TAG, "Stopped listening for RTSP connection on " + mRemoteDisplayInterface + " from Wifi display: " + mConnectedDevice.deviceName); if (mRemoteDisplay != null) { mRemoteDisplay.dispose(); } else if (mExtRemoteDisplay != null) { ExtendedRemoteDisplayHelper.dispose(mExtRemoteDisplay); } mExtRemoteDisplay = null; mRemoteDisplay = null; mRemoteDisplayInterface = null; mRemoteDisplayConnected = false; mHandler.removeCallbacks(mRtspTimeout); mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_DISABLED); unadvertiseDisplay(); // continue to next step } // Step 2. Before we try to connect to a new device, disconnect from the old one. if (mDisconnectingDevice != null) { return; // wait for asynchronous callback } if (mConnectedDevice != null && mConnectedDevice != mDesiredDevice) { Slog.i(TAG, "Disconnecting from Wifi display: " + mConnectedDevice.deviceName); mDisconnectingDevice = mConnectedDevice; mConnectedDevice = null; mConnectedDeviceGroupInfo = null; unadvertiseDisplay(); final WifiP2pDevice oldDevice = mDisconnectingDevice; mWifiP2pManager.removeGroup( mWifiP2pChannel, new ActionListener() { @Override public void onSuccess() { Slog.i(TAG, "Disconnected from Wifi display: " + oldDevice.deviceName); next(); } @Override public void onFailure(int reason) { Slog.i( TAG, "Failed to disconnect from Wifi display: " + oldDevice.deviceName + ", reason=" + reason); next(); } private void next() { if (mDisconnectingDevice == oldDevice) { mDisconnectingDevice = null; updateConnection(); } } }); return; // wait for asynchronous callback } // Step 3. Before we try to connect to a new device, stop trying to connect // to the old one. if (mCancelingDevice != null) { return; // wait for asynchronous callback } if (mConnectingDevice != null && mConnectingDevice != mDesiredDevice) { Slog.i(TAG, "Canceling connection to Wifi display: " + mConnectingDevice.deviceName); mCancelingDevice = mConnectingDevice; mConnectingDevice = null; unadvertiseDisplay(); mHandler.removeCallbacks(mConnectionTimeout); final WifiP2pDevice oldDevice = mCancelingDevice; mWifiP2pManager.cancelConnect( mWifiP2pChannel, new ActionListener() { @Override public void onSuccess() { Slog.i(TAG, "Canceled connection to Wifi display: " + oldDevice.deviceName); next(); } @Override public void onFailure(int reason) { Slog.i( TAG, "Failed to cancel connection to Wifi display: " + oldDevice.deviceName + ", reason=" + reason); next(); } private void next() { if (mCancelingDevice == oldDevice) { mCancelingDevice = null; updateConnection(); } } }); return; // wait for asynchronous callback } // Step 4. If we wanted to disconnect, or we're updating after starting an // autonomous GO, then mission accomplished. if (mDesiredDevice == null) { if (mWifiDisplayCertMode) { mListener.onDisplaySessionInfo(getSessionInfo(mConnectedDeviceGroupInfo, 0)); } unadvertiseDisplay(); return; // done } // Step 5. Try to connect. if (mConnectedDevice == null && mConnectingDevice == null) { Slog.i(TAG, "Connecting to Wifi display: " + mDesiredDevice.deviceName); mConnectingDevice = mDesiredDevice; WifiP2pConfig config = new WifiP2pConfig(); WpsInfo wps = new WpsInfo(); if (mWifiDisplayWpsConfig != WpsInfo.INVALID) { wps.setup = mWifiDisplayWpsConfig; } else if (mConnectingDevice.wpsPbcSupported()) { wps.setup = WpsInfo.PBC; } else if (mConnectingDevice.wpsDisplaySupported()) { // We do keypad if peer does display wps.setup = WpsInfo.KEYPAD; } else { wps.setup = WpsInfo.DISPLAY; } config.wps = wps; config.deviceAddress = mConnectingDevice.deviceAddress; // Helps with STA & P2P concurrency config.groupOwnerIntent = WifiP2pConfig.MIN_GROUP_OWNER_INTENT; WifiDisplay display = createWifiDisplay(mConnectingDevice); advertiseDisplay(display, null, 0, 0, 0); final WifiP2pDevice newDevice = mDesiredDevice; mWifiP2pManager.connect( mWifiP2pChannel, config, new ActionListener() { @Override public void onSuccess() { // The connection may not yet be established. We still need to wait // for WIFI_P2P_CONNECTION_CHANGED_ACTION. However, we might never // get that broadcast, so we register a timeout. Slog.i(TAG, "Initiated connection to Wifi display: " + newDevice.deviceName); mHandler.postDelayed(mConnectionTimeout, CONNECTION_TIMEOUT_SECONDS * 1000); } @Override public void onFailure(int reason) { if (mConnectingDevice == newDevice) { Slog.i( TAG, "Failed to initiate connection to Wifi display: " + newDevice.deviceName + ", reason=" + reason); mConnectingDevice = null; handleConnectionFailure(false); } } }); return; // wait for asynchronous callback } // Step 6. Listen for incoming RTSP connection. if (mConnectedDevice != null && mRemoteDisplay == null && mExtRemoteDisplay == null) { Inet4Address addr = getInterfaceAddress(mConnectedDeviceGroupInfo); if (addr == null) { Slog.i( TAG, "Failed to get local interface address for communicating " + "with Wifi display: " + mConnectedDevice.deviceName); handleConnectionFailure(false); return; // done } mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE); final WifiP2pDevice oldDevice = mConnectedDevice; final int port = getPortNumber(mConnectedDevice); final String iface = addr.getHostAddress() + ":" + port; mRemoteDisplayInterface = iface; Slog.i( TAG, "Listening for RTSP connection on " + iface + " from Wifi display: " + mConnectedDevice.deviceName); RemoteDisplay.Listener listener = new RemoteDisplay.Listener() { @Override public void onDisplayConnected( Surface surface, int width, int height, int flags, int session) { if (mConnectedDevice == oldDevice && !mRemoteDisplayConnected) { Slog.i( TAG, "Opened RTSP connection with Wifi display: " + mConnectedDevice.deviceName); mRemoteDisplayConnected = true; mHandler.removeCallbacks(mRtspTimeout); if (mWifiDisplayCertMode) { mListener.onDisplaySessionInfo( getSessionInfo(mConnectedDeviceGroupInfo, session)); } final WifiDisplay display = createWifiDisplay(mConnectedDevice); advertiseDisplay(display, surface, width, height, flags); } } @Override public void onDisplayDisconnected() { if (mConnectedDevice == oldDevice) { Slog.i( TAG, "Closed RTSP connection with Wifi display: " + mConnectedDevice.deviceName); mHandler.removeCallbacks(mRtspTimeout); disconnect(); } } @Override public void onDisplayError(int error) { if (mConnectedDevice == oldDevice) { Slog.i( TAG, "Lost RTSP connection with Wifi display due to error " + error + ": " + mConnectedDevice.deviceName); mHandler.removeCallbacks(mRtspTimeout); handleConnectionFailure(false); } } }; if (ExtendedRemoteDisplayHelper.isAvailable()) { mExtRemoteDisplay = ExtendedRemoteDisplayHelper.listen(iface, listener, mHandler, mContext); } else { mRemoteDisplay = RemoteDisplay.listen(iface, listener, mHandler, mContext.getOpPackageName()); } // Use extended timeout value for certification, as some tests require user inputs int rtspTimeout = mWifiDisplayCertMode ? RTSP_TIMEOUT_SECONDS_CERT_MODE : RTSP_TIMEOUT_SECONDS; mHandler.postDelayed(mRtspTimeout, rtspTimeout * 1000); } }
/** * TODO: Simplify more, as no one is interested in what happened only what the current list * contains. */ private synchronized void updateSubscriptionInfoByIccId() { logd("updateSubscriptionInfoByIccId:+ Start"); mSubscriptionManager.clearSubscriptionInfo(); for (int i = 0; i < PROJECT_SIM_NUM; i++) { mInsertSimState[i] = SIM_NOT_CHANGE; } int insertedSimCount = PROJECT_SIM_NUM; for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (ICCID_STRING_FOR_NO_SIM.equals(mIccId[i])) { insertedSimCount--; mInsertSimState[i] = SIM_NOT_INSERT; } } logd("insertedSimCount = " + insertedSimCount); int index = 0; for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (mInsertSimState[i] == SIM_NOT_INSERT) { continue; } index = 2; for (int j = i + 1; j < PROJECT_SIM_NUM; j++) { if (mInsertSimState[j] == SIM_NOT_CHANGE && mIccId[i].equals(mIccId[j])) { mInsertSimState[i] = 1; mInsertSimState[j] = index; index++; } } } ContentResolver contentResolver = mContext.getContentResolver(); String[] oldIccId = new String[PROJECT_SIM_NUM]; for (int i = 0; i < PROJECT_SIM_NUM; i++) { oldIccId[i] = null; List<SubscriptionInfo> oldSubInfo = SubscriptionController.getInstance() .getSubInfoUsingSlotIdWithCheck(i, false, mContext.getOpPackageName()); if (oldSubInfo != null) { oldIccId[i] = oldSubInfo.get(0).getIccId(); logd("updateSubscriptionInfoByIccId: oldSubId = " + oldSubInfo.get(0).getSubscriptionId()); if (mInsertSimState[i] == SIM_NOT_CHANGE && !mIccId[i].equals(oldIccId[i])) { mInsertSimState[i] = SIM_CHANGED; } if (mInsertSimState[i] != SIM_NOT_CHANGE) { ContentValues value = new ContentValues(1); value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX); contentResolver.update( SubscriptionManager.CONTENT_URI, value, SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + Integer.toString(oldSubInfo.get(0).getSubscriptionId()), null); } } else { if (mInsertSimState[i] == SIM_NOT_CHANGE) { // no SIM inserted last time, but there is one SIM inserted now mInsertSimState[i] = SIM_CHANGED; } oldIccId[i] = ICCID_STRING_FOR_NO_SIM; logd("updateSubscriptionInfoByIccId: No SIM in slot " + i + " last time"); } } for (int i = 0; i < PROJECT_SIM_NUM; i++) { logd( "updateSubscriptionInfoByIccId: oldIccId[" + i + "] = " + oldIccId[i] + ", sIccId[" + i + "] = " + mIccId[i]); } // check if the inserted SIM is new SIM int nNewCardCount = 0; int nNewSimStatus = 0; for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (mInsertSimState[i] == SIM_NOT_INSERT) { logd("updateSubscriptionInfoByIccId: No SIM inserted in slot " + i + " this time"); } else { if (mInsertSimState[i] > 0) { // some special SIMs may have the same IccIds, add suffix to distinguish them // FIXME: addSubInfoRecord can return an error. mSubscriptionManager.addSubscriptionInfoRecord( mIccId[i] + Integer.toString(mInsertSimState[i]), i); logd("SUB" + (i + 1) + " has invalid IccId"); } else /*if (sInsertSimState[i] != SIM_NOT_INSERT)*/ { mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i], i); } if (isNewSim(mIccId[i], oldIccId)) { nNewCardCount++; switch (i) { case PhoneConstants.SUB1: nNewSimStatus |= STATUS_SIM1_INSERTED; break; case PhoneConstants.SUB2: nNewSimStatus |= STATUS_SIM2_INSERTED; break; case PhoneConstants.SUB3: nNewSimStatus |= STATUS_SIM3_INSERTED; break; // case PhoneConstants.SUB3: // nNewSimStatus |= STATUS_SIM4_INSERTED; // break; } mInsertSimState[i] = SIM_NEW; } } } for (int i = 0; i < PROJECT_SIM_NUM; i++) { if (mInsertSimState[i] == SIM_CHANGED) { mInsertSimState[i] = SIM_REPOSITION; } logd("updateSubscriptionInfoByIccId: sInsertSimState[" + i + "] = " + mInsertSimState[i]); } List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList(); int nSubCount = (subInfos == null) ? 0 : subInfos.size(); logd("updateSubscriptionInfoByIccId: nSubCount = " + nSubCount); for (int i = 0; i < nSubCount; i++) { SubscriptionInfo temp = subInfos.get(i); String msisdn = TelephonyManager.getDefault().getLine1NumberForSubscriber(temp.getSubscriptionId()); if (msisdn != null) { ContentValues value = new ContentValues(1); value.put(SubscriptionManager.NUMBER, msisdn); contentResolver.update( SubscriptionManager.CONTENT_URI, value, SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + Integer.toString(temp.getSubscriptionId()), null); } } // Ensure the modems are mapped correctly mSubscriptionManager.setDefaultDataSubId(mSubscriptionManager.getDefaultDataSubId()); SubscriptionController.getInstance().notifySubscriptionInfoChanged(); logd("updateSubscriptionInfoByIccId:- SsubscriptionInfo update complete"); }
private void handleSimLoaded(int slotId) { logd("handleSimStateLoadedInternal: slotId: " + slotId); // The SIM should be loaded at this state, but it is possible in cases such as SIM being // removed or a refresh RESET that the IccRecords could be null. The right behavior is to // not broadcast the SIM loaded. IccRecords records = mPhone[slotId].getIccCard().getIccRecords(); if (records == null) { // Possibly a race condition. logd("onRecieve: IccRecords null"); return; } if (records.getIccId() == null) { logd("onRecieve: IccID null"); return; } mIccId[slotId] = records.getIccId(); if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(); } int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; int[] subIds = SubscriptionController.getInstance().getSubId(slotId); if (subIds != null) { // Why an array? subId = subIds[0]; } if (SubscriptionManager.isValidSubscriptionId(subId)) { String operator = records.getOperatorNumeric(); if (operator != null) { if (subId == SubscriptionController.getInstance().getDefaultSubId()) { MccTable.updateMccMncConfiguration(mContext, operator, false); } SubscriptionController.getInstance().setMccMnc(operator, subId); } else { logd("EVENT_RECORDS_LOADED Operator name is null"); } TelephonyManager tm = TelephonyManager.getDefault(); String msisdn = tm.getLine1NumberForSubscriber(subId); ContentResolver contentResolver = mContext.getContentResolver(); if (msisdn != null) { ContentValues number = new ContentValues(1); number.put(SubscriptionManager.NUMBER, msisdn); contentResolver.update( SubscriptionManager.CONTENT_URI, number, SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + Long.toString(subId), null); } SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId); String nameToSet; String simCarrierName = tm.getSimOperatorNameForSubscription(subId); ContentValues name = new ContentValues(1); if (subInfo != null && subInfo.getNameSource() != SubscriptionManager.NAME_SOURCE_USER_INPUT) { if (!TextUtils.isEmpty(simCarrierName)) { nameToSet = simCarrierName; } else { nameToSet = "CARD " + Integer.toString(slotId + 1); } name.put(SubscriptionManager.DISPLAY_NAME, nameToSet); logd("sim name = " + nameToSet); contentResolver.update( SubscriptionManager.CONTENT_URI, name, SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + Long.toString(subId), null); } /* Update preferred network type and network selection mode on SIM change. * Storing last subId in SharedPreference for now to detect SIM change. */ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); int storedSubId = sp.getInt(CURR_SUBID + slotId, -1); if (storedSubId != subId) { int networkType = RILConstants.PREFERRED_NETWORK_MODE; // Set the modem network mode mPhone[slotId].setPreferredNetworkType(networkType, null); Settings.Global.putInt( mPhone[slotId].getContext().getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType); // Only support automatic selection mode on SIM change. mPhone[slotId].getNetworkSelectionMode( obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, new Integer(slotId))); // Update stored subId SharedPreferences.Editor editor = sp.edit(); editor.putInt(CURR_SUBID + slotId, subId); editor.apply(); } } else { logd("Invalid subId, could not update ContentResolver"); } // Update set of enabled carrier apps now that the privilege rules may have changed. CarrierAppUtils.disableCarrierAppsUntilPrivileged( mContext.getOpPackageName(), mPackageManager, TelephonyManager.getDefault(), mCurrentlyActiveUserId); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOADED, null); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_LOADED); }