summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml38
-rw-r--r--core/java/android/os/AsyncTask.java79
-rw-r--r--core/java/android/view/ViewRoot.java2
-rw-r--r--libs/hwui/Layer.h16
-rw-r--r--libs/hwui/LayerRenderer.cpp92
-rw-r--r--libs/hwui/LayerRenderer.h5
-rw-r--r--libs/hwui/OpenGLRenderer.cpp55
-rw-r--r--libs/hwui/OpenGLRenderer.h34
-rw-r--r--libs/hwui/Snapshot.h2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java13
-rw-r--r--services/java/com/android/server/WifiService.java5
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl3
-rw-r--r--wifi/java/android/net/wifi/WifiConfigStore.java36
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java6
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java30
-rw-r--r--wifi/java/android/net/wifi/WpsResult.aidl19
-rw-r--r--wifi/java/android/net/wifi/WpsResult.java90
-rw-r--r--wifi/java/android/net/wifi/WpsStateMachine.java24
20 files changed, 501 insertions, 101 deletions
diff --git a/api/current.xml b/api/current.xml
index 7e2ac7e9a027..4989eba7d2f7 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -137540,6 +137540,34 @@
<parameter name="params" type="Params...">
</parameter>
</method>
+<method name="execute"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="runnable" type="java.lang.Runnable">
+</parameter>
+</method>
+<method name="executeOnExecutor"
+ return="android.os.AsyncTask&lt;Params, Progress, Result&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="exec" type="java.util.concurrent.Executor">
+</parameter>
+<parameter name="params" type="Params...">
+</parameter>
+</method>
<method name="get"
return="Result"
abstract="false"
@@ -137672,6 +137700,16 @@
<parameter name="values" type="Progress...">
</parameter>
</method>
+<field name="THREAD_POOL_EXECUTOR"
+ type="java.util.concurrent.ThreadPoolExecutor"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="AsyncTask.Status"
extends="java.lang.Enum"
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 9f7e31cd8edb..adc0a8b322b9 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -16,9 +16,11 @@
package android.os;
+import java.util.ArrayDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
@@ -151,8 +153,6 @@ public abstract class AsyncTask<Params, Progress, Result> {
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;
- private static final BlockingQueue<Runnable> sWorkQueue =
- new LinkedBlockingQueue<Runnable>(10);
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
@@ -162,8 +162,17 @@ public abstract class AsyncTask<Params, Progress, Result> {
}
};
- private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
- MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
+ private static final BlockingQueue<Runnable> sPoolWorkQueue =
+ new LinkedBlockingQueue<Runnable>(10);
+
+ /**
+ * A {@link ThreadPoolExecutor} that can be used to execute tasks in parallel.
+ */
+ public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR
+ = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
+ TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
+
+ private static final SerialExecutor sSerialExecutor = new SerialExecutor();
private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;
@@ -177,6 +186,32 @@ public abstract class AsyncTask<Params, Progress, Result> {
private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
+ private static class SerialExecutor implements Executor {
+ final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
+ Runnable mActive;
+
+ public synchronized void execute(final Runnable r) {
+ mTasks.offer(new Runnable() {
+ public void run() {
+ try {
+ r.run();
+ } finally {
+ scheduleNext();
+ }
+ }
+ });
+ if (mActive == null) {
+ scheduleNext();
+ }
+ }
+
+ protected synchronized void scheduleNext() {
+ if ((mActive = mTasks.poll()) != null) {
+ THREAD_POOL_EXECUTOR.execute(mActive);
+ }
+ }
+ }
+
/**
* Indicates the current status of the task. Each status will be set only once
* during the lifetime of a task.
@@ -433,7 +468,11 @@ public abstract class AsyncTask<Params, Progress, Result> {
/**
* Executes the task with the specified parameters. The task returns
- * itself (this) so that the caller can keep a reference to it.
+ * itself (this) so that the caller can keep a reference to it. The tasks
+ * started by all invocations of this method in a given process are run
+ * sequentially. Call the {@link #execute(Executor,Params...) execute(Executor,Params...)}
+ * with a custom {@link Executor} to have finer grained control over how the
+ * tasks are run.
*
* This method must be invoked on the UI thread.
*
@@ -445,6 +484,26 @@ public abstract class AsyncTask<Params, Progress, Result> {
* {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
*/
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
+ return executeOnExecutor(sSerialExecutor, params);
+ }
+
+ /**
+ * Executes the task with the specified parameters. The task returns
+ * itself (this) so that the caller can keep a reference to it.
+ *
+ * This method must be invoked on the UI thread.
+ *
+ * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a
+ * convenient process-wide thread pool for tasks that are loosely coupled.
+ * @param params The parameters of the task.
+ *
+ * @return This instance of AsyncTask.
+ *
+ * @throws IllegalStateException If {@link #getStatus()} returns either
+ * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
+ */
+ public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
+ Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
@@ -462,12 +521,20 @@ public abstract class AsyncTask<Params, Progress, Result> {
onPreExecute();
mWorker.mParams = params;
- sExecutor.execute(mFuture);
+ exec.execute(mFuture);
return this;
}
/**
+ * Schedules the {@link Runnable} in serial with the other AsyncTasks that were started
+ * with {@link #execute}.
+ */
+ public static void execute(Runnable runnable) {
+ sSerialExecutor.execute(runnable);
+ }
+
+ /**
* This method can be invoked from {@link #doInBackground} to
* publish updates on the UI thread while the background computation is
* still running. Each call to this method will trigger the execution of
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index ad9e68633958..e2285373c7e8 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1780,7 +1780,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
void dispatchDetachedFromWindow() {
- if (mView != null) {
+ if (mView != null && mView.mAttachInfo != null) {
mView.dispatchDetachedFromWindow();
}
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 7d54d3b3255d..bb2843790ed7 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -27,6 +27,7 @@
#include "Rect.h"
#include "SkiaColorFilter.h"
+#include "Vertex.h"
namespace android {
namespace uirenderer {
@@ -41,6 +42,14 @@ namespace uirenderer {
struct Layer {
Layer(const uint32_t layerWidth, const uint32_t layerHeight):
width(layerWidth), height(layerHeight) {
+ mesh = NULL;
+ meshIndices = NULL;
+ meshElementCount = 0;
+ }
+
+ ~Layer() {
+ if (mesh) delete mesh;
+ if (meshIndices) delete meshIndices;
}
/**
@@ -99,6 +108,13 @@ struct Layer {
* Color filter used to draw this layer. Optional.
*/
SkiaColorFilter* colorFilter;
+
+ /**
+ * If the layer can be rendered as a mesh, this is non-null.
+ */
+ TextureVertex* mesh;
+ uint16_t* meshIndices;
+ GLsizei meshElementCount;
}; // struct Layer
}; // namespace uirenderer
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index a25c95ed6614..cd2554e14a4f 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -29,6 +29,10 @@ namespace uirenderer {
void LayerRenderer::prepare(bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
+#if RENDER_LAYERS_AS_REGIONS
+ mLayer->region.clear();
+#endif
+
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo);
glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
@@ -39,11 +43,97 @@ void LayerRenderer::finish() {
OpenGLRenderer::finish();
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo);
+ generateMesh();
+
LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->mFbo);
}
///////////////////////////////////////////////////////////////////////////////
-// Static functions
+// Dirty region tracking
+///////////////////////////////////////////////////////////////////////////////
+
+bool LayerRenderer::hasLayer() {
+ return true;
+}
+
+Region* LayerRenderer::getRegion() {
+#if RENDER_LAYERS_AS_REGIONS
+ if (getSnapshot()->flags & Snapshot::kFlagFboTarget) {
+ return OpenGLRenderer::getRegion();
+ }
+ return &mLayer->region;
+#else
+ return OpenGLRenderer::getRegion();
+#endif
+}
+
+void LayerRenderer::generateMesh() {
+#if RENDER_LAYERS_AS_REGIONS
+ if (mLayer->region.isRect() || mLayer->region.isEmpty()) {
+ if (mLayer->mesh) {
+ delete mLayer->mesh;
+ delete mLayer->meshIndices;
+
+ mLayer->mesh = NULL;
+ mLayer->meshIndices = NULL;
+ mLayer->meshElementCount = 0;
+ }
+ return;
+ }
+
+ size_t count;
+ const android::Rect* rects = mLayer->region.getArray(&count);
+
+ GLsizei elementCount = count * 6;
+
+ if (mLayer->mesh && mLayer->meshElementCount < elementCount) {
+ delete mLayer->mesh;
+ delete mLayer->meshIndices;
+
+ mLayer->mesh = NULL;
+ mLayer->meshIndices = NULL;
+ }
+
+ if (!mLayer->mesh) {
+ mLayer->mesh = new TextureVertex[count * 4];
+ mLayer->meshIndices = new uint16_t[elementCount];
+ mLayer->meshElementCount = elementCount;
+ }
+
+ const float texX = 1.0f / float(mLayer->width);
+ const float texY = 1.0f / float(mLayer->height);
+ const float height = mLayer->layer.getHeight();
+
+ TextureVertex* mesh = mLayer->mesh;
+ uint16_t* indices = mLayer->meshIndices;
+
+ for (size_t i = 0; i < count; i++) {
+ const android::Rect* r = &rects[i];
+
+ const float u1 = r->left * texX;
+ const float v1 = (height - r->top) * texY;
+ const float u2 = r->right * texX;
+ const float v2 = (height - r->bottom) * texY;
+
+ TextureVertex::set(mesh++, r->left, r->top, u1, v1);
+ TextureVertex::set(mesh++, r->right, r->top, u2, v1);
+ TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
+ TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
+
+ uint16_t quad = i * 4;
+ int index = i * 6;
+ indices[index ] = quad; // top-left
+ indices[index + 1] = quad + 1; // top-right
+ indices[index + 2] = quad + 2; // bottom-left
+ indices[index + 3] = quad + 2; // bottom-left
+ indices[index + 4] = quad + 1; // top-right
+ indices[index + 5] = quad + 3; // bottom-right
+ }
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Layers management
///////////////////////////////////////////////////////////////////////////////
Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque) {
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index ed5d9609c001..f2fb898b21c7 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -49,12 +49,17 @@ public:
void prepare(bool opaque);
void finish();
+ bool hasLayer();
+ Region* getRegion();
+
static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
static void destroyLayer(Layer* layer);
static void destroyLayerDeferred(Layer* layer);
private:
+ void generateMesh();
+
Layer* mLayer;
GLuint mPreviousFbo;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b9332327df99..16a1de7adc32 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -615,6 +615,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
const float alpha = layer->alpha / 255.0f;
const float texX = 1.0f / float(layer->width);
const float texY = 1.0f / float(layer->height);
+ const float height = rect.getHeight();
TextureVertex* mesh = mCaches.getRegionMesh();
GLsizei numQuads = 0;
@@ -636,9 +637,9 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
const android::Rect* r = &rects[i];
const float u1 = r->left * texX;
- const float v1 = (rect.getHeight() - r->top) * texY;
+ const float v1 = (height - r->top) * texY;
const float u2 = r->right * texX;
- const float v2 = (rect.getHeight() - r->bottom) * texY;
+ const float v2 = (height - r->bottom) * texY;
// TODO: Reject quads outside of the clip
TextureVertex::set(mesh++, r->left, r->top, u1, v1);
@@ -694,10 +695,10 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
void OpenGLRenderer::dirtyLayer(const float left, const float top,
const float right, const float bottom, const mat4 transform) {
#if RENDER_LAYERS_AS_REGIONS
- if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) {
+ if (hasLayer()) {
Rect bounds(left, top, right, bottom);
transform.mapRect(bounds);
- dirtyLayerUnchecked(bounds, mSnapshot->region);
+ dirtyLayerUnchecked(bounds, getRegion());
}
#endif
}
@@ -705,9 +706,9 @@ void OpenGLRenderer::dirtyLayer(const float left, const float top,
void OpenGLRenderer::dirtyLayer(const float left, const float top,
const float right, const float bottom) {
#if RENDER_LAYERS_AS_REGIONS
- if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) {
+ if (hasLayer()) {
Rect bounds(left, top, right, bottom);
- dirtyLayerUnchecked(bounds, mSnapshot->region);
+ dirtyLayerUnchecked(bounds, getRegion());
}
#endif
}
@@ -1419,24 +1420,20 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
#if RENDER_LAYERS_AS_REGIONS
- bool hasLayer = (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
+ bool hasActiveLayer = hasLayer();
#else
- bool hasLayer = false;
+ bool hasActiveLayer = false;
#endif
mCaches.unbindMeshBuffer();
if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y,
- hasLayer ? &bounds : NULL)) {
+ hasActiveLayer ? &bounds : NULL)) {
#if RENDER_LAYERS_AS_REGIONS
- if (hasLayer) {
+ if (hasActiveLayer) {
if (!pureTranslate) {
mSnapshot->transform->mapRect(bounds);
}
- bounds.intersect(*mSnapshot->clipRect);
- bounds.snapToPixelBoundaries();
-
- android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
- mSnapshot->region->orSelf(dirty);
+ dirtyLayerUnchecked(bounds, getRegion());
}
#endif
}
@@ -1501,8 +1498,36 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
layer->alpha = alpha;
layer->mode = mode;
+
+#if RENDER_LAYERS_AS_REGIONS
+ if (layer->region.isRect()) {
+ const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
+ composeLayerRect(layer, r);
+ } else if (!layer->region.isEmpty() && layer->mesh) {
+ const Rect& rect = layer->layer;
+
+ setupDraw();
+ setupDrawWithTexture();
+ setupDrawColor(alpha, alpha, alpha, alpha);
+ setupDrawColorFilter();
+ setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
+ setupDrawProgram();
+ setupDrawDirtyRegionsDisabled();
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawTexture(layer->texture);
+ setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
+ setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]);
+
+ glDrawElements(GL_TRIANGLES, layer->meshElementCount,
+ GL_UNSIGNED_SHORT, layer->meshIndices);
+
+ finishDrawTexture();
+ }
+#else
const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
composeLayerRect(layer, r);
+#endif
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 56be13458e10..7387b9268c39 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -133,19 +133,24 @@ protected:
virtual void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
/**
- * Mark the layer as dirty at the specified coordinates. The coordinates
- * are transformed with the supplied matrix.
+ * Marks the specified region as dirty at the specified bounds.
*/
- virtual void dirtyLayer(const float left, const float top,
- const float right, const float bottom, const mat4 transform);
+ void dirtyLayerUnchecked(Rect& bounds, Region* region);
/**
- * Mark the layer as dirty at the specified coordinates.
+ * Returns the current snapshot.
*/
- virtual void dirtyLayer(const float left, const float top,
- const float right, const float bottom);
+ sp<Snapshot> getSnapshot() {
+ return mSnapshot;
+ }
- void dirtyLayerUnchecked(Rect& bounds, Region* region);
+ virtual Region* getRegion() {
+ return mSnapshot->region;
+ }
+
+ virtual bool hasLayer() {
+ return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
+ }
private:
/**
@@ -225,6 +230,19 @@ private:
void clearLayerRegions();
/**
+ * Mark the layer as dirty at the specified coordinates. The coordinates
+ * are transformed with the supplied matrix.
+ */
+ void dirtyLayer(const float left, const float top,
+ const float right, const float bottom, const mat4 transform);
+
+ /**
+ * Mark the layer as dirty at the specified coordinates.
+ */
+ void dirtyLayer(const float left, const float top,
+ const float right, const float bottom);
+
+ /**
* Draws a colored rectangle with the specified color. The specified coordinates
* are transformed by the current snapshot's transform matrix.
*
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 9898df491eba..595ad4e92e3b 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -268,7 +268,7 @@ public:
Rect* clipRect;
/**
- * The ancestor layer's dirty region..
+ * The ancestor layer's dirty region.
*/
Region* region;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
index da60f0d681c7..1b2fcadcbeb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
@@ -21,6 +21,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.AsyncTask;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
@@ -78,15 +79,19 @@ public class AirplaneModeController extends BroadcastReceiver
// TODO: Fix this racy API by adding something better to TelephonyManager or
// ConnectivityService.
- private void unsafe(boolean enabled) {
- Settings.System.putInt(
- mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON,
- enabled ? 1 : 0);
- Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("state", enabled);
- mContext.sendBroadcast(intent);
+ private void unsafe(final boolean enabled) {
+ AsyncTask.execute(new Runnable() {
+ public void run() {
+ Settings.System.putInt(
+ mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON,
+ enabled ? 1 : 0);
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.putExtra("state", enabled);
+ mContext.sendBroadcast(intent);
+ }
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
index 866e5fcad7b4..b0a6d7aeca78 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy;
import android.content.ContentResolver;
import android.content.Context;
+import android.os.AsyncTask;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
@@ -45,7 +46,6 @@ public class AutoRotateController implements CompoundButton.OnCheckedChangeListe
}
public void onCheckedChanged(CompoundButton view, boolean checked) {
- Slog.d(TAG, "onCheckedChanged checked=" + checked + " mLockRotation=" + mLockRotation);
if (checked != mLockRotation) {
setLockRotation(checked);
}
@@ -56,18 +56,22 @@ public class AutoRotateController implements CompoundButton.OnCheckedChangeListe
return 0 == Settings.System.getInt(cr, Settings.System.ACCELEROMETER_ROTATION, 0);
}
- private void setLockRotation(boolean locked) {
+ private void setLockRotation(final boolean locked) {
mLockRotation = locked;
- try {
- IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService(
- Context.WINDOW_SERVICE));
- ContentResolver cr = mContext.getContentResolver();
- if (locked) {
- wm.freezeRotation();
- } else {
- wm.thawRotation();
- }
- } catch (RemoteException exc) {
- }
+ AsyncTask.execute(new Runnable() {
+ public void run() {
+ try {
+ IWindowManager wm = IWindowManager.Stub.asInterface(
+ ServiceManager.getService(Context.WINDOW_SERVICE));
+ ContentResolver cr = mContext.getContentResolver();
+ if (locked) {
+ wm.freezeRotation();
+ } else {
+ wm.thawRotation();
+ }
+ } catch (RemoteException exc) {
+ }
+ }
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
index ca1d98fc8984..521467a5d76a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy;
import android.content.ContentResolver;
import android.content.Context;
+import android.os.AsyncTask;
import android.os.IPowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -79,11 +80,15 @@ public class BrightnessController implements ToggleSlider.Listener {
setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
: Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
if (!automatic) {
- value = value + value + MINIMUM_BACKLIGHT;
- setBrightness(value);
+ final int val = value + value + MINIMUM_BACKLIGHT;
+ setBrightness(val);
if (!tracking) {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SCREEN_BRIGHTNESS, value);
+ AsyncTask.execute(new Runnable() {
+ public void run() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, val);
+ }
+ });
}
}
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 1b590ba2190b..cf072392cbe1 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -37,6 +37,7 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WpsConfiguration;
+import android.net.wifi.WpsResult;
import android.net.ConnectivityManager;
import android.net.InterfaceConfiguration;
import android.net.DhcpInfo;
@@ -841,13 +842,13 @@ public class WifiService extends IWifiManager.Stub {
mWifiStateMachine.forgetNetwork(netId);
}
- public String startWps(WpsConfiguration config) {
+ public WpsResult startWps(WpsConfiguration config) {
enforceChangePermission();
if (mChannel != null) {
return mWifiStateMachine.startWps(mChannel, config);
} else {
Slog.e(TAG, "mChannel is not initialized");
- return "";
+ return new WpsResult(WpsResult.Status.FAILURE);
}
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 9dbba202689c..847577fea4ff 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -19,6 +19,7 @@ package android.net.wifi;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WpsConfiguration;
+import android.net.wifi.WpsResult;
import android.net.wifi.ScanResult;
import android.net.DhcpInfo;
@@ -109,6 +110,6 @@ interface IWifiManager
void forgetNetwork(int networkId);
- String startWps(in WpsConfiguration config);
+ WpsResult startWps(in WpsConfiguration config);
}
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 56bc5d773851..73c24cf02397 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -370,44 +370,52 @@ class WifiConfigStore {
* Start WPS pin method configuration with pin obtained
* from the access point
*/
- static boolean startWpsWithPinFromAccessPoint(WpsConfiguration config) {
+ static WpsResult startWpsWithPinFromAccessPoint(WpsConfiguration config) {
+ WpsResult result = new WpsResult();
if (WifiNative.startWpsWithPinFromAccessPointCommand(config.BSSID, config.pin)) {
/* WPS leaves all networks disabled */
markAllNetworksDisabled();
- return true;
+ result.status = WpsResult.Status.SUCCESS;
+ } else {
+ Log.e(TAG, "Failed to start WPS pin method configuration");
+ result.status = WpsResult.Status.FAILURE;
}
- Log.e(TAG, "Failed to start WPS pin method configuration");
- return false;
+ return result;
}
/**
* Start WPS pin method configuration with pin obtained
* from the device
- * @return empty string on failure. null is never returned.
+ * @return WpsResult indicating status and pin
*/
- static String startWpsWithPinFromDevice(WpsConfiguration config) {
- String pin = WifiNative.startWpsWithPinFromDeviceCommand(config.BSSID);
+ static WpsResult startWpsWithPinFromDevice(WpsConfiguration config) {
+ WpsResult result = new WpsResult();
+ result.pin = WifiNative.startWpsWithPinFromDeviceCommand(config.BSSID);
/* WPS leaves all networks disabled */
- if (!TextUtils.isEmpty(pin)) {
+ if (!TextUtils.isEmpty(result.pin)) {
markAllNetworksDisabled();
+ result.status = WpsResult.Status.SUCCESS;
} else {
Log.e(TAG, "Failed to start WPS pin method configuration");
- pin = "";
+ result.status = WpsResult.Status.FAILURE;
}
- return pin;
+ return result;
}
/**
* Start WPS push button configuration
*/
- static boolean startWpsPbc(WpsConfiguration config) {
+ static WpsResult startWpsPbc(WpsConfiguration config) {
+ WpsResult result = new WpsResult();
if (WifiNative.startWpsPbcCommand(config.BSSID)) {
/* WPS leaves all networks disabled */
markAllNetworksDisabled();
- return true;
+ result.status = WpsResult.Status.SUCCESS;
+ } else {
+ Log.e(TAG, "Failed to start WPS push button configuration");
+ result.status = WpsResult.Status.FAILURE;
}
- Log.e(TAG, "Failed to start WPS push button configuration");
- return false;
+ return result;
}
/**
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 46237214861b..54887d7be1a2 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1074,15 +1074,15 @@ public class WifiManager {
* Start Wi-fi Protected Setup
*
* @param config WPS configuration
- * @return pin generated by device, if any
+ * @return WpsResult containing pin and status
* @hide
* TODO: with use of AsyncChannel, return value should go away
*/
- public String startWps(WpsConfiguration config) {
+ public WpsResult startWps(WpsConfiguration config) {
try {
return mService.startWps(config);
} catch (RemoteException e) {
- return null;
+ return new WpsResult(WpsResult.Status.FAILURE);
}
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 871811730679..d7d86f0b8fad 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -47,6 +47,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo.DetailedState;
import android.net.LinkProperties;
import android.net.wifi.NetworkUpdateResult;
+import android.net.wifi.WpsResult.Status;
import android.os.Binder;
import android.os.Message;
import android.os.IBinder;
@@ -302,10 +303,11 @@ public class WifiStateMachine extends HierarchicalStateMachine {
/* Reset the supplicant state tracker */
static final int CMD_RESET_SUPPLICANT_STATE = 111;
-
/* Commands/events reported by WpsStateMachine */
/* Indicates the completion of WPS activity */
static final int WPS_COMPLETED_EVENT = 121;
+ /* Reset the WPS state machine */
+ static final int CMD_RESET_WPS_STATE = 122;
private static final int CONNECT_MODE = 1;
private static final int SCAN_ONLY_MODE = 2;
@@ -793,18 +795,19 @@ public class WifiStateMachine extends HierarchicalStateMachine {
sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
}
- public String startWps(AsyncChannel channel, WpsConfiguration config) {
- String result = null;
+ public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) {
+ WpsResult result;
switch (config.setup) {
case PIN_FROM_DEVICE:
+ case PBC:
+ case PIN_FROM_ACCESS_POINT:
//TODO: will go away with AsyncChannel use from settings
Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
- result = (String) resultMsg.obj;
+ result = (WpsResult) resultMsg.obj;
resultMsg.recycle();
break;
- case PBC:
- case PIN_FROM_ACCESS_POINT:
- sendMessage(obtainMessage(CMD_START_WPS, config));
+ default:
+ result = new WpsResult(Status.FAILURE);
break;
}
return result;
@@ -1511,13 +1514,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_ENABLE_ALL_NETWORKS:
break;
case CMD_START_WPS:
- WpsConfiguration config = (WpsConfiguration) message.obj;
- switch (config.setup) {
- case PIN_FROM_DEVICE:
- String pin = "";
- mReplyChannel.replyToMessage(message, message.what, pin);
- break;
- }
+ /* Return failure when the state machine cannot handle WPS initiation*/
+ mReplyChannel.replyToMessage(message, message.what,
+ new WpsResult(Status.FAILURE));
break;
default:
Log.e(TAG, "Error! unhandled message" + message);
@@ -1803,6 +1802,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
/* Reset the supplicant state to indicate the supplicant
* state is not known at this time */
mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
+ mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
/* Initialize data structures */
mLastBssid = null;
mLastNetworkId = -1;
@@ -1884,6 +1884,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
setWifiState(WIFI_STATE_DISABLING);
sendSupplicantConnectionChangedBroadcast(false);
mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
+ mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
transitionTo(mSupplicantStoppingState);
break;
case SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */
@@ -1894,6 +1895,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
handleNetworkDisconnect();
sendSupplicantConnectionChangedBroadcast(false);
mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
+ mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
transitionTo(mDriverLoadedState);
sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
break;
diff --git a/wifi/java/android/net/wifi/WpsResult.aidl b/wifi/java/android/net/wifi/WpsResult.aidl
new file mode 100644
index 000000000000..eb4c4f5539ba
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsResult.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+parcelable WpsResult;
diff --git a/wifi/java/android/net/wifi/WpsResult.java b/wifi/java/android/net/wifi/WpsResult.java
new file mode 100644
index 000000000000..d4fd3e23d08f
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsResult.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class representing the result of a WPS request
+ * @hide
+ */
+public class WpsResult implements Parcelable {
+
+ public enum Status {
+ SUCCESS,
+ FAILURE,
+ IN_PROGRESS,
+ }
+
+ public Status status;
+
+ public String pin;
+
+ public WpsResult() {
+ status = Status.FAILURE;
+ pin = null;
+ }
+
+ public WpsResult(Status s) {
+ status = s;
+ pin = null;
+ }
+
+ public String toString() {
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append(" status: ").append(status.toString());
+ sbuf.append('\n');
+ sbuf.append(" pin: ").append(pin);
+ sbuf.append("\n");
+ return sbuf.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** copy constructor {@hide} */
+ public WpsResult(WpsResult source) {
+ if (source != null) {
+ status = source.status;
+ pin = source.pin;
+ }
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(status.name());
+ dest.writeString(pin);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<WpsResult> CREATOR =
+ new Creator<WpsResult>() {
+ public WpsResult createFromParcel(Parcel in) {
+ WpsResult result = new WpsResult();
+ result.status = Status.valueOf(in.readString());
+ result.pin = in.readString();
+ return result;
+ }
+
+ public WpsResult[] newArray(int size) {
+ return new WpsResult[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java
index 381444c9b53f..92f9f57f5448 100644
--- a/wifi/java/android/net/wifi/WpsStateMachine.java
+++ b/wifi/java/android/net/wifi/WpsStateMachine.java
@@ -23,6 +23,7 @@ import com.android.internal.util.HierarchicalStateMachine;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiStateMachine.StateChangeResult;
+import android.net.wifi.WpsResult.Status;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
@@ -93,29 +94,32 @@ class WpsStateMachine extends HierarchicalStateMachine {
switch (message.what) {
case WifiStateMachine.CMD_START_WPS:
mWpsConfig = (WpsConfiguration) message.obj;
- boolean success = false;
+ WpsResult result;
switch (mWpsConfig.setup) {
case PBC:
- success = WifiConfigStore.startWpsPbc(mWpsConfig);
+ result = WifiConfigStore.startWpsPbc(mWpsConfig);
break;
case PIN_FROM_ACCESS_POINT:
- success = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsConfig);
+ result = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsConfig);
break;
case PIN_FROM_DEVICE:
- String pin = WifiConfigStore.startWpsWithPinFromDevice(mWpsConfig);
- success = (pin != null);
- mReplyChannel.replyToMessage(message, message.what, pin);
+ result = WifiConfigStore.startWpsWithPinFromDevice(mWpsConfig);
break;
default:
+ result = new WpsResult(Status.FAILURE);
Log.e(TAG, "Invalid setup for WPS");
break;
}
- if (success) {
+ mReplyChannel.replyToMessage(message, message.what, result);
+ if (result.status == Status.SUCCESS) {
transitionTo(mActiveState);
} else {
Log.e(TAG, "Failed to start WPS with config " + mWpsConfig.toString());
}
break;
+ case WifiStateMachine.CMD_RESET_WPS_STATE:
+ transitionTo(mInactiveState);
+ break;
default:
Log.e(TAG, "Failed to handle " + message);
break;
@@ -167,7 +171,9 @@ class WpsStateMachine extends HierarchicalStateMachine {
}
break;
case WifiStateMachine.CMD_START_WPS:
- deferMessage(message);
+ /* Ignore request and send an in progress message */
+ mReplyChannel.replyToMessage(message, message.what,
+ new WpsResult(Status.IN_PROGRESS));
break;
default:
retValue = NOT_HANDLED;
@@ -197,4 +203,4 @@ class WpsStateMachine extends HierarchicalStateMachine {
}
}
-} \ No newline at end of file
+}