diff options
15 files changed, 358 insertions, 89 deletions
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp index 1dc08ea2dc1d..74649a9bf36e 100644 --- a/cmds/stagefright/sf2.cpp +++ b/cmds/stagefright/sf2.cpp @@ -170,6 +170,7 @@ protected: mCodec->signalResume(); (new AMessage(kWhatSeek, id()))->post(5000000ll); + } else if (what == ACodec::kWhatOutputFormatChanged) { } else { CHECK_EQ(what, (int32_t)ACodec::kWhatShutdownCompleted); diff --git a/core/java/android/net/dhcp/DhcpAckPacket.java b/core/java/android/net/dhcp/DhcpAckPacket.java index 900a0e6987c5..4eca5317ca78 100644 --- a/core/java/android/net/dhcp/DhcpAckPacket.java +++ b/core/java/android/net/dhcp/DhcpAckPacket.java @@ -33,7 +33,7 @@ class DhcpAckPacket extends DhcpPacket { DhcpAckPacket(int transId, boolean broadcast, InetAddress serverAddress, InetAddress clientIp, byte[] clientMac) { - super(transId, Inet4Address.ANY, clientIp, Inet4Address.ANY, + super(transId, Inet4Address.ANY, clientIp, serverAddress, Inet4Address.ANY, clientMac, broadcast); mBroadcast = broadcast; mSrcIp = serverAddress; diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index 1a351122b05e..62f66b6ce799 100755..100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -1723,6 +1723,21 @@ public final class Telephony { public static final String TYPE = "type"; + /** + * The protocol to be used to connect to this APN. + * + * One of the PDP_type values in TS 27.007 section 10.1.1. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + */ + public static final String PROTOCOL = "protocol"; + + /** + * The protocol to be used to connect to this APN when roaming. + * + * The syntax is the same as protocol. + */ + public static final String ROAMING_PROTOCOL = "roaming_protocol"; + public static final String CURRENT = "current"; } diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 4599d70d1faf..a9697962e3ca 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -109,7 +109,7 @@ private: status_t allocateOutputBuffersFromNativeWindow(); status_t cancelBufferToNativeWindow(BufferInfo *info); - status_t freeOutputBuffersOwnedByNativeWindow(); + status_t freeOutputBuffersNotOwnedByComponent(); BufferInfo *dequeueBufferFromNativeWindow(); BufferInfo *findBufferByID( diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index dfb4e000e6bf..505d9d46ab98 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -197,6 +197,9 @@ struct ACodec::ExecutingState : public ACodec::BaseState { // to fill with data. void resume(); + // Returns true iff input and output buffers are in play. + bool active() const { return mActive; } + protected: virtual PortMode getPortMode(OMX_U32 portIndex); virtual bool onMessageReceived(const sp<AMessage> &msg); @@ -205,6 +208,8 @@ protected: virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); private: + bool mActive; + DISALLOW_EVIL_CONSTRUCTORS(ExecutingState); }; @@ -564,13 +569,17 @@ status_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) { return OK; } -status_t ACodec::freeOutputBuffersOwnedByNativeWindow() { +status_t ACodec::freeOutputBuffersNotOwnedByComponent() { for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) { BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); - if (info->mStatus == - BufferInfo::OWNED_BY_NATIVE_WINDOW) { + if (info->mStatus != + BufferInfo::OWNED_BY_COMPONENT) { + // We shouldn't have sent out any buffers to the client at this + // point. + CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM); + CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i)); } } @@ -1195,6 +1204,9 @@ bool ACodec::BaseState::onOMXEvent( } bool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) { + LOGV("[%s] onOMXEmptyBufferDone %p", + mCodec->mComponentName.c_str(), bufferID); + BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID); @@ -1295,7 +1307,7 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { } if (buffer != info->mData) { - if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) { + if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) { LOGV("[%s] Needs to copy input data.", mCodec->mComponentName.c_str()); } @@ -1304,6 +1316,9 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { memcpy(info->mData->data(), buffer->data(), buffer->size()); } + LOGV("[%s] calling emptyBuffer %p", + mCodec->mComponentName.c_str(), bufferID); + CHECK_EQ(mCodec->mOMX->emptyBuffer( mCodec->mNode, bufferID, @@ -1320,6 +1335,9 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { LOGV("[%s] Signalling EOS on the input port", mCodec->mComponentName.c_str()); + LOGV("[%s] calling emptyBuffer %p", + mCodec->mComponentName.c_str(), bufferID); + CHECK_EQ(mCodec->mOMX->emptyBuffer( mCodec->mNode, bufferID, @@ -1378,6 +1396,9 @@ bool ACodec::BaseState::onOMXFillBufferDone( int64_t timeUs, void *platformPrivate, void *dataPtr) { + LOGV("[%s] onOMXFillBufferDone %p", + mCodec->mComponentName.c_str(), bufferID); + ssize_t index; BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index); @@ -1396,6 +1417,9 @@ bool ACodec::BaseState::onOMXFillBufferDone( { if (rangeLength == 0) { if (!(flags & OMX_BUFFERFLAG_EOS)) { + LOGV("[%s] calling fillBuffer %p", + mCodec->mComponentName.c_str(), info->mBufferID); + CHECK_EQ(mCodec->mOMX->fillBuffer( mCodec->mNode, info->mBufferID), (status_t)OK); @@ -1503,6 +1527,9 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { info = mCodec->dequeueBufferFromNativeWindow(); } + LOGV("[%s] calling fillBuffer %p", + mCodec->mComponentName.c_str(), info->mBufferID); + CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), (status_t)OK); @@ -1600,6 +1627,9 @@ void ACodec::UninitializedState::onSetup( mCodec->mOMX = omx; mCodec->mNode = node; + mCodec->mPortEOS[kPortIndexInput] = + mCodec->mPortEOS[kPortIndexOutput] = false; + mCodec->configureCodec(mime.c_str(), msg); sp<RefBase> obj; @@ -1717,7 +1747,8 @@ bool ACodec::IdleToExecutingState::onOMXEvent( //////////////////////////////////////////////////////////////////////////////// ACodec::ExecutingState::ExecutingState(ACodec *codec) - : BaseState(codec) { + : BaseState(codec), + mActive(false) { } ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode( @@ -1745,6 +1776,9 @@ void ACodec::ExecutingState::submitOutputBuffers() { CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); } + LOGV("[%s] calling fillBuffer %p", + mCodec->mComponentName.c_str(), info->mBufferID); + CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID), (status_t)OK); @@ -1753,6 +1787,13 @@ void ACodec::ExecutingState::submitOutputBuffers() { } void ACodec::ExecutingState::resume() { + if (mActive) { + LOGV("[%s] We're already active, no need to resume.", + mCodec->mComponentName.c_str()); + + return; + } + submitOutputBuffers(); // Post the first input buffer. @@ -1760,6 +1801,8 @@ void ACodec::ExecutingState::resume() { BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0); postFillThisBuffer(info); + + mActive = true; } void ACodec::ExecutingState::stateEntered() { @@ -1774,6 +1817,8 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatShutdown: { + mActive = false; + CHECK_EQ(mCodec->mOMX->sendCommand( mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle), (status_t)OK); @@ -1786,6 +1831,8 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) { case kWhatFlush: { + mActive = false; + CHECK_EQ(mCodec->mOMX->sendCommand( mCodec->mNode, OMX_CommandFlush, OMX_ALL), (status_t)OK); @@ -1825,10 +1872,7 @@ bool ACodec::ExecutingState::onOMXEvent( OMX_CommandPortDisable, kPortIndexOutput), (status_t)OK); - if (mCodec->mNativeWindow != NULL) { - CHECK_EQ((status_t)OK, - mCodec->freeOutputBuffersOwnedByNativeWindow()); - } + mCodec->freeOutputBuffersNotOwnedByComponent(); mCodec->changeState(mCodec->mOutputPortSettingsChangedState); } else if (data2 == OMX_IndexConfigCommonOutputCrop) { @@ -1876,7 +1920,12 @@ bool ACodec::OutputPortSettingsChangedState::onMessageReceived( switch (msg->what()) { case kWhatFlush: case kWhatShutdown: + case kWhatResume: { + if (msg->what() == kWhatResume) { + LOGV("[%s] Deferring resume", mCodec->mComponentName.c_str()); + } + mCodec->deferMessage(msg); handled = true; break; @@ -1925,7 +1974,10 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( LOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str()); - mCodec->mExecutingState->submitOutputBuffers(); + if (mCodec->mExecutingState->active()) { + mCodec->mExecutingState->submitOutputBuffers(); + } + mCodec->changeState(mCodec->mExecutingState); return true; @@ -1992,6 +2044,13 @@ bool ACodec::ExecutingToIdleState::onOMXEvent( return true; } + case OMX_EventPortSettingsChanged: + case OMX_EventBufferFlag: + { + // We're shutting down and don't care about this anymore. + return true; + } + default: return BaseState::onOMXEvent(event, data1, data2); } @@ -2170,6 +2229,23 @@ bool ACodec::FlushingState::onOMXEvent( return true; } + case OMX_EventPortSettingsChanged: + { + sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id()); + msg->setInt32("type", omx_message::EVENT); + msg->setPointer("node", mCodec->mNode); + msg->setInt32("event", event); + msg->setInt32("data1", data1); + msg->setInt32("data2", data2); + + LOGV("[%s] Deferring OMX_EventPortSettingsChanged", + mCodec->mComponentName.c_str()); + + mCodec->deferMessage(msg); + + return true; + } + default: return BaseState::onOMXEvent(event, data1, data2); } diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index b04672d7d6fe..953ddacd7c5a 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -488,13 +488,6 @@ status_t AudioPolicyService::onTransact( // ---------------------------------------------------------------------------- -void AudioPolicyService::instantiate() { - defaultServiceManager()->addService( - String16("media.audio_policy"), new AudioPolicyService()); -} - - -// ---------------------------------------------------------------------------- // AudioPolicyClientInterface implementation // ---------------------------------------------------------------------------- diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h index 54af1f1e0265..4749b8b4f610 100644 --- a/services/audioflinger/AudioPolicyService.h +++ b/services/audioflinger/AudioPolicyService.h @@ -21,6 +21,7 @@ #include <hardware_legacy/AudioPolicyInterface.h> #include <media/ToneGenerator.h> #include <utils/Vector.h> +#include <binder/BinderService.h> namespace android { @@ -28,12 +29,17 @@ class String8; // ---------------------------------------------------------------------------- -class AudioPolicyService: public BnAudioPolicyService, public AudioPolicyClientInterface, +class AudioPolicyService : + public BinderService<AudioPolicyService>, + public BnAudioPolicyService, + public AudioPolicyClientInterface, public IBinder::DeathRecipient { + friend class BinderService<AudioPolicyService>; public: - static void instantiate(); + // for BinderService + static const char *getServiceName() { return "media.audio_policy"; } virtual status_t dump(int fd, const Vector<String16>& args); @@ -241,11 +247,3 @@ private: }; // namespace android #endif // ANDROID_AUDIOPOLICYSERVICE_H - - - - - - - - diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 31866bca3270..c51e4a6fc5de 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -285,6 +285,8 @@ public class WindowManagerService extends IWindowManager.Stub final IBatteryStats mBatteryStats; + private static final boolean mInEmulator = SystemProperties.get("ro.kernel.qemu").equals("1"); + /** * All currently active sessions with clients. */ @@ -5186,7 +5188,9 @@ public class WindowManagerService extends IWindowManager.Stub public void setRotationUnchecked(int rotation, boolean alwaysSendConfiguration, int animFlags) { if(DEBUG_ORIENTATION) Slog.v(TAG, - "alwaysSendConfiguration set to "+alwaysSendConfiguration); + "setRotationUnchecked(rotation=" + rotation + + " alwaysSendConfiguration=" + alwaysSendConfiguration + + " animFlags=" + animFlags); long origId = Binder.clearCallingIdentity(); boolean changed; @@ -5257,7 +5261,9 @@ public class WindowManagerService extends IWindowManager.Stub Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags); mInputManager.setDisplayOrientation(0, rotation); if (mDisplayEnabled) { - if (CUSTOM_SCREEN_ROTATION) { + // NOTE: We disable the rotation in the emulator because + // it doesn't support hardware OpenGL emulation yet. + if (CUSTOM_SCREEN_ROTATION && !mInEmulator) { Surface.freezeDisplay(0); if (!inTransaction) { if (SHOW_TRANSACTIONS) Slog.i(TAG, diff --git a/telephony/java/com/android/internal/telephony/ApnSetting.java b/telephony/java/com/android/internal/telephony/ApnSetting.java index 5af8e355ae57..20dbaf3a2353 100644 --- a/telephony/java/com/android/internal/telephony/ApnSetting.java +++ b/telephony/java/com/android/internal/telephony/ApnSetting.java @@ -21,6 +21,8 @@ package com.android.internal.telephony; */ public class ApnSetting { + static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*"; + public String carrier; public String apn; public String proxy; @@ -34,11 +36,14 @@ public class ApnSetting { public String[] types; public int id; public String numeric; + public String protocol; + public String roamingProtocol; - - public ApnSetting(int id, String numeric, String carrier, String apn, String proxy, String port, + public ApnSetting(int id, String numeric, String carrier, String apn, + String proxy, String port, String mmsc, String mmsProxy, String mmsPort, - String user, String password, int authType, String[] types) { + String user, String password, int authType, String[] types, + String protocol, String roamingProtocol) { this.id = id; this.numeric = numeric; this.carrier = carrier; @@ -52,40 +57,81 @@ public class ApnSetting { this.password = password; this.authType = authType; this.types = types; + this.protocol = protocol; + this.roamingProtocol = roamingProtocol; } - // data[0] = name - // data[1] = apn - // data[2] = proxy - // data[3] = port - // data[4] = username - // data[5] = password - // data[6] = server - // data[7] = mmsc - // data[8] = mmsproxy - // data[9] = mmsport - // data[10] = mcc - // data[11] = mnc - // data[12] = auth - // data[13] = first type... + /** + * Creates an ApnSetting object from a string. + * + * @param data the string to read. + * + * The string must be in one of two formats (newlines added for clarity, + * spaces are optional): + * + * v1 format: + * <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>, + * <mmsport>, <user>, <password>, <authtype>, <mcc>,<mnc>, + * <type>[, <type>...] + * + * v2 format: + * [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>, + * <mmsport>, <user>, <password, <authtype>, <mcc>, <mnc>, + * <type>[| <type>...], <protocol>, <roaming_protocol> + * + * Note that the strings generated by toString() do not contain the username + * and password and thus cannot be read by this method. + * + * @see ApnSettingTest + */ public static ApnSetting fromString(String data) { if (data == null) return null; + + int version; + // matches() operates on the whole string, so append .* to the regex. + if (data.matches(V2_FORMAT_REGEX + ".*")) { + version = 2; + data = data.replaceFirst(V2_FORMAT_REGEX, ""); + } else { + version = 1; + } + String[] a = data.split("\\s*,\\s*"); - if (a.length < 14) return null; - int authType = 0; + if (a.length < 14) { + return null; + } + + int authType; try { authType = Integer.parseInt(a[12]); } catch (Exception e) { + authType = 0; } - String[] typeArray = new String[a.length - 13]; - System.arraycopy(a, 13, typeArray, 0, a.length - 13); + + String[] typeArray; + String protocol, roamingProtocol; + if (version == 1) { + typeArray = new String[a.length - 13]; + System.arraycopy(a, 13, typeArray, 0, a.length - 13); + protocol = RILConstants.SETUP_DATA_PROTOCOL_IP; + roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP; + } else { + if (a.length < 16) { + return null; + } + typeArray = a[13].split("\\s*\\|\\s*"); + protocol = a[14]; + roamingProtocol = a[15]; + } + return new ApnSetting(-1,a[10]+a[11],a[0],a[1],a[2],a[3],a[7],a[8], - a[9],a[4],a[5],authType,typeArray); + a[9],a[4],a[5],authType,typeArray,protocol,roamingProtocol); } public String toString() { StringBuilder sb = new StringBuilder(); - sb.append(carrier) + sb.append("[ApnSettingV2] ") + .append(carrier) .append(", ").append(id) .append(", ").append(numeric) .append(", ").append(apn) @@ -94,10 +140,15 @@ public class ApnSetting { .append(", ").append(mmsProxy) .append(", ").append(mmsPort) .append(", ").append(port) - .append(", ").append(authType); - for (String t : types) { - sb.append(", ").append(t); + .append(", ").append(authType).append(", "); + for (int i = 0; i < types.length; i++) { + sb.append(types[i]); + if (i < types.length - 1) { + sb.append(" | "); + } } + sb.append(", ").append(protocol); + sb.append(", ").append(roamingProtocol); return sb.toString(); } diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index 31c89d079efb..aa9c4a37c08d 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -401,22 +401,26 @@ public abstract class DataConnection extends HierarchicalStateMachine { try { cid = response.cid; linkProperties.setInterfaceName(response.ifname); - for (String addr : response.addresses) { - LinkAddress la; - if (!InetAddress.isNumeric(addr)) { - EventLogTags.writeBadIpAddress(addr); - throw new UnknownHostException("Non-numeric ip addr=" + addr); - } - InetAddress ia = InetAddress.getByName(addr); - if (ia instanceof Inet4Address) { - la = new LinkAddress(ia, 32); - } else { - la = new LinkAddress(ia, 128); + if (response.addresses != null && response.addresses.length > 0) { + for (String addr : response.addresses) { + LinkAddress la; + if (!InetAddress.isNumeric(addr)) { + EventLogTags.writeBadIpAddress(addr); + throw new UnknownHostException("Non-numeric ip addr=" + addr); + } + InetAddress ia = InetAddress.getByName(addr); + if (ia instanceof Inet4Address) { + la = new LinkAddress(ia, 32); + } else { + la = new LinkAddress(ia, 128); + } + linkProperties.addLinkAddress(la); } - linkProperties.addLinkAddress(la); + } else { + EventLogTags.writeBadIpAddress("no address for ifname=" + response.ifname); + throw new UnknownHostException("no address for ifname=" + response.ifname); } - - if (response.dnses.length != 0) { + if (response.dnses != null && response.dnses.length > 0) { for (String addr : response.dnses) { if (!InetAddress.isNumeric(addr)) { EventLogTags.writePdpBadDnsAddress("dns=" + addr); diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index dbc489a08ebe..3ef1924c55a2 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -44,6 +44,7 @@ import android.telephony.NeighboringCellInfo; import android.telephony.PhoneNumberUtils; import android.telephony.SmsManager; import android.telephony.SmsMessage; +import android.text.TextUtils; import android.util.Config; import android.util.Log; @@ -2945,7 +2946,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { dataCall.type = p.readString(); p.readString(); // Ignore apn String addresses = p.readString(); - if (addresses != null) { + if (TextUtils.isEmpty(addresses)) { dataCall.addresses = addresses.split(" "); } } else { @@ -2954,12 +2955,15 @@ public final class RIL extends BaseCommands implements CommandsInterface { dataCall.active = p.readInt(); dataCall.type = p.readString(); dataCall.ifname = p.readString(); + if (TextUtils.isEmpty(dataCall.ifname)) { + throw new RuntimeException("getDataCallState, no ifname"); + } String addresses = p.readString(); - if (addresses != null) { + if (!TextUtils.isEmpty(addresses)) { dataCall.addresses = addresses.split(" "); } String dnses = p.readString(); - if (addresses != null) { + if (!TextUtils.isEmpty(dnses)) { dataCall.dnses = dnses.split(" "); } } @@ -2991,23 +2995,25 @@ public final class RIL extends BaseCommands implements CommandsInterface { DataCallState dataCall; if (ver < 5) { - if (num != 3) { - throw new RuntimeException( - "RIL_REQUEST_SETUP_DATA_CALL response expecting 3 strings got " + num); - } dataCall = new DataCallState(); + dataCall.version = ver; dataCall.cid = Integer.parseInt(p.readString()); dataCall.ifname = p.readString(); - if (dataCall.ifname == null) { + if (TextUtils.isEmpty(dataCall.ifname)) { throw new RuntimeException( - "RIL_REQUEST_SETUP_DATA_CALL response ifname"); + "RIL_REQUEST_SETUP_DATA_CALL response, no ifname"); } String addresses = p.readString(); - if (addresses == null) { - throw new RuntimeException( - "RIL_REQUEST_SETUP_DATA_CALL response no addresses"); + if (!TextUtils.isEmpty(addresses)) { + dataCall.addresses = addresses.split(" "); + } + if (num >= 4) { + String dnses = p.readString(); + Log.d(LOG_TAG, "responseSetupDataCall got dnses=" + dnses); + if (!TextUtils.isEmpty(dnses)) { + dataCall.dnses = dnses.split(" "); + } } - dataCall.addresses = addresses.split(" "); } else { if (num != 1) { throw new RuntimeException( diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 60df7dfe0f45..c324a717207f 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -336,7 +336,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { types = mDefaultApnTypes; apnId = mDefaultApnId; } - mActiveApn = new ApnSetting(apnId, "", "", "", "", "", "", "", "", "", "", 0, types); + mActiveApn = new ApnSetting(apnId, "", "", "", "", "", "", "", "", "", + "", 0, types, "IP", "IP"); if (DBG) log("setupData: mActiveApn=" + mActiveApn); Message msg = obtainMessage(); diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java index 1d60bdae1e69..4689b2d38630 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java @@ -92,12 +92,19 @@ public class GsmDataConnection extends DataConnection { authType = (apn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP : RILConstants.SETUP_DATA_AUTH_NONE; } + + String protocol; + if (phone.getServiceState().getRoaming()) { + protocol = apn.roamingProtocol; + } else { + protocol = apn.protocol; + } + phone.mCM.setupDataCall( Integer.toString(RILConstants.SETUP_DATA_TECH_GSM), Integer.toString(RILConstants.DATA_PROFILE_DEFAULT), - apn.apn, apn.user, apn.password, - Integer.toString(authType), - RILConstants.SETUP_DATA_PROTOCOL_IP, msg); + apn.apn, apn.user, apn.password, Integer.toString(authType), + protocol, msg); } @Override diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index cd0d9e392a87..f2cdf0c3066a 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -432,7 +432,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)), cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)), cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)), - types); + types, + cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)), + cursor.getString(cursor.getColumnIndexOrThrow( + Telephony.Carriers.ROAMING_PROTOCOL))); result.add(apn); } while (cursor.moveToNext()); } diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java new file mode 100644 index 000000000000..10320743e253 --- /dev/null +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * 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.android.internal.telephony; + +import junit.framework.TestCase; + +import android.test.suitebuilder.annotation.SmallTest; + +public class ApnSettingTest extends TestCase { + + public static final String[] TYPES = {"default", "*"}; + + public static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) { + assertEquals(a1.carrier, a2.carrier); + assertEquals(a1.apn, a2.apn); + assertEquals(a1.proxy, a2.proxy); + assertEquals(a1.port, a2.port); + assertEquals(a1.mmsc, a2.mmsc); + assertEquals(a1.mmsProxy, a2.mmsProxy); + assertEquals(a1.mmsPort, a2.mmsPort); + assertEquals(a1.user, a2.user); + assertEquals(a1.password, a2.password); + assertEquals(a1.authType, a2.authType); + assertEquals(a1.id, a2.id); + assertEquals(a1.numeric, a2.numeric); + assertEquals(a1.protocol, a2.protocol); + assertEquals(a1.roamingProtocol, a2.roamingProtocol); + assertEquals(a1.types.length, a2.types.length); + int i; + for (i = 0; i < a1.types.length; i++) { + assertEquals(a1.types[i], a2.types[i]); + } + } + + @SmallTest + public void testFromString() throws Exception { + String[] dunTypes = {"DUN"}; + String[] mmsTypes = {"mms", "*"}; + + ApnSetting expected_apn; + String testString; + + // A real-world v1 example string. + testString = "Vodafone IT,web.omnitel.it,,,,,,,,,222,10,,DUN"; + expected_apn = new ApnSetting( + -1, "22210", "Vodafone IT", "web.omnitel.it", "", "", + "", "", "", "", "", 0, dunTypes, "IP", "IP"); + assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); + + // A v2 string. + testString = "[ApnSettingV2] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP"; + expected_apn = new ApnSetting( + -1, "12345", "Name", "apn", "", "", + "", "", "", "", "", 0, mmsTypes, "IPV6", "IP"); + assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); + + // A v2 string with spaces. + testString = "[ApnSettingV2] Name,apn, ,,,,,,,,123,45,,mms|*,IPV4V6, IP"; + expected_apn = new ApnSetting( + -1, "12345", "Name", "apn", "", "", + "", "", "", "", "", 0, mmsTypes, "IPV4V6", "IP"); + assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); + + // Return null if insufficient fields given. + testString = "[ApnSettingV2] Name,apn,,,,,,,,,123, 45,,mms|*"; + assertEquals(null, ApnSetting.fromString(testString)); + + testString = "Name,apn,,,,,,,,,123, 45,"; + assertEquals(null, ApnSetting.fromString(testString)); + + // Parse (incorrect) V2 format without the tag as V1. + testString = "Name,apn,,,,,,,,,123, 45,,mms|*,IPV6"; + String[] incorrectTypes = {"mms|*", "IPV6"}; + expected_apn = new ApnSetting( + -1, "12345", "Name", "apn", "", "", + "", "", "", "", "", 0, incorrectTypes, "IP", "IP"); + assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString)); + } + + + @SmallTest + public void testToString() throws Exception { + String[] types = {"default", "*"}; + ApnSetting apn = new ApnSetting( + 99, "12345", "Name", "apn", "proxy", "port", + "mmsc", "mmsproxy", "mmsport", "user", "password", 0, + types, "IPV4V6", "IP"); + String expected = "[ApnSettingV2] Name, 99, 12345, apn, proxy, " + + "mmsc, mmsproxy, mmsport, port, 0, default | *, " + + "IPV4V6, IP"; + assertEquals(expected, apn.toString()); + } +} + |