Merge "Finishing light linking." into graphics-dev
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f5add25..d569e20 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -113,7 +113,10 @@
      * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
      * that you take care of task management as described in the
      * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
-     * Stack</a> document.
+     * Stack</a> document.  In particular, make sure to read the notification section
+     * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
+     * Notifications</a> for the correct ways to launch an application from a
+     * notification.
      */
     public PendingIntent contentIntent;
 
@@ -765,7 +768,9 @@
          * Supply a {@link PendingIntent} to send when the notification is clicked.
          * If you do not supply an intent, you can now add PendingIntents to individual
          * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
-         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
+         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.  Be sure to
+         * read {@link Notification#contentIntent Notification.contentIntent} for
+         * how to correctly use this.
          */
         public Builder setContentIntent(PendingIntent intent) {
             mContentIntent = intent;
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e1bc275..cdf235d 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -219,6 +219,36 @@
     public static final int THREAD_PRIORITY_LESS_FAVORABLE = +1;
 
     /**
+     * Default scheduling policy
+     * @hide
+     */
+    public static final int SCHED_OTHER = 0;
+
+    /**
+     * First-In First-Out scheduling policy
+     * @hide
+     */
+    public static final int SCHED_FIFO = 1;
+
+    /**
+     * Round-Robin scheduling policy
+     * @hide
+     */
+    public static final int SCHED_RR = 2;
+
+    /**
+     * Batch scheduling policy
+     * @hide
+     */
+    public static final int SCHED_BATCH = 3;
+
+    /**
+     * Idle scheduling policy
+     * @hide
+     */
+    public static final int SCHED_IDLE = 5;
+
+    /**
      * Default thread group - gets a 'normal' share of the CPU
      * @hide
      */
@@ -675,6 +705,24 @@
             throws IllegalArgumentException;
     
     /**
+     * Set the scheduling policy and priority of a thread, based on Linux.
+     *
+     * @param tid The identifier of the thread/process to change.
+     * @param policy A Linux scheduling policy such as SCHED_OTHER etc.
+     * @param priority A Linux priority level in a range appropriate for the given policy.
+     *
+     * @throws IllegalArgumentException Throws IllegalArgumentException if
+     * <var>tid</var> does not exist, or if <var>priority</var> is out of range for the policy.
+     * @throws SecurityException Throws SecurityException if your process does
+     * not have permission to modify the given thread, or to use the given
+     * scheduling policy or priority.
+     *
+     * {@hide}
+     */
+    public static final native void setThreadScheduler(int tid, int policy, int priority)
+            throws IllegalArgumentException;
+
+    /**
      * Determine whether the current environment supports multiple processes.
      * 
      * @return Returns true if the system can run in multiple processes, else
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 168baad..770f8ac 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -327,6 +327,15 @@
  * property to {@code device-dpi}. This stops Android from performing scaling in your web page and
  * allows you to make the necessary adjustments for each density via CSS and JavaScript.</p>
  *
+ * <h3>HTML5 Video support</h3>
+ *
+ * <p>In order to support inline HTML5 video in your application, you need to have hardware
+ * acceleration turned on, and set a {@link android.webkit.WebChromeClient}. For full screen support,
+ * implementations of {@link WebChromeClient#onShowCustomView(View, WebChromeClient.CustomViewCallback)}
+ * and {@link WebChromeClient#onHideCustomView()} are required,
+ * {@link WebChromeClient#getVideoLoadingProgressView()} is optional.
+ * </p>
+ *
  *
  */
 @Widget
@@ -611,6 +620,7 @@
     private boolean mIsPaused;
 
     private HitTestResult mInitialHitTestResult;
+    private WebKitHitTest mFocusedNode;
 
     /**
      * Customizable constant
@@ -1073,6 +1083,15 @@
     }
 
     /**
+     * Refer to {@link WebView#requestFocusNodeHref(Message)} for more information
+     */
+    static class FocusNodeHref {
+        static final String TITLE = "title";
+        static final String URL = "url";
+        static final String SRC = "src";
+    }
+
+    /**
      * Construct a new WebView with a Context object.
      * @param context A Context object used to access application assets.
      */
@@ -2704,6 +2723,14 @@
         }
         int contentX = viewToContentX(mLastTouchX + mScrollX);
         int contentY = viewToContentY(mLastTouchY + mScrollY);
+        if (mFocusedNode != null && mFocusedNode.mHitTestX == contentX
+                && mFocusedNode.mHitTestY == contentY) {
+            hrefMsg.getData().putString(FocusNodeHref.URL, mFocusedNode.mLinkUrl);
+            hrefMsg.getData().putString(FocusNodeHref.TITLE, mFocusedNode.mAnchorText);
+            hrefMsg.getData().putString(FocusNodeHref.SRC, mFocusedNode.mImageUrl);
+            hrefMsg.sendToTarget();
+            return;
+        }
         if (nativeHasCursorNode()) {
             Rect cursorBounds = nativeGetCursorRingBounds();
             if (!cursorBounds.contains(contentX, contentY)) {
@@ -3742,6 +3769,8 @@
         nativeScrollLayer(mCurrentScrollingLayerId, x, y);
         mScrollingLayerRect.left = x;
         mScrollingLayerRect.top = y;
+        mWebViewCore.sendMessage(WebViewCore.EventHub.SCROLL_LAYER, mCurrentScrollingLayerId,
+                mScrollingLayerRect);
         onScrollChanged(mScrollX, mScrollY, mScrollX, mScrollY);
         invalidate();
     }
@@ -8837,13 +8866,25 @@
 
                 case HIT_TEST_RESULT:
                     WebKitHitTest hit = (WebKitHitTest) msg.obj;
+                    mFocusedNode = hit;
                     setTouchHighlightRects(hit != null ? hit.mTouchRects : null);
                     if (hit == null) {
                         mInitialHitTestResult = null;
                     } else {
                         mInitialHitTestResult = new HitTestResult();
-                        mInitialHitTestResult.mType = hit.mType;
-                        mInitialHitTestResult.mExtra = hit.mExtra;
+                        if (hit.mLinkUrl != null) {
+                            mInitialHitTestResult.mType = HitTestResult.SRC_ANCHOR_TYPE;
+                            mInitialHitTestResult.mExtra = hit.mLinkUrl;
+                            if (hit.mImageUrl != null) {
+                                mInitialHitTestResult.mType = HitTestResult.SRC_IMAGE_ANCHOR_TYPE;
+                                mInitialHitTestResult.mExtra = hit.mImageUrl;
+                            }
+                        } else if (hit.mImageUrl != null) {
+                            mInitialHitTestResult.mType = HitTestResult.IMAGE_TYPE;
+                            mInitialHitTestResult.mExtra = hit.mImageUrl;
+                        } else if (hit.mEditable) {
+                            mInitialHitTestResult.mType = HitTestResult.EDIT_TEXT_TYPE;
+                        }
                     }
                     break;
 
@@ -8882,8 +8923,10 @@
     }
 
     private void setTouchHighlightRects(Rect[] rects) {
-        invalidate(mTouchHighlightRegion.getBounds());
-        mTouchHighlightRegion.setEmpty();
+        if (!mTouchHighlightRegion.isEmpty()) {
+            invalidate(mTouchHighlightRegion.getBounds());
+            mTouchHighlightRegion.setEmpty();
+        }
         if (rects != null) {
             for (Rect rect : rects) {
                 Rect viewRect = contentToViewRect(rect);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 824f556..fb9c98a 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -26,6 +26,7 @@
 import android.media.MediaFile;
 import android.net.ProxyProperties;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -37,6 +38,7 @@
 import android.view.MotionEvent;
 import android.view.SurfaceView;
 import android.view.View;
+import android.webkit.WebView.FocusNodeHref;
 
 import junit.framework.Assert;
 
@@ -861,9 +863,19 @@
     }
 
     static class WebKitHitTest {
-        int mType;
-        String mExtra;
+        String mLinkUrl;
+        String mAnchorText;
+        String mImageUrl;
+        String mAltDisplayString;
+        String mTitle;
         Rect[] mTouchRects;
+        boolean mEditable;
+
+        // These are the input values that produced this hit test
+        int mHitTestX;
+        int mHitTestY;
+        int mHitTestSlop;
+        boolean mHitTestMovedMouse;
     }
 
     static class AutoFillData {
@@ -1097,6 +1109,8 @@
 
         static final int HEARTBEAT = 197;
 
+        static final int SCROLL_LAYER = 198;
+
         // private message ids
         private static final int DESTROY =     200;
 
@@ -1512,13 +1526,12 @@
                             break;
 
                         case REQUEST_CURSOR_HREF: {
+                            WebKitHitTest hit = performHitTest(msg.arg1, msg.arg2, 1, false);
                             Message hrefMsg = (Message) msg.obj;
-                            hrefMsg.getData().putString("url",
-                                    nativeRetrieveHref(mNativeClass, msg.arg1, msg.arg2));
-                            hrefMsg.getData().putString("title",
-                                    nativeRetrieveAnchorText(mNativeClass, msg.arg1, msg.arg2));
-                            hrefMsg.getData().putString("src",
-                                    nativeRetrieveImageSource(mNativeClass, msg.arg1, msg.arg2));
+                            Bundle data = hrefMsg.getData();
+                            data.putString(FocusNodeHref.URL,hit.mLinkUrl);
+                            data.putString(FocusNodeHref.TITLE, hit.mAnchorText);
+                            data.putString(FocusNodeHref.SRC, hit.mImageUrl);
                             hrefMsg.sendToTarget();
                             break;
                         }
@@ -1683,8 +1696,7 @@
                                 nativeScrollLayer(mNativeClass,
                                         d.mNativeLayer, d.mNativeLayerRect);
                             }
-                            WebKitHitTest hit = nativeHitTest(mNativeClass,
-                                    d.mX, d.mY, d.mSlop);
+                            WebKitHitTest hit = performHitTest(d.mX, d.mY, d.mSlop, true);
                             mWebView.mPrivateHandler.obtainMessage(
                                     WebView.HIT_TEST_RESULT, hit)
                                     .sendToTarget();
@@ -1708,6 +1720,11 @@
                                 mBrowserFrame.stringByEvaluatingJavaScriptFromString((String) msg.obj);
                             }
                             break;
+                        case SCROLL_LAYER:
+                            int nativeLayer = msg.arg1;
+                            Rect rect = (Rect) msg.obj;
+                            nativeScrollLayer(mNativeClass, nativeLayer,
+                                    rect);
                     }
                 }
             };
@@ -1883,6 +1900,15 @@
     // WebViewCore private methods
     //-------------------------------------------------------------------------
 
