summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml66
-rw-r--r--core/java/android/gesture/GestureLibrary.java10
-rw-r--r--core/java/android/gesture/GestureStroke.java11
-rwxr-xr-xcore/java/android/gesture/GestureUtilities.java44
-rwxr-xr-xcore/java/android/gesture/Instance.java32
-rw-r--r--core/java/android/gesture/InstanceLearner.java9
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--core/res/res/values/strings.xml9
-rw-r--r--services/java/com/android/server/WifiService.java14
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl4
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java143
-rw-r--r--wifi/java/android/net/wifi/WifiStateTracker.java6
12 files changed, 243 insertions, 112 deletions
diff --git a/api/current.xml b/api/current.xml
index 4db6e66..f93fefd 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -309,6 +309,17 @@
visibility="public"
>
</field>
+<field name="CHANGE_WIFI_MULTICAST_STATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.permission.CHANGE_WIFI_MULTICAST_STATE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="CHANGE_WIFI_STATE"
type="java.lang.String"
transient="false"
@@ -80263,6 +80274,19 @@
<parameter name="rssiB" type="int">
</parameter>
</method>
+<method name="createMulticastLock"
+ return="android.net.wifi.WifiManager.MulticastLock"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="java.lang.String">
+</parameter>
+</method>
<method name="createWifiLock"
return="android.net.wifi.WifiManager.WifiLock"
abstract="false"
@@ -80755,6 +80779,48 @@
>
</field>
</class>
+<class name="WifiManager.MulticastLock"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="acquire"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isHeld"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="release"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
<class name="WifiManager.WifiLock"
extends="java.lang.Object"
abstract="false"
diff --git a/core/java/android/gesture/GestureLibrary.java b/core/java/android/gesture/GestureLibrary.java
index 9020d2b..1cf192e 100644
--- a/core/java/android/gesture/GestureLibrary.java
+++ b/core/java/android/gesture/GestureLibrary.java
@@ -136,7 +136,7 @@ public class GestureLibrary {
* @return a list of predictions of possible entries for a given gesture
*/
public ArrayList<Prediction> recognize(Gesture gesture) {
- Instance instance = Instance.createInstance(mSequenceType, mOrientationStyle, gesture, null);
+ Instance instance = Instance.createInstance(mSequenceType, gesture, null);
return mClassifier.classify(mSequenceType, instance.vector);
}
@@ -156,7 +156,7 @@ public class GestureLibrary {
mNamedGestures.put(entryName, gestures);
}
gestures.add(gesture);
- mClassifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, entryName));
+ mClassifier.addInstance(Instance.createInstance(mSequenceType, gesture, entryName));
mChanged = true;
}
@@ -337,14 +337,10 @@ public class GestureLibrary {
for (int j = 0; j < gestureCount; j++) {
final Gesture gesture = Gesture.deserialize(in);
gestures.add(gesture);
- classifier.addInstance(Instance.createInstance(mSequenceType, mOrientationStyle, gesture, name));
+ classifier.addInstance(Instance.createInstance(mSequenceType, gesture, name));
}
namedGestures.put(name, gestures);
}
}
-
- Learner getLearner() {
- return mClassifier;
- }
}
diff --git a/core/java/android/gesture/GestureStroke.java b/core/java/android/gesture/GestureStroke.java
index 90faaed..0d7bc2d 100644
--- a/core/java/android/gesture/GestureStroke.java
+++ b/core/java/android/gesture/GestureStroke.java
@@ -17,6 +17,7 @@
package android.gesture;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
@@ -146,12 +147,10 @@ public class GestureStroke {
final float[] pts = GestureUtilities.temporalSampling(this, numSample);
final RectF rect = boundingBox;
- GestureUtilities.translate(pts, -rect.left, -rect.top);
-
- float sx = width / rect.width();
- float sy = height / rect.height();
- float scale = sx > sy ? sy : sx;
- GestureUtilities.scale(pts, scale, scale);
+ final Matrix matrix = new Matrix();
+ matrix.setTranslate(-rect.left, -rect.top);
+ matrix.postScale(width / rect.width(), height / rect.height());
+ matrix.mapPoints(pts);
float mX = 0;
float mY = 0;
diff --git a/core/java/android/gesture/GestureUtilities.java b/core/java/android/gesture/GestureUtilities.java
index 3e8a3c8..4a3144c 100755
--- a/core/java/android/gesture/GestureUtilities.java
+++ b/core/java/android/gesture/GestureUtilities.java
@@ -17,6 +17,7 @@
package android.gesture;
import android.graphics.RectF;
+import android.graphics.Matrix;
import android.util.Log;
import java.util.ArrayList;
@@ -379,17 +380,22 @@ final class GestureUtilities {
}
static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) {
- translate(points, -centroid[0], -centroid[1]);
+ Matrix tr = new Matrix();
+ tr.setTranslate(-centroid[0], -centroid[1]);
+ tr.mapPoints(points);
double[][] array = computeCoVariance(points);
double[] targetVector = computeOrientation(array);
float angle;
if (targetVector[0] == 0 && targetVector[1] == 0) {
- angle = (float) -Math.PI/2;
+ angle = -90;
} else { // -PI<alpha<PI
angle = (float) Math.atan2(targetVector[1], targetVector[0]);
- rotate(points, -angle);
+ angle = (float) (180 * angle / Math.PI);
+ Matrix trans = new Matrix();
+ trans.setRotate(-angle);
+ trans.mapPoints(points);
}
float minx = Float.MAX_VALUE;
@@ -440,36 +446,4 @@ final class GestureUtilities {
}
return targetVector;
}
-
-
- static float[] rotate(float[] points, double angle) {
- double cos = Math.cos(angle);
- double sin = Math.sin(angle);
- int size = points.length;
- for (int i = 0; i < size; i += 2) {
- float x = (float) (points[i] * cos - points[i + 1] * sin);
- float y = (float) (points[i] * sin + points[i + 1] * cos);
- points[i] = x;
- points[i + 1] = y;
- }
- return points;
- }
-
- static float[] translate(float[] points, float dx, float dy) {
- int size = points.length;
- for (int i = 0; i < size; i += 2) {
- points[i] += dx;
- points[i + 1] += dy;
- }
- return points;
- }
-
- static float[] scale(float[] points, float sx, float sy) {
- int size = points.length;
- for (int i = 0; i < size; i += 2) {
- points[i] *= sx;
- points[i + 1] *= sy;
- }
- return points;
- }
}
diff --git a/core/java/android/gesture/Instance.java b/core/java/android/gesture/Instance.java
index 9ac0a96..7922fab 100755
--- a/core/java/android/gesture/Instance.java
+++ b/core/java/android/gesture/Instance.java
@@ -16,6 +16,7 @@
package android.gesture;
+import android.graphics.Matrix;
/**
* An instance represents a sample if the label is available or a query if the
@@ -27,9 +28,7 @@ class Instance {
private static final int PATCH_SAMPLE_SIZE = 16;
private final static float[] ORIENTATIONS = {
- 0, (float) (Math.PI / 4), (float) (Math.PI / 2), (float) (Math.PI * 3 / 4),
- (float) Math.PI, -0, (float) (-Math.PI / 4), (float) (-Math.PI / 2),
- (float) (-Math.PI * 3 / 4), (float) -Math.PI
+ 0, 45, 90, 135, 180, -0, -45, -90, -135, -180
};
// the feature vector
@@ -40,13 +39,13 @@ class Instance {
// the id of the instance
final long id;
-
+
private Instance(long id, float[] sample, String sampleName) {
this.id = id;
vector = sample;
label = sampleName;
}
-
+
private void normalize() {
float[] sample = vector;
float sum = 0;
@@ -56,7 +55,7 @@ class Instance {
sum += sample[i] * sample[i];
}
- float magnitude = (float)Math.sqrt(sum);
+ float magnitude = (float) Math.sqrt(sum);
for (int i = 0; i < size; i++) {
sample[i] /= magnitude;
}
@@ -69,11 +68,11 @@ class Instance {
* @param label
* @return the instance
*/
- static Instance createInstance(int sequenceType, int orientationType, Gesture gesture, String label) {
+ static Instance createInstance(int samplingType, Gesture gesture, String label) {
float[] pts;
Instance instance;
- if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) {
- pts = temporalSampler(orientationType, gesture);
+ if (samplingType == GestureLibrary.SEQUENCE_SENSITIVE) {
+ pts = temporalSampler(samplingType, gesture);
instance = new Instance(gesture.getID(), pts, label);
instance.normalize();
} else {
@@ -82,19 +81,20 @@ class Instance {
}
return instance;
}
-
+
private static float[] spatialSampler(Gesture gesture) {
return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
}
- private static float[] temporalSampler(int orientationType, Gesture gesture) {
+ private static float[] temporalSampler(int samplingType, Gesture gesture) {
float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0),
SEQUENCE_SAMPLE_SIZE);
float[] center = GestureUtilities.computeCentroid(pts);
- float orientation = (float)Math.atan2(pts[1] - center[1], pts[0] - center[0]);
+ float orientation = (float) Math.atan2(pts[1] - center[1], pts[0] - center[0]);
+ orientation *= 180 / Math.PI;
float adjustment = -orientation;
- if (orientationType == GestureLibrary.ORIENTATION_SENSITIVE) {
+ if (samplingType == GestureLibrary.ORIENTATION_SENSITIVE) {
int count = ORIENTATIONS.length;
for (int i = 0; i < count; i++) {
float delta = ORIENTATIONS[i] - orientation;
@@ -104,8 +104,10 @@ class Instance {
}
}
- GestureUtilities.translate(pts, -center[0], -center[1]);
- GestureUtilities.rotate(pts, adjustment);
+ Matrix m = new Matrix();
+ m.setTranslate(-center[0], -center[1]);
+ m.postRotate(adjustment);
+ m.mapPoints(pts);
return pts;
}
diff --git a/core/java/android/gesture/InstanceLearner.java b/core/java/android/gesture/InstanceLearner.java
index b6feb64..1739cdc 100644
--- a/core/java/android/gesture/InstanceLearner.java
+++ b/core/java/android/gesture/InstanceLearner.java
@@ -16,9 +16,14 @@
package android.gesture;
+import android.util.Config;
+import android.util.Log;
+import static android.gesture.GestureConstants.*;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Iterator;
import java.util.TreeMap;
/**
@@ -27,7 +32,7 @@ import java.util.TreeMap;
class InstanceLearner extends Learner {
@Override
- ArrayList<Prediction> classify(int sequenceType, float[] vector) {
+ ArrayList<Prediction> classify(int gestureType, float[] vector) {
ArrayList<Prediction> predictions = new ArrayList<Prediction>();
ArrayList<Instance> instances = getInstances();
int count = instances.size();
@@ -38,7 +43,7 @@ class InstanceLearner extends Learner {
continue;
}
double distance;
- if (sequenceType == GestureLibrary.SEQUENCE_SENSITIVE) {
+ if (gestureType == GestureLibrary.SEQUENCE_SENSITIVE) {
distance = GestureUtilities.cosineDistance(sample.vector, vector);
} else {
distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b97e07b..0a24bb7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -644,6 +644,13 @@
android:description="@string/permdesc_changeWifiState"
android:label="@string/permlab_changeWifiState" />
+ <!-- Allows applications to enter Wi-Fi Multicast mode -->
+ <permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="dangerous"
+ android:description="@string/permdesc_changeWifiMulticastState"
+ android:label="@string/permlab_changeWifiMulticastState" />
+
<!-- Allows applications to discover and pair bluetooth devices -->
<permission android:name="android.permission.BLUETOOTH_ADMIN"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6512006..39485e2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1012,6 +1012,15 @@
configured Wi-Fi networks.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_changeWifiMulticastState">allow Wi-Fi Multicast
+ reception</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_changeWifiMulticastState">Allows an application to
+ receive packets not directly addressed to your device. This can be
+ useful when discovering services offered near by. It uses more power
+ than the non-multicast mode.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bluetoothAdmin">bluetooth administration</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bluetoothAdmin">Allows an application to configure
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 64d1ba2..5bded50 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -588,6 +588,12 @@ public class WifiService extends IWifiManager.Stub {
}
+ private void enforceMulticastChangePermission() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
+ "WifiService");
+ }
+
/**
* see {@link WifiManager#getWifiState()}
* @return One of {@link WifiManager#WIFI_STATE_DISABLED},
@@ -1935,8 +1941,8 @@ public class WifiService extends IWifiManager.Stub {
}
}
- public void enableMulticast(IBinder binder, String tag) {
- enforceChangePermission();
+ public void acquireMulticastLock(IBinder binder, String tag) {
+ enforceMulticastChangePermission();
synchronized (mMulticasters) {
mMulticastEnabled++;
@@ -1958,8 +1964,8 @@ public class WifiService extends IWifiManager.Stub {
}
}
- public void disableMulticast() {
- enforceChangePermission();
+ public void releaseMulticastLock() {
+ enforceMulticastChangePermission();
int uid = Binder.getCallingUid();
synchronized (mMulticasters) {
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 0db868e..c31577c 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -72,8 +72,8 @@ interface IWifiManager
boolean isMulticastEnabled();
- void enableMulticast(IBinder binder, String tag);
+ void acquireMulticastLock(IBinder binder, String tag);
- void disableMulticast();
+ void releaseMulticastLock();
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 141d53f..c4dff6a 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -825,62 +825,127 @@ public class WifiManager {
return new WifiLock(WIFI_MODE_FULL, tag);
}
+
/**
- * Check multicast filter status.
+ * Create a new MulticastLock
*
- * @return true if multicast packets are allowed.
+ * @param tag a tag for the MulticastLock to identify it in debugging
+ * messages.
*
- * @hide pending API council approval
+ * @return a new, unacquired MulticastLock with the given tag.
+ *
+ * @see MulticastLock
*/
- public boolean isMulticastEnabled() {
- try {
- return mService.isMulticastEnabled();
- } catch (RemoteException e) {
- return false;
- }
+ public MulticastLock createMulticastLock(String tag) {
+ return new MulticastLock(tag);
}
/**
- * Turn on the reception of multicast packets.
- * The default behavior is to disable multicast packets as they
- * have a noticable negative effect on battery life. An
- * application can turn them on, but should not leave it on for longer
- * than needed. When the app quits (or crashes) its request will
- * be reverted.
- *
- * @param tag a string associated with this request for debugging.
- *
- * @return true on success
- *
- * @see #disableMulticast
- *
- * @hide pending API council approval
+ * Allows an application to receive Wifi Multicast packets.
+ * Normally the Wifi stack filters out packets not explicitly
+ * addressed to this device. Acquring a MulticastLock will
+ * cause the stack to receive packets addressed to multicast
+ * addresses. Processing these extra packets can cause a noticable
+ * battery drain and should be disabled when not needed
*/
- public boolean enableMulticast(String tag) {
- try {
- mService.enableMulticast(new Binder(), tag);
- return true;
- } catch (RemoteException e) {
- return false;
+ public class MulticastLock {
+ private String mTag;
+ private final IBinder mBinder;
+ private boolean mHeld;
+
+ private MulticastLock(String tag) {
+ mTag = tag;
+ mBinder = new Binder();
+ mHeld = false;
+ }
+
+ /**
+ * Locks Wifi Multicast on until {@link #release} is called.
+ *
+ * The first call to {@code acquire} will lock the Multicast on
+ * but subsequent calls will be ignored. Only one call to
+ * {@link #release} will be required, regardless of the number of
+ * times that {@code acquire} is called.
+ *
+ * Note that other applications may also lock Wifi Multicast on.
+ * Only they can relinquish their lock.
+ *
+ * Also note that applications cannot leave Multicast locked on.
+ * When an app exits or crashes, any Multicast locks will be released.
+ */
+ public void acquire() {
+ synchronized (mBinder) {
+ if (!mHeld) {
+ try {
+ mService.acquireMulticastLock(mBinder, mTag);
+ mHeld = true;
+ } catch (RemoteException ignore) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Unlocks Wifi Multicast, restoring the filter of packets
+ * not addressed specifically to this device and saving power.
+ *
+ * Note that if any other Wifi Multicast Locks are still outstanding
+ * this {@code release} call will not have an immediate effect. Only
+ * when all applications have released all their Multicast Locks will
+ * the Multicast filter be turned back on.
+ *
+ * Also note that when an app exits or crashes all of its Multicast
+ * Locks will be automatically released.
+ */
+ public void release() {
+ synchronized (mBinder) {
+ if (mHeld) {
+ try {
+ mService.releaseMulticastLock();
+ mHeld = false;
+ } catch (RemoteException ignore) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks whether this MulticastLock is currently held.
+ *
+ * @return true if this MulticastLock is held, false otherwise
+ */
+ public boolean isHeld() {
+ synchronized (mBinder) {
+ return mHeld;
+ }
+ }
+
+ public String toString() {
+ String s1, s2;
+ synchronized (mBinder) {
+ s1 = Integer.toHexString(System.identityHashCode(this));
+ s2 = mHeld ? "held; " : "";
+ return "MulticastLock{ " + s1 + "; " + s2 + " }";
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ release();
}
}
/**
- * Return to the default multicast-off setting.
- * Note that if others had turned on Multicast reception, your
- * call will not turn it back off - they must also turn off their
- * request for multicast reception.
- *
- * @return true on success
+ * Check multicast filter status.
*
- * @see #enableMulticast
+ * @return true if multicast packets are allowed.
*
* @hide pending API council approval
*/
- public boolean disableMulticast() {
+ public boolean isMulticastEnabled() {
try {
- mService.disableMulticast();
- return true;
+ return mService.isMulticastEnabled();
} catch (RemoteException e) {
return false;
}
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 7ba124f..e6f4130 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -755,8 +755,10 @@ public class WifiStateTracker extends NetworkStateTracker {
* first and then off.. if nobody else wants it on it'll be
* off then and it's all synchronized within the API.
*/
- mWM.enableMulticast("WifiStateTracker");
- mWM.disableMulticast();
+ WifiManager.MulticastLock l =
+ mWM.createMulticastLock("WifiStateTracker");
+ l.acquire();
+ l.release();
if (mBluetoothA2dp == null) {
mBluetoothA2dp = new BluetoothA2dp(mContext);