diff options
| -rw-r--r-- | api/current.xml | 66 | ||||
| -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 | 
7 files changed, 202 insertions, 47 deletions
| diff --git a/api/current.xml b/api/current.xml index ce1b726..bf3044e 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" @@ -77087,6 +77098,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" @@ -77579,6 +77603,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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index fbaef5f..36f7dfb 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 8b2689b..e311abd 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1005,6 +1005,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 5fa8701..1528ba3 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}, @@ -1930,8 +1936,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++; @@ -1953,8 +1959,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 7c3af69..3d65d3c 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 1a7caef..5b8ced6 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -824,62 +824,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 6771136..2fbc779 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -747,8 +747,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); | 