+    private WebKitHitTest performHitTest(int x, int y, int slop, boolean moveMouse) {
+        WebKitHitTest hit = nativeHitTest(mNativeClass, x, y, slop, moveMouse);
+        hit.mHitTestX = x;
+        hit.mHitTestY = y;
+        hit.mHitTestSlop = slop;
+        hit.mHitTestMovedMouse = moveMouse;
+        return hit;
+    }
+
     private void clearCache(boolean includeDiskFiles) {
         mBrowserFrame.clearCache();
         if (includeDiskFiles) {
@@ -2933,7 +2959,8 @@
     private native boolean nativeValidNodeAndBounds(int nativeClass, int frame,
             int node, Rect bounds);
 
-    private native WebKitHitTest nativeHitTest(int nativeClass, int x, int y, int slop);
+    private native WebKitHitTest nativeHitTest(int nativeClass, int x, int y,
+            int slop, boolean moveMouse);
 
     private native void nativeAutoFillForm(int nativeClass, int queryId);
     private native void nativeScrollLayer(int nativeClass, int layer, Rect rect);
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
new file mode 100644
index 0000000..3ce95e7
--- /dev/null
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2012 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;
+
+import android.os.FileUtils;
+
+import com.android.internal.util.FileRotator.Reader;
+import com.android.internal.util.FileRotator.Writer;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import libcore.io.IoUtils;
+
+/**
+ * Utility that rotates files over time, similar to {@code logrotate}. There is
+ * a single "active" file, which is periodically rotated into historical files,
+ * and eventually deleted entirely. Files are stored under a specific directory
+ * with a well-known prefix.
+ * <p>
+ * Instead of manipulating files directly, users implement interfaces that
+ * perform operations on {@link InputStream} and {@link OutputStream}. This
+ * enables atomic rewriting of file contents in
+ * {@link #combineActive(Reader, Writer, long)}.
+ * <p>
+ * Users must periodically call {@link #maybeRotate(long)} to perform actual
+ * rotation. Not inherently thread safe.
+ */
+public class FileRotator {
+    private final File mBasePath;
+    private final String mPrefix;
+    private final long mRotateAgeMillis;
+    private final long mDeleteAgeMillis;
+
+    private static final String SUFFIX_BACKUP = ".backup";
+    private static final String SUFFIX_NO_BACKUP = ".no_backup";
+
+    // TODO: provide method to append to active file
+
+    /**
+     * External class that reads data from a given {@link InputStream}. May be
+     * called multiple times when reading rotated data.
+     */
+    public interface Reader {
+        public void read(InputStream in) throws IOException;
+    }
+
+    /**
+     * External class that writes data to a given {@link OutputStream}.
+     */
+    public interface Writer {
+        public void write(OutputStream out) throws IOException;
+    }
+
+    /**
+     * Create a file rotator.
+     *
+     * @param basePath Directory under which all files will be placed.
+     * @param prefix Filename prefix used to identify this rotator.
+     * @param rotateAgeMillis Age in milliseconds beyond which an active file
+     *            may be rotated into a historical file.
+     * @param deleteAgeMillis Age in milliseconds beyond which a rotated file
+     *            may be deleted.
+     */
+    public FileRotator(File basePath, String prefix, long rotateAgeMillis, long deleteAgeMillis) {
+        mBasePath = Preconditions.checkNotNull(basePath);
+        mPrefix = Preconditions.checkNotNull(prefix);
+        mRotateAgeMillis = rotateAgeMillis;
+        mDeleteAgeMillis = deleteAgeMillis;
+
+        // ensure that base path exists
+        mBasePath.mkdirs();
+
+        // recover any backup files
+        for (String name : mBasePath.list()) {
+            if (!name.startsWith(mPrefix)) continue;
+
+            if (name.endsWith(SUFFIX_BACKUP)) {
+                final File backupFile = new File(mBasePath, name);
+                final File file = new File(
+                        mBasePath, name.substring(0, name.length() - SUFFIX_BACKUP.length()));
+
+                // write failed with backup; recover last file
+                backupFile.renameTo(file);
+
+            } else if (name.endsWith(SUFFIX_NO_BACKUP)) {
+                final File noBackupFile = new File(mBasePath, name);
+                final File file = new File(
+                        mBasePath, name.substring(0, name.length() - SUFFIX_NO_BACKUP.length()));
+
+                // write failed without backup; delete both
+                noBackupFile.delete();
+                file.delete();
+            }
+        }
+    }
+
+    /**
+     * Atomically combine data with existing data in currently active file.
+     * Maintains a backup during write, which is restored if the write fails.
+     */
+    public void combineActive(Reader reader, Writer writer, long currentTimeMillis)
+            throws IOException {
+        final String activeName = getActiveName(currentTimeMillis);
+
+        final File file = new File(mBasePath, activeName);
+        final File backupFile;
+
+        if (file.exists()) {
+            // read existing data
+            readFile(file, reader);
+
+            // backup existing data during write
+            backupFile = new File(mBasePath, activeName + SUFFIX_BACKUP);
+            file.renameTo(backupFile);
+
+            try {
+                writeFile(file, writer);
+
+                // write success, delete backup
+                backupFile.delete();
+            } catch (IOException e) {
+                // write failed, delete file and restore backup
+                file.delete();
+                backupFile.renameTo(file);
+                throw e;
+            }
+
+        } else {
+            // create empty backup during write
+            backupFile = new File(mBasePath, activeName + SUFFIX_NO_BACKUP);
+            backupFile.createNewFile();
+
+            try {
+                writeFile(file, writer);
+
+                // write success, delete empty backup
+                backupFile.delete();
+            } catch (IOException e) {
+                // write failed, delete file and empty backup
+                file.delete();
+                backupFile.delete();
+                throw e;
+            }
+        }
+    }
+
+    /**
+     * Read any rotated data that overlap the requested time range.
+     */
+    public void readMatching(Reader reader, long matchStartMillis, long matchEndMillis)
+            throws IOException {
+        final FileInfo info = new FileInfo(mPrefix);
+        for (String name : mBasePath.list()) {
+            if (!info.parse(name)) continue;
+
+            // read file when it overlaps
+            if (info.startMillis <= matchEndMillis && matchStartMillis <= info.endMillis) {
+                final File file = new File(mBasePath, name);
+                readFile(file, reader);
+            }
+        }
+    }
+
+    /**
+     * Return the currently active file, which may not exist yet.
+     */
+    private String getActiveName(long currentTimeMillis) {
+        String oldestActiveName = null;
+        long oldestActiveStart = Long.MAX_VALUE;
+
+        final FileInfo info = new FileInfo(mPrefix);
+        for (String name : mBasePath.list()) {
+            if (!info.parse(name)) continue;
+
+            // pick the oldest active file which covers current time
+            if (info.isActive() && info.startMillis < currentTimeMillis
+                    && info.startMillis < oldestActiveStart) {
+                oldestActiveName = name;
+                oldestActiveStart = info.startMillis;
+            }
+        }
+
+        if (oldestActiveName != null) {
+            return oldestActiveName;
+        } else {
+            // no active file found above; create one starting now
+            info.startMillis = currentTimeMillis;
+            info.endMillis = Long.MAX_VALUE;
+            return info.build();
+        }
+    }
+
+    /**
+     * Examine all files managed by this rotator, renaming or deleting if their
+     * age matches the configured thresholds.
+     */
+    public void maybeRotate(long currentTimeMillis) {
+        final long rotateBefore = currentTimeMillis - mRotateAgeMillis;
+        final long deleteBefore = currentTimeMillis - mDeleteAgeMillis;
+
+        final FileInfo info = new FileInfo(mPrefix);
+        for (String name : mBasePath.list()) {
+            if (!info.parse(name)) continue;
+
+            if (info.isActive()) {
+                // found active file; rotate if old enough
+                if (info.startMillis < rotateBefore) {
+                    info.endMillis = currentTimeMillis;
+
+                    final File file = new File(mBasePath, name);
+                    final File destFile = new File(mBasePath, info.build());
+                    file.renameTo(destFile);
+                }
+            } else if (info.endMillis < deleteBefore) {
+                // found rotated file; delete if old enough
+                final File file = new File(mBasePath, name);
+                file.delete();
+            }
+        }
+    }
+
+    private static void readFile(File file, Reader reader) throws IOException {
+        final FileInputStream fis = new FileInputStream(file);
+        final BufferedInputStream bis = new BufferedInputStream(fis);
+        try {
+            reader.read(bis);
+        } finally {
+            IoUtils.closeQuietly(bis);
+        }
+    }
+
+    private static void writeFile(File file, Writer writer) throws IOException {
+        final FileOutputStream fos = new FileOutputStream(file);
+        final BufferedOutputStream bos = new BufferedOutputStream(fos);
+        try {
+            writer.write(bos);
+            bos.flush();
+        } finally {
+            FileUtils.sync(fos);
+            IoUtils.closeQuietly(bos);
+        }
+    }
+
+    /**
+     * Details for a rotated file, either parsed from an existing filename, or
+     * ready to be built into a new filename.
+     */
+    private static class FileInfo {
+        public final String prefix;
+
+        public long startMillis;
+        public long endMillis;
+
+        public FileInfo(String prefix) {
+            this.prefix = Preconditions.checkNotNull(prefix);
+        }
+
+        /**
+         * Attempt parsing the given filename.
+         *
+         * @return Whether parsing was successful.
+         */
+        public boolean parse(String name) {
+            startMillis = endMillis = -1;
+
+            final int dotIndex = name.lastIndexOf('.');
+            final int dashIndex = name.lastIndexOf('-');
+
+            // skip when missing time section
+            if (dotIndex == -1 || dashIndex == -1) return false;
+
+            // skip when prefix doesn't match
+            if (!prefix.equals(name.substring(0, dotIndex))) return false;
+
+            try {
+                startMillis = Long.parseLong(name.substring(dotIndex + 1, dashIndex));
+
+                if (name.length() - dashIndex == 1) {
+                    endMillis = Long.MAX_VALUE;
+                } else {
+                    endMillis = Long.parseLong(name.substring(dashIndex + 1));
+                }
+
+                return true;
+            } catch (NumberFormatException e) {
+                return false;
+            }
+        }
+
+        /**
+         * Build current state into filename.
+         */
+        public String build() {
+            final StringBuilder name = new StringBuilder();
+            name.append(prefix).append('.').append(startMillis).append('-');
+            if (endMillis != Long.MAX_VALUE) {
+                name.append(endMillis);
+            }
+            return name.toString();
+        }
+
+        /**
+         * Test if current file is active (no end timestamp).
+         */
+        public boolean isActive() {
+            return endMillis == Long.MAX_VALUE;
+        }
+    }
+}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 0c5101f..29f9d54 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -72,7 +72,7 @@
 android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
 {
     bool state = false;
-    AudioSystem::isStreamActive(stream, &state, inPastMs);
+    AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
     return state;
 }
 
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index d921685..4aa49f4 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -75,7 +75,7 @@
         sp<MemoryHeapBase>         mMemHeap;
         sp<MemoryBase>             mMemBase;
         audiotrack_callback_cookie mCallbackData;
-        int                        mStreamType;
+        audio_stream_type_t        mStreamType;
 
     AudioTrackJniStorage() {
         mCallbackData.audioTrack_class = 0;
@@ -175,11 +175,11 @@
     int afSampleRate;
     int afFrameCount;
 
-    if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
+    if (AudioSystem::getOutputFrameCount(&afFrameCount, (audio_stream_type_t) streamType) != NO_ERROR) {
         ALOGE("Error creating AudioTrack: Could not get AudioSystem frame count.");
         return AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM;
     }
-    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
+    if (AudioSystem::getOutputSamplingRate(&afSampleRate, (audio_stream_type_t) streamType) != NO_ERROR) {
         ALOGE("Error creating AudioTrack: Could not get AudioSystem sampling rate.");
         return AUDIOTRACK_ERROR_SETUP_AUDIOSYSTEM;
     }
diff --git a/core/jni/android_media_ToneGenerator.cpp b/core/jni/android_media_ToneGenerator.cpp
index 49be1c7..53a0501 100644
--- a/core/jni/android_media_ToneGenerator.cpp
+++ b/core/jni/android_media_ToneGenerator.cpp
@@ -79,7 +79,7 @@
 
 static void android_media_ToneGenerator_native_setup(JNIEnv *env, jobject thiz,
         jint streamType, jint volume) {
-    ToneGenerator *lpToneGen = new ToneGenerator(streamType, AudioSystem::linearToLog(volume), true);
+    ToneGenerator *lpToneGen = new ToneGenerator((audio_stream_type_t) streamType, AudioSystem::linearToLog(volume), true);
 
     env->SetIntField(thiz, fields.context, 0);
 
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 8234f1b..07a7f22 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -50,7 +50,7 @@
 static pthread_key_t gBgKey = -1;
 #endif
 
-static void signalExceptionForPriorityError(JNIEnv* env, jobject obj, int err)
+static void signalExceptionForPriorityError(JNIEnv* env, int err)
 {
     switch (err) {
         case EINVAL:
@@ -71,7 +71,7 @@
     }
 }
 
-static void signalExceptionForGroupError(JNIEnv* env, jobject obj, int err)
+static void signalExceptionForGroupError(JNIEnv* env, int err)
 {
     switch (err) {
         case EINVAL:
@@ -173,7 +173,7 @@
 {
     int res = androidSetThreadSchedulingGroup(pid, grp);
     if (res != NO_ERROR) {
-        signalExceptionForGroupError(env, clazz, res == BAD_VALUE ? EINVAL : errno);
+        signalExceptionForGroupError(env, res == BAD_VALUE ? EINVAL : errno);
         return;
     }
 }
@@ -186,7 +186,7 @@
     struct dirent *de;
 
     if (grp > ANDROID_TGROUP_MAX || grp < 0) {
-        signalExceptionForGroupError(env, clazz, EINVAL);
+        signalExceptionForGroupError(env, EINVAL);
         return;
     }
 
@@ -214,7 +214,7 @@
     if (!(d = opendir(proc_path))) {
         // If the process exited on us, don't generate an exception
         if (errno != ENOENT)
-            signalExceptionForGroupError(env, clazz, errno);
+            signalExceptionForGroupError(env, errno);
         return;
     }
 
@@ -240,7 +240,7 @@
         }
 
         if (androidSetThreadSchedulingGroup(t_pid, grp) != NO_ERROR) {
-            signalExceptionForGroupError(env, clazz, errno);
+            signalExceptionForGroupError(env, errno);
             break;
         }
     }
@@ -264,6 +264,21 @@
 #endif
 }
 
+void android_os_Process_setThreadScheduler(JNIEnv* env, jclass clazz,
+                                              jint tid, jint policy, jint pri)
+{
+#ifdef HAVE_SCHED_SETSCHEDULER
+    struct sched_param param;
+    param.sched_priority = pri;
+    int rc = sched_setscheduler(tid, policy, &param);
+    if (rc) {
+        signalExceptionForPriorityError(env, errno);
+    }
+#else
+    signalExceptionForPriorityError(env, ENOSYS);
+#endif
+}
+
 void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
                                               jint pid, jint pri)
 {
@@ -285,9 +300,9 @@
     int rc = androidSetThreadPriority(pid, pri);
     if (rc != 0) {
         if (rc == INVALID_OPERATION) {
-            signalExceptionForPriorityError(env, clazz, errno);
+            signalExceptionForPriorityError(env, errno);
         } else {
-            signalExceptionForGroupError(env, clazz, errno);
+            signalExceptionForGroupError(env, errno);
         }
     }
 
@@ -308,7 +323,7 @@
     errno = 0;
     jint pri = getpriority(PRIO_PROCESS, pid);
     if (errno != 0) {
-        signalExceptionForPriorityError(env, clazz, errno);
+        signalExceptionForPriorityError(env, errno);
     }
     //ALOGI("Returning priority of %d: %d\n", pid, pri);
     return pri;
@@ -852,6 +867,7 @@
     {"getUidForName",       "(Ljava/lang/String;)I", (void*)android_os_Process_getUidForName},
     {"getGidForName",       "(Ljava/lang/String;)I", (void*)android_os_Process_getGidForName},
     {"setThreadPriority",   "(II)V", (void*)android_os_Process_setThreadPriority},
+    {"setThreadScheduler",  "(III)V", (void*)android_os_Process_setThreadScheduler},
     {"setCanSelfBackground", "(Z)V", (void*)android_os_Process_setCanSelfBackground},
     {"setThreadPriority",   "(I)V", (void*)android_os_Process_setCallingThreadPriority},
     {"getThreadPriority",   "(I)I", (void*)android_os_Process_getThreadPriority},
diff --git a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
new file mode 100644
index 0000000..94d1cb6
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2012 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;
+
+import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.text.format.DateUtils.SECOND_IN_MILLIS;
+import static android.text.format.DateUtils.WEEK_IN_MILLIS;
+import static android.text.format.DateUtils.YEAR_IN_MILLIS;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+
+import com.android.internal.util.FileRotator.Reader;
+import com.android.internal.util.FileRotator.Writer;
+import com.google.android.collect.Lists;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ProtocolException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Random;
+
+import libcore.io.IoUtils;
+
+/**
+ * Tests for {@link FileRotator}.
+ */
+public class FileRotatorTest extends AndroidTestCase {
+    private static final String TAG = "FileRotatorTest";
+
+    private File mBasePath;
+
+    private static final String PREFIX = "rotator";
+    private static final String ANOTHER_PREFIX = "another_rotator";
+
+    private static final long TEST_TIME = 1300000000000L;
+
+    // TODO: test throwing rolls back correctly
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mBasePath = getContext().getFilesDir();
+        IoUtils.deleteContents(mBasePath);
+    }
+
+    public void testEmpty() throws Exception {
+        final FileRotator rotate1 = new FileRotator(
+                mBasePath, PREFIX, DAY_IN_MILLIS, WEEK_IN_MILLIS);
+        final FileRotator rotate2 = new FileRotator(
+                mBasePath, ANOTHER_PREFIX, DAY_IN_MILLIS, WEEK_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // write single new value
+        rotate1.combineActive(reader, writer("foo"), currentTime);
+        reader.assertRead();
+
+        // assert that one rotator doesn't leak into another
+        assertReadAll(rotate1, "foo");
+        assertReadAll(rotate2);
+    }
+
+    public void testCombine() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, DAY_IN_MILLIS, WEEK_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // first combine should have empty read, but still write data.
+        rotate.combineActive(reader, writer("foo"), currentTime);
+        reader.assertRead();
+        assertReadAll(rotate, "foo");
+
+        // second combine should replace contents; should read existing data,
+        // and write final data to disk.
+        currentTime += SECOND_IN_MILLIS;
+        reader.reset();
+        rotate.combineActive(reader, writer("bar"), currentTime);
+        reader.assertRead("foo");
+        assertReadAll(rotate, "bar");
+    }
+
+    public void testRotate() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, DAY_IN_MILLIS, WEEK_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // combine first record into file
+        rotate.combineActive(reader, writer("foo"), currentTime);
+        reader.assertRead();
+        assertReadAll(rotate, "foo");
+
+        // push time a few minutes forward; shouldn't rotate file
+        reader.reset();
+        currentTime += MINUTE_IN_MILLIS;
+        rotate.combineActive(reader, writer("bar"), currentTime);
+        reader.assertRead("foo");
+        assertReadAll(rotate, "bar");
+
+        // push time forward enough to rotate file; should still have same data
+        currentTime += DAY_IN_MILLIS + SECOND_IN_MILLIS;
+        rotate.maybeRotate(currentTime);
+        assertReadAll(rotate, "bar");
+
+        // combine a second time, should leave rotated value untouched, and
+        // active file should be empty.
+        reader.reset();
+        rotate.combineActive(reader, writer("baz"), currentTime);
+        reader.assertRead();
+        assertReadAll(rotate, "bar", "baz");
+    }
+
+    public void testDelete() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, MINUTE_IN_MILLIS, DAY_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // create first record and trigger rotating it
+        rotate.combineActive(reader, writer("foo"), currentTime);
+        reader.assertRead();
+        currentTime += MINUTE_IN_MILLIS + SECOND_IN_MILLIS;
+        rotate.maybeRotate(currentTime);
+
+        // create second record
+        reader.reset();
+        rotate.combineActive(reader, writer("bar"), currentTime);
+        reader.assertRead();
+        assertReadAll(rotate, "foo", "bar");
+
+        // push time far enough to expire first record
+        currentTime = TEST_TIME + DAY_IN_MILLIS + (2 * MINUTE_IN_MILLIS);
+        rotate.maybeRotate(currentTime);
+        assertReadAll(rotate, "bar");
+
+        // push further to delete second record
+        currentTime += WEEK_IN_MILLIS;
+        rotate.maybeRotate(currentTime);
+        assertReadAll(rotate);
+    }
+
+    public void testThrowRestoresBackup() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, MINUTE_IN_MILLIS, DAY_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // first, write some valid data
+        rotate.combineActive(reader, writer("foo"), currentTime);
+        reader.assertRead();
+        assertReadAll(rotate, "foo");
+
+        try {
+            // now, try writing which will throw
+            reader.reset();
+            rotate.combineActive(reader, new Writer() {
+                public void write(OutputStream out) throws IOException {
+                    new DataOutputStream(out).writeUTF("bar");
+                    throw new ProtocolException("yikes");
+                }
+            }, currentTime);
+
+            fail("woah, somehow able to write exception");
+        } catch (ProtocolException e) {
+            // expected from above
+        }
+
+        // assert that we read original data, and that it's still intact after
+        // the failed write above.
+        reader.assertRead("foo");
+        assertReadAll(rotate, "foo");
+    }
+
+    public void testOtherFilesAndMalformed() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, SECOND_IN_MILLIS, SECOND_IN_MILLIS);
+
+        // should ignore another prefix
+        touch("another_rotator.1024");
+        touch("another_rotator.1024-2048");
+        assertReadAll(rotate);
+
+        // verify that broken filenames don't crash
+        touch("rotator");
+        touch("rotator...");
+        touch("rotator.-");
+        touch("rotator.---");
+        touch("rotator.a-b");
+        touch("rotator_but_not_actually");
+        assertReadAll(rotate);
+
+        // and make sure that we can read something from a legit file
+        write("rotator.100-200", "meow");
+        assertReadAll(rotate, "meow");
+    }
+
+    private static final String RED = "red";
+    private static final String GREEN = "green";
+    private static final String BLUE = "blue";
+    private static final String YELLOW = "yellow";
+
+    public void testQueryMatch() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, HOUR_IN_MILLIS, YEAR_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // rotate a bunch of historical data
+        rotate.maybeRotate(currentTime);
+        rotate.combineActive(reader, writer(RED), currentTime);
+
+        currentTime += DAY_IN_MILLIS;
+        rotate.maybeRotate(currentTime);
+        rotate.combineActive(reader, writer(GREEN), currentTime);
+
+        currentTime += DAY_IN_MILLIS;
+        rotate.maybeRotate(currentTime);
+        rotate.combineActive(reader, writer(BLUE), currentTime);
+
+        currentTime += DAY_IN_MILLIS;
+        rotate.maybeRotate(currentTime);
+        rotate.combineActive(reader, writer(YELLOW), currentTime);
+
+        final String[] FULL_SET = { RED, GREEN, BLUE, YELLOW };
+
+        assertReadAll(rotate, FULL_SET);
+        assertReadMatching(rotate, Long.MIN_VALUE, Long.MAX_VALUE, FULL_SET);
+        assertReadMatching(rotate, Long.MIN_VALUE, currentTime, FULL_SET);
+        assertReadMatching(rotate, TEST_TIME + SECOND_IN_MILLIS, currentTime, FULL_SET);
+
+        // should omit last value, since it only touches at currentTime
+        assertReadMatching(rotate, TEST_TIME + SECOND_IN_MILLIS, currentTime - SECOND_IN_MILLIS,
+                RED, GREEN, BLUE);
+
+        // check boundary condition
+        assertReadMatching(rotate, TEST_TIME + DAY_IN_MILLIS, Long.MAX_VALUE, FULL_SET);
+        assertReadMatching(rotate, TEST_TIME + DAY_IN_MILLIS + SECOND_IN_MILLIS, Long.MAX_VALUE,
+                GREEN, BLUE, YELLOW);
+
+        // test range smaller than file
+        final long blueStart = TEST_TIME + (DAY_IN_MILLIS * 2);
+        final long blueEnd = TEST_TIME + (DAY_IN_MILLIS * 3);
+        assertReadMatching(rotate, blueStart + SECOND_IN_MILLIS, blueEnd - SECOND_IN_MILLIS, BLUE);
+
+        // outside range should return nothing
+        assertReadMatching(rotate, Long.MIN_VALUE, TEST_TIME - DAY_IN_MILLIS);
+    }
+
+    public void testClockRollingBackwards() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, DAY_IN_MILLIS, YEAR_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // create record at current time
+        // --> foo
+        rotate.combineActive(reader, writer("foo"), currentTime);
+        reader.assertRead();
+        assertReadAll(rotate, "foo");
+
+        // record a day in past; should create a new active file
+        // --> bar
+        currentTime -= DAY_IN_MILLIS;
+        reader.reset();
+        rotate.combineActive(reader, writer("bar"), currentTime);
+        reader.assertRead();
+        assertReadAll(rotate, "bar", "foo");
+
+        // verify that we rewrite current active file
+        // bar --> baz
+        currentTime += SECOND_IN_MILLIS;
+        reader.reset();
+        rotate.combineActive(reader, writer("baz"), currentTime);
+        reader.assertRead("bar");
+        assertReadAll(rotate, "baz", "foo");
+
+        // return to present and verify we write oldest active file
+        // baz --> meow
+        currentTime = TEST_TIME + SECOND_IN_MILLIS;
+        reader.reset();
+        rotate.combineActive(reader, writer("meow"), currentTime);
+        reader.assertRead("baz");
+        assertReadAll(rotate, "meow", "foo");
+
+        // current time should trigger rotate of older active file
+        rotate.maybeRotate(currentTime);
+
+        // write active file, verify this time we touch original
+        // foo --> yay
+        reader.reset();
+        rotate.combineActive(reader, writer("yay"), currentTime);
+        reader.assertRead("foo");
+        assertReadAll(rotate, "meow", "yay");
+    }
+
+    @Suppress
+    public void testFuzz() throws Exception {
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, HOUR_IN_MILLIS, DAY_IN_MILLIS);
+
+        final RecordingReader reader = new RecordingReader();
+        long currentTime = TEST_TIME;
+
+        // walk forward through time, ensuring that files are cleaned properly
+        final Random random = new Random();
+        for (int i = 0; i < 1024; i++) {
+            currentTime += Math.abs(random.nextLong()) % DAY_IN_MILLIS;
+
+            reader.reset();
+            rotate.combineActive(reader, writer("meow"), currentTime);
+
+            if (random.nextBoolean()) {
+                rotate.maybeRotate(currentTime);
+            }
+        }
+
+        rotate.maybeRotate(currentTime);
+
+        Log.d(TAG, "currentTime=" + currentTime);
+        Log.d(TAG, Arrays.toString(mBasePath.list()));
+    }
+
+    public void testRecoverAtomic() throws Exception {
+        write("rotator.1024-2048", "foo");
+        write("rotator.1024-2048.backup", "bar");
+        write("rotator.2048-4096", "baz");
+        write("rotator.2048-4096.no_backup", "");
+
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, SECOND_IN_MILLIS, SECOND_IN_MILLIS);
+
+        // verify backup value was recovered; no_backup indicates that
+        // corresponding file had no backup and should be discarded.
+        assertReadAll(rotate, "bar");
+    }
+
+    private void touch(String... names) throws IOException {
+        for (String name : names) {
+            final OutputStream out = new FileOutputStream(new File(mBasePath, name));
+            out.close();
+        }
+    }
+
+    private void write(String name, String value) throws IOException {
+        final DataOutputStream out = new DataOutputStream(
+                new FileOutputStream(new File(mBasePath, name)));
+        out.writeUTF(value);
+        out.close();
+    }
+
+    private static Writer writer(final String value) {
+        return new Writer() {
+            public void write(OutputStream out) throws IOException {
+                new DataOutputStream(out).writeUTF(value);
+            }
+        };
+    }
+
+    private static void assertReadAll(FileRotator rotate, String... expected) throws IOException {
+        assertReadMatching(rotate, Long.MIN_VALUE, Long.MAX_VALUE, expected);
+    }
+
+    private static void assertReadMatching(
+            FileRotator rotate, long matchStartMillis, long matchEndMillis, String... expected)
+            throws IOException {
+        final RecordingReader reader = new RecordingReader();
+        rotate.readMatching(reader, matchStartMillis, matchEndMillis);
+        reader.assertRead(expected);
+    }
+
+    private static class RecordingReader implements Reader {
+        private ArrayList<String> mActual = Lists.newArrayList();
+
+        public void read(InputStream in) throws IOException {
+            mActual.add(new DataInputStream(in).readUTF());
+        }
+
+        public void reset() {
+            mActual.clear();
+        }
+
+        public void assertRead(String... expected) {
+            assertEquals(expected.length, mActual.size());
+
+            final ArrayList<String> actualCopy = new ArrayList<String>(mActual);
+            for (String value : expected) {
+                if (!actualCopy.remove(value)) {
+                    final String expectedString = Arrays.toString(expected);
+                    final String actualString = Arrays.toString(mActual.toArray());
+                    fail("expected: " + expectedString + " but was: " + actualString);
+                }
+            }
+        }
+    }
+}
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index 6610f5f..07b9370 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -398,8 +398,8 @@
       the device's SIM (for GSM devices), not the current roaming carrier.</p></li></ul>
 </td> </tr> <tr>
   <td valign="top">Native Platform</td> <td valign="top"><p>An application that includes native
-    libraries that target a specific platform (ARM EABI v7, for example) will only be
-    visible on devices that support that platform. For details about the NDK and using
+    libraries that target a specific platform (ARM EABI v7 or x86, for example) are
+    visible only on devices that support that platform. For details about the NDK and using
     native libraries, see <a href="{@docRoot}sdk/ndk/index.html#overview">What is the
       Android NDK?</a></p> </tr> <tr>
         <td valign="top">Copy-Protected Applications</td> <td valign="top"><p>To
diff --git a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
index 31ad466..5faa7ec 100644
--- a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
@@ -40,7 +40,7 @@
       <li><a href=#reusing_tip>Handle case where no activity matches</a></li>
       <li><a href=#activity_launching_tip>Consider how to launch your activities</a></li>
       <li><a href=#activities_added_to_task_tip>Allow activities to add to current task</a></li>
-      <li><a href=#notifications_get_back_tip>Notifications should let user easily get back</li>
+      <li><a href=#notifications_get_back_tip>Notifications and App Widgets should provide consistent back behavior</li>
       <li><a href=#use_notification_tip>Use the notification system</a></li>
       <li><a href=#taking_over_back_key>Don't take over BACK key unless you absolutely need to</a></li>
     </ol>
@@ -1063,110 +1063,23 @@
 </p>
 
     
-<h3 id="notifications_get_back_tip">Notifications should let the user easily get back to the previous activity</h3>
+<h3 id="notifications_get_back_tip">Notifications and App Widgets should provide consistent back behavior</h3>
 <p>
-  Applications that are in the background or not running can have
-  services that send out notifications to the user letting them know about
-  events of interest. Two examples are Calendar, which can send out notifications of
-  upcoming events, and Email, which can send out notifications when new
-  messages arrive. One of the user interface guidelines is that when the
-  user is in activity A, gets a notification for activity B and
-  picks that notification, when they press the BACK key, they should
-  go back to activity A.&nbsp;
+  Notifications and app widgets are two common ways that a user can launch
+  your app through something besides its main icon in Launcher.  You must
+  take care when implementing these so that the user has a consistent experience
+  with the back button, not causing surprises in where they return to or the
+  state the application ends up in.
 </p>
 
 <p>
-  The following scenario shows how the activity stack should work
-  when the user responds to a notification.
-</p>
-
-<ol>
-  <li>
-    User is creating a new event in Calendar. They realize they
-    need to copy part of an email message into this event
-  </li>
-  <li>
-    The user chooses Home &gt; Gmail
-  </li>
-  <li>
-    While in Gmail, they receive a notification from Calendar for an upcoming meeting
-  </li>
-  <li>
-    So they choose that notification, which takes them to a
-    dedicated Calendar activity that displays brief details of the
-    upcoming meeting
-  </li>
-  <li>
-    The user chooses this short notice to view further details
-  </li>
-  <li>
-    When done viewing the event, the user presses the BACK
-    key. They should be taken to Gmail, which is where they were
-    when they took the notification
-  </li>
-</ol>
-
-<p>
-This behavior doesn't necessarily happen by default.
-</p>
-
-<p>
-Notifications generally happen primarily in one of two ways:
-</p>
-
-  <ul>
-    <li>
-      <b>The chosen activity is dedicated for notification only</b> -
-      For example, when the user receives a
-      Calendar notification, choosing that
-      notification starts a special activity that displays a list
-      of upcoming calendar events &mdash; this view is available only
-      from the notification, not through the Calendar's own user
-      interface. After viewing this upcoming event, to ensure that
-      the user pressing the BACK key will return to the activity
-      the user was in when they picked the notification, you would
-      make sure this dedicated activity does not have the same
-      task affinity as the Calendar or any other activity. (You do
-      this by setting task affinity to the empty string, which
-      means it has no affinity to anything.) The explanation for
-      this follows.
-
-      <p>
-      Because of the way tasks work, if the taskAffinity of the
-      dedicated activity is kept as its default, then pressing the
-      BACK key (in step 6, above) would go to Calendar, rather
-      than Gmail. The reason is that, by default, all activities
-      in a given application have the same task
-      affinity. Therefore, the task affinity of the dedicated
-      activity matches the Calendar task, which is already running
-      in step 1. This means in step 4, choosing the notification
-      brings the existing Calendar event (in step 1) forward and
-      starts the dedicated activity on top of it.  This is not
-      what you want to have happen. Setting the dedicated
-      activity's taskAffinity to empty string fixes this.
-      </p>
-    </li>
-
-    <li>
-      <b>The chosen activity is not dedicated, but always comes to
-      the foreground in its initial state</b> - For example, in
-      response to a notification, when the Gmail application comes
-      to the foreground, it always presents the list of conversations.
-      You can ensure this happens by setting a "clear top" flag in the
-      intent that the notification triggers.  This ensures that when the
-      activity is launched, it displays its initial activity, preventing
-      Gmail from coming to the foreground in whatever state the user last
-      happened to be viewing it. (To do this, you put {@link
-      android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP
-      FLAG_ACTIVITY_CLEAR_TOP} in the intent you pass to startActivity()). 
-    </li>
-  </ul>
-
-<p>
-  There are other ways to handle notifications, such as bringing the
-  activity to the foreground, set to display specific data, such as
-  displaying the text message thread for the person who just sent a
-  new text message.
+  The
+  <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
+  Notifications</a> section of the developer guide's
+  <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
+  documentation provides an overview of how to write code to correctly handle
+  notification.  This dicussion applies equally to handling interactions with
+  app widgets.
 </p>
 
 <p>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 3a176e6..380791a 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -231,6 +231,9 @@
     </ul>
     <p>You can append more than one <em>{@code &lt;qualifier&gt;}</em>. Separate each
 one with a dash.</p>
+    <p class="caution"><strong>Caution:</strong> When appending multiple qualifiers, you must
+place them in the same order in which they are listed in table 2. If the qualifiers are ordered
+wrong, the resources are ignored.</p>
   </li>
   <li>Save the respective alternative resources in this new directory. The resource files must be
 named exactly the same as the default resource files.</li>
@@ -254,20 +257,14 @@
 the same. This way, the resource ID that you use to reference the {@code icon.png} or {@code
 background.png} image is always the same, but Android selects the
 version of each resource that best matches the current device, by comparing the device
-configuration information with the qualifiers in the alternative resource directory name.</p>
+configuration information with the qualifiers in the resource directory name.</p>
 
 <p>Android supports several configuration qualifiers and you can
 add multiple qualifiers to one directory name, by separating each qualifier with a dash. Table 2
 lists the valid configuration qualifiers, in order of precedence&mdash;if you use multiple
-qualifiers for one resource directory, they must be added to the directory name in the order they
+qualifiers for a resource directory, you must add them to the directory name in the order they
 are listed in the table.</p>
 
-<p class="note"><strong>Note:</strong> Some configuration qualifiers were added after Android 1.0,
-so not
-all versions of Android support all the qualifiers listed in table 2. New qualifiers
-indicate the version in which they were added. To avoid any issues, always include a set of default
-resources for resources that your application uses. For more information, see the section about <a
-href="#Compatibility">Providing the Best Device Compatibility with Resources</a>.</p>
 
 <p class="table-caption" id="table2"><strong>Table 2.</strong> Configuration qualifier
 names.</p>
@@ -752,6 +749,17 @@
 </table>
 
 
+<p class="note"><strong>Note:</strong> Some configuration qualifiers have been added since Android
+1.0, so not all versions of Android support all the qualifiers. Using a new qualifier implicitly
+adds the platform version qualifier so that older devices are sure to ignore it. For example, using
+a <code>w600dp</code> qualifier will automatically include the <code>v13</code> qualifier, because
+the available-width qualifier was new in API level 13. To avoid any issues, always include a set of
+default resources (a set of resources with <em>no qualifiers</em>). For more information, see the
+section about <a href="#Compatibility">Providing the Best Device Compatibility with
+Resources</a>.</p>
+
+
+
 <h3 id="QualifierRules">Qualifier name rules</h3>
 
 <p>Here are some rules about using configuration qualifier names:</p>
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index 71aa2fe..33b0fec 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -16,6 +16,7 @@
     <h2>In this document</h2>
     <ol>
       <li><a href="#Basics">The Basics</a></li>
+      <li><a href="#HandlingNotifications">Responding to Notifications</a></li>
       <li><a href="#ManageYourNotifications">Managing your Notifications</a></li>
       <li><a href="#CreateANotification">Creating a Notification</a>
         <ol>
@@ -137,6 +138,138 @@
 </ol>
 
 
