Refactor PhoneFacade.
Separate listeners from PhoneFacade.
Add TelecommManager support to sl4a.
Bug and formatting fixes.
The listeners actually work now.
Change-Id: Ib18064d8282a7a52866937b297dc7cfa51b90531
diff --git a/Common/src/com/googlecode/android_scripting/facade/PhoneFacade.java b/Common/src/com/googlecode/android_scripting/facade/tele/PhoneFacade.java
similarity index 63%
rename from Common/src/com/googlecode/android_scripting/facade/PhoneFacade.java
rename to Common/src/com/googlecode/android_scripting/facade/tele/PhoneFacade.java
index 91394ad..ff4c1db 100755
--- a/Common/src/com/googlecode/android_scripting/facade/PhoneFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/tele/PhoneFacade.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.googlecode.android_scripting.facade;
+package com.googlecode.android_scripting.facade.tele;
import android.app.Service;
import android.content.ContentResolver;
@@ -22,29 +22,35 @@
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Bundle;
+import android.os.RemoteException;
import android.provider.ContactsContract;
import android.telephony.CellLocation;
import android.telephony.NeighboringCellInfo;
import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
-import android.telephony.PreciseCallState;
-import android.net.ConnectivityManager;
import android.provider.Telephony;
-import android.telephony.DataConnectionRealTimeInfo;
+import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.TelephonyProperties;
import android.content.ContentValues;
import android.os.SystemProperties;
-import com.googlecode.android_scripting.MainThread;
+import com.googlecode.android_scripting.facade.AndroidFacade;
+import com.googlecode.android_scripting.facade.EventFacade;
+import com.googlecode.android_scripting.facade.FacadeManager;
+import com.googlecode.android_scripting.facade.tele.TelephonyStateListeners
+ .CallStateChangeListener;
+import com.googlecode.android_scripting.facade.tele.TelephonyStateListeners
+ .DataConnectionChangeListener;
+import com.googlecode.android_scripting.facade.tele.TelephonyStateListeners
+ .ServiceStateChangeListener;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcDefault;
import com.googlecode.android_scripting.rpc.RpcParameter;
import com.googlecode.android_scripting.Log;
+import com.googlecode.android_scripting.MainThread;
import com.googlecode.android_scripting.rpc.RpcOptional;
import java.io.UnsupportedEncodingException;
@@ -61,21 +67,17 @@
*/
public class PhoneFacade extends RpcReceiver {
+ private final Service mService;
private final AndroidFacade mAndroidFacade;
private final EventFacade mEventFacade;
private final TelephonyManager mTelephonyManager;
- private final Bundle mPhoneState;
- private final Service mService;
- private final Bundle mServiceState;
- private PhoneStateListener mPhoneStateListener;
- private final ConnectivityManager mConnect;
- private final Bundle mModemPowerLevel;
- private final Bundle mPreciseCallState;
- private final int POWER_STATE_LOW = 1;
- private final int POWER_STATE_MEDIUM = 2;
- private final int POWER_STATE_HIGH = 3;
- private final int POWER_STATE_UNKNOWN = Integer.MAX_VALUE;
+ private CallStateChangeListener mCallStateChangeListener;
+ private DataConnectionChangeListener mDataConnectionChangeListener;
+ private ServiceStateChangeListener mServiceStateChangeListener;
+
+ private ITelephony mITelephony;
+ private PhoneStateListener mPhoneStateListener;
private static final String[] sProjection = new String[] {
Telephony.Carriers._ID, // 0
@@ -99,8 +101,7 @@
Telephony.Carriers.BEARER, // 18
Telephony.Carriers.ROAMING_PROTOCOL, // 19
Telephony.Carriers.MVNO_TYPE, // 20
- Telephony.Carriers.MVNO_MATCH_DATA
- // 21
+ Telephony.Carriers.MVNO_MATCH_DATA // 21
};
public PhoneFacade(FacadeManager manager) {
@@ -108,160 +109,63 @@
mService = manager.getService();
mTelephonyManager =
(TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE);
- mConnect =
- (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE);
mAndroidFacade = manager.getReceiver(AndroidFacade.class);
mEventFacade = manager.getReceiver(EventFacade.class);
- mPhoneState = new Bundle();
- mServiceState = new Bundle();
- mModemPowerLevel = new Bundle();
- mModemPowerLevel.putLong("time", 0);
- mModemPowerLevel.putInt("power_level", POWER_STATE_UNKNOWN);
- mPreciseCallState = new Bundle();
- mPreciseCallState.putString("CallState", "");
-
- mPhoneStateListener = MainThread.run(mService,
- new Callable<PhoneStateListener>() {
+ MainThread.run(manager.getService(), new Callable<Object>() {
@Override
- public PhoneStateListener call() throws Exception {
- return new PhoneStateListener() {
- @Override
- public void onCallStateChanged(int state,
- String incomingNumber) {
- mPhoneState.putString("incomingNumber",
- incomingNumber);
- switch (state) {
- case TelephonyManager.CALL_STATE_IDLE:
- mPhoneState.putString("state", "idle");
- break;
- case TelephonyManager.CALL_STATE_OFFHOOK:
- mPhoneState.putString("state", "offhook");
- break;
- case TelephonyManager.CALL_STATE_RINGING:
- mPhoneState.putString("state", "ringing");
- break;
- }
- mEventFacade.postEvent("PhoneCallStateChanged", mPhoneState.clone());
- mPhoneState.clear();
- }
-
- public void onServiceStateChanged(ServiceState serviceState) {
- switch(serviceState.getVoiceRegState()) {
- case ServiceState.STATE_EMERGENCY_ONLY:
- mServiceState.putString("serviceState", "emergency");
- break;
- case ServiceState.STATE_IN_SERVICE:
- mServiceState.putString("serviceState", "inService");
- break;
- case ServiceState.STATE_OUT_OF_SERVICE:
- mServiceState.putString("serviceState","noService");
- break;
- case ServiceState.STATE_POWER_OFF:
- mServiceState.putString("serviceState", "powerOff");
- break;
- }
- mServiceState.putString("operatorName",
- serviceState.getOperatorAlphaLong());
- mServiceState.putString("operatorCode",
- serviceState.getOperatorNumeric());
- mEventFacade.postEvent("PhoneServiceStateChanged", mPhoneState.clone());
- mPhoneState.clear();
- }
-
- @Override
- public void onDataConnectionRealTimeInfoChanged(
- DataConnectionRealTimeInfo dcRtInfo) {
- mModemPowerLevel.putString("Type", "modemPowerLvl");
- mModemPowerLevel.putLong("time", dcRtInfo.getTime());
-
- int state = dcRtInfo.getDcPowerState();
- if (POWER_STATE_LOW == state) {
- mModemPowerLevel.putString("power_level", "LOW");
- } else if (POWER_STATE_MEDIUM == state) {
- mModemPowerLevel.putString("power_level", "MEDIUM");
- } else if (POWER_STATE_HIGH == state) {
- mModemPowerLevel.putString("power_level", "HIGH");
- } else {
- mModemPowerLevel.putString("power_level", "UNKNOWN");
- }
-
- mEventFacade.postEvent("PhoneModemPowerLevelChanged",
- mModemPowerLevel.clone());
- mModemPowerLevel.clear();
- }
-
- @Override
- public void
- onPreciseCallStateChanged(PreciseCallState callState) {
- int foreGroundCallState = callState.getForegroundCallState();
-
- if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
- mPreciseCallState.putString("CallState", "ACTIVE");
- } else if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_HOLDING) {
- mPreciseCallState.putString("CallState", "HOLDING)");
- } else if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_DIALING) {
- mPreciseCallState.putString("CallState", "DIALING");
- } else if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_ALERTING) {
- mPreciseCallState.putString("CallState", "ALERTING");
- } else if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_INCOMING) {
- mPreciseCallState.putString("CallState", "INCOMING)");
- } else if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_WAITING) {
- mPreciseCallState.putString("CallState", "WAITING");
- } else if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED) {
- mPreciseCallState.putString("CallState", "DISCONNECTED");
- } else if (foreGroundCallState ==
- PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING) {
- mPreciseCallState.putString("CallState", "DISCONNECTING");
- } else {
- if (callState.getRingingCallState() ==
- PreciseCallState.PRECISE_CALL_STATE_INCOMING) {
- mPreciseCallState.putString("CallState", "INCOMING");
- } else {
- mPreciseCallState.putString("CallState", "IDLE");
- }
- }
- mEventFacade.postEvent("PhonePreciseCallStateChanged",
- mPreciseCallState.clone());
- mPreciseCallState.clear();
- }
-
- };
+ public Object call() throws Exception {
+ mCallStateChangeListener = new CallStateChangeListener(mEventFacade);
+ mDataConnectionChangeListener = new DataConnectionChangeListener(mEventFacade);
+ mServiceStateChangeListener = new ServiceStateChangeListener(mEventFacade);
+ return null;
}
});
}
- @Override
- public void shutdown() {
- stopTrackingPhoneState();
+ @Rpc(description = "Starts tracking call state change.")
+ public void phoneStartTrackingCallState() {
+ mTelephonyManager.listen(mCallStateChangeListener,
+ CallStateChangeListener.sListeningStates);
}
- @Rpc(description = "Starts tracking phone state.")
- public void startTrackingPhoneState() {
- mTelephonyManager.listen(mPhoneStateListener,
- PhoneStateListener.LISTEN_CALL_STATE
- | PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO
- | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
- | PhoneStateListener.LISTEN_SERVICE_STATE);
+ @Rpc(description = "Turn on/off precise listening on fore/background or ringing calls.")
+ public void phoneAdjustPreciseCallStateListenLevel(String type, Boolean listen) {
+ if (type.equals("Foreground")) {
+ mCallStateChangeListener.listenForeground = listen;
+ } else if (type.equals("Ringing")) {
+ mCallStateChangeListener.listenRinging = listen;
+ } else if (type.equals("Background")) {
+ mCallStateChangeListener.listenBackground = listen;
+ }
}
- @Rpc(description = "Returns the current phone state and incoming number.",
- returns = "A Map of \"state\" and \"incomingNumber\"")
- public Bundle readPhoneState() {
- return mPhoneState;
- }
-
- @Rpc(description = "Stops tracking phone state.")
- public void stopTrackingPhoneState() {
+ @Rpc(description = "Stops tracking call state change.")
+ public void phoneStopTrackingCallStateChange() {
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
}
+ @Rpc(description = "Starts tracking power level change.")
+ public void phoneStartTrackingPowerLevelChange() {
+ mTelephonyManager.listen(mDataConnectionChangeListener,
+ DataConnectionChangeListener.sListeningStates);
+ }
+
+ @Rpc(description = "Stops tracking power level change.")
+ public void phoneStopTrackingPowerLevelChange() {
+ mTelephonyManager.listen(mDataConnectionChangeListener, PhoneStateListener.LISTEN_NONE);
+ }
+
+ @Rpc(description = "Starts tracking service state change.")
+ public void phoneStartTrackingServiceStateChange() {
+ mTelephonyManager.listen(mServiceStateChangeListener,
+ ServiceStateChangeListener.sListeningStates);
+ }
+
+ @Rpc(description = "Stops tracking service state change.")
+ public void phoneStopTrackingServicetateChange() {
+ mTelephonyManager.listen(mServiceStateChangeListener, PhoneStateListener.LISTEN_NONE);
+ }
+
@Rpc(description = "Calls a contact/phone number by URI.")
public void phoneCall(@RpcParameter(name = "uri")
final String uriString)
@@ -319,6 +223,12 @@
null, null);
}
+ @Rpc(description = "Answers an incoming ringing call.")
+ public void phoneAnswerCall() throws RemoteException {
+ mITelephony.silenceRinger();
+ mITelephony.answerRingingCall();
+ }
+
@Rpc(description = "Dials a phone number.")
public void phoneDialNumber(@RpcParameter(name = "phone number")
final String number)
@@ -388,9 +298,9 @@
case TelephonyManager.PHONE_TYPE_NONE:
return "none";
case TelephonyManager.PHONE_TYPE_CDMA:
- return "none";
+ return "cdma";
case TelephonyManager.PHONE_TYPE_SIP:
- return "none";
+ return "sip";
default:
return null;
}
@@ -493,15 +403,10 @@
}
@Rpc(description = "Sets an APN and make that as preferred APN.")
- public void setAPN(
- @RpcParameter(name = "name")
- final String name,
- @RpcParameter(name = "apn")
- final String apn,
- @RpcParameter(name = "type")
- @RpcOptional
- @RpcDefault("")
- final String type) {
+ public void setAPN(@RpcParameter(name = "name") final String name,
+ @RpcParameter(name = "apn") final String apn,
+ @RpcParameter(name = "type") @RpcOptional @RpcDefault("")
+ final String type) {
Uri uri;
Cursor cursor;
@@ -520,13 +425,11 @@
uri = mService.getContentResolver().insert(
Telephony.Carriers.CONTENT_URI, new ContentValues());
if (uri == null) {
- Log.w("Failed to insert new telephony provider into "
- + Telephony.Carriers.CONTENT_URI);
+ Log.w("Failed to insert new provider into " + Telephony.Carriers.CONTENT_URI);
return;
}
- cursor = mService.getContentResolver().query(uri, sProjection, null,
- null, null);
+ cursor = mService.getContentResolver().query(uri, sProjection, null, null, null);
cursor.moveToFirst();
ContentValues values = new ContentValues();
@@ -573,24 +476,20 @@
@Rpc(description = "Returns the number of APNs defined")
public int getNumberOfAPNs() {
- int noOfAPN = 0;
- String where = "numeric=\""
- + android.os.SystemProperties.get(
- TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "")
- + "\"";
+ int result = 0;
+ String where = "numeric=\"" + android.os.SystemProperties.get(
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "") + "\"";
Cursor cursor = mService.getContentResolver().query(
Telephony.Carriers.CONTENT_URI,
- new String[] {
- "_id", "name", "apn", "type"
- }, where, null,
+ new String[] {"_id", "name", "apn", "type"}, where, null,
Telephony.Carriers.DEFAULT_SORT_ORDER);
if (cursor != null) {
- noOfAPN = cursor.getCount();
+ result = cursor.getCount();
}
cursor.close();
- return noOfAPN;
+ return result;
}
@Rpc(description = "Returns the currently selected APN name")
@@ -599,11 +498,9 @@
int ID_INDEX = 0;
final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
- Cursor cursor = mService.getContentResolver().query(
- Uri.parse(PREFERRED_APN_URI), new String[] {
- "name"
- }, null,
- null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+ Cursor cursor = mService.getContentResolver().query(Uri.parse(PREFERRED_APN_URI),
+ new String[] {"name"}, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+
if (cursor.getCount() > 0) {
cursor.moveToFirst();
key = cursor.getString(ID_INDEX);
@@ -611,4 +508,11 @@
cursor.close();
return key;
}
+
+ @Override
+ public void shutdown() {
+ phoneStopTrackingCallStateChange();
+ phoneStopTrackingPowerLevelChange();
+ phoneStopTrackingServicetateChange();
+ }
}
diff --git a/Common/src/com/googlecode/android_scripting/facade/tele/TelecommManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/tele/TelecommManagerFacade.java
new file mode 100644
index 0000000..2c53465
--- /dev/null
+++ b/Common/src/com/googlecode/android_scripting/facade/tele/TelecommManagerFacade.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.googlecode.android_scripting.facade.tele;
+
+import java.util.List;
+
+import android.app.Service;
+import android.telecomm.PhoneAccount;
+import android.telecomm.TelecommManager;
+
+import com.googlecode.android_scripting.facade.FacadeManager;
+import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
+import com.googlecode.android_scripting.rpc.Rpc;
+
+/**
+ * Exposes TelecommManager functionality.
+ *
+ */
+public class TelecommManagerFacade extends RpcReceiver {
+ private final TelecommManager mTelecommManager;
+ private final Service mService;
+
+ public TelecommManagerFacade(FacadeManager manager) {
+ super(manager);
+ mService = manager.getService();
+ mTelecommManager = new TelecommManager(mService);
+ }
+
+ @Rpc(description = "If there's a ringing call, accept on behalf of the user.")
+ public List<PhoneAccount> telecommGetEnabledPhoneAccounts() {
+ return mTelecommManager.getEnabledPhoneAccounts();
+ }
+
+ @Rpc(description = "If there's a ringing call, accept on behalf of the user.")
+ public void telecommAcceptRingingCall() {
+ mTelecommManager.acceptRingingCall();
+ }
+
+ @Rpc(description = "End an ongoing call.")
+ public Boolean telecommEndCall() {
+ return mTelecommManager.endCall();
+ }
+
+ @Rpc(description = "Returns whether there is a ringing incoming call.")
+ public Boolean telecommIsRinging() {
+ return mTelecommManager.isRinging();
+ }
+
+ @Rpc(description = "Returns whether there is an ongoing phone call.")
+ public Boolean telecommIsInAPhoneCall() {
+ return mTelecommManager.isInAPhoneCall();
+ }
+
+ @Rpc(description = "Silences the rigner if there's a ringing call.")
+ public void telecommSilenceRinger() {
+ mTelecommManager.silenceRinger();
+ }
+
+ @Override
+ public void shutdown() {
+ }
+
+}
diff --git a/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyStateListeners.java b/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyStateListeners.java
new file mode 100644
index 0000000..834d8cb
--- /dev/null
+++ b/Common/src/com/googlecode/android_scripting/facade/tele/TelephonyStateListeners.java
@@ -0,0 +1,177 @@
+package com.googlecode.android_scripting.facade.tele;
+
+import com.googlecode.android_scripting.facade.EventFacade;
+import android.os.Bundle;
+import android.telephony.DataConnectionRealTimeInfo;
+import android.telephony.PhoneStateListener;
+import android.telephony.PreciseCallState;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+
+/**
+ * Store all subclasses of PhoneStateListener here.
+ */
+public class TelephonyStateListeners {
+
+ public static class CallStateChangeListener extends PhoneStateListener {
+
+ private final EventFacade mEventFacade;
+ public static final int sListeningStates = PhoneStateListener.LISTEN_CALL_STATE |
+ PhoneStateListener.LISTEN_PRECISE_CALL_STATE;
+
+ public boolean listenForeground = true;
+ public boolean listenRinging = false;
+ public boolean listenBackground = false;
+
+ public CallStateChangeListener(EventFacade ef) {
+ super();
+ mEventFacade = ef;
+ }
+
+ public CallStateChangeListener(EventFacade ef, int subId) {
+ super(subId);
+ mEventFacade = ef;
+ }
+
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ Bundle mCallStateEvent = new Bundle();
+ if (incomingNumber.length() > 0) {
+ mCallStateEvent.putString("incomingNumber", incomingNumber);
+ }
+ switch (state) {
+ case TelephonyManager.CALL_STATE_IDLE:
+ mCallStateEvent.putString("State", "IDLE");
+ break;
+ case TelephonyManager.CALL_STATE_OFFHOOK:
+ mCallStateEvent.putString("State", "OFFHOOK");
+ break;
+ case TelephonyManager.CALL_STATE_RINGING:
+ mCallStateEvent.putString("State", "RINGING");
+ break;
+ }
+ mEventFacade.postEvent("onCallStateChanged", mCallStateEvent.clone());
+ mCallStateEvent.clear();
+ }
+
+ @Override
+ public void onPreciseCallStateChanged(PreciseCallState callState) {
+ int foregroundState = callState.getForegroundCallState();
+ int ringingState = callState.getRingingCallState();
+ int backgroundState = callState.getBackgroundCallState();
+ if (listenForeground &&
+ foregroundState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID) {
+ processCallState(foregroundState, "Foreground", callState);
+ }
+ if (listenRinging &&
+ ringingState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID) {
+ processCallState(ringingState, "Ringing", callState);
+ }
+ if (listenBackground &&
+ backgroundState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID) {
+ processCallState(backgroundState, "Background", callState);
+ }
+ }
+
+ private void processCallState(int newState, String which, PreciseCallState callState) {
+ Bundle EventMsg = new Bundle();
+ EventMsg.putString("Type", which);
+ if (newState == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
+ EventMsg.putString("State", "ACTIVE");
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_HOLDING) {
+ EventMsg.putString("State", "HOLDING)");
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_DIALING) {
+ EventMsg.putString("State", "DIALING");
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_ALERTING) {
+ EventMsg.putString("State", "ALERTING");
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_INCOMING) {
+ EventMsg.putString("State", "INCOMING");
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_WAITING) {
+ EventMsg.putString("State", "WAITING");
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED) {
+ EventMsg.putString("State", "DISCONNECTED");
+ EventMsg.putInt("Cause", callState.getPreciseDisconnectCause());
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING) {
+ EventMsg.putString("State", "DISCONNECTING");
+ } else if (newState == PreciseCallState.PRECISE_CALL_STATE_IDLE) {
+ EventMsg.putString("State", "IDLE");
+ }
+ mEventFacade.postEvent("onPreciseStateChanged", EventMsg);
+ }
+ }
+
+ public static class DataConnectionChangeListener extends PhoneStateListener {
+
+ private final EventFacade mEventFacade;
+ public static final int sListeningStates =
+ PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO;
+
+ public DataConnectionChangeListener(EventFacade ef) {
+ super();
+ mEventFacade = ef;
+ }
+
+ public DataConnectionChangeListener(EventFacade ef, int subId) {
+ super(subId);
+ mEventFacade = ef;
+ }
+
+ @Override
+ public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) {
+ Bundle event = new Bundle();
+ event.putString("Type", "modemPowerLvl");
+ event.putLong("Time", dcRtInfo.getTime());
+
+ int state = dcRtInfo.getDcPowerState();
+ if (state == DataConnectionRealTimeInfo.DC_POWER_STATE_LOW) {
+ event.putString("PowerLevel", "LOW");
+ } else if (state == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH) {
+ event.putString("PowerLevel", "MEDIUM");
+ } else if (state == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) {
+ event.putString("PowerLevel", "HIGH");
+ } else if (state == DataConnectionRealTimeInfo.DC_POWER_STATE_UNKNOWN) {
+ event.putString("PowerLevel", "UNKNOWN");
+ }
+ mEventFacade.postEvent("onModemPowerLevelChanged", event);
+ }
+ }
+
+ public static class ServiceStateChangeListener extends PhoneStateListener {
+
+ private final EventFacade mEventFacade;
+ public static final int sListeningStates = PhoneStateListener.LISTEN_SERVICE_STATE;
+
+ public ServiceStateChangeListener(EventFacade ef) {
+ super();
+ mEventFacade = ef;
+ }
+
+ public ServiceStateChangeListener(EventFacade ef, int subId) {
+ super(subId);
+ mEventFacade = ef;
+ }
+
+ @Override
+ public void onServiceStateChanged(ServiceState serviceState) {
+ Bundle event = new Bundle();;
+ switch(serviceState.getVoiceRegState()) {
+ case ServiceState.STATE_EMERGENCY_ONLY:
+ event.putString("State", "EMERGENCY_ONLY");
+ break;
+ case ServiceState.STATE_IN_SERVICE:
+ event.putString("State", "IN_SERVICE");
+ break;
+ case ServiceState.STATE_OUT_OF_SERVICE:
+ event.putString("State","OUT_OF_SERVICE");
+ break;
+ case ServiceState.STATE_POWER_OFF:
+ event.putString("State", "POWER_OFF");
+ break;
+ }
+ event.putString("OperatorName", serviceState.getOperatorAlphaLong());
+ event.putString("OperatorId", serviceState.getOperatorNumeric());
+ mEventFacade.postEvent("onServiceStateChanged", event);
+ }
+ }
+
+}
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 9b88a0b..144597c 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -43,8 +43,10 @@
import android.net.wifi.WifiInfo;
import android.os.Bundle;
import android.os.ParcelUuid;
+import android.telecomm.PhoneAccount;
import android.telephony.CellLocation;
import android.telephony.NeighboringCellInfo;
+import android.telephony.SmsMessage;
import android.telephony.gsm.GsmCellLocation;
import android.util.DisplayMetrics;
@@ -154,6 +156,12 @@
if (data instanceof Point) {
return buildPoint((Point) data);
}
+ if (data instanceof SmsMessage) {
+ return buildSmsMessage((SmsMessage) data);
+ }
+ if (data instanceof PhoneAccount) {
+ return buildPhoneAccount((PhoneAccount) data);
+ }
if (data instanceof DisplayMetrics) {
return buildDisplayMetrics((DisplayMetrics) data);
}
@@ -355,6 +363,19 @@
return point;
}
+ private static Object buildSmsMessage(SmsMessage data) throws JSONException {
+ JSONObject msg = new JSONObject();
+ msg.put("originatingAddress", data.getOriginatingAddress());
+ msg.put("messageBody", data.getMessageBody());
+ return msg;
+ }
+
+ private static Object buildPhoneAccount(PhoneAccount data) throws JSONException {
+ JSONObject msg = new JSONObject();
+ msg.put("id", data.getId());
+ return msg;
+ }
+
private static Object buildDisplayMetrics(DisplayMetrics data) throws JSONException {
JSONObject dm = new JSONObject();
dm.put("widthPixels", data.widthPixels);
diff --git a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
index 11d2501..5d77696 100644
--- a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
+++ b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
@@ -29,6 +29,8 @@
import com.googlecode.android_scripting.facade.bluetooth.BluetoothLeScanFacade;
import com.googlecode.android_scripting.facade.bluetooth.BluetoothMapFacade;
import com.googlecode.android_scripting.facade.bluetooth.BluetoothRfcommFacade;
+import com.googlecode.android_scripting.facade.tele.PhoneFacade;
+import com.googlecode.android_scripting.facade.tele.TelecommManagerFacade;
import com.googlecode.android_scripting.facade.ui.UiFacade;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.MethodDescriptor;
@@ -82,8 +84,7 @@
sFacadeClassList.add(MediaSessionFacade.class);
sFacadeClassList.add(SensorManagerFacade.class);
sFacadeClassList.add(SettingsFacade.class);
- // Could not get SmsFacade to compile. APIs are deprecated
- // sFacadeClassList.add(SmsFacade.class);
+ sFacadeClassList.add(SmsFacade.class);
sFacadeClassList.add(SpeechRecognitionFacade.class);
sFacadeClassList.add(ToneGeneratorFacade.class);
sFacadeClassList.add(WakeLockFacade.class);
@@ -121,6 +122,7 @@
sFacadeClassList.add(BluetoothGattFacade.class);
sFacadeClassList.add(BluetoothLeAdvertiseFacade.class);
sFacadeClassList.add(DisplayFacade.class);
+ sFacadeClassList.add(TelecommManagerFacade.class);
sFacadeClassList.add(WifiPasspointManagerFacade.class);
sFacadeClassList.add(WifiScannerFacade.class);
}
diff --git a/ScriptingLayerForAndroid/AndroidManifest.xml b/ScriptingLayerForAndroid/AndroidManifest.xml
index a69bf92..666d93a 100644
--- a/ScriptingLayerForAndroid/AndroidManifest.xml
+++ b/ScriptingLayerForAndroid/AndroidManifest.xml
@@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" />
+ <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
@@ -20,6 +21,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.PERSISTENT_ACTIVITY" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.GET_TASKS" />