Merge "Add RouteInfo objects for tracking routes." into honeycomb-LTE
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 9e6bcc8..6570078 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -109,7 +109,10 @@
run_command("NETWORK INTERFACES", 10, "su", "root", "netcfg", NULL);
dump_file("NETWORK ROUTES", "/proc/net/route");
+ dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
dump_file("ARP CACHE", "/proc/net/arp");
+ run_command("IPTABLES", 10, "su", "root", "iptables", "-L", NULL);
+ run_command("IPTABLE NAT", 10, "su", "root", "iptables", "-t", "nat", "-L", NULL);
run_command("WIFI NETWORKS", 20,
"su", "root", "wpa_cli", "list_networks", NULL);
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
new file mode 100644
index 0000000..eaf087f
--- /dev/null
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2011 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 android.net;
+
+import com.android.internal.util.Protocol;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.DhcpInfoInternal;
+import android.net.NetworkUtils;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.Log;
+
+/**
+ * StateMachine that interacts with the native DHCP client and can talk to
+ * a controller that also needs to be a StateMachine
+ *
+ * The Dhcp state machine provides the following features:
+ * - Wakeup and renewal using the native DHCP client (which will not renew
+ * on its own when the device is in suspend state and this can lead to device
+ * holding IP address beyond expiry)
+ * - A notification right before DHCP request or renewal is started. This
+ * can be used for any additional setup before DHCP. For example, wifi sets
+ * BT-Wifi coex settings right before DHCP is initiated
+ *
+ * @hide
+ */
+public class DhcpStateMachine extends StateMachine {
+
+ private static final String TAG = "DhcpStateMachine";
+ private static final boolean DBG = false;
+
+
+ /* A StateMachine that controls the DhcpStateMachine */
+ private StateMachine mController;
+
+ private Context mContext;
+ private BroadcastReceiver mBroadcastReceiver;
+ private AlarmManager mAlarmManager;
+ private PendingIntent mDhcpRenewalIntent;
+ private PowerManager.WakeLock mDhcpRenewWakeLock;
+ private static final String WAKELOCK_TAG = "DHCP";
+
+ private static final int DHCP_RENEW = 0;
+ private static final String ACTION_DHCP_RENEW = "android.net.wifi.DHCP_RENEW";
+
+ private enum DhcpAction {
+ START,
+ RENEW
+ };
+
+ private String mInterfaceName;
+ private boolean mRegisteredForPreDhcpNotification = false;
+
+ private static final int BASE = Protocol.BASE_DHCP;
+
+ /* Commands from controller to start/stop DHCP */
+ public static final int CMD_START_DHCP = BASE + 1;
+ public static final int CMD_STOP_DHCP = BASE + 2;
+ public static final int CMD_RENEW_DHCP = BASE + 3;
+
+ /* Notification from DHCP state machine prior to DHCP discovery/renewal */
+ public static final int CMD_PRE_DHCP_ACTION = BASE + 4;
+ /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
+ * success/failure */
+ public static final int CMD_POST_DHCP_ACTION = BASE + 5;
+
+ /* Command from controller to indicate DHCP discovery/renewal can continue
+ * after pre DHCP action is complete */
+ public static final int CMD_PRE_DHCP_ACTION_COMPLETE = BASE + 6;
+
+ /* Message.arg1 arguments to CMD_POST_DHCP notification */
+ public static final int DHCP_SUCCESS = 1;
+ public static final int DHCP_FAILURE = 2;
+
+ private State mDefaultState = new DefaultState();
+ private State mStoppedState = new StoppedState();
+ private State mWaitBeforeStartState = new WaitBeforeStartState();
+ private State mRunningState = new RunningState();
+ private State mWaitBeforeRenewalState = new WaitBeforeRenewalState();
+
+ private DhcpStateMachine(Context context, StateMachine controller, String intf) {
+ super(TAG);
+
+ mContext = context;
+ mController = controller;
+ mInterfaceName = intf;
+
+ mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+ Intent dhcpRenewalIntent = new Intent(ACTION_DHCP_RENEW, null);
+ mDhcpRenewalIntent = PendingIntent.getBroadcast(mContext, DHCP_RENEW, dhcpRenewalIntent, 0);
+
+ PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+ mDhcpRenewWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
+
+ mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ //DHCP renew
+ if (DBG) Log.d(TAG, "Sending a DHCP renewal " + this);
+ //acquire a 40s wakelock to finish DHCP renewal
+ mDhcpRenewWakeLock.acquire(40000);
+ sendMessage(CMD_RENEW_DHCP);
+ }
+ };
+ mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_DHCP_RENEW));
+
+ addState(mDefaultState);
+ addState(mStoppedState, mDefaultState);
+ addState(mWaitBeforeStartState, mDefaultState);
+ addState(mRunningState, mDefaultState);
+ addState(mWaitBeforeRenewalState, mDefaultState);
+
+ setInitialState(mStoppedState);
+ }
+
+ public static DhcpStateMachine makeDhcpStateMachine(Context context, StateMachine controller,
+ String intf) {
+ DhcpStateMachine dsm = new DhcpStateMachine(context, controller, intf);
+ dsm.start();
+ return dsm;
+ }
+
+ /**
+ * This sends a notification right before DHCP request/renewal so that the
+ * controller can do certain actions before DHCP packets are sent out.
+ * When the controller is ready, it sends a CMD_PRE_DHCP_ACTION_COMPLETE message
+ * to indicate DHCP can continue
+ *
+ * This is used by Wifi at this time for the purpose of doing BT-Wifi coex
+ * handling during Dhcp
+ */
+ public void registerForPreDhcpNotification() {
+ mRegisteredForPreDhcpNotification = true;
+ }
+
+ class DefaultState extends State {
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case CMD_RENEW_DHCP:
+ Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
+ break;
+ case SM_QUIT_CMD:
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ //let parent kill the state machine
+ return NOT_HANDLED;
+ default:
+ Log.e(TAG, "Error! unhandled message " + message);
+ break;
+ }
+ return HANDLED;
+ }
+ }
+
+
+ class StoppedState extends State {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = HANDLED;
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case CMD_START_DHCP:
+ if (mRegisteredForPreDhcpNotification) {
+ /* Notify controller before starting DHCP */
+ mController.sendMessage(CMD_PRE_DHCP_ACTION);
+ transitionTo(mWaitBeforeStartState);
+ } else {
+ if (runDhcp(DhcpAction.START)) {
+ transitionTo(mRunningState);
+ }
+ }
+ break;
+ case CMD_STOP_DHCP:
+ //ignore
+ break;
+ default:
+ retValue = NOT_HANDLED;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class WaitBeforeStartState extends State {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = HANDLED;
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case CMD_PRE_DHCP_ACTION_COMPLETE:
+ if (runDhcp(DhcpAction.START)) {
+ transitionTo(mRunningState);
+ } else {
+ transitionTo(mStoppedState);
+ }
+ break;
+ case CMD_STOP_DHCP:
+ transitionTo(mStoppedState);
+ break;
+ case CMD_START_DHCP:
+ //ignore
+ break;
+ default:
+ retValue = NOT_HANDLED;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class RunningState extends State {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = HANDLED;
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case CMD_STOP_DHCP:
+ mAlarmManager.cancel(mDhcpRenewalIntent);
+ if (!NetworkUtils.stopDhcp(mInterfaceName)) {
+ Log.e(TAG, "Failed to stop Dhcp on " + mInterfaceName);
+ }
+ transitionTo(mStoppedState);
+ break;
+ case CMD_RENEW_DHCP:
+ if (mRegisteredForPreDhcpNotification) {
+ /* Notify controller before starting DHCP */
+ mController.sendMessage(CMD_PRE_DHCP_ACTION);
+ transitionTo(mWaitBeforeRenewalState);
+ } else {
+ if (!runDhcp(DhcpAction.RENEW)) {
+ transitionTo(mStoppedState);
+ }
+ }
+ break;
+ case CMD_START_DHCP:
+ //ignore
+ break;
+ default:
+ retValue = NOT_HANDLED;
+ }
+ return retValue;
+ }
+ }
+
+ class WaitBeforeRenewalState extends State {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = HANDLED;
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case CMD_STOP_DHCP:
+ mAlarmManager.cancel(mDhcpRenewalIntent);
+ if (!NetworkUtils.stopDhcp(mInterfaceName)) {
+ Log.e(TAG, "Failed to stop Dhcp on " + mInterfaceName);
+ }
+ transitionTo(mStoppedState);
+ break;
+ case CMD_PRE_DHCP_ACTION_COMPLETE:
+ if (runDhcp(DhcpAction.RENEW)) {
+ transitionTo(mRunningState);
+ } else {
+ transitionTo(mStoppedState);
+ }
+ break;
+ case CMD_START_DHCP:
+ //ignore
+ break;
+ default:
+ retValue = NOT_HANDLED;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ private boolean runDhcp(DhcpAction dhcpAction) {
+ boolean success = false;
+ DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
+
+ if (dhcpAction == DhcpAction.START) {
+ Log.d(TAG, "DHCP request on " + mInterfaceName);
+ success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
+ } else if (dhcpAction == DhcpAction.RENEW) {
+ Log.d(TAG, "DHCP renewal on " + mInterfaceName);
+ success = NetworkUtils.runDhcpRenew(mInterfaceName, dhcpInfoInternal);
+ }
+
+ if (success) {
+ Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
+ //Do it a bit earlier than half the lease duration time
+ //to beat the native DHCP client and avoid extra packets
+ //48% for one hour lease time = 29 minutes
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() +
+ dhcpInfoInternal.leaseDuration * 480, //in milliseconds
+ mDhcpRenewalIntent);
+
+ mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpInfoInternal)
+ .sendToTarget();
+ } else {
+ Log.d(TAG, "DHCP failed on " + mInterfaceName + ": " +
+ NetworkUtils.getDhcpError());
+ NetworkUtils.stopDhcp(mInterfaceName);
+ mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0)
+ .sendToTarget();
+ }
+ return success;
+ }
+}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index b3f3988..823d10f 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -80,6 +80,16 @@
public native static boolean runDhcp(String interfaceName, DhcpInfoInternal ipInfo);
/**
+ * Initiate renewal on the Dhcp client daemon. This call blocks until it obtains
+ * a result (either success or failure) from the daemon.
+ * @param interfaceName the name of the interface to configure
+ * @param ipInfo if the request succeeds, this object is filled in with
+ * the IP address information.
+ * @return {@code true} for success, {@code false} for failure
+ */
+ public native static boolean runDhcpRenew(String interfaceName, DhcpInfoInternal ipInfo);
+
+ /**
* Shut down the DHCP client daemon.
* @param interfaceName the name of the interface for which the daemon
* should be stopped
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index cf72ec4..6b676b4 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -64,15 +64,16 @@
*
* <p>
* A progress bar can also be made indeterminate. In indeterminate mode, the
- * progress bar shows a cyclic animation. This mode is used by applications
- * when the length of the task is unknown.
+ * progress bar shows a cyclic animation without an indication of progress. This mode is used by
+ * applications when the length of the task is unknown. The indeterminate progress bar can be either
+ * a spinning wheel or a horizontal bar.
* </p>
*
* <p>The following code example shows how a progress bar can be used from
* a worker thread to update the user interface to notify the user of progress:
* </p>
*
- * <pre class="prettyprint">
+ * <pre>
* public class MyActivity extends Activity {
* private static final int PROGRESS = 0x1;
*
@@ -91,7 +92,7 @@
* // Start lengthy operation in a background thread
* new Thread(new Runnable() {
* public void run() {
- * while (mProgressStatus < 100) {
+ * while (mProgressStatus < 100) {
* mProgressStatus = doWork();
*
* // Update the progress bar
@@ -104,8 +105,61 @@
* }
* }).start();
* }
- * }
- * </pre>
+ * }</pre>
+ *
+ * <p>To add a progress bar to a layout file, you can use the {@code <ProgressBar>} element.
+ * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a
+ * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal
+ * Widget.ProgressBar.Horizontal} style, like so:</p>
+ *
+ * <pre>
+ * <ProgressBar
+ * style="@android:style/Widget.ProgressBar.Horizontal"
+ * ... /></pre>
+ *
+ * <p>If you will use the progress bar to show real progress, you must use the horizontal bar. You
+ * can then increment the progress with {@link #incrementProgressBy incrementProgressBy()} or
+ * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If
+ * necessary, you can adjust the maximum value (the value for a full bar) using the {@link
+ * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed
+ * below.</p>
+ *
+ * <p>Another common style to apply to the progress bar is {@link
+ * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller
+ * version of the spinning wheel—useful when waiting for content to load.
+ * For example, you can insert this kind of progress bar into your default layout for
+ * a view that will be populated by some content fetched from the Internet—the spinning wheel
+ * appears immediately and when your application receives the content, it replaces the progress bar
+ * with the loaded content. For example:</p>
+ *
+ * <pre>
+ * <LinearLayout
+ * android:orientation="horizontal"
+ * ... >
+ * <ProgressBar
+ * android:layout_width="wrap_content"
+ * android:layout_height="wrap_content"
+ * style="@android:style/Widget.ProgressBar.Small"
+ * android:layout_marginRight="5dp" />
+ * <TextView
+ * android:layout_width="wrap_content"
+ * android:layout_height="wrap_content"
+ * android:text="@string/loading" />
+ * </LinearLayout></pre>
+ *
+ * <p>Other progress bar styles provided by the system include:</p>
+ * <ul>
+ * <li>{@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Small_Inverse
+ * Widget.ProgressBar.Small.Inverse}</li>
+ * <li>{@link android.R.style#Widget_ProgressBar_Large_Inverse
+ * Widget.ProgressBar.Large.Inverse}</li>
+ * </ul>
+ * <p>The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary
+ * if your application uses a light colored theme (a white background).</p>
*
* <p><strong>XML attributes</b></strong>
* <p>
@@ -113,13 +167,21 @@
* {@link android.R.styleable#View View Attributes}
* </p>
*
- * <p><strong>Styles</b></strong>
- * <p>
- * @attr ref android.R.styleable#Theme_progressBarStyle
- * @attr ref android.R.styleable#Theme_progressBarStyleSmall
- * @attr ref android.R.styleable#Theme_progressBarStyleLarge
- * @attr ref android.R.styleable#Theme_progressBarStyleHorizontal
- * </p>
+ * @attr ref android.R.styleable#ProgressBar_animationResolution
+ * @attr ref android.R.styleable#ProgressBar_indeterminate
+ * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior
+ * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable
+ * @attr ref android.R.styleable#ProgressBar_indeterminateDuration
+ * @attr ref android.R.styleable#ProgressBar_indeterminateOnly
+ * @attr ref android.R.styleable#ProgressBar_interpolator
+ * @attr ref android.R.styleable#ProgressBar_max
+ * @attr ref android.R.styleable#ProgressBar_maxHeight
+ * @attr ref android.R.styleable#ProgressBar_maxWidth
+ * @attr ref android.R.styleable#ProgressBar_minHeight
+ * @attr ref android.R.styleable#ProgressBar_minWidth
+ * @attr ref android.R.styleable#ProgressBar_progress
+ * @attr ref android.R.styleable#ProgressBar_progressDrawable
+ * @attr ref android.R.styleable#ProgressBar_secondaryProgress
*/
@RemoteView
public class ProgressBar extends View {
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index 101dd91..3973344 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -44,16 +44,16 @@
* In this usage model there is no need for the destination to
* use the connect methods. The typical sequence of operations is:</p>
*<ol>
- * <li>Client calls AsyncChannel#connect</li>
- * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
+ * <li>Client calls AsyncChannel#connectSync or Asynchronously:</li>
+ * <ol>For an asynchronous half connection client calls AsyncChannel#connect.</ol>
+ * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
+ * </ol>
* <li><code>comm-loop:</code></li>
- * <li>Client calls AsyncChannel#sendMessage(msgX)</li>
- * <li>Server receives and processes msgX</li>
- * <li>Server optionally calls AsyncChannel#replyToMessage(msgY)
- * and if sent Client receives and processes msgY</li>
+ * <li>Client calls AsyncChannel#sendMessage</li>
+ * <li>Server processes messages and optionally replies using AsyncChannel#replyToMessage
* <li>Loop to <code>comm-loop</code> until done</li>
- * <li>When done Client calls {@link AsyncChannel#disconnect(int)}</li>
- * <li>Client receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
+ * <li>When done Client calls {@link AsyncChannel#disconnect}</li>
+ * <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
*</ol>
*<br/>
* <p>A second usage model is where the server/destination needs to know
@@ -62,21 +62,26 @@
* different state for each client. In this model the server will also
* use the connect methods. The typical sequence of operation is:</p>
*<ol>
- * <li>Client calls AsyncChannel#connect</li>
- * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
- * <li>Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)</li>
+ * <li>Client calls AsyncChannel#fullyConnectSync or Asynchronously:<li>
+ * <ol>For an asynchronous full connection it calls AsyncChannel#connect</li>
+ * <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
+ * <li>Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)</li>
+ * </ol>
* <li>Server receives CMD_CHANNEL_FULL_CONNECTION</li>
- * <li>Server calls AsyncChannel#connect</li>
- * <li>Server receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
+ * <li>Server calls AsyncChannel#connected</li>
* <li>Server sends AsyncChannel#sendMessage(CMD_CHANNEL_FULLY_CONNECTED)</li>
* <li>Client receives CMD_CHANNEL_FULLY_CONNECTED</li>
* <li><code>comm-loop:</code></li>
* <li>Client/Server uses AsyncChannel#sendMessage/replyToMessage
* to communicate and perform work</li>
* <li>Loop to <code>comm-loop</code> until done</li>
- * <li>When done Client/Server calls {@link AsyncChannel#disconnect(int)}</li>
+ * <li>When done Client/Server calls {@link AsyncChannel#disconnect}</li>
* <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
*</ol>
+ *
+ * TODO: Consider simplifying where we have connect and fullyConnect with only one response
+ * message RSP_CHANNEL_CONNECT instead of two, CMD_CHANNEL_HALF_CONNECTED and
+ * CMD_CHANNEL_FULLY_CONNECTED. We'd also change CMD_CHANNEL_FULL_CONNECTION to REQ_CHANNEL_CONNECT.
*/
public class AsyncChannel {
/** Log tag */
@@ -85,6 +90,8 @@
/** Enable to turn on debugging */
private static final boolean DBG = false;
+ private static final int BASE = Protocol.BASE_SYSTEM_ASYNC_CHANNEL;
+
/**
* Command sent when the channel is half connected. Half connected
* means that the channel can be used to send commends to the destination
@@ -98,7 +105,7 @@
* msg.obj == the AsyncChannel
* msg.replyTo == dstMessenger if successful
*/
- public static final int CMD_CHANNEL_HALF_CONNECTED = -1;
+ public static final int CMD_CHANNEL_HALF_CONNECTED = BASE + 0;
/**
* Command typically sent when after receiving the CMD_CHANNEL_HALF_CONNECTED.
@@ -107,7 +114,7 @@
*
* msg.replyTo = srcMessenger.
*/
- public static final int CMD_CHANNEL_FULL_CONNECTION = -2;
+ public static final int CMD_CHANNEL_FULL_CONNECTION = BASE + 1;
/**
* Command typically sent after the destination receives a CMD_CHANNEL_FULL_CONNECTION.
@@ -115,31 +122,33 @@
*
* msg.arg1 == 0 : Accept connection
* : All other values signify the destination rejected the connection
- * and {@link AsyncChannel#disconnect(int)} would typically be called.
+ * and {@link AsyncChannel#disconnect} would typically be called.
*/
- public static final int CMD_CHANNEL_FULLY_CONNECTED = -3;
+ public static final int CMD_CHANNEL_FULLY_CONNECTED = BASE + 2;
/**
* Command sent when one side or the other wishes to disconnect. The sender
* may or may not be able to receive a reply depending upon the protocol and
- * the state of the connection. The receiver should call {@link AsyncChannel#disconnect(int)}
+ * the state of the connection. The receiver should call {@link AsyncChannel#disconnect}
* to close its side of the channel and it will receive a CMD_CHANNEL_DISCONNECTED
* when the channel is closed.
*
* msg.replyTo = messenger that is disconnecting
*/
- public static final int CMD_CHANNEL_DISCONNECT = -4;
+ public static final int CMD_CHANNEL_DISCONNECT = BASE + 3;
/**
* Command sent when the channel becomes disconnected. This is sent when the
* channel is forcibly disconnected by the system or as a reply to CMD_CHANNEL_DISCONNECT.
*
* msg.arg1 == 0 : STATUS_SUCCESSFUL
+ * 1 : STATUS_BINDING_UNSUCCESSFUL
+ * 2 : STATUS_SEND_UNSUCCESSFUL
* : All other values signify failure and the channel state is indeterminate
* msg.obj == the AsyncChannel
* msg.replyTo = messenger disconnecting or null if it was never connected.
*/
- public static final int CMD_CHANNEL_DISCONNECTED = -5;
+ public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4;
/** Successful status always 0, !0 is an unsuccessful status */
public static final int STATUS_SUCCESSFUL = 0;
@@ -147,6 +156,12 @@
/** Error attempting to bind on a connect */
public static final int STATUS_BINDING_UNSUCCESSFUL = 1;
+ /** Error attempting to send a message */
+ public static final int STATUS_SEND_UNSUCCESSFUL = 2;
+
+ /** CMD_FULLY_CONNECTED refused because a connection already exists*/
+ public static final int STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED = 3;
+
/** Service connection */
private AsyncChannelConnection mConnection;
@@ -169,9 +184,7 @@
}
/**
- * Connect handler to named package/class.
- *
- * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
+ * Connect handler to named package/class synchronously.
*
* @param srcContext is the context of the source
* @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
@@ -179,8 +192,10 @@
* @param dstPackageName is the destination package name
* @param dstClassName is the fully qualified class name (i.e. contains
* package name)
+ *
+ * @return STATUS_SUCCESSFUL on success any other value is an error.
*/
- private void connectSrcHandlerToPackage(
+ public int connectSrcHandlerToPackageSync(
Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) {
if (DBG) log("connect srcHandler to dst Package & class E");
@@ -202,11 +217,61 @@
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName(dstPackageName, dstClassName);
boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- if (!result) {
- replyHalfConnected(STATUS_BINDING_UNSUCCESSFUL);
- }
-
if (DBG) log("connect srcHandler to dst Package & class X result=" + result);
+ return result ? STATUS_SUCCESSFUL : STATUS_BINDING_UNSUCCESSFUL;
+ }
+
+ /**
+ * Connect a handler to Messenger synchronously.
+ *
+ * @param srcContext is the context of the source
+ * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
+ * messages
+ * @param dstMessenger is the hander to send messages to.
+ *
+ * @return STATUS_SUCCESSFUL on success any other value is an error.
+ */
+ public int connectSync(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
+ if (DBG) log("halfConnectSync srcHandler to the dstMessenger E");
+
+ // We are connected
+ connected(srcContext, srcHandler, dstMessenger);
+
+ if (DBG) log("halfConnectSync srcHandler to the dstMessenger X");
+ return STATUS_SUCCESSFUL;
+ }
+
+ /**
+ * connect two local Handlers synchronously.
+ *
+ * @param srcContext is the context of the source
+ * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
+ * messages
+ * @param dstHandler is the hander to send messages to.
+ *
+ * @return STATUS_SUCCESSFUL on success any other value is an error.
+ */
+ public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {
+ return connectSync(srcContext, srcHandler, new Messenger(dstHandler));
+ }
+
+ /**
+ * Fully connect two local Handlers synchronously.
+ *
+ * @param srcContext is the context of the source
+ * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
+ * messages
+ * @param dstHandler is the hander to send messages to.
+ *
+ * @return STATUS_SUCCESSFUL on success any other value is an error.
+ */
+ public int fullyConnectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {
+ int status = connectSync(srcContext, srcHandler, dstHandler);
+ if (status == STATUS_SUCCESSFUL) {
+ Message response = sendMessageSynchronously(CMD_CHANNEL_FULL_CONNECTION);
+ status = response.arg1;
+ }
+ return status;
}
/**
@@ -241,8 +306,11 @@
mDstClassName = dstClassName;
}
+ @Override
public void run() {
- connectSrcHandlerToPackage(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName);
+ int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName,
+ mDstClassName);
+ replyHalfConnected(result);
}
}
@@ -281,15 +349,8 @@
public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
if (DBG) log("connect srcHandler to the dstMessenger E");
- // Initialize source fields
- mSrcContext = srcContext;
- mSrcHandler = srcHandler;
- mSrcMessenger = new Messenger(mSrcHandler);
-
- // Initialize destination fields
- mDstMessenger = dstMessenger;
-
- if (DBG) log("tell source we are half connected");
+ // We are connected
+ connected(srcContext, srcHandler, dstMessenger);
// Tell source we are half connected
replyHalfConnected(STATUS_SUCCESSFUL);
@@ -298,11 +359,31 @@
}
/**
- * Connect two local Handlers.
+ * Connect handler to messenger. This method is typically called
+ * when a server receives a CMD_CHANNEL_FULL_CONNECTION request
+ * and initializes the internal instance variables to allow communication
+ * with the dstMessenger.
*
- * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
- * msg.arg1 = status
- * msg.obj = the AsyncChannel
+ * @param srcContext
+ * @param srcHandler
+ * @param dstMessenger
+ */
+ public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
+ if (DBG) log("connected srcHandler to the dstMessenger E");
+
+ // Initialize source fields
+ mSrcContext = srcContext;
+ mSrcHandler = srcHandler;
+ mSrcMessenger = new Messenger(mSrcHandler);
+
+ // Initialize destination fields
+ mDstMessenger = dstMessenger;
+
+ if (DBG) log("connected srcHandler to the dstMessenger X");
+ }
+
+ /**
+ * Connect two local Handlers.
*
* @param srcContext is the context of the source
* @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
@@ -331,6 +412,7 @@
* To close the connection call when handler receives CMD_CHANNEL_DISCONNECTED
*/
public void disconnected() {
+ mSrcContext = null;
mSrcHandler = null;
mSrcMessenger = null;
mDstMessenger = null;
@@ -341,15 +423,11 @@
* Disconnect
*/
public void disconnect() {
- if (mConnection != null) {
+ if ((mConnection != null) && (mSrcContext != null)) {
mSrcContext.unbindService(mConnection);
}
if (mSrcHandler != null) {
- Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
- msg.arg1 = STATUS_SUCCESSFUL;
- msg.obj = this;
- msg.replyTo = mDstMessenger;
- mSrcHandler.sendMessage(msg);
+ replyDisconnected(STATUS_SUCCESSFUL);
}
}
@@ -363,7 +441,7 @@
try {
mDstMessenger.send(msg);
} catch (RemoteException e) {
- log("TODO: handle sendMessage RemoteException" + e);
+ replyDisconnected(STATUS_SEND_UNSUCCESSFUL);
}
}
@@ -444,6 +522,7 @@
*/
public void replyToMessage(Message srcMsg, Message dstMsg) {
try {
+ dstMsg.replyTo = mSrcMessenger;
srcMsg.replyTo.send(dstMsg);
} catch (RemoteException e) {
log("TODO: handle replyToMessage RemoteException" + e);
@@ -694,10 +773,14 @@
private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) {
SyncMessenger sm = SyncMessenger.obtain();
try {
- msg.replyTo = sm.mMessenger;
- dstMessenger.send(msg);
- synchronized (sm.mHandler.mLockObject) {
- sm.mHandler.mLockObject.wait();
+ if (dstMessenger != null && msg != null) {
+ msg.replyTo = sm.mMessenger;
+ synchronized (sm.mHandler.mLockObject) {
+ dstMessenger.send(msg);
+ sm.mHandler.mLockObject.wait();
+ }
+ } else {
+ sm.mHandler.mResultMsg = null;
}
} catch (InterruptedException e) {
sm.mHandler.mResultMsg = null;
@@ -712,6 +795,7 @@
/**
* Reply to the src handler that we're half connected.
+ * see: CMD_CHANNEL_HALF_CONNECTED for message contents
*
* @param status to be stored in msg.arg1
*/
@@ -724,23 +808,36 @@
}
/**
+ * Reply to the src handler that we are disconnected
+ * see: CMD_CHANNEL_DISCONNECTED for message contents
+ *
+ * @param status to be stored in msg.arg1
+ */
+ private void replyDisconnected(int status) {
+ Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
+ msg.arg1 = status;
+ msg.obj = this;
+ msg.replyTo = mDstMessenger;
+ mSrcHandler.sendMessage(msg);
+ }
+
+
+ /**
* ServiceConnection to receive call backs.
*/
class AsyncChannelConnection implements ServiceConnection {
AsyncChannelConnection() {
}
+ @Override
public void onServiceConnected(ComponentName className, IBinder service) {
mDstMessenger = new Messenger(service);
replyHalfConnected(STATUS_SUCCESSFUL);
}
+ @Override
public void onServiceDisconnected(ComponentName className) {
- Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
- msg.arg1 = STATUS_SUCCESSFUL;
- msg.obj = AsyncChannel.this;
- msg.replyTo = mDstMessenger;
- mSrcHandler.sendMessage(msg);
+ replyDisconnected(STATUS_SUCCESSFUL);
}
}
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
new file mode 100644
index 0000000..b35f615
--- /dev/null
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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.util;
+
+/**
+ * This class defines Message.what base addresses for various protocols that are recognized
+ * to be unique by any {@link com.android.internal.util.Statemachine} implementation. This
+ * allows for interaction between different StateMachine implementations without a conflict
+ * of message codes.
+ *
+ * As an example, all messages in {@link android.net.wifi.WifiStateMachine} will have message
+ * codes with Message.what starting at Protocol.WIFI + 1 and less than or equal to Protocol.WIFI +
+ * Protocol.MAX_MESSAGE
+ *
+ * {@hide}
+ */
+public class Protocol {
+ public static final int MAX_MESSAGE = 0x0000FFFF;
+
+ /** Base reserved for system */
+ public static final int BASE_SYSTEM_RESERVED = 0x00010000;
+ public static final int BASE_SYSTEM_ASYNC_CHANNEL = 0x00011000;
+
+ /** Non system protocols */
+ public static final int BASE_WIFI = 0x00020000;
+ public static final int BASE_DHCP = 0x00030000;
+ public static final int BASE_DATA_CONNECTION = 0x00040000;
+ public static final int BASE_DATA_CONNECTION_TRACKER = 0x00050000;
+
+ //TODO: define all used protocols
+}
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 33ba26a..904eaf9 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -40,6 +40,16 @@
const char *dns2,
const char *server,
uint32_t *lease);
+
+int dhcp_do_request_renew(const char *ifname,
+ const char *ipaddr,
+ const char *gateway,
+ uint32_t *prefixLength,
+ const char *dns1,
+ const char *dns2,
+ const char *server,
+ uint32_t *lease);
+
int dhcp_stop(const char *ifname);
int dhcp_release_lease(const char *ifname);
char *dhcp_get_errmsg();
@@ -145,7 +155,8 @@
return (jint)result;
}
-static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
+static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
+ jobject info, bool renew)
{
int result;
char ipaddr[PROPERTY_VALUE_MAX];
@@ -159,8 +170,14 @@
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
if (nameStr == NULL) return (jboolean)false;
- result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
- dns1, dns2, server, &lease);
+ if (renew) {
+ result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
+ dns1, dns2, server, &lease);
+ } else {
+ result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
+ dns1, dns2, server, &lease);
+ }
+
env->ReleaseStringUTFChars(ifname, nameStr);
if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
@@ -198,6 +215,17 @@
return (jboolean)(result == 0);
}
+static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
+{
+ return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
+}
+
+static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
+{
+ return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
+}
+
+
static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
@@ -241,6 +269,7 @@
{ "removeDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_removeDefaultRoute },
{ "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections },
{ "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcp },
+ { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcpRenew },
{ "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
{ "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 1da2622..7c84bd2 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -264,8 +264,8 @@
names.</p>
<table>
<tr>
- <th>Qualifier</th>
- <th>Values</th>
+ <th>Configuration</th>
+ <th>Qualifier Values</th>
<th>Description</th>
</tr>
<tr id="MccQualifier">
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index 2da022c..4a574be 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -295,7 +295,9 @@
{@link android.view.ViewGroup.MarginLayoutParams} for further information.
</p>
-<p>For more information about dimensions, see <a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">Dimension Values</a>.</p>
+ <p>For more information about dimensions, see
+ <a href="{@docRoot}guide/topics/resources/more-resources.html#Dimension">Dimension Values</a>.
+ </p>
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index 669beac..8ce1d9a 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -75,11 +75,17 @@
* @param name The name to assign to the object.
*/
public void setName(String name) {
+ if (name == null) {
+ throw new RSIllegalArgumentException(
+ "setName requires a string of non-zero length.");
+ }
if(name.length() < 1) {
- throw new RSIllegalArgumentException("setName does not accept a zero length string.");
+ throw new RSIllegalArgumentException(
+ "setName does not accept a zero length string.");
}
if(mName != null) {
- throw new RSIllegalArgumentException("setName object already has a name.");
+ throw new RSIllegalArgumentException(
+ "setName object already has a name.");
}
try {
@@ -106,9 +112,9 @@
}
/**
- * destroy disconnects the object from the native object effectivly
+ * destroy disconnects the object from the native object effectively
* rendering this java object dead. The primary use is to force immediate
- * cleanup of resources when its believed the GC will not respond quickly
+ * cleanup of resources when it is believed the GC will not respond quickly
* enough.
*/
synchronized public void destroy() {
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 23230a6..8a4789a 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -76,13 +76,15 @@
static float SC_randf(float max) {
float r = (float)rand();
r *= max;
- return r / RAND_MAX;
+ r /= RAND_MAX;
+ return r;
}
static float SC_randf2(float min, float max) {
float r = (float)rand();
+ r /= RAND_MAX;
r = r * (max - min) + min;
- return r / RAND_MAX;
+ return r;
}
static int SC_randi(int max) {
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index bee0d5e..62fb732 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -100,6 +100,7 @@
mNumBandwidthHistoryItems(0),
mTotalTransferTimeUs(0),
mTotalTransferBytes(0),
+ mPrevBandwidthMeasureTimeUs(0),
mDecryptHandle(NULL),
mDrmManagerClient(NULL) {
}
@@ -534,6 +535,16 @@
mTotalTransferBytes -= entry->mNumBytes;
mBandwidthHistory.erase(mBandwidthHistory.begin());
--mNumBandwidthHistoryItems;
+ int64_t timeNowUs = ALooper::GetNowUs();
+ if (timeNowUs - mPrevBandwidthMeasureTimeUs > 2000000LL) {
+ if (mPrevBandwidthMeasureTimeUs != 0) {
+ double estimatedBandwidth =
+ ((double)mTotalTransferBytes * 8E3 / mTotalTransferTimeUs);
+ LOGI("estimated avg bandwidth is %8.2f kbps in the past %lld us",
+ estimatedBandwidth, timeNowUs - mPrevBandwidthMeasureTimeUs);
+ }
+ mPrevBandwidthMeasureTimeUs = timeNowUs;
+ }
}
}
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index 2569568..0d68234 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -97,6 +97,7 @@
size_t mNumBandwidthHistoryItems;
int64_t mTotalTransferTimeUs;
size_t mTotalTransferBytes;
+ int64_t mPrevBandwidthMeasureTimeUs;
DecryptHandle *mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index f347623..6edd0b6 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -3025,7 +3025,7 @@
dataCall.active = p.readInt();
dataCall.type = p.readString();
String addresses = p.readString();
- if (TextUtils.isEmpty(addresses)) {
+ if (!TextUtils.isEmpty(addresses)) {
dataCall.addresses = addresses.split(" ");
}
} else {
@@ -3034,7 +3034,8 @@
dataCall.active = p.readInt();
dataCall.type = p.readString();
dataCall.ifname = p.readString();
- if (TextUtils.isEmpty(dataCall.ifname)) {
+ if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) &&
+ TextUtils.isEmpty(dataCall.ifname)) {
throw new RuntimeException("getDataCallState, no ifname");
}
String addresses = p.readString();
diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
index a6c7777..2f3b177 100644
--- a/telephony/java/com/android/internal/telephony/cat/CatService.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatService.java
@@ -135,6 +135,7 @@
static final int MSG_ID_CALL_SETUP = 4;
static final int MSG_ID_REFRESH = 5;
static final int MSG_ID_RESPONSE = 6;
+ static final int MSG_ID_SIM_READY = 7;
static final int MSG_ID_RIL_MSG_DECODED = 10;
@@ -172,9 +173,11 @@
mIccRecords = ir;
// Register for SIM ready event.
+ mCmdIf.registerForSIMReady(this, MSG_ID_SIM_READY, null);
+ mCmdIf.registerForRUIMReady(this, MSG_ID_SIM_READY, null);
+ mCmdIf.registerForNVReady(this, MSG_ID_SIM_READY, null);
mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
- mCmdIf.reportStkServiceIsRunning(null);
CatLog.d(this, "Is running");
}
@@ -588,6 +591,10 @@
case MSG_ID_RESPONSE:
handleCmdResponse((CatResponseMessage) msg.obj);
break;
+ case MSG_ID_SIM_READY:
+ CatLog.d(this, "SIM ready. Reporting STK service running now...");
+ mCmdIf.reportStkServiceIsRunning(null);
+ break;
default:
throw new AssertionError("Unrecognized CAT command: " + msg.what);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index cd585cf..e299d4a 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -99,9 +99,9 @@
@Override
protected boolean isDnsOk(String[] domainNameServers) {
- if ((NULL_IP.equals(domainNameServers[0])
+ if (NULL_IP.equals(domainNameServers[0])
&& NULL_IP.equals(domainNameServers[1])
- && !((CDMAPhone) phone).isDnsCheckDisabled())) {
+ && !phone.isDnsCheckDisabled()) {
return false;
} else {
return true;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 109daf0..32c5d75 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -44,22 +44,14 @@
CDMALTEPhone mCdmaLtePhone;
- private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
-
- private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
+ private ServiceState mLteSS; // The last LTE state from Voice Registration
public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
super(phone);
mCdmaLtePhone = phone;
- if (DBG) log("CdmaLteServiceStateTracker Constructors");
- }
- /**
- * @return The current GPRS state. IN_SERVICE is the same as "attached" and
- * OUT_OF_SERVICE is the same as detached.
- */
- public int getCurrentDataConnectionState() {
- return gprsState;
+ mLteSS = new ServiceState();
+ if (DBG) log("CdmaLteServiceStateTracker Constructors");
}
@Override
@@ -77,11 +69,13 @@
}
/**
- * The LTE data connection state, only return true here
+ * Set the cdmaSS for EVENT_POLL_STATE_REGISTRATION_CDMA
*/
@Override
- protected boolean checkAdditionalDataAvaiable() {
- return newGPRSState != ServiceState.STATE_IN_SERVICE;
+ protected void setCdmaTechnology(int radioTechnology) {
+ // Called on voice registration state response.
+ // Just record new CDMA radio technology
+ newSS.setRadioTechnology(radioTechnology);
}
/**
@@ -109,14 +103,10 @@
}
}
- newGPRSState = regCodeToServiceState(regState);
// Not sure if this is needed in CDMALTE phone.
// mDataRoaming = regCodeIsRoaming(regState);
- if (newGPRSState == ServiceState.STATE_IN_SERVICE) {
- this.newCdmaDataConnectionState = newGPRSState;
- newNetworkType = type;
- newSS.setRadioTechnology(type);
- }
+ mLteSS.setRadioTechnology(type);
+ mLteSS.setState(regCodeToServiceState(regState));
} else {
super.handlePollStateResultMessage(what, ar);
}
@@ -216,6 +206,21 @@
@Override
protected void pollStateDone() {
+ // determine data NetworkType from both LET and CDMA SS
+ if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) {
+ //in LTE service
+ newNetworkType = mLteSS.getRadioTechnology();
+ mNewDataConnectionState = mLteSS.getState();
+ newSS.setRadioTechnology(newNetworkType);
+ log("pollStateDone LTE/eHRPD STATE_IN_SERVICE newNetworkType = " + newNetworkType);
+ } else {
+ // LTE out of service, get CDMA Service State
+ newNetworkType = newSS.getRadioTechnology();
+ mNewDataConnectionState = radioTechnologyToDataServiceState(newNetworkType);
+ log("pollStateDone CDMA STATE_IN_SERVICE newNetworkType = " + newNetworkType +
+ " mNewDataConnectionState = " + mNewDataConnectionState);
+ }
+
if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE
@@ -225,15 +230,15 @@
&& newSS.getState() != ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionAttached =
- this.cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE
- && this.newCdmaDataConnectionState == ServiceState.STATE_IN_SERVICE;
+ mDataConnectionState != ServiceState.STATE_IN_SERVICE
+ && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionDetached =
- this.cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE
- && this.newCdmaDataConnectionState != ServiceState.STATE_IN_SERVICE;
+ mDataConnectionState == ServiceState.STATE_IN_SERVICE
+ && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionChanged =
- cdmaDataConnectionState != newCdmaDataConnectionState;
+ mDataConnectionState != mNewDataConnectionState;
boolean hasNetworkTypeChanged = networkType != newNetworkType;
@@ -272,9 +277,9 @@
}
// Add an event log when connection state changes
if (ss.getState() != newSS.getState()
- || cdmaDataConnectionState != newCdmaDataConnectionState) {
+ || mDataConnectionState != mNewDataConnectionState) {
EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, ss.getState(),
- cdmaDataConnectionState, newSS.getState(), newCdmaDataConnectionState);
+ mDataConnectionState, newSS.getState(), mNewDataConnectionState);
}
ServiceState tss;
@@ -283,6 +288,7 @@
newSS = tss;
// clean slate for next time
newSS.setStateOutOfService();
+ mLteSS.setStateOutOfService();
// TODO: 4G Tech Handoff
// if (has4gHandoff) {
@@ -309,11 +315,9 @@
cellLoc = newCellLoc;
newCellLoc = tcl;
- cdmaDataConnectionState = newCdmaDataConnectionState;
+ mDataConnectionState = mNewDataConnectionState;
networkType = newNetworkType;
- gprsState = newCdmaDataConnectionState;
-
newSS.setStateOutOfService(); // clean slate for next time
if (hasNetworkTypeChanged) {
@@ -424,8 +428,8 @@
: -1;
if (networkType == ServiceState.RADIO_TECHNOLOGY_LTE) {
lteRssi = (ints[offset + 5] >= 0) ? ints[offset + 5] : 99;
- lteRsrp = (ints[offset + 6] > 0) ? -ints[offset + 7] : -1;
- lteCqi = (ints[offset + 7] >= 0) ? ints[offset + 6] : 99;
+ lteRsrp = (ints[offset + 6] < 0) ? ints[offset + 6] : -1;
+ lteCqi = (ints[offset + 7] >= 0) ? ints[offset + 7] : 99;
}
if (networkType != ServiceState.RADIO_TECHNOLOGY_LTE) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index ac8352d..afebebe 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -97,8 +97,8 @@
/**
* Initially assume no data connection.
*/
- protected int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
- protected int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
+ protected int mDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
+ protected int mNewDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
protected int mRegistrationState = -1;
protected RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
@@ -217,8 +217,8 @@
phone.mRuimRecords.unregisterForRecordsLoaded(this);
cm.unSetOnSignalStrengthUpdate(this);
cm.unSetOnNITZTime(this);
- cr.unregisterContentObserver(this.mAutoTimeObserver);
- cr.unregisterContentObserver(this.mAutoTimeZoneObserver);
+ cr.unregisterContentObserver(mAutoTimeObserver);
+ cr.unregisterContentObserver(mAutoTimeZoneObserver);
}
@Override
@@ -548,10 +548,12 @@
}
/**
- * The LTE data connection state, only return true here
+ * Determine data network type based on radio technology.
*/
- protected boolean checkAdditionalDataAvaiable(){
- return true;
+ protected void setCdmaTechnology(int radioTechnology){
+ mNewDataConnectionState = radioTechnologyToDataServiceState(radioTechnology);
+ newSS.setRadioTechnology(radioTechnology);
+ newNetworkType = radioTechnology;
}
/**
@@ -639,12 +641,7 @@
regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
newSS.setState (regCodeToServiceState(registrationState));
- if(checkAdditionalDataAvaiable()) {
- this.newCdmaDataConnectionState =
- radioTechnologyToDataServiceState(radioTechnology);
- newSS.setRadioTechnology(radioTechnology);
- newNetworkType = radioTechnology;
- }
+ setCdmaTechnology(radioTechnology);
newSS.setCssIndicator(cssIndicator);
newSS.setSystemAndNetworkId(systemId, networkId);
@@ -953,15 +950,15 @@
&& newSS.getState() != ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionAttached =
- this.cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE
- && this.newCdmaDataConnectionState == ServiceState.STATE_IN_SERVICE;
+ mDataConnectionState != ServiceState.STATE_IN_SERVICE
+ && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionDetached =
- this.cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE
- && this.newCdmaDataConnectionState != ServiceState.STATE_IN_SERVICE;
+ mDataConnectionState == ServiceState.STATE_IN_SERVICE
+ && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
boolean hasCdmaDataConnectionChanged =
- cdmaDataConnectionState != newCdmaDataConnectionState;
+ mDataConnectionState != mNewDataConnectionState;
boolean hasNetworkTypeChanged = networkType != newNetworkType;
@@ -975,10 +972,10 @@
// Add an event log when connection state changes
if (ss.getState() != newSS.getState() ||
- cdmaDataConnectionState != newCdmaDataConnectionState) {
+ mDataConnectionState != mNewDataConnectionState) {
EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE,
- ss.getState(), cdmaDataConnectionState,
- newSS.getState(), newCdmaDataConnectionState);
+ ss.getState(), mDataConnectionState,
+ newSS.getState(), mNewDataConnectionState);
}
ServiceState tss;
@@ -992,7 +989,7 @@
cellLoc = newCellLoc;
newCellLoc = tcl;
- cdmaDataConnectionState = newCdmaDataConnectionState;
+ mDataConnectionState = mNewDataConnectionState;
networkType = newNetworkType;
// this new state has been applied - forget it until we get a new new state
newNetworkType = 0;
@@ -1175,7 +1172,7 @@
}
- private int radioTechnologyToDataServiceState(int code) {
+ protected int radioTechnologyToDataServiceState(int code) {
int retVal = ServiceState.STATE_OUT_OF_SERVICE;
switch(code) {
case 0:
@@ -1226,14 +1223,14 @@
* ServiceState.RADIO_TECHNOLOGY_UNKNOWN is the same as detached.
*/
/*package*/ int getCurrentCdmaDataConnectionState() {
- return cdmaDataConnectionState;
+ return mDataConnectionState;
}
/**
* TODO: In the future, we need remove getCurrentCdmaDataConnectionState
*/
public int getCurrentDataConnectionState() {
- return cdmaDataConnectionState;
+ return mDataConnectionState;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 8a11ae3..545ad8a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -130,7 +130,7 @@
@Override
protected boolean isDnsOk(String[] domainNameServers) {
if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1])
- && !((GSMPhone) phone).isDnsCheckDisabled()) {
+ && !phone.isDnsCheckDisabled()) {
// Work around a race condition where QMI does not fill in DNS:
// Deactivate PDP and let DataConnectionTracker retry.
// Do not apply the race condition workaround for MMS APN
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 223c8ad..8e675fc 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -115,6 +115,7 @@
static final Uri PREFERAPN_URI = Uri.parse("content://telephony/carriers/preferapn");
static final String APN_ID = "apn_id";
private boolean canSetPreferApn = false;
+ private boolean mRadioAvailable = false;
@Override
protected void onActionIntentReconnectAlarm(Intent intent) {
@@ -519,6 +520,7 @@
} else {
if (DBG) log("return APN_ALREADY_INACTIVE");
apnContext.setEnabled(false);
+ apnContext.setDataConnection(null);
return Phone.APN_ALREADY_INACTIVE;
}
@@ -1267,6 +1269,7 @@
if (!apnContext.getDataConnection().isRetryNeeded()) {
if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)){
// if no more retries on a secondary APN attempt, tell the world and revert.
+ apnContext.setDataConnection(null);
notifyDataConnection(Phone.REASON_APN_FAILED);
return;
}
@@ -1323,6 +1326,10 @@
private void onRecordsLoaded() {
if (DBG) log("onRecordsLoaded: createAllApnList");
createAllApnList();
+ if (mRadioAvailable) {
+ if (DBG) log("onRecordsLoaded, notifying data availability");
+ notifyDataAvailability(null);
+ }
setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
}
@@ -1434,6 +1441,8 @@
@Override
protected void onRadioAvailable() {
+
+ mRadioAvailable = true;
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
@@ -1461,6 +1470,7 @@
dc.resetRetryCount();
}
mReregisterOnReconnectFailure = false;
+ mRadioAvailable = false;
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
@@ -1470,6 +1480,7 @@
if (DBG) log("Radio is off and clean up all connection");
cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
}
+ notifyDataAvailability(null);
}
@Override
@@ -1562,6 +1573,7 @@
log("onDataSetupComplete: All APN's had permanent failures, stop retrying");
}
apnContext.setState(State.FAILED);
+ apnContext.setDataConnection(null);
notifyDataConnection(Phone.REASON_APN_FAILED);
} else {
if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
@@ -1600,6 +1612,7 @@
if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
apnContext.setEnabled(false);
apnContext.setPendingAction(ApnContext.PENDING_ACTION_NONE);
+ apnContext.setDataConnection(null);
}
mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
@@ -1618,7 +1631,10 @@
if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_RECONNECT) {
apnContext.setPendingAction(ApnContext.PENDING_ACTION_NONE);
}
- trySetupData(apnContext);
+ // Wait a bit before trying the next APN, so that
+ // we're not tying up the RIL command channel.
+ // This also helps in any external dependency to turn off the context.
+ sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext),APN_DELAY_MILLIS);
}
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index afa5c1d..a6b1a2c 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -48,6 +48,7 @@
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.DhcpInfoInternal;
+import android.net.DhcpStateMachine;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -73,6 +74,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
@@ -151,6 +153,7 @@
private NetworkInfo mNetworkInfo;
private SupplicantStateTracker mSupplicantStateTracker;
private WpsStateMachine mWpsStateMachine;
+ private DhcpStateMachine mDhcpStateMachine;
private AlarmManager mAlarmManager;
private PendingIntent mScanIntent;
@@ -165,95 +168,97 @@
private static final int EVENTLOG_WIFI_EVENT_HANDLED = 50022;
private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED = 50023;
+ /* The base for wifi message types */
+ static final int BASE = Protocol.BASE_WIFI;
/* Load the driver */
- static final int CMD_LOAD_DRIVER = 1;
+ static final int CMD_LOAD_DRIVER = BASE + 1;
/* Unload the driver */
- static final int CMD_UNLOAD_DRIVER = 2;
+ static final int CMD_UNLOAD_DRIVER = BASE + 2;
/* Indicates driver load succeeded */
- static final int CMD_LOAD_DRIVER_SUCCESS = 3;
+ static final int CMD_LOAD_DRIVER_SUCCESS = BASE + 3;
/* Indicates driver load failed */
- static final int CMD_LOAD_DRIVER_FAILURE = 4;
+ static final int CMD_LOAD_DRIVER_FAILURE = BASE + 4;
/* Indicates driver unload succeeded */
- static final int CMD_UNLOAD_DRIVER_SUCCESS = 5;
+ static final int CMD_UNLOAD_DRIVER_SUCCESS = BASE + 5;
/* Indicates driver unload failed */
- static final int CMD_UNLOAD_DRIVER_FAILURE = 6;
+ static final int CMD_UNLOAD_DRIVER_FAILURE = BASE + 6;
/* Start the supplicant */
- static final int CMD_START_SUPPLICANT = 11;
+ static final int CMD_START_SUPPLICANT = BASE + 11;
/* Stop the supplicant */
- static final int CMD_STOP_SUPPLICANT = 12;
+ static final int CMD_STOP_SUPPLICANT = BASE + 12;
/* Start the driver */
- static final int CMD_START_DRIVER = 13;
+ static final int CMD_START_DRIVER = BASE + 13;
/* Start the driver */
- static final int CMD_STOP_DRIVER = 14;
- /* Indicates DHCP succeded */
- static final int CMD_IP_CONFIG_SUCCESS = 15;
- /* Indicates DHCP failed */
- static final int CMD_IP_CONFIG_FAILURE = 16;
+ static final int CMD_STOP_DRIVER = BASE + 14;
+ /* Indicates Static IP succeded */
+ static final int CMD_STATIC_IP_SUCCESS = BASE + 15;
+ /* Indicates Static IP failed */
+ static final int CMD_STATIC_IP_FAILURE = BASE + 16;
/* Start the soft access point */
- static final int CMD_START_AP = 21;
+ static final int CMD_START_AP = BASE + 21;
/* Stop the soft access point */
- static final int CMD_STOP_AP = 22;
+ static final int CMD_STOP_AP = BASE + 22;
- static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = 23;
+ static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 23;
/* Supplicant events */
/* Connection to supplicant established */
- static final int SUP_CONNECTION_EVENT = 31;
+ static final int SUP_CONNECTION_EVENT = BASE + 31;
/* Connection to supplicant lost */
- static final int SUP_DISCONNECTION_EVENT = 32;
+ static final int SUP_DISCONNECTION_EVENT = BASE + 32;
/* Driver start completed */
- static final int DRIVER_START_EVENT = 33;
+ static final int DRIVER_START_EVENT = BASE + 33;
/* Driver stop completed */
- static final int DRIVER_STOP_EVENT = 34;
+ static final int DRIVER_STOP_EVENT = BASE + 34;
/* Network connection completed */
- static final int NETWORK_CONNECTION_EVENT = 36;
+ static final int NETWORK_CONNECTION_EVENT = BASE + 36;
/* Network disconnection completed */
- static final int NETWORK_DISCONNECTION_EVENT = 37;
+ static final int NETWORK_DISCONNECTION_EVENT = BASE + 37;
/* Scan results are available */
- static final int SCAN_RESULTS_EVENT = 38;
+ static final int SCAN_RESULTS_EVENT = BASE + 38;
/* Supplicate state changed */
- static final int SUPPLICANT_STATE_CHANGE_EVENT = 39;
+ static final int SUPPLICANT_STATE_CHANGE_EVENT = BASE + 39;
/* Password failure and EAP authentication failure */
- static final int AUTHENTICATION_FAILURE_EVENT = 40;
+ static final int AUTHENTICATION_FAILURE_EVENT = BASE + 40;
/* WPS overlap detected */
- static final int WPS_OVERLAP_EVENT = 41;
+ static final int WPS_OVERLAP_EVENT = BASE + 41;
/* Supplicant commands */
/* Is supplicant alive ? */
- static final int CMD_PING_SUPPLICANT = 51;
+ static final int CMD_PING_SUPPLICANT = BASE + 51;
/* Add/update a network configuration */
- static final int CMD_ADD_OR_UPDATE_NETWORK = 52;
+ static final int CMD_ADD_OR_UPDATE_NETWORK = BASE + 52;
/* Delete a network */
- static final int CMD_REMOVE_NETWORK = 53;
+ static final int CMD_REMOVE_NETWORK = BASE + 53;
/* Enable a network. The device will attempt a connection to the given network. */
- static final int CMD_ENABLE_NETWORK = 54;
+ static final int CMD_ENABLE_NETWORK = BASE + 54;
/* Enable all networks */
- static final int CMD_ENABLE_ALL_NETWORKS = 55;
+ static final int CMD_ENABLE_ALL_NETWORKS = BASE + 55;
/* Disable a network. The device does not attempt a connection to the given network. */
- static final int CMD_DISABLE_NETWORK = 56;
+ static final int CMD_DISABLE_NETWORK = BASE + 56;
/* Blacklist network. De-prioritizes the given BSSID for connection. */
- static final int CMD_BLACKLIST_NETWORK = 57;
+ static final int CMD_BLACKLIST_NETWORK = BASE + 57;
/* Clear the blacklist network list */
- static final int CMD_CLEAR_BLACKLIST = 58;
+ static final int CMD_CLEAR_BLACKLIST = BASE + 58;
/* Save configuration */
- static final int CMD_SAVE_CONFIG = 59;
+ static final int CMD_SAVE_CONFIG = BASE + 59;
/* Supplicant commands after driver start*/
/* Initiate a scan */
- static final int CMD_START_SCAN = 71;
+ static final int CMD_START_SCAN = BASE + 71;
/* Set scan mode. CONNECT_MODE or SCAN_ONLY_MODE */
- static final int CMD_SET_SCAN_MODE = 72;
+ static final int CMD_SET_SCAN_MODE = BASE + 72;
/* Set scan type. SCAN_ACTIVE or SCAN_PASSIVE */
- static final int CMD_SET_SCAN_TYPE = 73;
+ static final int CMD_SET_SCAN_TYPE = BASE + 73;
/* Disconnect from a network */
- static final int CMD_DISCONNECT = 74;
+ static final int CMD_DISCONNECT = BASE + 74;
/* Reconnect to a network */
- static final int CMD_RECONNECT = 75;
+ static final int CMD_RECONNECT = BASE + 75;
/* Reassociate to a network */
- static final int CMD_REASSOCIATE = 76;
+ static final int CMD_REASSOCIATE = BASE + 76;
/* Controls power mode and suspend mode optimizations
*
* When high perf mode is enabled, power mode is set to
@@ -267,19 +272,19 @@
* - turn off roaming
* - DTIM wake up settings
*/
- static final int CMD_SET_HIGH_PERF_MODE = 77;
+ static final int CMD_SET_HIGH_PERF_MODE = BASE + 77;
/* Set the country code */
- static final int CMD_SET_COUNTRY_CODE = 80;
+ static final int CMD_SET_COUNTRY_CODE = BASE + 80;
/* Request connectivity manager wake lock before driver stop */
- static final int CMD_REQUEST_CM_WAKELOCK = 81;
+ static final int CMD_REQUEST_CM_WAKELOCK = BASE + 81;
/* Enables RSSI poll */
- static final int CMD_ENABLE_RSSI_POLL = 82;
+ static final int CMD_ENABLE_RSSI_POLL = BASE + 82;
/* RSSI poll */
- static final int CMD_RSSI_POLL = 83;
+ static final int CMD_RSSI_POLL = BASE + 83;
/* Set up packet filtering */
- static final int CMD_START_PACKET_FILTERING = 84;
+ static final int CMD_START_PACKET_FILTERING = BASE + 84;
/* Clear packet filter */
- static final int CMD_STOP_PACKET_FILTERING = 85;
+ static final int CMD_STOP_PACKET_FILTERING = BASE + 85;
/* Connect to a specified network (network id
* or WifiConfiguration) This involves increasing
* the priority of the network, enabling the network
@@ -288,33 +293,33 @@
* an existing network. All the networks get enabled
* upon a successful connection or a failure.
*/
- static final int CMD_CONNECT_NETWORK = 86;
+ static final int CMD_CONNECT_NETWORK = BASE + 86;
/* Save the specified network. This involves adding
* an enabled network (if new) and updating the
* config and issuing a save on supplicant config.
*/
- static final int CMD_SAVE_NETWORK = 87;
+ static final int CMD_SAVE_NETWORK = BASE + 87;
/* Delete the specified network. This involves
* removing the network and issuing a save on
* supplicant config.
*/
- static final int CMD_FORGET_NETWORK = 88;
+ static final int CMD_FORGET_NETWORK = BASE + 88;
/* Start Wi-Fi protected setup */
- static final int CMD_START_WPS = 89;
+ static final int CMD_START_WPS = BASE + 89;
/* Set the frequency band */
- static final int CMD_SET_FREQUENCY_BAND = 90;
+ static final int CMD_SET_FREQUENCY_BAND = BASE + 90;
/* Enable background scan for configured networks */
- static final int CMD_ENABLE_BACKGROUND_SCAN = 91;
+ static final int CMD_ENABLE_BACKGROUND_SCAN = BASE + 91;
/* Commands from/to the SupplicantStateTracker */
/* Reset the supplicant state tracker */
- static final int CMD_RESET_SUPPLICANT_STATE = 111;
+ static final int CMD_RESET_SUPPLICANT_STATE = BASE + 111;
/* Commands/events reported by WpsStateMachine */
/* Indicates the completion of WPS activity */
- static final int WPS_COMPLETED_EVENT = 121;
+ static final int WPS_COMPLETED_EVENT = BASE + 121;
/* Reset the WPS state machine */
- static final int CMD_RESET_WPS_STATE = 122;
+ static final int CMD_RESET_WPS_STATE = BASE + 122;
private static final int CONNECT_MODE = 1;
private static final int SCAN_ONLY_MODE = 2;
@@ -335,8 +340,11 @@
*/
private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
- private static final int POWER_MODE_ACTIVE = 1;
- private static final int POWER_MODE_AUTO = 0;
+ static final int POWER_MODE_ACTIVE = 1;
+ static final int POWER_MODE_AUTO = 0;
+
+ /* Tracks the power mode for restoration after a DHCP request/renewal goes through */
+ private int mPowerMode = POWER_MODE_AUTO;
/**
* See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
@@ -1389,8 +1397,10 @@
*/
NetworkUtils.resetConnections(mInterfaceName);
- if (!NetworkUtils.stopDhcp(mInterfaceName)) {
- Log.e(TAG, "Could not stop DHCP");
+ if (mDhcpStateMachine != null) {
+ mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
+ mDhcpStateMachine.quit();
+ mDhcpStateMachine = null;
}
/* Disable interface */
@@ -1416,6 +1426,100 @@
}
+ void handlePreDhcpSetup() {
+ if (!mBluetoothConnectionActive) {
+ /*
+ * There are problems setting the Wi-Fi driver's power
+ * mode to active when bluetooth coexistence mode is
+ * enabled or sense.
+ * <p>
+ * We set Wi-Fi to active mode when
+ * obtaining an IP address because we've found
+ * compatibility issues with some routers with low power
+ * mode.
+ * <p>
+ * In order for this active power mode to properly be set,
+ * we disable coexistence mode until we're done with
+ * obtaining an IP address. One exception is if we
+ * are currently connected to a headset, since disabling
+ * coexistence would interrupt that connection.
+ */
+ // Disable the coexistence mode
+ WifiNative.setBluetoothCoexistenceModeCommand(
+ WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
+ }
+
+ mPowerMode = WifiNative.getPowerModeCommand();
+ if (mPowerMode < 0) {
+ // Handle the case where supplicant driver does not support
+ // getPowerModeCommand.
+ mPowerMode = WifiStateMachine.POWER_MODE_AUTO;
+ }
+ if (mPowerMode != WifiStateMachine.POWER_MODE_ACTIVE) {
+ WifiNative.setPowerModeCommand(WifiStateMachine.POWER_MODE_ACTIVE);
+ }
+ }
+
+
+ void handlePostDhcpSetup() {
+ /* restore power mode */
+ WifiNative.setPowerModeCommand(mPowerMode);
+
+ // Set the coexistence mode back to its default value
+ WifiNative.setBluetoothCoexistenceModeCommand(
+ WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
+ }
+
+ private void handleSuccessfulIpConfiguration(DhcpInfoInternal dhcpInfoInternal) {
+ synchronized (mDhcpInfoInternal) {
+ mDhcpInfoInternal = dhcpInfoInternal;
+ }
+ mLastSignalLevel = -1; // force update of signal strength
+ WifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
+ InetAddress addr = NetworkUtils.numericToInetAddress(dhcpInfoInternal.ipAddress);
+ mWifiInfo.setInetAddress(addr);
+ if (getNetworkDetailedState() == DetailedState.CONNECTED) {
+ //DHCP renewal in connected state
+ LinkProperties linkProperties = dhcpInfoInternal.makeLinkProperties();
+ linkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
+ linkProperties.setInterfaceName(mInterfaceName);
+ if (!linkProperties.equals(mLinkProperties)) {
+ Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId
+ + " old: " + mLinkProperties + "new: " + linkProperties);
+ NetworkUtils.resetConnections(mInterfaceName);
+ mLinkProperties = linkProperties;
+ sendLinkConfigurationChangedBroadcast();
+ }
+ } else {
+ configureLinkProperties();
+ setNetworkDetailedState(DetailedState.CONNECTED);
+ sendNetworkStateChangeBroadcast(mLastBssid);
+ }
+ }
+
+ private void handleFailedIpConfiguration() {
+ Log.e(TAG, "IP configuration failed");
+
+ mWifiInfo.setInetAddress(null);
+ /**
+ * If we've exceeded the maximum number of retries for DHCP
+ * to a given network, disable the network
+ */
+ if (++mReconnectCount > getMaxDhcpRetries()) {
+ Log.e(TAG, "Failed " +
+ mReconnectCount + " times, Disabling " + mLastNetworkId);
+ WifiConfigStore.disableNetwork(mLastNetworkId);
+ mReconnectCount = 0;
+ }
+
+ /* DHCP times out after about 30 seconds, we do a
+ * disconnect and an immediate reconnect to try again
+ */
+ WifiNative.disconnectCommand();
+ WifiNative.reconnectCommand();
+
+ }
+
/*********************************************************
* Notifications from WifiMonitor
@@ -1587,6 +1691,8 @@
case CMD_FORGET_NETWORK:
case CMD_RSSI_POLL:
case CMD_ENABLE_ALL_NETWORKS:
+ case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
+ case DhcpStateMachine.CMD_POST_DHCP_ACTION:
break;
case CMD_START_WPS:
/* Return failure when the state machine cannot handle WPS initiation*/
@@ -2459,74 +2565,18 @@
}
class ConnectingState extends State {
- boolean mModifiedBluetoothCoexistenceMode;
- int mPowerMode;
- boolean mUseStaticIp;
- Thread mDhcpThread;
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
- mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
- if (!mUseStaticIp) {
- mDhcpThread = null;
- mModifiedBluetoothCoexistenceMode = false;
- mPowerMode = POWER_MODE_AUTO;
- if (!mBluetoothConnectionActive) {
- /*
- * There are problems setting the Wi-Fi driver's power
- * mode to active when bluetooth coexistence mode is
- * enabled or sense.
- * <p>
- * We set Wi-Fi to active mode when
- * obtaining an IP address because we've found
- * compatibility issues with some routers with low power
- * mode.
- * <p>
- * In order for this active power mode to properly be set,
- * we disable coexistence mode until we're done with
- * obtaining an IP address. One exception is if we
- * are currently connected to a headset, since disabling
- * coexistence would interrupt that connection.
- */
- mModifiedBluetoothCoexistenceMode = true;
-
- // Disable the coexistence mode
- WifiNative.setBluetoothCoexistenceModeCommand(
- WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
- }
-
- mPowerMode = WifiNative.getPowerModeCommand();
- if (mPowerMode < 0) {
- // Handle the case where supplicant driver does not support
- // getPowerModeCommand.
- mPowerMode = POWER_MODE_AUTO;
- }
- if (mPowerMode != POWER_MODE_ACTIVE) {
- WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
- }
-
- Log.d(TAG, "DHCP request started");
- mDhcpThread = new Thread(new Runnable() {
- public void run() {
- DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
- if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal)) {
- Log.d(TAG, "DHCP request succeeded");
- synchronized (mDhcpInfoInternal) {
- mDhcpInfoInternal = dhcpInfoInternal;
- }
- WifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
- sendMessage(CMD_IP_CONFIG_SUCCESS);
- } else {
- Log.d(TAG, "DHCP request failed: " +
- NetworkUtils.getDhcpError());
- sendMessage(CMD_IP_CONFIG_FAILURE);
- }
- }
- });
- mDhcpThread.start();
+ if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+ //start DHCP
+ mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
+ mContext, WifiStateMachine.this, mInterfaceName);
+ mDhcpStateMachine.registerForPreDhcpNotification();
+ mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
} else {
DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration(
mLastNetworkId);
@@ -2538,16 +2588,13 @@
try {
netd.setInterfaceConfig(mInterfaceName, ifcg);
Log.v(TAG, "Static IP configuration succeeded");
- synchronized (mDhcpInfoInternal) {
- mDhcpInfoInternal = dhcpInfoInternal;
- }
- sendMessage(CMD_IP_CONFIG_SUCCESS);
+ sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
} catch (RemoteException re) {
Log.v(TAG, "Static IP configuration failed: " + re);
- sendMessage(CMD_IP_CONFIG_FAILURE);
+ sendMessage(CMD_STATIC_IP_FAILURE);
} catch (IllegalStateException e) {
Log.v(TAG, "Static IP configuration failed: " + e);
- sendMessage(CMD_IP_CONFIG_FAILURE);
+ sendMessage(CMD_STATIC_IP_FAILURE);
}
}
}
@@ -2556,44 +2603,26 @@
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
switch(message.what) {
- case CMD_IP_CONFIG_SUCCESS:
- mLastSignalLevel = -1; // force update of signal strength
- InetAddress addr;
- synchronized (mDhcpInfoInternal) {
- addr = NetworkUtils.numericToInetAddress(mDhcpInfoInternal.ipAddress);
+ case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
+ handlePreDhcpSetup();
+ mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
+ break;
+ case DhcpStateMachine.CMD_POST_DHCP_ACTION:
+ handlePostDhcpSetup();
+ if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
+ handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
+ transitionTo(mConnectedState);
+ } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
+ handleFailedIpConfiguration();
+ transitionTo(mDisconnectingState);
}
- mWifiInfo.setInetAddress(addr);
- configureLinkProperties();
- if (getNetworkDetailedState() == DetailedState.CONNECTED) {
- sendLinkConfigurationChangedBroadcast();
- } else {
- setNetworkDetailedState(DetailedState.CONNECTED);
- sendNetworkStateChangeBroadcast(mLastBssid);
- }
- //TODO: The framework is not detecting a DHCP renewal and a possible
- //IP change. we should detect this and send out a config change broadcast
+ break;
+ case CMD_STATIC_IP_SUCCESS:
+ handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
transitionTo(mConnectedState);
break;
- case CMD_IP_CONFIG_FAILURE:
- mWifiInfo.setInetAddress(null);
-
- Log.e(TAG, "IP configuration failed");
- /**
- * If we've exceeded the maximum number of retries for DHCP
- * to a given network, disable the network
- */
- if (++mReconnectCount > getMaxDhcpRetries()) {
- Log.e(TAG, "Failed " +
- mReconnectCount + " times, Disabling " + mLastNetworkId);
- WifiConfigStore.disableNetwork(mLastNetworkId);
- mReconnectCount = 0;
- }
-
- /* DHCP times out after about 30 seconds, we do a
- * disconnect and an immediate reconnect to try again
- */
- WifiNative.disconnectCommand();
- WifiNative.reconnectCommand();
+ case CMD_STATIC_IP_FAILURE:
+ handleFailedIpConfiguration();
transitionTo(mDisconnectingState);
break;
case CMD_DISCONNECT:
@@ -2637,23 +2666,6 @@
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
return HANDLED;
}
-
- @Override
- public void exit() {
- /* reset power state & bluetooth coexistence if on DHCP */
- if (!mUseStaticIp) {
- if (mPowerMode != POWER_MODE_ACTIVE) {
- WifiNative.setPowerModeCommand(mPowerMode);
- }
-
- if (mModifiedBluetoothCoexistenceMode) {
- // Set the coexistence mode back to its default value
- WifiNative.setBluetoothCoexistenceModeCommand(
- WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
- }
- }
-
- }
}
class ConnectedState extends State {
@@ -2671,6 +2683,19 @@
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
boolean eventLoggingEnabled = true;
switch (message.what) {
+ case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
+ handlePreDhcpSetup();
+ mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
+ break;
+ case DhcpStateMachine.CMD_POST_DHCP_ACTION:
+ handlePostDhcpSetup();
+ if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
+ handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
+ } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
+ handleFailedIpConfiguration();
+ transitionTo(mDisconnectingState);
+ }
+ break;
case CMD_DISCONNECT:
WifiNative.disconnectCommand();
transitionTo(mDisconnectingState);