+<h2 id="HandlingNotifications">Responding to Notifications</h2>
+
+<p>A central part of the user's experience with a notification revolves around
+how it interacts with the application's UI flow.  You must implement
+this correctly to provide a consistent user experience within your app.</p>
+
+<p>Two typical examples of notifications are provided by Calendar, which can send out
+notifications of upcoming events, and Email, which can send out notifications
+when new messages arrive.  These represent the two recommended patterns for handling
+notifications: either launching into an activity that is separate from the
+main application, or launching an entirely new instance of the application
+showing the appropriate point for the notification.</p>
+
+<p>The following scenario shows how the activity stack should work
+in these two typical notification flows, first handling a Calendar notification:
+</p>
+
+<ol>
+  <li>User is creating a new event in Calendar. They realize they
+    need to copy part of an email message into this event.
+  </li>
+  <li>
+    The user chooses Home &gt; Email.
+  </li>
+  <li>
+    While in Email, they receive a notification from Calendar for an upcoming
+    meeting.
+  </li>
+  <li>
+    So they choose that notification, which takes them to a
+    dedicated Calendar activity that displays brief details of the
+    upcoming meeting.
+  </li>
+  <li>
+    The user has seen enough to know they have a meeting coming up,
+    so they press the BACK button.  They are now returned to Email, which
+    is where they were when they took the notification.
+  </li>
+</ol>
+
+<p>Handling an Email notification:</p>
+
+<ol>
+  <li>
+    The user is currently in Email composing a message, and needs to
+    check a date in their calendar.
+  </li>
+  <li>
+    The user chooses Home &gt; Calendar.
+  </li>
+  <li>
+    While in Calendar, they receive a notification from Email about a new
+    message.
+  </li>
+  <li>
+    They select the notification, which brings them to Email with the message
+    details displayed.  This has replaced what they were previously doing
+    (writing an e-mail), but that message is still saved in their drafts.
+  </li>
+  <li>
+    The user presses BACK once to go to the message list (the typical flow in the
+    Email app), and press BACK again to return to Calendar as they left it.
+  </li>
+</ol>
+
+<p>In an Email style of notification, the UI launched by the notification
+shows the main application in a state representing that notification.
+For example, when the Email application comes to the foreground from its
+notification, it displays either the conversion list or a specific
+conversation depending on whether there are multiple or only one new
+email.  To achieve this, we want to completely replace whatever current
+state the application is in with a new activity stack representing the
+new notification state.</p>
+
+<p>The following code illustrates how to show this kind of notification.  Of
+most interest is the <code>makeMessageIntentStack()</code> method, which constructs
+an array of intents representing the app's new activity stack for this state.
+(If you are using fragments, you may need to initialize your fragment and
+app state so that pressing BACK will switch the UI back to its parent state.)
+The core of this is the {@link android.content.Intent#makeRestartActivityTask
+Intent.makeRestartActivityTask()} method, which constructs the root activity
+of the stack with the appropriate flags, such as
+{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK Intent.FLAG_ACTIVITY_CLEAR_TASK}.</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
+  app_notification}
+
+<p>In a Calendar style of notification, the UI launched by the notification
+is a dedicated activity that is not part of the normal application flow.
+For example, when the user receives a Calendar notification, choosing that
+notification starts a special activity that displays a list
+of upcoming calendar events &mdash; this view is available only
+from the notification, not through the Calendar's normal user
+interface.</p>
+
+<p>The code for posting this type of notification is very straight-forward; it
+is like the above, but the {@link android.app.PendingIntent} is for just a single
+activity, our dedicated notification activity.</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
+  interstitial_notification}
+
+<p>This is not enough, however.  Normally Android considers all activities within
+an application to be part of that application's UI flow, so simply launching the
+activity like this can cause it to be mixed with your normal application back stack
+in undesired ways.  To make it behave correctly, in the manifest declaration
+for the activity the attributes 
+<code>android:launchMode="singleInstance"</code> and
+<code>android:excludeFromRecents="true"</code>
+must be set.  The full activity declaration for this sample is:</p>
+
+{@sample development/samples/ApiDemos/AndroidManifest.xml interstitial_affinity}
+
+<p>Because of the use of <code>singleInstance</code>, you must be careful about launching
+any other activities from this one.  These activities will be launched
+in their own task, and care must be taken to make sure this interacts
+well with the current state of your application's task.  This is essentially
+the same as switching to the main application as described for the Email style
+notification shown before.  Given the <code>makeMessageIntentStack()</code>
+method previously shown, handling a click here would look something like this:</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageInterstitial.java
+  app_launch}
+
+<p>If you don't want to use the <code>singleInstance</code> launch mode for
+this activity, an alternative approach is to use <code>android:taskAffinity=""</code>.
+This tells Android that the activity should not be treated as part of the
+main application flow, so it will not get mixed together with that.  All of the
+other issues discussed here do still apply, though this would allow you to start
+additional activities that are part of this notification task instead of switching
+to and replacing the main application task.</p>
+
 <h2 id="ManageYourNotifications">Managing your Notifications</h2>
 
 <p>The {@link android.app.NotificationManager} is a system service that manages all
diff --git a/docs/html/guide/topics/usb/adk.jd b/docs/html/guide/topics/usb/adk.jd
index 99c5f92..4d5fbfa 100644
--- a/docs/html/guide/topics/usb/adk.jd
+++ b/docs/html/guide/topics/usb/adk.jd
@@ -281,16 +281,17 @@
       <p>On Mac:</p>
 
       <ol type="a">
-        <li>Right-click on the Arduino application in Finder and select <strong>Show Package
-        Contents</strong>.</li>
+        <li>Create, if it does not already exist, an <code>Arduino</code>
+        directory inside your user account's <code>Documents</code> directory, and within
+        that, a <code>libraries</code> directory.</li>
 
         <li>Copy the <code>firmware/arduino_libs/AndroidAccessory</code> and
-        <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the complete directories,
-        not just the files within) to the <code>Contents/Resources/Java/libraries</code> directory
-        inside the Arduino application.</li>
+        <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the
+        complete directories, not just the files within) to your
+        <code>Documents/Arduino/libraries/</code> directory.</li>
 
-        <li>Create a <code>CapSense</code> directory in the
-        <code>Contents/Resources/Java/libraries</code> directory.</li>
+        <li>Create a <code>CapSense</code> directory in your
+        <code>Documents/Arduino/libraries/</code> directory.</li>
 
         <li>Copy <code>CapSense.cpp</code> and <code>CapSense.h</code> from the unzipped CapSense
         download to the <code>CapSense</code> directory.</li>
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 2fb69b6..84a8f1c 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -206,7 +206,7 @@
             int         channelCount() const;
             int         channels() const;
             uint32_t    frameCount() const;
-            int         frameSize() const;
+            size_t      frameSize() const;
             int         inputSource() const;
 
 
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 6a15f6e..e49d8f5 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -55,19 +55,19 @@
     static status_t getMasterMute(bool* mute);
 
     // set/get stream volume on specified output
-    static status_t setStreamVolume(int stream, float value, int output);
-    static status_t getStreamVolume(int stream, float* volume, int output);
+    static status_t setStreamVolume(audio_stream_type_t stream, float value, int output);
+    static status_t getStreamVolume(audio_stream_type_t stream, float* volume, int output);
 
     // mute/unmute stream
-    static status_t setStreamMute(int stream, bool mute);
-    static status_t getStreamMute(int stream, bool* mute);
+    static status_t setStreamMute(audio_stream_type_t stream, bool mute);
+    static status_t getStreamMute(audio_stream_type_t stream, bool* mute);
 
     // set audio mode in audio hardware (see audio_mode_t)
     static status_t setMode(int mode);
 
     // returns true in *state if tracks are active on the specified stream or has been active
     // in the past inPastMs milliseconds
-    static status_t isStreamActive(int stream, bool *state, uint32_t inPastMs = 0);
+    static status_t isStreamActive(audio_stream_type_t stream, bool *state, uint32_t inPastMs = 0);
 
     // set/get audio hardware parameters. The function accepts a list of parameters
     // key value pairs in the form: key1=value1;key2=value2;...
@@ -83,11 +83,11 @@
     static float linearToLog(int volume);
     static int logToLinear(float volume);
 
-    static status_t getOutputSamplingRate(int* samplingRate, int stream = AUDIO_STREAM_DEFAULT);
-    static status_t getOutputFrameCount(int* frameCount, int stream = AUDIO_STREAM_DEFAULT);
-    static status_t getOutputLatency(uint32_t* latency, int stream = AUDIO_STREAM_DEFAULT);
+    static status_t getOutputSamplingRate(int* samplingRate, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
+    static status_t getOutputFrameCount(int* frameCount, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
+    static status_t getOutputLatency(uint32_t* latency, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
 
-    static bool routedToA2dpOutput(int streamType);
+    static bool routedToA2dpOutput(audio_stream_type_t streamType);
 
     static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
         size_t* buffSize);
@@ -103,7 +103,7 @@
     // - BAD_VALUE: invalid parameter
     // NOTE: this feature is not supported on all hardware platforms and it is
     // necessary to check returned status before using the returned values.
-    static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = AUDIO_STREAM_DEFAULT);
+    static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
 
     static unsigned int  getInputFramesLost(audio_io_handle_t ioHandle);
 
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 60b052bd9..6e4a9f5 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -110,7 +110,7 @@
      */
 
      static status_t getMinFrameCount(int* frameCount,
-                                      int streamType      =-1,
+                                      audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT,
                                       uint32_t sampleRate = 0);
 
     /* Constructs an uninitialized AudioTrack. No connection with
@@ -142,7 +142,7 @@
      * sessionId:          Specific session ID, or zero to use default.
      */
 
-                        AudioTrack( int streamType,
+                        AudioTrack( audio_stream_type_t streamType,
                                     uint32_t sampleRate  = 0,
                                     audio_format_t format = AUDIO_FORMAT_DEFAULT,
                                     int channelMask      = 0,
@@ -162,7 +162,7 @@
      * EVENT_UNDERRUN event.
      */
 
-                        AudioTrack( int streamType,
+                        AudioTrack( audio_stream_type_t streamType,
                                     uint32_t sampleRate = 0,
                                     audio_format_t format = AUDIO_FORMAT_DEFAULT,
                                     int channelMask     = 0,
@@ -186,7 +186,7 @@
      *  - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
      *  - NO_INIT: audio server or audio hardware not initialized
      * */
-            status_t    set(int streamType      =-1,
+            status_t    set(audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT,
                             uint32_t sampleRate = 0,
                             audio_format_t format = AUDIO_FORMAT_DEFAULT,
                             int channelMask     = 0,
@@ -215,11 +215,16 @@
 
     /* getters, see constructor */
 
-            int         streamType() const;
+            audio_stream_type_t streamType() const;
             audio_format_t format() const;
             int         channelCount() const;
             uint32_t    frameCount() const;
-            int         frameSize() const;
+
+    /* Return channelCount * (bit depth per channel / 8).
+     * channelCount is determined from channelMask, and bit depth comes from format.
+     */
+            size_t      frameSize() const;
+
             sp<IMemory>& sharedBuffer();
 
 
@@ -433,7 +438,7 @@
     };
 
             bool processAudioBuffer(const sp<AudioTrackThread>& thread);
-            status_t createTrack_l(int streamType,
+            status_t createTrack_l(audio_stream_type_t streamType,
                                  uint32_t sampleRate,
                                  audio_format_t format,
                                  uint32_t channelMask,
@@ -458,7 +463,7 @@
 
     audio_track_cblk_t*     mCblk;
     audio_format_t          mFormat;
-    uint8_t                 mStreamType;
+    audio_stream_type_t     mStreamType;
     uint8_t                 mChannelCount;
     uint8_t                 mMuted;
     uint8_t                 mReserved;
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 9e3cb7f..15d3ca9 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -46,7 +46,7 @@
      */
     virtual sp<IAudioTrack> createTrack(
                                 pid_t pid,
-                                int streamType,
+                                audio_stream_type_t streamType,
                                 uint32_t sampleRate,
                                 uint32_t format,
                                 uint32_t channelMask,
@@ -89,11 +89,11 @@
     /* set/get stream type state. This will probably be used by
      * the preference panel, mostly.
      */
-    virtual     status_t    setStreamVolume(int stream, float value, int output) = 0;
-    virtual     status_t    setStreamMute(int stream, bool muted) = 0;
+    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value, int output) = 0;
+    virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted) = 0;
 
-    virtual     float       streamVolume(int stream, int output) const = 0;
-    virtual     bool        streamMute(int stream) const = 0;
+    virtual     float       streamVolume(audio_stream_type_t stream, int output) const = 0;
+    virtual     bool        streamMute(audio_stream_type_t stream) const = 0;
 
     // set audio mode
     virtual     status_t    setMode(int mode) = 0;
@@ -129,7 +129,7 @@
                                     uint32_t acoustics) = 0;
     virtual status_t closeInput(int input) = 0;
 
-    virtual status_t setStreamOutput(uint32_t stream, int output) = 0;
+    virtual status_t setStreamOutput(audio_stream_type_t stream, int output) = 0;
 
     virtual status_t setVoiceVolume(float volume) = 0;
 
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 9807cbe..1ac0bbf 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -85,7 +85,7 @@
                                     int id) = 0;
     virtual status_t unregisterEffect(int id) = 0;
     virtual status_t setEffectEnabled(int id, bool enabled) = 0;
-    virtual bool     isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
+    virtual bool     isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0;
     virtual status_t queryDefaultPreProcessing(int audioSession,
                                               effect_descriptor_t *descriptors,
                                               uint32_t *count) = 0;
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index e905903..6425886 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -21,6 +21,7 @@
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
 #include <utils/KeyedVector.h>
+#include <system/audio.h>
 
 namespace android {
 
@@ -51,7 +52,7 @@
     virtual status_t        getCurrentPosition(int* msec) = 0;
     virtual status_t        getDuration(int* msec) = 0;
     virtual status_t        reset() = 0;
-    virtual status_t        setAudioStreamType(int type) = 0;
+    virtual status_t        setAudioStreamType(audio_stream_type_t type) = 0;
     virtual status_t        setLooping(int loop) = 0;
     virtual status_t        setVolume(float leftVolume, float rightVolume) = 0;
     virtual status_t        setAuxEffectSendLevel(float level) = 0;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 1f6bdda..7beb176 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -199,7 +199,7 @@
     virtual             ~MediaPlayerHWInterface() {}
     virtual bool        hardwareOutput() { return true; }
     virtual status_t    setVolume(float leftVolume, float rightVolume) = 0;
-    virtual status_t    setAudioStreamType(int streamType) = 0;
+    virtual status_t    setAudioStreamType(audio_stream_type_t streamType) = 0;
 };
 
 }; // namespace android
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index 1ad1f26..7d890bd 100644
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -151,7 +151,7 @@
         NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1
     };
 
-    ToneGenerator(int streamType, float volume, bool threadCanCallJava = false);
+    ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava = false);
     ~ToneGenerator();
 
     bool startTone(int toneType, int durationMs = -1);
@@ -266,7 +266,7 @@
     Mutex mCbkCondLock; // Mutex associated to mWaitCbkCond
     Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested
     float mVolume;  // Volume applied to audio track
-    int mStreamType; // Audio stream used for output
+    audio_stream_type_t mStreamType; // Audio stream used for output
     unsigned int mProcessSize;  // Size of audio blocks generated at a time by audioCallback() (in PCM frames).
 
     bool initAudioTrack();
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 2dc055e..00b7dd5 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -185,7 +185,7 @@
             status_t        getCurrentPosition(int *msec);
             status_t        getDuration(int *msec);
             status_t        reset();
-            status_t        setAudioStreamType(int type);
+            status_t        setAudioStreamType(audio_stream_type_t type);
             status_t        setLooping(int loop);
             bool            isLooping();
             status_t        setVolume(float leftVolume, float rightVolume);
@@ -223,7 +223,7 @@
     int                         mSeekPosition;
     bool                        mPrepareSync;
     status_t                    mPrepareStatus;
-    int                         mStreamType;
+    audio_stream_type_t         mStreamType;
     bool                        mLoop;
     float                       mLeftVolume;
     float                       mRightVolume;
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 046d5e9..33a92cd 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -80,12 +80,14 @@
                 // 8 bit PCM data: in this case,  mCblk->frameSize is based on a sample size of
                 // 16 bit because data is converted to 16 bit before being stored in buffer
 
-                uint8_t     frameSize;
+                uint8_t     frameSize;       // would normally be size_t, but 8 bits is plenty
                 uint8_t     pad1;
                 uint16_t    bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger
 
                 uint16_t    waitTimeMs;      // Cumulated wait time
-                uint16_t    sendLevel;
+private:
+                uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0
+public:
     volatile    int32_t     flags;
 
                 // Cache line boundary (32 bytes)
@@ -98,6 +100,19 @@
                 uint32_t    framesAvailable_l();
                 uint32_t    framesReady();
                 bool        tryLock();
+
+                // No barriers on the following operations, so the ordering of loads/stores
+                // with respect to other parameters is UNPREDICTABLE. That's considered safe.
+
+                // for AudioTrack client only, caller must limit to 0.0 <= sendLevel <= 1.0
+                void        setSendLevel(float sendLevel) {
+                    mSendLevel = uint16_t(sendLevel * 0x1000);
+                }
+
+                // for AudioFlinger only; the return value must be validated by the caller
+                uint16_t    getSendLevel_U4_12() const {
+                    return mSendLevel;
+                }
 };
 
 
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 39fd9a9..8ff9dd3 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -479,7 +479,7 @@
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
-    process_media_player_call( env, thiz, mp->setAudioStreamType(streamtype) , NULL, NULL );
+    process_media_player_call( env, thiz, mp->setAudioStreamType((audio_stream_type_t) streamtype) , NULL, NULL );
 }
 
 static void
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index b5303ef..0d51def 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -39,7 +39,7 @@
 uint32_t kDefaultSampleRate = 44100;
 uint32_t kDefaultFrameCount = 1200;
 
-SoundPool::SoundPool(int maxChannels, int streamType, int srcQuality)
+SoundPool::SoundPool(int maxChannels, audio_stream_type_t streamType, int srcQuality)
 {
     ALOGV("SoundPool constructor: maxChannels=%d, streamType=%d, srcQuality=%d",
             maxChannels, streamType, srcQuality);
@@ -570,7 +570,7 @@
         // initialize track
         int afFrameCount;
         int afSampleRate;
-        int streamType = mSoundPool->streamType();
+        audio_stream_type_t streamType = mSoundPool->streamType();
         if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
             afFrameCount = kDefaultFrameCount;
         }
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index 1b91b3b..6b11c28 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -162,7 +162,7 @@
     friend class SoundPoolThread;
     friend class SoundChannel;
 public:
-    SoundPool(int maxChannels, int streamType, int srcQuality);
+    SoundPool(int maxChannels, audio_stream_type_t streamType, int srcQuality);
     ~SoundPool();
     int load(const char* url, int priority);
     int load(int fd, int64_t offset, int64_t length, int priority);
@@ -178,7 +178,7 @@
     void setPriority(int channelID, int priority);
     void setLoop(int channelID, int loop);
     void setRate(int channelID, float rate);
-    int streamType() const { return mStreamType; }
+    audio_stream_type_t streamType() const { return mStreamType; }
     int srcQuality() const { return mSrcQuality; }
 
     // called from SoundPoolThread
@@ -220,7 +220,7 @@
     List<SoundChannel*>     mStop;
     DefaultKeyedVector< int, sp<Sample> >   mSamples;
     int                     mMaxChannels;
-    int                     mStreamType;
+    audio_stream_type_t     mStreamType;
     int                     mSrcQuality;
     int                     mAllocated;
     int                     mNextSampleID;
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
index fe1c20a..da3af9d 100644
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ b/media/jni/soundpool/android_media_SoundPool.cpp
@@ -179,7 +179,7 @@
 android_media_SoundPool_native_setup(JNIEnv *env, jobject thiz, jobject weakRef, jint maxChannels, jint streamType, jint srcQuality)
 {
     ALOGV("android_media_SoundPool_native_setup");
-    SoundPool *ap = new SoundPool(maxChannels, streamType, srcQuality);
+    SoundPool *ap = new SoundPool(maxChannels, (audio_stream_type_t) streamType, srcQuality);
     if (ap == NULL) {
         return -1;
     }
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 8e4a9d6..32b5bac 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -263,7 +263,7 @@
     return mFrameCount;
 }
 
-int AudioRecord::frameSize() const
+size_t AudioRecord::frameSize() const
 {
     if (audio_is_linear_pcm(mFormat)) {
         return channelCount()*audio_bytes_per_sample(mFormat);
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 9d4137e..5193848 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -120,7 +120,7 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::setStreamVolume(int stream, float value, int output)
+status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value, int output)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -129,7 +129,7 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::setStreamMute(int stream, bool mute)
+status_t AudioSystem::setStreamMute(audio_stream_type_t stream, bool mute)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -138,7 +138,7 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::getStreamVolume(int stream, float* volume, int output)
+status_t AudioSystem::getStreamVolume(audio_stream_type_t stream, float* volume, int output)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -147,7 +147,7 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::getStreamMute(int stream, bool* mute)
+status_t AudioSystem::getStreamMute(audio_stream_type_t stream, bool* mute)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -203,7 +203,7 @@
     return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;
 }
 
-status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType)
+status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type_t streamType)
 {
     OutputDescriptor *outputDesc;
     audio_io_handle_t output;
@@ -212,7 +212,7 @@
         streamType = AUDIO_STREAM_MUSIC;
     }
 
-    output = getOutput((audio_stream_type_t)streamType);
+    output = getOutput(streamType);
     if (output == 0) {
         return PERMISSION_DENIED;
     }
@@ -236,7 +236,7 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType)
+status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t streamType)
 {
     OutputDescriptor *outputDesc;
     audio_io_handle_t output;
@@ -245,7 +245,7 @@
         streamType = AUDIO_STREAM_MUSIC;
     }
 
-    output = getOutput((audio_stream_type_t)streamType);
+    output = getOutput(streamType);
     if (output == 0) {
         return PERMISSION_DENIED;
     }
@@ -267,7 +267,7 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType)
+status_t AudioSystem::getOutputLatency(uint32_t* latency, audio_stream_type_t streamType)
 {
     OutputDescriptor *outputDesc;
     audio_io_handle_t output;
@@ -276,7 +276,7 @@
         streamType = AUDIO_STREAM_MUSIC;
     }
 
-    output = getOutput((audio_stream_type_t)streamType);
+    output = getOutput(streamType);
     if (output == 0) {
         return PERMISSION_DENIED;
     }
@@ -333,7 +333,7 @@
     return af->setVoiceVolume(value);
 }
 
-status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream)
+status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream)
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
     if (af == 0) return PERMISSION_DENIED;
@@ -342,7 +342,7 @@
         stream = AUDIO_STREAM_MUSIC;
     }
 
-    return af->getRenderPosition(halFrames, dspFrames, getOutput((audio_stream_type_t)stream));
+    return af->getRenderPosition(halFrames, dspFrames, getOutput(stream));
 }
 
 unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
@@ -467,7 +467,7 @@
     gAudioErrorCallback = cb;
 }
 
-bool AudioSystem::routedToA2dpOutput(int streamType) {
+bool AudioSystem::routedToA2dpOutput(audio_stream_type_t streamType) {
     switch(streamType) {
     case AUDIO_STREAM_MUSIC:
     case AUDIO_STREAM_VOICE_CALL:
@@ -728,7 +728,7 @@
     return aps->setEffectEnabled(id, enabled);
 }
 
-status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs)
+status_t AudioSystem::isStreamActive(audio_stream_type_t stream, bool* state, uint32_t inPastMs)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 9c650ad..97b2312 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -49,7 +49,7 @@
 // static
 status_t AudioTrack::getMinFrameCount(
         int* frameCount,
-        int streamType,
+        audio_stream_type_t streamType,
         uint32_t sampleRate)
 {
     int afSampleRate;
@@ -83,7 +83,7 @@
 }
 
 AudioTrack::AudioTrack(
-        int streamType,
+        audio_stream_type_t streamType,
         uint32_t sampleRate,
         audio_format_t format,
         int channelMask,
@@ -102,7 +102,7 @@
 }
 
 AudioTrack::AudioTrack(
-        int streamType,
+        audio_stream_type_t streamType,
         uint32_t sampleRate,
         audio_format_t format,
         int channelMask,
@@ -140,7 +140,7 @@
 }
 
 status_t AudioTrack::set(
-        int streamType,
+        audio_stream_type_t streamType,
         uint32_t sampleRate,
         audio_format_t format,
         int channelMask,
@@ -204,7 +204,7 @@
     uint32_t channelCount = popcount(channelMask);
 
     audio_io_handle_t output = AudioSystem::getOutput(
-                                    (audio_stream_type_t)streamType,
+                                    streamType,
                                     sampleRate, format, channelMask,
                                     (audio_policy_output_flags_t)flags);
 
@@ -215,7 +215,7 @@
 
     mVolume[LEFT] = 1.0f;
     mVolume[RIGHT] = 1.0f;
-    mSendLevel = 0;
+    mSendLevel = 0.0f;
     mFrameCount = frameCount;
     mNotificationFramesReq = notificationFrames;
     mSessionId = sessionId;
@@ -275,7 +275,7 @@
     return mLatency;
 }
 
-int AudioTrack::streamType() const
+audio_stream_type_t AudioTrack::streamType() const
 {
     return mStreamType;
 }
@@ -295,7 +295,7 @@
     return mCblk->frameCount;
 }
 
