/
PhoneToggler.java
executable file
·183 lines (156 loc) · 8.76 KB
/
PhoneToggler.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package com.android.phone;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
public class PhoneToggler extends BroadcastReceiver {
/** Used for brodcasting network data change and receive new mode **/
public static final String NETWORK_MODE_CHANGED="com.android.internal.telephony.NETWORK_MODE_CHANGED";
public static final String REQUEST_NETWORK_MODE="com.android.internal.telephony.REQUEST_NETWORK_MODE";
public static final String MODIFY_NETWORK_MODE="com.android.internal.telephony.MODIFY_NETWORK_MODE";
public static final String MOBILE_DATA_CHANGED="com.android.internal.telephony.MOBILE_DATA_CHANGED";
public static final String NETWORK_MODE = "networkMode";
public static final String CHANGE_NETWORK_MODE_PERM= "com.android.phone.CHANGE_NETWORK_MODE";
private static final String LOG_TAG = "PhoneToggler";
private static final boolean DBG = true;
private Phone mPhone;
private MyHandler mHandler;
private Phone getPhone() {
if (mPhone==null) mPhone = PhoneFactory.getDefaultPhone();
return mPhone;
}
private MyHandler getHandler() {
if (mHandler==null) mHandler = new MyHandler();
return mHandler;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MODIFY_NETWORK_MODE)) {
if (DBG) Log.d(LOG_TAG,"Got modify intent");
if (intent.getExtras()!=null) {
int networkMode = intent.getExtras().getInt(NETWORK_MODE);
boolean networkModeOk = false;
int phoneType = getPhone().getPhoneType();
boolean isLteOnCdma = getPhone().getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE;
if (phoneType == Phone.PHONE_TYPE_GSM) {
if (networkMode == Phone.NT_MODE_GSM_ONLY
|| networkMode == Phone.NT_MODE_GSM_UMTS
|| networkMode == Phone.NT_MODE_WCDMA_PREF
|| networkMode == Phone.NT_MODE_LTE_GSM_WCDMA
|| networkMode == Phone.NT_MODE_WCDMA_ONLY) {
networkModeOk = true;
}
} else if (phoneType == Phone.PHONE_TYPE_CDMA) {
if (networkMode == Phone.NT_MODE_CDMA
|| networkMode == Phone.NT_MODE_CDMA_NO_EVDO
|| networkMode == Phone.NT_MODE_EVDO_NO_CDMA) {
networkModeOk = true;
}
}
if (context.getResources().getBoolean(R.bool.world_phone) || isLteOnCdma) {
if (networkMode == Phone.NT_MODE_GLOBAL) {
networkModeOk = true;
}
}
if (networkModeOk) {
if (DBG) Log.d(LOG_TAG,"Will modify it to: "+networkMode);
changeNetworkMode(networkMode);
if (DBG) Log.d(LOG_TAG,"Accepted modification of network mode to : "+networkMode);
} else {
Log.e(LOG_TAG,"Not accepted network mode: "+networkMode);
}
}
} else if (intent.getAction().equals(REQUEST_NETWORK_MODE)) {
if (DBG) Log.d(LOG_TAG,"Sending Intent with current phone network mode");
triggerIntent();
} else {
Log.e(LOG_TAG,"Not accepted intent: "+intent.getAction());
}
}
private void changeNetworkMode(int modemNetworkMode) {
getPhone().setPreferredNetworkType(modemNetworkMode, getHandler()
.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
}
private void triggerIntent() {
getPhone().getPreferredNetworkType(getHandler()
.obtainMessage(MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
}
private class MyHandler extends Handler {
private static final int MESSAGE_GET_PREFERRED_NETWORK_TYPE = 0;
private static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 1;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_GET_PREFERRED_NETWORK_TYPE:
handleGetPreferredNetworkTypeResponse(msg);
break;
case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
handleSetPreferredNetworkTypeResponse(msg);
break;
}
}
private void handleGetPreferredNetworkTypeResponse(Message msg) {
AsyncResult ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
int modemNetworkMode = ((int[])ar.result)[0];
if (DBG) Log.d(LOG_TAG,"handleGetPreferredNetworkTypeResponse: modemNetworkMode = "+modemNetworkMode);
int settingsNetworkMode = android.provider.Settings.Secure.getInt(
getPhone().getContext().getContentResolver(),
android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
MobileNetworkSettings.preferredNetworkMode);
if (DBG) Log.d(LOG_TAG,"handleGetPreferredNetworkTypeReponse: settingsNetworkMode = "+settingsNetworkMode);
//check that modemNetworkMode is from an accepted value
if (modemNetworkMode == Phone.NT_MODE_WCDMA_PREF ||
modemNetworkMode == Phone.NT_MODE_GSM_ONLY ||
modemNetworkMode == Phone.NT_MODE_WCDMA_ONLY ||
modemNetworkMode == Phone.NT_MODE_GSM_UMTS ||
modemNetworkMode == Phone.NT_MODE_LTE_GSM_WCDMA ||
modemNetworkMode == Phone.NT_MODE_CDMA ||
modemNetworkMode == Phone.NT_MODE_CDMA_NO_EVDO ||
modemNetworkMode == Phone.NT_MODE_EVDO_NO_CDMA ||
//A modem might report world phone sometimes
//but it's not true. Double check here
(getPhone().getContext().getResources().getBoolean(R.bool.world_phone) == true &&
modemNetworkMode == Phone.NT_MODE_GLOBAL) ) {
if (DBG) Log.d(LOG_TAG,"handleGetPreferredNetworkTypeResponse: if 1: modemNetworkMode = "+modemNetworkMode);
//check changes in modemNetworkMode and updates settingsNetworkMode
if (modemNetworkMode != settingsNetworkMode) {
if (DBG) Log.d(LOG_TAG,"handleGetPreferredNetworkTypeResponse: if 2: modemNetworkMode != settingsNetworkMode");
settingsNetworkMode = modemNetworkMode;
if (DBG) Log.d(LOG_TAG,"handleGetPreferredNetworkTypeResponse: if 2: settingsNetworkMode = "+settingsNetworkMode);
//changes the Settings.System accordingly to modemNetworkMode
android.provider.Settings.Secure.putInt(
getPhone().getContext().getContentResolver(),
android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
settingsNetworkMode );
}
Intent intent = new Intent(NETWORK_MODE_CHANGED);
intent.putExtra(NETWORK_MODE, settingsNetworkMode);
getPhone().getContext().sendBroadcast(intent,CHANGE_NETWORK_MODE_PERM);
} else if (modemNetworkMode == Phone.NT_MODE_LTE_ONLY) {
if (DBG) Log.d(LOG_TAG,"handleGetPreferredNetworkTypeResponse: lte only: no action");
} else {
if (DBG) Log.d(LOG_TAG,"handleGetPreferredNetworkTypeResponse: else: reset to default");
resetNetworkModeToDefault();
}
}
}
private void handleSetPreferredNetworkTypeResponse(Message msg) {
//PSAFS - TODO: For now no status is stored, so we will always get the real status from Phone.
getPhone().getPreferredNetworkType(obtainMessage(MESSAGE_GET_PREFERRED_NETWORK_TYPE));
}
private void resetNetworkModeToDefault() {
android.provider.Settings.Secure.putInt(getPhone().getContext().getContentResolver(),
android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
MobileNetworkSettings.preferredNetworkMode );
//Set the Modem
getPhone().setPreferredNetworkType(MobileNetworkSettings.preferredNetworkMode,
this.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
}
}
}