summaryrefslogtreecommitdiffstats
path: root/wifi
diff options
context:
space:
mode:
authorYuhao Zheng <yuhaozheng@google.com>2014-04-10 11:45:42 -0700
committerVinit Deshpande <vinitd@google.com>2014-05-18 09:41:35 -0700
commita4864472313208e4f1de02f45d3eadad237c54af (patch)
treef112d0faf7a8e91d6d891f189d7bf8f883ff8104 /wifi
parent1ab9cc8029f723cc6198c013d9df1477fad2d3f9 (diff)
downloadframeworks_base-a4864472313208e4f1de02f45d3eadad237c54af.zip
frameworks_base-a4864472313208e4f1de02f45d3eadad237c54af.tar.gz
frameworks_base-a4864472313208e4f1de02f45d3eadad237c54af.tar.bz2
Hotspot 2.0 framework APIs -- initial implementation
Cherry-picked from klp-wireless-dev-mirror SHA1: e73969fac45aaca72528226dc8c0c5e54fb2cdd4 Bug: 5485670 Change-Id: If3250a2fae181a3774d3158e341220006ad6ebe5
Diffstat (limited to 'wifi')
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java24
-rw-r--r--wifi/java/android/net/wifi/hotspot/WifiHotspotManager.java48
-rw-r--r--wifi/java/android/net/wifi/passpoint/IPasspointManager.aidl31
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointCredential.aidl (renamed from wifi/java/android/net/wifi/hotspot/IWifiHotspotManager.aidl)13
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointCredential.java56
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointInfo.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointInfo.java220
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointManager.java490
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.java92
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointPolicy.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/PasspointPolicy.java55
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiTree.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiTree.java51
14 files changed, 1096 insertions, 60 deletions
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 1cb9546..6d66b4c 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -16,6 +16,8 @@
package android.net.wifi;
+import android.net.wifi.passpoint.PasspointInfo;
+import android.net.wifi.passpoint.PasspointManager;
import android.os.Parcelable;
import android.os.Parcel;
@@ -77,6 +79,12 @@ public class ScanResult implements Parcelable {
public int distanceSdCm;
/**
+ * Passpoint ANQP information. This is not fetched automatically.
+ * Use {@link PasspointManager#requestAnqpInfo} to request ANQP info.
+ */
+ public PasspointInfo passpoint;
+
+ /**
* {@hide}
*/
public final static int UNSPECIFIED = -1;
@@ -122,6 +130,8 @@ public class ScanResult implements Parcelable {
distanceCm = source.distanceCm;
distanceSdCm = source.distanceSdCm;
seen = source.seen;
+ if (source.passpoint != null)
+ passpoint = new PasspointInfo(source.passpoint);
}
}
@@ -155,6 +165,8 @@ public class ScanResult implements Parcelable {
sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
append("(cm)");
+ if (passpoint != null) sb.append(passpoint.toString());
+
return sb.toString();
}
@@ -178,6 +190,12 @@ public class ScanResult implements Parcelable {
dest.writeLong(timestamp);
dest.writeInt(distanceCm);
dest.writeInt(distanceSdCm);
+ if (passpoint != null) {
+ dest.writeInt(1);
+ passpoint.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
}
/** Implement the Parcelable interface {@hide} */
@@ -188,7 +206,7 @@ public class ScanResult implements Parcelable {
if (in.readInt() == 1) {
wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
}
- return new ScanResult(
+ ScanResult sr = new ScanResult(
wifiSsid,
in.readString(),
in.readString(),
@@ -198,6 +216,10 @@ public class ScanResult implements Parcelable {
in.readInt(),
in.readInt()
);
+ if (in.readInt() == 1) {
+ sr.passpoint = PasspointInfo.CREATOR.createFromParcel(in);
+ }
+ return sr;
}
public ScanResult[] newArray(int size) {
diff --git a/wifi/java/android/net/wifi/hotspot/WifiHotspotManager.java b/wifi/java/android/net/wifi/hotspot/WifiHotspotManager.java
deleted file mode 100644
index ac15017..0000000
--- a/wifi/java/android/net/wifi/hotspot/WifiHotspotManager.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2014 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.hotspot;
-
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * TODO: doc
- */
-public class WifiHotspotManager {
-
- private static final String TAG = "WifiHotspotManager";
-
- private Context mContext;
- IWifiHotspotManager mService;
-
- public WifiHotspotManager(Context context, IWifiHotspotManager service) {
- mContext = context;
- mService = service;
- }
-
- public void test() {
- try{
- Log.d(TAG, "test()");
- mService.test();
- }
- catch (RemoteException e) {
- Log.e(TAG, "test() exception");
- e.printStackTrace();
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/passpoint/IPasspointManager.aidl b/wifi/java/android/net/wifi/passpoint/IPasspointManager.aidl
new file mode 100644
index 0000000..e57db64
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/IPasspointManager.aidl
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+import android.os.Messenger;
+
+/**
+ * Interface that allows controlling and querying Passpoint connectivity.
+ *
+ * {@hide}
+ */
+interface IPasspointManager
+{
+ Messenger getMessenger();
+ int getPasspointState();
+}
+
diff --git a/wifi/java/android/net/wifi/hotspot/IWifiHotspotManager.aidl b/wifi/java/android/net/wifi/passpoint/PasspointCredential.aidl
index 2b1601b..6f75cbe 100644
--- a/wifi/java/android/net/wifi/hotspot/IWifiHotspotManager.aidl
+++ b/wifi/java/android/net/wifi/passpoint/PasspointCredential.aidl
@@ -14,15 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi.hotspot;
-
-/**
- * Interface that allows controlling and querying Hotspot connectivity.
- *
- * {@hide}
- */
-interface IWifiHotspotManager
-{
- void test();
-}
+package android.net.wifi.passpoint;
+parcelable PasspointCredential;
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointCredential.java b/wifi/java/android/net/wifi/passpoint/PasspointCredential.java
new file mode 100644
index 0000000..4218f23
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointCredential.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+public class PasspointCredential implements Parcelable {
+
+ @Override
+ public String toString() {
+ // TODO
+ return null;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // TODO
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<PasspointCredential> CREATOR =
+ new Creator<PasspointCredential>() {
+ @Override
+ public PasspointCredential createFromParcel(Parcel in) {
+ // TODO
+ return null;
+ }
+
+ @Override
+ public PasspointCredential[] newArray(int size) {
+ return new PasspointCredential[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointInfo.aidl b/wifi/java/android/net/wifi/passpoint/PasspointInfo.aidl
new file mode 100644
index 0000000..cc11045
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable PasspointInfo;
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointInfo.java b/wifi/java/android/net/wifi/passpoint/PasspointInfo.java
new file mode 100644
index 0000000..4997aa9
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointInfo.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TODO: doc
+ */
+public class PasspointInfo implements Parcelable {
+
+ /** TODO doc */
+ public static final int ANQP_CAPABILITY = 1 << 0;
+
+ /** TODO doc */
+ public static final int VENUE_NAME = 1 << 1;
+
+ /** TODO doc */
+ public static final int NETWORK_AUTH_TYPE = 1 << 2;
+
+ /** TODO doc */
+ public static final int ROAMING_CONSORTIUM = 1 << 3;
+
+ /** TODO doc */
+ public static final int IP_ADDR_TYPE_AVAILABILITY = 1 << 4;
+
+ /** TODO doc */
+ public static final int NAI_REALM = 1 << 5;
+
+ /** TODO doc */
+ public static final int CELLULAR_NETWORK = 1 << 6;
+
+ /** TODO doc */
+ public static final int DOMAIN_NAME = 1 << 7;
+
+ /** TODO doc */
+ public static final int HOTSPOT_CAPABILITY = 1 << 8;
+
+ /** TODO doc */
+ public static final int OPERATOR_FRIENDLY_NAME = 1 << 9;
+
+ /** TODO doc */
+ public static final int WAN_METRICS = 1 << 10;
+
+ /** TODO doc */
+ public static final int CONNECTION_CAPABILITY = 1 << 11;
+
+ /** TODO doc */
+ public static final int OSU_PROVIDER = 1 << 12;
+
+ /** TODO doc */
+ public static final int PRESET_CRED_MATCH =
+ ANQP_CAPABILITY |
+ HOTSPOT_CAPABILITY |
+ NAI_REALM |
+ CELLULAR_NETWORK |
+ DOMAIN_NAME;
+
+ /** TODO doc */
+ public static final int PRESET_ALL =
+ ANQP_CAPABILITY |
+ VENUE_NAME |
+ NETWORK_AUTH_TYPE |
+ ROAMING_CONSORTIUM |
+ IP_ADDR_TYPE_AVAILABILITY |
+ NAI_REALM |
+ CELLULAR_NETWORK |
+ DOMAIN_NAME |
+ HOTSPOT_CAPABILITY |
+ OPERATOR_FRIENDLY_NAME |
+ WAN_METRICS |
+ CONNECTION_CAPABILITY |
+ OSU_PROVIDER;
+
+
+ /** TODO doc */
+ public String bssid;
+
+ /** TODO doc */
+ public String venueName;
+
+ /** TODO doc */
+ public String networkAuthType;
+
+ /** TODO doc */
+ public String roamingConsortium;
+
+ /** TODO doc */
+ public String ipAddrTypeAvaibility;
+
+ /** TODO doc */
+ public String naiRealm;
+
+ /** TODO doc */
+ public String cellularNetwork;
+
+ /** TODO doc */
+ public String domainName;
+
+ /** TODO doc */
+ public String operatorFriendlyName;
+
+ /** TODO doc */
+ public String wanMetrics;
+
+ /** TODO doc */
+ public String connectionCapability;
+
+ /** TODO doc */
+ public List<PasspointOsuProvider> osuProviderList;
+
+
+ /** default constructor @hide */
+ public PasspointInfo() {
+// osuProviderList = new ArrayList<OsuProvider>();
+ }
+
+ /** copy constructor @hide */
+ public PasspointInfo(PasspointInfo source) {
+ // TODO
+ bssid = source.bssid;
+ venueName = source.venueName;
+ networkAuthType = source.networkAuthType;
+ roamingConsortium = source.roamingConsortium;
+ ipAddrTypeAvaibility = source.ipAddrTypeAvaibility;
+ naiRealm = source.naiRealm;
+ cellularNetwork = source.cellularNetwork;
+ domainName = source.domainName;
+ operatorFriendlyName = source.operatorFriendlyName;
+ wanMetrics = source.wanMetrics;
+ connectionCapability = source.connectionCapability;
+ if (source.osuProviderList != null) {
+ osuProviderList = new ArrayList<PasspointOsuProvider>();
+ for (PasspointOsuProvider osu : source.osuProviderList)
+ osuProviderList.add(new PasspointOsuProvider(osu));
+ }
+ }
+
+ /**
+ * Convert mask to ANQP subtypes, for supplicant command use.
+ *
+ * @param mask The ANQP subtypes mask.
+ * @return String of ANQP subtypes, good for supplicant command use
+ * @hide
+ */
+ public static String toAnqpSubtypes(int mask) {
+ StringBuilder sb = new StringBuilder();
+ if ((mask & ANQP_CAPABILITY) != 0) sb.append("257,");
+ if ((mask & VENUE_NAME) != 0) sb.append("258,");
+ if ((mask & NETWORK_AUTH_TYPE) != 0) sb.append("260,");
+ if ((mask & ROAMING_CONSORTIUM) != 0) sb.append("261,");
+ if ((mask & IP_ADDR_TYPE_AVAILABILITY) != 0) sb.append("262,");
+ if ((mask & NAI_REALM) != 0) sb.append("263,");
+ if ((mask & CELLULAR_NETWORK) != 0) sb.append("264,");
+ if ((mask & DOMAIN_NAME) != 0) sb.append("268,");
+ if ((mask & HOTSPOT_CAPABILITY) != 0) sb.append("hs20:2,");
+ if ((mask & OPERATOR_FRIENDLY_NAME) != 0) sb.append("hs20:3,");
+ if ((mask & WAN_METRICS) != 0) sb.append("hs20:4,");
+ if ((mask & CONNECTION_CAPABILITY) != 0) sb.append("hs20:5,");
+ if ((mask & OSU_PROVIDER) != 0) sb.append("hs20:8,");
+ if (sb.length() > 0) sb.deleteCharAt(sb.length() - 1);
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ // TODO
+ return "PasspointInfo";
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ // TODO
+ out.writeValue(bssid);
+ out.writeValue(venueName);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Parcelable.Creator<PasspointInfo> CREATOR =
+ new Parcelable.Creator<PasspointInfo>() {
+ @Override
+ public PasspointInfo createFromParcel(Parcel in) {
+ PasspointInfo pi = new PasspointInfo();
+ pi.bssid = (String) in.readValue(String.class.getClassLoader());
+ pi.venueName = (String) in.readValue(String.class.getClassLoader());
+ // TODO
+ return pi;
+ }
+
+ @Override
+ public PasspointInfo[] newArray(int size) {
+ return new PasspointInfo[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointManager.java b/wifi/java/android/net/wifi/passpoint/PasspointManager.java
new file mode 100644
index 0000000..f32536f
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointManager.java
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.Protocol;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * TODO: doc
+ */
+public class PasspointManager {
+
+ private static final String TAG = "PasspointManager";
+
+ private static final boolean DBG = true;
+
+ /* Passpoint states values */
+
+ /** Passpoint is in an known state. This should only occur in boot time */
+ public static final int PASSPOINT_STATE_UNKNOWN = 0;
+
+ /** Passpoint is disabled. This occurs when wifi is disabled. */
+ public static final int PASSPOINT_STATE_DISABLED = 1;
+
+ /** Passpoint is enabled and in discovery state. */
+ public static final int PASSPOINT_STATE_DISCOVERY = 2;
+
+ /** Passpoint is enabled and in access state. */
+ public static final int PASSPOINT_STATE_ACCESS = 3;
+
+ /** Passpoint is enabled and in provisioning state. */
+ public static final int PASSPOINT_STATE_PROVISION = 4;
+
+ /* Passpoint callback error codes */
+
+ /** Indicates that the operation failed due to an internal error */
+ public static final int ERROR = 0;
+
+ /** Indicates that the operation failed because wifi is disabled */
+ public static final int WIFI_DISABLED = 1;
+
+ /** Indicates that the operation failed because the framework is busy */
+ public static final int BUSY = 2;
+
+ /* Passpoint broadcasts */
+
+ /**
+ * Broadcast intent action indicating that the state of Passpoint
+ * connectivity has changed
+ */
+ public static final String PASSPOINT_STATE_CHANGED_ACTION =
+ "android.net.wifi.passpoint.STATE_CHANGE";
+
+ /**
+ * Broadcast intent action indicating that the saved Passpoint credential
+ * list has changed
+ */
+ public static final String PASSPOINT_CRED_CHANGED_ACTION =
+ "android.net.wifi.passpoint.CRED_CHANGE";
+
+ /**
+ * Broadcast intent action indicating that Passpoint online sign up is
+ * avaiable.
+ * @hide
+ */
+ public static final String PASSPOINT_OSU_AVAILABLE_ACTION =
+ "android.net.wifi.passpoint.OSU_AVAILABLE";
+
+ /**
+ * Broadcast intent action indicating that user remediation is required
+ * @hide
+ */
+ public static final String PASSPOINT_USER_REM_REQ_ACTION =
+ "android.net.wifi.passpoint.USER_REM_REQ";
+
+
+ /**
+ * Interface for callback invocation when framework channel is lost
+ */
+ public interface ChannelListener {
+ /**
+ * The channel to the framework has been disconnected. Application could
+ * try re-initializing using {@link #initialize}
+ */
+ public void onChannelDisconnected();
+ }
+
+ /**
+ * Interface for callback invocation on an application action
+ */
+ public interface ActionListener {
+ /** The operation succeeded */
+ public void onSuccess();
+
+ /**
+ * * The operation failed
+ *
+ * @param reason The reason for failure could be one of
+ * {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
+ */
+ public void onFailure(int reason);
+ }
+
+ /**
+ * Interface for callback invocation when doing OSU or user remediation
+ * @hide
+ */
+ public interface OsuRemListener {
+ /** The operation succeeded */
+ public void onSuccess();
+
+ /**
+ * The operation failed
+ *
+ * @param reason The reason for failure could be one of
+ * {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
+ */
+ public void onFailure(int reason);
+
+ /**
+ * Browser launch is requried for user interaction. When this callback
+ * is called, app should launch browser / webview to the given URL.
+ *
+ * @param url URL for browser launch
+ */
+ public void onBrowserLaunch(String url);
+
+ /**
+ * When this is called, app should dismiss the previously lanched browser.
+ */
+ public void onBrowserDismiss();
+ }
+
+ /**
+ * A channel that connects the application to the wifi passpoint framework.
+ * Most passpoint operations require a Channel as an argument.
+ * An instance of Channel is obtained by doing a call on {@link #initialize}
+ */
+ public static class Channel {
+ private final static int INVALID_LISTENER_KEY = 0;
+
+ private ChannelListener mChannelListener;
+
+ private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
+ private HashMap<Integer, Integer> mListenerMapCount = new HashMap<Integer, Integer>();
+ private Object mListenerMapLock = new Object();
+ private int mListenerKey = 0;
+
+ private List<ScanResult> mAnqpRequest = new LinkedList<ScanResult>();
+ private Object mAnqpRequestLock = new Object();
+
+ private AsyncChannel mAsyncChannel;
+ private PasspointHandler mHandler;
+ Context mContext;
+
+ Channel(Context context, Looper looper, ChannelListener l) {
+ mAsyncChannel = new AsyncChannel();
+ mHandler = new PasspointHandler(looper);
+ mChannelListener = l;
+ mContext = context;
+ }
+
+ private int putListener(Object listener) {
+ return putListener(listener, 1);
+ }
+
+ private int putListener(Object listener, int count) {
+ if (listener == null || count <= 0) return INVALID_LISTENER_KEY;
+ int key;
+ synchronized (mListenerMapLock) {
+ do {
+ key = mListenerKey++;
+ } while (key == INVALID_LISTENER_KEY);
+ mListenerMap.put(key, listener);
+ mListenerMapCount.put(key, count);
+ }
+ return key;
+ }
+
+ private Object getListener(int key, boolean force) {
+ Log.d(TAG, "getListener() key=" + key + " force=" + force);
+ if (key == INVALID_LISTENER_KEY) return null;
+ synchronized (mListenerMapLock) {
+ if (!force) {
+ int count = mListenerMapCount.get(key);
+ Log.d(TAG, "count=" + count);
+ mListenerMapCount.put(key, --count);
+ if (count > 0) return null;
+ }
+ Log.d(TAG, "remove key");
+ mListenerMapCount.remove(key);
+ return mListenerMap.remove(key);
+ }
+ }
+
+ private void anqpRequestStart(ScanResult sr) {
+ Log.d(TAG, "anqpRequestStart sr.bssid=" + sr.BSSID);
+ synchronized(mAnqpRequestLock) { mAnqpRequest.add(sr); }
+ }
+
+ private void anqpRequestFinish(PasspointInfo pi) {
+ Log.d(TAG, "anqpRequestFinish pi.bssid=" + pi.bssid);
+ synchronized(mAnqpRequestLock) {
+ for (ScanResult sr : mAnqpRequest)
+ if (sr.BSSID.equals(pi.bssid)) {
+ Log.d(TAG, "find hit " + pi.bssid);
+ sr.passpoint = pi;
+ mAnqpRequest.remove(sr);
+ Log.d(TAG, "mAnqpRequest.len=" + mAnqpRequest.size());
+ break;
+ }
+ }
+ }
+
+ private void anqpRequestFinish(ScanResult sr) {
+ Log.d(TAG, "anqpRequestFinish sr.bssid=" + sr.BSSID);
+ synchronized(mAnqpRequestLock) {
+ for (ScanResult sr1 : mAnqpRequest)
+ if (sr1.BSSID.equals(sr.BSSID)) {
+ mAnqpRequest.remove(sr1);
+ break;
+ }
+ }
+ }
+
+ class PasspointHandler extends Handler {
+ PasspointHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ Object listener = getListener(message.arg2, false);
+ switch (message.what) {
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+ if (mChannelListener != null) {
+ mChannelListener.onChannelDisconnected();
+ mChannelListener = null;
+ }
+ break;
+
+ case REQUEST_ANQP_INFO_SUCCEEDED:
+ PasspointInfo pi = (PasspointInfo) message.obj;
+ anqpRequestFinish(pi);
+ if (listener != null) {
+ ((ActionListener) listener).onSuccess();
+ }
+ break;
+
+ case REQUEST_ANQP_INFO_FAILED:
+ anqpRequestFinish((ScanResult) message.obj);
+ if (listener == null) getListener(message.arg2, true);
+ if (listener != null) {
+ ((ActionListener) listener).onFailure(message.arg1);
+ }
+ break;
+
+ default:
+ Log.d(TAG, "Ignored " + message);
+ break;
+ }
+ }
+ }
+
+ }
+
+
+ private static final int BASE = Protocol.BASE_WIFI_PASSPOINT_MANAGER;
+
+ /** @hide */
+ public static final int REQUEST_ANQP_INFO = BASE + 1;
+
+ /** @hide */
+ public static final int REQUEST_ANQP_INFO_FAILED = BASE + 2;
+
+ /** @hide */
+ public static final int REQUEST_ANQP_INFO_SUCCEEDED = BASE + 3;
+
+ /** @hide */
+ public static final int REQUEST_OSU_INFO = BASE + 4;
+
+ /** @hide */
+ public static final int REQUEST_OSU_INFO_FAILED = BASE + 5;
+
+ /** @hide */
+ public static final int REQUEST_OSU_INFO_SUCCEEDED = BASE + 6;
+
+
+ private Context mContext;
+ IPasspointManager mService;
+
+
+ /**
+ * TODO: doc
+ * @param context
+ * @param service
+ */
+ public PasspointManager(Context context, IPasspointManager service) {
+ mContext = context;
+ mService = service;
+ }
+
+ /**
+ * Registers the application with the framework. This function must be the
+ * first to be called before any async passpoint operations are performed.
+ *
+ * @param srcContext is the context of the source
+ * @param srcLooper is the Looper on which the callbacks are receivied
+ * @param listener for callback at loss of framework communication. Can be
+ * null.
+ * @return Channel instance that is necessary for performing any further
+ * passpoint operations
+ */
+ public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
+ Messenger messenger = getMessenger();
+ if (messenger == null) return null;
+
+ Channel c = new Channel(srcContext, srcLooper, listener);
+ if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
+ == AsyncChannel.STATUS_SUCCESSFUL) {
+ return c;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * STOPSHIP: temp solution, should use supplicant manager instead, check
+ * with b/13931972
+ *
+ * @hide
+ */
+ public Messenger getMessenger() {
+ try {
+ return mService.getMessenger();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get Passpoint state.
+ *
+ * @return One of {@link #PASSPOINT_STATE_DISABLED},
+ * {@link #PASSPOINT_STATE_DISCOVERY},
+ * {@link #PASSPOINT_STATE_ACCESS},
+ * {@link #PASSPOINT_STATE_PROVISION},
+ * {@link #PASSPOINT_STATE_UNKNOWN}
+ */
+ public int getPasspointState() {
+ try{
+ return mService.getPasspointState();
+ }
+ catch (RemoteException e) {
+ return PASSPOINT_STATE_UNKNOWN;
+ }
+ }
+
+ /**
+ * TODO: doc
+ *
+ * @param c
+ * @param requested
+ * @param mask
+ * @param listener
+ *
+ * @hide
+ */
+ public void requestAnqpInfo(Channel c, List<ScanResult> requested, int mask,
+ ActionListener listener) {
+ checkChannel(c);
+ List<ScanResult> list = new ArrayList<ScanResult>();
+ for (ScanResult sr : requested) if (sr.capabilities.contains("[HS20]")) {
+ list.add(sr);
+ c.anqpRequestStart(sr);
+ }
+ int count = list.size();
+ if (count == 0) {
+ if (DBG) Log.d(TAG, "ANQP info request contains no HS20 APs, skipped");
+ listener.onSuccess();
+ return;
+ }
+ int key = c.putListener(listener, count);
+ for (ScanResult sr : list)
+ c.mAsyncChannel.sendMessage(REQUEST_ANQP_INFO, mask, key, sr);
+ }
+
+ /**
+ * TODO: doc
+ *
+ * @param c
+ * @param requested
+ * @param listener
+ */
+ public void requestOsuIcons(Channel c, List<PasspointOsuProvider> requested,
+ ActionListener listener) {
+ }
+
+ /* TODO: add credential APIs */
+
+ /**
+ * Give a list of all saved Passpoint credentials.
+ *
+ * @return The list of credentials
+ */
+ public List<PasspointCredential> getSavedCredentials() {
+ return null;
+ }
+
+ /**
+ * Add a new Passpoint credential.
+ *
+ * @param cred The credential to be added
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean addCredential(PasspointCredential cred) {
+ return true;
+ }
+
+ /**
+ * Update an existing Passpoint credential.
+ *
+ * @param cred The credential to be updated
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean updateCredential(PasspointCredential cred) {
+ return true;
+ }
+
+ /**
+ * Remove an existing Passpoint credential.
+ *
+ * @param cred The credential to be removed
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean removeCredential(PasspointCredential cred) {
+ return true;
+ }
+
+ /** @hide */
+ public void startOsu(Channel c, PasspointOsuProvider selected, OsuRemListener listener) {
+
+ }
+
+ /** @hide */
+ public void startUserRemediation(Channel c, OsuRemListener listener) {
+ }
+
+ /**
+ * Select and connect to a Passpoint network.
+ *
+ * @param policy Selected Passpoint network, see {@link PasspointPolicy}
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean connect(PasspointPolicy policy) {
+ return true;
+ }
+
+ private static void checkChannel(Channel c) {
+ if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
+ }
+}
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.aidl b/wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.aidl
new file mode 100644
index 0000000..f5ecb7c
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable PasspointOsuProvider;
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.java b/wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.java
new file mode 100644
index 0000000..b896307
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointOsuProvider.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * TODO: doc
+ */
+public class PasspointOsuProvider implements Parcelable {
+
+ /** TODO: doc */
+ public static final int OSU_METHOD_OMADM = 0;
+
+ /** TODO: doc */
+ public static final int OSU_METHOD_SOAP = 1;
+
+ /** TODO: doc */
+ public String SSID;
+
+ /** TODO: doc */
+ public String friendlyName;
+
+ /** TODO: doc */
+ public String serverUri;
+
+ /** TODO: doc */
+ public int osuMethod;
+
+ /** TODO: doc */
+ public String iconFileName;
+
+ /** TODO: doc */
+ public Object icon; // TODO: should change to image format
+
+ /** TODO: doc */
+ public String osuNai;
+
+ /** TODO: doc */
+ public String osuService;
+
+
+ /** default constructor @hide */
+ public PasspointOsuProvider() {
+ // TODO
+ }
+
+ /** copy constructor @hide */
+ public PasspointOsuProvider(PasspointOsuProvider source) {
+ // TODO
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // TODO
+ }
+
+ public static final Parcelable.Creator<PasspointOsuProvider> CREATOR =
+ new Parcelable.Creator<PasspointOsuProvider>() {
+ @Override
+ public PasspointOsuProvider createFromParcel(Parcel in) {
+ PasspointOsuProvider osu = new PasspointOsuProvider();
+ // TODO
+ return osu;
+ }
+
+ @Override
+ public PasspointOsuProvider[] newArray(int size) {
+ return new PasspointOsuProvider[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointPolicy.aidl b/wifi/java/android/net/wifi/passpoint/PasspointPolicy.aidl
new file mode 100644
index 0000000..c2cc731
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointPolicy.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable PasspointPolicy;
diff --git a/wifi/java/android/net/wifi/passpoint/PasspointPolicy.java b/wifi/java/android/net/wifi/passpoint/PasspointPolicy.java
new file mode 100644
index 0000000..3a8806b
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/PasspointPolicy.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+public class PasspointPolicy implements Parcelable {
+
+ @Override
+ public String toString() {
+ // TODO
+ return null;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // TODO
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<PasspointPolicy> CREATOR =
+ new Creator<PasspointPolicy>() {
+ @Override
+ public PasspointPolicy createFromParcel(Parcel in) {
+ return null;
+ }
+
+ @Override
+ public PasspointPolicy[] newArray(int size) {
+ return new PasspointPolicy[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiTree.aidl b/wifi/java/android/net/wifi/passpoint/WifiTree.aidl
new file mode 100644
index 0000000..8e2fab7
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiTree.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable WifiTree;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiTree.java b/wifi/java/android/net/wifi/passpoint/WifiTree.java
new file mode 100644
index 0000000..8fdb6e1
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiTree.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+/** @hide */
+public class WifiTree implements Parcelable {
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ // TODO
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Parcelable.Creator<WifiTree> CREATOR =
+ new Parcelable.Creator<WifiTree>() {
+ @Override
+ public WifiTree createFromParcel(Parcel in) {
+ // TODO
+ return null;
+ }
+
+ @Override
+ public WifiTree[] newArray(int size) {
+ return new WifiTree[size];
+ }
+ };
+}