-int AudioTrack::frameSize() const
+size_t AudioTrack::frameSize() const
 {
     if (audio_is_linear_pcm(mFormat)) {
         return channelCount()*audio_bytes_per_sample(mFormat);
@@ -499,14 +499,14 @@
 status_t AudioTrack::setAuxEffectSendLevel(float level)
 {
     ALOGV("setAuxEffectSendLevel(%f)", level);
-    if (level > 1.0f) {
+    if (level < 0.0f || level > 1.0f) {
         return BAD_VALUE;
     }
     AutoMutex lock(mLock);
 
     mSendLevel = level;
 
-    mCblk->sendLevel = uint16_t(level * 0x1000);
+    mCblk->setSendLevel(level);
 
     return NO_ERROR;
 }
@@ -688,7 +688,7 @@
 // must be called with mLock held
 audio_io_handle_t AudioTrack::getOutput_l()
 {
-    return AudioSystem::getOutput((audio_stream_type_t)mStreamType,
+    return AudioSystem::getOutput(mStreamType,
             mCblk->sampleRate, mFormat, mChannelMask, (audio_policy_output_flags_t)mFlags);
 }
 
@@ -711,7 +711,7 @@
 
 // must be called with mLock held
 status_t AudioTrack::createTrack_l(
-        int streamType,
+        audio_stream_type_t streamType,
         uint32_t sampleRate,
         audio_format_t format,
         uint32_t channelMask,
@@ -818,7 +818,7 @@
     }
 
     mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000);
-    mCblk->sendLevel = uint16_t(mSendLevel * 0x1000);
+    mCblk->setSendLevel(mSendLevel);
     mAudioTrack->attachAuxEffect(mAuxEffectId);
     mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
     mCblk->waitTimeMs = 0;
@@ -979,7 +979,7 @@
     ssize_t written = 0;
     const int8_t *src = (const int8_t *)buffer;
     Buffer audioBuffer;
-    size_t frameSz = (size_t)frameSize();
+    size_t frameSz = frameSize();
 
     do {
         audioBuffer.frameCount = userSize/frameSz;
@@ -1137,7 +1137,7 @@
 
         audioBuffer.size = writtenSize;
         // NOTE: mCblk->frameSize is not equal to AudioTrack::frameSize() for
-        // 8 bit PCM data: in this case,  mCblk->frameSize is based on a sampel size of
+        // 8 bit PCM data: in this case,  mCblk->frameSize is based on a sample size of
         // 16 bit.
         audioBuffer.frameCount = writtenSize/mCblk->frameSize;
 
@@ -1311,7 +1311,7 @@
     : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
     userBase(0), serverBase(0), buffers(0), frameCount(0),
     loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0),
-    sendLevel(0), flags(0)
+    mSendLevel(0), flags(0)
 {
 }
 
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index abd491f..9ed1a2a 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -82,7 +82,7 @@
 
     virtual sp<IAudioTrack> createTrack(
                                 pid_t pid,
-                                int streamType,
+                                audio_stream_type_t streamType,
                                 uint32_t sampleRate,
                                 uint32_t format,
                                 uint32_t channelMask,
@@ -97,7 +97,7 @@
         sp<IAudioTrack> track;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(pid);
-        data.writeInt32(streamType);
+        data.writeInt32((int32_t) streamType);
         data.writeInt32(sampleRate);
         data.writeInt32(format);
         data.writeInt32(channelMask);
@@ -249,42 +249,42 @@
         return reply.readInt32();
     }
 
-    virtual status_t setStreamVolume(int stream, float value, int output)
+    virtual status_t setStreamVolume(audio_stream_type_t stream, float value, int output)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         data.writeFloat(value);
         data.writeInt32(output);
         remote()->transact(SET_STREAM_VOLUME, data, &reply);
         return reply.readInt32();
     }
 
-    virtual status_t setStreamMute(int stream, bool muted)
+    virtual status_t setStreamMute(audio_stream_type_t stream, bool muted)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         data.writeInt32(muted);
         remote()->transact(SET_STREAM_MUTE, data, &reply);
         return reply.readInt32();
     }
 
-    virtual float streamVolume(int stream, int output) const
+    virtual float streamVolume(audio_stream_type_t stream, int output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         data.writeInt32(output);
         remote()->transact(STREAM_VOLUME, data, &reply);
         return reply.readFloat();
     }
 
-    virtual bool streamMute(int stream) const
+    virtual bool streamMute(audio_stream_type_t stream) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         remote()->transact(STREAM_MUTE, data, &reply);
         return reply.readInt32();
     }
@@ -468,11 +468,11 @@
         return reply.readInt32();
     }
 
-    virtual status_t setStreamOutput(uint32_t stream, int output)
+    virtual status_t setStreamOutput(audio_stream_type_t stream, int output)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         data.writeInt32(output);
         remote()->transact(SET_STREAM_OUTPUT, data, &reply);
         return reply.readInt32();
@@ -687,7 +687,7 @@
             int sessionId = data.readInt32();
             status_t status;
             sp<IAudioTrack> track = createTrack(pid,
-                    streamType, sampleRate, format,
+                    (audio_stream_type_t) streamType, sampleRate, format,
                     channelCount, bufferCount, flags, buffer, output, &sessionId, &status);
             reply->writeInt32(sessionId);
             reply->writeInt32(status);
@@ -762,26 +762,26 @@
             int stream = data.readInt32();
             float volume = data.readFloat();
             int output = data.readInt32();
-            reply->writeInt32( setStreamVolume(stream, volume, output) );
+            reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) );
             return NO_ERROR;
         } break;
         case SET_STREAM_MUTE: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             int stream = data.readInt32();
-            reply->writeInt32( setStreamMute(stream, data.readInt32()) );
+            reply->writeInt32( setStreamMute((audio_stream_type_t) stream, data.readInt32()) );
             return NO_ERROR;
         } break;
         case STREAM_VOLUME: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             int stream = data.readInt32();
             int output = data.readInt32();
-            reply->writeFloat( streamVolume(stream, output) );
+            reply->writeFloat( streamVolume((audio_stream_type_t) stream, output) );
             return NO_ERROR;
         } break;
         case STREAM_MUTE: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             int stream = data.readInt32();
-            reply->writeInt32( streamMute(stream) );
+            reply->writeInt32( streamMute((audio_stream_type_t) stream) );
             return NO_ERROR;
         } break;
         case SET_MODE: {
@@ -904,7 +904,7 @@
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             uint32_t stream = data.readInt32();
             int output = data.readInt32();
-            reply->writeInt32(setStreamOutput(stream, output));
+            reply->writeInt32(setStreamOutput((audio_stream_type_t) stream, output));
             return NO_ERROR;
         } break;
         case SET_VOICE_VOLUME: {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 50b4855..67d9c45 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -154,7 +154,7 @@
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(output);
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         data.writeInt32(session);
         remote()->transact(START_OUTPUT, data, &reply);
         return static_cast <status_t> (reply.readInt32());
@@ -167,7 +167,7 @@
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
         data.writeInt32(output);
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         data.writeInt32(session);
         remote()->transact(STOP_OUTPUT, data, &reply);
         return static_cast <status_t> (reply.readInt32());
@@ -324,11 +324,11 @@
         return static_cast <status_t> (reply.readInt32());
     }
 
-    virtual bool isStreamActive(int stream, uint32_t inPastMs) const
+    virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        data.writeInt32(stream);
+        data.writeInt32((int32_t) stream);
         data.writeInt32(inPastMs);
         remote()->transact(IS_STREAM_ACTIVE, data, &reply);
         return reply.readInt32();
@@ -598,9 +598,9 @@
 
         case IS_STREAM_ACTIVE: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            int stream = data.readInt32();
+            audio_stream_type_t stream = (audio_stream_type_t) data.readInt32();
             uint32_t inPastMs = (uint32_t)data.readInt32();
-            reply->writeInt32( isStreamActive(stream, inPastMs) );
+            reply->writeInt32( isStreamActive((audio_stream_type_t) stream, inPastMs) );
             return NO_ERROR;
         } break;
 
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 9c1e6b7..64cc919 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -198,11 +198,11 @@
         return reply.readInt32();
     }
 
-    status_t setAudioStreamType(int type)
+    status_t setAudioStreamType(audio_stream_type_t stream)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
-        data.writeInt32(type);
+        data.writeInt32((int32_t) stream);
         remote()->transact(SET_AUDIO_STREAM_TYPE, data, &reply);
         return reply.readInt32();
     }
@@ -397,7 +397,7 @@
         } break;
         case SET_AUDIO_STREAM_TYPE: {
             CHECK_INTERFACE(IMediaPlayer, data, reply);
-            reply->writeInt32(setAudioStreamType(data.readInt32()));
+            reply->writeInt32(setAudioStreamType((audio_stream_type_t) data.readInt32()));
             return NO_ERROR;
         } break;
         case SET_LOOPING: {
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 9d32460..5ceb912 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -798,7 +798,7 @@
 //        none
 //
 ////////////////////////////////////////////////////////////////////////////////
-ToneGenerator::ToneGenerator(int streamType, float volume, bool threadCanCallJava) {
+ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava) {
 
     ALOGV("ToneGenerator constructor: streamType=%d, volume=%f\n", streamType, volume);
 
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 4be960c..acf97a6 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -478,7 +478,7 @@
     return reset_l();
 }
 
-status_t MediaPlayer::setAudioStreamType(int type)
+status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type)
 {
     ALOGV("MediaPlayer::setAudioStreamType");
     Mutex::Autolock _l(mLock);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index af58cac..a0c20ae 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1010,7 +1010,7 @@
     return p->reset();
 }
 
-status_t MediaPlayerService::Client::setAudioStreamType(int type)
+status_t MediaPlayerService::Client::setAudioStreamType(audio_stream_type_t type)
 {
     ALOGV("[%d] setAudioStreamType(%d)", mConnId, type);
     // TODO: for hardware output, call player instead
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 66f245d..6b68b87 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -92,7 +92,7 @@
         virtual void            flush();
         virtual void            pause();
         virtual void            close();
-                void            setAudioStreamType(int streamType) { mStreamType = streamType; }
+                void            setAudioStreamType(audio_stream_type_t streamType) { mStreamType = streamType; }
                 void            setVolume(float left, float right);
                 status_t        setAuxEffectSendLevel(float level);
                 status_t        attachAuxEffect(int effectId);
@@ -108,7 +108,7 @@
         AudioTrack*             mTrack;
         AudioCallback           mCallback;
         void *                  mCallbackCookie;
-        int                     mStreamType;
+        audio_stream_type_t     mStreamType;
         float                   mLeftVolume;
         float                   mRightVolume;
         float                   mMsecsPerFrame;
@@ -149,7 +149,7 @@
         virtual void            flush() {}
         virtual void            pause() {}
         virtual void            close() {}
-                void            setAudioStreamType(int streamType) {}
+                void            setAudioStreamType(audio_stream_type_t streamType) {}
                 void            setVolume(float left, float right) {}
                 uint32_t        sampleRate() const { return mSampleRate; }
                 audio_format_t  format() const { return mFormat; }
@@ -259,7 +259,7 @@
         virtual status_t        getCurrentPosition(int* msec);
         virtual status_t        getDuration(int* msec);
         virtual status_t        reset();
-        virtual status_t        setAudioStreamType(int type);
+        virtual status_t        setAudioStreamType(audio_stream_type_t type);
         virtual status_t        setLooping(int loop);
         virtual status_t        setVolume(float leftVolume, float rightVolume);
         virtual status_t        invoke(const Parcel& request, Parcel *reply);
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index 2a0dcf9..dfe4318 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -78,7 +78,7 @@
     EAS_I32             mDuration;
     EAS_STATE           mState;
     EAS_FILE            mFileLocator;
-    int                 mStreamType;
+    audio_stream_type_t mStreamType;
     bool                mLoop;
     volatile bool       mExit;
     bool                mPaused;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 9fb666e..cf925b0 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -380,7 +380,7 @@
 
 sp<IAudioTrack> AudioFlinger::createTrack(
         pid_t pid,
-        int streamType,
+        audio_stream_type_t streamType,
         uint32_t sampleRate,
         uint32_t format,
         uint32_t channelMask,
@@ -398,7 +398,9 @@
     status_t lStatus;
     int lSessionId;
 
-    if (streamType >= AUDIO_STREAM_CNT) {
+    // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
+    // but if someone uses binder directly they could bypass that and cause us to crash
+    if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
         ALOGE("createTrack() invalid stream type %d", streamType);
         lStatus = BAD_VALUE;
         goto Exit;
@@ -646,22 +648,24 @@
 
 float AudioFlinger::masterVolume() const
 {
-    return mMasterVolume;
+    Mutex::Autolock _l(mLock);
+    return masterVolume_l();
 }
 
 bool AudioFlinger::masterMute() const
 {
-    return mMasterMute;
+    Mutex::Autolock _l(mLock);
+    return masterMute_l();
 }
 
-status_t AudioFlinger::setStreamVolume(int stream, float value, int output)
+status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, int output)
 {
     // check calling permissions
     if (!settingsAllowed()) {
         return PERMISSION_DENIED;
     }
 
-    if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) {
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         ALOGE("setStreamVolume() invalid stream %d", stream);
         return BAD_VALUE;
     }
@@ -688,14 +692,14 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::setStreamMute(int stream, bool muted)
+status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
 {
     // check calling permissions
     if (!settingsAllowed()) {
         return PERMISSION_DENIED;
     }
 
-    if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT ||
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT ||
         uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
         ALOGE("setStreamMute() invalid stream %d", stream);
         return BAD_VALUE;
@@ -709,9 +713,9 @@
     return NO_ERROR;
 }
 
-float AudioFlinger::streamVolume(int stream, int output) const
+float AudioFlinger::streamVolume(audio_stream_type_t stream, int output) const
 {
-    if (stream < 0 || uint32_t(stream) >= AUDIO_STREAM_CNT) {
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         return 0.0f;
     }
 
@@ -730,9 +734,9 @@
     return volume;
 }
 
-bool AudioFlinger::streamMute(int stream) const
+bool AudioFlinger::streamMute(audio_stream_type_t stream) const
 {
-    if (stream < 0 || stream >= (int)AUDIO_STREAM_CNT) {
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         return true;
     }
 
@@ -1118,7 +1122,7 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "Format: %d\n", mFormat);
     result.append(buffer);
-    snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize);
+    snprintf(buffer, SIZE, "Frame size: %u\n", mFrameSize);
     result.append(buffer);
 
     snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
@@ -1379,13 +1383,19 @@
 
     readOutputParameters();
 
-    mMasterVolume = mAudioFlinger->masterVolume();
-    mMasterMute = mAudioFlinger->masterMute();
+    // Assumes constructor is called by AudioFlinger with it's mLock held,
+    // but it would be safer to explicitly pass these as parameters
+    mMasterVolume = mAudioFlinger->masterVolume_l();
+    mMasterMute = mAudioFlinger->masterMute_l();
 
-    for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
+    // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor
+    // There is no AUDIO_STREAM_MIN, and ++ operator does not compile
+    for (audio_stream_type_t stream = (audio_stream_type_t) 0; stream < AUDIO_STREAM_CNT;
+            stream = (audio_stream_type_t) (stream + 1)) {
         mStreamTypes[stream].volume = mAudioFlinger->streamVolumeInternal(stream);
         mStreamTypes[stream].mute = mAudioFlinger->streamMute(stream);
-        mStreamTypes[stream].valid = true;
+        // initialized by stream_type_t default constructor
+        // mStreamTypes[stream].valid = true;
     }
 }
 
@@ -1483,7 +1493,7 @@
 // PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
 sp<AudioFlinger::PlaybackThread::Track>  AudioFlinger::PlaybackThread::createTrack_l(
         const sp<AudioFlinger::Client>& client,
-        int streamType,
+        audio_stream_type_t streamType,
         uint32_t sampleRate,
         uint32_t format,
         uint32_t channelMask,
@@ -1606,24 +1616,24 @@
     return mMasterMute;
 }
 
-status_t AudioFlinger::PlaybackThread::setStreamVolume(int stream, float value)
+status_t AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
 {
     mStreamTypes[stream].volume = value;
     return NO_ERROR;
 }
 
-status_t AudioFlinger::PlaybackThread::setStreamMute(int stream, bool muted)
+status_t AudioFlinger::PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
 {
     mStreamTypes[stream].mute = muted;
     return NO_ERROR;
 }
 
-float AudioFlinger::PlaybackThread::streamVolume(int stream) const
+float AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) const
 {
     return mStreamTypes[stream].volume;
 }
 
-bool AudioFlinger::PlaybackThread::streamMute(int stream) const
+bool AudioFlinger::PlaybackThread::streamMute(audio_stream_type_t stream) const
 {
     return mStreamTypes[stream].mute;
 }
@@ -1727,7 +1737,7 @@
     mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common);
     mChannelCount = (uint16_t)popcount(mChannelMask);
     mFormat = mOutput->stream->common.get_format(&mOutput->stream->common);
-    mFrameSize = (uint16_t)audio_stream_frame_size(&mOutput->stream->common);
+    mFrameSize = audio_stream_frame_size(&mOutput->stream->common);
     mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize;
 
     // FIXME - Current mixer implementation only supports stereo output: Always
@@ -2183,7 +2193,13 @@
                 vl = (uint32_t)(v * cblk->volume[0]) << 12;
                 vr = (uint32_t)(v * cblk->volume[1]) << 12;
 
-                va = (uint32_t)(v * cblk->sendLevel);
+                uint16_t sendLevel = cblk->getSendLevel_U4_12();
+                // send level comes from shared memory and so may be corrupt
+                if (sendLevel >= 0x1000) {
+                    ALOGV("Track send level out of range: %04X", sendLevel);
+                    sendLevel = 0x1000;
+                }
+                va = (uint32_t)(v * sendLevel);
             }
             // Delegate volume control to effect in track effect chain if needed
             if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
@@ -2297,7 +2313,7 @@
     return mixerStatus;
 }
 
-void AudioFlinger::MixerThread::invalidateTracks(int streamType)
+void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
 {
     ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
             this,  streamType, mTracks.size());
@@ -2313,7 +2329,7 @@
     }
 }
 
-void AudioFlinger::PlaybackThread::setStreamValid(int streamType, bool valid)
+void AudioFlinger::PlaybackThread::setStreamValid(audio_stream_type_t streamType, bool valid)
 {
     ALOGV ("PlaybackThread::setStreamValid() thread %p, streamType %d, valid %d",
             this,  streamType, valid);
@@ -3324,12 +3340,13 @@
 
 void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
     audio_track_cblk_t* cblk = this->cblk();
-    int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*cblk->frameSize;
-    int8_t *bufferEnd = bufferStart + frames * cblk->frameSize;
+    size_t frameSize = cblk->frameSize;
+    int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*frameSize;
+    int8_t *bufferEnd = bufferStart + frames * frameSize;
 
     // Check validity of returned pointer in case the track control block would have been corrupted.
     if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd ||
-        ((unsigned long)bufferStart & (unsigned long)(cblk->frameSize - 1))) {
+        ((unsigned long)bufferStart & (unsigned long)(frameSize - 1))) {
         ALOGE("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
                 server %d, serverBase %d, user %d, userBase %d",
                 bufferStart, bufferEnd, mBuffer, mBufferEnd,
@@ -3346,7 +3363,7 @@
 AudioFlinger::PlaybackThread::Track::Track(
             const wp<ThreadBase>& thread,
             const sp<Client>& client,
-            int streamType,
+            audio_stream_type_t streamType,
             uint32_t sampleRate,
             uint32_t format,
             uint32_t channelMask,
@@ -4800,7 +4817,7 @@
     mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common);
     mChannelCount = (uint16_t)popcount(mChannelMask);
     mFormat = mInput->stream->common.get_format(&mInput->stream->common);
-    mFrameSize = (uint16_t)audio_stream_frame_size(&mInput->stream->common);
+    mFrameSize = audio_stream_frame_size(&mInput->stream->common);
     mInputBytes = mInput->stream->common.get_buffer_size(&mInput->stream->common);
     mFrameCount = mInputBytes / mFrameSize;
     mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
@@ -5156,7 +5173,7 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::setStreamOutput(uint32_t stream, int output)
+status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, int output)
 {
     Mutex::Autolock _l(mLock);
     MixerThread *dstThread = checkMixerThread_l(output);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index f99e764..9d1d862 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -70,7 +70,7 @@
     // IAudioFlinger interface
     virtual sp<IAudioTrack> createTrack(
                                 pid_t pid,
-                                int streamType,
+                                audio_stream_type_t streamType,
                                 uint32_t sampleRate,
                                 uint32_t format,
                                 uint32_t channelMask,
@@ -93,11 +93,11 @@
     virtual     float       masterVolume() const;
     virtual     bool        masterMute() const;
 
-    virtual     status_t    setStreamVolume(int stream, float value, int output);
-    virtual     status_t    setStreamMute(int stream, bool muted);
+    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value, int output);
+    virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted);
 
-    virtual     float       streamVolume(int stream, int output) const;
-    virtual     bool        streamMute(int stream) const;
+    virtual     float       streamVolume(audio_stream_type_t stream, int output) const;
+    virtual     bool        streamMute(audio_stream_type_t stream) const;
 
     virtual     status_t    setMode(int mode);
 
@@ -135,7 +135,7 @@
 
     virtual status_t closeInput(int input);
 
-    virtual status_t setStreamOutput(uint32_t stream, int output);
+    virtual status_t setStreamOutput(audio_stream_type_t stream, int output);
 
     virtual status_t setVoiceVolume(float volume);
 
@@ -536,7 +536,7 @@
                     size_t                  mFrameCount;
                     uint32_t                mChannelMask;
                     uint16_t                mChannelCount;
-                    uint16_t                mFrameSize;
+                    size_t                  mFrameSize;
                     uint32_t                mFormat;
                     Condition               mParamCond;
                     Vector<String8>         mNewParameters;
@@ -573,7 +573,7 @@
         public:
                                 Track(  const wp<ThreadBase>& thread,
                                         const sp<Client>& client,
-                                        int streamType,
+                                        audio_stream_type_t streamType,
                                         uint32_t sampleRate,
                                         uint32_t format,
                                         uint32_t channelMask,
@@ -595,7 +595,7 @@
                         return mName;
                     }
 
-                    int type() const {
+                    audio_stream_type_t type() const {
                         return mStreamType;
                     }
                     status_t    attachAuxEffect(int EffectId);
@@ -641,7 +641,7 @@
             int8_t              mRetryCount;
             sp<IMemory>         mSharedBuffer;
             bool                mResetDone;
-            int                 mStreamType;
+            audio_stream_type_t mStreamType;
             int                 mName;
             int16_t             *mMainBuffer;
             int32_t             *mAuxBuffer;
@@ -707,15 +707,15 @@
         virtual     float       masterVolume() const;
         virtual     bool        masterMute() const;
 
-        virtual     status_t    setStreamVolume(int stream, float value);
-        virtual     status_t    setStreamMute(int stream, bool muted);
+        virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value);
+        virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted);
 
