Merge "Use PhoneBase in the phone list." into gingerbread
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index fd6769c..deba70c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3542,10 +3542,10 @@
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.isOverlayEnabled()) {
- canvas.translate(child.mLeft + child.mScrollX, child.mTop + child.mScrollY);
+ canvas.translate(child.mLeft - child.mScrollX, child.mTop - child.mScrollY);
child.onDrawOverlay(canvas);
- canvas.translate(-(child.mLeft + child.mScrollX),
- -(child.mTop + child.mScrollY));
+ canvas.translate(-(child.mLeft - child.mScrollX),
+ -(child.mTop - child.mScrollY));
}
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a14d004..a09b0c8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7727,8 +7727,9 @@
bounds.bottom = bounds.top + drawableHeight;
convertFromViewportToContentCoordinates(bounds);
+ invalidate();
mDrawable.setBounds(bounds);
- postInvalidate();
+ invalidate();
}
boolean hasFingerOn(float x, float y) {
@@ -7745,9 +7746,16 @@
return Rect.intersects(mDrawable.getBounds(), fingerRect);
}
+ void invalidate() {
+ final Rect bounds = mDrawable.getBounds();
+ TextView.this.invalidate(bounds.left, bounds.top,
+ bounds.right, bounds.bottom);
+ }
+
void postInvalidate() {
final Rect bounds = mDrawable.getBounds();
- TextView.this.postInvalidate(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ TextView.this.postInvalidate(bounds.left, bounds.top,
+ bounds.right, bounds.bottom);
}
void postInvalidateDelayed(long delay) {
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d565c68..720dc97 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -342,4 +342,6 @@
<!-- 2 means give warning -->
<integer name="config_datause_notification_type">2</integer>
+ <!-- Enables SIP on WIFI only -->
+ <bool name="config_sip_wifi_only">false</bool>
</resources>
diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp
index 4aa50d6..b46279e 100644
--- a/libs/utils/Looper.cpp
+++ b/libs/utils/Looper.cpp
@@ -184,44 +184,50 @@
#if DEBUG_POLL_AND_WAKE
LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
#endif
- { // acquire lock
- AutoMutex _l(mLock);
- for (int i = 0; i < eventCount; i++) {
- int fd = eventItems[i].data.fd;
- uint32_t epollEvents = eventItems[i].events;
- if (fd == mWakeReadPipeFd) {
- if (epollEvents & EPOLLIN) {
+ bool acquiredLock = false;
+ for (int i = 0; i < eventCount; i++) {
+ int fd = eventItems[i].data.fd;
+ uint32_t epollEvents = eventItems[i].events;
+ if (fd == mWakeReadPipeFd) {
+ if (epollEvents & EPOLLIN) {
#if DEBUG_POLL_AND_WAKE
- LOGD("%p ~ pollOnce - awoken", this);
+ LOGD("%p ~ pollOnce - awoken", this);
#endif
- char buffer[16];
- ssize_t nRead;
- do {
- nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
- } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
- } else {
- LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
- }
+ char buffer[16];
+ ssize_t nRead;
+ do {
+ nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
+ } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
} else {
- ssize_t requestIndex = mRequests.indexOfKey(fd);
- if (requestIndex >= 0) {
- int events = 0;
- if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
- if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
- if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
- if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
+ LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
+ }
+ } else {
+ if (! acquiredLock) {
+ mLock.lock();
+ acquiredLock = true;
+ }
- Response response;
- response.events = events;
- response.request = mRequests.valueAt(requestIndex);
- mResponses.push(response);
- } else {
- LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
- "no longer registered.", epollEvents, fd);
- }
+ ssize_t requestIndex = mRequests.indexOfKey(fd);
+ if (requestIndex >= 0) {
+ int events = 0;
+ if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
+ if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
+ if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
+ if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
+
+ Response response;
+ response.events = events;
+ response.request = mRequests.valueAt(requestIndex);
+ mResponses.push(response);
+ } else {
+ LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
+ "no longer registered.", epollEvents, fd);
}
}
}
+ if (acquiredLock) {
+ mLock.unlock();
+ }
for (size_t i = 0; i < mResponses.size(); i++) {
const Response& response = mResponses.itemAt(i);
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 5d6ac26..747c829 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -136,30 +136,24 @@
*/
void* dso;
- char path[PATH_MAX];
int index = int(display);
driver_t* hnd = 0;
- const char* const format = "/system/lib/egl/lib%s_%s.so";
char const* tag = getTag(index, impl);
if (tag) {
- snprintf(path, PATH_MAX, format, "GLES", tag);
- dso = load_driver(path, cnx, EGL | GLESv1_CM | GLESv2);
+ dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2);
if (dso) {
hnd = new driver_t(dso);
} else {
// Always load EGL first
- snprintf(path, PATH_MAX, format, "EGL", tag);
- dso = load_driver(path, cnx, EGL);
+ dso = load_driver("EGL", tag, cnx, EGL);
if (dso) {
hnd = new driver_t(dso);
// TODO: make this more automated
- snprintf(path, PATH_MAX, format, "GLESv1_CM", tag);
- hnd->set( load_driver(path, cnx, GLESv1_CM), GLESv1_CM );
+ hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM );
- snprintf(path, PATH_MAX, format, "GLESv2", tag);
- hnd->set( load_driver(path, cnx, GLESv2), GLESv2 );
+ hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 );
}
}
}
@@ -222,12 +216,20 @@
}
}
-void *Loader::load_driver(const char* driver_absolute_path,
+void *Loader::load_driver(const char* kind, const char *tag,
egl_connection_t* cnx, uint32_t mask)
{
+ char driver_absolute_path[PATH_MAX];
+ const char* const search1 = "/vendor/lib/egl/lib%s_%s.so";
+ const char* const search2 = "/system/lib/egl/lib%s_%s.so";
+
+ snprintf(driver_absolute_path, PATH_MAX, search1, kind, tag);
if (access(driver_absolute_path, R_OK)) {
- // this happens often, we don't want to log an error
- return 0;
+ snprintf(driver_absolute_path, PATH_MAX, search2, kind, tag);
+ if (access(driver_absolute_path, R_OK)) {
+ // this happens often, we don't want to log an error
+ return 0;
+ }
}
void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 8659b0b..580d6e4 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -74,7 +74,7 @@
private:
Loader();
- void *load_driver(const char* driver, egl_connection_t* cnx, uint32_t mask);
+ void *load_driver(const char* kind, const char *tag, egl_connection_t* cnx, uint32_t mask);
static __attribute__((noinline))
void init_api(void* dso,
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index eb0a8a9..1bc5e4b 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -35,6 +35,7 @@
import android.net.NetworkUtils;
import android.os.Binder;
import android.os.Environment;
+import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.INetworkManagementService;
@@ -110,6 +111,14 @@
private boolean mUsbMassStorageOff; // track the status of USB Mass Storage
private boolean mUsbConnected; // track the status of USB connection
+ // mUsbHandler message
+ static final int USB_STATE_CHANGE = 1;
+ static final int USB_DISCONNECTED = 0;
+ static final int USB_CONNECTED = 1;
+
+ // Time to delay before processing USB disconnect events
+ static final long USB_DISCONNECT_DELAY = 1000;
+
public Tethering(Context context, Looper looper) {
Log.d(TAG, "Tethering starting");
mContext = context;
@@ -421,12 +430,25 @@
}
}
+ private Handler mUsbHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ mUsbConnected = (msg.arg1 == USB_CONNECTED);
+ updateUsbStatus();
+ }
+ };
+
private class StateReceiver extends BroadcastReceiver {
public void onReceive(Context content, Intent intent) {
String action = intent.getAction();
if (action.equals(Usb.ACTION_USB_STATE)) {
- mUsbConnected = intent.getExtras().getBoolean(Usb.USB_CONNECTED);
- updateUsbStatus();
+ // process connect events immediately, but delay handling disconnects
+ // to debounce USB configuration changes
+ boolean connected = intent.getExtras().getBoolean(Usb.USB_CONNECTED);
+ Message msg = Message.obtain(mUsbHandler, USB_STATE_CHANGE,
+ (connected ? USB_CONNECTED : USB_DISCONNECTED), 0);
+ mUsbHandler.removeMessages(USB_STATE_CHANGE);
+ mUsbHandler.sendMessageDelayed(msg, connected ? 0 : USB_DISCONNECT_DELAY);
} else if (action.equals(Intent.ACTION_MEDIA_SHARED)) {
mUsbMassStorageOff = false;
updateUsbStatus();
diff --git a/services/java/com/android/server/sip/SipService.java b/services/java/com/android/server/sip/SipService.java
index d7747fb..a2ebc69 100644
--- a/services/java/com/android/server/sip/SipService.java
+++ b/services/java/com/android/server/sip/SipService.java
@@ -35,6 +35,10 @@
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.text.TextUtils;
@@ -71,6 +75,9 @@
private boolean mConnected;
private WakeupTimer mTimer;
private WifiManager.WifiLock mWifiLock;
+ private boolean mWifiOnly;
+
+ private MyExecutor mExecutor;
// SipProfile URI --> group
private Map<String, SipSessionGroupExt> mSipGroups =
@@ -99,6 +106,13 @@
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
mTimer = new WakeupTimer(context);
+ mWifiOnly = SipManager.isSipWifiOnly(context);
+ }
+
+ private MyExecutor getExecutor() {
+ // create mExecutor lazily
+ if (mExecutor == null) mExecutor = new MyExecutor();
+ return mExecutor;
}
public synchronized SipProfile[] getListOfProfiles() {
@@ -474,10 +488,10 @@
}
@Override
- public void onError(ISipSession session, String errorClass,
+ public void onError(ISipSession session, int errorCode,
String message) {
- if (DEBUG) Log.d(TAG, "sip session error: " + errorClass + ": "
- + message);
+ if (DEBUG) Log.d(TAG, "sip session error: "
+ + SipErrorCode.toString(errorCode) + ": " + message);
}
public boolean isOpened() {
@@ -507,6 +521,15 @@
}
public void run() {
+ // delegate to mExecutor
+ getExecutor().addTask(new Runnable() {
+ public void run() {
+ realRun();
+ }
+ });
+ }
+
+ private void realRun() {
synchronized (SipService.this) {
SipSessionGroup.SipSessionImpl session = mSession.duplicate();
if (DEBUG) Log.d(TAG, "~~~ keepalive");
@@ -533,7 +556,7 @@
private int mBackoff = 1;
private boolean mRegistered;
private long mExpiryTime;
- private SipErrorCode mErrorCode;
+ private int mErrorCode;
private String mErrorMessage;
private String getAction() {
@@ -589,10 +612,9 @@
if (mSession == null) return;
try {
- SipSessionState state = (mSession == null)
+ int state = (mSession == null)
? SipSessionState.READY_TO_CALL
- : Enum.valueOf(
- SipSessionState.class, mSession.getState());
+ : mSession.getState();
if ((state == SipSessionState.REGISTERING)
|| (state == SipSessionState.DEREGISTERING)) {
mProxy.onRegistering(mSession);
@@ -600,12 +622,12 @@
int duration = (int)
(mExpiryTime - SystemClock.elapsedRealtime());
mProxy.onRegistrationDone(mSession, duration);
- } else if (mErrorCode != null) {
+ } else if (mErrorCode != SipErrorCode.NO_ERROR) {
if (mErrorCode == SipErrorCode.TIME_OUT) {
mProxy.onRegistrationTimeout(mSession);
} else {
- mProxy.onRegistrationFailed(mSession,
- mErrorCode.toString(), mErrorMessage);
+ mProxy.onRegistrationFailed(mSession, mErrorCode,
+ mErrorMessage);
}
}
} catch (Throwable t) {
@@ -619,7 +641,16 @@
}
public void run() {
- mErrorCode = null;
+ // delegate to mExecutor
+ getExecutor().addTask(new Runnable() {
+ public void run() {
+ realRun();
+ }
+ });
+ }
+
+ private void realRun() {
+ mErrorCode = SipErrorCode.NO_ERROR;
mErrorMessage = null;
if (DEBUG) Log.d(TAG, "~~~ registering");
synchronized (SipService.this) {
@@ -712,18 +743,15 @@
}
@Override
- public void onRegistrationFailed(ISipSession session,
- String errorCodeString, String message) {
- SipErrorCode errorCode =
- Enum.valueOf(SipErrorCode.class, errorCodeString);
+ public void onRegistrationFailed(ISipSession session, int errorCode,
+ String message) {
if (DEBUG) Log.d(TAG, "onRegistrationFailed(): " + session + ": "
- + errorCode + ": " + message);
+ + SipErrorCode.toString(errorCode) + ": " + message);
synchronized (SipService.this) {
if (!isStopped() && (session != mSession)) return;
mErrorCode = errorCode;
mErrorMessage = message;
- mProxy.onRegistrationFailed(session, errorCode.toString(),
- message);
+ mProxy.onRegistrationFailed(session, errorCode, message);
if (errorCode == SipErrorCode.INVALID_CREDENTIALS) {
if (DEBUG) Log.d(TAG, " pause auto-registration");
@@ -774,6 +802,15 @@
String type = netInfo.getTypeName();
NetworkInfo.State state = netInfo.getState();
+ if (mWifiOnly && (netInfo.getType() !=
+ ConnectivityManager.TYPE_WIFI)) {
+ if (DEBUG) {
+ Log.d(TAG, "Wifi only, other connectivity ignored: "
+ + type);
+ }
+ return;
+ }
+
NetworkInfo activeNetInfo = getActiveNetworkInfo();
if (DEBUG) {
if (activeNetInfo != null) {
@@ -822,7 +859,7 @@
if (connected) {
if (mTask != null) mTask.cancel();
mTask = new MyTimerTask(type, connected);
- mTimer.schedule(mTask, 3 * 1000L);
+ mTimer.schedule(mTask, 2 * 1000L);
// TODO: hold wakup lock so that we can finish change before
// the device goes to sleep
} else {
@@ -845,6 +882,15 @@
@Override
public void run() {
+ // delegate to mExecutor
+ getExecutor().addTask(new Runnable() {
+ public void run() {
+ realRun();
+ }
+ });
+ }
+
+ private void realRun() {
synchronized (SipService.this) {
if (mTask != this) {
Log.w(TAG, " unexpected task: " + mNetworkType
@@ -1155,4 +1201,30 @@
return (this == that);
}
}
+
+ // Single-threaded executor
+ private static class MyExecutor extends Handler {
+ MyExecutor() {
+ super(createLooper());
+ }
+
+ private static Looper createLooper() {
+ HandlerThread thread = new HandlerThread("SipService");
+ thread.start();
+ return thread.getLooper();
+ }
+
+ void addTask(Runnable task) {
+ Message.obtain(this, 0/* don't care */, task).sendToTarget();
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.obj instanceof Runnable) {
+ ((Runnable) msg.obj).run();
+ } else {
+ Log.w(TAG, "can't handle msg: " + msg);
+ }
+ }
+ }
}
diff --git a/services/java/com/android/server/sip/SipSessionGroup.java b/services/java/com/android/server/sip/SipSessionGroup.java
index baf9a8e..b4c2241 100644
--- a/services/java/com/android/server/sip/SipSessionGroup.java
+++ b/services/java/com/android/server/sip/SipSessionGroup.java
@@ -300,7 +300,8 @@
boolean isLoggable = isLoggable(session, event);
boolean processed = (session != null) && session.process(event);
if (isLoggable && processed) {
- Log.d(TAG, "new state after: " + session.mState);
+ Log.d(TAG, "new state after: "
+ + SipSessionState.toString(session.mState));
}
} catch (Throwable e) {
Log.w(TAG, "event process error: " + event, e);
@@ -331,7 +332,8 @@
public boolean process(EventObject evt) throws SipException {
if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": "
- + mState + ": processing " + log(evt));
+ + SipSessionState.toString(mState) + ": processing "
+ + log(evt));
if (isRequestEvent(Request.INVITE, evt)) {
RequestEvent event = (RequestEvent) evt;
SipSessionImpl newSession = new SipSessionImpl(mProxy);
@@ -356,7 +358,7 @@
class SipSessionImpl extends ISipSession.Stub {
SipProfile mPeerProfile;
SipSessionListenerProxy mProxy = new SipSessionListenerProxy();
- SipSessionState mState = SipSessionState.READY_TO_CALL;
+ int mState = SipSessionState.READY_TO_CALL;
RequestEvent mInviteReceived;
Dialog mDialog;
ServerTransaction mServerTransaction;
@@ -447,8 +449,8 @@
return null;
}
- public String getState() {
- return mState.toString();
+ public int getState() {
+ return mState;
}
public void setListener(ISipSessionListener listener) {
@@ -521,7 +523,7 @@
mState = SipSessionState.PINGING;
try {
processCommand(new OptionsCommand());
- while (SipSessionState.PINGING.equals(mState)) {
+ while (SipSessionState.PINGING == mState) {
Thread.sleep(1000);
}
} catch (SipException e) {
@@ -547,7 +549,8 @@
public String toString() {
try {
String s = super.toString();
- return s.substring(s.indexOf("@")) + ":" + mState;
+ return s.substring(s.indexOf("@")) + ":"
+ + SipSessionState.toString(mState);
} catch (Throwable e) {
return super.toString();
}
@@ -555,7 +558,8 @@
public boolean process(EventObject evt) throws SipException {
if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": "
- + mState + ": processing " + log(evt));
+ + SipSessionState.toString(mState) + ": processing "
+ + log(evt));
synchronized (SipSessionGroup.this) {
if (isClosed()) return false;
@@ -570,30 +574,30 @@
boolean processed;
switch (mState) {
- case REGISTERING:
- case DEREGISTERING:
+ case SipSessionState.REGISTERING:
+ case SipSessionState.DEREGISTERING:
processed = registeringToReady(evt);
break;
- case PINGING:
+ case SipSessionState.PINGING:
processed = keepAliveProcess(evt);
break;
- case READY_TO_CALL:
+ case SipSessionState.READY_TO_CALL:
processed = readyForCall(evt);
break;
- case INCOMING_CALL:
+ case SipSessionState.INCOMING_CALL:
processed = incomingCall(evt);
break;
- case INCOMING_CALL_ANSWERING:
+ case SipSessionState.INCOMING_CALL_ANSWERING:
processed = incomingCallToInCall(evt);
break;
- case OUTGOING_CALL:
- case OUTGOING_CALL_RING_BACK:
+ case SipSessionState.OUTGOING_CALL:
+ case SipSessionState.OUTGOING_CALL_RING_BACK:
processed = outgoingCall(evt);
break;
- case OUTGOING_CALL_CANCELING:
+ case SipSessionState.OUTGOING_CALL_CANCELING:
processed = outgoingCallToReady(evt);
break;
- case IN_CALL:
+ case SipSessionState.IN_CALL:
processed = inCall(evt);
break;
default:
@@ -640,8 +644,8 @@
private void processTransactionTerminated(
TransactionTerminatedEvent event) {
switch (mState) {
- case IN_CALL:
- case READY_TO_CALL:
+ case SipSessionState.IN_CALL:
+ case SipSessionState.READY_TO_CALL:
Log.d(TAG, "Transaction terminated; do nothing");
break;
default:
@@ -666,18 +670,18 @@
return;
}
switch (mState) {
- case REGISTERING:
- case DEREGISTERING:
+ case SipSessionState.REGISTERING:
+ case SipSessionState.DEREGISTERING:
reset();
mProxy.onRegistrationTimeout(this);
break;
- case INCOMING_CALL:
- case INCOMING_CALL_ANSWERING:
- case OUTGOING_CALL:
- case OUTGOING_CALL_CANCELING:
+ case SipSessionState.INCOMING_CALL:
+ case SipSessionState.INCOMING_CALL_ANSWERING:
+ case SipSessionState.OUTGOING_CALL:
+ case SipSessionState.OUTGOING_CALL_CANCELING:
onError(SipErrorCode.TIME_OUT, event.toString());
break;
- case PINGING:
+ case SipSessionState.PINGING:
reset();
mReRegisterFlag = true;
mState = SipSessionState.READY_TO_CALL;
@@ -753,7 +757,7 @@
int statusCode = response.getStatusCode();
switch (statusCode) {
case Response.OK:
- SipSessionState state = mState;
+ int state = mState;
onRegistrationDone((state == SipSessionState.REGISTERING)
? getExpiryTime(((ResponseEvent) evt).getResponse())
: -1);
@@ -1062,10 +1066,9 @@
mProxy.onCallEstablished(this, mPeerSessionDescription);
}
- private void fallbackToPreviousInCall(SipErrorCode errorCode,
- String message) {
+ private void fallbackToPreviousInCall(int errorCode, String message) {
mState = SipSessionState.IN_CALL;
- mProxy.onCallChangeFailed(this, errorCode.toString(), message);
+ mProxy.onCallChangeFailed(this, errorCode, message);
}
private void endCallNormally() {
@@ -1073,9 +1076,9 @@
mProxy.onCallEnded(this);
}
- private void endCallOnError(SipErrorCode errorCode, String message) {
+ private void endCallOnError(int errorCode, String message) {
reset();
- mProxy.onError(this, errorCode.toString(), message);
+ mProxy.onError(this, errorCode, message);
}
private void endCallOnBusy() {
@@ -1083,11 +1086,11 @@
mProxy.onCallBusy(this);
}
- private void onError(SipErrorCode errorCode, String message) {
+ private void onError(int errorCode, String message) {
cancelSessionTimer();
switch (mState) {
- case REGISTERING:
- case DEREGISTERING:
+ case SipSessionState.REGISTERING:
+ case SipSessionState.DEREGISTERING:
onRegistrationFailed(errorCode, message);
break;
default:
@@ -1115,7 +1118,7 @@
}
}
- private SipErrorCode getErrorCode(int responseStatusCode) {
+ private int getErrorCode(int responseStatusCode) {
switch (responseStatusCode) {
case Response.TEMPORARILY_UNAVAILABLE:
case Response.FORBIDDEN:
@@ -1151,7 +1154,7 @@
return exception;
}
- private SipErrorCode getErrorCode(Throwable exception) {
+ private int getErrorCode(Throwable exception) {
String message = exception.getMessage();
if (exception instanceof UnknownHostException) {
return SipErrorCode.INVALID_REMOTE_URI;
@@ -1169,10 +1172,9 @@
mProxy.onRegistrationDone(this, duration);
}
- private void onRegistrationFailed(SipErrorCode errorCode,
- String message) {
+ private void onRegistrationFailed(int errorCode, String message) {
reset();
- mProxy.onRegistrationFailed(this, errorCode.toString(), message);
+ mProxy.onRegistrationFailed(this, errorCode, message);
}
private void onRegistrationFailed(Throwable exception) {
@@ -1262,7 +1264,7 @@
private static boolean isLoggable(SipSessionImpl s) {
if (s != null) {
switch (s.mState) {
- case PINGING:
+ case SipSessionState.PINGING:
return DEBUG_PING;
}
}
diff --git a/services/java/com/android/server/sip/SipSessionListenerProxy.java b/services/java/com/android/server/sip/SipSessionListenerProxy.java
index 747d79f..a4cd102 100644
--- a/services/java/com/android/server/sip/SipSessionListenerProxy.java
+++ b/services/java/com/android/server/sip/SipSessionListenerProxy.java
@@ -124,7 +124,7 @@
}
public void onCallChangeFailed(final ISipSession session,
- final String errorCode, final String message) {
+ final int errorCode, final String message) {
if (mListener == null) return;
proxy(new Runnable() {
public void run() {
@@ -137,7 +137,7 @@
});
}
- public void onError(final ISipSession session, final String errorCode,
+ public void onError(final ISipSession session, final int errorCode,
final String message) {
if (mListener == null) return;
proxy(new Runnable() {
@@ -179,7 +179,7 @@
}
public void onRegistrationFailed(final ISipSession session,
- final String errorCode, final String message) {
+ final int errorCode, final String message) {
if (mListener == null) return;
proxy(new Runnable() {
public void run() {
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 4887950..0a87ddb 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -802,15 +802,15 @@
private static Call.State getCallStateFrom(SipAudioCall sipAudioCall) {
if (sipAudioCall.isOnHold()) return Call.State.HOLDING;
- SipSessionState sessionState = sipAudioCall.getState();
+ int sessionState = sipAudioCall.getState();
switch (sessionState) {
- case READY_TO_CALL: return Call.State.IDLE;
- case INCOMING_CALL:
- case INCOMING_CALL_ANSWERING: return Call.State.INCOMING;
- case OUTGOING_CALL: return Call.State.DIALING;
- case OUTGOING_CALL_RING_BACK: return Call.State.ALERTING;
- case OUTGOING_CALL_CANCELING: return Call.State.DISCONNECTING;
- case IN_CALL: return Call.State.ACTIVE;
+ case SipSessionState.READY_TO_CALL: return Call.State.IDLE;
+ case SipSessionState.INCOMING_CALL:
+ case SipSessionState.INCOMING_CALL_ANSWERING: return Call.State.INCOMING;
+ case SipSessionState.OUTGOING_CALL: return Call.State.DIALING;
+ case SipSessionState.OUTGOING_CALL_RING_BACK: return Call.State.ALERTING;
+ case SipSessionState.OUTGOING_CALL_CANCELING: return Call.State.DISCONNECTING;
+ case SipSessionState.IN_CALL: return Call.State.ACTIVE;
default:
Log.w(LOG_TAG, "illegal connection state: " + sessionState);
return Call.State.DISCONNECTED;
@@ -823,7 +823,9 @@
@Override
public void onCallEnded(SipAudioCall call) {
- onCallEnded(Connection.DisconnectCause.NORMAL);
+ onCallEnded(call.isInCall()
+ ? Connection.DisconnectCause.NORMAL
+ : Connection.DisconnectCause.INCOMING_MISSED);
}
@Override
@@ -832,30 +834,31 @@
}
@Override
- public void onError(SipAudioCall call, SipErrorCode errorCode,
+ public void onError(SipAudioCall call, int errorCode,
String errorMessage) {
switch (errorCode) {
- case PEER_NOT_REACHABLE:
+ case SipErrorCode.PEER_NOT_REACHABLE:
onError(Connection.DisconnectCause.NUMBER_UNREACHABLE);
break;
- case INVALID_REMOTE_URI:
+ case SipErrorCode.INVALID_REMOTE_URI:
onError(Connection.DisconnectCause.INVALID_NUMBER);
break;
- case TIME_OUT:
- case TRANSACTION_TERMINTED:
+ case SipErrorCode.TIME_OUT:
+ case SipErrorCode.TRANSACTION_TERMINTED:
onError(Connection.DisconnectCause.TIMED_OUT);
break;
- case DATA_CONNECTION_LOST:
+ case SipErrorCode.DATA_CONNECTION_LOST:
onError(Connection.DisconnectCause.LOST_SIGNAL);
break;
- case INVALID_CREDENTIALS:
+ case SipErrorCode.INVALID_CREDENTIALS:
onError(Connection.DisconnectCause.INVALID_CREDENTIALS);
break;
- case SOCKET_ERROR:
- case SERVER_ERROR:
- case CLIENT_ERROR:
+ case SipErrorCode.SOCKET_ERROR:
+ case SipErrorCode.SERVER_ERROR:
+ case SipErrorCode.CLIENT_ERROR:
default:
- Log.w(LOG_TAG, "error: " + errorCode + ": " + errorMessage);
+ Log.w(LOG_TAG, "error: " + SipErrorCode.toString(errorCode)
+ + ": " + errorMessage);
onError(Connection.DisconnectCause.ERROR_UNSPECIFIED);
}
}
diff --git a/voip/java/android/net/sip/ISipSession.aidl b/voip/java/android/net/sip/ISipSession.aidl
index 5661b8f..2d515db 100644
--- a/voip/java/android/net/sip/ISipSession.aidl
+++ b/voip/java/android/net/sip/ISipSession.aidl
@@ -49,14 +49,11 @@
/**
* Gets the session state. The value returned must be one of the states in
- * {@link SipSessionState}. One may convert it to {@link SipSessionState} by
- * <code>
- * Enum.valueOf(SipSessionState.class, session.getState());
- * </code>
+ * {@link SipSessionState}.
*
* @return the session state
*/
- String getState();
+ int getState();
/**
* Checks if the session is in a call.
diff --git a/voip/java/android/net/sip/ISipSessionListener.aidl b/voip/java/android/net/sip/ISipSessionListener.aidl
index 0a6220b..5920bca 100644
--- a/voip/java/android/net/sip/ISipSessionListener.aidl
+++ b/voip/java/android/net/sip/ISipSessionListener.aidl
@@ -79,8 +79,7 @@
* @param errorCode error code defined in {@link SipErrorCode}
* @param errorMessage error message
*/
- void onError(in ISipSession session, String errorCode,
- String errorMessage);
+ void onError(in ISipSession session, int errorCode, String errorMessage);
/**
* Called when an error occurs during session modification negotiation.
@@ -89,7 +88,7 @@
* @param errorCode error code defined in {@link SipErrorCode}
* @param errorMessage error message
*/
- void onCallChangeFailed(in ISipSession session, String errorCode,
+ void onCallChangeFailed(in ISipSession session, int errorCode,
String errorMessage);
/**
@@ -114,7 +113,7 @@
* @param errorCode error code defined in {@link SipErrorCode}
* @param errorMessage error message
*/
- void onRegistrationFailed(in ISipSession session, String errorCode,
+ void onRegistrationFailed(in ISipSession session, int errorCode,
String errorMessage);
/**
diff --git a/voip/java/android/net/sip/SipAudioCall.java b/voip/java/android/net/sip/SipAudioCall.java
index 4abea20..0069fe0 100644
--- a/voip/java/android/net/sip/SipAudioCall.java
+++ b/voip/java/android/net/sip/SipAudioCall.java
@@ -90,9 +90,9 @@
* @param call the call object that carries out the audio call
* @param errorCode error code of this error
* @param errorMessage error message
+ * @see SipErrorCode
*/
- void onError(SipAudioCall call, SipErrorCode errorCode,
- String errorMessage);
+ void onError(SipAudioCall call, int errorCode, String errorMessage);
}
/**
@@ -126,7 +126,7 @@
public void onCallHeld(SipAudioCall call) {
onChanged(call);
}
- public void onError(SipAudioCall call, SipErrorCode errorCode,
+ public void onError(SipAudioCall call, int errorCode,
String errorMessage) {
onChanged(call);
}
@@ -318,10 +318,11 @@
/**
* Gets the state of the {@link ISipSession} that carries this call.
+ * The value returned must be one of the states in {@link SipSessionState}.
*
* @return the session state
*/
- SipSessionState getState();
+ int getState();
/**
* Gets the {@link ISipSession} that carries this call.
diff --git a/voip/java/android/net/sip/SipAudioCallImpl.java b/voip/java/android/net/sip/SipAudioCallImpl.java
index e61e878..ccf4d15 100644
--- a/voip/java/android/net/sip/SipAudioCallImpl.java
+++ b/voip/java/android/net/sip/SipAudioCallImpl.java
@@ -81,7 +81,7 @@
private WifiManager mWm;
private WifiManager.WifiLock mWifiHighPerfLock;
- private SipErrorCode mErrorCode;
+ private int mErrorCode = SipErrorCode.NO_ERROR;
private String mErrorMessage;
public SipAudioCallImpl(Context context, SipProfile localProfile) {
@@ -100,7 +100,7 @@
try {
if ((listener == null) || !callbackImmediately) {
// do nothing
- } else if (mErrorCode != null) {
+ } else if (mErrorCode != SipErrorCode.NO_ERROR) {
listener.onError(this, mErrorCode, mErrorMessage);
} else if (mInCall) {
if (mHold) {
@@ -109,18 +109,18 @@
listener.onCallEstablished(this);
}
} else {
- SipSessionState state = getState();
+ int state = getState();
switch (state) {
- case READY_TO_CALL:
+ case SipSessionState.READY_TO_CALL:
listener.onReadyToCall(this);
break;
- case INCOMING_CALL:
+ case SipSessionState.INCOMING_CALL:
listener.onRinging(this, getPeerProfile(mSipSession));
break;
- case OUTGOING_CALL:
+ case SipSessionState.OUTGOING_CALL:
listener.onCalling(this);
break;
- case OUTGOING_CALL_RING_BACK:
+ case SipSessionState.OUTGOING_CALL_RING_BACK:
listener.onRingingBack(this);
break;
}
@@ -150,7 +150,7 @@
mInCall = false;
mHold = false;
mSessionId = -1L;
- mErrorCode = null;
+ mErrorCode = SipErrorCode.NO_ERROR;
mErrorMessage = null;
if (mSipSession != null) {
@@ -175,10 +175,10 @@
}
}
- public synchronized SipSessionState getState() {
+ public synchronized int getState() {
if (mSipSession == null) return SipSessionState.READY_TO_CALL;
try {
- return Enum.valueOf(SipSessionState.class, mSipSession.getState());
+ return mSipSession.getState();
} catch (RemoteException e) {
return SipSessionState.REMOTE_ERROR;
}
@@ -269,7 +269,6 @@
@Override
public void onCallEnded(ISipSession session) {
Log.d(TAG, "sip call ended: " + session);
- close();
Listener listener = mListener;
if (listener != null) {
try {
@@ -278,12 +277,12 @@
Log.e(TAG, "onCallEnded()", t);
}
}
+ close();
}
@Override
public void onCallBusy(ISipSession session) {
Log.d(TAG, "sip call busy: " + session);
- close(false);
Listener listener = mListener;
if (listener != null) {
try {
@@ -292,17 +291,14 @@
Log.e(TAG, "onCallBusy()", t);
}
}
- }
-
- private SipErrorCode getErrorCode(String errorCode) {
- return Enum.valueOf(SipErrorCode.class, errorCode);
+ close(false);
}
@Override
- public void onCallChangeFailed(ISipSession session, String errorCode,
+ public void onCallChangeFailed(ISipSession session, int errorCode,
String message) {
Log.d(TAG, "sip call change failed: " + message);
- mErrorCode = getErrorCode(errorCode);
+ mErrorCode = errorCode;
mErrorMessage = message;
Listener listener = mListener;
if (listener != null) {
@@ -315,17 +311,11 @@
}
@Override
- public void onError(ISipSession session, String errorCodeString,
- String message) {
- Log.d(TAG, "sip session error: " + errorCodeString + ": " + message);
- SipErrorCode errorCode = mErrorCode = getErrorCode(errorCodeString);
+ public void onError(ISipSession session, int errorCode, String message) {
+ Log.d(TAG, "sip session error: " + SipErrorCode.toString(errorCode)
+ + ": " + message);
+ mErrorCode = errorCode;
mErrorMessage = message;
- synchronized (this) {
- if ((mErrorCode == SipErrorCode.DATA_CONNECTION_LOST)
- || !isInCall()) {
- close(true);
- }
- }
Listener listener = mListener;
if (listener != null) {
try {
@@ -334,6 +324,12 @@
Log.e(TAG, "onError()", t);
}
}
+ synchronized (this) {
+ if ((errorCode == SipErrorCode.DATA_CONNECTION_LOST)
+ || !isInCall()) {
+ close(true);
+ }
+ }
}
public synchronized void attachCall(ISipSession session,
@@ -608,10 +604,10 @@
try {
startAudioInternal();
} catch (UnknownHostException e) {
- onError(mSipSession, SipErrorCode.PEER_NOT_REACHABLE.toString(),
+ onError(mSipSession, SipErrorCode.PEER_NOT_REACHABLE,
e.getMessage());
} catch (Throwable e) {
- onError(mSipSession, SipErrorCode.CLIENT_ERROR.toString(),
+ onError(mSipSession, SipErrorCode.CLIENT_ERROR,
e.getMessage());
}
}
diff --git a/voip/java/android/net/sip/SipErrorCode.java b/voip/java/android/net/sip/SipErrorCode.java
index a27f740..7496d28 100644
--- a/voip/java/android/net/sip/SipErrorCode.java
+++ b/voip/java/android/net/sip/SipErrorCode.java
@@ -24,34 +24,69 @@
* {@link ISipSessionListener#onRegistrationFailed}.
* @hide
*/
-public enum SipErrorCode {
+public class SipErrorCode {
+ /** Not an error. */
+ public static final int NO_ERROR = 0;
+
/** When some socket error occurs. */
- SOCKET_ERROR,
+ public static final int SOCKET_ERROR = -1;
/** When server responds with an error. */
- SERVER_ERROR,
+ public static final int SERVER_ERROR = -2;
/** When transaction is terminated unexpectedly. */
- TRANSACTION_TERMINTED,
+ public static final int TRANSACTION_TERMINTED = -3;
/** When some error occurs on the device, possibly due to a bug. */
- CLIENT_ERROR,
+ public static final int CLIENT_ERROR = -4;
/** When the transaction gets timed out. */
- TIME_OUT,
+ public static final int TIME_OUT = -5;
/** When the remote URI is not valid. */
- INVALID_REMOTE_URI,
+ public static final int INVALID_REMOTE_URI = -6;
/** When the peer is not reachable. */
- PEER_NOT_REACHABLE,
+ public static final int PEER_NOT_REACHABLE = -7;
/** When invalid credentials are provided. */
- INVALID_CREDENTIALS,
+ public static final int INVALID_CREDENTIALS = -8;
/** The client is in a transaction and cannot initiate a new one. */
- IN_PROGRESS,
+ public static final int IN_PROGRESS = -9;
/** When data connection is lost. */
- DATA_CONNECTION_LOST;
+ public static final int DATA_CONNECTION_LOST = -10;
+
+ public static String toString(int errorCode) {
+ switch (errorCode) {
+ case NO_ERROR:
+ return "NO_ERROR";
+ case SOCKET_ERROR:
+ return "SOCKET_ERROR";
+ case SERVER_ERROR:
+ return "SERVER_ERROR";
+ case TRANSACTION_TERMINTED:
+ return "TRANSACTION_TERMINTED";
+ case CLIENT_ERROR:
+ return "CLIENT_ERROR";
+ case TIME_OUT:
+ return "TIME_OUT";
+ case INVALID_REMOTE_URI:
+ return "INVALID_REMOTE_URI";
+ case PEER_NOT_REACHABLE:
+ return "PEER_NOT_REACHABLE";
+ case INVALID_CREDENTIALS:
+ return "INVALID_CREDENTIALS";
+ case IN_PROGRESS:
+ return "IN_PROGRESS";
+ case DATA_CONNECTION_LOST:
+ return "DATA_CONNECTION_LOST";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ private SipErrorCode() {
+ }
}
diff --git a/voip/java/android/net/sip/SipManager.java b/voip/java/android/net/sip/SipManager.java
index 36895cd..31768d7 100644
--- a/voip/java/android/net/sip/SipManager.java
+++ b/voip/java/android/net/sip/SipManager.java
@@ -97,6 +97,14 @@
*/
}
+ /**
+ * Returns true if SIP is only available on WIFI.
+ */
+ public static boolean isSipWifiOnly(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_sip_wifi_only);
+ }
+
private SipManager() {
createSipService();
}
@@ -503,10 +511,9 @@
}
@Override
- public void onRegistrationFailed(ISipSession session, String errorCode,
+ public void onRegistrationFailed(ISipSession session, int errorCode,
String message) {
- mListener.onRegistrationFailed(getUri(session),
- Enum.valueOf(SipErrorCode.class, errorCode), message);
+ mListener.onRegistrationFailed(getUri(session), errorCode, message);
}
@Override
diff --git a/voip/java/android/net/sip/SipRegistrationListener.java b/voip/java/android/net/sip/SipRegistrationListener.java
index 705f271..37c9ce2 100644
--- a/voip/java/android/net/sip/SipRegistrationListener.java
+++ b/voip/java/android/net/sip/SipRegistrationListener.java
@@ -42,7 +42,8 @@
* @param localProfileUri the URI string of the SIP profile to register with
* @param errorCode error code of this error
* @param errorMessage error message
+ * @see SipErrorCode
*/
- void onRegistrationFailed(String localProfileUri, SipErrorCode errorCode,
+ void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage);
}
diff --git a/voip/java/android/net/sip/SipSessionAdapter.java b/voip/java/android/net/sip/SipSessionAdapter.java
index 6020f2c..86aca37 100644
--- a/voip/java/android/net/sip/SipSessionAdapter.java
+++ b/voip/java/android/net/sip/SipSessionAdapter.java
@@ -42,11 +42,11 @@
public void onCallBusy(ISipSession session) {
}
- public void onCallChangeFailed(ISipSession session, String errorCode,
+ public void onCallChangeFailed(ISipSession session, int errorCode,
String message) {
}
- public void onError(ISipSession session, String errorCode, String message) {
+ public void onError(ISipSession session, int errorCode, String message) {
}
public void onRegistering(ISipSession session) {
@@ -55,7 +55,7 @@
public void onRegistrationDone(ISipSession session, int duration) {
}
- public void onRegistrationFailed(ISipSession session, String errorCode,
+ public void onRegistrationFailed(ISipSession session, int errorCode,
String message) {
}
diff --git a/voip/java/android/net/sip/SipSessionState.java b/voip/java/android/net/sip/SipSessionState.java
index 5bab112..31e9d3f 100644
--- a/voip/java/android/net/sip/SipSessionState.java
+++ b/voip/java/android/net/sip/SipSessionState.java
@@ -20,47 +20,75 @@
* Defines {@link ISipSession} states.
* @hide
*/
-public enum SipSessionState {
+public class SipSessionState {
/** When session is ready to initiate a call or transaction. */
- READY_TO_CALL,
+ public static final int READY_TO_CALL = 0;
/** When the registration request is sent out. */
- REGISTERING,
+ public static final int REGISTERING = 1;
/** When the unregistration request is sent out. */
- DEREGISTERING,
+ public static final int DEREGISTERING = 2;
/** When an INVITE request is received. */
- INCOMING_CALL,
+ public static final int INCOMING_CALL = 3;
/** When an OK response is sent for the INVITE request received. */
- INCOMING_CALL_ANSWERING,
+ public static final int INCOMING_CALL_ANSWERING = 4;
/** When an INVITE request is sent. */
- OUTGOING_CALL,
+ public static final int OUTGOING_CALL = 5;
/** When a RINGING response is received for the INVITE request sent. */
- OUTGOING_CALL_RING_BACK,
+ public static final int OUTGOING_CALL_RING_BACK = 6;
/** When a CANCEL request is sent for the INVITE request sent. */
- OUTGOING_CALL_CANCELING,
+ public static final int OUTGOING_CALL_CANCELING = 7;
/** When a call is established. */
- IN_CALL,
+ public static final int IN_CALL = 8;
/** Some error occurs when making a remote call to {@link ISipSession}. */
- REMOTE_ERROR,
+ public static final int REMOTE_ERROR = 9;
/** When an OPTIONS request is sent. */
- PINGING;
+ public static final int PINGING = 10;
+
+ /** Not defined. */
+ public static final int NOT_DEFINED = 101;
/**
- * Checks if the specified string represents the same state as this object.
- *
- * @return true if the specified string represents the same state as this
- * object
+ * Converts the state to string.
*/
- public boolean equals(String state) {
- return toString().equals(state);
+ public static String toString(int state) {
+ switch (state) {
+ case READY_TO_CALL:
+ return "READY_TO_CALL";
+ case REGISTERING:
+ return "REGISTERING";
+ case DEREGISTERING:
+ return "DEREGISTERING";
+ case INCOMING_CALL:
+ return "INCOMING_CALL";
+ case INCOMING_CALL_ANSWERING:
+ return "INCOMING_CALL_ANSWERING";
+ case OUTGOING_CALL:
+ return "OUTGOING_CALL";
+ case OUTGOING_CALL_RING_BACK:
+ return "OUTGOING_CALL_RING_BACK";
+ case OUTGOING_CALL_CANCELING:
+ return "OUTGOING_CALL_CANCELING";
+ case IN_CALL:
+ return "IN_CALL";
+ case REMOTE_ERROR:
+ return "REMOTE_ERROR";
+ case PINGING:
+ return "PINGING";
+ default:
+ return "NOT_DEFINED";
+ }
+ }
+
+ private SipSessionState() {
}
}