Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: net/android/java/src/org/chromium/net/AndroidCellularSignalStrength.java

Issue 2763853002: Use Android callback API to obtain cellular signal strength (Closed)
Patch Set: pauljensen comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/android/cellular_signal_strength_unittest.cc ('k') | net/nqe/network_quality_estimator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.net; 5 package org.chromium.net;
6 6
7 import android.Manifest;
8 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
9 import android.content.Context; 8 import android.content.Context;
10 import android.content.pm.PackageManager;
11 import android.os.Build; 9 import android.os.Build;
12 import android.os.Process; 10 import android.telephony.PhoneStateListener;
13 import android.telephony.CellInfo; 11 import android.telephony.SignalStrength;
14 import android.telephony.CellInfoCdma;
15 import android.telephony.CellInfoGsm;
16 import android.telephony.CellInfoLte;
17 import android.telephony.CellInfoWcdma;
18 import android.telephony.TelephonyManager; 12 import android.telephony.TelephonyManager;
19 13
20 import org.chromium.base.ContextUtils; 14 import org.chromium.base.ContextUtils;
15 import org.chromium.base.ThreadUtils;
21 import org.chromium.base.annotations.CalledByNative; 16 import org.chromium.base.annotations.CalledByNative;
22 import org.chromium.base.annotations.JNINamespace; 17 import org.chromium.base.annotations.JNINamespace;
18 import org.chromium.base.annotations.SuppressFBWarnings;
23 19
24 import java.util.Iterator; 20 import javax.annotation.concurrent.GuardedBy;
25 import java.util.List;
26 21
27 /** 22 /**
28 * This class interacts with the CellInfo API provided by Android. This class is thread safe. 23 * This class provides the cellular signal strength using the APIs provided by A ndroid. This class
24 * is thread safe.
29 */ 25 */
30 @JNINamespace("net::android::cellular_signal_strength") 26 @JNINamespace("net::android")
31 public class AndroidCellularSignalStrength { 27 public class AndroidCellularSignalStrength {
28 private final Context mContext;
pauljensen 2017/06/08 18:07:33 Don't keep pointers to Context, just use ContextUt
tbansal1 2017/06/08 23:34:30 Done.
29
30 private final Object mLock = new Object();
31
32 @GuardedBy("mLock")
33 private int mSignalLevel = CellularSignalStrengthError.ERROR_NOT_SUPPORTED;
pauljensen 2017/06/08 18:07:33 I don't think this needs to be guarded by a lock.
tbansal1 2017/06/08 23:34:30 Done.
34
35 @SuppressFBWarnings("URF_UNREAD_FIELD")
36 private CellStateListener mCellStateListener;
37
32 /** 38 /**
33 * @return Signal strength (in dbM) for the currently registered cellular ne twork. Returns 39 * This class listens to the changes in the cellular signal strength level a nd updates {@link
34 * {@link CellularSignalStrengthError#ERROR_NOT_SUPPORTED} if the signal str ength is 40 * mSignalLevel}.
35 * unavailable or if there are multiple cellular radios on the device.
36 */ 41 */
37 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 42 private class CellStateListener extends PhoneStateListener {
43 CellStateListener() {
44 ThreadUtils.assertOnUiThread();
pauljensen 2017/06/08 18:07:33 Why does this need to be done on the UI thread?
tbansal1 2017/06/08 23:34:30 06-08 15:55:20.685 11863 11930 W System.err: java.
pauljensen 2017/06/13 11:53:43 I don't think it needs to be done on the UI thread
tbansal1 2017/06/20 15:50:53 It takes around 10 msec or so. I have moved it to
45
46 TelephonyManager telephonyManager =
47 (TelephonyManager) mContext.getSystemService(Context.TELEPHO NY_SERVICE);
48
49 if (telephonyManager.getSimState() != TelephonyManager.SIM_STATE_REA DY) return;
50
51 telephonyManager.listen(this, PhoneStateListener.LISTEN_SIGNAL_STREN GTHS);
52 }
53
54 @Override
55 @TargetApi(Build.VERSION_CODES.M)
56 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
57 synchronized (mLock) {
58 mSignalLevel = signalStrength.getLevel();
59 }
60 }
61 }
62
38 @CalledByNative 63 @CalledByNative
39 public static int getSignalStrengthDbm() { 64 private static AndroidCellularSignalStrength create() {
40 List<CellInfo> cellInfos = getRegisteredCellInfo(); 65 return new AndroidCellularSignalStrength();
41 return cellInfos == null || cellInfos.size() != 1 66 }
42 ? CellularSignalStrengthError.ERROR_NOT_SUPPORTED 67
43 : getSignalStrengthDbm(cellInfos.get(0)); 68 private AndroidCellularSignalStrength() {
69 mContext = ContextUtils.getApplicationContext();
70
71 if (!isAPIAvailable(mContext)) {
72 return;
73 }
74
75 ThreadUtils.runOnUiThread(new Runnable() {
76 @Override
77 public void run() {
78 mCellStateListener = new CellStateListener();
79 }
80 });
44 } 81 }
45 82
46 /** 83 /**
47 * @return the signal strength level (between 0 and 4, both inclusive) for t he currently 84 * @return the signal strength level (between 0 and 4, both inclusive) for t he currently
48 * registered cellular network with lower value indicating lower signal stre ngth. Returns 85 * registered cellular network with lower value indicating lower signal stre ngth. Returns
49 * {@link CellularSignalStrengthError#ERROR_NOT_SUPPORTED} if the signal str ength level is 86 * {@link CellularSignalStrengthError#ERROR_NOT_SUPPORTED} if the signal str ength level is
50 * unavailable or if there are multiple cellular radios on the device. 87 * unavailable.
51 */ 88 */
52 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 89 @TargetApi(Build.VERSION_CODES.M)
53 @CalledByNative 90 @CalledByNative
54 public static int getSignalStrengthLevel() { 91 public int getSignalStrengthLevel() {
55 List<CellInfo> cellInfos = getRegisteredCellInfo(); 92 synchronized (mLock) {
56 return cellInfos == null || cellInfos.size() != 1 93 return mSignalLevel;
57 ? CellularSignalStrengthError.ERROR_NOT_SUPPORTED 94 }
58 : getSignalStrengthLevel(cellInfos.get(0));
59 } 95 }
60 96
61 /** 97 /**
62 * Returns true if the API for quering the signal strength is available. 98 * Returns true if the API for quering the signal strength is available.
63 * {@link android.telephony#CellInfoWcdma} is only available on API Level 99 * {@link android.telephony.SignalStrength#getLevel} is only available on AP I Level
64 * {@link Build.VERSION_CODES#JELLY_BEAN_MR2} and higher. Also verifies that appropriate 100 * {@link Build.VERSION_CODES#M} and higher.
65 * permissions are already available. This ensures that on Android M and hig her, Chromium will
66 * not request run-time permission from the user when querying for cellular signal strength.
67 * TODO(tbansal): Consider using {@link TelephonyManager#getNeighboringCellI nfo}
68 * for earlier versions of Android.
69 */
70 private static boolean isAPIAvailable() {
71 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return f alse;
72
73 try {
74 return ContextUtils.getApplicationContext().checkPermission(
75 Manifest.permission.ACCESS_COARSE_LOCATION, Process.m yPid(),
76 Process.myUid())
77 == PackageManager.PERMISSION_GRANTED;
78 } catch (Exception ignored) {
79 // Work around certain platforms where this method sometimes throws a runtime exception.
80 // See crbug.com/663360.
81 }
82 return false;
83 }
84
85 /**
86 * Returns all observed cell information from all radios on the device inclu ding the primary
87 * and neighboring cells. Returns only the information of cells that are reg istered to a
88 * mobile network. May return {@code null}.
89 */ 101 */
90 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 102 private static boolean isAPIAvailable(Context context) {
91 private static List<CellInfo> getRegisteredCellInfo() { 103 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
pauljensen 2017/06/08 18:07:33 Are you aware that M+ is only ~40% of users: https
tbansal1 2017/06/08 23:34:30 Yes. I think this is probably the best option for
92 if (!isAPIAvailable()) {
93 return null;
94 }
95
96 TelephonyManager telephonyManager =
97 (TelephonyManager) ContextUtils.getApplicationContext().getSyste mService(
98 Context.TELEPHONY_SERVICE);
99 if (telephonyManager == null) {
100 return null;
101 }
102
103 List<CellInfo> cellInfos = telephonyManager.getAllCellInfo();
104 if (cellInfos == null) {
105 return null;
106 }
107
108 Iterator<CellInfo> iter = cellInfos.iterator();
109 while (iter.hasNext()) {
110 if (!iter.next().isRegistered()) {
111 iter.remove();
112 }
113 }
114 return cellInfos;
115 }
116
117 /**
118 * @return Signal strength (in dbM) from {@link cellInfo}. Returns {@link
119 * CellularSignalStrengthError#ERROR_NOT_SUPPORTED} if the signal strength i s unavailable.
120 */
121 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
122 private static int getSignalStrengthDbm(CellInfo cellInfo) {
123 if (cellInfo instanceof CellInfoCdma) {
124 return ((CellInfoCdma) cellInfo).getCellSignalStrength().getDbm();
125 }
126 if (cellInfo instanceof CellInfoGsm) {
127 return ((CellInfoGsm) cellInfo).getCellSignalStrength().getDbm();
128 }
129 if (cellInfo instanceof CellInfoLte) {
130 return ((CellInfoLte) cellInfo).getCellSignalStrength().getDbm();
131 }
132 if (cellInfo instanceof CellInfoWcdma) {
133 return ((CellInfoWcdma) cellInfo).getCellSignalStrength().getDbm();
134 }
135 return CellularSignalStrengthError.ERROR_NOT_SUPPORTED;
136 }
137
138 /**
139 * @return the signal level from {@link cellInfo}. Returns {@link
140 * CellularSignalStrengthError#ERROR_NOT_SUPPORTED} if the signal
141 * level is unavailable with lower value indicating lower signal strength.
142 */
143 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
144 private static int getSignalStrengthLevel(CellInfo cellInfo) {
145 if (cellInfo instanceof CellInfoCdma) {
146 return ((CellInfoCdma) cellInfo).getCellSignalStrength().getLevel();
147 }
148 if (cellInfo instanceof CellInfoGsm) {
149 return ((CellInfoGsm) cellInfo).getCellSignalStrength().getLevel();
150 }
151 if (cellInfo instanceof CellInfoLte) {
152 return ((CellInfoLte) cellInfo).getCellSignalStrength().getLevel();
153 }
154 if (cellInfo instanceof CellInfoWcdma) {
155 return ((CellInfoWcdma) cellInfo).getCellSignalStrength().getLevel() ;
156 }
157 return CellularSignalStrengthError.ERROR_NOT_SUPPORTED;
158 } 104 }
159 } 105 }
OLDNEW
« no previous file with comments | « net/android/cellular_signal_strength_unittest.cc ('k') | net/nqe/network_quality_estimator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698