-        virtual     float       streamVolume(int stream) const;
-        virtual     bool        streamMute(int stream) const;
+        virtual     float       streamVolume(audio_stream_type_t stream) const;
+        virtual     bool        streamMute(audio_stream_type_t stream) const;
 
                     sp<Track>   createTrack_l(
                                     const sp<AudioFlinger::Client>& client,
-                                    int streamType,
+                                    audio_stream_type_t streamType,
                                     uint32_t sampleRate,
                                     uint32_t format,
                                     uint32_t channelMask,
@@ -747,7 +747,7 @@
                     virtual uint32_t hasAudioSession(int sessionId);
                     virtual uint32_t getStrategyForSession_l(int sessionId);
 
-                            void setStreamValid(int streamType, bool valid);
+                            void setStreamValid(audio_stream_type_t streamType, bool valid);
 
         struct  stream_type_t {
             stream_type_t()
@@ -765,7 +765,9 @@
         int16_t*                        mMixBuffer;
         int                             mSuspended;
         int                             mBytesWritten;
+    private:
         bool                            mMasterMute;
+    protected:
         SortedVector< wp<Track> >       mActiveTracks;
 
         virtual int             getTrackName_l() = 0;
@@ -797,7 +799,7 @@
         status_t    dumpTracks(int fd, const Vector<String16>& args);
 
         SortedVector< sp<Track> >       mTracks;
-        // mStreamTypes[] uses 1 additionnal stream type internally for the OutputTrack used by DuplicatingThread
+        // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by DuplicatingThread
         stream_type_t                   mStreamTypes[AUDIO_STREAM_CNT + 1];
         AudioStreamOut*                 mOutput;
         float                           mMasterVolume;
@@ -818,7 +820,7 @@
         // Thread virtuals
         virtual     bool        threadLoop();
 
-                    void        invalidateTracks(int streamType);
+                    void        invalidateTracks(audio_stream_type_t streamType);
         virtual     bool        checkForNewParameters_l();
         virtual     status_t    dumpInternals(int fd, const Vector<String16>& args);
 
@@ -884,7 +886,7 @@
               PlaybackThread *checkPlaybackThread_l(int output) const;
               MixerThread *checkMixerThread_l(int output) const;
               RecordThread *checkRecordThread_l(int input) const;
-              float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; }
+              float streamVolumeInternal(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; }
               void audioConfigChanged_l(int event, int ioHandle, void *param2);
 
               uint32_t nextUniqueId();
@@ -1388,6 +1390,8 @@
 
                 DefaultKeyedVector< int, sp<PlaybackThread> >  mPlaybackThreads;
                 PlaybackThread::stream_type_t       mStreamTypes[AUDIO_STREAM_CNT];
+
+                // both are protected by mLock
                 float                               mMasterVolume;
                 bool                                mMasterMute;
 
@@ -1399,6 +1403,9 @@
                 bool                                mBtNrecIsOff;
 
                 Vector<AudioSessionRef*> mAudioSessionRefs;
+
+                float       masterVolume_l() const  { return mMasterVolume; }
+                bool        masterMute_l() const    { return mMasterMute; }
 };
 
 
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 3f86d58..44311d0 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -400,7 +400,7 @@
     if (!checkPermission()) {
         return PERMISSION_DENIED;
     }
-    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         return BAD_VALUE;
     }
     mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
@@ -415,7 +415,7 @@
     if (!checkPermission()) {
         return PERMISSION_DENIED;
     }
-    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         return BAD_VALUE;
     }
 
@@ -427,7 +427,7 @@
     if (mpAudioPolicy == NULL) {
         return NO_INIT;
     }
-    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
+    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         return BAD_VALUE;
     }
     return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
@@ -486,7 +486,7 @@
     return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled);
 }
 
-bool AudioPolicyService::isStreamActive(int stream, uint32_t inPastMs) const
+bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
 {
     if (mpAudioPolicy == NULL) {
         return 0;
@@ -781,7 +781,7 @@
     return NO_ERROR;
 }
 
-void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
+void AudioPolicyService::AudioCommandThread::startToneCommand(int type, audio_stream_type_t stream)
 {
     AudioCommand *command = new AudioCommand();
     command->mCommand = START_TONE;
@@ -808,7 +808,7 @@
     mWaitWorkCV.signal();
 }
 
-status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream,
+status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
                                                                float volume,
                                                                int output,
                                                                int delayMs)
@@ -1019,7 +1019,7 @@
                                         audio_io_handle_t output,
                                         int delayMs)
 {
-    return (int)mAudioCommandThread->volumeCommand((int)stream, volume,
+    return (int)mAudioCommandThread->volumeCommand(stream, volume,
                                                    (int)output, delayMs);
 }
 
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 88cb1e9..e98ec68 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -102,7 +102,7 @@
                                     int id);
     virtual status_t unregisterEffect(int id);
     virtual status_t setEffectEnabled(int id, bool enabled);
