Merge "Import revised translations.  DO NOT MERGE" into honeycomb
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 8c55bf3..78d7991 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -122,13 +122,13 @@
      *
      *          final float alpha = 0.8;
      *
-     *          gravity[0] = alpha * gravity[0] + (1 - alpha) * event.data[0];
-     *          gravity[1] = alpha * gravity[1] + (1 - alpha) * event.data[1];
-     *          gravity[2] = alpha * gravity[2] + (1 - alpha) * event.data[2];
+     *          gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
+     *          gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
+     *          gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
      *
-     *          linear_acceleration[0] = event.data[0] - gravity[0];
-     *          linear_acceleration[1] = event.data[1] - gravity[1];
-     *          linear_acceleration[2] = event.data[2] - gravity[2];
+     *          linear_acceleration[0] = event.values[0] - gravity[0];
+     *          linear_acceleration[1] = event.values[1] - gravity[1];
+     *          linear_acceleration[2] = event.values[2] - gravity[2];
      *     }
      * </pre>
      *
@@ -186,9 +186,9 @@
      *     {
      *          if (timestamp != 0) {
      *              final float dT = (event.timestamp - timestamp) * NS2S;
-     *              angle[0] += event.data[0] * dT;
-     *              angle[1] += event.data[1] * dT;
-     *              angle[2] += event.data[2] * dT;
+     *              angle[0] += event.values[0] * dT;
+     *              angle[1] += event.values[1] * dT;
+     *              angle[2] += event.values[2] * dT;
      *          }
      *          timestamp = event.timestamp;
      *     }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 257f275..1718189 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1797,7 +1797,6 @@
          */
         public static final String[] SETTINGS_TO_BACKUP = {
             STAY_ON_WHILE_PLUGGED_IN,
-            WIFI_SLEEP_POLICY,
             WIFI_USE_STATIC_IP,
             WIFI_STATIC_IP,
             WIFI_STATIC_GATEWAY,
@@ -3704,7 +3703,6 @@
             TTS_ENABLED_PLUGINS,
             WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
             WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
-            WIFI_COUNTRY_CODE,
             WIFI_NUM_OPEN_NETWORKS_KEPT,
             MOUNT_PLAY_NOTIFICATION_SND,
             MOUNT_UMS_AUTOSTART,
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 3b102996..e1b8d29 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -575,7 +575,6 @@
     return doBooleanCommand(cmdstr, "OK");
 }
 
-
 static jboolean android_net_wifi_doDhcpRequest(JNIEnv* env, jobject clazz, jobject info)
 {
     jint ipaddr, gateway, mask, dns1, dns2, server, lease;
@@ -598,6 +597,18 @@
     return env->NewStringUTF(::get_dhcp_error_string());
 }
 
