Merge "Fix naming of key"
diff --git a/api/current.txt b/api/current.txt
index 86b2119..dbe8399 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -60758,31 +60758,31 @@
ctor public CopyOnWriteArrayList();
ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
ctor public CopyOnWriteArrayList(E[]);
- method public synchronized boolean add(E);
- method public synchronized void add(int, E);
- method public synchronized boolean addAll(java.util.Collection<? extends E>);
- method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
- method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
- method public synchronized boolean addIfAbsent(E);
- method public synchronized void clear();
+ method public boolean add(E);
+ method public void add(int, E);
+ method public boolean addAll(java.util.Collection<? extends E>);
+ method public boolean addAll(int, java.util.Collection<? extends E>);
+ method public int addAllAbsent(java.util.Collection<? extends E>);
+ method public boolean addIfAbsent(E);
+ method public void clear();
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
- method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
+ method public int indexOf(E, int);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
- method public int lastIndexOf(E, int);
method public int lastIndexOf(java.lang.Object);
- method public java.util.ListIterator<E> listIterator(int);
+ method public int lastIndexOf(E, int);
method public java.util.ListIterator<E> listIterator();
- method public synchronized E remove(int);
- method public synchronized boolean remove(java.lang.Object);
- method public synchronized boolean removeAll(java.util.Collection<?>);
- method public synchronized boolean retainAll(java.util.Collection<?>);
- method public synchronized E set(int, E);
+ method public java.util.ListIterator<E> listIterator(int);
+ method public E remove(int);
+ method public boolean remove(java.lang.Object);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public E set(int, E);
method public int size();
method public java.util.List<E> subList(int, int);
method public java.lang.Object[] toArray();
diff --git a/api/system-current.txt b/api/system-current.txt
index 36c81d8..6d8b280 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -63,7 +63,7 @@
field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
field public static final java.lang.String BODY_SENSORS = "android.permission.BODY_SENSORS";
field public static final java.lang.String BRICK = "android.permission.BRICK";
- field public static final java.lang.String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED";
+ field public static final deprecated java.lang.String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED";
field public static final java.lang.String BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";
field public static final java.lang.String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
field public static final java.lang.String BROADCAST_STICKY = "android.permission.BROADCAST_STICKY";
@@ -197,6 +197,7 @@
field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
+ field public static final java.lang.String REQUEST_NETWORK_SCORES = "android.permission.REQUEST_NETWORK_SCORES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
field public static final java.lang.String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
@@ -25833,10 +25834,16 @@
ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve);
ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve, boolean);
ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve, boolean, android.os.Bundle);
+ method public int calculateBadge(int);
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
+ field public static final java.lang.String ATTRIBUTES_KEY_BADGING_CURVE = "android.net.attributes.key.BADGING_CURVE";
field public static final java.lang.String ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL = "android.net.attributes.key.HAS_CAPTIVE_PORTAL";
field public static final java.lang.String ATTRIBUTES_KEY_RANKING_SCORE_OFFSET = "android.net.attributes.key.RANKING_SCORE_OFFSET";
+ field public static final int BADGING_4K = 30; // 0x1e
+ field public static final int BADGING_HD = 20; // 0x14
+ field public static final int BADGING_NONE = 0; // 0x0
+ field public static final int BADGING_SD = 10; // 0xa
field public static final android.os.Parcelable.Creator<android.net.ScoredNetwork> CREATOR;
field public final android.os.Bundle attributes;
field public final boolean meteredHint;
@@ -25844,6 +25851,9 @@
field public final android.net.RssiCurve rssiCurve;
}
+ public static abstract class ScoredNetwork.Badging implements java.lang.annotation.Annotation {
+ }
+
public class TrafficStats {
ctor public TrafficStats();
method public static void clearThreadStatsTag();
@@ -26852,6 +26862,8 @@
public class WifiConfiguration implements android.os.Parcelable {
ctor public WifiConfiguration();
method public int describeContents();
+ method public boolean hasNoInternetAccess();
+ method public boolean isNoInternetAccessExpected();
method public boolean isPasspoint();
method public void writeToParcel(android.os.Parcel, int);
field public java.lang.String BSSID;
@@ -64338,31 +64350,31 @@
ctor public CopyOnWriteArrayList();
ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
ctor public CopyOnWriteArrayList(E[]);
- method public synchronized boolean add(E);
- method public synchronized void add(int, E);
- method public synchronized boolean addAll(java.util.Collection<? extends E>);
- method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
- method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
- method public synchronized boolean addIfAbsent(E);
- method public synchronized void clear();
+ method public boolean add(E);
+ method public void add(int, E);
+ method public boolean addAll(java.util.Collection<? extends E>);
+ method public boolean addAll(int, java.util.Collection<? extends E>);
+ method public int addAllAbsent(java.util.Collection<? extends E>);
+ method public boolean addIfAbsent(E);
+ method public void clear();
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
- method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
+ method public int indexOf(E, int);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
- method public int lastIndexOf(E, int);
method public int lastIndexOf(java.lang.Object);
- method public java.util.ListIterator<E> listIterator(int);
+ method public int lastIndexOf(E, int);
method public java.util.ListIterator<E> listIterator();
- method public synchronized E remove(int);
- method public synchronized boolean remove(java.lang.Object);
- method public synchronized boolean removeAll(java.util.Collection<?>);
- method public synchronized boolean retainAll(java.util.Collection<?>);
- method public synchronized E set(int, E);
+ method public java.util.ListIterator<E> listIterator(int);
+ method public E remove(int);
+ method public boolean remove(java.lang.Object);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public E set(int, E);
method public int size();
method public java.util.List<E> subList(int, int);
method public java.lang.Object[] toArray();
diff --git a/api/test-current.txt b/api/test-current.txt
index e3a395b..ea7e58a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -60849,31 +60849,31 @@
ctor public CopyOnWriteArrayList();
ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
ctor public CopyOnWriteArrayList(E[]);
- method public synchronized boolean add(E);
- method public synchronized void add(int, E);
- method public synchronized boolean addAll(java.util.Collection<? extends E>);
- method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
- method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
- method public synchronized boolean addIfAbsent(E);
- method public synchronized void clear();
+ method public boolean add(E);
+ method public void add(int, E);
+ method public boolean addAll(java.util.Collection<? extends E>);
+ method public boolean addAll(int, java.util.Collection<? extends E>);
+ method public int addAllAbsent(java.util.Collection<? extends E>);
+ method public boolean addIfAbsent(E);
+ method public void clear();
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
- method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
+ method public int indexOf(E, int);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
- method public int lastIndexOf(E, int);
method public int lastIndexOf(java.lang.Object);
- method public java.util.ListIterator<E> listIterator(int);
+ method public int lastIndexOf(E, int);
method public java.util.ListIterator<E> listIterator();
- method public synchronized E remove(int);
- method public synchronized boolean remove(java.lang.Object);
- method public synchronized boolean removeAll(java.util.Collection<?>);
- method public synchronized boolean retainAll(java.util.Collection<?>);
- method public synchronized E set(int, E);
+ method public java.util.ListIterator<E> listIterator(int);
+ method public E remove(int);
+ method public boolean remove(java.lang.Object);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public E set(int, E);
method public int size();
method public java.util.List<E> subList(int, int);
method public java.lang.Object[] toArray();
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index 5cc1277..52cd2de 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -47,7 +47,14 @@
public static final String EXTRA_PREVIOUS_CODEC_CONFIG =
"android.bluetooth.codec.extra.PREVIOUS_CODEC_CONFIG";
+ // Add an entry for each source codec here.
+ // NOTE: The values should be same as those listed in the following file:
+ // hardware/libhardware/include/hardware/bt_av.h
public static final int SOURCE_CODEC_TYPE_SBC = 0;
+ public static final int SOURCE_CODEC_TYPE_APTX = 1;
+ public static final int SOURCE_CODEC_TYPE_APTX_HD = 2;
+ public static final int SOURCE_CODEC_TYPE_LDAC = 3;
+
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
public static final int CODEC_PRIORITY_DEFAULT = 0;
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
index 3f8d9d3..d9ad74b 100644
--- a/core/java/android/net/LocalSocket.java
+++ b/core/java/android/net/LocalSocket.java
@@ -73,6 +73,7 @@
this(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
isBound = true;
isConnected = true;
+ implCreated = true;
}
private LocalSocket(LocalSocketImpl impl, int sockType) {
@@ -223,11 +224,11 @@
implCreateIfNeeded();
impl.shutdownOutput();
}
-
+
public void setReceiveBufferSize(int size) throws IOException {
impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
}
-
+
public int getReceiveBufferSize() throws IOException {
return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue();
}
@@ -235,7 +236,7 @@
public void setSoTimeout(int n) throws IOException {
impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(n));
}
-
+
public int getSoTimeout() throws IOException {
return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
}
@@ -243,7 +244,7 @@
public void setSendBufferSize(int n) throws IOException {
impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(n));
}
-
+
public int getSendBufferSize() throws IOException {
return ((Integer) impl.getOption(SocketOptions.SO_SNDBUF)).intValue();
}
@@ -328,5 +329,5 @@
*/
public FileDescriptor getFileDescriptor() {
return impl.getFileDescriptor();
- }
+ }
}
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 1825956..9a6dca0 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -27,7 +27,6 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserHandle;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -44,19 +43,11 @@
* <p>A network scorer is any application which:
* <ul>
* <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
- * <li>Includes a receiver for {@link #ACTION_SCORE_NETWORKS} guarded by the
- * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission which scores
- * networks and (eventually) calls {@link #updateScores} with the results. If this receiver
- * specifies an android:label attribute, this label will be used when referring to the
- * application throughout system settings; otherwise, the application label will be used.
+ * <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action
+ * protected by the {@link android.Manifest.permission#BIND_NETWORK_RECOMMENDATION_SERVICE}
+ * permission.
* </ul>
*
- * <p>The system keeps track of an active scorer application; at any time, only this application
- * will receive {@link #ACTION_SCORE_NETWORKS} broadcasts and will be permitted to call
- * {@link #updateScores}. Applications may determine the current active scorer with
- * {@link #getActiveScorerPackage()} and request to change the active scorer by sending an
- * {@link #ACTION_CHANGE_ACTIVE} broadcast with another scorer.
- *
* @hide
*/
@SystemApi
@@ -263,12 +254,9 @@
/**
* Request scoring for networks.
*
- * <p>Note that this is just a helper method to assemble the broadcast, and will run in the
- * calling process.
- *
* @return true if the broadcast was sent, or false if there is no active scorer.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
+ * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
* @hide
*/
public boolean requestScores(NetworkKey[] networks) throws SecurityException {
@@ -285,7 +273,7 @@
* @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
+ * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
* @throws IllegalArgumentException if a score cache is already registered for this type.
* @deprecated equivalent to registering for cache updates with CACHE_FILTER_NONE.
* @hide
@@ -302,7 +290,7 @@
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores
* @param filterType the {@link CacheUpdateFilter} to apply
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
+ * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
* @throws IllegalArgumentException if a score cache is already registered for this type.
* @hide
*/
@@ -321,7 +309,7 @@
* @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
+ * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
* @throws IllegalArgumentException if a score cache is already registered for this type.
* @hide
*/
@@ -342,7 +330,8 @@
* request details
* @return a {@link RecommendationResult} instance containing the recommended network
* to connect to
- * @throws SecurityException
+ * @throws SecurityException if the caller does not hold the
+ * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
*/
public RecommendationResult requestRecommendation(RecommendationRequest request)
throws SecurityException {
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 4282ca7..ec0bb25d 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -231,13 +231,7 @@
if (defaultApp == null) {
return false;
}
- if (callingUid != defaultApp.packageUid) {
- return false;
- }
- // To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always
- // should, since it couldn't become the active scorer otherwise, but this can't hurt.
- return mContext.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) ==
- PackageManager.PERMISSION_GRANTED;
+ return callingUid == defaultApp.packageUid;
}
private boolean isNetworkRecommendationsDisabled() {
diff --git a/core/java/android/net/ScoredNetwork.java b/core/java/android/net/ScoredNetwork.java
index 94e5187..7e3dd77 100644
--- a/core/java/android/net/ScoredNetwork.java
+++ b/core/java/android/net/ScoredNetwork.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Bundle;
@@ -24,6 +25,8 @@
import java.lang.Math;
import java.lang.UnsupportedOperationException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -33,6 +36,15 @@
*/
@SystemApi
public class ScoredNetwork implements Parcelable {
+
+ /**
+ * Key used with the {@link #attributes} bundle to define the badging curve.
+ *
+ * <p>The badging curve is a {@link RssiCurve} used to map different RSSI values to {@link
+ * Badging} enums.
+ */
+ public static final String ATTRIBUTES_KEY_BADGING_CURVE =
+ "android.net.attributes.key.BADGING_CURVE";
/**
* Extra used with {@link #attributes} to specify whether the
* network is believed to have a captive portal.
@@ -58,6 +70,15 @@
public static final String ATTRIBUTES_KEY_RANKING_SCORE_OFFSET =
"android.net.attributes.key.RANKING_SCORE_OFFSET";
+ @IntDef({BADGING_NONE, BADGING_SD, BADGING_HD, BADGING_4K})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Badging {}
+
+ public static final int BADGING_NONE = 0;
+ public static final int BADGING_SD = 10;
+ public static final int BADGING_HD = 20;
+ public static final int BADGING_4K = 30;
+
/** A {@link NetworkKey} uniquely identifying this network. */
public final NetworkKey networkKey;
@@ -249,6 +270,25 @@
}
}
+ /**
+ * Return the {@link Badging} enum for this network for the given RSSI, derived from the
+ * badging curve.
+ *
+ * <p>If no badging curve is present, {@link #BADGE_NONE} will be returned.
+ *
+ * @param rssi The rssi level for which the badge should be calculated
+ */
+ @Badging
+ public int calculateBadge(int rssi) {
+ if (attributes != null && attributes.containsKey(ATTRIBUTES_KEY_BADGING_CURVE)) {
+ RssiCurve badgingCurve =
+ attributes.getParcelable(ATTRIBUTES_KEY_BADGING_CURVE);
+ return badgingCurve.lookupScore(rssi);
+ }
+
+ return BADGING_NONE;
+ }
+
public static final Parcelable.Creator<ScoredNetwork> CREATOR =
new Parcelable.Creator<ScoredNetwork>() {
@Override
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index bcc3468..e025494 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -17,6 +17,7 @@
package android.os;
import java.util.ArrayList;
+import java.util.NoSuchElementException;
import libcore.util.NativeAllocationRegistry;
/** @hide */
@@ -44,11 +45,13 @@
public native final void registerService(
ArrayList<String> interfaceChain,
- String serviceName);
+ String serviceName)
+ throws RemoteException;
public static native final IHwBinder getService(
String iface,
- String serviceName);
+ String serviceName)
+ throws RemoteException, NoSuchElementException;
// Returns address of the "freeFunction".
private static native final long native_init();
diff --git a/core/java/android/os/IHwBinder.java b/core/java/android/os/IHwBinder.java
index 2a65679..619f4dc 100644
--- a/core/java/android/os/IHwBinder.java
+++ b/core/java/android/os/IHwBinder.java
@@ -37,6 +37,5 @@
}
public boolean linkToDeath(DeathRecipient recipient, long cookie);
-
public boolean unlinkToDeath(DeathRecipient recipient);
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index c5507b9..9252887 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -40,6 +40,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -49,6 +50,7 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
@@ -930,24 +932,38 @@
}
/** {@hide} */
- public long getPrimaryStorageSize() {
+ public static Pair<String, Long> getPrimaryStoragePathAndSize() {
for (String path : INTERNAL_STORAGE_SIZE_PATHS) {
final long numberBlocks = readLong(path);
if (numberBlocks > 0) {
- return numberBlocks * INTERNAL_STORAGE_SECTOR_SIZE;
+ return new Pair<>(path, Long.valueOf(numberBlocks * INTERNAL_STORAGE_SECTOR_SIZE));
}
}
- return 0;
+ return null;
}
- private long readLong(String path) {
+
+ /** {@hide} */
+ public long getPrimaryStorageSize() {
+ final Pair<String, Long> pair = getPrimaryStoragePathAndSize();
+ return pair == null ? 0 : pair.second.longValue();
+ }
+
+ private static long readLong(String path) {
try (final FileInputStream fis = new FileInputStream(path);
final BufferedReader reader = new BufferedReader(new InputStreamReader(fis));) {
return Long.parseLong(reader.readLine());
- } catch (Exception e) {
- Slog.w(TAG, "Could not read " + path, e);
+ } catch (FileNotFoundException e) {
+ // This is expected since we are trying to parse multiple paths.
+ Slog.i(TAG, "readLong(): Path doesn't exist: " + path + ": " + e);
return 0;
- }
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "readLong(): Could not parse " + path + ": " + e);
+ return 0;
+ } catch (Exception e) {
+ Slog.e(TAG, "readLong(): Unknown exception while opening " + path + ": " + e);
+ return 0;
+ }
}
/** @removed */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e52983e..3ea5dcb 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6498,7 +6498,8 @@
QS_TILES,
DOZE_ENABLED,
DOZE_PULSE_ON_PICK_UP,
- DOZE_PULSE_ON_DOUBLE_TAP
+ DOZE_PULSE_ON_DOUBLE_TAP,
+ NFC_PAYMENT_DEFAULT_COMPONENT
};
/**
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 2e0729b..67196ca 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -75,17 +75,6 @@
private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
/**
- * System property used to enable or disable dirty regions invalidation.
- * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
- * The default value of this property is assumed to be true.
- *
- * Possible values:
- * "true", to enable partial invalidates
- * "false", to disable partial invalidates
- */
- static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions";
-
- /**
* System property used to enable or disable hardware rendering profiling.
* The default value of this property is assumed to be false.
*
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index e0d589a..2d6f443 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -24,6 +24,8 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -38,70 +40,104 @@
private static final String WEBVIEW_ZYGOTE_SERVICE_32 = "webview_zygote32";
private static final String WEBVIEW_ZYGOTE_SERVICE_64 = "webview_zygote64";
+ /**
+ * Lock object that protects all other static members.
+ */
+ private static final Object sLock = new Object();
+
+ /**
+ * Instance that maintains the socket connection to the zygote. This is null if the zygote
+ * is not running or is not connected.
+ */
+ @GuardedBy("sLock")
private static ZygoteProcess sZygote;
+ /**
+ * Information about the selected WebView package. This is set from #onWebViewProviderChanged().
+ */
+ @GuardedBy("sLock")
private static PackageInfo sPackage;
+ /**
+ * Flag for whether multi-process WebView is enabled. If this is false, the zygote
+ * will not be started.
+ */
+ @GuardedBy("sLock")
private static boolean sMultiprocessEnabled = false;
public static ZygoteProcess getProcess() {
- connectToZygoteIfNeeded();
- return sZygote;
+ synchronized (sLock) {
+ connectToZygoteIfNeededLocked();
+ return sZygote;
+ }
}
public static String getPackageName() {
- return sPackage.packageName;
+ synchronized (sLock) {
+ return sPackage.packageName;
+ }
}
public static boolean isMultiprocessEnabled() {
- return sMultiprocessEnabled && sPackage != null;
+ synchronized (sLock) {
+ return sMultiprocessEnabled && sPackage != null;
+ }
}
public static void setMultiprocessEnabled(boolean enabled) {
- sMultiprocessEnabled = enabled;
+ synchronized (sLock) {
+ sMultiprocessEnabled = enabled;
- // When toggling between multi-process being on/off, start or stop the
- // service. If it is enabled and the zygote is not yet started, bring up the service.
- // Otherwise, bring down the service. The name may be null if the package
- // information has not yet been resolved.
- final String serviceName = getServiceName();
- if (serviceName == null) return;
+ // When toggling between multi-process being on/off, start or stop the
+ // service. If it is enabled and the zygote is not yet started, bring up the service.
+ // Otherwise, bring down the service. The name may be null if the package
+ // information has not yet been resolved.
+ final String serviceName = getServiceNameLocked();
+ if (serviceName == null) return;
- if (enabled && sZygote == null) {
- SystemService.start(serviceName);
- } else {
- SystemService.stop(serviceName);
- sZygote = null;
+ if (enabled && sZygote == null) {
+ SystemService.start(serviceName);
+ } else {
+ SystemService.stop(serviceName);
+ sZygote = null;
+ }
}
}
public static void onWebViewProviderChanged(PackageInfo packageInfo) {
- sPackage = packageInfo;
+ String serviceName;
+ synchronized (sLock) {
+ sPackage = packageInfo;
- // If multi-process is not enabled, then do not start the zygote service.
- if (!sMultiprocessEnabled) {
- return;
+ // If multi-process is not enabled, then do not start the zygote service.
+ if (!sMultiprocessEnabled) {
+ return;
+ }
+
+ serviceName = getServiceNameLocked();
+ sZygote = null;
+
+ // The service may enter the RUNNING state before it opens the socket,
+ // so connectToZygoteIfNeededLocked() may still fail.
+ if (SystemService.isStopped(serviceName)) {
+ SystemService.start(serviceName);
+ } else {
+ SystemService.restart(serviceName);
+ }
+
+ try {
+ SystemService.waitForState(serviceName, SystemService.State.RUNNING, 5000);
+ } catch (TimeoutException e) {
+ Log.e(LOGTAG, "Timed out waiting for " + serviceName);
+ return;
+ }
+
+ connectToZygoteIfNeededLocked();
}
-
- final String serviceName = getServiceName();
-
- if (SystemService.isStopped(serviceName)) {
- SystemService.start(serviceName);
- } else if (sZygote != null) {
- SystemService.restart(serviceName);
- }
-
- try {
- SystemService.waitForState(serviceName, SystemService.State.RUNNING, 5000);
- } catch (TimeoutException e) {
- Log.e(LOGTAG, "Timed out waiting for " + serviceName);
- return;
- }
-
- connectToZygoteIfNeeded();
}
- private static String getServiceName() {
+ @GuardedBy("sLock")
+ private static String getServiceNameLocked() {
if (sPackage == null)
return null;
@@ -113,7 +149,8 @@
return WEBVIEW_ZYGOTE_SERVICE_32;
}
- private static void connectToZygoteIfNeeded() {
+ @GuardedBy("sLock")
+ private static void connectToZygoteIfNeededLocked() {
if (sZygote != null)
return;
@@ -122,7 +159,7 @@
return;
}
- final String serviceName = getServiceName();
+ final String serviceName = getServiceNameLocked();
if (!SystemService.isRunning(serviceName)) {
Log.e(LOGTAG, serviceName + " is not running");
return;
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index d968e3c..a8a5549 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -62,6 +62,9 @@
ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader(
packagePath, libsPath);
+ // Add the APK to the Zygote's list of allowed files for children.
+ Zygote.nativeAllowFileAcrossFork(packagePath);
+
// Once we have the classloader, look up the WebViewFactoryProvider implementation and
// call preloadInZygote() on it to give it the opportunity to preload the native library
// and perform any other initialisation work that should be shared among the children.
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index fc0ccb7..293de3d 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -153,6 +153,11 @@
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
/**
+ * Lets children of the zygote inherit open file descriptors to this path.
+ */
+ native protected static void nativeAllowFileAcrossFork(String path);
+
+ /**
* Zygote unmount storage space on initializing.
* This method is called once.
*/
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 70e9004..d9d06c5 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -179,6 +179,7 @@
com_android_internal_util_VirtualRefBasePtr.cpp \
com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp \
hwbinder/EphemeralStorage.cpp \
+ fd_utils.cpp \
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/include \
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
index 8eb39e1..fbccfd5 100644
--- a/core/jni/android_hardware_location_ContextHubService.cpp
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -33,6 +33,7 @@
#include <unordered_map>
#include <queue>
+#include <android-base/macros.h>
#include <cutils/log.h>
#include "JNIHelp.h"
@@ -704,10 +705,10 @@
}
jbyteArray jmsg = env->NewByteArray(msgLen);
- jintArray jheader = env->NewIntArray(sizeof(header));
+ jintArray jheader = env->NewIntArray(arraysize(header));
env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
- env->SetIntArrayRegion(jheader, 0, sizeof(header), (jint *)header);
+ env->SetIntArrayRegion(jheader, 0, arraysize(header), (jint *)header);
ALOGI("Passing msg type %" PRIu32 " from app %" PRIu32 " from hub %" PRIu32,
header[HEADER_FIELD_MSG_TYPE], header[HEADER_FIELD_APP_INSTANCE],
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index c456d62..20bb885 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -39,6 +39,8 @@
using android::AndroidRuntime;
using android::hardware::hidl_vec;
using android::hardware::hidl_string;
+template<typename T>
+using Return = android::hardware::Return<T>;
#define PACKAGE_PATH "android/os"
#define CLASS_NAME "HwBinder"
@@ -257,8 +259,6 @@
hidl_vec<hidl_string> interfaceChain;
interfaceChain.setToExternal(strings, numInterfaces, true /* shouldOwn */);
- using android::hidl::manager::V1_0::IServiceManager;
-
sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz);
/* TODO(b/33440494) this is not right */
@@ -268,24 +268,23 @@
if (manager == nullptr) {
LOG(ERROR) << "Could not get hwservicemanager.";
- signalExceptionForError(env, UNKNOWN_ERROR);
+ signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
return;
}
- bool ok = manager->add(
- interfaceChain,
- serviceName,
- base);
+ Return<bool> ret = manager->add(interfaceChain, serviceName, base);
env->ReleaseStringUTFChars(serviceNameObj, serviceName);
serviceName = NULL;
+ bool ok = ret.isOk() && ret;
+
if (ok) {
LOG(INFO) << "Starting thread pool.";
::android::hardware::ProcessState::self()->startThreadPool();
}
- signalExceptionForError(env, (ok ? OK : UNKNOWN_ERROR));
+ signalExceptionForError(env, (ok ? OK : UNKNOWN_ERROR), true /* canThrowRemoteException */);
}
static jobject JHwBinder_native_getService(
@@ -321,19 +320,18 @@
if (manager == nullptr) {
LOG(ERROR) << "Could not get hwservicemanager.";
- signalExceptionForError(env, UNKNOWN_ERROR);
+ signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
return NULL;
}
- sp<hardware::IBinder> service;
- manager->get(
- ifaceName,
- serviceName,
- [&service](sp<hidl::base::V1_0::IBase> out) {
- service = hardware::toBinder<
- hidl::base::V1_0::IBase, hidl::base::V1_0::BpBase
- >(out);
- });
+ Return<sp<hidl::base::V1_0::IBase>> ret = manager->get(ifaceName, serviceName);
+
+ if (!ret.isOk()) {
+ signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
+ }
+
+ sp<hardware::IBinder> service = hardware::toBinder<
+ hidl::base::V1_0::IBase, hidl::base::V1_0::BpBase>(ret);
env->ReleaseStringUTFChars(ifaceNameObj, ifaceName);
ifaceName = NULL;
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index fec8f4e..94935cc 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -56,7 +56,7 @@
#include "ScopedLocalRef.h"
#include "ScopedPrimitiveArray.h"
#include "ScopedUtfChars.h"
-#include "fd_utils-inl.h"
+#include "fd_utils.h"
#include "nativebridge/native_bridge.h"
@@ -684,6 +684,16 @@
return pid;
}
+static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork(
+ JNIEnv* env, jclass, jstring path) {
+ ScopedUtfChars path_native(env, path);
+ const char* path_cstr = path_native.c_str();
+ if (!path_cstr) {
+ RuntimeAbort(env, __LINE__, "path_cstr == NULL");
+ }
+ FileDescriptorWhitelist::Get()->Allow(path_cstr);
+}
+
static void com_android_internal_os_Zygote_nativeUnmountStorageOnInit(JNIEnv* env, jclass) {
// Zygote process unmount root storage space initially before every child processes are forked.
// Every forked child processes (include SystemServer) only mount their own root storage space
@@ -728,6 +738,8 @@
(void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
(void *) com_android_internal_os_Zygote_nativeForkSystemServer },
+ { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
+ (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork },
{ "nativeUnmountStorageOnInit", "()V",
(void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit }
};
diff --git a/core/jni/fd_utils-inl.h b/core/jni/fd_utils-inl.h
deleted file mode 100644
index b78b8ff..0000000
--- a/core/jni/fd_utils-inl.h
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#include <string>
-#include <unordered_map>
-#include <set>
-#include <vector>
-#include <algorithm>
-
-#include <android-base/strings.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <inttypes.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <cutils/log.h>
-#include "JNIHelp.h"
-#include "ScopedPrimitiveArray.h"
-
-// Whitelist of open paths that the zygote is allowed to keep open.
-//
-// In addition to the paths listed here, all files ending with
-// ".jar" under /system/framework" are whitelisted. See
-// FileDescriptorInfo::IsWhitelisted for the canonical definition.
-//
-// If the whitelisted path is associated with a regular file or a
-// character device, the file is reopened after a fork with the same
-// offset and mode. If the whilelisted path is associated with a
-// AF_UNIX socket, the socket will refer to /dev/null after each
-// fork, and all operations on it will fail.
-static const char* kPathWhitelist[] = {
- "/dev/null",
- "/dev/socket/zygote",
- "/dev/socket/zygote_secondary",
- "/dev/socket/webview_zygote",
- "/sys/kernel/debug/tracing/trace_marker",
- "/system/framework/framework-res.apk",
- "/dev/urandom",
- "/dev/ion",
- "/dev/dri/renderD129", // Fixes b/31172436
-};
-
-static const char* kFdPath = "/proc/self/fd";
-
-// Keeps track of all relevant information (flags, offset etc.) of an
-// open zygote file descriptor.
-class FileDescriptorInfo {
- public:
- // Create a FileDescriptorInfo for a given file descriptor. Returns
- // |NULL| if an error occurred.
- static FileDescriptorInfo* createFromFd(int fd) {
- struct stat f_stat;
- // This should never happen; the zygote should always have the right set
- // of permissions required to stat all its open files.
- if (TEMP_FAILURE_RETRY(fstat(fd, &f_stat)) == -1) {
- ALOGE("Unable to stat fd %d : %s", fd, strerror(errno));
- return NULL;
- }
-
- if (S_ISSOCK(f_stat.st_mode)) {
- std::string socket_name;
- if (!GetSocketName(fd, &socket_name)) {
- return NULL;
- }
-
- if (!IsWhitelisted(socket_name)) {
- ALOGE("Socket name not whitelisted : %s (fd=%d)", socket_name.c_str(), fd);
- return NULL;
- }
-
- return new FileDescriptorInfo(fd);
- }
-
- // We only handle whitelisted regular files and character devices. Whitelisted
- // character devices must provide a guarantee of sensible behaviour when
- // reopened.
- //
- // S_ISDIR : Not supported. (We could if we wanted to, but it's unused).
- // S_ISLINK : Not supported.
- // S_ISBLK : Not supported.
- // S_ISFIFO : Not supported. Note that the zygote uses pipes to communicate
- // with the child process across forks but those should have been closed
- // before we got to this point.
- if (!S_ISCHR(f_stat.st_mode) && !S_ISREG(f_stat.st_mode)) {
- ALOGE("Unsupported st_mode %d", f_stat.st_mode);
- return NULL;
- }
-
- std::string file_path;
- if (!Readlink(fd, &file_path)) {
- return NULL;
- }
-
- if (!IsWhitelisted(file_path)) {
- ALOGE("Not whitelisted : %s", file_path.c_str());
- return NULL;
- }
-
- // File descriptor flags : currently on FD_CLOEXEC. We can set these
- // using F_SETFD - we're single threaded at this point of execution so
- // there won't be any races.
- const int fd_flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD));
- if (fd_flags == -1) {
- ALOGE("Failed fcntl(%d, F_GETFD) : %s", fd, strerror(errno));
- return NULL;
- }
-
- // File status flags :
- // - File access mode : (O_RDONLY, O_WRONLY...) we'll pass these through
- // to the open() call.
- //
- // - File creation flags : (O_CREAT, O_EXCL...) - there's not much we can
- // do about these, since the file has already been created. We shall ignore
- // them here.
- //
- // - Other flags : We'll have to set these via F_SETFL. On linux, F_SETFL
- // can only set O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK.
- // In particular, it can't set O_SYNC and O_DSYNC. We'll have to test for
- // their presence and pass them in to open().
- int fs_flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
- if (fs_flags == -1) {
- ALOGE("Failed fcntl(%d, F_GETFL) : %s", fd, strerror(errno));
- return NULL;
- }
-
- // File offset : Ignore the offset for non seekable files.
- const off_t offset = TEMP_FAILURE_RETRY(lseek64(fd, 0, SEEK_CUR));
-
- // We pass the flags that open accepts to open, and use F_SETFL for
- // the rest of them.
- static const int kOpenFlags = (O_RDONLY | O_WRONLY | O_RDWR | O_DSYNC | O_SYNC);
- int open_flags = fs_flags & (kOpenFlags);
- fs_flags = fs_flags & (~(kOpenFlags));
-
- return new FileDescriptorInfo(f_stat, file_path, fd, open_flags, fd_flags, fs_flags, offset);
- }
-
- // Checks whether the file descriptor associated with this object
- // refers to the same description.
- bool Restat() const {
- struct stat f_stat;
- if (TEMP_FAILURE_RETRY(fstat(fd, &f_stat)) == -1) {
- return false;
- }
-
- return f_stat.st_ino == stat.st_ino && f_stat.st_dev == stat.st_dev;
- }
-
- bool ReopenOrDetach() const {
- if (is_sock) {
- return DetachSocket();
- }
-
- // NOTE: This might happen if the file was unlinked after being opened.
- // It's a common pattern in the case of temporary files and the like but
- // we should not allow such usage from the zygote.
- const int new_fd = TEMP_FAILURE_RETRY(open(file_path.c_str(), open_flags));
-
- if (new_fd == -1) {
- ALOGE("Failed open(%s, %d) : %s", file_path.c_str(), open_flags, strerror(errno));
- return false;
- }
-
- if (TEMP_FAILURE_RETRY(fcntl(new_fd, F_SETFD, fd_flags)) == -1) {
- close(new_fd);
- ALOGE("Failed fcntl(%d, F_SETFD, %x) : %s", new_fd, fd_flags, strerror(errno));
- return false;
- }
-
- if (TEMP_FAILURE_RETRY(fcntl(new_fd, F_SETFL, fs_flags)) == -1) {
- close(new_fd);
- ALOGE("Failed fcntl(%d, F_SETFL, %x) : %s", new_fd, fs_flags, strerror(errno));
- return false;
- }
-
- if (offset != -1 && TEMP_FAILURE_RETRY(lseek64(new_fd, offset, SEEK_SET)) == -1) {
- close(new_fd);
- ALOGE("Failed lseek64(%d, SEEK_SET) : %s", new_fd, strerror(errno));
- return false;
- }
-
- if (TEMP_FAILURE_RETRY(dup2(new_fd, fd)) == -1) {
- close(new_fd);
- ALOGE("Failed dup2(%d, %d) : %s", fd, new_fd, strerror(errno));
- return false;
- }
-
- close(new_fd);
-
- return true;
- }
-
- const int fd;
- const struct stat stat;
- const std::string file_path;
- const int open_flags;
- const int fd_flags;
- const int fs_flags;
- const off_t offset;
- const bool is_sock;
-
- private:
- FileDescriptorInfo(int fd) :
- fd(fd),
- stat(),
- open_flags(0),
- fd_flags(0),
- fs_flags(0),
- offset(0),
- is_sock(true) {
- }
-
- FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
- int fd_flags, int fs_flags, off_t offset) :
- fd(fd),
- stat(stat),
- file_path(file_path),
- open_flags(open_flags),
- fd_flags(fd_flags),
- fs_flags(fs_flags),
- offset(offset),
- is_sock(false) {
- }
-
- // Returns true iff. a given path is whitelisted. A path is whitelisted
- // if it belongs to the whitelist (see kPathWhitelist) or if it's a path
- // under /system/framework that ends with ".jar" or if it is a system
- // framework overlay.
- static bool IsWhitelisted(const std::string& path) {
- for (size_t i = 0; i < (sizeof(kPathWhitelist) / sizeof(kPathWhitelist[0])); ++i) {
- if (kPathWhitelist[i] == path) {
- return true;
- }
- }
-
- static const char* kFrameworksPrefix = "/system/framework/";
- static const char* kJarSuffix = ".jar";
- if (android::base::StartsWith(path, kFrameworksPrefix)
- && android::base::EndsWith(path, kJarSuffix)) {
- return true;
- }
-
- // Whitelist files needed for Runtime Resource Overlay, like these:
- // /system/vendor/overlay/framework-res.apk
- // /system/vendor/overlay/PG/android-framework-runtime-resource-overlay.apk
- // /data/resource-cache/system@vendor@overlay@framework-res.apk@idmap
- // /data/resource-cache/system@vendor@overlay@PG@framework-res.apk@idmap
- static const char* kOverlayDir = "/system/vendor/overlay/";
- static const char* kApkSuffix = ".apk";
-
- if (android::base::StartsWith(path, kOverlayDir)
- && android::base::EndsWith(path, kApkSuffix)
- && path.find("/../") == std::string::npos) {
- return true;
- }
-
- static const char* kOverlayIdmapPrefix = "/data/resource-cache/";
- static const char* kOverlayIdmapSuffix = ".apk@idmap";
- if (android::base::StartsWith(path, kOverlayIdmapPrefix)
- && android::base::EndsWith(path, kOverlayIdmapSuffix)) {
- return true;
- }
-
- return false;
- }
-
- // TODO: Call android::base::Readlink instead of copying the code here.
- static bool Readlink(const int fd, std::string* result) {
- char path[64];
- snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
-
- // Code copied from android::base::Readlink starts here :
-
- // Annoyingly, the readlink system call returns EINVAL for a zero-sized buffer,
- // and truncates to whatever size you do supply, so it can't be used to query.
- // We could call lstat first, but that would introduce a race condition that
- // we couldn't detect.
- // ext2 and ext4 both have PAGE_SIZE limitations, so we assume that here.
- char buf[4096];
- ssize_t len = readlink(path, buf, sizeof(buf));
- if (len == -1) return false;
-
- result->assign(buf, len);
- return true;
- }
-
- // Returns the locally-bound name of the socket |fd|. Returns true
- // iff. all of the following hold :
- //
- // - the socket's sa_family is AF_UNIX.
- // - the length of the path is greater than zero (i.e, not an unnamed socket).
- // - the first byte of the path isn't zero (i.e, not a socket with an abstract
- // address).
- static bool GetSocketName(const int fd, std::string* result) {
- sockaddr_storage ss;
- sockaddr* addr = reinterpret_cast<sockaddr*>(&ss);
- socklen_t addr_len = sizeof(ss);
-
- if (TEMP_FAILURE_RETRY(getsockname(fd, addr, &addr_len)) == -1) {
- ALOGE("Failed getsockname(%d) : %s", fd, strerror(errno));
- return false;
- }
-
- if (addr->sa_family != AF_UNIX) {
- ALOGE("Unsupported socket (fd=%d) with family %d", fd, addr->sa_family);
- return false;
- }
-
- const sockaddr_un* unix_addr = reinterpret_cast<const sockaddr_un*>(&ss);
-
- size_t path_len = addr_len - offsetof(struct sockaddr_un, sun_path);
- // This is an unnamed local socket, we do not accept it.
- if (path_len == 0) {
- ALOGE("Unsupported AF_UNIX socket (fd=%d) with empty path.", fd);
- return false;
- }
-
- // This is a local socket with an abstract address, we do not accept it.
- if (unix_addr->sun_path[0] == '\0') {
- ALOGE("Unsupported AF_UNIX socket (fd=%d) with abstract address.", fd);
- return false;
- }
-
- // If we're here, sun_path must refer to a null terminated filesystem
- // pathname (man 7 unix). Remove the terminator before assigning it to an
- // std::string.
- if (unix_addr->sun_path[path_len - 1] == '\0') {
- --path_len;
- }
-
- result->assign(unix_addr->sun_path, path_len);
- return true;
- }
-
- bool DetachSocket() const {
- const int dev_null_fd = open("/dev/null", O_RDWR);
- if (dev_null_fd < 0) {
- ALOGE("Failed to open /dev/null : %s", strerror(errno));
- return false;
- }
-
- if (dup2(dev_null_fd, fd) == -1) {
- ALOGE("Failed dup2 on socket descriptor %d : %s", fd, strerror(errno));
- return false;
- }
-
- if (close(dev_null_fd) == -1) {
- ALOGE("Failed close(%d) : %s", dev_null_fd, strerror(errno));
- return false;
- }
-
- return true;
- }
-
- DISALLOW_COPY_AND_ASSIGN(FileDescriptorInfo);
-};
-
-// A FileDescriptorTable is a collection of FileDescriptorInfo objects
-// keyed by their FDs.
-class FileDescriptorTable {
- public:
- // Creates a new FileDescriptorTable. This function scans
- // /proc/self/fd for the list of open file descriptors and collects
- // information about them. Returns NULL if an error occurs.
- static FileDescriptorTable* Create() {
- DIR* d = opendir(kFdPath);
- if (d == NULL) {
- ALOGE("Unable to open directory %s: %s", kFdPath, strerror(errno));
- return NULL;
- }
- int dir_fd = dirfd(d);
- dirent* e;
-
- std::unordered_map<int, FileDescriptorInfo*> open_fd_map;
- while ((e = readdir(d)) != NULL) {
- const int fd = ParseFd(e, dir_fd);
- if (fd == -1) {
- continue;
- }
-
- FileDescriptorInfo* info = FileDescriptorInfo::createFromFd(fd);
- if (info == NULL) {
- if (closedir(d) == -1) {
- ALOGE("Unable to close directory : %s", strerror(errno));
- }
- return NULL;
- }
- open_fd_map[fd] = info;
- }
-
- if (closedir(d) == -1) {
- ALOGE("Unable to close directory : %s", strerror(errno));
- return NULL;
- }
- return new FileDescriptorTable(open_fd_map);
- }
-
- bool Restat() {
- std::set<int> open_fds;
-
- // First get the list of open descriptors.
- DIR* d = opendir(kFdPath);
- if (d == NULL) {
- ALOGE("Unable to open directory %s: %s", kFdPath, strerror(errno));
- return false;
- }
-
- int dir_fd = dirfd(d);
- dirent* e;
- while ((e = readdir(d)) != NULL) {
- const int fd = ParseFd(e, dir_fd);
- if (fd == -1) {
- continue;
- }
-
- open_fds.insert(fd);
- }
-
- if (closedir(d) == -1) {
- ALOGE("Unable to close directory : %s", strerror(errno));
- return false;
- }
-
- return RestatInternal(open_fds);
- }
-
- // Reopens all file descriptors that are contained in the table. Returns true
- // if all descriptors were successfully re-opened or detached, and false if an
- // error occurred.
- bool ReopenOrDetach() {
- std::unordered_map<int, FileDescriptorInfo*>::const_iterator it;
- for (it = open_fd_map_.begin(); it != open_fd_map_.end(); ++it) {
- const FileDescriptorInfo* info = it->second;
- if (info == NULL || !info->ReopenOrDetach()) {
- return false;
- }
- }
-
- return true;
- }
-
- private:
- FileDescriptorTable(const std::unordered_map<int, FileDescriptorInfo*>& map)
- : open_fd_map_(map) {
- }
-
- bool RestatInternal(std::set<int>& open_fds) {
- bool error = false;
-
- // Iterate through the list of file descriptors we've already recorded
- // and check whether :
- //
- // (a) they continue to be open.
- // (b) they refer to the same file.
- std::unordered_map<int, FileDescriptorInfo*>::iterator it = open_fd_map_.begin();
- while (it != open_fd_map_.end()) {
- std::set<int>::const_iterator element = open_fds.find(it->first);
- if (element == open_fds.end()) {
- // The entry from the file descriptor table is no longer in the list
- // of open files. We warn about this condition and remove it from
- // the list of FDs under consideration.
- //
- // TODO(narayan): This will be an error in a future android release.
- // error = true;
- // ALOGW("Zygote closed file descriptor %d.", it->first);
- it = open_fd_map_.erase(it);
- } else {
- // The entry from the file descriptor table is still open. Restat
- // it and check whether it refers to the same file.
- const bool same_file = it->second->Restat();
- if (!same_file) {
- // The file descriptor refers to a different description. We must
- // update our entry in the table.
- delete it->second;
- it->second = FileDescriptorInfo::createFromFd(*element);
- if (it->second == NULL) {
- // The descriptor no longer no longer refers to a whitelisted file.
- // We flag an error and remove it from the list of files we're
- // tracking.
- error = true;
- it = open_fd_map_.erase(it);
- } else {
- // Successfully restatted the file, move on to the next open FD.
- ++it;
- }
- } else {
- // It's the same file. Nothing to do here. Move on to the next open
- // FD.
- ++it;
- }
-
- // Finally, remove the FD from the set of open_fds. We do this last because
- // |element| will not remain valid after a call to erase.
- open_fds.erase(element);
- }
- }
-
- if (open_fds.size() > 0) {
- // The zygote has opened new file descriptors since our last inspection.
- // We warn about this condition and add them to our table.
- //
- // TODO(narayan): This will be an error in a future android release.
- // error = true;
- // ALOGW("Zygote opened %zd new file descriptor(s).", open_fds.size());
-
- // TODO(narayan): This code will be removed in a future android release.
- std::set<int>::const_iterator it;
- for (it = open_fds.begin(); it != open_fds.end(); ++it) {
- const int fd = (*it);
- FileDescriptorInfo* info = FileDescriptorInfo::createFromFd(fd);
- if (info == NULL) {
- // A newly opened file is not on the whitelist. Flag an error and
- // continue.
- error = true;
- } else {
- // Track the newly opened file.
- open_fd_map_[fd] = info;
- }
- }
- }
-
- return !error;
- }
-
- static int ParseFd(dirent* e, int dir_fd) {
- char* end;
- const int fd = strtol(e->d_name, &end, 10);
- if ((*end) != '\0') {
- return -1;
- }
-
- // Don't bother with the standard input/output/error, they're handled
- // specially post-fork anyway.
- if (fd <= STDERR_FILENO || fd == dir_fd) {
- return -1;
- }
-
- return fd;
- }
-
- // Invariant: All values in this unordered_map are non-NULL.
- std::unordered_map<int, FileDescriptorInfo*> open_fd_map_;
-
- DISALLOW_COPY_AND_ASSIGN(FileDescriptorTable);
-};
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
new file mode 100644
index 0000000..969d336f3
--- /dev/null
+++ b/core/jni/fd_utils.cpp
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "fd_utils.h"
+
+#include <algorithm>
+
+#include <fcntl.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <android-base/strings.h>
+#include <cutils/log.h>
+
+// Static whitelist of open paths that the zygote is allowed to keep open.
+static const char* kPathWhitelist[] = {
+ "/dev/null",
+ "/dev/socket/zygote",
+ "/dev/socket/zygote_secondary",
+ "/dev/socket/webview_zygote",
+ "/sys/kernel/debug/tracing/trace_marker",
+ "/system/framework/framework-res.apk",
+ "/dev/urandom",
+ "/dev/ion",
+ "/dev/dri/renderD129", // Fixes b/31172436
+};
+
+static const char kFdPath[] = "/proc/self/fd";
+
+// static
+FileDescriptorWhitelist* FileDescriptorWhitelist::Get() {
+ if (instance_ == nullptr) {
+ instance_ = new FileDescriptorWhitelist();
+ }
+ return instance_;
+}
+
+bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const {
+ // Check the static whitelist path.
+ for (const auto& whitelist_path : kPathWhitelist) {
+ if (path == whitelist_path)
+ return true;
+ }
+
+ // Check any paths added to the dynamic whitelist.
+ for (const auto& whitelist_path : whitelist_) {
+ if (path == whitelist_path)
+ return true;
+ }
+
+ static const std::string kFrameworksPrefix = "/system/framework/";
+ static const std::string kJarSuffix = ".jar";
+ if (StartsWith(path, kFrameworksPrefix) && EndsWith(path, kJarSuffix)) {
+ return true;
+ }
+
+ // Whitelist files needed for Runtime Resource Overlay, like these:
+ // /system/vendor/overlay/framework-res.apk
+ // /system/vendor/overlay-subdir/pg/framework-res.apk
+ // /vendor/overlay/framework-res.apk
+ // /vendor/overlay/PG/android-framework-runtime-resource-overlay.apk
+ // /data/resource-cache/system@vendor@overlay@framework-res.apk@idmap
+ // /data/resource-cache/system@vendor@overlay-subdir@pg@framework-res.apk@idmap
+ // See AssetManager.cpp for more details on overlay-subdir.
+ static const std::string kOverlayDir = "/system/vendor/overlay/";
+ static const std::string kVendorOverlayDir = "/vendor/overlay";
+ static const std::string kOverlaySubdir = "/system/vendor/overlay-subdir/";
+ static const std::string kApkSuffix = ".apk";
+
+ if ((StartsWith(path, kOverlayDir) || StartsWith(path, kOverlaySubdir)
+ || StartsWith(path, kVendorOverlayDir))
+ && EndsWith(path, kApkSuffix)
+ && path.find("/../") == std::string::npos) {
+ return true;
+ }
+
+ static const std::string kOverlayIdmapPrefix = "/data/resource-cache/";
+ static const std::string kOverlayIdmapSuffix = ".apk@idmap";
+ if (StartsWith(path, kOverlayIdmapPrefix) && EndsWith(path, kOverlayIdmapSuffix)
+ && path.find("/../") == std::string::npos) {
+ return true;
+ }
+
+ // All regular files that are placed under this path are whitelisted automatically.
+ static const std::string kZygoteWhitelistPath = "/vendor/zygote_whitelist/";
+ if (StartsWith(path, kZygoteWhitelistPath) && path.find("/../") == std::string::npos) {
+ return true;
+ }
+
+ return false;
+}
+
+FileDescriptorWhitelist::FileDescriptorWhitelist()
+ : whitelist_() {
+}
+
+// TODO: Call android::base::StartsWith instead of copying the code here.
+// static
+bool FileDescriptorWhitelist::StartsWith(const std::string& str,
+ const std::string& prefix) {
+ return str.compare(0, prefix.size(), prefix) == 0;
+}
+
+// TODO: Call android::base::EndsWith instead of copying the code here.
+// static
+bool FileDescriptorWhitelist::EndsWith(const std::string& str,
+ const std::string& suffix) {
+ if (suffix.size() > str.size()) {
+ return false;
+ }
+
+ return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+FileDescriptorWhitelist* FileDescriptorWhitelist::instance_ = nullptr;
+
+// static
+FileDescriptorInfo* FileDescriptorInfo::CreateFromFd(int fd) {
+ struct stat f_stat;
+ // This should never happen; the zygote should always have the right set
+ // of permissions required to stat all its open files.
+ if (TEMP_FAILURE_RETRY(fstat(fd, &f_stat)) == -1) {
+ ALOGE("Unable to stat fd %d : %s", fd, strerror(errno));
+ return NULL;
+ }
+
+ const FileDescriptorWhitelist* whitelist = FileDescriptorWhitelist::Get();
+
+ if (S_ISSOCK(f_stat.st_mode)) {
+ std::string socket_name;
+ if (!GetSocketName(fd, &socket_name)) {
+ return NULL;
+ }
+
+ if (!whitelist->IsAllowed(socket_name)) {
+ ALOGE("Socket name not whitelisted : %s (fd=%d)", socket_name.c_str(), fd);
+ return NULL;
+ }
+
+ return new FileDescriptorInfo(fd);
+ }
+
+ // We only handle whitelisted regular files and character devices. Whitelisted
+ // character devices must provide a guarantee of sensible behaviour when
+ // reopened.
+ //
+ // S_ISDIR : Not supported. (We could if we wanted to, but it's unused).
+ // S_ISLINK : Not supported.
+ // S_ISBLK : Not supported.
+ // S_ISFIFO : Not supported. Note that the zygote uses pipes to communicate
+ // with the child process across forks but those should have been closed
+ // before we got to this point.
+ if (!S_ISCHR(f_stat.st_mode) && !S_ISREG(f_stat.st_mode)) {
+ ALOGE("Unsupported st_mode %d", f_stat.st_mode);
+ return NULL;
+ }
+
+ std::string file_path;
+ if (!Readlink(fd, &file_path)) {
+ return NULL;
+ }
+
+ if (!whitelist->IsAllowed(file_path)) {
+ ALOGE("Not whitelisted : %s", file_path.c_str());
+ return NULL;
+ }
+
+ // File descriptor flags : currently on FD_CLOEXEC. We can set these
+ // using F_SETFD - we're single threaded at this point of execution so
+ // there won't be any races.
+ const int fd_flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD));
+ if (fd_flags == -1) {
+ ALOGE("Failed fcntl(%d, F_GETFD) : %s", fd, strerror(errno));
+ return NULL;
+ }
+
+ // File status flags :
+ // - File access mode : (O_RDONLY, O_WRONLY...) we'll pass these through
+ // to the open() call.
+ //
+ // - File creation flags : (O_CREAT, O_EXCL...) - there's not much we can
+ // do about these, since the file has already been created. We shall ignore
+ // them here.
+ //
+ // - Other flags : We'll have to set these via F_SETFL. On linux, F_SETFL
+ // can only set O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK.
+ // In particular, it can't set O_SYNC and O_DSYNC. We'll have to test for
+ // their presence and pass them in to open().
+ int fs_flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
+ if (fs_flags == -1) {
+ ALOGE("Failed fcntl(%d, F_GETFL) : %s", fd, strerror(errno));
+ return NULL;
+ }
+
+ // File offset : Ignore the offset for non seekable files.
+ const off_t offset = TEMP_FAILURE_RETRY(lseek64(fd, 0, SEEK_CUR));
+
+ // We pass the flags that open accepts to open, and use F_SETFL for
+ // the rest of them.
+ static const int kOpenFlags = (O_RDONLY | O_WRONLY | O_RDWR | O_DSYNC | O_SYNC);
+ int open_flags = fs_flags & (kOpenFlags);
+ fs_flags = fs_flags & (~(kOpenFlags));
+
+ return new FileDescriptorInfo(f_stat, file_path, fd, open_flags, fd_flags, fs_flags, offset);
+}
+
+bool FileDescriptorInfo::Restat() const {
+ struct stat f_stat;
+ if (TEMP_FAILURE_RETRY(fstat(fd, &f_stat)) == -1) {
+ return false;
+ }
+
+ return f_stat.st_ino == stat.st_ino && f_stat.st_dev == stat.st_dev;
+}
+
+bool FileDescriptorInfo::ReopenOrDetach() const {
+ if (is_sock) {
+ return DetachSocket();
+ }
+
+ // NOTE: This might happen if the file was unlinked after being opened.
+ // It's a common pattern in the case of temporary files and the like but
+ // we should not allow such usage from the zygote.
+ const int new_fd = TEMP_FAILURE_RETRY(open(file_path.c_str(), open_flags));
+
+ if (new_fd == -1) {
+ ALOGE("Failed open(%s, %d) : %s", file_path.c_str(), open_flags, strerror(errno));
+ return false;
+ }
+
+ if (TEMP_FAILURE_RETRY(fcntl(new_fd, F_SETFD, fd_flags)) == -1) {
+ close(new_fd);
+ ALOGE("Failed fcntl(%d, F_SETFD, %x) : %s", new_fd, fd_flags, strerror(errno));
+ return false;
+ }
+
+ if (TEMP_FAILURE_RETRY(fcntl(new_fd, F_SETFL, fs_flags)) == -1) {
+ close(new_fd);
+ ALOGE("Failed fcntl(%d, F_SETFL, %x) : %s", new_fd, fs_flags, strerror(errno));
+ return false;
+ }
+
+ if (offset != -1 && TEMP_FAILURE_RETRY(lseek64(new_fd, offset, SEEK_SET)) == -1) {
+ close(new_fd);
+ ALOGE("Failed lseek64(%d, SEEK_SET) : %s", new_fd, strerror(errno));
+ return false;
+ }
+
+ if (TEMP_FAILURE_RETRY(dup2(new_fd, fd)) == -1) {
+ close(new_fd);
+ ALOGE("Failed dup2(%d, %d) : %s", fd, new_fd, strerror(errno));
+ return false;
+ }
+
+ close(new_fd);
+
+ return true;
+}
+
+FileDescriptorInfo::FileDescriptorInfo(int fd) :
+ fd(fd),
+ stat(),
+ open_flags(0),
+ fd_flags(0),
+ fs_flags(0),
+ offset(0),
+ is_sock(true) {
+}
+
+FileDescriptorInfo::FileDescriptorInfo(struct stat stat, const std::string& file_path,
+ int fd, int open_flags, int fd_flags, int fs_flags,
+ off_t offset) :
+ fd(fd),
+ stat(stat),
+ file_path(file_path),
+ open_flags(open_flags),
+ fd_flags(fd_flags),
+ fs_flags(fs_flags),
+ offset(offset),
+ is_sock(false) {
+}
+
+// TODO: Call android::base::Readlink instead of copying the code here.
+// static
+bool FileDescriptorInfo::Readlink(const int fd, std::string* result) {
+ char path[64];
+ snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
+
+ // Code copied from android::base::Readlink starts here :
+
+ // Annoyingly, the readlink system call returns EINVAL for a zero-sized buffer,
+ // and truncates to whatever size you do supply, so it can't be used to query.
+ // We could call lstat first, but that would introduce a race condition that
+ // we couldn't detect.
+ // ext2 and ext4 both have PAGE_SIZE limitations, so we assume that here.
+ char buf[4096];
+ ssize_t len = readlink(path, buf, sizeof(buf));
+ if (len == -1) return false;
+
+ result->assign(buf, len);
+ return true;
+}
+
+// static
+bool FileDescriptorInfo::GetSocketName(const int fd, std::string* result) {
+ sockaddr_storage ss;
+ sockaddr* addr = reinterpret_cast<sockaddr*>(&ss);
+ socklen_t addr_len = sizeof(ss);
+
+ if (TEMP_FAILURE_RETRY(getsockname(fd, addr, &addr_len)) == -1) {
+ ALOGE("Failed getsockname(%d) : %s", fd, strerror(errno));
+ return false;
+ }
+
+ if (addr->sa_family != AF_UNIX) {
+ ALOGE("Unsupported socket (fd=%d) with family %d", fd, addr->sa_family);
+ return false;
+ }
+
+ const sockaddr_un* unix_addr = reinterpret_cast<const sockaddr_un*>(&ss);
+
+ size_t path_len = addr_len - offsetof(struct sockaddr_un, sun_path);
+ // This is an unnamed local socket, we do not accept it.
+ if (path_len == 0) {
+ ALOGE("Unsupported AF_UNIX socket (fd=%d) with empty path.", fd);
+ return false;
+ }
+
+ // This is a local socket with an abstract address, we do not accept it.
+ if (unix_addr->sun_path[0] == '\0') {
+ ALOGE("Unsupported AF_UNIX socket (fd=%d) with abstract address.", fd);
+ return false;
+ }
+
+ // If we're here, sun_path must refer to a null terminated filesystem
+ // pathname (man 7 unix). Remove the terminator before assigning it to an
+ // std::string.
+ if (unix_addr->sun_path[path_len - 1] == '\0') {
+ --path_len;
+ }
+
+ result->assign(unix_addr->sun_path, path_len);
+ return true;
+}
+
+bool FileDescriptorInfo::DetachSocket() const {
+ const int dev_null_fd = open("/dev/null", O_RDWR);
+ if (dev_null_fd < 0) {
+ ALOGE("Failed to open /dev/null : %s", strerror(errno));
+ return false;
+ }
+
+ if (dup2(dev_null_fd, fd) == -1) {
+ ALOGE("Failed dup2 on socket descriptor %d : %s", fd, strerror(errno));
+ return false;
+ }
+
+ if (close(dev_null_fd) == -1) {
+ ALOGE("Failed close(%d) : %s", dev_null_fd, strerror(errno));
+ return false;
+ }
+
+ return true;
+}
+
+// static
+FileDescriptorTable* FileDescriptorTable::Create() {
+ DIR* d = opendir(kFdPath);
+ if (d == NULL) {
+ ALOGE("Unable to open directory %s: %s", kFdPath, strerror(errno));
+ return NULL;
+ }
+ int dir_fd = dirfd(d);
+ dirent* e;
+
+ std::unordered_map<int, FileDescriptorInfo*> open_fd_map;
+ while ((e = readdir(d)) != NULL) {
+ const int fd = ParseFd(e, dir_fd);
+ if (fd == -1) {
+ continue;
+ }
+
+ FileDescriptorInfo* info = FileDescriptorInfo::CreateFromFd(fd);
+ if (info == NULL) {
+ if (closedir(d) == -1) {
+ ALOGE("Unable to close directory : %s", strerror(errno));
+ }
+ return NULL;
+ }
+ open_fd_map[fd] = info;
+ }
+
+ if (closedir(d) == -1) {
+ ALOGE("Unable to close directory : %s", strerror(errno));
+ return NULL;
+ }
+ return new FileDescriptorTable(open_fd_map);
+}
+
+bool FileDescriptorTable::Restat() {
+ std::set<int> open_fds;
+
+ // First get the list of open descriptors.
+ DIR* d = opendir(kFdPath);
+ if (d == NULL) {
+ ALOGE("Unable to open directory %s: %s", kFdPath, strerror(errno));
+ return false;
+ }
+
+ int dir_fd = dirfd(d);
+ dirent* e;
+ while ((e = readdir(d)) != NULL) {
+ const int fd = ParseFd(e, dir_fd);
+ if (fd == -1) {
+ continue;
+ }
+
+ open_fds.insert(fd);
+ }
+
+ if (closedir(d) == -1) {
+ ALOGE("Unable to close directory : %s", strerror(errno));
+ return false;
+ }
+
+ return RestatInternal(open_fds);
+}
+
+// Reopens all file descriptors that are contained in the table. Returns true
+// if all descriptors were successfully re-opened or detached, and false if an
+// error occurred.
+bool FileDescriptorTable::ReopenOrDetach() {
+ std::unordered_map<int, FileDescriptorInfo*>::const_iterator it;
+ for (it = open_fd_map_.begin(); it != open_fd_map_.end(); ++it) {
+ const FileDescriptorInfo* info = it->second;
+ if (info == NULL || !info->ReopenOrDetach()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+FileDescriptorTable::FileDescriptorTable(
+ const std::unordered_map<int, FileDescriptorInfo*>& map)
+ : open_fd_map_(map) {
+}
+
+bool FileDescriptorTable::RestatInternal(std::set<int>& open_fds) {
+ bool error = false;
+
+ // Iterate through the list of file descriptors we've already recorded
+ // and check whether :
+ //
+ // (a) they continue to be open.
+ // (b) they refer to the same file.
+ std::unordered_map<int, FileDescriptorInfo*>::iterator it = open_fd_map_.begin();
+ while (it != open_fd_map_.end()) {
+ std::set<int>::const_iterator element = open_fds.find(it->first);
+ if (element == open_fds.end()) {
+ // The entry from the file descriptor table is no longer in the list
+ // of open files. We warn about this condition and remove it from
+ // the list of FDs under consideration.
+ //
+ // TODO(narayan): This will be an error in a future android release.
+ // error = true;
+ // ALOGW("Zygote closed file descriptor %d.", it->first);
+ it = open_fd_map_.erase(it);
+ } else {
+ // The entry from the file descriptor table is still open. Restat
+ // it and check whether it refers to the same file.
+ const bool same_file = it->second->Restat();
+ if (!same_file) {
+ // The file descriptor refers to a different description. We must
+ // update our entry in the table.
+ delete it->second;
+ it->second = FileDescriptorInfo::CreateFromFd(*element);
+ if (it->second == NULL) {
+ // The descriptor no longer no longer refers to a whitelisted file.
+ // We flag an error and remove it from the list of files we're
+ // tracking.
+ error = true;
+ it = open_fd_map_.erase(it);
+ } else {
+ // Successfully restatted the file, move on to the next open FD.
+ ++it;
+ }
+ } else {
+ // It's the same file. Nothing to do here. Move on to the next open
+ // FD.
+ ++it;
+ }
+
+ // Finally, remove the FD from the set of open_fds. We do this last because
+ // |element| will not remain valid after a call to erase.
+ open_fds.erase(element);
+ }
+ }
+
+ if (open_fds.size() > 0) {
+ // The zygote has opened new file descriptors since our last inspection.
+ // We warn about this condition and add them to our table.
+ //
+ // TODO(narayan): This will be an error in a future android release.
+ // error = true;
+ // ALOGW("Zygote opened %zd new file descriptor(s).", open_fds.size());
+
+ // TODO(narayan): This code will be removed in a future android release.
+ std::set<int>::const_iterator it;
+ for (it = open_fds.begin(); it != open_fds.end(); ++it) {
+ const int fd = (*it);
+ FileDescriptorInfo* info = FileDescriptorInfo::CreateFromFd(fd);
+ if (info == NULL) {
+ // A newly opened file is not on the whitelist. Flag an error and
+ // continue.
+ error = true;
+ } else {
+ // Track the newly opened file.
+ open_fd_map_[fd] = info;
+ }
+ }
+ }
+
+ return !error;
+}
+
+// static
+int FileDescriptorTable::ParseFd(dirent* e, int dir_fd) {
+ char* end;
+ const int fd = strtol(e->d_name, &end, 10);
+ if ((*end) != '\0') {
+ return -1;
+ }
+
+ // Don't bother with the standard input/output/error, they're handled
+ // specially post-fork anyway.
+ if (fd <= STDERR_FILENO || fd == dir_fd) {
+ return -1;
+ }
+
+ return fd;
+}
diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h
new file mode 100644
index 0000000..9e3afd9
--- /dev/null
+++ b/core/jni/fd_utils.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_CORE_JNI_FD_UTILS_H_
+#define FRAMEWORKS_BASE_CORE_JNI_FD_UTILS_H_
+
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+
+#include <android-base/macros.h>
+
+// Whitelist of open paths that the zygote is allowed to keep open.
+//
+// In addition to the paths listed in kPathWhitelist in file_utils.cpp, and
+// paths dynamically added with Allow(), all files ending with ".jar"
+// under /system/framework" are whitelisted. See IsAllowed() for the canonical
+// definition.
+//
+// If the whitelisted path is associated with a regular file or a
+// character device, the file is reopened after a fork with the same
+// offset and mode. If the whilelisted path is associated with a
+// AF_UNIX socket, the socket will refer to /dev/null after each
+// fork, and all operations on it will fail.
+class FileDescriptorWhitelist {
+ public:
+ // Lazily creates the global whitelist.
+ static FileDescriptorWhitelist* Get();
+
+ // Adds a path to the whitelist.
+ void Allow(const std::string& path) {
+ whitelist_.push_back(path);
+ }
+
+ // Returns true iff. a given path is whitelisted. A path is whitelisted
+ // if it belongs to the whitelist (see kPathWhitelist) or if it's a path
+ // under /system/framework that ends with ".jar" or if it is a system
+ // framework overlay.
+ bool IsAllowed(const std::string& path) const;
+
+ private:
+ FileDescriptorWhitelist();
+
+ static bool StartsWith(const std::string& str, const std::string& prefix);
+
+ static bool EndsWith(const std::string& str, const std::string& suffix);
+
+ static FileDescriptorWhitelist* instance_;
+
+ std::vector<std::string> whitelist_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileDescriptorWhitelist);
+};
+
+// Keeps track of all relevant information (flags, offset etc.) of an
+// open zygote file descriptor.
+class FileDescriptorInfo {
+ public:
+ // Create a FileDescriptorInfo for a given file descriptor. Returns
+ // |NULL| if an error occurred.
+ static FileDescriptorInfo* CreateFromFd(int fd);
+
+ // Checks whether the file descriptor associated with this object
+ // refers to the same description.
+ bool Restat() const;
+
+ bool ReopenOrDetach() const;
+
+ const int fd;
+ const struct stat stat;
+ const std::string file_path;
+ const int open_flags;
+ const int fd_flags;
+ const int fs_flags;
+ const off_t offset;
+ const bool is_sock;
+
+ private:
+ FileDescriptorInfo(int fd);
+
+ FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
+ int fd_flags, int fs_flags, off_t offset);
+
+ static bool Readlink(const int fd, std::string* result);
+
+ // Returns the locally-bound name of the socket |fd|. Returns true
+ // iff. all of the following hold :
+ //
+ // - the socket's sa_family is AF_UNIX.
+ // - the length of the path is greater than zero (i.e, not an unnamed socket).
+ // - the first byte of the path isn't zero (i.e, not a socket with an abstract
+ // address).
+ static bool GetSocketName(const int fd, std::string* result);
+
+ bool DetachSocket() const;
+
+ DISALLOW_COPY_AND_ASSIGN(FileDescriptorInfo);
+};
+
+// A FileDescriptorTable is a collection of FileDescriptorInfo objects
+// keyed by their FDs.
+class FileDescriptorTable {
+ public:
+ // Creates a new FileDescriptorTable. This function scans
+ // /proc/self/fd for the list of open file descriptors and collects
+ // information about them. Returns NULL if an error occurs.
+ static FileDescriptorTable* Create();
+
+ bool Restat();
+
+ // Reopens all file descriptors that are contained in the table. Returns true
+ // if all descriptors were successfully re-opened or detached, and false if an
+ // error occurred.
+ bool ReopenOrDetach();
+
+ private:
+ FileDescriptorTable(const std::unordered_map<int, FileDescriptorInfo*>& map);
+
+ bool RestatInternal(std::set<int>& open_fds);
+
+ static int ParseFd(dirent* e, int dir_fd);
+
+ // Invariant: All values in this unordered_map are non-NULL.
+ std::unordered_map<int, FileDescriptorInfo*> open_fd_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileDescriptorTable);
+};
+
+#endif // FRAMEWORKS_BASE_CORE_JNI_FD_UTILS_H_
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4c6e7a3..048214a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1232,6 +1232,12 @@
<permission android:name="android.permission.SCORE_NETWORKS"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows applications to request network
+ recommendations and scores from the NetworkScoreService.
+ <p>Not for use by third-party applications. @hide -->
+ <permission android:name="android.permission.REQUEST_NETWORK_SCORES"
+ android:protectionLevel="signature" />
+
<!-- ======================================= -->
<!-- Permissions for short range, peripheral networks -->
<!-- ======================================= -->
@@ -2642,7 +2648,10 @@
android:protectionLevel="signature" />
<!-- @SystemApi Allows an application to broadcast privileged networking requests.
- <p>Not for use by third-party applications. @hide -->
+ <p>Not for use by third-party applications.
+ @hide
+ @deprecated Use {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} instead
+ -->
<permission android:name="android.permission.BROADCAST_NETWORK_PRIVILEGED"
android:protectionLevel="signature|privileged" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4cf1226..dbc4324 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1280,9 +1280,8 @@
<!-- A list of potential packages, in priority order, that may contain a
network recommendation provider. A network recommendation provider must:
* Be granted the SCORE_NETWORKS permission.
- * Include a Receiver for the android.net.scoring.SCORE_NETWORKS action guarded by the
- BROADCAST_NETWORK_PRIVILEGED permission.
- * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action.
+ * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action
+ protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission.
This may be empty if network scoring and recommending isn't supported.
-->
@@ -2676,4 +2675,7 @@
<!-- An array of packages for which notifications cannot be blocked. -->
<string-array translatable="false" name="config_nonBlockableNotificationPackages" />
+
+ <!-- Component name of the default cell broadcast receiver -->
+ <string name="config_defaultCellBroadcastReceiverComponent" translatable="false">com.android.cellbroadcastreceiver/.PrivilegedCellBroadcastReceiver</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fe88cd1..dadbce8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2739,4 +2739,6 @@
<!-- Network Recommendation -->
<java-symbol type="array" name="config_networkRecommendationPackageNames" />
+
+ <java-symbol type="string" name="config_defaultCellBroadcastReceiverComponent" />
</resources>
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index 5bfff26..29020ba 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -169,6 +169,25 @@
assertNull(activeScorer);
}
+ public void testIsCallerActiveScorer_providerNotAvailable() throws Exception {
+ ContentResolver cr = mTargetContext.getContentResolver();
+ Settings.Global.putInt(cr, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 1);
+
+ assertFalse(mNetworkScorerAppManager.isCallerActiveScorer(924));
+ }
+
+ public void testIsCallerActiveScorer_providerAvailable() throws Exception {
+ setNetworkRecommendationPackageNames("package1");
+ mockScoreNetworksGranted("package1");
+ mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+
+ ContentResolver cr = mTargetContext.getContentResolver();
+ Settings.Global.putInt(cr, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 1);
+
+ assertTrue(mNetworkScorerAppManager.isCallerActiveScorer(924));
+ assertFalse(mNetworkScorerAppManager.isCallerActiveScorer(925));
+ }
+
private void setNetworkRecommendationPackageNames(String... names) {
if (names == null) {
names = new String[0];
diff --git a/core/tests/coretests/src/android/net/ScoredNetworkTest.java b/core/tests/coretests/src/android/net/ScoredNetworkTest.java
index 9c3346e..e818c56 100644
--- a/core/tests/coretests/src/android/net/ScoredNetworkTest.java
+++ b/core/tests/coretests/src/android/net/ScoredNetworkTest.java
@@ -166,4 +166,52 @@
assertTrue(newNetwork.meteredHint);
assertNull(newNetwork.attributes);
}
+
+ @Test
+ public void calculateBadgeShouldReturnNoBadgeWhenNoAttributesBundle() {
+ ScoredNetwork network = new ScoredNetwork(KEY, CURVE);
+ assertEquals(ScoredNetwork.BADGING_NONE, network.calculateBadge(TEST_RSSI));
+ }
+
+ @Test
+ public void calculateBadgeShouldReturnNoBadgeWhenNoBadgingCurveInBundle() {
+ ScoredNetwork network = new ScoredNetwork(KEY, CURVE, false /* meteredHint */, ATTRIBUTES);
+ assertEquals(ScoredNetwork.BADGING_NONE, network.calculateBadge(TEST_RSSI));
+ }
+
+ @Test
+ public void calculateBadgeShouldReturn4kBadge() {
+ ScoredNetwork network =
+ buildScoredNetworkWithGivenBadgeForTestRssi(ScoredNetwork.BADGING_4K);
+ assertEquals(ScoredNetwork.BADGING_4K, network.calculateBadge(TEST_RSSI));
+ }
+
+ @Test
+ public void calculateBadgeShouldReturnHdBadge() {
+ ScoredNetwork network =
+ buildScoredNetworkWithGivenBadgeForTestRssi(ScoredNetwork.BADGING_HD);
+ assertEquals(ScoredNetwork.BADGING_HD, network.calculateBadge(TEST_RSSI));
+ }
+
+ @Test
+ public void calculateBadgeShouldReturnSdBadge() {
+ ScoredNetwork network =
+ buildScoredNetworkWithGivenBadgeForTestRssi(ScoredNetwork.BADGING_SD);
+ assertEquals(ScoredNetwork.BADGING_SD, network.calculateBadge(TEST_RSSI));
+ }
+
+ @Test
+ public void calculateBadgeShouldReturnNoBadge() {
+ ScoredNetwork network =
+ buildScoredNetworkWithGivenBadgeForTestRssi(ScoredNetwork.BADGING_NONE);
+ assertEquals(ScoredNetwork.BADGING_NONE, network.calculateBadge(TEST_RSSI));
+ }
+
+ private ScoredNetwork buildScoredNetworkWithGivenBadgeForTestRssi(int badge) {
+ RssiCurve badgingCurve =
+ new RssiCurve(RSSI_START, 10, new byte[] {0, 0, 0, 0, 0, 0, (byte) badge});
+ Bundle attr = new Bundle();
+ attr.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgingCurve);
+ return new ScoredNetwork(KEY, CURVE, false /* meteredHint */, attr);
+ }
}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
index 9b2b9f1..836ede6 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
@@ -23,7 +23,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 8
LOCAL_PACKAGE_NAME := MultiDexLegacyAndException
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
index 874263f..2915914 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
@@ -23,7 +23,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 8
LOCAL_PACKAGE_NAME := MultiDexLegacyTestApp
@@ -45,7 +45,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 8
LOCAL_PACKAGE_NAME := MultiDexLegacyTestApp2
diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd
index 5d6b3a8..1f1939c 100755
--- a/docs/html/google/play/billing/billing_integrate.jd
+++ b/docs/html/google/play/billing/billing_integrate.jd
@@ -294,7 +294,7 @@
skuList.add("premiumUpgrade");
skuList.add("gas");
Bundle querySkus = new Bundle();
-querySkus.putStringArrayList(“ITEM_ID_LIST”, skuList);
+querySkus.putStringArrayList("ITEM_ID_LIST", skuList);
</pre>
<p>
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index ac6a28f..86731c9 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -134,7 +134,12 @@
void EglManager::initExtensions() {
auto extensions = StringUtils::split(
eglQueryString(mEglDisplay, EGL_EXTENSIONS));
- EglExtensions.bufferAge = extensions.has("EGL_EXT_buffer_age");
+ // For our purposes we don't care if EGL_BUFFER_AGE is a result of
+ // EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered
+ // under EGL_KHR_partial_update and we don't need the expanded scope
+ // that EGL_EXT_buffer_age provides.
+ EglExtensions.bufferAge = extensions.has("EGL_EXT_buffer_age")
+ || extensions.has("EGL_KHR_partial_update");
EglExtensions.setDamage = extensions.has("EGL_KHR_partial_update");
LOG_ALWAYS_FATAL_IF(!extensions.has("EGL_KHR_swap_buffers_with_damage"),
"Missing required extension EGL_KHR_swap_buffers_with_damage");
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 33c9655..5843637 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -17,4 +17,5 @@
name: "libandroid.ndk",
symbol_file: "libandroid.map.txt",
first_version: "9",
+ unversioned_until: "current",
}
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index e09b0b4..17feb53 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -17,4 +17,5 @@
name: "libjnigraphics.ndk",
symbol_file: "libjnigraphics.map.txt",
first_version: "9",
+ unversioned_until: "current",
}
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 5b11303..f79cf04 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -100,6 +100,129 @@
<item>Always use HDCP checking</item>
</string-array>
+
+ <!-- Bluetooth settings -->
+
+ <!-- Titles for Bluetooth Audio Codec selection preference. [CHAR LIMIT=40] -->
+ <string-array name="bluetooth_a2dp_codec_titles">
+ <item>Default</item>
+ <item>SBC</item>
+ <item>aptX</item>
+ <item>aptX-HD</item>
+ <item>LDAC</item>
+ </string-array>
+
+ <!-- Values for Bluetooth Audio Codec selection preference. -->
+ <string-array name="bluetooth_a2dp_codec_values" translatable="false" >
+ <item>1000000</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+ <!-- Summaries for Bluetooth Audio Codec selection preference. [CHAR LIMIT=40]-->
+ <string-array name="bluetooth_a2dp_codec_summaries" >
+ <item>Default</item>
+ <item>SBC</item>
+ <item>aptX</item>
+ <item>aptX-HD</item>
+ <item>LDAC</item>
+ </string-array>
+
+ <!-- Titles for Bluetooth Audio Codec Sample Rate selection preference. [CHAR LIMIT=40] -->
+ <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
+ <item>Default</item>
+ <item>44.1 kHz</item>
+ <item>48.0 kHz</item>
+ <item>88.2 kHz</item>
+ <item>96.0 kHz</item>
+ </string-array>
+
+ <!-- Values for Bluetooth Audio Codec Sample Rate selection preference. -->
+ <string-array name="bluetooth_a2dp_codec_sample_rate_values" translatable="false" >
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>4</item>
+ <item>8</item>
+ </string-array>
+
+ <!-- Summaries for Bluetooth Audio Codec Sample Rate selection preference. [CHAR LIMIT=40]-->
+ <string-array name="bluetooth_a2dp_codec_sample_rate_summaries" >
+ <item>Default</item>
+ <item>44.1 kHz</item>
+ <item>48.0 kHz</item>
+ <item>88.2 kHz</item>
+ <item>96.0 kHz</item>
+ </string-array>
+
+ <!-- Titles for Bluetooth Audio Codec Bits Per Sample selection preference. [CHAR LIMIT=40] -->
+ <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
+ <item>Default</item>
+ <item>16 bits/sample</item>
+ <item>24 bits/sample</item>
+ <item>32 bits/sample</item>
+ </string-array>
+
+ <!-- Values for Bluetooth Audio Codec Bits Per Sample selection preference. -->
+ <string-array name="bluetooth_a2dp_codec_bits_per_sample_values" translatable="false" >
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>4</item>
+ </string-array>
+
+ <!-- Summaries for Bluetooth Audio Codec Bits Per Sample selection preference. [CHAR LIMIT=40]-->
+ <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries" >
+ <item>Default</item>
+ <item>16 bits/sample</item>
+ <item>24 bits/sample</item>
+ <item>32 bits/sample</item>
+ </string-array>
+
+ <!-- Titles for Bluetooth Audio Codec Channel Mode selection preference. [CHAR LIMIT=40] -->
+ <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
+ <item>Default</item>
+ <item>Mono</item>
+ <item>Stereo</item>
+ </string-array>
+
+ <!-- Values for Bluetooth Audio Codec Channel Mode selection preference. -->
+ <string-array name="bluetooth_a2dp_codec_channel_mode_values" translatable="false" >
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ </string-array>
+
+ <!-- Summaries for Bluetooth Audio Codec Channel Mode selection preference. [CHAR LIMIT=40]-->
+ <string-array name="bluetooth_a2dp_codec_channel_mode_summaries" >
+ <item>Default</item>
+ <item>Mono</item>
+ <item>Stereo</item>
+ </string-array>
+
+ <!-- Titles for Bluetooth Audio Codec LDAC Playback Quality selection preference. [CHAR LIMIT=40] -->
+ <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
+ <item>Sound quality preferred (990kbps/909kbps)</item>
+ <item>Standard (660kbps/606kbps)</item>
+ <item>Connection preferred (330kbps/303kbps)</item>
+ </string-array>
+
+ <!-- Values for Bluetooth Audio Codec LDAC Playback Quaility selection preference. -->
+ <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_values" translatable="false" >
+ <item>1000</item>
+ <item>1001</item>
+ <item>1002</item>
+ </string-array>
+
+ <!-- Summaries for Bluetooth Audio Codec LDAC Playback Quality selection preference. [CHAR LIMIT=40]-->
+ <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries" >
+ <item>Sound quality preferred (990kbps/909kbps)</item>
+ <item>Standard (660kbps/606kbps)</item>
+ <item>Connection preferred (330kbps/303kbps)</item>
+ </string-array>
+
<!-- Titles for logd limit size selection preference. [CHAR LIMIT=14] -->
<string-array name="select_logd_size_titles">
<item>Off</item>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 29839e7..f389000 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -428,6 +428,31 @@
<!-- Setting Checkbox title for disabling Bluetooth absolute volume -->
<string name="bluetooth_disable_absolute_volume">Disable absolute volume</string>
+ <!-- UI debug setting: Select Bluetooth Audio Codec -->
+ <string name="bluetooth_select_a2dp_codec_type">Bluetooth Audio Codec</string>
+ <!-- UI debug setting: Select Preferred Bluetooth A2DP Codec -->
+ <string name="bluetooth_select_a2dp_codec_type_dialog_title">Select Preferred Bluetooth A2DP Codec</string>
+
+ <!-- UI debug setting: Select Bluetooth Audio Sample Rate -->
+ <string name="bluetooth_select_a2dp_codec_sample_rate">Bluetooth Audio Sample Rate</string>
+ <!-- UI debug setting: Select Preferred Bluetooth A2DP Codec Sample Rate -->
+ <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title">Select Preferred Bluetooth A2DP Codec Sample Rate</string>
+
+ <!-- UI debug setting: Select Bluetooth Audio Bits Per Sample -->
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample">Bluetooth Audio Bits Per Sample</string>
+ <!-- UI debug setting: Select Preferred Bluetooth A2DP Codec Bits Per Sample -->
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title">Select Preferred Bluetooth A2DP Codec Bits Per Sample</string>
+
+ <!-- UI debug setting: Select Bluetooth Audio Channel Mode -->
+ <string name="bluetooth_select_a2dp_codec_channel_mode">Bluetooth Audio Channel Mode</string>
+ <!-- UI debug setting: Select Preferred Bluetooth A2DP Codec Channel Mode -->
+ <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title">Select Preferred Bluetooth A2DP Codec Channel Mode</string>
+
+ <!-- UI debug setting: Select Bluetooth Audio LDAC Playback Quality -->
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality">Bluetooth Audio LDAC Playback Quality</string>
+ <!-- UI debug setting: Select Preferred Bluetooth A2DP Codec LDAC Playback Quality -->
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title">Select Preferred Bluetooth A2DP Codec LDAC Playback Quality</string>
+
<!-- setting Checkbox summary whether to show options for wireless display certification -->
<string name="wifi_display_certification_summary">Show options for wireless display certification</string>
<!-- Setting Checkbox summary whether to enable Wifi verbose Logging [CHAR LIMIT=80] -->
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index b9a4831..4cc2931 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -46,6 +46,7 @@
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.ObbInfo;
+import android.net.TrafficStats;
import android.net.Uri;
import android.os.Binder;
import android.os.DropBoxManager;
@@ -86,6 +87,7 @@
import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.TimeUtils;
import android.util.Xml;
@@ -3738,6 +3740,18 @@
pw.println();
pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
+ final Pair<String, Long> pair = StorageManager.getPrimaryStoragePathAndSize();
+ if (pair == null) {
+ pw.println("Internal storage total size: N/A");
+ } else {
+ pw.print("Internal storage (");
+ pw.print(pair.first);
+ pw.print(") total size: ");
+ pw.print(pair.second);
+ pw.print(" (");
+ pw.print((float) pair.second / TrafficStats.GB_IN_BYTES);
+ pw.println(" GB)");
+ }
pw.println("Force adoptable: " + mForceAdoptable);
pw.println();
pw.println("Local unlocked users: " + Arrays.toString(mLocalUnlockedUsers));
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 983d039..cef459a 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -34,9 +34,9 @@
import android.net.INetworkScoreCache;
import android.net.INetworkScoreService;
import android.net.NetworkKey;
+import android.net.NetworkScoreManager;
import android.net.NetworkScorerAppManager;
import android.net.NetworkScorerAppManager.NetworkScorerAppData;
-import android.net.NetworkScoreManager;
import android.net.RecommendationRequest;
import android.net.RecommendationResult;
import android.net.ScoredNetwork;
@@ -380,13 +380,16 @@
}
}
+ private boolean isCallerSystemUid() {
+ // REQUEST_NETWORK_SCORES is a signature only permission.
+ return mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES) ==
+ PackageManager.PERMISSION_GRANTED;
+ }
+
@Override
public boolean clearScores() {
- // Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
- // should be allowed to flush all scores.
- if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) ||
- mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
- PackageManager.PERMISSION_GRANTED) {
+ // Only the active scorer or the system should be allowed to flush all scores.
+ if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
final long token = Binder.clearCallingIdentity();
try {
clearInternal();
@@ -409,7 +412,6 @@
// In the future, should this API be opened to 3p apps, we will need to lock this down and
// figure out another way to streamline the UX.
- // mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
mContext.enforceCallingOrSelfPermission(permission.SCORE_NETWORKS, TAG);
// Scorers (recommendation providers) are selected and no longer set.
@@ -418,11 +420,8 @@
@Override
public void disableScoring() {
- // Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
- // should be allowed to disable scoring.
- if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) ||
- mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
- PackageManager.PERMISSION_GRANTED) {
+ // Only the active scorer or the system should be allowed to disable scoring.
+ if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
// no-op for now but we could write to the setting if needed.
} else {
throw new SecurityException(
@@ -450,7 +449,7 @@
public void registerNetworkScoreCache(int networkType,
INetworkScoreCache scoreCache,
int filterType) {
- mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
+ mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
final long token = Binder.clearCallingIdentity();
try {
synchronized (mScoreCaches) {
@@ -475,7 +474,7 @@
@Override
public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
- mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
+ mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
final long token = Binder.clearCallingIdentity();
try {
synchronized (mScoreCaches) {
@@ -496,7 +495,7 @@
@Override
public RecommendationResult requestRecommendation(RecommendationRequest request) {
- mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
+ mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
throwIfCalledOnMainThread();
final long token = Binder.clearCallingIdentity();
try {
@@ -526,7 +525,7 @@
@Override
public boolean requestScores(NetworkKey[] networks) {
- mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
+ mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
final long token = Binder.clearCallingIdentity();
try {
final INetworkRecommendationProvider provider = getRecommendationProvider();
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 5016ec0..a6f9243 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -1013,7 +1013,7 @@
permissions.clear();
}
permissions.add(permissionGrant.name);
- grantRuntimePermissionsLPw(pkg, permissions, false,
+ grantRuntimePermissionsLPw(pkg, permissions,
permissionGrant.fixed, userId);
}
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 605fa5d..98249dd1 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -199,16 +199,44 @@
}
}
- public void getAppSize(String uuid, String packageName, int userId, int flags, int appId,
- long ceDataInode, String codePath, String externalUuid, PackageStats stats)
+ public void getAppSize(String uuid, String[] packageNames, int userId, int flags, int appId,
+ long[] ceDataInodes, String[] codePaths, PackageStats stats)
throws InstallerException {
if (!checkBeforeRemote()) return;
try {
- final long[] res = mInstalld.getAppSize(uuid, packageName, userId, flags, appId,
- ceDataInode, codePath, externalUuid);
+ final long[] res = mInstalld.getAppSize(uuid, packageNames, userId, flags,
+ appId, ceDataInodes, codePaths);
stats.codeSize += res[0];
stats.dataSize += res[1];
stats.cacheSize += res[2];
+ stats.externalCodeSize += res[3];
+ stats.externalDataSize += res[4];
+ stats.externalCacheSize += res[5];
+ } catch (Exception e) {
+ throw InstallerException.from(e);
+ }
+ }
+
+ public void getUserSize(String uuid, int userId, int flags, int[] appIds, PackageStats stats)
+ throws InstallerException {
+ if (!checkBeforeRemote()) return;
+ try {
+ final long[] res = mInstalld.getUserSize(uuid, userId, flags, appIds);
+ stats.codeSize += res[0];
+ stats.dataSize += res[1];
+ stats.cacheSize += res[2];
+ stats.externalCodeSize += res[3];
+ stats.externalDataSize += res[4];
+ stats.externalCacheSize += res[5];
+ } catch (Exception e) {
+ throw InstallerException.from(e);
+ }
+ }
+
+ public long[] getExternalSize(String uuid, int userId, int flags) throws InstallerException {
+ if (!checkBeforeRemote()) return new long[4];
+ try {
+ return mInstalld.getExternalSize(uuid, userId, flags);
} catch (Exception e) {
throw InstallerException.from(e);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 614230c..f2d1d1e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -16872,11 +16872,6 @@
mHandler.sendMessage(msg);
}
- private boolean equals(PackageStats a, PackageStats b) {
- return (a.codeSize == b.codeSize) && (a.dataSize == b.dataSize)
- && (a.cacheSize == b.cacheSize);
- }
-
private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
final PackageSetting ps;
synchronized (mPackages) {
@@ -16887,44 +16882,21 @@
}
}
- final long ceDataInode = ps.getCeDataInode(userId);
- final PackageStats quotaStats = new PackageStats(stats.packageName, stats.userHandle);
+ final String[] packageNames = { packageName };
+ final long[] ceDataInodes = { ps.getCeDataInode(userId) };
+ final String[] codePaths = { ps.codePathString };
- final StorageManager storage = mContext.getSystemService(StorageManager.class);
- final String externalUuid = storage.getPrimaryStorageUuid();
try {
- final long start = SystemClock.elapsedRealtimeNanos();
- mInstaller.getAppSize(ps.volumeUuid, packageName, userId, 0,
- ps.appId, ceDataInode, ps.codePathString, externalUuid, stats);
- final long stopManual = SystemClock.elapsedRealtimeNanos();
- if (ENABLE_QUOTA) {
- mInstaller.getAppSize(ps.volumeUuid, packageName, userId, Installer.FLAG_USE_QUOTA,
- ps.appId, ceDataInode, ps.codePathString, externalUuid, quotaStats);
- }
- final long stopQuota = SystemClock.elapsedRealtimeNanos();
+ mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
+ ps.appId, ceDataInodes, codePaths, stats);
// For now, ignore code size of packages on system partition
if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
stats.codeSize = 0;
- quotaStats.codeSize = 0;
- }
-
- if (ENABLE_QUOTA && Build.IS_ENG && !ps.isSharedUser()) {
- if (!equals(stats, quotaStats)) {
- Log.w(TAG, "Found discrepancy between statistics:");
- Log.w(TAG, "Manual: " + stats);
- Log.w(TAG, "Quota: " + quotaStats);
- }
- final long manualTime = stopManual - start;
- final long quotaTime = stopQuota - stopManual;
- EventLogTags.writePmPackageStats(manualTime, quotaTime,
- stats.dataSize, quotaStats.dataSize,
- stats.cacheSize, quotaStats.cacheSize);
}
// External clients expect these to be tracked separately
stats.dataSize -= stats.cacheSize;
- quotaStats.dataSize -= quotaStats.cacheSize;
} catch (InstallerException e) {
Slog.w(TAG, String.valueOf(e));
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 69d27f2..af570b0 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -53,6 +53,7 @@
import android.net.INetworkRecommendationProvider;
import android.net.INetworkScoreCache;
import android.net.NetworkKey;
+import android.net.NetworkScoreManager;
import android.net.NetworkScorerAppManager;
import android.net.NetworkScorerAppManager.NetworkScorerAppData;
import android.net.RecommendationRequest;
@@ -134,9 +135,10 @@
mNetworkScoreService.systemRunning();
- verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
- new ComponentName(NEW_SCORER.packageName,
- NEW_SCORER.recommendationServiceClassName))),
+ verify(mContext).bindServiceAsUser(MockUtils.checkIntent(
+ new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
+ .setComponent(new ComponentName(NEW_SCORER.packageName,
+ NEW_SCORER.recommendationServiceClassName))),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.SYSTEM));
@@ -145,11 +147,11 @@
@Test
public void testRequestScores_noPermission() throws Exception {
doThrow(new SecurityException()).when(mContext)
- .enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED),
+ .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
anyString());
try {
mNetworkScoreService.requestScores(null);
- fail("BROADCAST_NETWORK_PRIVILEGED not enforced.");
+ fail("REQUEST_NETWORK_SCORES not enforced.");
} catch (SecurityException e) {
// expected
}
@@ -182,11 +184,11 @@
@Test
public void testRequestRecommendation_noPermission() throws Exception {
doThrow(new SecurityException()).when(mContext)
- .enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED),
+ .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
anyString());
try {
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
- fail("BROADCAST_NETWORK_PRIVILEGED not enforced.");
+ fail("REQUEST_NETWORK_SCORES not enforced.");
} catch (SecurityException e) {
// expected
}
@@ -320,9 +322,9 @@
}
@Test
- public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() {
+ public void testClearScores_notActiveScorer_noRequestNetworkScoresPermission() {
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
- when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
.thenReturn(PackageManager.PERMISSION_DENIED);
try {
mNetworkScoreService.clearScores();
@@ -333,9 +335,9 @@
}
@Test
- public void testClearScores_activeScorer_noBroadcastNetworkPermission() {
+ public void testClearScores_activeScorer_noRequestNetworkScoresPermission() {
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
- when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
.thenReturn(PackageManager.PERMISSION_DENIED);
mNetworkScoreService.clearScores();
@@ -353,10 +355,10 @@
}
@Test
- public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission()
+ public void testClearScores_notActiveScorer_hasRequestNetworkScoresPermission()
throws RemoteException {
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
- when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
.thenReturn(PackageManager.PERMISSION_GRANTED);
mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
@@ -380,9 +382,9 @@
}
@Test
- public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() {
+ public void testDisableScoring_notActiveScorer_noRequestNetworkScoresPermission() {
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
- when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
.thenReturn(PackageManager.PERMISSION_DENIED);
try {
@@ -394,9 +396,9 @@
}
@Test
- public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() {
+ public void testRegisterNetworkScoreCache_noRequestNetworkScoresPermission() {
doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
- eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
+ eq(permission.REQUEST_NETWORK_SCORES), anyString());
try {
mNetworkScoreService.registerNetworkScoreCache(
@@ -408,9 +410,9 @@
}
@Test
- public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() {
+ public void testUnregisterNetworkScoreCache_noRequestNetworkScoresPermission() {
doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
- eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
+ eq(permission.REQUEST_NETWORK_SCORES), anyString());
try {
mNetworkScoreService.unregisterNetworkScoreCache(
diff --git a/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java
new file mode 100644
index 0000000..2a7cbc2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 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 com.android.server.pm;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageStats;
+import android.os.UserHandle;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.Arrays;
+
+public class InstallerTest extends AndroidTestCase {
+ private static final String TAG = "InstallerTest";
+
+ private Installer mInstaller;
+
+ @Override
+ public void setUp() throws Exception {
+ mInstaller = new Installer(getContext());
+ mInstaller.onStart();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mInstaller = null;
+ }
+
+ public void testGetAppSize() throws Exception {
+ final PackageManager pm = getContext().getPackageManager();
+ for (ApplicationInfo app : pm.getInstalledApplications(0)) {
+ final int userId = UserHandle.getUserId(app.uid);
+ final int appId = UserHandle.getAppId(app.uid);
+
+ final String[] packageNames = pm.getPackagesForUid(app.uid);
+ final long[] ceDataInodes = new long[packageNames.length];
+ final String[] codePaths = new String[packageNames.length];
+
+ for (int i = 0; i < packageNames.length; i++) {
+ final ApplicationInfo info = pm.getApplicationInfo(packageNames[i], 0);
+ codePaths[i] = info.getCodePath();
+ }
+
+ final PackageStats stats = new PackageStats(app.packageName);
+ final PackageStats quotaStats = new PackageStats(app.packageName);
+
+ mInstaller.getAppSize(app.volumeUuid, packageNames, userId, 0,
+ appId, ceDataInodes, codePaths, stats);
+
+ mInstaller.getAppSize(app.volumeUuid, packageNames, userId, Installer.FLAG_USE_QUOTA,
+ appId, ceDataInodes, codePaths, quotaStats);
+
+ checkEquals(Arrays.toString(packageNames) + " UID=" + app.uid, stats, quotaStats);
+ }
+ }
+
+ public void testGetUserSize() throws Exception {
+ int[] appIds = null;
+
+ final PackageManager pm = getContext().getPackageManager();
+ for (ApplicationInfo app : pm.getInstalledApplications(0)) {
+ final int appId = UserHandle.getAppId(app.uid);
+ if (!ArrayUtils.contains(appIds, appId)) {
+ appIds = ArrayUtils.appendInt(appIds, appId);
+ }
+ }
+
+ final PackageStats stats = new PackageStats("android");
+ final PackageStats quotaStats = new PackageStats("android");
+
+ mInstaller.getUserSize(null, UserHandle.USER_SYSTEM, 0,
+ appIds, stats);
+
+ mInstaller.getUserSize(null, UserHandle.USER_SYSTEM, Installer.FLAG_USE_QUOTA,
+ appIds, quotaStats);
+
+ checkEquals(Arrays.toString(appIds), stats, quotaStats);
+ }
+
+ public void testGetExternalSize() throws Exception {
+
+ final long[] stats = mInstaller.getExternalSize(null, UserHandle.USER_SYSTEM, 0);
+
+ final long[] quotaStats = mInstaller.getExternalSize(null, UserHandle.USER_SYSTEM,
+ Installer.FLAG_USE_QUOTA);
+
+ for (int i = 0; i < stats.length; i++) {
+ checkEquals("#" + i, stats[i], quotaStats[i]);
+ }
+ }
+
+ private static void checkEquals(String msg, PackageStats a, PackageStats b) {
+ checkEquals(msg + " codeSize", a.codeSize, b.codeSize);
+ checkEquals(msg + " dataSize", a.dataSize, b.dataSize);
+ checkEquals(msg + " cacheSize", a.cacheSize, b.cacheSize);
+ checkEquals(msg + " externalCodeSize", a.externalCodeSize, b.externalCodeSize);
+ checkEquals(msg + " externalDataSize", a.externalDataSize, b.externalDataSize);
+ checkEquals(msg + " externalCacheSize", a.externalCacheSize, b.externalCacheSize);
+ }
+
+ private static void checkEquals(String msg, long expected, long actual) {
+ if (expected != actual) {
+ Log.e(TAG, msg + " expected " + expected + " actual " + actual);
+ }
+ }
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 9e897bf..18c1245 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -59,7 +59,7 @@
int addOrUpdateNetwork(in WifiConfiguration config);
- boolean addPasspointConfiguration(in PasspointConfiguration config);
+ boolean addOrUpdatePasspointConfiguration(in PasspointConfiguration config);
boolean removePasspointConfiguration(in String fqdn);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 3b7f721..958279b 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -608,6 +608,7 @@
* if there has been a report of it having no internet access, and, it never have had
* internet access in the past.
*/
+ @SystemApi
public boolean hasNoInternetAccess() {
return numNoInternetAccessReports > 0 && !validatedInternetAccess;
}
@@ -621,6 +622,17 @@
public boolean noInternetAccessExpected;
/**
+ * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a
+ * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to
+ * this configuration and selects "don't ask again".
+ * @hide
+ */
+ @SystemApi
+ public boolean isNoInternetAccessExpected() {
+ return noInternetAccessExpected;
+ }
+
+ /**
* @hide
* Last time the system was connected to this configuration.
*/
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 674c161..618a719 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -842,31 +842,31 @@
}
/**
- * Add a Passpoint configuration. The configuration provides a credential
+ * Add or update a Passpoint configuration. The configuration provides a credential
* for connecting to Passpoint networks that are operated by the Passpoint
* service provider specified in the configuration.
*
* Each configuration is uniquely identified by its FQDN (Fully Qualified Domain
- * Name). In the case when there is an existing configuration with the same base
- * domain, the new configuration will replace the existing configuration.
+ * Name). In the case when there is an existing configuration with the same
+ * FQDN, the new configuration will replace the existing configuration.
*
* @param config The Passpoint configuration to be added
- * @return true on success or false on failure
+ * @return true on success
* @hide
*/
- public boolean addPasspointConfiguration(PasspointConfiguration config) {
+ public boolean addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
try {
- return mService.addPasspointConfiguration(config);
+ return mService.addOrUpdatePasspointConfiguration(config);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
- * Remove a Passpoint configuration identified by its FQDN (Fully Qualified Domain Name).
+ * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name).
*
* @param fqdn The FQDN of the passpoint configuration to be removed
- * @return true on success or false on failure
+ * @return true on success
* @hide
*/
public boolean removePasspointConfiguration(String fqdn) {
@@ -880,7 +880,9 @@
/**
* Return the list of installed Passpoint configurations.
*
- * @return A list of PasspointConfiguration or null
+ * An empty list will be returned when no configurations are installed.
+ *
+ * @return A list of {@link PasspointConfiguration}
* @hide
*/
public List<PasspointConfiguration> getPasspointConfigurations() {
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java b/wifi/java/android/net/wifi/aware/AttachCallback.java
similarity index 78%
rename from wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java
rename to wifi/java/android/net/wifi/aware/AttachCallback.java
index 1e8dbd9..90216f3 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java
+++ b/wifi/java/android/net/wifi/aware/AttachCallback.java
@@ -18,16 +18,16 @@
/**
* Base class for Aware attach callbacks. Should be extended by applications and set when calling
- * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}. These are callbacks
+ * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}. These are callbacks
* applying to the Aware connection as a whole - not to specific publish or subscribe sessions -
- * for that see {@link WifiAwareDiscoverySessionCallback}.
+ * for that see {@link DiscoverySessionCallback}.
*
* @hide PROPOSED_AWARE_API
*/
-public class WifiAwareAttachCallback {
+public class AttachCallback {
/**
* Called when Aware attach operation
- * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}
+ * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}
* is completed and that we can now start discovery sessions or connections.
*
* @param session The Aware object on which we can execute further Aware operations - e.g.
@@ -39,7 +39,7 @@
/**
* Called when Aware attach operation
- * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)} failed.
+ * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)} failed.
*/
public void onAttachFailed() {
/* empty */
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.aidl b/wifi/java/android/net/wifi/aware/Characteristics.aidl
similarity index 94%
rename from wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.aidl
rename to wifi/java/android/net/wifi/aware/Characteristics.aidl
index a35e71d..77305e9 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.aidl
+++ b/wifi/java/android/net/wifi/aware/Characteristics.aidl
@@ -16,4 +16,4 @@
package android.net.wifi.aware;
-parcelable WifiAwareCharacteristics;
+parcelable Characteristics;
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java b/wifi/java/android/net/wifi/aware/Characteristics.java
similarity index 83%
rename from wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
rename to wifi/java/android/net/wifi/aware/Characteristics.java
index 092aa34..1c3e390 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
+++ b/wifi/java/android/net/wifi/aware/Characteristics.java
@@ -25,7 +25,7 @@
*
* @hide PROPOSED_AWARE_API
*/
-public class WifiAwareCharacteristics implements Parcelable {
+public class Characteristics implements Parcelable {
/** @hide */
public static final String KEY_MAX_SERVICE_NAME_LENGTH = "key_max_service_name_length";
/** @hide */
@@ -37,7 +37,7 @@
private Bundle mCharacteristics = new Bundle();
/** @hide : should not be created by apps */
- public WifiAwareCharacteristics(Bundle characteristics) {
+ public Characteristics(Bundle characteristics) {
mCharacteristics = characteristics;
}
@@ -58,7 +58,7 @@
* message exchange. Restricts the parameters of the
* {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
* {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
- * {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, byte[])}
+ * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}
* variants.
*
* @return A positive integer, maximum length of byte array for Aware messaging.
@@ -89,17 +89,17 @@
return 0;
}
- public static final Creator<WifiAwareCharacteristics> CREATOR =
- new Creator<WifiAwareCharacteristics>() {
+ public static final Creator<Characteristics> CREATOR =
+ new Creator<Characteristics>() {
@Override
- public WifiAwareCharacteristics createFromParcel(Parcel in) {
- WifiAwareCharacteristics c = new WifiAwareCharacteristics(in.readBundle());
+ public Characteristics createFromParcel(Parcel in) {
+ Characteristics c = new Characteristics(in.readBundle());
return c;
}
@Override
- public WifiAwareCharacteristics[] newArray(int size) {
- return new WifiAwareCharacteristics[size];
+ public Characteristics[] newArray(int size) {
+ return new Characteristics[size];
}
};
}
diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.java b/wifi/java/android/net/wifi/aware/ConfigRequest.java
index 4b21b15..6a5957b 100644
--- a/wifi/java/android/net/wifi/aware/ConfigRequest.java
+++ b/wifi/java/android/net/wifi/aware/ConfigRequest.java
@@ -22,7 +22,7 @@
/**
* Defines a request object to configure a Wi-Fi Aware network. Built using
* {@link ConfigRequest.Builder}. Configuration is requested using
- * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}.
+ * {@link WifiAwareManager#attach(AttachCallback, android.os.Handler)}.
* Note that the actual achieved configuration may be different from the
* requested configuration - since different applications may request different
* configurations.
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
similarity index 79%
rename from wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
rename to wifi/java/android/net/wifi/aware/DiscoverySession.java
index 2812ad4..c89718f 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -29,21 +29,21 @@
/**
* A class representing a single publish or subscribe Aware session. This object
* will not be created directly - only its child classes are available:
- * {@link WifiAwarePublishDiscoverySession} and {@link WifiAwareSubscribeDiscoverySession}. This
+ * {@link PublishDiscoverySession} and {@link SubscribeDiscoverySession}. This
* class provides functionality common to both publish and subscribe discovery sessions:
* <ul>
- * <li>Sending messages: {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[])} or
- * {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)} methods.
+ * <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} or
+ * {@link #sendMessage(PeerHandle, int, byte[], int)} methods.
* <li>Creating a network-specifier when requesting a Aware connection:
- * {@link #createNetworkSpecifier(WifiAwareManager.PeerHandle, byte[])}.
+ * {@link #createNetworkSpecifier(PeerHandle, byte[])}.
* </ul>
* The {@link #destroy()} method must be called to destroy discovery sessions once they are
* no longer needed.
*
* @hide PROPOSED_AWARE_API
*/
-public class WifiAwareDiscoveryBaseSession {
- private static final String TAG = "WifiAwareDiscBaseSsn";
+public class DiscoverySession {
+ private static final String TAG = "DiscoverySession";
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
@@ -62,7 +62,7 @@
/**
* Return the maximum permitted retry count when sending messages using
- * {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)}.
+ * {@link #sendMessage(PeerHandle, int, byte[], int)}.
*
* @return Maximum retry count when sending messages.
*/
@@ -71,7 +71,7 @@
}
/** @hide */
- public WifiAwareDiscoveryBaseSession(WifiAwareManager manager, int clientId, int sessionId) {
+ public DiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
if (VDBG) {
Log.v(TAG, "New discovery session created: manager=" + manager + ", clientId="
+ clientId + ", sessionId=" + sessionId);
@@ -93,7 +93,7 @@
* This operation must be done on a session which is no longer needed. Otherwise system
* resources will continue to be utilized until the application exits. The only
* exception is a session for which we received a termination callback,
- * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)}.
+ * {@link DiscoverySessionCallback#onSessionTerminated()}.
*/
public void destroy() {
WifiAwareManager mgr = mMgr.get();
@@ -139,23 +139,23 @@
/**
* Sends a message to the specified destination. Aware messages are transmitted in the context
* of a discovery session - executed subsequent to a publish/subscribe
- * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
* byte[], java.util.List)} event.
* <p>
* Aware messages are not guaranteed delivery. Callbacks on
- * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
- * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
+ * {@link DiscoverySessionCallback} indicate message was transmitted successfully,
+ * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
* failed (possibly after several retries) -
- * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}.
+ * {@link DiscoverySessionCallback#onMessageSendFailed(int)}.
* <p>
* The peer will get a callback indicating a message was received using
- * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
* byte[])}.
*
* @param peerHandle The peer's handle for the message. Must be a result of an
- * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
* byte[], java.util.List)} or
- * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
* byte[])} events.
* @param messageId An arbitrary integer used by the caller to identify the message. The same
* integer ID will be returned in the callbacks indicating message send success or
@@ -167,7 +167,7 @@
* (note: no retransmissions are attempted in other failure cases). A value of 0
* indicates no retries. Max permitted value is {@link #getMaxSendRetryCount()}.
*/
- public void sendMessage(@NonNull WifiAwareManager.PeerHandle peerHandle, int messageId,
+ public void sendMessage(@NonNull PeerHandle peerHandle, int messageId,
@Nullable byte[] message, int retryCount) {
if (mTerminated) {
Log.w(TAG, "sendMessage: called on terminated session");
@@ -186,25 +186,25 @@
/**
* Sends a message to the specified destination. Aware messages are transmitted in the context
* of a discovery session - executed subsequent to a publish/subscribe
- * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
* byte[], java.util.List)} event.
* <p>
* Aware messages are not guaranteed delivery. Callbacks on
- * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
- * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
+ * {@link DiscoverySessionCallback} indicate message was transmitted successfully,
+ * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
* failed (possibly after several retries) -
- * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}.
+ * {@link DiscoverySessionCallback#onMessageSendFailed(int)}.
* <p>
* The peer will get a callback indicating a message was received using
- * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
* byte[])}.
- * Equivalent to {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)}
+ * Equivalent to {@link #sendMessage(PeerHandle, int, byte[], int)}
* with a {@code retryCount} of 0.
*
* @param peerHandle The peer's handle for the message. Must be a result of an
- * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
* byte[], java.util.List)} or
- * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
* byte[])} events.
* @param messageId An arbitrary integer used by the caller to identify the message. The same
* integer ID will be returned in the callbacks indicating message send success or
@@ -212,16 +212,16 @@
* can be arbitrary and non-unique.
* @param message The message to be transmitted.
*/
- public void sendMessage(@NonNull WifiAwareManager.PeerHandle peerHandle, int messageId,
+ public void sendMessage(@NonNull PeerHandle peerHandle, int messageId,
@Nullable byte[] message) {
sendMessage(peerHandle, messageId, message, 0);
}
/**
* Start a ranging operation with the specified peers. The peer IDs are obtained from an
- * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
* byte[], java.util.List)} or
- * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
* byte[])} operation - can
* only range devices which are part of an ongoing discovery session.
*
@@ -265,9 +265,9 @@
* and a Publisher is a RESPONDER.
*
* @param peerHandle The peer's handle obtained through
- * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
* byte[], java.util.List)} or
- * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
* byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
* from only that peer. A RESPONDER may specified a null - indicating that
* it will accept connection requests from any device.
@@ -283,7 +283,7 @@
* android.net.ConnectivityManager.NetworkCallback)}
* [or other varieties of that API].
*/
- public String createNetworkSpecifier(@Nullable WifiAwareManager.PeerHandle peerHandle,
+ public String createNetworkSpecifier(@Nullable PeerHandle peerHandle,
@Nullable byte[] token) {
if (mTerminated) {
Log.w(TAG, "createNetworkSpecifier: called on terminated session");
@@ -295,7 +295,7 @@
return null;
}
- int role = this instanceof WifiAwareSubscribeDiscoverySession
+ int role = this instanceof SubscribeDiscoverySession
? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
new file mode 100644
index 0000000..1fe449f
--- /dev/null
+++ b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2016 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.aware;
+
+import android.annotation.NonNull;
+
+import java.util.List;
+
+/**
+ * Base class for Aware session events callbacks. Should be extended by
+ * applications wanting notifications. The callbacks are set when a
+ * publish or subscribe session is created using
+ * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
+ * android.os.Handler)} or
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
+ * android.os.Handler)}.
+ * <p>
+ * A single callback is set at session creation - it cannot be replaced.
+ *
+ * @hide PROPOSED_AWARE_API
+ */
+public class DiscoverySessionCallback {
+ /**
+ * Called when a publish operation is started successfully in response to a
+ * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
+ * android.os.Handler)} operation.
+ *
+ * @param session The {@link PublishDiscoverySession} used to control the
+ * discovery session.
+ */
+ public void onPublishStarted(@NonNull PublishDiscoverySession session) {
+ /* empty */
+ }
+
+ /**
+ * Called when a subscribe operation is started successfully in response to a
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
+ * android.os.Handler)} operation.
+ *
+ * @param session The {@link SubscribeDiscoverySession} used to control the
+ * discovery session.
+ */
+ public void onSubscribeStarted(@NonNull SubscribeDiscoverySession session) {
+ /* empty */
+ }
+
+ /**
+ * Called when a publish or subscribe discovery session configuration update request
+ * succeeds. Called in response to
+ * {@link PublishDiscoverySession#updatePublish(PublishConfig)} or
+ * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+ */
+ public void onSessionConfigUpdated() {
+ /* empty */
+ }
+
+ /**
+ * Called when a publish or subscribe discovery session cannot be created:
+ * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
+ * android.os.Handler)} or
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
+ * android.os.Handler)}, or when a configuration update fails:
+ * {@link PublishDiscoverySession#updatePublish(PublishConfig)} or
+ * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+ * <p>
+ * For discovery session updates failure leaves the session running with its previous
+ * configuration - the discovery session is not terminated.
+ */
+ public void onSessionConfigFailed() {
+ /* empty */
+ }
+
+ /**
+ * Called when a discovery session (publish or subscribe) terminates. Termination may be due
+ * to user-request (either directly through {@link DiscoverySession#destroy()} or
+ * application-specified expiration, e.g. {@link PublishConfig.Builder#setPublishCount(int)}
+ * or {@link SubscribeConfig.Builder#setTtlSec(int)}).
+ */
+ public void onSessionTerminated() {
+ /* empty */
+ }
+
+ /**
+ * Called when a discovery (publish or subscribe) operation results in a
+ * service discovery.
+ *
+ * @param peerHandle An opaque handle to the peer matching our discovery operation.
+ * @param serviceSpecificInfo The service specific information (arbitrary
+ * byte array) provided by the peer as part of its discovery
+ * configuration.
+ * @param matchFilter The filter which resulted in this service discovery.
+ */
+ public void onServiceDiscovered(PeerHandle peerHandle,
+ byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
+ /* empty */
+ }
+
+ /**
+ * Called in response to
+ * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])}
+ * when a message is transmitted successfully - i.e. when it was received successfully by the
+ * peer (corresponds to an ACK being received).
+ * <p>
+ * Note that either this callback or
+ * {@link DiscoverySessionCallback#onMessageSendFailed(int)} will be
+ * received - never both.
+ *
+ * @param messageId The arbitrary message ID specified when sending the message.
+ */
+ public void onMessageSendSucceeded(@SuppressWarnings("unused") int messageId) {
+ /* empty */
+ }
+
+ /**
+ * Called when message transmission fails - when no ACK is received from the peer.
+ * Retries when ACKs are not received are done by hardware, MAC, and in the Aware stack (using
+ * the {@link DiscoverySession#sendMessage(PeerHandle, int,
+ * byte[], int)} method) - this event is received after all retries are exhausted.
+ * <p>
+ * Note that either this callback or
+ * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)} will be received
+ * - never both.
+ *
+ * @param messageId The arbitrary message ID specified when sending the message.
+ */
+ public void onMessageSendFailed(@SuppressWarnings("unused") int messageId) {
+ /* empty */
+ }
+
+ /**
+ * Called when a message is received from a discovery session peer - in response to the
+ * peer's {@link DiscoverySession#sendMessage(PeerHandle, int,
+ * byte[])} or {@link DiscoverySession#sendMessage(PeerHandle,
+ * int, byte[], int)}.
+ *
+ * @param peerHandle An opaque handle to the peer matching our discovery operation.
+ * @param message A byte array containing the message.
+ */
+ public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
+ /* empty */
+ }
+}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
index 9c92807..794c142 100644
--- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
@@ -23,7 +23,7 @@
import android.net.wifi.aware.IWifiAwareEventCallback;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.SubscribeConfig;
-import android.net.wifi.aware.WifiAwareCharacteristics;
+import android.net.wifi.aware.Characteristics;
import android.net.wifi.RttManager;
/**
@@ -37,7 +37,7 @@
void enableUsage();
void disableUsage();
boolean isUsageEnabled();
- WifiAwareCharacteristics getCharacteristics();
+ Characteristics getCharacteristics();
// client API
void connect(in IBinder binder, in String callingPackage, in IWifiAwareEventCallback callback,
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareIdentityChangedListener.java b/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
similarity index 97%
rename from wifi/java/android/net/wifi/aware/WifiAwareIdentityChangedListener.java
rename to wifi/java/android/net/wifi/aware/IdentityChangedListener.java
index e8f52cd4..b0f97bd 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareIdentityChangedListener.java
+++ b/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
@@ -28,7 +28,7 @@
*
* @hide PROPOSED_AWARE_API
*/
-public class WifiAwareIdentityChangedListener {
+public class IdentityChangedListener {
/**
* @param mac The MAC address of the Aware discovery interface. The application must have the
* {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to get the actual MAC address,
diff --git a/wifi/java/android/net/wifi/aware/PeerHandle.java b/wifi/java/android/net/wifi/aware/PeerHandle.java
new file mode 100644
index 0000000..777d9a3
--- /dev/null
+++ b/wifi/java/android/net/wifi/aware/PeerHandle.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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.aware;
+
+/**
+ * Opaque object used to represent a Wi-Fi Aware peer. Obtained from discovery sessions in
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}, used
+ * when sending messages e,g, {@link PublishDiscoverySession#sendMessage(PeerHandle, int, byte[])},
+ * or when configuring a network link to a peer, e.g.
+ * {@link PublishDiscoverySession#createNetworkSpecifier(PeerHandle, byte[])}.
+ *
+ * @hide PROPOSED_AWARE_API
+ */
+public class PeerHandle {
+ /** @hide */
+ public PeerHandle(int peerId) {
+ this.peerId = peerId;
+ }
+
+ /** @hide */
+ public int peerId;
+}
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index 3925bd7..1b8ef84 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -33,9 +33,9 @@
/**
* Defines the configuration of a Aware publish session. Built using
* {@link PublishConfig.Builder}. A publish session is created using
- * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
+ * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
* android.os.Handler)} or updated using
- * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)}.
+ * {@link PublishDiscoverySession#updatePublish(PublishConfig)}.
*
* @hide PROPOSED_AWARE_API
*/
@@ -184,7 +184,7 @@
*
* @hide
*/
- public void assertValid(WifiAwareCharacteristics characteristics)
+ public void assertValid(Characteristics characteristics)
throws IllegalArgumentException {
WifiAwareUtils.validateServiceName(mServiceName);
@@ -322,12 +322,11 @@
* Sets the number of times an unsolicited (configured using
* {@link PublishConfig.Builder#setPublishType(int)}) publish session
* will be broadcast. When the count is reached an event will be
- * generated for {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)}
- * with {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE} [unless
- * {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
+ * generated for {@link DiscoverySessionCallback#onSessionTerminated()}
+ * [unless {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
* <p>
* Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
+ * Session will be terminated when {@link DiscoverySession#destroy()} is
* called.
*
* @param publishCount Number of publish packets to broadcast.
@@ -348,12 +347,11 @@
* {@link PublishConfig.Builder#setPublishType(int)}) publish session
* will be alive - broadcasting a packet. When the TTL is reached
* an event will be generated for
- * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} with
- * {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE} [unless
+ * {@link DiscoverySessionCallback#onSessionTerminated()} [unless
* {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
* <p>
* Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
+ * Session will be terminated when {@link DiscoverySession#destroy()} is
* called.
*
* @param ttlSec Lifetime of a publish session in seconds.
@@ -371,7 +369,7 @@
/**
* Configure whether a publish terminate notification
- * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} is reported
+ * {@link DiscoverySessionCallback#onSessionTerminated()} is reported
* back to the callback.
*
* @param enable If true the terminate callback will be called when the
diff --git a/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java b/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java
similarity index 70%
rename from wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
rename to wifi/java/android/net/wifi/aware/PublishDiscoverySession.java
index 68786d1..f2355b3 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/PublishDiscoverySession.java
@@ -21,32 +21,32 @@
/**
* A class representing a Aware publish session. Created when
- * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
+ * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback,
* android.os.Handler)} is called and a discovery session is created and returned in
- * {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)}. See
- * baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}. This
+ * {@link DiscoverySessionCallback#onPublishStarted(PublishDiscoverySession)}. See
+ * baseline functionality of all discovery sessions in {@link DiscoverySession}. This
* object allows updating an existing/running publish discovery session using
* {@link #updatePublish(PublishConfig)}.
*
* @hide PROPOSED_AWARE_API
*/
-public class WifiAwarePublishDiscoverySession extends WifiAwareDiscoveryBaseSession {
- private static final String TAG = "WifiAwarePublishDiscSsn";
+public class PublishDiscoverySession extends DiscoverySession {
+ private static final String TAG = "PublishDiscoverySession";
/** @hide */
- public WifiAwarePublishDiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
+ public PublishDiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
super(manager, clientId, sessionId);
}
/**
* Re-configure the currently active publish session. The
- * {@link WifiAwareDiscoverySessionCallback} is not replaced - the same listener used
+ * {@link DiscoverySessionCallback} is not replaced - the same listener used
* at creation is still used. The results of the configuration are returned using
- * {@link WifiAwareDiscoverySessionCallback}:
+ * {@link DiscoverySessionCallback}:
* <ul>
- * <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigUpdated()}: configuration
+ * <li>{@link DiscoverySessionCallback#onSessionConfigUpdated()}: configuration
* update succeeded.
- * <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()}: configuration
+ * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()}: configuration
* update failed. The publish discovery session is still running using its previous
* configuration (i.e. update failure does not terminate the session).
* </ul>
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 0fe69a8..a54a4f5 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -33,9 +33,9 @@
/**
* Defines the configuration of a Aware subscribe session. Built using
* {@link SubscribeConfig.Builder}. Subscribe is done using
- * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
* android.os.Handler)} or
- * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+ * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
*
* @hide PROPOSED_AWARE_API
*/
@@ -212,7 +212,7 @@
*
* @hide
*/
- public void assertValid(WifiAwareCharacteristics characteristics)
+ public void assertValid(Characteristics characteristics)
throws IllegalArgumentException {
WifiAwareUtils.validateServiceName(mServiceName);
@@ -355,11 +355,10 @@
* Sets the number of times an active (
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
* will broadcast. When the count is reached an event will be
- * generated for {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)}
- * with {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE}.
+ * generated for {@link DiscoverySessionCallback#onSessionTerminated()}.
* <p>
* Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
+ * Session will be terminated when {@link DiscoverySession#destroy()} is
* called.
*
* @param subscribeCount Number of subscribe packets to broadcast.
@@ -380,11 +379,10 @@
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
* will be alive - i.e. broadcasting a packet. When the TTL is reached
* an event will be generated for
- * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} with
- * {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE}.
+ * {@link DiscoverySessionCallback#onSessionTerminated()}.
* <p>
* Optional. 0 by default - indicating the session doesn't terminate on its own.
- * Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
+ * Session will be terminated when {@link DiscoverySession#destroy()} is
* called.
*
* @param ttlSec Lifetime of a subscribe session in seconds.
@@ -404,8 +402,8 @@
* Sets the match style of the subscription - how are matches from a
* single match session (corresponding to the same publish action on the
* peer) reported to the host (using the
- * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
- * byte[], List)}). The options are: only report the first match and ignore the rest
+ * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[],
+ * java.util.List)}). The options are: only report the first match and ignore the rest
* {@link SubscribeConfig#MATCH_STYLE_FIRST_ONLY} or report every single
* match {@link SubscribeConfig#MATCH_STYLE_ALL} (the default).
*
@@ -424,7 +422,7 @@
/**
* Configure whether a subscribe terminate notification
- * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} is reported
+ * {@link DiscoverySessionCallback#onSessionTerminated()} is reported
* back to the callback.
*
* @param enable If true the terminate callback will be called when the
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java b/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java
similarity index 75%
rename from wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
rename to wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java
index a0ec809..39db1c7 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeDiscoverySession.java
@@ -22,35 +22,35 @@
/**
* A class representing a Aware subscribe session. Created when
* {@link WifiAwareSession#subscribe(SubscribeConfig,
- * WifiAwareDiscoverySessionCallback, android.os.Handler)}
+ * DiscoverySessionCallback, android.os.Handler)}
* is called and a discovery session is created and returned in
- * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(WifiAwareSubscribeDiscoverySession)}.
- * See baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}.
+ * {@link DiscoverySessionCallback#onSubscribeStarted(SubscribeDiscoverySession)}.
+ * See baseline functionality of all discovery sessions in {@link DiscoverySession}.
* This object allows updating an existing/running subscribe discovery session using
* {@link #updateSubscribe(SubscribeConfig)}.
*
* @hide PROPOSED_AWARE_API
*/
-public class WifiAwareSubscribeDiscoverySession extends WifiAwareDiscoveryBaseSession {
- private static final String TAG = "WifiAwareSubsDiscSsn";
+public class SubscribeDiscoverySession extends DiscoverySession {
+ private static final String TAG = "SubscribeDiscSession";
/**
* {@hide}
*/
- public WifiAwareSubscribeDiscoverySession(WifiAwareManager manager, int clientId,
+ public SubscribeDiscoverySession(WifiAwareManager manager, int clientId,
int sessionId) {
super(manager, clientId, sessionId);
}
/**
* Re-configure the currently active subscribe session. The
- * {@link WifiAwareDiscoverySessionCallback} is not replaced - the same listener used
+ * {@link DiscoverySessionCallback} is not replaced - the same listener used
* at creation is still used. The results of the configuration are returned using
- * {@link WifiAwareDiscoverySessionCallback}:
+ * {@link DiscoverySessionCallback}:
* <ul>
- * <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigUpdated()}: configuration
+ * <li>{@link DiscoverySessionCallback#onSessionConfigUpdated()}: configuration
* update succeeded.
- * <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()}: configuration
+ * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()}: configuration
* update failed. The subscribe discovery session is still running using its previous
* configuration (i.e. update failure does not terminate the session).
* </ul>
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
deleted file mode 100644
index fdf0d01..0000000
--- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2016 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.aware;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * Base class for Aware session events callbacks. Should be extended by
- * applications wanting notifications. The callbacks are set when a
- * publish or subscribe session is created using
- * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
- * android.os.Handler)} or
- * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
- * android.os.Handler)}.
- * <p>
- * A single callback is set at session creation - it cannot be replaced.
- *
- * @hide PROPOSED_AWARE_API
- */
-public class WifiAwareDiscoverySessionCallback {
- /** @hide */
- @IntDef({
- TERMINATE_REASON_DONE, TERMINATE_REASON_FAIL })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SessionTerminateCodes {
- }
-
- /**
- * Indicates that publish or subscribe session is done - all the
- * requested operations (per {@link PublishConfig} or
- * {@link SubscribeConfig}) have been executed. Failure reason flag for
- * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} callback.
- */
- public static final int TERMINATE_REASON_DONE = 100;
-
- /**
- * Indicates that publish or subscribe session is terminated due to a
- * failure.
- * Failure reason flag for
- * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} callback.
- */
- public static final int TERMINATE_REASON_FAIL = 101;
-
- /**
- * Called when a publish operation is started successfully in response to a
- * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
- * android.os.Handler)} operation.
- *
- * @param session The {@link WifiAwarePublishDiscoverySession} used to control the
- * discovery session.
- */
- public void onPublishStarted(@NonNull WifiAwarePublishDiscoverySession session) {
- /* empty */
- }
-
- /**
- * Called when a subscribe operation is started successfully in response to a
- * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
- * android.os.Handler)} operation.
- *
- * @param session The {@link WifiAwareSubscribeDiscoverySession} used to control the
- * discovery session.
- */
- public void onSubscribeStarted(@NonNull WifiAwareSubscribeDiscoverySession session) {
- /* empty */
- }
-
- /**
- * Called when a publish or subscribe discovery session configuration update request
- * succeeds. Called in response to
- * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} or
- * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
- */
- public void onSessionConfigUpdated() {
- /* empty */
- }
-
- /**
- * Called when a publish or subscribe discovery session cannot be created:
- * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
- * android.os.Handler)} or
- * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
- * android.os.Handler)}, or when a configuration update fails:
- * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} or
- * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
- * <p>
- * For discovery session updates failure leaves the session running with its previous
- * configuration - the discovery session is not terminated.
- */
- public void onSessionConfigFailed() {
- /* empty */
- }
-
- /**
- * Called when a discovery session (publish or subscribe) terminates. Termination may be due
- * to user-request (either directly through {@link WifiAwareDiscoveryBaseSession#destroy()} or
- * application-specified expiration, e.g. {@link PublishConfig.Builder#setPublishCount(int)}
- * or {@link SubscribeConfig.Builder#setTtlSec(int)}) or due to a failure.
- *
- * @param reason The termination reason using
- * {@code WifiAwareDiscoverySessionCallback.TERMINATE_*} codes.
- */
- public void onSessionTerminated(@SessionTerminateCodes int reason) {
- /* empty */
- }
-
- /**
- * Called when a discovery (publish or subscribe) operation results in a
- * service discovery.
- *
- * @param peerHandle An opaque handle to the peer matching our discovery operation.
- * @param serviceSpecificInfo The service specific information (arbitrary
- * byte array) provided by the peer as part of its discovery
- * configuration.
- * @param matchFilter The filter which resulted in this service discovery.
- */
- public void onServiceDiscovered(WifiAwareManager.PeerHandle peerHandle,
- byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
- /* empty */
- }
-
- /**
- * Called in response to
- * {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, byte[])}
- * when a message is transmitted successfully - i.e. when it was received successfully by the
- * peer (corresponds to an ACK being received).
- * <p>
- * Note that either this callback or
- * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)} will be
- * received - never both.
- *
- * @param messageId The arbitrary message ID specified when sending the message.
- */
- public void onMessageSendSucceeded(@SuppressWarnings("unused") int messageId) {
- /* empty */
- }
-
- /**
- * Called when message transmission fails - when no ACK is received from the peer.
- * Retries when ACKs are not received are done by hardware, MAC, and in the Aware stack (using
- * the {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int,
- * byte[], int)} method) - this event is received after all retries are exhausted.
- * <p>
- * Note that either this callback or
- * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)} will be received
- * - never both.
- *
- * @param messageId The arbitrary message ID specified when sending the message.
- */
- public void onMessageSendFailed(@SuppressWarnings("unused") int messageId) {
- /* empty */
- }
-
- /**
- * Called when a message is received from a discovery session peer - in response to the
- * peer's {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int,
- * byte[])} or {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle,
- * int, byte[], int)}.
- *
- * @param peerHandle An opaque handle to the peer matching our discovery operation.
- * @param message A byte array containing the message.
- */
- public void onMessageReceived(WifiAwareManager.PeerHandle peerHandle, byte[] message) {
- /* empty */
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 029794d..8c0a3a0 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -58,14 +58,14 @@
* The class provides access to:
* <ul>
* <li>Initialize a Aware cluster (peer-to-peer synchronization). Refer to
- * {@link #attach(WifiAwareAttachCallback, Handler)}.
+ * {@link #attach(AttachCallback, Handler)}.
* <li>Create discovery sessions (publish or subscribe sessions). Refer to
- * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)} and
- * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, Handler)}.
+ * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)} and
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback, Handler)}.
* <li>Create a Aware network specifier to be used with
* {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
* to set-up a Aware connection with a peer. Refer to
- * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(PeerHandle, byte[])} and
+ * {@link DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])} and
* {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}.
* </ul>
* <p>
@@ -75,37 +75,37 @@
* broadcast. Note that this broadcast is not sticky - you should register for it and then
* check the above API to avoid a race condition.
* <p>
- * An application must use {@link #attach(WifiAwareAttachCallback, Handler)} to initialize a
+ * An application must use {@link #attach(AttachCallback, Handler)} to initialize a
* Aware cluster - before making any other Aware operation. Aware cluster membership is a
* device-wide operation - the API guarantees that the device is in a cluster or joins a
* Aware cluster (or starts one if none can be found). Information about attach success (or
- * failure) are returned in callbacks of {@link WifiAwareAttachCallback}. Proceed with Aware
+ * failure) are returned in callbacks of {@link AttachCallback}. Proceed with Aware
* discovery or connection setup only after receiving confirmation that Aware attach
- * succeeded - {@link WifiAwareAttachCallback#onAttached(WifiAwareSession)}. When an
+ * succeeded - {@link AttachCallback#onAttached(WifiAwareSession)}. When an
* application is finished using Aware it <b>must</b> use the
* {@link WifiAwareSession#destroy()} API to indicate to the Aware service that the device
* may detach from the Aware cluster. The device will actually disable Aware once the last
* application detaches.
* <p>
* Once a Aware attach is confirmed use the
- * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)}
+ * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)}
* or
- * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback,
* Handler)} to create publish or subscribe Aware discovery sessions. Events are called on the
- * provided callback object {@link WifiAwareDiscoverySessionCallback}. Specifically, the
- * {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)}
+ * provided callback object {@link DiscoverySessionCallback}. Specifically, the
+ * {@link DiscoverySessionCallback#onPublishStarted(PublishDiscoverySession)}
* and
- * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(
- * WifiAwareSubscribeDiscoverySession)}
- * return {@link WifiAwarePublishDiscoverySession} and
- * {@link WifiAwareSubscribeDiscoverySession}
+ * {@link DiscoverySessionCallback#onSubscribeStarted(
+ *SubscribeDiscoverySession)}
+ * return {@link PublishDiscoverySession} and
+ * {@link SubscribeDiscoverySession}
* objects respectively on which additional session operations can be performed, e.g. updating
- * the session {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} and
- * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can
+ * the session {@link PublishDiscoverySession#updatePublish(PublishConfig)} and
+ * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can
* also be used to send messages using the
- * {@link WifiAwareDiscoveryBaseSession#sendMessage(PeerHandle, int, byte[])} APIs. When an
+ * {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])} APIs. When an
* application is finished with a discovery session it <b>must</b> terminate it using the
- * {@link WifiAwareDiscoveryBaseSession#destroy()} API.
+ * {@link DiscoverySession#destroy()} API.
* <p>
* Creating connections between Aware devices is managed by the standard
* {@link ConnectivityManager#requestNetwork(NetworkRequest,
@@ -116,7 +116,7 @@
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
* <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
* {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} or
- * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(PeerHandle, byte[])}.
+ * {@link DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])}.
* </ul>
*
* @hide PROPOSED_AWARE_API
@@ -226,7 +226,7 @@
* Connection creation role is that of INITIATOR. Used to create a network specifier string
* when requesting a Aware network.
*
- * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(PeerHandle, byte[])
+ * @see DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])
* @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
*/
public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0;
@@ -235,7 +235,7 @@
* Connection creation role is that of RESPONDER. Used to create a network specifier string
* when requesting a Aware network.
*
- * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(PeerHandle, byte[])
+ * @see DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])
* @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
*/
public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1;
@@ -307,7 +307,7 @@
* @return An object specifying configuration limitations of Aware.
* @hide PROPOSED_AWARE_API
*/
- public WifiAwareCharacteristics getCharacteristics() {
+ public Characteristics getCharacteristics() {
try {
return mService.getCharacteristics();
} catch (RemoteException e) {
@@ -328,12 +328,12 @@
* attachCallback}.
*
* @param attachCallback A callback for attach events, extended from
- * {@link WifiAwareAttachCallback}.
+ * {@link AttachCallback}.
* @param handler The Handler on whose thread to execute the callbacks of the {@code
* attachCallback} object. If a null is provided then the application's main thread will be
* used.
*/
- public void attach(@NonNull WifiAwareAttachCallback attachCallback, @Nullable Handler handler) {
+ public void attach(@NonNull AttachCallback attachCallback, @Nullable Handler handler) {
attach(handler, null, attachCallback, null);
}
@@ -353,28 +353,28 @@
* on startup and whenever it is updated (it is randomized at regular intervals for privacy).
* The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
* permission to execute this attach request. Otherwise, use the
- * {@link #attach(WifiAwareAttachCallback, Handler)} version. Note that aside from permission
+ * {@link #attach(AttachCallback, Handler)} version. Note that aside from permission
* requirements this listener will wake up the host at regular intervals causing higher power
* consumption, do not use it unless the information is necessary (e.g. for OOB discovery).
*
* @param attachCallback A callback for attach events, extended from
- * {@link WifiAwareAttachCallback}.
+ * {@link AttachCallback}.
* @param identityChangedListener A listener for changed identity, extended from
- * {@link WifiAwareIdentityChangedListener}.
+ * {@link IdentityChangedListener}.
* @param handler The Handler on whose thread to execute the callbacks of the {@code
* attachCallback} and {@code identityChangedListener} objects. If a null is provided then the
* application's main thread will be used.
*/
- public void attach(@NonNull WifiAwareAttachCallback attachCallback,
- @NonNull WifiAwareIdentityChangedListener identityChangedListener,
+ public void attach(@NonNull AttachCallback attachCallback,
+ @NonNull IdentityChangedListener identityChangedListener,
@Nullable Handler handler) {
attach(handler, null, attachCallback, identityChangedListener);
}
/** @hide */
public void attach(Handler handler, ConfigRequest configRequest,
- WifiAwareAttachCallback attachCallback,
- WifiAwareIdentityChangedListener identityChangedListener) {
+ AttachCallback attachCallback,
+ IdentityChangedListener identityChangedListener) {
if (VDBG) {
Log.v(TAG, "attach(): handler=" + handler + ", callback=" + attachCallback
+ ", configRequest=" + configRequest + ", identityChangedListener="
@@ -409,7 +409,7 @@
/** @hide */
public void publish(int clientId, Looper looper, PublishConfig publishConfig,
- WifiAwareDiscoverySessionCallback callback) {
+ DiscoverySessionCallback callback) {
if (VDBG) Log.v(TAG, "publish(): clientId=" + clientId + ", config=" + publishConfig);
try {
@@ -437,7 +437,7 @@
/** @hide */
public void subscribe(int clientId, Looper looper, SubscribeConfig subscribeConfig,
- WifiAwareDiscoverySessionCallback callback) {
+ DiscoverySessionCallback callback) {
if (VDBG) {
if (VDBG) {
Log.v(TAG,
@@ -672,14 +672,14 @@
}
/**
- * Constructs a {@link WifiAwareAttachCallback} using the specified looper.
+ * Constructs a {@link AttachCallback} using the specified looper.
* All callbacks will delivered on the thread of the specified looper.
*
* @param looper The looper on which to execute the callbacks.
*/
WifiAwareEventCallbackProxy(WifiAwareManager mgr, Looper looper, Binder binder,
- final WifiAwareAttachCallback attachCallback,
- final WifiAwareIdentityChangedListener identityChangedListener) {
+ final AttachCallback attachCallback,
+ final IdentityChangedListener identityChangedListener) {
mAwareManager = new WeakReference<>(mgr);
mLooper = looper;
mBinder = binder;
@@ -828,14 +828,14 @@
private final WeakReference<WifiAwareManager> mAwareManager;
private final boolean mIsPublish;
- private final WifiAwareDiscoverySessionCallback mOriginalCallback;
+ private final DiscoverySessionCallback mOriginalCallback;
private final int mClientId;
private final Handler mHandler;
- private WifiAwareDiscoveryBaseSession mSession;
+ private DiscoverySession mSession;
WifiAwareDiscoverySessionCallbackProxy(WifiAwareManager mgr, Looper looper,
- boolean isPublish, WifiAwareDiscoverySessionCallback originalCallback,
+ boolean isPublish, DiscoverySessionCallback originalCallback,
int clientId) {
mAwareManager = new WeakReference<>(mgr);
mIsPublish = isPublish;
@@ -1006,13 +1006,13 @@
}
if (mIsPublish) {
- WifiAwarePublishDiscoverySession session = new WifiAwarePublishDiscoverySession(mgr,
+ PublishDiscoverySession session = new PublishDiscoverySession(mgr,
mClientId, sessionId);
mSession = session;
mOriginalCallback.onPublishStarted(session);
} else {
- WifiAwareSubscribeDiscoverySession
- session = new WifiAwareSubscribeDiscoverySession(mgr, mClientId, sessionId);
+ SubscribeDiscoverySession
+ session = new SubscribeDiscoverySession(mgr, mClientId, sessionId);
mSession = session;
mOriginalCallback.onSubscribeStarted(session);
}
@@ -1027,18 +1027,7 @@
Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
}
mAwareManager.clear();
- mOriginalCallback.onSessionTerminated(reason);
+ mOriginalCallback.onSessionTerminated();
}
}
-
- /** @hide PROPOSED_AWARE_API */
- public static class PeerHandle {
- /** @hide */
- public PeerHandle(int peerId) {
- this.peerId = peerId;
- }
-
- /** @hide */
- public int peerId;
- }
}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 005895a..e3ebe86 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -65,7 +65,7 @@
* session-wide destroy.
* <p>
* An application may re-attach after a destroy using
- * {@link WifiAwareManager#attach(WifiAwareAttachCallback, Handler)} .
+ * {@link WifiAwareManager#attach(AttachCallback, Handler)} .
*/
public void destroy() {
WifiAwareManager mgr = mMgr.get();
@@ -95,22 +95,22 @@
/**
* Issue a request to the Aware service to create a new Aware publish discovery session, using
* the specified {@code publishConfig} configuration. The results of the publish operation
- * are routed to the callbacks of {@link WifiAwareDiscoverySessionCallback}:
+ * are routed to the callbacks of {@link DiscoverySessionCallback}:
* <ul>
* <li>
- * {@link WifiAwareDiscoverySessionCallback#onPublishStarted(
- * WifiAwarePublishDiscoverySession)}
+ * {@link DiscoverySessionCallback#onPublishStarted(
+ *PublishDiscoverySession)}
* is called when the publish session is created and provides a handle to the session.
* Further operations on the publish session can be executed on that object.
- * <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()} is called if the
+ * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()} is called if the
* publish operation failed.
* </ul>
* <p>
* Other results of the publish session operations will also be routed to callbacks
* on the {@code callback} object. The resulting publish session can be modified using
- * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)}.
+ * {@link PublishDiscoverySession#updatePublish(PublishConfig)}.
* <p>
- * An application must use the {@link WifiAwareDiscoveryBaseSession#destroy()} to
+ * An application must use the {@link DiscoverySession#destroy()} to
* terminate the publish discovery session once it isn't needed. This will free
* resources as well terminate any on-air transmissions.
* <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
@@ -118,13 +118,13 @@
*
* @param publishConfig The {@link PublishConfig} specifying the
* configuration of the requested publish session.
- * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for
+ * @param callback A {@link DiscoverySessionCallback} derived object to be used for
* session event callbacks.
* @param handler The Handler on whose thread to execute the callbacks of the {@code
* callback} object. If a null is provided then the application's main thread will be used.
*/
public void publish(@NonNull PublishConfig publishConfig,
- @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) {
+ @NonNull DiscoverySessionCallback callback, @Nullable Handler handler) {
WifiAwareManager mgr = mMgr.get();
if (mgr == null) {
Log.e(TAG, "publish: called post GC on WifiAwareManager");
@@ -141,22 +141,22 @@
/**
* Issue a request to the Aware service to create a new Aware subscribe discovery session, using
* the specified {@code subscribeConfig} configuration. The results of the subscribe
- * operation are routed to the callbacks of {@link WifiAwareDiscoverySessionCallback}:
+ * operation are routed to the callbacks of {@link DiscoverySessionCallback}:
* <ul>
* <li>
- * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(
- * WifiAwareSubscribeDiscoverySession)}
+ * {@link DiscoverySessionCallback#onSubscribeStarted(
+ *SubscribeDiscoverySession)}
* is called when the subscribe session is created and provides a handle to the session.
* Further operations on the subscribe session can be executed on that object.
- * <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()} is called if the
+ * <li>{@link DiscoverySessionCallback#onSessionConfigFailed()} is called if the
* subscribe operation failed.
* </ul>
* <p>
* Other results of the subscribe session operations will also be routed to callbacks
* on the {@code callback} object. The resulting subscribe session can be modified using
- * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+ * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
* <p>
- * An application must use the {@link WifiAwareDiscoveryBaseSession#destroy()} to
+ * An application must use the {@link DiscoverySession#destroy()} to
* terminate the subscribe discovery session once it isn't needed. This will free
* resources as well terminate any on-air transmissions.
* <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
@@ -164,13 +164,13 @@
*
* @param subscribeConfig The {@link SubscribeConfig} specifying the
* configuration of the requested subscribe session.
- * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for
+ * @param callback A {@link DiscoverySessionCallback} derived object to be used for
* session event callbacks.
* @param handler The Handler on whose thread to execute the callbacks of the {@code
* callback} object. If a null is provided then the application's main thread will be used.
*/
public void subscribe(@NonNull SubscribeConfig subscribeConfig,
- @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) {
+ @NonNull DiscoverySessionCallback callback, @Nullable Handler handler) {
WifiAwareManager mgr = mMgr.get();
if (mgr == null) {
Log.e(TAG, "publish: called post GC on WifiAwareManager");
@@ -193,7 +193,7 @@
* This API is targeted for applications which can obtain the peer MAC address using OOB
* (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
* when using Aware discovery use the alternative network specifier method -
- * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(WifiAwareManager.PeerHandle,
+ * {@link DiscoverySession#createNetworkSpecifier(PeerHandle,
* byte[])}.
*
* @param role The role of this device:
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 24c0127..a396d87 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -67,19 +67,19 @@
public Context mockContext;
@Mock
- public WifiAwareAttachCallback mockCallback;
+ public AttachCallback mockCallback;
@Mock
- public WifiAwareDiscoverySessionCallback mockSessionCallback;
+ public DiscoverySessionCallback mockSessionCallback;
@Mock
public IWifiAwareManager mockAwareService;
@Mock
- public WifiAwarePublishDiscoverySession mockPublishSession;
+ public PublishDiscoverySession mockPublishSession;
@Mock
- public WifiAwareSubscribeDiscoverySession mockSubscribeSession;
+ public SubscribeDiscoverySession mockSubscribeSession;
@Mock
public RttManager.RttListener mockRttListener;
@@ -276,7 +276,7 @@
final int sessionId = 123;
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final PublishConfig publishConfig = new PublishConfig.Builder().build();
- final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873);
+ final PeerHandle peerHandle = new PeerHandle(873);
final String string1 = "hey from here...";
final byte[] matchFilter = { 1, 12, 2, 31, 32 };
final int messageId = 2123;
@@ -290,10 +290,9 @@
.forClass(IWifiAwareEventCallback.class);
ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
.forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<WifiAwarePublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(WifiAwarePublishDiscoverySession.class);
- ArgumentCaptor<WifiAwareManager.PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(
- WifiAwareManager.PeerHandle.class);
+ ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
+ .forClass(PublishDiscoverySession.class);
+ ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
ArgumentCaptor<List<byte[]>> matchFilterCaptor = ArgumentCaptor.forClass(
(Class) List.class);
@@ -377,7 +376,6 @@
final int sessionId = 123;
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final PublishConfig publishConfig = new PublishConfig.Builder().build();
- final int reason = WifiAwareDiscoverySessionCallback.TERMINATE_REASON_DONE;
InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
mockPublishSession);
@@ -387,8 +385,8 @@
.forClass(IWifiAwareEventCallback.class);
ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
.forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<WifiAwarePublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(WifiAwarePublishDiscoverySession.class);
+ ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
+ .forClass(PublishDiscoverySession.class);
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
@@ -404,10 +402,10 @@
inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig),
sessionProxyCallback.capture());
sessionProxyCallback.getValue().onSessionStarted(sessionId);
- sessionProxyCallback.getValue().onSessionTerminated(reason);
+ sessionProxyCallback.getValue().onSessionTerminated(0);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
- inOrder.verify(mockSessionCallback).onSessionTerminated(reason);
+ inOrder.verify(mockSessionCallback).onSessionTerminated();
// (3) failure when trying to update: NOP
publishSession.getValue().updatePublish(publishConfig);
@@ -428,7 +426,7 @@
final int sessionId = 123;
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
- final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873);
+ final PeerHandle peerHandle = new PeerHandle(873);
final String string1 = "hey from here...";
final byte[] matchFilter = { 1, 12, 3, 31, 32 }; // bad data!
final int messageId = 2123;
@@ -442,10 +440,9 @@
.forClass(IWifiAwareEventCallback.class);
ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
.forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<WifiAwareSubscribeDiscoverySession> subscribeSession = ArgumentCaptor
- .forClass(WifiAwareSubscribeDiscoverySession.class);
- ArgumentCaptor<WifiAwareManager.PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(
- WifiAwareManager.PeerHandle.class);
+ ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
+ .forClass(SubscribeDiscoverySession.class);
+ ArgumentCaptor<PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(PeerHandle.class);
// (0) connect + success
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
@@ -516,7 +513,6 @@
final int sessionId = 123;
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
- final int reason = WifiAwareDiscoverySessionCallback.TERMINATE_REASON_DONE;
InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
mockSubscribeSession);
@@ -526,8 +522,8 @@
.forClass(IWifiAwareEventCallback.class);
ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
.forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<WifiAwareSubscribeDiscoverySession> subscribeSession = ArgumentCaptor
- .forClass(WifiAwareSubscribeDiscoverySession.class);
+ ArgumentCaptor<SubscribeDiscoverySession> subscribeSession = ArgumentCaptor
+ .forClass(SubscribeDiscoverySession.class);
// (1) connect successfully
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
@@ -543,10 +539,10 @@
inOrder.verify(mockAwareService).subscribe(eq(clientId), eq(subscribeConfig),
sessionProxyCallback.capture());
sessionProxyCallback.getValue().onSessionStarted(sessionId);
- sessionProxyCallback.getValue().onSessionTerminated(reason);
+ sessionProxyCallback.getValue().onSessionTerminated(0);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
- inOrder.verify(mockSessionCallback).onSessionTerminated(reason);
+ inOrder.verify(mockSessionCallback).onSessionTerminated();
// (3) failure when trying to update: NOP
subscribeSession.getValue().updateSubscribe(subscribeConfig);
@@ -892,8 +888,8 @@
.forClass(IWifiAwareEventCallback.class);
ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
.forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<WifiAwarePublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(WifiAwarePublishDiscoverySession.class);
+ ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
+ .forClass(PublishDiscoverySession.class);
ArgumentCaptor<RttManager.ParcelableRttParams> rttParamCaptor = ArgumentCaptor
.forClass(RttManager.ParcelableRttParams.class);
ArgumentCaptor<RttManager.RttResult[]> rttResultsCaptor = ArgumentCaptor
@@ -953,7 +949,7 @@
public void testNetworkSpecifierWithClient() throws Exception {
final int clientId = 4565;
final int sessionId = 123;
- final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(123412);
+ final PeerHandle peerHandle = new PeerHandle(123412);
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
final String token = "Some arbitrary token string - can really be anything";
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
@@ -967,8 +963,8 @@
.forClass(IWifiAwareEventCallback.class);
ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor
.forClass(IWifiAwareDiscoverySessionCallback.class);
- ArgumentCaptor<WifiAwarePublishDiscoverySession> publishSession = ArgumentCaptor
- .forClass(WifiAwarePublishDiscoverySession.class);
+ ArgumentCaptor<PublishDiscoverySession> publishSession = ArgumentCaptor
+ .forClass(PublishDiscoverySession.class);
InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockAwareService,
mockPublishSession, mockRttListener);