summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/sf2.cpp1
-rw-r--r--core/java/android/net/dhcp/DhcpAckPacket.java2
-rw-r--r--[-rwxr-xr-x]core/java/android/provider/Telephony.java15
-rw-r--r--include/media/stagefright/ACodec.h2
-rw-r--r--media/libstagefright/ACodec.cpp96
-rw-r--r--services/audioflinger/AudioPolicyService.cpp7
-rw-r--r--services/audioflinger/AudioPolicyService.h18
-rw-r--r--services/java/com/android/server/WindowManagerService.java10
-rw-r--r--telephony/java/com/android/internal/telephony/ApnSetting.java103
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java32
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java32
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java3
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java13
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java5
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java108
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());
+ }
+}
+