+static void android_net_wifi_enableBackgroundScan(JNIEnv* env, jobject clazz, jboolean enable)
+{
+    //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml
+    //and will need an update if the names are changed
+    if (enable) {
+        doBooleanCommand("DRIVER BGSCAN-START", "OK");
+    }
+    else {
+        doBooleanCommand("DRIVER BGSCAN-STOP", "OK");
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 /*
@@ -667,6 +678,7 @@
         (void*) android_net_wifi_setCountryCodeCommand},
     { "doDhcpRequest", "(Landroid/net/DhcpInfo;)Z", (void*) android_net_wifi_doDhcpRequest },
     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_wifi_getDhcpError },
+    { "enableBackgroundScan", "(Z)V", (void*) android_net_wifi_enableBackgroundScan},
 };
 
 int register_android_net_wifi_WifiManager(JNIEnv* env)
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e0c26d4..aa3f722 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -194,6 +194,13 @@
     <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
     <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
 
+    <!-- Boolean indicating whether the wifi chipset supports background scanning mechanism.
+         This mechanism allows the host to remain in suspend state and the dongle to actively
+         scan and wake the host when a configured SSID is detected by the dongle. This chipset
+         capability can provide power savings when wifi needs to be always kept on.
+         The driver commands needed to support the feature are BGSCAN-START and BGSCAN-STOP -->
+    <bool translatable="false" name="config_wifi_background_scan_support">false</bool>
+
     <!-- Flag indicating whether the keyguard should be bypassed when
          the slider is open.  This can be set or unset depending how easily
          the slider can be opened (for example, in a pocket or purse). -->
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index df8869e..7f6f0105 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -2,20 +2,20 @@
 sdk.redirect=0
 
 sdk.win_installer=installer_r10-windows.exe
-sdk.win_installer_bytes=32845713
-sdk.win_installer_checksum=4e4356c472a6271ac9c062df0219dcb3
+sdk.win_installer_bytes=32878481
+sdk.win_installer_checksum=8ffa2dd734829d0bbd3ea601b50b36c7
 
 sdk.win_download=android-sdk_r10-windows.zip
-sdk.win_bytes=30112516
-sdk.win_checksum=643a75d99f5d4ca39dcf743fe894d599
+sdk.win_bytes=32832260
+sdk.win_checksum=1e42b8f528d9ca6d9b887c58c6f1b9a2
 
 sdk.mac_download=android-sdk_r10-mac_x86.zip
-sdk.mac_bytes=28224540
-sdk.mac_checksum=4d0a99a458e4f4bde65a01f8545f27e9
+sdk.mac_bytes=28847132
+sdk.mac_checksum=e3aa5578a6553b69cc36659c9505be3f
 
 sdk.linux_download=android-sdk_r10-linux_x86.tgz
-sdk.linux_bytes=26556013
-sdk.linux_checksum=10cafdd44771bfe2ba9d4440886389e7
+sdk.linux_bytes=26981997
+sdk.linux_checksum=c022dda3a56c8a67698e6a39b0b1a4e0
 
 @jd:body
 
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index d2f2ec7..22583f7 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -94,6 +94,9 @@
     private boolean mDeviceIdle;
     private int mPluggedType;
 
+    /* Chipset supports background scan */
+    private final boolean mBackgroundScanSupported;
+
     // true if the user enabled Wifi while in airplane mode
     private AtomicBoolean mAirplaneModeOverwridden = new AtomicBoolean(false);
 
@@ -305,6 +308,9 @@
                 Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l;
         mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(new Handler());
         mNotificationEnabledSettingObserver.register();
+
+        mBackgroundScanSupported = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_wifi_background_scan_support);
     }
 
     /**
@@ -874,6 +880,9 @@
                 // because of any locks so clear that tracking immediately.
                 reportStartWorkSource();
                 mWifiStateMachine.enableRssiPolling(true);
+                if (mBackgroundScanSupported) {
+                    mWifiStateMachine.enableBackgroundScan(false);
+                }
                 mWifiStateMachine.enableAllNetworks();
                 updateWifiState();
             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
@@ -882,6 +891,9 @@
                 }
                 mScreenOff = true;
                 mWifiStateMachine.enableRssiPolling(false);
+                if (mBackgroundScanSupported) {
+                    mWifiStateMachine.enableBackgroundScan(true);
+                }
                 /*
                  * Set a timer to put Wi-Fi to sleep, but only if the screen is off
                  * AND the "stay on while plugged in" setting doesn't match the
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 91b19a9..657377f 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -244,6 +244,8 @@
 
     Object     mLastNITZTimeInfo;
 
+    private static final String WIFI_ONLY_CARRIER = "wifi-only";
+
     //***** Events
 
     static final int EVENT_SEND                 = 1;
@@ -656,14 +658,22 @@
         Looper looper = mSenderThread.getLooper();
         mSender = new RILSender(looper);
 
-        mReceiver = new RILReceiver();
-        mReceiverThread = new Thread(mReceiver, "RILReceiver");
-        mReceiverThread.start();
+        // TODO: Provide a common API for determining if a
+        // device is wifi-only. bug: 3480713
+        String carrier = SystemProperties.get("ro.carrier");
+        if (WIFI_ONLY_CARRIER.equals(carrier)) {
+            riljLog("Not starting RILReceiver: wifi-only");
+        } else {
+            riljLog("Starting RILReceiver");
+            mReceiver = new RILReceiver();
+            mReceiverThread = new Thread(mReceiver, "RILReceiver");
+            mReceiverThread.start();
 
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_SCREEN_ON);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        context.registerReceiver(mIntentReceiver, filter);
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_SCREEN_ON);
+            filter.addAction(Intent.ACTION_SCREEN_OFF);
+            context.registerReceiver(mIntentReceiver, filter);
+        }
     }
 
     //***** CommandsInterface implementation
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 030048f..a113c5c 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -176,4 +176,6 @@
      * @return the event string sent by the supplicant.
      */
     public native static String waitForEvent();
+
+    public native static void enableBackgroundScan(boolean enable);
 }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 4d0acdd..65f2a19 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -112,9 +112,11 @@
     private String mLastBssid;
     private int mLastNetworkId;
     private boolean mEnableRssiPolling = false;
+    private boolean mEnableBackgroundScan = false;
     private int mRssiPollToken = 0;
     private int mReconnectCount = 0;
     private boolean mIsScanMode = false;
+    private boolean mScanResultIsPending = false;
 
     private boolean mBluetoothConnectionActive = false;
 
@@ -300,6 +302,8 @@
     static final int CMD_START_WPS                        = 89;
     /* Set the frequency band */
     static final int CMD_SET_FREQUENCY_BAND               = 90;
+    /* Enable background scan for configured networks */
+    static final int CMD_ENABLE_BACKGROUND_SCAN           = 91;
 
     /* Commands from/to the SupplicantStateTracker */
     /* Reset the supplicant state tracker */
