Skip to content

Commit

Permalink
Optionally use the new getAllCellInfo API (mozilla#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
illarionov committed Jan 26, 2014
1 parent b9cd4c2 commit 03b610a
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 21 deletions.
48 changes: 48 additions & 0 deletions src/org/mozilla/mozstumbler/cellscanner/CellInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,54 @@ void setNeighboringCellInfo(NeighboringCellInfo nci, String networkOperator) {
if (rssi != NeighboringCellInfo.UNKNOWN_RSSI) mAsu = rssi;
}

void setGsmCellInfo(int mcc, int mnc, int lac, int cid, int asu) {
mCellRadio = CELL_RADIO_GSM;
mMcc = mcc != Integer.MAX_VALUE ? mcc : UNKNOWN_CID;
mMnc = mnc != Integer.MAX_VALUE ? mnc : UNKNOWN_CID;
mLac = lac != Integer.MAX_VALUE ? lac : UNKNOWN_CID;
mCid = cid != Integer.MAX_VALUE ? cid : UNKNOWN_CID;
mAsu = asu;
}

void setWcmdaCellInfo(int mcc, int mnc, int lac, int cid, int psc, int asu) {
mCellRadio = CELL_RADIO_UMTS;
mMcc = mcc != Integer.MAX_VALUE ? mcc : UNKNOWN_CID;
mMnc = mnc != Integer.MAX_VALUE ? mnc : UNKNOWN_CID;
mLac = lac != Integer.MAX_VALUE ? lac : UNKNOWN_CID;
mCid = cid != Integer.MAX_VALUE ? cid : UNKNOWN_CID;
mPsc = psc != Integer.MAX_VALUE ? psc : UNKNOWN_CID;
mAsu = asu;
}

/**
*
* @param mcc Mobile Country Code, Integer.MAX_VALUE if unknown
* @param mnc Mobile Network Code, Integer.MAX_VALUE if unknown
* @param ci Cell Identity, Integer.MAX_VALUE if unknown
* @param pci Physical Cell Id, Integer.MAX_VALUE if unknown
* @param tac Tracking Area Code, Integer.MAX_VALUE if unknown
* @param asu Arbitrary strength unit
* @param ta Timing advance
*/
void setLteCellInfo(int mcc, int mnc, int ci, int pci, int tac, int asu, int ta) {
mCellRadio = CELL_RADIO_LTE;
mMcc = mcc != Integer.MAX_VALUE ? mcc : UNKNOWN_CID;
mMnc = mnc != Integer.MAX_VALUE ? mnc : UNKNOWN_CID;
mLac = tac != Integer.MAX_VALUE ? tac : UNKNOWN_CID;
mCid = ci != Integer.MAX_VALUE ? ci : UNKNOWN_CID;
mPsc = pci != Integer.MAX_VALUE ? pci : UNKNOWN_CID;
mAsu = asu;
mTa = ta;
}

void setCdmaCellInfo(int baseStationId, int networkId, int systemId, int dbm) {
mCellRadio = CELL_RADIO_CDMA;
mMnc = systemId != Integer.MAX_VALUE ? systemId : UNKNOWN_CID;
mLac = networkId != Integer.MAX_VALUE ? networkId : UNKNOWN_CID;
mCid = baseStationId != Integer.MAX_VALUE ? baseStationId : UNKNOWN_CID;
mSignal = dbm;
}

void setNetworkOperator(String mccMnc) {
if (mccMnc == null || mccMnc.length() < 5 || mccMnc.length() > 8) {
throw new IllegalArgumentException("Bad mccMnc: " + mccMnc);
Expand Down
172 changes: 151 additions & 21 deletions src/org/mozilla/mozstumbler/cellscanner/DefaultCellScanner.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
package org.mozilla.mozstumbler.cellscanner;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.CellLocation;
import android.telephony.CellSignalStrengthCdma;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.CellSignalStrengthLte;
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.NeighboringCellInfo;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
Expand All @@ -17,13 +31,27 @@ public class DefaultCellScanner implements CellScanner.CellScannerImpl {

private static final String LOGTAG = DefaultCellScanner.class.getName();

private static final GetAllCellInfoScannerImpl sGetAllInfoCellScanner;

private final TelephonyManager mTelephonyManager;

private final int mPhoneType;

private volatile int mSignalStrength;
private volatile int mCdmaDbm;

interface GetAllCellInfoScannerImpl {
List<CellInfo> getAllCellInfo(TelephonyManager tm);
}

static {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
sGetAllInfoCellScanner = new GetAllCellInfoScannerMr2();
}else {
sGetAllInfoCellScanner = new GetAllCellInfoScannerDummy();
}
}

DefaultCellScanner(Context context) {
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephonyManager == null) {
Expand Down Expand Up @@ -56,42 +84,71 @@ public void stop() {

@Override
public List<CellInfo> getCellInfo() {
String networkOperator;
final CellLocation cl = mTelephonyManager.getCellLocation();
if (cl == null) {
return Collections.emptyList();
List<CellInfo> records = new ArrayList<CellInfo>();

List<CellInfo> allCells = sGetAllInfoCellScanner.getAllCellInfo(mTelephonyManager);
if (allCells.isEmpty()) {
CellInfo currentCell = getCurrentCellInfo();
if (currentCell == null) {
return records;
}
records.add(currentCell);
}else {
records.addAll(allCells);
}
Collection<NeighboringCellInfo> cells = mTelephonyManager.getNeighboringCellInfo();

networkOperator = mTelephonyManager.getNetworkOperator();
// getNeighboringCells() sometimes contains more information than that is already
// in getAllCellInfo(). Use the results of both of them.
records.addAll(getNeighboringCells());
return records;
}

private String getNetworkOperator() {
String networkOperator = mTelephonyManager.getNetworkOperator();
// getNetworkOperator() may be unreliable on CDMA networks
if (networkOperator == null || networkOperator.length() <= 3) {
networkOperator = mTelephonyManager.getSimOperator();
}
final List<CellInfo> records = new ArrayList<CellInfo>(1 + (cells == null ? 0 : cells.size()));
final CellInfo info = new CellInfo(mPhoneType);
return networkOperator;
}

private CellInfo getCurrentCellInfo() {
final CellLocation currentCell;
currentCell = mTelephonyManager.getCellLocation();
if (currentCell == null) {
return null;
}
try {
final CellInfo info = new CellInfo(mPhoneType);
final int signalStrength = mSignalStrength;
final int cdmaDbm = mCdmaDbm;
info.setCellLocation(cl,
info.setCellLocation(currentCell,
mTelephonyManager.getNetworkType(),
networkOperator,
getNetworkOperator(),
signalStrength == CellInfo.UNKNOWN_SIGNAL ? null : signalStrength,
cdmaDbm == CellInfo.UNKNOWN_SIGNAL ? null : cdmaDbm);
records.add(info);
return info;
} catch (IllegalArgumentException iae) {
Log.e(LOGTAG, "Skip invalid or incomplete CellLocation: " + cl, iae);
Log.e(LOGTAG, "Skip invalid or incomplete CellLocation: " + currentCell, iae);
}
return null;
}

if (cells != null) {
for (NeighboringCellInfo nci : cells) {
try {
final CellInfo record = new CellInfo(mPhoneType);
record.setNeighboringCellInfo(nci, networkOperator);
records.add(record);
} catch (IllegalArgumentException iae) {
Log.e(LOGTAG, "Skip invalid or incomplete NeighboringCellInfo: " + nci, iae);
}
private List<CellInfo> getNeighboringCells() {
Collection<NeighboringCellInfo> cells = mTelephonyManager.getNeighboringCellInfo();
if (cells == null || cells.isEmpty()) {
return Collections.emptyList();
}

String networkOperator = getNetworkOperator();
List<CellInfo> records = new ArrayList<CellInfo>(cells.size());
for (NeighboringCellInfo nci : cells) {
try {
final CellInfo record = new CellInfo(mPhoneType);
record.setNeighboringCellInfo(nci, networkOperator);
records.add(record);
} catch (IllegalArgumentException iae) {
Log.e(LOGTAG, "Skip invalid or incomplete NeighboringCellInfo: " + nci, iae);
}
}
return records;
Expand All @@ -107,4 +164,77 @@ public void onSignalStrengthsChanged(SignalStrength ss) {
}
}
};

private static class GetAllCellInfoScannerDummy implements GetAllCellInfoScannerImpl {
@Override
public List<CellInfo> getAllCellInfo(TelephonyManager tm) {
return Collections.emptyList();
}
}

@TargetApi(18)
private static class GetAllCellInfoScannerMr2 implements GetAllCellInfoScannerImpl {
@Override
public List<CellInfo> getAllCellInfo(TelephonyManager tm) {
final List<android.telephony.CellInfo> observed = tm.getAllCellInfo();
if (observed == null || observed.isEmpty()) {
return Collections.emptyList();
}

List<CellInfo> cells = new ArrayList<CellInfo>(observed.size());
for (android.telephony.CellInfo observedCell : observed) {
if (observedCell instanceof CellInfoGsm) {
CellIdentityGsm ident = ((CellInfoGsm) observedCell).getCellIdentity();
if (ident.getMcc() != Integer.MAX_VALUE && ident.getMnc() != Integer.MAX_VALUE) {
CellSignalStrengthGsm strength = ((CellInfoGsm) observedCell).getCellSignalStrength();
CellInfo cell = new CellInfo(tm.getPhoneType());
cell.setGsmCellInfo(ident.getMcc(),
ident.getMnc(),
ident.getLac(),
ident.getCid(),
strength.getAsuLevel());
cells.add(cell);
}
} else if (observedCell instanceof CellInfoCdma) {
CellInfo cell = new CellInfo(tm.getPhoneType());
CellIdentityCdma ident = ((CellInfoCdma) observedCell).getCellIdentity();
CellSignalStrengthCdma strength = ((CellInfoCdma) observedCell).getCellSignalStrength();
cell.setCdmaCellInfo(ident.getBasestationId(),
ident.getNetworkId(),
ident.getSystemId(),
strength.getDbm());
cells.add(cell);
} else if (observedCell instanceof CellInfoLte) {
CellIdentityLte ident = ((CellInfoLte) observedCell).getCellIdentity();
if (ident.getMnc() != Integer.MAX_VALUE && ident.getMnc() != Integer.MAX_VALUE) {
CellInfo cell = new CellInfo(tm.getPhoneType());
CellSignalStrengthLte strength = ((CellInfoLte) observedCell).getCellSignalStrength();
cell.setLteCellInfo(ident.getMcc(),
ident.getMnc(),
ident.getCi(),
ident.getPci(),
ident.getTac(),
strength.getAsuLevel(),
strength.getTimingAdvance());
}
} else if (observedCell instanceof CellInfoWcdma) {
CellIdentityWcdma ident = ((CellInfoWcdma) observedCell).getCellIdentity();
if (ident.getMnc() != Integer.MAX_VALUE && ident.getMnc() != Integer.MAX_VALUE) {
CellInfo cell = new CellInfo(tm.getPhoneType());
CellSignalStrengthWcdma strength = ((CellInfoWcdma) observedCell).getCellSignalStrength();
cell.setWcmdaCellInfo(ident.getMcc(),
ident.getMnc(),
ident.getLac(),
ident.getCid(),
ident.getPsc(),
strength.getAsuLevel());
cells.add(cell);
}
} else {
Log.i(LOGTAG, "Skipped CellInfo of unknown class: " + observedCell.toString());
}
}
return cells;
}
}
}

0 comments on commit 03b610a

Please sign in to comment.