diff options
-rw-r--r-- | api/current.xml | 66 | ||||
-rw-r--r-- | core/java/android/gesture/GestureLibrary.java | 10 | ||||
-rw-r--r-- | core/java/android/gesture/GestureStroke.java | 11 | ||||
-rwxr-xr-x | core/java/android/gesture/GestureUtilities.java | 44 | ||||
-rwxr-xr-x | core/java/android/gesture/Instance.java | 32 | ||||
-rw-r--r-- | core/java/android/gesture/InstanceLearner.java | 9 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 7 | ||||
-rw-r--r-- | core/res/res/values/strings.xml | 9 | ||||
-rw-r--r-- | services/java/com/android/server/WifiService.java | 14 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/IWifiManager.aidl | 4 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 143 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiStateTracker.java | 6 |
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=""android.permission.CHANGE_WIFI_MULTICAST_STATE"" + 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); |