-    virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const;
+    virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
 
     virtual status_t queryDefaultPreProcessing(int audioSession,
                                               effect_descriptor_t *descriptors,
@@ -168,9 +168,9 @@
         virtual     bool        threadLoop();
 
                     void        exit();
-                    void        startToneCommand(int type = 0, int stream = 0);
+                    void        startToneCommand(int type = 0, audio_stream_type_t stream = AUDIO_STREAM_VOICE_CALL);
                     void        stopToneCommand();
-                    status_t    volumeCommand(int stream, float volume, int output, int delayMs = 0);
+                    status_t    volumeCommand(audio_stream_type_t stream, float volume, int output, int delayMs = 0);
                     status_t    parametersCommand(int ioHandle, const char *keyValuePairs, int delayMs = 0);
                     status_t    voiceVolumeCommand(float volume, int delayMs = 0);
                     void        insertCommand_l(AudioCommand *command, int delayMs = 0);
@@ -196,12 +196,12 @@
         class ToneData {
         public:
             int mType;      // tone type (START_TONE only)
-            int mStream;    // stream type (START_TONE only)
+            audio_stream_type_t mStream;    // stream type (START_TONE only)
         };
 
         class VolumeData {
         public:
-            int mStream;
+            audio_stream_type_t mStream;
             float mVolume;
             int mIO;
         };
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index cbd284c..104a02d 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -39,6 +39,7 @@
     private static final boolean DBG = false;
 
     private WifiStateMachine mWifiStateMachine;
+    private WifiConfigStore mWifiConfigStore;
     private int mAuthenticationFailuresCount = 0;
     /* Indicates authentication failure in supplicant broadcast.
      * TODO: enhance auth failure reporting to include notification
@@ -62,11 +63,12 @@
     private State mCompletedState = new CompletedState();
     private State mDormantState = new DormantState();
 
-    public SupplicantStateTracker(Context context, WifiStateMachine wsm, Handler target) {
-        super(TAG, target.getLooper());
+    public SupplicantStateTracker(Context c, WifiStateMachine wsm, WifiConfigStore wcs, Handler t) {
+        super(TAG, t.getLooper());
 
-        mContext = context;
+        mContext = c;
         mWifiStateMachine = wsm;
+        mWifiConfigStore = wcs;
         addState(mDefaultState);
             addState(mUninitializedState, mDefaultState);
             addState(mInactiveState, mDefaultState);
@@ -85,11 +87,11 @@
     private void handleNetworkConnectionFailure(int netId) {
         /* If other networks disabled during connection, enable them */
         if (mNetworksDisabledDuringConnect) {
-            WifiConfigStore.enableAllNetworks();
+            mWifiConfigStore.enableAllNetworks();
             mNetworksDisabledDuringConnect = false;
         }
         /* Disable failed network */
-        WifiConfigStore.disableNetwork(netId, WifiConfiguration.DISABLED_AUTH_FAILURE);
+        mWifiConfigStore.disableNetwork(netId, WifiConfiguration.DISABLED_AUTH_FAILURE);
     }
 
     private void transitionOnSupplicantStateChange(StateChangeResult stateChangeResult) {
@@ -285,7 +287,7 @@
              /* Reset authentication failure count */
              mAuthenticationFailuresCount = 0;
              if (mNetworksDisabledDuringConnect) {
-                 WifiConfigStore.enableAllNetworks();
+                 mWifiConfigStore.enableAllNetworks();
                  mNetworksDisabledDuringConnect = false;
              }
         }
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index cba0fba..5dffa60 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -103,12 +103,12 @@
  */
 class WifiConfigStore {
 
-    private static Context sContext;
+    private Context mContext;
     private static final String TAG = "WifiConfigStore";
     private static final boolean DBG = false;
 
     /* configured networks with network id as the key */
-    private static HashMap<Integer, WifiConfiguration> sConfiguredNetworks =
+    private HashMap<Integer, WifiConfiguration> mConfiguredNetworks =
             new HashMap<Integer, WifiConfiguration>();
 
     /* A network id is a unique identifier for a network configured in the
@@ -118,11 +118,11 @@
      * that is generated from SSID and security type of the network. A mapping
      * from the generated unique id to network id of the network is needed to
      * map supplicant config to IP configuration. */
-    private static HashMap<Integer, Integer> sNetworkIds =
+    private HashMap<Integer, Integer> mNetworkIds =
             new HashMap<Integer, Integer>();
 
     /* Tracks the highest priority of configured networks */
-    private static int sLastPriority = -1;
+    private int mLastPriority = -1;
 
     private static final String ipConfigFile = Environment.getDataDirectory() +
             "/misc/wifi/ipconfig.txt";
@@ -141,20 +141,19 @@
     private static final String EXCLUSION_LIST_KEY = "exclusionList";
     private static final String EOS = "eos";
 
-    private static HandlerThread sDiskWriteHandlerThread;
-    private static DiskWriteHandler sDiskWriteHandler;
-    private static Object sDiskWriteHandlerSync = new Object();
-    /* Tracks multiple writes on the same thread */
-    private static int sWriteSequence = 0;
-    private static final int WRITE = 1;
+    private WifiNative mWifiNative;
+
+    WifiConfigStore(Context c, WifiNative wn) {
+        mContext = c;
+        mWifiNative = wn;
+    }
 
     /**
-     * Initialize context, fetch the list of configured networks
+     * Fetch the list of configured networks
      * and enable all stored networks in supplicant.
      */
-    static void initialize(Context context) {
+    void initialize() {
         if (DBG) log("Loading config and enabling all networks");
-        sContext = context;
         loadConfiguredNetworks();
         enableAllNetworks();
     }
@@ -163,9 +162,9 @@
      * Fetch the list of currently configured networks
      * @return List of networks
      */
-    static List<WifiConfiguration> getConfiguredNetworks() {
+    List<WifiConfiguration> getConfiguredNetworks() {
         List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-        for(WifiConfiguration config : sConfiguredNetworks.values()) {
+        for(WifiConfiguration config : mConfiguredNetworks.values()) {
             networks.add(new WifiConfiguration(config));
         }
         return networks;
@@ -175,11 +174,11 @@
      * enable all networks and save config. This will be a no-op if the list
      * of configured networks indicates all networks as being enabled
      */
-    static void enableAllNetworks() {
+    void enableAllNetworks() {
         boolean networkEnabledStateChanged = false;
-        for(WifiConfiguration config : sConfiguredNetworks.values()) {
+        for(WifiConfiguration config : mConfiguredNetworks.values()) {
             if(config != null && config.status == Status.DISABLED) {
-                if(WifiNative.enableNetwork(config.networkId, false)) {
+                if(mWifiNative.enableNetwork(config.networkId, false)) {
                     networkEnabledStateChanged = true;
                     config.status = Status.ENABLED;
                 } else {
@@ -189,7 +188,7 @@
         }
 
         if (networkEnabledStateChanged) {
-            WifiNative.saveConfig();
+            mWifiNative.saveConfig();
             sendConfiguredNetworksChangedBroadcast();
         }
     }
@@ -206,7 +205,7 @@
      * @param config The configuration details in WifiConfiguration
      * @return the networkId now associated with the specified configuration
      */
-    static int selectNetwork(WifiConfiguration config) {
+    int selectNetwork(WifiConfiguration config) {
         if (config != null) {
             NetworkUpdateResult result = addOrUpdateNetworkNative(config);
             int netId = result.getNetworkId();
@@ -231,25 +230,25 @@
      *
      * @param netId network to select for connection
      */
-    static void selectNetwork(int netId) {
+    void selectNetwork(int netId) {
         // Reset the priority of each network at start or if it goes too high.
-        if (sLastPriority == -1 || sLastPriority > 1000000) {
-            for(WifiConfiguration config : sConfiguredNetworks.values()) {
+        if (mLastPriority == -1 || mLastPriority > 1000000) {
+            for(WifiConfiguration config : mConfiguredNetworks.values()) {
                 if (config.networkId != INVALID_NETWORK_ID) {
                     config.priority = 0;
                     addOrUpdateNetworkNative(config);
                 }
             }
-            sLastPriority = 0;
+            mLastPriority = 0;
         }
 
         // Set to the highest priority and save the configuration.
         WifiConfiguration config = new WifiConfiguration();
         config.networkId = netId;
-        config.priority = ++sLastPriority;
+        config.priority = ++mLastPriority;
 
         addOrUpdateNetworkNative(config);
-        WifiNative.saveConfig();
+        mWifiNative.saveConfig();
 
         /* Enable the given network while disabling all other networks */
         enableNetworkWithoutBroadcast(netId, true);
@@ -263,23 +262,23 @@
      *
      * @param config WifiConfiguration to be saved
      */
-    static NetworkUpdateResult saveNetwork(WifiConfiguration config) {
+    NetworkUpdateResult saveNetwork(WifiConfiguration config) {
         boolean newNetwork = (config.networkId == INVALID_NETWORK_ID);
         NetworkUpdateResult result = addOrUpdateNetworkNative(config);
         int netId = result.getNetworkId();
         /* enable a new network */
         if (newNetwork && netId != INVALID_NETWORK_ID) {
-            WifiNative.enableNetwork(netId, false);
-            sConfiguredNetworks.get(netId).status = Status.ENABLED;
+            mWifiNative.enableNetwork(netId, false);
+            mConfiguredNetworks.get(netId).status = Status.ENABLED;
         }
-        WifiNative.saveConfig();
+        mWifiNative.saveConfig();
         sendConfiguredNetworksChangedBroadcast();
         return result;
     }
 
-    static void updateStatus(int netId, DetailedState state) {
+    void updateStatus(int netId, DetailedState state) {
         if (netId != INVALID_NETWORK_ID) {
-            WifiConfiguration config = sConfiguredNetworks.get(netId);
+            WifiConfiguration config = mConfiguredNetworks.get(netId);
             if (config == null) return;
             switch (state) {
                 case CONNECTED:
@@ -300,13 +299,13 @@
      *
      * @param netId network to forget
      */
-    static void forgetNetwork(int netId) {
-        if (WifiNative.removeNetwork(netId)) {
-            WifiNative.saveConfig();
-            WifiConfiguration config = sConfiguredNetworks.get(netId);
+    void forgetNetwork(int netId) {
+        if (mWifiNative.removeNetwork(netId)) {
+            mWifiNative.saveConfig();
+            WifiConfiguration config = mConfiguredNetworks.get(netId);
             if (config != null) {
-                sConfiguredNetworks.remove(netId);
-                sNetworkIds.remove(configKey(config));
+                mConfiguredNetworks.remove(netId);
+                mNetworkIds.remove(configKey(config));
             }
             writeIpAndProxyConfigurations();
             sendConfiguredNetworksChangedBroadcast();
@@ -323,7 +322,7 @@
      *
      * @param config wifi configuration to add/update
      */
-    static int addOrUpdateNetwork(WifiConfiguration config) {
+    int addOrUpdateNetwork(WifiConfiguration config) {
         NetworkUpdateResult result = addOrUpdateNetworkNative(config);
         sendConfiguredNetworksChangedBroadcast();
         return result.getNetworkId();
@@ -337,13 +336,13 @@
      *
      * @param netId network to be removed
      */
-    static boolean removeNetwork(int netId) {
-        boolean ret = WifiNative.removeNetwork(netId);
+    boolean removeNetwork(int netId) {
+        boolean ret = mWifiNative.removeNetwork(netId);
         if (ret) {
-            WifiConfiguration config = sConfiguredNetworks.get(netId);
+            WifiConfiguration config = mConfiguredNetworks.get(netId);
             if (config != null) {
-                sConfiguredNetworks.remove(netId);
-                sNetworkIds.remove(configKey(config));
+                mConfiguredNetworks.remove(netId);
+                mNetworkIds.remove(configKey(config));
             }
         }
         sendConfiguredNetworksChangedBroadcast();
@@ -358,16 +357,16 @@
      *
      * @param netId network to be removed
      */
-    static boolean enableNetwork(int netId, boolean disableOthers) {
+    boolean enableNetwork(int netId, boolean disableOthers) {
         boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
         sendConfiguredNetworksChangedBroadcast();
         return ret;
     }
 
-    static boolean enableNetworkWithoutBroadcast(int netId, boolean disableOthers) {
-        boolean ret = WifiNative.enableNetwork(netId, disableOthers);
+    boolean enableNetworkWithoutBroadcast(int netId, boolean disableOthers) {
+        boolean ret = mWifiNative.enableNetwork(netId, disableOthers);
 
-        WifiConfiguration config = sConfiguredNetworks.get(netId);
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
         if (config != null) config.status = Status.ENABLED;
 
         if (disableOthers) {
@@ -380,7 +379,7 @@
      * Disable a network. Note that there is no saveConfig operation.
      * @param netId network to be disabled
      */
-    static boolean disableNetwork(int netId) {
+    boolean disableNetwork(int netId) {
         return disableNetwork(netId, WifiConfiguration.DISABLED_UNKNOWN_REASON);
     }
 
@@ -389,9 +388,9 @@
      * @param netId network to be disabled
      * @param reason reason code network was disabled
      */
-    static boolean disableNetwork(int netId, int reason) {
-        boolean ret = WifiNative.disableNetwork(netId);
-        WifiConfiguration config = sConfiguredNetworks.get(netId);
+    boolean disableNetwork(int netId, int reason) {
+        boolean ret = mWifiNative.disableNetwork(netId);
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
         /* Only change the reason if the network was not previously disabled */
         if (config != null && config.status != Status.DISABLED) {
             config.status = Status.DISABLED;
@@ -404,17 +403,17 @@
     /**
      * Save the configured networks in supplicant to disk
      */
-    static boolean saveConfig() {
-        return WifiNative.saveConfig();
+    boolean saveConfig() {
+        return mWifiNative.saveConfig();
     }
 
     /**
      * Start WPS pin method configuration with pin obtained
      * from the access point
      */
-    static WpsResult startWpsWithPinFromAccessPoint(WpsInfo config) {
+    WpsResult startWpsWithPinFromAccessPoint(WpsInfo config) {
         WpsResult result = new WpsResult();
-        if (WifiNative.startWpsRegistrar(config.BSSID, config.pin)) {
+        if (mWifiNative.startWpsRegistrar(config.BSSID, config.pin)) {
             /* WPS leaves all networks disabled */
             markAllNetworksDisabled();
             result.status = WpsResult.Status.SUCCESS;
@@ -430,9 +429,9 @@
      * from the device
      * @return WpsResult indicating status and pin
      */
-    static WpsResult startWpsWithPinFromDevice(WpsInfo config) {
+    WpsResult startWpsWithPinFromDevice(WpsInfo config) {
         WpsResult result = new WpsResult();
-        result.pin = WifiNative.startWpsPinDisplay(config.BSSID);
+        result.pin = mWifiNative.startWpsPinDisplay(config.BSSID);
         /* WPS leaves all networks disabled */
         if (!TextUtils.isEmpty(result.pin)) {
             markAllNetworksDisabled();
@@ -447,9 +446,9 @@
     /**
      * Start WPS push button configuration
      */
-    static WpsResult startWpsPbc(WpsInfo config) {
+    WpsResult startWpsPbc(WpsInfo config) {
         WpsResult result = new WpsResult();
-        if (WifiNative.startWpsPbc(config.BSSID)) {
+        if (mWifiNative.startWpsPbc(config.BSSID)) {
             /* WPS leaves all networks disabled */
             markAllNetworksDisabled();
             result.status = WpsResult.Status.SUCCESS;
@@ -463,8 +462,8 @@
     /**
      * Fetch the link properties for a given network id
      */
-    static LinkProperties getLinkProperties(int netId) {
-        WifiConfiguration config = sConfiguredNetworks.get(netId);
+    LinkProperties getLinkProperties(int netId) {
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
         if (config != null) return new LinkProperties(config.linkProperties);
         return null;
     }
@@ -476,7 +475,7 @@
      *       that, we should remove handling DhcpInfo and move
      *       to using LinkProperties
      */
-    static DhcpInfoInternal getIpConfiguration(int netId) {
+    DhcpInfoInternal getIpConfiguration(int netId) {
         DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
         LinkProperties linkProperties = getLinkProperties(netId);
 
@@ -502,10 +501,10 @@
     /**
      * set IP configuration for a given network id
      */
-    static void setIpConfiguration(int netId, DhcpInfoInternal dhcpInfo) {
+    void setIpConfiguration(int netId, DhcpInfoInternal dhcpInfo) {
         LinkProperties linkProperties = dhcpInfo.makeLinkProperties();
 
-        WifiConfiguration config = sConfiguredNetworks.get(netId);
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
         if (config != null) {
             // add old proxy details
             if(config.linkProperties != null) {
@@ -518,8 +517,8 @@
     /**
      * clear IP configuration for a given network id
      */
-    static void clearIpConfiguration(int netId) {
-        WifiConfiguration config = sConfiguredNetworks.get(netId);
+    void clearIpConfiguration(int netId) {
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
         if (config != null && config.linkProperties != null) {
             // Clear everything except proxy
             ProxyProperties proxy = config.linkProperties.getHttpProxy();
@@ -532,7 +531,7 @@
     /**
      * Fetch the proxy properties for a given network id
      */
-    static ProxyProperties getProxyProperties(int netId) {
+    ProxyProperties getProxyProperties(int netId) {
         LinkProperties linkProperties = getLinkProperties(netId);
         if (linkProperties != null) {
             return new ProxyProperties(linkProperties.getHttpProxy());
@@ -543,26 +542,26 @@
     /**
      * Return if the specified network is using static IP
      */
-    static boolean isUsingStaticIp(int netId) {
-        WifiConfiguration config = sConfiguredNetworks.get(netId);
+    boolean isUsingStaticIp(int netId) {
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
         if (config != null && config.ipAssignment == IpAssignment.STATIC) {
             return true;
         }
         return false;
     }
 
-    private static void sendConfiguredNetworksChangedBroadcast() {
+    private void sendConfiguredNetworksChangedBroadcast() {
         Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        sContext.sendBroadcast(intent);
+        mContext.sendBroadcast(intent);
     }
 
-    static void loadConfiguredNetworks() {
-        String listStr = WifiNative.listNetworks();
-        sLastPriority = 0;
+    void loadConfiguredNetworks() {
+        String listStr = mWifiNative.listNetworks();
+        mLastPriority = 0;
 
-        sConfiguredNetworks.clear();
-        sNetworkIds.clear();
+        mConfiguredNetworks.clear();
+        mNetworkIds.clear();
 
         if (listStr == null)
             return;
@@ -589,19 +588,19 @@
                 config.status = WifiConfiguration.Status.ENABLED;
             }
             readNetworkVariables(config);
-            if (config.priority > sLastPriority) {
-                sLastPriority = config.priority;
+            if (config.priority > mLastPriority) {
+                mLastPriority = config.priority;
             }
-            sConfiguredNetworks.put(config.networkId, config);
-            sNetworkIds.put(configKey(config), config.networkId);
+            mConfiguredNetworks.put(config.networkId, config);
+            mNetworkIds.put(configKey(config), config.networkId);
         }
 
         readIpAndProxyConfigurations();
         sendConfiguredNetworksChangedBroadcast();
     }
 
-    static void updateIpAndProxyFromWpsConfig(int netId, WpsInfo wpsConfig) {
-        WifiConfiguration config = sConfiguredNetworks.get(netId);
+    void updateIpAndProxyFromWpsConfig(int netId, WpsInfo wpsConfig) {
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
         if (config != null) {
             config.ipAssignment = wpsConfig.ipAssignment;
             config.proxySettings = wpsConfig.proxySettings;
@@ -611,8 +610,8 @@
     }
 
     /* Mark all networks except specified netId as disabled */
-    private static void markAllNetworksDisabledExcept(int netId) {
-        for(WifiConfiguration config : sConfiguredNetworks.values()) {
+    private void markAllNetworksDisabledExcept(int netId) {
+        for(WifiConfiguration config : mConfiguredNetworks.values()) {
             if(config != null && config.networkId != netId) {
                 if (config.status != Status.DISABLED) {
                     config.status = Status.DISABLED;
@@ -622,43 +621,49 @@
         }
     }
 
-    private static void markAllNetworksDisabled() {
+    private void markAllNetworksDisabled() {
         markAllNetworksDisabledExcept(INVALID_NETWORK_ID);
     }
 
-    private static void writeIpAndProxyConfigurations() {
+    private void writeIpAndProxyConfigurations() {
 
         /* Make a copy */
         List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-        for(WifiConfiguration config : sConfiguredNetworks.values()) {
+        for(WifiConfiguration config : mConfiguredNetworks.values()) {
             networks.add(new WifiConfiguration(config));
         }
 
-        /* Do a delayed write to disk on a seperate handler thread */
-        synchronized (sDiskWriteHandlerSync) {
-            if (++sWriteSequence == 1) {
-                sDiskWriteHandlerThread = new HandlerThread("WifiConfigThread");
-                sDiskWriteHandlerThread.start();
-                sDiskWriteHandler = new DiskWriteHandler(sDiskWriteHandlerThread.getLooper());
-            }
-        }
-
-        sDiskWriteHandler.sendMessage(Message.obtain(sDiskWriteHandler, WRITE, networks));
+        DelayedDiskWrite.write(networks);
     }
 
-    private static class DiskWriteHandler extends Handler {
+    private static class DelayedDiskWrite {
 
-        DiskWriteHandler(android.os.Looper l) {
-            super(l);
-        }
+        private static HandlerThread sDiskWriteHandlerThread;
+        private static Handler sDiskWriteHandler;
+        /* Tracks multiple writes on the same thread */
+        private static int sWriteSequence = 0;
+        private static final String TAG = "DelayedDiskWrite";
 
-        public void handleMessage(Message msg) {
+        static void write (final List<WifiConfiguration> networks) {
 
-            if (msg.what != WRITE) {
-                throw new RuntimeException("Unsupported message in WifiConfigStore: " + msg);
+            /* Do a delayed write to disk on a seperate handler thread */
+            synchronized (DelayedDiskWrite.class) {
+                if (++sWriteSequence == 1) {
+                    sDiskWriteHandlerThread = new HandlerThread("WifiConfigThread");
+                    sDiskWriteHandlerThread.start();
+                    sDiskWriteHandler = new Handler(sDiskWriteHandlerThread.getLooper());
+                }
             }
 
-            List<WifiConfiguration> networks = (List<WifiConfiguration>) msg.obj;
+            sDiskWriteHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        onWriteCalled(networks);
+                    }
+                });
+        }
+
+        private static void onWriteCalled(List<WifiConfiguration> networks) {
 
             DataOutputStream out = null;
             try {
@@ -740,7 +745,7 @@
                                 /* Ignore */
                                 break;
                             default:
-                                loge("Ignore invalid proxy settings while writing");
+                                loge("Ignthisore invalid proxy settings while writing");
                                 break;
                         }
                         if (writeToFile) {
@@ -763,18 +768,22 @@
                 }
 
                 //Quit if no more writes sent
-                synchronized (sDiskWriteHandlerSync) {
+                synchronized (DelayedDiskWrite.class) {
                     if (--sWriteSequence == 0) {
-                        getLooper().quit();
+                        sDiskWriteHandler.getLooper().quit();
+                        sDiskWriteHandler = null;
                         sDiskWriteHandlerThread = null;
-                        sDiskWriteHandler= null;
                     }
                 }
             }
-       }
+        }
+
+        private static void loge(String s) {
+            Log.e(TAG, s);
+        }
     }
 
-    private static void readIpAndProxyConfigurations() {
+    private void readIpAndProxyConfigurations() {
 
         DataInputStream in = null;
         try {
@@ -847,8 +856,8 @@
                 } while (true);
 
                 if (id != -1) {
-                    WifiConfiguration config = sConfiguredNetworks.get(
-                            sNetworkIds.get(id));
+                    WifiConfiguration config = mConfiguredNetworks.get(
+                            mNetworkIds.get(id));
 
                     if (config == null) {
                         loge("configuration found for missing network, ignored");
@@ -901,7 +910,7 @@
         }
     }
 
-    private static NetworkUpdateResult addOrUpdateNetworkNative(WifiConfiguration config) {
+    private NetworkUpdateResult addOrUpdateNetworkNative(WifiConfiguration config) {
         /*
          * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
          * network configuration. Otherwise, the networkId should
@@ -911,12 +920,12 @@
         boolean newNetwork = false;
         // networkId of INVALID_NETWORK_ID means we want to create a new network
         if (netId == INVALID_NETWORK_ID) {
-            Integer savedNetId = sNetworkIds.get(configKey(config));
+            Integer savedNetId = mNetworkIds.get(configKey(config));
             if (savedNetId != null) {
                 netId = savedNetId;
             } else {
                 newNetwork = true;
-                netId = WifiNative.addNetwork();
+                netId = mWifiNative.addNetwork();
                 if (netId < 0) {
                     loge("Failed to add a network!");
                     return new NetworkUpdateResult(INVALID_NETWORK_ID);
@@ -929,7 +938,7 @@
         setVariables: {
 
             if (config.SSID != null &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.ssidVarName,
                         config.SSID)) {
@@ -938,7 +947,7 @@
             }
 
             if (config.BSSID != null &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.bssidVarName,
                         config.BSSID)) {
@@ -949,7 +958,7 @@
             String allowedKeyManagementString =
                 makeString(config.allowedKeyManagement, WifiConfiguration.KeyMgmt.strings);
             if (config.allowedKeyManagement.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.KeyMgmt.varName,
                         allowedKeyManagementString)) {
@@ -961,7 +970,7 @@
             String allowedProtocolsString =
                 makeString(config.allowedProtocols, WifiConfiguration.Protocol.strings);
             if (config.allowedProtocols.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.Protocol.varName,
                         allowedProtocolsString)) {
@@ -973,7 +982,7 @@
             String allowedAuthAlgorithmsString =
                 makeString(config.allowedAuthAlgorithms, WifiConfiguration.AuthAlgorithm.strings);
             if (config.allowedAuthAlgorithms.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.AuthAlgorithm.varName,
                         allowedAuthAlgorithmsString)) {
@@ -986,7 +995,7 @@
                     makeString(config.allowedPairwiseCiphers,
                     WifiConfiguration.PairwiseCipher.strings);
             if (config.allowedPairwiseCiphers.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.PairwiseCipher.varName,
                         allowedPairwiseCiphersString)) {
@@ -998,7 +1007,7 @@
             String allowedGroupCiphersString =
                 makeString(config.allowedGroupCiphers, WifiConfiguration.GroupCipher.strings);
             if (config.allowedGroupCiphers.cardinality() != 0 &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.GroupCipher.varName,
                         allowedGroupCiphersString)) {
@@ -1010,7 +1019,7 @@
             // Prevent client screw-up by passing in a WifiConfiguration we gave it
             // by preventing "*" as a key.
             if (config.preSharedKey != null && !config.preSharedKey.equals("*") &&
-                    !WifiNative.setNetworkVariable(
+                    !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.pskVarName,
                         config.preSharedKey)) {
@@ -1024,7 +1033,7 @@
                     // Prevent client screw-up by passing in a WifiConfiguration we gave it
                     // by preventing "*" as a key.
                     if (config.wepKeys[i] != null && !config.wepKeys[i].equals("*")) {
-                        if (!WifiNative.setNetworkVariable(
+                        if (!mWifiNative.setNetworkVariable(
                                     netId,
                                     WifiConfiguration.wepKeyVarNames[i],
                                     config.wepKeys[i])) {
@@ -1037,7 +1046,7 @@
             }
 
             if (hasSetKey) {
-                if (!WifiNative.setNetworkVariable(
+                if (!mWifiNative.setNetworkVariable(
                             netId,
                             WifiConfiguration.wepTxKeyIdxVarName,
                             Integer.toString(config.wepTxKeyIndex))) {
@@ -1046,7 +1055,7 @@
                 }
             }
 
-            if (!WifiNative.setNetworkVariable(
+            if (!mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.priorityVarName,
                         Integer.toString(config.priority))) {
@@ -1055,7 +1064,7 @@
                 break setVariables;
             }
 
-            if (config.hiddenSSID && !WifiNative.setNetworkVariable(
+            if (config.hiddenSSID && !mWifiNative.setNetworkVariable(
                         netId,
                         WifiConfiguration.hiddenSSIDVarName,
                         Integer.toString(config.hiddenSSID ? 1 : 0))) {
@@ -1072,7 +1081,7 @@
                     if (field != config.eap) {
                         value = (value.length() == 0) ? "NULL" : convertToQuotedString(value);
                     }
-                    if (!WifiNative.setNetworkVariable(
+                    if (!mWifiNative.setNetworkVariable(
                                 netId,
                                 varName,
                                 value)) {
@@ -1087,37 +1096,37 @@
 
         if (updateFailed) {
             if (newNetwork) {
-                WifiNative.removeNetwork(netId);
+                mWifiNative.removeNetwork(netId);
                 loge("Failed to set a network variable, removed network: " + netId);
             }
             return new NetworkUpdateResult(INVALID_NETWORK_ID);
         }
 
         /* An update of the network variables requires reading them
-         * back from the supplicant to update sConfiguredNetworks.
+         * back from the supplicant to update mConfiguredNetworks.
          * This is because some of the variables (SSID, wep keys &
          * passphrases) reflect different values when read back than
          * when written. For example, wep key is stored as * irrespective
          * of the value sent to the supplicant
          */
-        WifiConfiguration sConfig = sConfiguredNetworks.get(netId);
-        if (sConfig == null) {
-            sConfig = new WifiConfiguration();
-            sConfig.networkId = netId;
+        WifiConfiguration currentConfig = mConfiguredNetworks.get(netId);
+        if (currentConfig == null) {
+            currentConfig = new WifiConfiguration();
+            currentConfig.networkId = netId;
         }
 
-        readNetworkVariables(sConfig);
+        readNetworkVariables(currentConfig);
 
-        sConfiguredNetworks.put(netId, sConfig);
-        sNetworkIds.put(configKey(sConfig), netId);
+        mConfiguredNetworks.put(netId, currentConfig);
+        mNetworkIds.put(configKey(currentConfig), netId);
 
-        NetworkUpdateResult result = writeIpAndProxyConfigurationsOnChange(sConfig, config);
+        NetworkUpdateResult result = writeIpAndProxyConfigurationsOnChange(currentConfig, config);
         result.setNetworkId(netId);
         return result;
     }
 
     /* Compare current and new configuration and write to file on change */
-    private static NetworkUpdateResult writeIpAndProxyConfigurationsOnChange(
+    private NetworkUpdateResult writeIpAndProxyConfigurationsOnChange(
             WifiConfiguration currentConfig,
             WifiConfiguration newConfig) {
         boolean ipChanged = false;
@@ -1216,7 +1225,7 @@
         return new NetworkUpdateResult(ipChanged, proxyChanged);
     }
 
-    private static void addIpSettingsFromConfig(LinkProperties linkProperties,
+    private void addIpSettingsFromConfig(LinkProperties linkProperties,
             WifiConfiguration config) {
         for (LinkAddress linkAddr : config.linkProperties.getLinkAddresses()) {
             linkProperties.addLinkAddress(linkAddr);
@@ -1235,7 +1244,7 @@
      *
      * @param config the {@link WifiConfiguration} object to be filled in.
      */
-    private static void readNetworkVariables(WifiConfiguration config) {
+    private void readNetworkVariables(WifiConfiguration config) {
 
         int netId = config.networkId;
         if (netId < 0)
@@ -1248,21 +1257,21 @@
          */
         String value;
 
-        value = WifiNative.getNetworkVariable(netId, WifiConfiguration.ssidVarName);
+        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.ssidVarName);
         if (!TextUtils.isEmpty(value)) {
             config.SSID = value;
         } else {
             config.SSID = null;
         }
 
-        value = WifiNative.getNetworkVariable(netId, WifiConfiguration.bssidVarName);
+        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.bssidVarName);
         if (!TextUtils.isEmpty(value)) {
             config.BSSID = value;
         } else {
             config.BSSID = null;
         }
 
-        value = WifiNative.getNetworkVariable(netId, WifiConfiguration.priorityVarName);
+        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.priorityVarName);
         config.priority = -1;
         if (!TextUtils.isEmpty(value)) {
             try {
@@ -1271,7 +1280,7 @@
             }
         }
 
-        value = WifiNative.getNetworkVariable(netId, WifiConfiguration.hiddenSSIDVarName);
+        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.hiddenSSIDVarName);
         config.hiddenSSID = false;
         if (!TextUtils.isEmpty(value)) {
             try {
@@ -1280,7 +1289,7 @@
             }
         }
 
-        value = WifiNative.getNetworkVariable(netId, WifiConfiguration.wepTxKeyIdxVarName);
+        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.wepTxKeyIdxVarName);
         config.wepTxKeyIndex = -1;
         if (!TextUtils.isEmpty(value)) {
             try {
@@ -1290,7 +1299,7 @@
         }
 
         for (int i = 0; i < 4; i++) {
-            value = WifiNative.getNetworkVariable(netId,
+            value = mWifiNative.getNetworkVariable(netId,
                     WifiConfiguration.wepKeyVarNames[i]);
             if (!TextUtils.isEmpty(value)) {
                 config.wepKeys[i] = value;
@@ -1299,14 +1308,14 @@
             }
         }
 
-        value = WifiNative.getNetworkVariable(netId, WifiConfiguration.pskVarName);
+        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.pskVarName);
         if (!TextUtils.isEmpty(value)) {
             config.preSharedKey = value;
         } else {
             config.preSharedKey = null;
         }
 
-        value = WifiNative.getNetworkVariable(config.networkId,
+        value = mWifiNative.getNetworkVariable(config.networkId,
                 WifiConfiguration.Protocol.varName);
         if (!TextUtils.isEmpty(value)) {
             String vals[] = value.split(" ");
@@ -1319,7 +1328,7 @@
             }
         }
 
-        value = WifiNative.getNetworkVariable(config.networkId,
+        value = mWifiNative.getNetworkVariable(config.networkId,
                 WifiConfiguration.KeyMgmt.varName);
         if (!TextUtils.isEmpty(value)) {
             String vals[] = value.split(" ");
@@ -1332,7 +1341,7 @@
             }
         }
 
-        value = WifiNative.getNetworkVariable(config.networkId,
+        value = mWifiNative.getNetworkVariable(config.networkId,
                 WifiConfiguration.AuthAlgorithm.varName);
         if (!TextUtils.isEmpty(value)) {
             String vals[] = value.split(" ");
@@ -1345,7 +1354,7 @@
             }
         }
 
-        value = WifiNative.getNetworkVariable(config.networkId,
+        value = mWifiNative.getNetworkVariable(config.networkId,
                 WifiConfiguration.PairwiseCipher.varName);
         if (!TextUtils.isEmpty(value)) {
             String vals[] = value.split(" ");
@@ -1358,7 +1367,7 @@
             }
         }
 
-        value = WifiNative.getNetworkVariable(config.networkId,
+        value = mWifiNative.getNetworkVariable(config.networkId,
                 WifiConfiguration.GroupCipher.varName);
         if (!TextUtils.isEmpty(value)) {
             String vals[] = value.split(" ");
@@ -1373,7 +1382,7 @@
 
         for (WifiConfiguration.EnterpriseField field :
                 config.enterpriseFields) {
-            value = WifiNative.getNetworkVariable(netId,
+            value = mWifiNative.getNetworkVariable(netId,
                     field.varName());
             if (!TextUtils.isEmpty(value)) {
                 if (field != config.eap) value = removeDoubleQuotes(value);
@@ -1382,16 +1391,16 @@
         }
     }
 
-    private static String removeDoubleQuotes(String string) {
+    private String removeDoubleQuotes(String string) {
         if (string.length() <= 2) return "";
         return string.substring(1, string.length() - 1);
     }
 
-    private static String convertToQuotedString(String string) {
+    private String convertToQuotedString(String string) {
         return "\"" + string + "\"";
     }
 
-    private static String makeString(BitSet set, String[] strings) {
+    private String makeString(BitSet set, String[] strings) {
         StringBuffer buf = new StringBuffer();
         int nextSetBit = -1;
 
@@ -1411,7 +1420,7 @@
         return buf.toString();
     }
 
-    private static int lookupString(String string, String[] strings) {
+    private int lookupString(String string, String[] strings) {
         int size = strings.length;
 
         string = string.replace('-', '_');
@@ -1446,10 +1455,10 @@
         return key.hashCode();
     }
 
-    static String dump() {
+    String dump() {
         StringBuffer sb = new StringBuffer();
         String LS = System.getProperty("line.separator");
-        sb.append("sLastPriority ").append(sLastPriority).append(LS);
+        sb.append("mLastPriority ").append(mLastPriority).append(LS);
         sb.append("Configured networks ").append(LS);
         for (WifiConfiguration conf : getConfiguredNetworks()) {
             sb.append(conf).append(LS);
@@ -1457,15 +1466,15 @@
         return sb.toString();
     }
 
-    public static String getConfigFile() {
+    public String getConfigFile() {
         return ipConfigFile;
     }
 
-    private static void loge(String s) {
+    private void loge(String s) {
         Log.e(TAG, s);
     }
 
-    private static void log(String s) {
+    private void log(String s) {
         Log.d(TAG, s);
     }
 }
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 05b8fe1..bbb74d1 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -202,6 +202,7 @@
     private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
 
     private final StateMachine mStateMachine;
+    private final WifiNative mWifiNative;
 
     /* Supplicant events reported to a state machine */
     private static final int BASE = Protocol.BASE_WIFI_MONITOR;
@@ -266,8 +267,9 @@
      */
     private static final int MAX_RECV_ERRORS    = 10;
 
-    public WifiMonitor(StateMachine wifiStateMachine) {
+    public WifiMonitor(StateMachine wifiStateMachine, WifiNative wifiNative) {
         mStateMachine = wifiStateMachine;
+        mWifiNative = wifiNative;
     }
 
     public void startMonitoring() {
@@ -292,7 +294,7 @@
 
             //noinspection InfiniteLoopStatement
             for (;;) {
-                String eventStr = WifiNative.waitForEvent();
+                String eventStr = mWifiNative.waitForEvent();
 
                 // Skip logging the common but mostly uninteresting scan-results event
                 if (false && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
@@ -406,7 +408,7 @@
             int connectTries = 0;
 
             while (true) {
-                if (WifiNative.connectToSupplicant()) {
+                if (mWifiNative.connectToSupplicant()) {
                     return true;
                 }
                 if (connectTries++ < 5) {
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index f8eafde..48a785c 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -39,11 +39,13 @@
  */
 public class WifiNative {
 
+    private static final int DEFAULT_GROUP_OWNER_INTENT = 7;
+
     static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0;
     static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
     static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2;
 
-    static String sDefaultInterface;
+    String mInterface = "";
 
     public native static boolean loadDriver();
 
@@ -59,60 +61,60 @@
        or when the supplicant is hung */
     public native static boolean killSupplicant();
 
-    public native static boolean connectToSupplicant(String iface);
+    private native boolean connectToSupplicant(String iface);
 
-    public native static void closeSupplicantConnection(String iface);
+    private native void closeSupplicantConnection(String iface);
 
     /**
      * Wait for the supplicant to send an event, returning the event string.
      * @return the event string sent by the supplicant.
      */
-    public native static String waitForEvent(String iface);
+    private native String waitForEvent(String iface);
 
-    private native static boolean doBooleanCommand(String iface, String command);
+    private native boolean doBooleanCommand(String iface, String command);
 
-    private native static int doIntCommand(String iface, String command);
+    private native int doIntCommand(String iface, String command);
 
-    private native static String doStringCommand(String iface, String command);
+    private native String doStringCommand(String iface, String command);
 
-    public static void setDefaultInterface(String iface) {
-        sDefaultInterface = iface;
+    public WifiNative(String iface) {
+        mInterface = iface;
     }
 
-    public static boolean connectToSupplicant() {
-        return connectToSupplicant(sDefaultInterface);
+    public boolean connectToSupplicant() {
+        return connectToSupplicant(mInterface);
     }
 
-    public static void closeSupplicantConnection() {
-        closeSupplicantConnection(sDefaultInterface);
+    public void closeSupplicantConnection() {
+        closeSupplicantConnection(mInterface);
     }
 
-    public static String waitForEvent() {
-        return waitForEvent(sDefaultInterface);
+    public String waitForEvent() {
+        return waitForEvent(mInterface);
     }
 
-    private static boolean doBooleanCommand(String command) {
-        return doBooleanCommand(sDefaultInterface, command);
+    private boolean doBooleanCommand(String command) {
+        return doBooleanCommand(mInterface, command);
     }
 
-    private static int doIntCommand(String command) {
-        return doIntCommand(sDefaultInterface, command);
+    private int doIntCommand(String command) {
+        return doIntCommand(mInterface, command);
     }
 
-    private static String doStringCommand(String command) {
-        return doStringCommand(sDefaultInterface, command);
+    private String doStringCommand(String command) {
+        return doStringCommand(mInterface, command);
     }
 
-    public static boolean ping() {
+    public boolean ping() {
         String pong = doStringCommand("PING");
         return (pong != null && pong.equals("PONG"));
     }
 
-    public static boolean scan() {
+    public boolean scan() {
        return doBooleanCommand("SCAN");
     }
 
-    public static boolean setScanMode(boolean setActive) {
+    public boolean setScanMode(boolean setActive) {
         if (setActive) {
             return doBooleanCommand("DRIVER SCAN-ACTIVE");
         } else {
@@ -126,33 +128,33 @@
      * for a graceful stop and a mild-sounding "stop" interface
      * to kill the process
      */
-    public static boolean stopSupplicant() {
+    public boolean stopSupplicant() {
         return doBooleanCommand("TERMINATE");
     }
 
-    public static String listNetworks() {
+    public String listNetworks() {
         return doStringCommand("LIST_NETWORKS");
     }
 
-    public static int addNetwork() {
+    public int addNetwork() {
         return doIntCommand("ADD_NETWORK");
     }
 
-    public static boolean setNetworkVariable(int netId, String name, String value) {
+    public boolean setNetworkVariable(int netId, String name, String value) {
         if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
         return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
     }
 
-    public static String getNetworkVariable(int netId, String name) {
+    public String getNetworkVariable(int netId, String name) {
         if (TextUtils.isEmpty(name)) return null;
         return doStringCommand("GET_NETWORK " + netId + " " + name);
     }
 
-    public static boolean removeNetwork(int netId) {
+    public boolean removeNetwork(int netId) {
         return doBooleanCommand("REMOVE_NETWORK " + netId);
     }
 
-    public static boolean enableNetwork(int netId, boolean disableOthers) {
+    public boolean enableNetwork(int netId, boolean disableOthers) {
         if (disableOthers) {
             return doBooleanCommand("SELECT_NETWORK " + netId);
         } else {
@@ -160,27 +162,27 @@
         }
     }
 
-    public static boolean disableNetwork(int netId) {
+    public boolean disableNetwork(int netId) {
         return doBooleanCommand("DISABLE_NETWORK " + netId);
     }
 
-    public static boolean reconnect() {
+    public boolean reconnect() {
         return doBooleanCommand("RECONNECT");
     }
 
-    public static boolean reassociate() {
+    public boolean reassociate() {
         return doBooleanCommand("REASSOCIATE");
     }
 
-    public static boolean disconnect() {
+    public boolean disconnect() {
         return doBooleanCommand("DISCONNECT");
     }
 
-    public static String status() {
+    public String status() {
         return doStringCommand("STATUS");
     }
 
-    public static String getMacAddress() {
+    public String getMacAddress() {
         //Macaddr = XX.XX.XX.XX.XX.XX
         String ret = doStringCommand("DRIVER MACADDR");
         if (!TextUtils.isEmpty(ret)) {
@@ -190,15 +192,15 @@
         return null;
     }
 
-    public static String scanResults() {
+    public String scanResults() {
         return doStringCommand("SCAN_RESULTS");
     }
 
-    public static boolean startDriver() {
+    public boolean startDriver() {
         return doBooleanCommand("DRIVER START");
     }
 
-    public static boolean stopDriver() {
+    public boolean stopDriver() {
         return doBooleanCommand("DRIVER STOP");
     }
 
@@ -227,7 +229,7 @@
      *
      * The  SETSUSPENDOPT driver command overrides the filtering rules
      */
-    public static boolean startFilteringMulticastV4Packets() {
+    public boolean startFilteringMulticastV4Packets() {
         return doBooleanCommand("DRIVER RXFILTER-STOP")
             && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
             && doBooleanCommand("DRIVER RXFILTER-START");
@@ -237,7 +239,7 @@
      * Stop filtering out Multicast V4 packets.
      * @return {@code true} if the operation succeeded, {@code false} otherwise
      */
-    public static boolean stopFilteringMulticastV4Packets() {
+    public boolean stopFilteringMulticastV4Packets() {
         return doBooleanCommand("DRIVER RXFILTER-STOP")
             && doBooleanCommand("DRIVER RXFILTER-ADD 2")
             && doBooleanCommand("DRIVER RXFILTER-START");
@@ -247,7 +249,7 @@
      * Start filtering out Multicast V6 packets
      * @return {@code true} if the operation succeeded, {@code false} otherwise
      */
-    public static boolean startFilteringMulticastV6Packets() {
+    public boolean startFilteringMulticastV6Packets() {
         return doBooleanCommand("DRIVER RXFILTER-STOP")
             && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
             && doBooleanCommand("DRIVER RXFILTER-START");
@@ -257,13 +259,13 @@
      * Stop filtering out Multicast V6 packets.
      * @return {@code true} if the operation succeeded, {@code false} otherwise
      */
-    public static boolean stopFilteringMulticastV6Packets() {
+    public boolean stopFilteringMulticastV6Packets() {
         return doBooleanCommand("DRIVER RXFILTER-STOP")
             && doBooleanCommand("DRIVER RXFILTER-ADD 3")
             && doBooleanCommand("DRIVER RXFILTER-START");
     }
 
-    public static int getPowerMode() {
+    public int getPowerMode() {
         String ret = doStringCommand("DRIVER GETPOWER");
         if (!TextUtils.isEmpty(ret)) {
             // reply comes back in the form "powermode = XX" where XX is the
@@ -278,11 +280,11 @@
         return -1;
     }
 
-    public static boolean setPowerMode(int mode) {
+    public boolean setPowerMode(int mode) {
         return doBooleanCommand("DRIVER POWERMODE " + mode);
     }
 
-    public static int getBand() {
+    public int getBand() {
        String ret = doStringCommand("DRIVER GETBAND");
         if (!TextUtils.isEmpty(ret)) {
             //reply is "BAND X" where X is the band
@@ -296,7 +298,7 @@
         return -1;
     }
 
-    public static boolean setBand(int band) {
+    public boolean setBand(int band) {
         return doBooleanCommand("DRIVER SETBAND " + band);
     }
 
@@ -308,7 +310,7 @@
      *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
      * @return Whether the mode was successfully set.
      */
-    public static boolean setBluetoothCoexistenceMode(int mode) {
+    public boolean setBluetoothCoexistenceMode(int mode) {
         return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
     }
 
@@ -320,7 +322,7 @@
      * @param isSet whether to enable or disable this mode
      * @return {@code true} if the command succeeded, {@code false} otherwise.
      */
-    public static boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
+    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
         if (setCoexScanMode) {
             return doBooleanCommand("DRIVER BTCOEXSCAN-START");
         } else {
@@ -328,25 +330,25 @@
         }
     }
 
-    public static boolean saveConfig() {
+    public boolean saveConfig() {
         // Make sure we never write out a value for AP_SCAN other than 1
         return doBooleanCommand("AP_SCAN 1") && doBooleanCommand("SAVE_CONFIG");
     }
 
-    public static boolean setScanResultHandling(int mode) {
+    public boolean setScanResultHandling(int mode) {
         return doBooleanCommand("AP_SCAN " + mode);
     }
 
-    public static boolean addToBlacklist(String bssid) {
+    public boolean addToBlacklist(String bssid) {
         if (TextUtils.isEmpty(bssid)) return false;
         return doBooleanCommand("BLACKLIST " + bssid);
     }
 
-    public static boolean clearBlacklist() {
+    public boolean clearBlacklist() {
         return doBooleanCommand("BLACKLIST clear");
     }
 
-    public static boolean setSuspendOptimizations(boolean enabled) {
+    public boolean setSuspendOptimizations(boolean enabled) {
         if (enabled) {
             return doBooleanCommand("DRIVER SETSUSPENDOPT 0");
         } else {
@@ -354,11 +356,11 @@
         }
     }
 
-    public static boolean setCountryCode(String countryCode) {
+    public boolean setCountryCode(String countryCode) {
         return doBooleanCommand("DRIVER COUNTRY " + countryCode);
     }
 
-    public static void enableBackgroundScan(boolean enable) {
+    public void enableBackgroundScan(boolean 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) {
@@ -368,7 +370,7 @@
         }
     }
 
-    public static void setScanInterval(int scanInterval) {
+    public void setScanInterval(int scanInterval) {
         doBooleanCommand("SCAN_INTERVAL " + scanInterval);
     }
 
@@ -378,81 +380,81 @@
      * NOISE=9999
      * FREQUENCY=0
      */
-    public static String signalPoll() {
+    public String signalPoll() {
         return doStringCommand("SIGNAL_POLL");
     }
 
-    public static boolean startWpsPbc() {
+    public boolean startWpsPbc() {
         return doBooleanCommand("WPS_PBC");
     }
 
-    public static boolean startWpsPbc(String bssid) {
+    public boolean startWpsPbc(String bssid) {
         return doBooleanCommand("WPS_PBC " + bssid);
     }
 
-    public static boolean startWpsPinKeypad(String pin) {
+    public boolean startWpsPinKeypad(String pin) {
         return doBooleanCommand("WPS_PIN any " + pin);
     }
 
-    public static String startWpsPinDisplay(String bssid) {
+    public String startWpsPinDisplay(String bssid) {
         return doStringCommand("WPS_PIN " + bssid);
     }
 
     /* Configures an access point connection */
-    public static boolean startWpsRegistrar(String bssid, String pin) {
+    public boolean startWpsRegistrar(String bssid, String pin) {
         return doBooleanCommand("WPS_REG " + bssid + " " + pin);
     }
 
-    public static boolean setPersistentReconnect(boolean enabled) {
+    public boolean setPersistentReconnect(boolean enabled) {
         int value = (enabled == true) ? 1 : 0;
         return doBooleanCommand("SET persistent_reconnect " + value);
     }
 
-    public static boolean setDeviceName(String name) {
+    public boolean setDeviceName(String name) {
         return doBooleanCommand("SET device_name " + name);
     }
 
-    public static boolean setDeviceType(String type) {
+    public boolean setDeviceType(String type) {
         return doBooleanCommand("SET device_type " + type);
     }
 
-    public static boolean setConfigMethods(String cfg) {
+    public boolean setConfigMethods(String cfg) {
         return doBooleanCommand("SET config_methods " + cfg);
     }
 
-    public static boolean setP2pSsidPostfix(String postfix) {
+    public boolean setP2pSsidPostfix(String postfix) {
         return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
     }
 
-    public static boolean p2pFind() {
+    public boolean p2pFind() {
         return doBooleanCommand("P2P_FIND");
     }
 
-    public static boolean p2pFind(int timeout) {
+    public boolean p2pFind(int timeout) {
         if (timeout <= 0) {
             return p2pFind();
         }
         return doBooleanCommand("P2P_FIND " + timeout);
     }
 
-    public static boolean p2pListen() {
+    public boolean p2pListen() {
         return doBooleanCommand("P2P_LISTEN");
     }
 
-    public static boolean p2pListen(int timeout) {
+    public boolean p2pListen(int timeout) {
         if (timeout <= 0) {
             return p2pListen();
         }
         return doBooleanCommand("P2P_LISTEN " + timeout);
     }
 
-    public static boolean p2pFlush() {
+    public boolean p2pFlush() {
         return doBooleanCommand("P2P_FLUSH");
     }
 
     /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
         [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
-    public static String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
+    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
         if (config == null) return null;
         List<String> args = new ArrayList<String>();
         WpsInfo wps = config.wps;
@@ -492,7 +494,7 @@
         //device battery state
         int groupOwnerIntent = config.groupOwnerIntent;
         if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
-            groupOwnerIntent = 7; //default value
+            groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
         }
         args.add("go_intent=" + groupOwnerIntent);
 
@@ -502,11 +504,11 @@
         return doStringCommand(command);
     }
 
-    public static boolean p2pCancelConnect() {
+    public boolean p2pCancelConnect() {
         return doBooleanCommand("P2P_CANCEL");
     }
 
-    public static boolean p2pProvisionDiscovery(WifiP2pConfig config) {
+    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
         if (config == null) return false;
 
         switch (config.wps.setup) {
@@ -524,21 +526,21 @@
         return false;
     }
 
-    public static boolean p2pGroupAdd() {
+    public boolean p2pGroupAdd() {
         return doBooleanCommand("P2P_GROUP_ADD");
     }
 
-    public static boolean p2pGroupRemove(String iface) {
+    public boolean p2pGroupRemove(String iface) {
         if (iface == null) return false;
         return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
     }
 
-    public static boolean p2pReject(String deviceAddress) {
+    public boolean p2pReject(String deviceAddress) {
         return doBooleanCommand("P2P_REJECT " + deviceAddress);
     }
 
     /* Invite a peer to a group */
-    public static boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
+    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
         if (deviceAddress == null) return false;
 
         if (group == null) {
@@ -550,14 +552,14 @@
     }
 
     /* Reinvoke a persistent connection */
-    public static boolean p2pReinvoke(int netId, String deviceAddress) {
+    public boolean p2pReinvoke(int netId, String deviceAddress) {
         if (deviceAddress == null || netId < 0) return false;
 
         return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
     }
 
 
-    public static String p2pGetInterfaceAddress(String deviceAddress) {
+    public String p2pGetInterfaceAddress(String deviceAddress) {
         if (deviceAddress == null) return null;
 
         //  "p2p_peer deviceAddress" returns a multi-line result containing
@@ -577,7 +579,7 @@
         return null;
     }
 
-    public static String p2pGetDeviceAddress() {
+    public String p2pGetDeviceAddress() {
         String status = status();
         if (status == null) return "";
 
@@ -592,7 +594,7 @@
         return "";
     }
 
-    public static String p2pPeer(String deviceAddress) {
+    public String p2pPeer(String deviceAddress) {
         return doStringCommand("P2P_PEER " + deviceAddress);
     }
 }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 58e19cf..8c9e472 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -113,6 +113,8 @@
     private static final String SOFTAP_IFACE = "wl0.1";
 
     private WifiMonitor mWifiMonitor;
+    private WifiNative mWifiNative;
+    private WifiConfigStore mWifiConfigStore;
     private INetworkManagementService mNwService;
     private ConnectivityManager mCm;
 
@@ -554,11 +556,14 @@
         IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
         mNwService = INetworkManagementService.Stub.asInterface(b);
 
-        mWifiMonitor = new WifiMonitor(this);
+        mWifiNative = new WifiNative(mInterfaceName);
+        mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
+        mWifiMonitor = new WifiMonitor(this, mWifiNative);
         mDhcpInfoInternal = new DhcpInfoInternal();
         mWifiInfo = new WifiInfo();
-        mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
-        mWpsStateMachine = new WpsStateMachine(context, this, getHandler());
+        mSupplicantStateTracker = new SupplicantStateTracker(context, this, mWifiConfigStore,
+                getHandler());
+        mWpsStateMachine = new WpsStateMachine(context, this, mWifiConfigStore, getHandler());
         mLinkProperties = new LinkProperties();
 
         WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
@@ -572,9 +577,6 @@
         mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
         mLastSignalLevel = -1;
 
-        /* Set default interface for all primary socket communication */
-        WifiNative.setDefaultInterface(mInterfaceName);
-
         mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
         Intent scanIntent = new Intent(ACTION_START_SCAN, null);
         mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
@@ -1044,7 +1046,7 @@
      * Returns the wifi configuration file
      */
     public String getConfigFile() {
-        return WifiConfigStore.getConfigFile();
+        return mWifiConfigStore.getConfigFile();
     }
 
     /**
@@ -1118,9 +1120,9 @@
         sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
         sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
         sb.append("Supplicant status").append(LS)
-                .append(WifiNative.status()).append(LS).append(LS);
+                .append(mWifiNative.status()).append(LS).append(LS);
 
-        sb.append(WifiConfigStore.dump());
+        sb.append(mWifiConfigStore.dump());
         return sb.toString();
     }
 
@@ -1413,7 +1415,7 @@
     }
 
     private String fetchSSID() {
-        String status = WifiNative.status();
+        String status = mWifiNative.status();
         if (status == null) {
             return null;
         }
@@ -1436,7 +1438,7 @@
         int newRssi = -1;
         int newLinkSpeed = -1;
 
-        String signalPoll = WifiNative.signalPoll();
+        String signalPoll = mWifiNative.signalPoll();
 
         if (signalPoll != null) {
             String[] lines = signalPoll.split("\n");
@@ -1486,28 +1488,28 @@
     }
 
     private void setHighPerfModeEnabledNative(boolean enable) {
-        if(!WifiNative.setSuspendOptimizations(!enable)) {
+        if(!mWifiNative.setSuspendOptimizations(!enable)) {
             loge("set suspend optimizations failed!");
         }
         if (enable) {
-            if (!WifiNative.setPowerMode(POWER_MODE_ACTIVE)) {
+            if (!mWifiNative.setPowerMode(POWER_MODE_ACTIVE)) {
                 loge("set power mode active failed!");
             }
         } else {
-            if (!WifiNative.setPowerMode(POWER_MODE_AUTO)) {
+            if (!mWifiNative.setPowerMode(POWER_MODE_AUTO)) {
                 loge("set power mode auto failed!");
             }
         }
     }
 
     private void configureLinkProperties() {
-        if (WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
-            mLinkProperties = WifiConfigStore.getLinkProperties(mLastNetworkId);
+        if (mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+            mLinkProperties = mWifiConfigStore.getLinkProperties(mLastNetworkId);
         } else {
             synchronized (mDhcpInfoInternal) {
                 mLinkProperties = mDhcpInfoInternal.makeLinkProperties();
             }
-            mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
+            mLinkProperties.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
         }
         mLinkProperties.setInterfaceName(mInterfaceName);
         if (DBG) {
@@ -1648,7 +1650,7 @@
         mWifiInfo.setLinkSpeed(-1);
 
         setNetworkDetailedState(DetailedState.DISCONNECTED);
-        WifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
+        mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
 
         /* send event to CM & network change broadcast */
         sendNetworkStateChangeBroadcast(mLastBssid);
@@ -1656,8 +1658,8 @@
         /* Clear network properties */
         mLinkProperties.clear();
         /* Clear IP settings if the network used DHCP */
-        if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
-            WifiConfigStore.clearIpConfiguration(mLastNetworkId);
+        if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+            mWifiConfigStore.clearIpConfiguration(mLastNetworkId);
         }
 
         mLastBssid= null;
@@ -1683,29 +1685,29 @@
              * coexistence would interrupt that connection.
              */
             // Disable the coexistence mode
-            WifiNative.setBluetoothCoexistenceMode(
-                    WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
+            mWifiNative.setBluetoothCoexistenceMode(
+                    mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
         }
 
-        mPowerMode =  WifiNative.getPowerMode();
+        mPowerMode =  mWifiNative.getPowerMode();
         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.setPowerMode(WifiStateMachine.POWER_MODE_ACTIVE);
+            mWifiNative.setPowerMode(WifiStateMachine.POWER_MODE_ACTIVE);
         }
     }
 
 
     void handlePostDhcpSetup() {
         /* restore power mode */
-        WifiNative.setPowerMode(mPowerMode);
+        mWifiNative.setPowerMode(mPowerMode);
 
         // Set the coexistence mode back to its default value
-        WifiNative.setBluetoothCoexistenceMode(
-                WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
+        mWifiNative.setBluetoothCoexistenceMode(
+                mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
     }
 
     private void handleSuccessfulIpConfiguration(DhcpInfoInternal dhcpInfoInternal) {
@@ -1714,13 +1716,13 @@
         }
         mLastSignalLevel = -1; // force update of signal strength
         mReconnectCount = 0; //Reset IP failure tracking
-        WifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
+        mWifiConfigStore.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.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
             linkProperties.setInterfaceName(mInterfaceName);
             if (!linkProperties.equals(mLinkProperties)) {
                 if (DBG) {
@@ -1733,7 +1735,7 @@
         } else {
             configureLinkProperties();
             setNetworkDetailedState(DetailedState.CONNECTED);
-            WifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CONNECTED);
+            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CONNECTED);
             sendNetworkStateChangeBroadcast(mLastBssid);
         }
     }
@@ -1749,7 +1751,7 @@
         if (++mReconnectCount > getMaxDhcpRetries()) {
             loge("Failed " +
                     mReconnectCount + " times, Disabling " + mLastNetworkId);
-            WifiConfigStore.disableNetwork(mLastNetworkId,
+            mWifiConfigStore.disableNetwork(mLastNetworkId,
                     WifiConfiguration.DISABLED_DHCP_FAILURE);
             mReconnectCount = 0;
         }
@@ -1757,8 +1759,8 @@
         /* DHCP times out after about 30 seconds, we do a
          * disconnect and an immediate reconnect to try again
          */
-        WifiNative.disconnect();
-        WifiNative.reconnect();
+        mWifiNative.disconnect();
+        mWifiNative.reconnect();
     }
 
     /* Current design is to not set the config on a running hostapd but instead
@@ -1826,7 +1828,7 @@
                     break;
                 case CMD_GET_CONFIGURED_NETWORKS:
                     mReplyChannel.replyToMessage(message, message.what,
-                            WifiConfigStore.getConfiguredNetworks());
+                            mWifiConfigStore.getConfiguredNetworks());
                     break;
                 case CMD_ENABLE_RSSI_POLL:
                     mEnableRssiPolling = (message.arg1 == 1);
@@ -1913,7 +1915,7 @@
             // 50021 wifi_state_changed (custom|1|5)
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
-            if (WifiNative.isDriverLoaded()) {
+            if (mWifiNative.isDriverLoaded()) {
                 transitionTo(mDriverLoadedState);
             }
             else {
@@ -1966,7 +1968,7 @@
                             break;
                     }
 
-                    if(WifiNative.loadDriver()) {
+                    if(mWifiNative.loadDriver()) {
                         if (DBG) log("Driver load successful");
                         sendMessage(CMD_LOAD_DRIVER_SUCCESS);
                     } else {
@@ -2054,7 +2056,7 @@
                         loge("Unable to change interface settings: " + ie);
                     }
 
-                    if(WifiNative.startSupplicant()) {
+                    if(mWifiNative.startSupplicant()) {
                         if (DBG) log("Supplicant start successful");
                         mWifiMonitor.startMonitoring();
                         transitionTo(mSupplicantStartingState);
@@ -2086,7 +2088,7 @@
                 public void run() {
                     if (DBG) log(getName() + message.toString() + "\n");
                     mWakeLock.acquire();
-                    if(WifiNative.unloadDriver()) {
+                    if(mWifiNative.unloadDriver()) {
                         if (DBG) log("Driver unload successful");
                         sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
 
@@ -2217,9 +2219,9 @@
                     mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
                     mLastSignalLevel = -1;
 
-                    mWifiInfo.setMacAddress(WifiNative.getMacAddress());
+                    mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
 
-                    WifiConfigStore.initialize(mContext);
+                    mWifiConfigStore.initialize();
 
                     sendSupplicantConnectionChangedBroadcast(true);
                     transitionTo(mDriverStartedState);
@@ -2227,7 +2229,7 @@
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
                     if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
                         loge("Failed to setup control channel, restart supplicant");
-                        WifiNative.killSupplicant();
+                        mWifiNative.killSupplicant();
                         transitionTo(mDriverLoadedState);
                         sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
                     } else {
@@ -2276,7 +2278,7 @@
             long supplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
                     Settings.Secure.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
                     mDefaultSupplicantScanIntervalMs);
-            WifiNative.setScanInterval((int)supplicantScanIntervalMs / 1000);
+            mWifiNative.setScanInterval((int)supplicantScanIntervalMs / 1000);
         }
         @Override
         public boolean processMessage(Message message) {
@@ -2289,8 +2291,8 @@
                     break;
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
                     loge("Connection lost, restart supplicant");
-                    WifiNative.killSupplicant();
-                    WifiNative.closeSupplicantConnection();
+                    mWifiNative.killSupplicant();
+                    mWifiNative.closeSupplicantConnection();
                     mNetworkInfo.setIsAvailable(false);
                     handleNetworkDisconnect();
                     sendSupplicantConnectionChangedBroadcast(false);
@@ -2301,46 +2303,46 @@
                     break;
                 case WifiMonitor.SCAN_RESULTS_EVENT:
                     eventLoggingEnabled = false;
-                    setScanResults(WifiNative.scanResults());
+                    setScanResults(mWifiNative.scanResults());
                     sendScanResultsAvailableBroadcast();
                     mScanResultIsPending = false;
                     break;
                 case CMD_PING_SUPPLICANT:
-                    boolean ok = WifiNative.ping();
+                    boolean ok = mWifiNative.ping();
                     mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
                     break;
                 case CMD_ADD_OR_UPDATE_NETWORK:
                     config = (WifiConfiguration) message.obj;
                     mReplyChannel.replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
-                            WifiConfigStore.addOrUpdateNetwork(config));
+                            mWifiConfigStore.addOrUpdateNetwork(config));
                     break;
                 case CMD_REMOVE_NETWORK:
-                    ok = WifiConfigStore.removeNetwork(message.arg1);
+                    ok = mWifiConfigStore.removeNetwork(message.arg1);
                     mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
                     break;
                 case CMD_ENABLE_NETWORK:
-                    ok = WifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
+                    ok = mWifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
                     mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
                     break;
                 case CMD_ENABLE_ALL_NETWORKS:
                     long time =  android.os.SystemClock.elapsedRealtime();
                     if (time - mLastEnableAllNetworksTime > MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS) {
-                        WifiConfigStore.enableAllNetworks();
+                        mWifiConfigStore.enableAllNetworks();
                         mLastEnableAllNetworksTime = time;
                     }
                     break;
                 case CMD_DISABLE_NETWORK:
-                    ok = WifiConfigStore.disableNetwork(message.arg1, message.arg2);
+                    ok = mWifiConfigStore.disableNetwork(message.arg1, message.arg2);
                     mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
                     break;
                 case CMD_BLACKLIST_NETWORK:
-                    WifiNative.addToBlacklist((String)message.obj);
+                    mWifiNative.addToBlacklist((String)message.obj);
                     break;
                 case CMD_CLEAR_BLACKLIST:
-                    WifiNative.clearBlacklist();
+                    mWifiNative.clearBlacklist();
                     break;
                 case CMD_SAVE_CONFIG:
-                    ok = WifiConfigStore.saveConfig();
+                    ok = mWifiConfigStore.saveConfig();
                     mReplyChannel.replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
 
                     // Inform the backup manager about a data change
@@ -2364,10 +2366,10 @@
                     break;
                 case CMD_SAVE_NETWORK:
                     config = (WifiConfiguration) message.obj;
-                    WifiConfigStore.saveNetwork(config);
+                    mWifiConfigStore.saveNetwork(config);
                     break;
                 case CMD_FORGET_NETWORK:
-                    WifiConfigStore.forgetNetwork(message.arg1);
+                    mWifiConfigStore.forgetNetwork(message.arg1);
                     break;
                 default:
                     return NOT_HANDLED;
@@ -2390,7 +2392,7 @@
             if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
             if (DBG) log("stopping supplicant");
-            if (!WifiNative.stopSupplicant()) {
+            if (!mWifiNative.stopSupplicant()) {
                 loge("Failed to stop supplicant");
             }
 
@@ -2417,15 +2419,15 @@
                     /* Socket connection can be lost when we do a graceful shutdown
                      * or when the driver is hung. Ensure supplicant is stopped here.
                      */
-                    WifiNative.killSupplicant();
-                    WifiNative.closeSupplicantConnection();
+                    mWifiNative.killSupplicant();
+                    mWifiNative.closeSupplicantConnection();
                     transitionTo(mDriverLoadedState);
                     break;
                 case CMD_STOP_SUPPLICANT_FAILED:
                     if (message.arg1 == mSupplicantStopFailureToken) {
                         loge("Timed out on a supplicant stop, kill and proceed");
-                        WifiNative.killSupplicant();
-                        WifiNative.closeSupplicantConnection();
+                        mWifiNative.killSupplicant();
+                        mWifiNative.closeSupplicantConnection();
                         transitionTo(mDriverLoadedState);
                     }
                     break;
@@ -2516,7 +2518,7 @@
              * When this mode is on, some of the low-level scan parameters used by the
              * driver are changed to reduce interference with bluetooth
              */
-            WifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
+            mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
             /* set country code */
             setCountryCode();
             /* set frequency band of operation */
@@ -2525,26 +2527,26 @@
             setNetworkDetailedState(DetailedState.DISCONNECTED);
 
             /* Remove any filtering on Multicast v6 at start */
-            WifiNative.stopFilteringMulticastV6Packets();
+            mWifiNative.stopFilteringMulticastV6Packets();
 
             /* Reset Multicast v4 filtering state */
             if (mFilteringMulticastV4Packets.get()) {
-                WifiNative.startFilteringMulticastV4Packets();
+                mWifiNative.startFilteringMulticastV4Packets();
             } else {
-                WifiNative.stopFilteringMulticastV4Packets();
+                mWifiNative.stopFilteringMulticastV4Packets();
             }
 
             if (mIsScanMode) {
-                WifiNative.setScanResultHandling(SCAN_ONLY_MODE);
-                WifiNative.disconnect();
+                mWifiNative.setScanResultHandling(SCAN_ONLY_MODE);
+                mWifiNative.disconnect();
                 transitionTo(mScanModeState);
             } else {
-                WifiNative.setScanResultHandling(CONNECT_MODE);
-                WifiNative.reconnect();
+                mWifiNative.setScanResultHandling(CONNECT_MODE);
+                mWifiNative.reconnect();
                 // Status pulls in the current supplicant state and network connection state
                 // events over the monitor connection. This helps framework sync up with
                 // current supplicant state
-                WifiNative.status();
+                mWifiNative.status();
                 transitionTo(mDisconnectedState);
             }
         }
@@ -2555,17 +2557,17 @@
             switch(message.what) {
                 case CMD_SET_SCAN_TYPE:
                     mSetScanActive = (message.arg1 == SCAN_ACTIVE);
-                    WifiNative.setScanMode(mSetScanActive);
+                    mWifiNative.setScanMode(mSetScanActive);
                     break;
                 case CMD_START_SCAN:
                     eventLoggingEnabled = false;
                     boolean forceActive = (message.arg1 == SCAN_ACTIVE);
                     if (forceActive && !mSetScanActive) {
-                        WifiNative.setScanMode(forceActive);
+                        mWifiNative.setScanMode(forceActive);
                     }
-                    WifiNative.scan();
+                    mWifiNative.scan();
                     if (forceActive && !mSetScanActive) {
-                        WifiNative.setScanMode(mSetScanActive);
+                        mWifiNative.setScanMode(mSetScanActive);
                     }
                     mScanResultIsPending = true;
                     break;
@@ -2575,14 +2577,14 @@
                 case CMD_SET_COUNTRY_CODE:
                     String country = (String) message.obj;
                     if (DBG) log("set country code " + country);
-                    if (!WifiNative.setCountryCode(country.toUpperCase())) {
+                    if (!mWifiNative.setCountryCode(country.toUpperCase())) {
                         loge("Failed to set country code " + country);
                     }
                     break;
                 case CMD_SET_FREQUENCY_BAND:
                     int band =  message.arg1;
                     if (DBG) log("set frequency band " + band);
-                    if (WifiNative.setBand(band)) {
+                    if (mWifiNative.setBand(band)) {
                         mFrequencyBand.set(band);
                         //Fetch the latest scan results when frequency band is set
                         startScan(true);
@@ -2593,7 +2595,7 @@
                 case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
                     mBluetoothConnectionActive = (message.arg1 !=
                             BluetoothAdapter.STATE_DISCONNECTED);
-                    WifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
+                    mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
                     break;
                 case CMD_STOP_DRIVER:
                     int mode = message.arg1;
@@ -2626,28 +2628,28 @@
                 case CMD_DELAYED_STOP_DRIVER:
                     if (message.arg1 != mDelayedStopCounter) break;
                     if (getCurrentState() != mDisconnectedState) {
-                        WifiNative.disconnect();
+                        mWifiNative.disconnect();
                         handleNetworkDisconnect();
                     }
                     mWakeLock.acquire();
-                    WifiNative.stopDriver();
+                    mWifiNative.stopDriver();
                     transitionTo(mDriverStoppingState);
                     mWakeLock.release();
                     break;
                 case CMD_START_PACKET_FILTERING:
                     if (message.arg1 == MULTICAST_V6) {
-                        WifiNative.startFilteringMulticastV6Packets();
+                        mWifiNative.startFilteringMulticastV6Packets();
                     } else if (message.arg1 == MULTICAST_V4) {
-                        WifiNative.startFilteringMulticastV4Packets();
+                        mWifiNative.startFilteringMulticastV4Packets();
                     } else {
                         loge("Illegal arugments to CMD_START_PACKET_FILTERING");
                     }
                     break;
                 case CMD_STOP_PACKET_FILTERING:
                     if (message.arg1 == MULTICAST_V6) {
-                        WifiNative.stopFilteringMulticastV6Packets();
+                        mWifiNative.stopFilteringMulticastV6Packets();
                     } else if (message.arg1 == MULTICAST_V4) {
-                        WifiNative.stopFilteringMulticastV4Packets();
+                        mWifiNative.stopFilteringMulticastV4Packets();
                     } else {
                         loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
                     }
@@ -2729,7 +2731,7 @@
                     break;
                 case CMD_START_DRIVER:
                     mWakeLock.acquire();
-                    WifiNative.startDriver();
+                    mWifiNative.startDriver();
                     mWakeLock.release();
                     transitionTo(mDriverStartingState);
                     break;
@@ -2756,8 +2758,8 @@
                         /* Ignore */
                         return HANDLED;
                     } else {
-                        WifiNative.setScanResultHandling(message.arg1);
-                        WifiNative.reconnect();
+                        mWifiNative.setScanResultHandling(message.arg1);
+                        mWifiNative.reconnect();
                         mIsScanMode = false;
                         transitionTo(mDisconnectedState);
                     }
@@ -2824,13 +2826,13 @@
                     break;
                     /* Do a redundant disconnect without transition */
                 case CMD_DISCONNECT:
-                    WifiNative.disconnect();
+                    mWifiNative.disconnect();
                     break;
                 case CMD_RECONNECT:
-                    WifiNative.reconnect();
+                    mWifiNative.reconnect();
                     break;
                 case CMD_REASSOCIATE:
-                    WifiNative.reassociate();
+                    mWifiNative.reassociate();
                     break;
                 case CMD_CONNECT_NETWORK:
                     int netId = message.arg1;
@@ -2844,15 +2846,15 @@
                      * a connection to the enabled network.
                      */
                     if (config != null) {
-                        netId = WifiConfigStore.selectNetwork(config);
+                        netId = mWifiConfigStore.selectNetwork(config);
                     } else {
-                        WifiConfigStore.selectNetwork(netId);
+                        mWifiConfigStore.selectNetwork(netId);
                     }
 
                     /* The state tracker handles enabling networks upon completion/failure */
                     mSupplicantStateTracker.sendMessage(CMD_CONNECT_NETWORK);
 
-                    WifiNative.reconnect();
+                    mWifiNative.reconnect();
                     /* Expect a disconnection from the old connection */
                     transitionTo(mDisconnectingState);
                     break;
@@ -2862,7 +2864,7 @@
                     break;
                 case WifiMonitor.SCAN_RESULTS_EVENT:
                     /* Set the scan setting back to "connect" mode */
-                    WifiNative.setScanResultHandling(CONNECT_MODE);
+                    mWifiNative.setScanResultHandling(CONNECT_MODE);
                     /* Handle scan results */
                     return NOT_HANDLED;
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
@@ -2907,14 +2909,14 @@
                 loge("Failed to enable IPv6: " + e);
             }
 
-            if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+            if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
                 //start DHCP
                 mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
                         mContext, WifiStateMachine.this, mInterfaceName);
                 mDhcpStateMachine.registerForPreDhcpNotification();
                 mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
             } else {
-                DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration(
+                DhcpInfoInternal dhcpInfoInternal = mWifiConfigStore.getIpConfiguration(
                         mLastNetworkId);
                 InterfaceConfiguration ifcg = new InterfaceConfiguration();
                 ifcg.setLinkAddress(dhcpInfoInternal.makeLinkAddress());
@@ -2960,7 +2962,7 @@
                   transitionTo(mDisconnectingState);
                   break;
               case CMD_DISCONNECT:
-                  WifiNative.disconnect();
+                  mWifiNative.disconnect();
                   transitionTo(mDisconnectingState);
                   break;
                   /* Ignore connection to same network */
@@ -3027,7 +3029,7 @@
                   }
                   break;
                 case CMD_DISCONNECT:
-                    WifiNative.disconnect();
+                    mWifiNative.disconnect();
                     transitionTo(mDisconnectingState);
                     break;
                 case CMD_SET_SCAN_MODE:
@@ -3043,7 +3045,7 @@
                      * When scan results are received, the mode is switched
                      * back to CONNECT_MODE.
                      */
-                    WifiNative.setScanResultHandling(SCAN_ONLY_MODE);
+                    mWifiNative.setScanResultHandling(SCAN_ONLY_MODE);
                     /* Have the parent state handle the rest */
                     return NOT_HANDLED;
                     /* Ignore connection to same network */
@@ -3055,7 +3057,7 @@
                     return NOT_HANDLED;
                 case CMD_SAVE_NETWORK:
                     WifiConfiguration config = (WifiConfiguration) message.obj;
-                    NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
+                    NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
                     if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
                         if (result.hasIpChanged()) {
                             log("Reconfiguring IP on connection");
@@ -3111,7 +3113,7 @@
              * is in SCAN_ONLY_MODE. Restore CONNECT_MODE on exit
              */
             if (mScanResultIsPending) {
-                WifiNative.setScanResultHandling(CONNECT_MODE);
+                mWifiNative.setScanResultHandling(CONNECT_MODE);
             }
         }
     }
@@ -3192,7 +3194,7 @@
                  * cleared
                  */
                 if (!mScanResultIsPending) {
-                    WifiNative.enableBackgroundScan(true);
+                    mWifiNative.enableBackgroundScan(true);
                 }
             } else {
                 setScanAlarm(true);
@@ -3204,9 +3206,9 @@
             switch (message.what) {
                 case CMD_SET_SCAN_MODE:
                     if (message.arg1 == SCAN_ONLY_MODE) {
-                        WifiNative.setScanResultHandling(message.arg1);
+                        mWifiNative.setScanResultHandling(message.arg1);
                         //Supplicant disconnect to prevent further connects
-                        WifiNative.disconnect();
+                        mWifiNative.disconnect();
                         mIsScanMode = true;
                         transitionTo(mScanModeState);
                     }
@@ -3214,10 +3216,10 @@
                 case CMD_ENABLE_BACKGROUND_SCAN:
                     mEnableBackgroundScan = (message.arg1 == 1);
                     if (mEnableBackgroundScan) {
-                        WifiNative.enableBackgroundScan(true);
+                        mWifiNative.enableBackgroundScan(true);
                         setScanAlarm(false);
                     } else {
-                        WifiNative.enableBackgroundScan(false);
+                        mWifiNative.enableBackgroundScan(false);
                         setScanAlarm(true);
                     }
                     break;
@@ -3232,14 +3234,14 @@
                 case CMD_START_SCAN:
                     /* Disable background scan temporarily during a regular scan */
                     if (mEnableBackgroundScan) {
-                        WifiNative.enableBackgroundScan(false);
+                        mWifiNative.enableBackgroundScan(false);
                     }
                     /* Handled in parent state */
                     return NOT_HANDLED;
                 case WifiMonitor.SCAN_RESULTS_EVENT:
                     /* Re-enable background scan when a pending scan result is received */
                     if (mEnableBackgroundScan && mScanResultIsPending) {
-                        WifiNative.enableBackgroundScan(true);
+                        mWifiNative.enableBackgroundScan(true);
                     }
                     /* Handled in parent state */
                     return NOT_HANDLED;
@@ -3254,7 +3256,7 @@
         public void exit() {
             /* No need for a background scan upon exit from a disconnected state */
             if (mEnableBackgroundScan) {
-                WifiNative.enableBackgroundScan(false);
+                mWifiNative.enableBackgroundScan(false);
             }
             setScanAlarm(false);
         }
diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java
index c14a8db..441a3b0 100644
--- a/wifi/java/android/net/wifi/WpsStateMachine.java
+++ b/wifi/java/android/net/wifi/WpsStateMachine.java
@@ -52,6 +52,7 @@
     private static final boolean DBG = false;
 
     private WifiStateMachine mWifiStateMachine;
+    private WifiConfigStore mWifiConfigStore;
 
     private WpsInfo mWpsInfo;
 
@@ -62,11 +63,12 @@
     private State mInactiveState = new InactiveState();
     private State mActiveState = new ActiveState();
 
-    public WpsStateMachine(Context context, WifiStateMachine wsm, Handler target) {
-        super(TAG, target.getLooper());
+    public WpsStateMachine(Context context, WifiStateMachine wsm, WifiConfigStore wcs, Handler t) {
+        super(TAG, t.getLooper());
 
         mContext = context;
         mWifiStateMachine = wsm;
+        mWifiConfigStore = wcs;
         addState(mDefaultState);
             addState(mInactiveState, mDefaultState);
             addState(mActiveState, mDefaultState);
@@ -97,13 +99,13 @@
                     WpsResult result;
                     switch (mWpsInfo.setup) {
                         case WpsInfo.PBC:
-                            result = WifiConfigStore.startWpsPbc(mWpsInfo);
+                            result = mWifiConfigStore.startWpsPbc(mWpsInfo);
                             break;
                         case WpsInfo.KEYPAD:
-                            result = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsInfo);
+                            result = mWifiConfigStore.startWpsWithPinFromAccessPoint(mWpsInfo);
                             break;
                         case WpsInfo.DISPLAY:
-                            result = WifiConfigStore.startWpsWithPinFromDevice(mWpsInfo);
+                            result = mWifiConfigStore.startWpsWithPinFromDevice(mWpsInfo);
                             break;
                         default:
                             result = new WpsResult(Status.FAILURE);
@@ -151,9 +153,9 @@
                              * and the configuration list needs to be reloaded from the supplicant.
                              */
                             Log.d(TAG, "WPS set up successful");
-                            WifiConfigStore.enableAllNetworks();
-                            WifiConfigStore.loadConfiguredNetworks();
-                            WifiConfigStore.updateIpAndProxyFromWpsConfig(
+                            mWifiConfigStore.enableAllNetworks();
+                            mWifiConfigStore.loadConfiguredNetworks();
+                            mWifiConfigStore.updateIpAndProxyFromWpsConfig(
                                     stateChangeResult.networkId, mWpsInfo);
                             mWifiStateMachine.sendMessage(WifiStateMachine.WPS_COMPLETED_EVENT);
                             transitionTo(mInactiveState);
@@ -161,7 +163,7 @@
                         case INACTIVE:
                             /* A failed WPS connection */
                             Log.d(TAG, "WPS set up failed, enabling other networks");
-                            WifiConfigStore.enableAllNetworks();
+                            mWifiConfigStore.enableAllNetworks();
                             mWifiStateMachine.sendMessage(WifiStateMachine.WPS_COMPLETED_EVENT);
                             transitionTo(mInactiveState);
                             break;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 1ad6336..69cbb5c 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -166,7 +166,8 @@
     public WifiP2pService(Context context) {
         mContext = context;
 
-        mInterface = SystemProperties.get("wifi.interface", "wlan0");
+        //STOPSHIP: fix this
+        mInterface = "p2p0";
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
 
         mP2pSupported = mContext.getPackageManager().hasSystemFeature(
@@ -278,7 +279,8 @@
         private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
         private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
 
-        private WifiMonitor mWifiMonitor = new WifiMonitor(this);
+        private WifiNative mWifiNative = new WifiNative(mInterface);
+        private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
 
         private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
         private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
@@ -456,9 +458,9 @@
         public void enter() {
             if (DBG) logd(getName());
             logd("stopping supplicant");
-            if (!WifiNative.stopSupplicant()) {
+            if (!mWifiNative.stopSupplicant()) {
                 loge("Failed to stop supplicant, issue kill");
-                WifiNative.killSupplicant();
+                mWifiNative.killSupplicant();
             }
         }
 
@@ -468,7 +470,7 @@
             switch (message.what) {
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
                     logd("Supplicant connection lost");
-                    WifiNative.closeSupplicantConnection();
+                    mWifiNative.closeSupplicantConnection();
                     transitionTo(mP2pDisabledState);
                     break;
                 case WifiP2pManager.ENABLE_P2P:
@@ -594,7 +596,7 @@
                         if (DBG) Slog.w(TAG, "Unable to bring down wlan interface: " + e);
                     }
 
-                    if (WifiNative.startP2pSupplicant()) {
+                    if (mWifiNative.startP2pSupplicant()) {
                         mWifiMonitor.startMonitoring();
                         transitionTo(mP2pEnablingState);
                     } else {
@@ -630,7 +632,7 @@
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
                     if (++mP2pRestartCount <= P2P_RESTART_TRIES) {
                         loge("Failed to start p2p, retry");
-                        WifiNative.killSupplicant();
+                        mWifiNative.killSupplicant();
                         sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
                     } else {
                         loge("Failed " + mP2pRestartCount + " times to start p2p, quit ");
@@ -673,7 +675,7 @@
                     break;
                 case WifiP2pManager.DISCOVER_PEERS:
                     int timeout = message.arg1;
-                    if (WifiNative.p2pFind(timeout)) {
+                    if (mWifiNative.p2pFind(timeout)) {
                         replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
                     } else {
                         replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
@@ -692,8 +694,8 @@
                     break;
                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant died */
                     loge("Connection lost, restart p2p");
-                    WifiNative.killSupplicant();
-                    WifiNative.closeSupplicantConnection();
+                    mWifiNative.killSupplicant();
+                    mWifiNative.closeSupplicantConnection();
                     if (mPeers.clear()) sendP2pPeersChangedBroadcast();
                     transitionTo(mP2pDisabledState);
                     sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
@@ -717,7 +719,7 @@
         public void enter() {
             if (DBG) logd(getName());
             //Start listening every time we get inactive
-            WifiNative.p2pListen();
+            mWifiNative.p2pListen();
         }
 
         @Override
@@ -727,13 +729,13 @@
                 case WifiP2pManager.CONNECT:
                     if (DBG) logd(getName() + " sending connect");
                     mSavedPeerConfig = (WifiP2pConfig) message.obj;
-                    String updatedPeerDetails = WifiNative.p2pPeer(mSavedPeerConfig.deviceAddress);
+                    String updatedPeerDetails = mWifiNative.p2pPeer(mSavedPeerConfig.deviceAddress);
                     mPeers.update(new WifiP2pDevice(updatedPeerDetails));
                     mPersistGroup = false;
                     int netId = configuredNetworkId(mSavedPeerConfig.deviceAddress);
                     if (netId >= 0) {
                         //TODO: if failure, remove config and do a regular p2pConnect()
-                        WifiNative.p2pReinvoke(netId, mSavedPeerConfig.deviceAddress);
+                        mWifiNative.p2pReinvoke(netId, mSavedPeerConfig.deviceAddress);
                     } else {
                         //If peer is a GO, we do not need to send provisional discovery,
                         //the supplicant takes care of it.
@@ -798,7 +800,7 @@
                     break;
                 case WifiP2pManager.CREATE_GROUP:
                     mPersistGroup = true;
-                    if (WifiNative.p2pGroupAdd()) {
+                    if (mWifiNative.p2pGroupAdd()) {
                         replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
                     } else {
                         replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
@@ -840,7 +842,7 @@
                             WifiP2pManager.BUSY);
                     break;
                 case WifiP2pManager.CANCEL_CONNECT:
-                    if (WifiNative.p2pCancelConnect()) {
+                    if (mWifiNative.p2pCancelConnect()) {
                         replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
                     } else {
                         replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
@@ -897,7 +899,7 @@
         @Override
         public void enter() {
             if (DBG) logd(getName());
-            WifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
+            mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
         }
 
         @Override
@@ -913,7 +915,7 @@
 
                     if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
                         if (DBG) logd("Found a match " + mSavedPeerConfig);
-                        WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                        mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
                         transitionTo(mGroupNegotiationState);
                     }
                     break;
@@ -926,7 +928,7 @@
                         if (DBG) logd("Found a match " + mSavedPeerConfig);
                         /* we already have the pin */
                         if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
-                            WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                            mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
                             transitionTo(mGroupNegotiationState);
                         } else {
                             transitionTo(mUserAuthorizingInvitationState);
@@ -941,7 +943,7 @@
                     if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
                         if (DBG) logd("Found a match " + mSavedPeerConfig);
                         mSavedPeerConfig.wps.pin = provDisc.pin;
-                        WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                        mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
                         notifyInvitationSent(provDisc.pin, device.deviceAddress);
                         transitionTo(mGroupNegotiationState);
                     }
@@ -1045,7 +1047,7 @@
                             if (DBG) logd("Removed client " + deviceAddress);
                             if (!mPersistGroup && mGroup.isClientListEmpty()) {
                                 Slog.d(TAG, "Client list empty, remove non-persistent p2p group");
-                                WifiNative.p2pGroupRemove(mGroup.getInterface());
+                                mWifiNative.p2pGroupRemove(mGroup.getInterface());
                             }
                         } else {
                             if (DBG) logd("Failed to remove client " + deviceAddress);
@@ -1067,12 +1069,12 @@
                         setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
                         sendP2pConnectionChangedBroadcast();
                     } else {
-                        WifiNative.p2pGroupRemove(mGroup.getInterface());
+                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
                     }
                     break;
                 case WifiP2pManager.REMOVE_GROUP:
                     if (DBG) loge(getName() + " remove group");
-                    if (WifiNative.p2pGroupRemove(mGroup.getInterface())) {
+                    if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
                         replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
                     } else {
                         replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
@@ -1119,7 +1121,7 @@
                 case WifiP2pManager.CONNECT:
                     WifiP2pConfig config = (WifiP2pConfig) message.obj;
                     logd("Inviting device : " + config.deviceAddress);
-                    if (WifiNative.p2pInvite(mGroup, config.deviceAddress)) {
+                    if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
                         updateDeviceStatus(config.deviceAddress, WifiP2pDevice.INVITED);
                         sendP2pPeersChangedBroadcast();
                         replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
@@ -1180,9 +1182,9 @@
                     break;
                 case PEER_CONNECTION_USER_ACCEPT:
                     if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
-                        WifiNative.startWpsPbc();
+                        mWifiNative.startWpsPbc();
                     } else {
-                        WifiNative.startWpsPinKeypad(mSavedPeerConfig.wps.pin);
+                        mWifiNative.startWpsPinKeypad(mSavedPeerConfig.wps.pin);
                     }
                     mSavedPeerConfig = null;
                     transitionTo(mGroupCreatedState);
@@ -1422,7 +1424,7 @@
     }
 
     private void p2pConnectWithPinDisplay(WifiP2pConfig config, boolean join) {
-        String pin = WifiNative.p2pConnect(config, join);
+        String pin = mWifiNative.p2pConnect(config, join);
         try {
             Integer.parseInt(pin);
             notifyInvitationSent(pin, config.deviceAddress);
@@ -1432,16 +1434,16 @@
     }
 
     private void initializeP2pSettings() {
-        WifiNative.setPersistentReconnect(true);
-        WifiNative.setDeviceName(mThisDevice.deviceName);
+        mWifiNative.setPersistentReconnect(true);
+        mWifiNative.setDeviceName(mThisDevice.deviceName);
         //DIRECT-XY-DEVICENAME (XY is randomly generated)
-        WifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
-        WifiNative.setDeviceType(mThisDevice.primaryDeviceType);
+        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
+        mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
         //The supplicant default is to support everything, but a bug necessitates
         //the framework to specify this explicitly
-        WifiNative.setConfigMethods("keypad display push_button");
+        mWifiNative.setConfigMethods("keypad display push_button");
 
-        mThisDevice.deviceAddress = WifiNative.p2pGetDeviceAddress();
+        mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
         updateThisDevice(WifiP2pDevice.AVAILABLE);
         if (DBG) Slog.d(TAG, "DeviceAddress: " + mThisDevice.deviceAddress);
     }