@@ -819,6 +823,10 @@
        sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
     }
 
+    public void enableBackgroundScan(boolean enabled) {
+       sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0));
+    }
+
     public void enableAllNetworks() {
         sendMessage(CMD_ENABLE_ALL_NETWORKS);
     }
@@ -1495,6 +1503,9 @@
                 case CMD_ENABLE_RSSI_POLL:
                     mEnableRssiPolling = (message.arg1 == 1);
                     break;
+                case CMD_ENABLE_BACKGROUND_SCAN:
+                    mEnableBackgroundScan = (message.arg1 == 1);
+                    break;
                     /* Discard */
                 case CMD_LOAD_DRIVER:
                 case CMD_UNLOAD_DRIVER:
@@ -1930,6 +1941,7 @@
                     eventLoggingEnabled = false;
                     setScanResults(WifiNative.scanResultsCommand());
                     sendScanResultsAvailableBroadcast();
+                    mScanResultIsPending = false;
                     break;
                 case CMD_PING_SUPPLICANT:
                     boolean ok = WifiNative.pingCommand();
@@ -2137,6 +2149,7 @@
                 case CMD_START_SCAN:
                     eventLoggingEnabled = false;
                     WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
+                    mScanResultIsPending = true;
                     break;
                 case CMD_SET_HIGH_PERF_MODE:
                     setHighPerfModeEnabledNative(message.arg1 == 1);
@@ -2626,8 +2639,8 @@
                      * back to CONNECT_MODE.
                      */
                     WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
-                    WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
-                    break;
+                    /* Have the parent state handle the rest */
+                    return NOT_HANDLED;
                     /* Ignore connection to same network */
                 case CMD_CONNECT_NETWORK:
                     int netId = message.arg1;
@@ -2716,21 +2729,35 @@
     }
 
     class DisconnectedState extends HierarchicalState {
+        private boolean mAlarmEnabled = false;
         @Override
         public void enter() {
             if (DBG) Log.d(TAG, getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
-            /**
-             * In a disconnected state, an infrequent scan that wakes
-             * up the device is needed to ensure a user connects to
-             * an access point on the move
+            /*
+             * We initiate background scanning if it is enabled, otherwise we
+             * initiate an infrequent scan that wakes up the device to ensure
+             * a user connects to an access point on the move
              */
-            long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
+            if (mEnableBackgroundScan) {
+                /* If a regular scan result is pending, do not initiate background
+                 * scan until the scan results are returned. This is needed because
+                 * initiating a background scan will cancel the regular scan and
+                 * scan results will not be returned until background scanning is
+                 * cleared
+                 */
+                if (!mScanResultIsPending) {
+                    WifiNative.enableBackgroundScan(true);
+                }
+            } else {
+                long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
                     Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
 
-            mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
+                mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                     System.currentTimeMillis() + scanMs, scanMs, mScanIntent);
+                mAlarmEnabled = true;
+            }
         }
         @Override
         public boolean processMessage(Message message) {
@@ -2745,6 +2772,10 @@
                         transitionTo(mScanModeState);
                     }
                     break;
+                case CMD_ENABLE_BACKGROUND_SCAN:
+                    mEnableBackgroundScan = (message.arg1 == 1);
+                    WifiNative.enableBackgroundScan(mEnableBackgroundScan);
+                    break;
                     /* Ignore network disconnect */
                 case NETWORK_DISCONNECTION_EVENT:
                     break;
@@ -2753,6 +2784,20 @@
                     setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
                     /* DriverStartedState does the rest of the handling */
                     return NOT_HANDLED;
+                case CMD_START_SCAN:
+                    /* Disable background scan temporarily during a regular scan */
+                    if (mEnableBackgroundScan) {
+                        WifiNative.enableBackgroundScan(false);
+                    }
+                    /* Handled in parent state */
+                    return NOT_HANDLED;
+                case SCAN_RESULTS_EVENT:
+                    /* Re-enable background scan when a pending scan result is received */
+                    if (mEnableBackgroundScan && mScanResultIsPending) {
+                        WifiNative.enableBackgroundScan(true);
+                    }
+                    /* Handled in parent state */
+                    return NOT_HANDLED;
                 default:
                     return NOT_HANDLED;
             }
@@ -2762,7 +2807,14 @@
 
         @Override
         public void exit() {
-            mAlarmManager.cancel(mScanIntent);
+            /* No need for a background scan upon exit from a disconnected state */
+            if (mEnableBackgroundScan) {
+                WifiNative.enableBackgroundScan(false);
+            }
+            if (mAlarmEnabled) {
+                mAlarmManager.cancel(mScanIntent);
+                mAlarmEnabled = false;
+            }
         }
     }