diff options
37 files changed, 704 insertions, 385 deletions
diff --git a/api/current.txt b/api/current.txt index 25741b3e79e6..8a00273ba893 100644 --- a/api/current.txt +++ b/api/current.txt @@ -59087,8 +59087,8 @@ package java.util { method public static void rotate(java.util.List<?>, int); method public static void shuffle(java.util.List<?>); method public static void shuffle(java.util.List<?>, java.util.Random); - method public static <E> java.util.Set<E> singleton(E); - method public static <E> java.util.List<E> singletonList(E); + method public static <T> java.util.Set<T> singleton(T); + method public static <T> java.util.List<T> singletonList(T); method public static <K, V> java.util.Map<K, V> singletonMap(K, V); method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>); method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>); diff --git a/api/system-current.txt b/api/system-current.txt index bfa590c7c85b..3ecc8aa575c9 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -62614,8 +62614,8 @@ package java.util { method public static void rotate(java.util.List<?>, int); method public static void shuffle(java.util.List<?>); method public static void shuffle(java.util.List<?>, java.util.Random); - method public static <E> java.util.Set<E> singleton(E); - method public static <E> java.util.List<E> singletonList(E); + method public static <T> java.util.Set<T> singleton(T); + method public static <T> java.util.List<T> singletonList(T); method public static <K, V> java.util.Map<K, V> singletonMap(K, V); method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>); method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>); diff --git a/api/test-current.txt b/api/test-current.txt index 4a54733c4f74..13b0c941fb17 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -59348,8 +59348,8 @@ package java.util { method public static void rotate(java.util.List<?>, int); method public static void shuffle(java.util.List<?>); method public static void shuffle(java.util.List<?>, java.util.Random); - method public static <E> java.util.Set<E> singleton(E); - method public static <E> java.util.List<E> singletonList(E); + method public static <T> java.util.Set<T> singleton(T); + method public static <T> java.util.List<T> singletonList(T); method public static <K, V> java.util.Map<K, V> singletonMap(K, V); method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>); method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>); diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 38e35722604c..bfa6d349a9f6 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -61,6 +61,11 @@ public abstract class ActivityManagerInternal { */ public static final int APP_TRANSITION_TIMEOUT = 3; + /** + * Verify that calling app has access to the given provider. + */ + public abstract String checkContentProviderAccess(String authority, int userId); + // Called by the power manager. public abstract void onWakefulnessChanged(int wakefulness); diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java index 6a73829da154..ef2db4a0d795 100644 --- a/core/java/android/app/ApplicationLoaders.java +++ b/core/java/android/app/ApplicationLoaders.java @@ -16,17 +16,19 @@ package android.app; +import android.os.Build; import android.os.Trace; import android.util.ArrayMap; import com.android.internal.os.PathClassLoaderFactory; import dalvik.system.PathClassLoader; -class ApplicationLoaders { +/** @hide */ +public class ApplicationLoaders { public static ApplicationLoaders getDefault() { return gApplicationLoaders; } - public ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled, + ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled, String librarySearchPath, String libraryPermittedPath, ClassLoader parent) { /* @@ -80,6 +82,19 @@ class ApplicationLoaders { } } + /** + * Creates a classloader for the WebView APK and places it in the cache of loaders maintained + * by this class. This is used in the WebView zygote, where its presence in the cache speeds up + * startup and enables memory sharing. + */ + public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath) { + // The correct paths are calculated by WebViewZygote in the system server and passed to + // us here. We hardcode the other parameters: WebView always targets the current SDK, + // does not need to use non-public system libraries, and uses the base classloader as its + // parent to permit usage of the cache. + return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null); + } + private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath); /** diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 827e02696e2b..496c05f5f1df 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -33,7 +33,6 @@ import android.content.IntentSender; import android.content.ReceiverCallNotAllowedException; import android.content.ServiceConnection; import android.content.SharedPreferences; -import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; @@ -160,7 +159,7 @@ class ContextImpl extends Context { private final String mOpPackageName; private final @NonNull ResourcesManager mResourcesManager; - private final @NonNull Resources mResources; + private @NonNull Resources mResources; private @Nullable Display mDisplay; // may be null if default display private final int mFlags; @@ -1835,6 +1834,19 @@ class ContextImpl extends Context { } } + private static Resources createResources(IBinder activityToken, LoadedApk pi, int displayId, + Configuration overrideConfig, CompatibilityInfo compatInfo) { + return ResourcesManager.getInstance().getResources(activityToken, + pi.getResDir(), + pi.getSplitResDirs(), + pi.getOverlayDirs(), + pi.getApplicationInfo().sharedLibraryFiles, + displayId, + overrideConfig, + compatInfo, + pi.getClassLoader()); + } + @Override public Context createApplicationContext(ApplicationInfo application, int flags) throws NameNotFoundException { @@ -1842,8 +1854,13 @@ class ContextImpl extends Context { flags | CONTEXT_REGISTER_PACKAGE); if (pi != null) { ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken, - new UserHandle(UserHandle.getUserId(application.uid)), flags, - mDisplay, null, Display.INVALID_DISPLAY); + new UserHandle(UserHandle.getUserId(application.uid)), flags); + + final int displayId = mDisplay != null + ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; + + c.mResources = createResources(mActivityToken, pi, displayId, null, + getDisplayAdjustments(displayId).getCompatibilityInfo()); if (c.mResources != null) { return c; } @@ -1864,15 +1881,21 @@ class ContextImpl extends Context { public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) throws NameNotFoundException { if (packageName.equals("system") || packageName.equals("android")) { - return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, - user, flags, mDisplay, null, Display.INVALID_DISPLAY); + // The system resources are loaded in every application, so we can safely copy + // the context without reloading Resources. + return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, user, flags); } LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier()); if (pi != null) { - ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken, - user, flags, mDisplay, null, Display.INVALID_DISPLAY); + ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken, user, flags); + + final int displayId = mDisplay != null + ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; + + c.mResources = createResources(mActivityToken, pi, displayId, null, + getDisplayAdjustments(displayId).getCompatibilityInfo()); if (c.mResources != null) { return c; } @@ -1889,8 +1912,14 @@ class ContextImpl extends Context { throw new IllegalArgumentException("overrideConfiguration must not be null"); } - return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, - mUser, mFlags, mDisplay, overrideConfiguration, Display.INVALID_DISPLAY); + ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, + mUser, mFlags); + + final int displayId = mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; + context.mResources = createResources(mActivityToken, mPackageInfo, displayId, + overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo()); + context.mDisplay = mDisplay; + return context; } @Override @@ -1899,24 +1928,28 @@ class ContextImpl extends Context { throw new IllegalArgumentException("display must not be null"); } - return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, - mUser, mFlags, display, null, Display.INVALID_DISPLAY); + ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, + mUser, mFlags); + + final int displayId = display.getDisplayId(); + context.mResources = createResources(mActivityToken, mPackageInfo, displayId, null, + getDisplayAdjustments(displayId).getCompatibilityInfo()); + context.mDisplay = display; + return context; } @Override public Context createDeviceProtectedStorageContext() { final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) | Context.CONTEXT_DEVICE_PROTECTED_STORAGE; - return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, - mUser, flags, mDisplay, null, Display.INVALID_DISPLAY); + return new ContextImplFlagContextWrapper(this, flags); } @Override public Context createCredentialProtectedStorageContext() { final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE) | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE; - return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, - mUser, flags, mDisplay, null, Display.INVALID_DISPLAY); + return new ContextImplFlagContextWrapper(this, flags); } @Override @@ -2003,8 +2036,8 @@ class ContextImpl extends Context { static ContextImpl createSystemContext(ActivityThread mainThread) { LoadedApk packageInfo = new LoadedApk(mainThread); - ContextImpl context = new ContextImpl(null, mainThread, - packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY); + ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0); + context.mResources = packageInfo.getResources(mainThread); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics()); return context; @@ -2012,21 +2045,35 @@ class ContextImpl extends Context { static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); - return new ContextImpl(null, mainThread, - packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY); + ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0); + context.mResources = packageInfo.getResources(mainThread); + return context; } static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); - return new ContextImpl(null, mainThread, packageInfo, activityToken, null, 0, - null, overrideConfiguration, displayId); + + ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityToken, null, + 0); + + // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY. + displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY; + + final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY) + ? packageInfo.getCompatibilityInfo() + : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; + + context.mResources = createResources(activityToken, packageInfo, displayId, + overrideConfiguration, compatInfo); + context.mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId, + context.mResources.getDisplayAdjustments()); + return context; } private ContextImpl(ContextImpl container, ActivityThread mainThread, - LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags, - Display display, Configuration overrideConfiguration, int createDisplayWithId) { + LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags) { mOuterContext = this; // If creator didn't specify which storage to use, use the default @@ -2053,64 +2100,11 @@ class ContextImpl extends Context { mPackageInfo = packageInfo; mResourcesManager = ResourcesManager.getInstance(); - final int displayId = (createDisplayWithId != Display.INVALID_DISPLAY) - ? createDisplayWithId - : (display != null) ? display.getDisplayId() : Display.DEFAULT_DISPLAY; - - CompatibilityInfo compatInfo = null; - if (container != null) { - compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo(); - } - if (compatInfo == null) { - compatInfo = (displayId == Display.DEFAULT_DISPLAY) - ? packageInfo.getCompatibilityInfo() - : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; - } - - Resources resources = packageInfo.getResources(mainThread); - if (resources != null) { - if (displayId != Display.DEFAULT_DISPLAY - || overrideConfiguration != null - || (compatInfo != null && compatInfo.applicationScale - != resources.getCompatibilityInfo().applicationScale)) { - - if (container != null) { - // This is a nested Context, so it can't be a base Activity context. - // Just create a regular Resources object associated with the Activity. - resources = mResourcesManager.getResources( - activityToken, - packageInfo.getResDir(), - packageInfo.getSplitResDirs(), - packageInfo.getOverlayDirs(), - packageInfo.getApplicationInfo().sharedLibraryFiles, - displayId, - overrideConfiguration, - compatInfo, - packageInfo.getClassLoader()); - } else { - // This is not a nested Context, so it must be the root Activity context. - // All other nested Contexts will inherit the configuration set here. - resources = mResourcesManager.createBaseActivityResources( - activityToken, - packageInfo.getResDir(), - packageInfo.getSplitResDirs(), - packageInfo.getOverlayDirs(), - packageInfo.getApplicationInfo().sharedLibraryFiles, - displayId, - overrideConfiguration, - compatInfo, - packageInfo.getClassLoader()); - } - } - } - mResources = resources; - - mDisplay = (createDisplayWithId == Display.INVALID_DISPLAY) ? display - : mResourcesManager.getAdjustedDisplay(displayId, mResources.getDisplayAdjustments()); - if (container != null) { mBasePackageName = container.mBasePackageName; mOpPackageName = container.mOpPackageName; + mResources = container.getResources(); + mDisplay = container.getDisplay(); } else { mBasePackageName = packageInfo.mPackageName; ApplicationInfo ainfo = packageInfo.getApplicationInfo(); diff --git a/core/java/android/app/ContextImplFlagContextWrapper.java b/core/java/android/app/ContextImplFlagContextWrapper.java new file mode 100644 index 000000000000..a83f13020dd1 --- /dev/null +++ b/core/java/android/app/ContextImplFlagContextWrapper.java @@ -0,0 +1,43 @@ +/* + * 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.app; + +import android.content.Context; +import android.content.ContextWrapper; + +class ContextImplFlagContextWrapper extends ContextWrapper { + private final int mFlags; + + public ContextImplFlagContextWrapper(Context base, int flags) { + super(base); + mFlags = flags; + } + + @Override + public boolean isRestricted() { + return (mFlags & Context.CONTEXT_RESTRICTED) != 0; + } + + @Override + public boolean isDeviceProtectedStorage() { + return (mFlags & Context.CONTEXT_DEVICE_PROTECTED_STORAGE) != 0; + } + + @Override + public boolean isCredentialProtectedStorage() { + return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0; + } +} diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index da99e8005f38..725cc29bd323 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -21,6 +21,7 @@ import android.annotation.RequiresPermission; import android.app.trust.ITrustManager; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Binder; import android.os.RemoteException; @@ -45,6 +46,7 @@ public class KeyguardManager { private IWindowManager mWM; private ITrustManager mTrustManager; private IUserManager mUserManager; + private Context mContext; /** * Intent used to prompt user for device credentials. @@ -87,8 +89,12 @@ public class KeyguardManager { Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL); intent.putExtra(EXTRA_TITLE, title); intent.putExtra(EXTRA_DESCRIPTION, description); - // For security reasons, only allow this to come from system settings. - intent.setPackage("com.android.settings"); + if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) { + intent.setPackage("com.google.android.apps.wearable.settings"); + } else { + // For security reasons, only allow this to come from system settings. + intent.setPackage("com.android.settings"); + } return intent; } @@ -109,8 +115,12 @@ public class KeyguardManager { intent.putExtra(EXTRA_TITLE, title); intent.putExtra(EXTRA_DESCRIPTION, description); intent.putExtra(Intent.EXTRA_USER_ID, userId); - // For security reasons, only allow this to come from system settings. - intent.setPackage("com.android.settings"); + if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) { + intent.setPackage("com.google.android.apps.wearable.settings"); + } else { + // For security reasons, only allow this to come from system settings. + intent.setPackage("com.android.settings"); + } return intent; } @@ -193,7 +203,8 @@ public class KeyguardManager { } - KeyguardManager() throws ServiceNotFoundException { + KeyguardManager(Context context) throws ServiceNotFoundException { + mContext = context; mWM = WindowManagerGlobal.getWindowManagerService(); mTrustManager = ITrustManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.TRUST_SERVICE)); diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index a38377e67709..94d24e49945b 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -339,39 +339,43 @@ public final class LoadedApk { * concatenation of both apps' shared library lists. */ - String instrumentationPackageName = activityThread.mInstrumentationPackageName; - String instrumentationAppDir = activityThread.mInstrumentationAppDir; - String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs; - String instrumentationLibDir = activityThread.mInstrumentationLibDir; - - String instrumentedAppDir = activityThread.mInstrumentedAppDir; - String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs; - String instrumentedLibDir = activityThread.mInstrumentedLibDir; String[] instrumentationLibs = null; - - if (appDir.equals(instrumentationAppDir) - || appDir.equals(instrumentedAppDir)) { - outZipPaths.clear(); - outZipPaths.add(instrumentationAppDir); - if (instrumentationSplitAppDirs != null) { - Collections.addAll(outZipPaths, instrumentationSplitAppDirs); - } - if (!instrumentationAppDir.equals(instrumentedAppDir)) { - outZipPaths.add(instrumentedAppDir); - if (instrumentedSplitAppDirs != null) { - Collections.addAll(outZipPaths, instrumentedSplitAppDirs); + // activityThread will be null when called from the WebView zygote; just assume + // no instrumentation applies in this case. + if (activityThread != null) { + String instrumentationPackageName = activityThread.mInstrumentationPackageName; + String instrumentationAppDir = activityThread.mInstrumentationAppDir; + String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs; + String instrumentationLibDir = activityThread.mInstrumentationLibDir; + + String instrumentedAppDir = activityThread.mInstrumentedAppDir; + String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs; + String instrumentedLibDir = activityThread.mInstrumentedLibDir; + + if (appDir.equals(instrumentationAppDir) + || appDir.equals(instrumentedAppDir)) { + outZipPaths.clear(); + outZipPaths.add(instrumentationAppDir); + if (instrumentationSplitAppDirs != null) { + Collections.addAll(outZipPaths, instrumentationSplitAppDirs); + } + if (!instrumentationAppDir.equals(instrumentedAppDir)) { + outZipPaths.add(instrumentedAppDir); + if (instrumentedSplitAppDirs != null) { + Collections.addAll(outZipPaths, instrumentedSplitAppDirs); + } } - } - if (outLibPaths != null) { - outLibPaths.add(instrumentationLibDir); - if (!instrumentationLibDir.equals(instrumentedLibDir)) { - outLibPaths.add(instrumentedLibDir); + if (outLibPaths != null) { + outLibPaths.add(instrumentationLibDir); + if (!instrumentationLibDir.equals(instrumentedLibDir)) { + outLibPaths.add(instrumentedLibDir); + } } - } - if (!instrumentedAppDir.equals(instrumentationAppDir)) { - instrumentationLibs = getLibrariesFor(instrumentationPackageName); + if (!instrumentedAppDir.equals(instrumentationAppDir)) { + instrumentationLibs = getLibrariesFor(instrumentationPackageName); + } } } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index f38c0d817047..3ecc309d75da 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -322,10 +322,10 @@ final class SystemServiceRegistry { }}); registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class, - new StaticServiceFetcher<KeyguardManager>() { + new CachedServiceFetcher<KeyguardManager>() { @Override - public KeyguardManager createService() throws ServiceNotFoundException { - return new KeyguardManager(); + public KeyguardManager createService(ContextImpl ctx) throws ServiceNotFoundException { + return new KeyguardManager(ctx); }}); registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class, diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java index 29ea5a07ee9b..945858e6d3c6 100644 --- a/core/java/android/content/pm/ParceledListSlice.java +++ b/core/java/android/content/pm/ParceledListSlice.java @@ -17,15 +17,12 @@ package android.content.pm; import android.os.Binder; -import android.os.Build; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; -import dalvik.system.VMRuntime; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -130,11 +127,7 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { } public List<T> getList() { - if (VMRuntime.getRuntime().getTargetSdkVersion() > Build.VERSION_CODES.N_MR1) { - return Collections.unmodifiableList(mList); - } else { - return mList; - } + return mList; } @Override diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index 1ac9fca51b77..e7436be273a3 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -108,6 +108,26 @@ public class TrafficStats { */ public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04; + /** @hide */ + public static final int TAG_SYSTEM_DHCP = 0xFFFFFF05; + /** @hide */ + public static final int TAG_SYSTEM_NTP = 0xFFFFFF06; + /** @hide */ + public static final int TAG_SYSTEM_PROBE = 0xFFFFFF07; + /** @hide */ + public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF08; + /** @hide */ + public static final int TAG_SYSTEM_GPS = 0xFFFFFF09; + /** @hide */ + public static final int TAG_SYSTEM_PAC = 0xFFFFFF0A; + + /** + * Sockets that are strictly local on device; never hits network. + * + * @hide + */ + public static final int TAG_SYSTEM_LOCAL = 0xFFFFFFAA; + private static INetworkStatsService sStatsService; private synchronized static INetworkStatsService getStatsService() { diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java index 3734831b0db2..5f27e3430bc4 100644 --- a/core/java/android/service/autofill/AutoFillService.java +++ b/core/java/android/service/autofill/AutoFillService.java @@ -114,6 +114,11 @@ public abstract class AutoFillService extends Service { private HandlerCaller mHandlerCaller; + /** + * {@inheritDoc} + * + * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}. + */ @Override public void onCreate() { super.onCreate(); diff --git a/core/java/android/service/autofill/IAutoFillCallback.aidl b/core/java/android/service/autofill/IAutoFillCallback.aidl index db8ef96976a2..d6d4f39651da 100644 --- a/core/java/android/service/autofill/IAutoFillCallback.aidl +++ b/core/java/android/service/autofill/IAutoFillCallback.aidl @@ -21,7 +21,7 @@ import java.util.List; /** * @hide */ -interface IAutoFillCallback { +oneway interface IAutoFillCallback { void autofill(in List values); void showError(String message); } diff --git a/core/java/android/service/autofill/IAutoFillManagerService.aidl b/core/java/android/service/autofill/IAutoFillManagerService.aidl index cab073f7045f..76a25614f8ec 100644 --- a/core/java/android/service/autofill/IAutoFillManagerService.aidl +++ b/core/java/android/service/autofill/IAutoFillManagerService.aidl @@ -23,7 +23,7 @@ import android.os.Bundle; * * {@hide} */ -interface IAutoFillManagerService { +oneway interface IAutoFillManagerService { /** * Request auto-fill on the top activity of a given user. diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl index e3e911c39215..bb122e5eff7d 100644 --- a/core/java/android/service/autofill/IAutoFillService.aidl +++ b/core/java/android/service/autofill/IAutoFillService.aidl @@ -25,7 +25,7 @@ import com.android.internal.os.IResultReceiver; * @hide */ interface IAutoFillService { - void onConnected(); - void onDisconnected(); + oneway void onConnected(); + oneway void onDisconnected(); IResultReceiver getAssistReceiver(); } diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index c14789506888..eb0c44c3a07d 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -57,7 +57,9 @@ import java.util.zip.ZipFile; @SystemApi public final class WebViewFactory { - private static final String CHROMIUM_WEBVIEW_FACTORY = + // visible for WebViewZygoteInit to look up the class by reflection and call preloadInZygote. + /** @hide */ + public static final String CHROMIUM_WEBVIEW_FACTORY = "com.android.webview.chromium.WebViewChromiumFactoryProvider"; private static final String CHROMIUM_WEBVIEW_FACTORY_METHOD = "create"; diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java index bc6e7b4a9dd3..c2069741d6cd 100644 --- a/core/java/android/webkit/WebViewZygote.java +++ b/core/java/android/webkit/WebViewZygote.java @@ -16,14 +16,19 @@ package android.webkit; +import android.app.LoadedApk; import android.content.pm.PackageInfo; import android.os.Build; import android.os.SystemService; import android.os.ZygoteProcess; +import android.text.TextUtils; import android.util.Log; +import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeoutException; /** @hide */ @@ -122,11 +127,21 @@ public class WebViewZygote { try { sZygote = new ZygoteProcess("webview_zygote", null); - String packagePath = sPackage.applicationInfo.sourceDir; - String libsPath = sPackage.applicationInfo.nativeLibraryDir; - - Log.d(LOGTAG, "Preloading package " + packagePath + " " + libsPath); - sZygote.preloadPackageForAbi(packagePath, libsPath, Build.SUPPORTED_ABIS[0]); + // All the work below is usually done by LoadedApk, but the zygote can't talk to + // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so + // doesn't have an ActivityThread and can't use Binder. + // Instead, figure out the paths here, in the system server where we have access to + // the package manager. Reuse the logic from LoadedApk to determine the correct + // paths and pass them to the zygote as strings. + final List<String> zipPaths = new ArrayList<>(10); + final List<String> libPaths = new ArrayList<>(10); + LoadedApk.makePaths(null, sPackage.applicationInfo, zipPaths, libPaths); + final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths); + final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) : + TextUtils.join(File.pathSeparator, zipPaths); + + Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); + sZygote.preloadPackageForAbi(zip, librarySearchPath, Build.SUPPORTED_ABIS[0]); } catch (Exception e) { Log.e(LOGTAG, "Error connecting to " + serviceName, e); sZygote = null; diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java index 11dd0e8771a7..d968e3c939ab 100644 --- a/core/java/com/android/internal/os/WebViewZygoteInit.java +++ b/core/java/com/android/internal/os/WebViewZygoteInit.java @@ -16,14 +16,17 @@ package com.android.internal.os; +import android.app.ApplicationLoaders; import android.net.LocalSocket; import android.os.Build; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; import android.util.Log; +import android.webkit.WebViewFactory; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; /** * Startup class for the WebView zygote process. @@ -52,7 +55,27 @@ class WebViewZygoteInit { @Override protected boolean handlePreloadPackage(String packagePath, String libsPath) { - // TODO: Use preload information to setup the ClassLoader. + // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that + // our children will reuse the same classloader instead of creating their own. + // This enables us to preload Java and native code in the webview zygote process and + // have the preloaded versions actually be used post-fork. + ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader( + packagePath, libsPath); + + // 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. + try { + Class providerClass = Class.forName(WebViewFactory.CHROMIUM_WEBVIEW_FACTORY, true, + loader); + Object result = providerClass.getMethod("preloadInZygote").invoke(null); + if (!((Boolean)result).booleanValue()) { + Log.e(TAG, "preloadInZygote returned false"); + } + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | + IllegalAccessException | InvocationTargetException e) { + Log.e(TAG, "Exception while preloading package", e); + } return false; } } diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp index fbccfd5532e2..4391d93721b1 100644 --- a/core/jni/android_hardware_location_ContextHubService.cpp +++ b/core/jni/android_hardware_location_ContextHubService.cpp @@ -16,26 +16,26 @@ #include "context_hub.h" +#undef LOG_NDEBUG +#undef LOG_TAG #define LOG_NDEBUG 0 #define LOG_TAG "ContextHubService" #include <inttypes.h> #include <jni.h> -#include <mutex> -#include <string.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> - -// TOOD: On master, alphabetize these and move <mutex> into this -// grouping. -#include <chrono> -#include <unordered_map> -#include <queue> +#include <string.h> #include <android-base/macros.h> #include <cutils/log.h> +#include <chrono> +#include <mutex> +#include <queue> +#include <unordered_map> + #include "JNIHelp.h" #include "core_jni_helpers.h" @@ -1180,7 +1180,6 @@ static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_, } if (setAddressSuccess && hubId >= 0) { - ALOGD("Asking HAL to remove app"); retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg); } else { ALOGD("Could not find app instance %" PRId32 " on hubHandle %" PRId32 diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java index 2348ab7c7585..52a68bfd96f9 100644 --- a/media/java/android/media/MediaHTTPService.java +++ b/media/java/android/media/MediaHTTPService.java @@ -17,6 +17,7 @@ package android.media; import android.os.IBinder; +import android.util.Log; /** @hide */ public class MediaHTTPService extends IMediaHTTPService.Stub { @@ -31,10 +32,10 @@ public class MediaHTTPService extends IMediaHTTPService.Stub { /* package private */static IBinder createHttpServiceBinderIfNecessary( String path) { - if (path.startsWith("http://") - || path.startsWith("https://") - || path.startsWith("widevine://")) { + if (path.startsWith("http://") || path.startsWith("https://")) { return (new MediaHTTPService()).asBinder(); + } else if (path.startsWith("widevine://")) { + Log.d(TAG, "Widevine classic is no longer supported"); } return null; diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index 5bfc17fcaaf9..9b48e4d02623 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -104,8 +104,8 @@ public class RecentsTaskLoadPlan { int currentUserId = UserHandle.USER_CURRENT; updateCurrentQuietProfilesCache(currentUserId); SystemServicesProxy ssp = Recents.getSystemServices(); - mRawTasks = new ArrayList<>(ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), - currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles)); + mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), + currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles); // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it Collections.reverse(mRawTasks); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a3f79eaf2866..c8ed872932c7 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8106,7 +8106,12 @@ public class ActivityManagerService extends IActivityManager.Stub // Third... does the caller itself have permission to access // this uri? - if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { + final int callingAppId = UserHandle.getAppId(callingUid); + if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) { + Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission" + + " grant to " + grantUri + "; use startActivityAsCaller() instead"); + return -1; + } else { if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { // Require they hold a strong enough Uri permission if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { @@ -10341,6 +10346,46 @@ public class ActivityManagerService extends IActivityManager.Stub } /** + * Check if the calling UID has a possible chance at accessing the provider + * at the given authority and user. + */ + public String checkContentProviderAccess(String authority, int userId) { + if (userId == UserHandle.USER_ALL) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); + userId = UserHandle.getCallingUserId(); + } + + ProviderInfo cpi = null; + try { + cpi = AppGlobals.getPackageManager().resolveContentProvider(authority, + STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS + | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, + userId); + } catch (RemoteException ignored) { + } + if (cpi == null) { + // TODO: make this an outright failure in a future platform release; + // until then anonymous content notifications are unprotected + //return "Failed to find provider " + authority + " for user " + userId; + return null; + } + + ProcessRecord r = null; + synchronized (mPidsSelfLocked) { + r = mPidsSelfLocked.get(Binder.getCallingPid()); + } + if (r == null) { + return "Failed to find PID " + Binder.getCallingPid(); + } + + synchronized (this) { + return checkContentProviderPermissionLocked(cpi, r, userId, true); + } + } + + /** * Check if {@link ProcessRecord} has a possible chance at accessing the * given {@link ProviderInfo}. Final permission checking is always done * in {@link ContentProvider}. @@ -22082,6 +22127,11 @@ public class ActivityManagerService extends IActivityManager.Stub private final class LocalService extends ActivityManagerInternal { @Override + public String checkContentProviderAccess(String authority, int userId) { + return ActivityManagerService.this.checkContentProviderAccess(authority, userId); + } + + @Override public void onWakefulnessChanged(int wakefulness) { ActivityManagerService.this.onWakefulnessChanged(wakefulness); } diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 3b4cef4be3d3..886c97f4ce17 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -20,11 +20,11 @@ import android.Manifest; import android.accounts.Account; import android.annotation.Nullable; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.job.JobInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; -import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.IContentService; @@ -65,7 +65,6 @@ import com.android.server.SystemService; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -295,24 +294,15 @@ public final class ContentService extends IContentService.Stub { final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); - final int callingUserHandle = UserHandle.getCallingUserId(); - // Registering an observer for any user other than the calling user requires uri grant or - // cross user permission - if (callingUserHandle != userHandle) { - if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle) - != PackageManager.PERMISSION_GRANTED) { - enforceCrossUserPermission(userHandle, - "no permission to observe other users' provider view"); - } - } - if (userHandle < 0) { - if (userHandle == UserHandle.USER_CURRENT) { - userHandle = ActivityManager.getCurrentUser(); - } else if (userHandle != UserHandle.USER_ALL) { - throw new InvalidParameterException("Bad user handle for registerContentObserver: " - + userHandle); - } + userHandle = handleIncomingUser(uri, pid, uid, + Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle); + + final String msg = LocalServices.getService(ActivityManagerInternal.class) + .checkContentProviderAccess(uri.getAuthority(), userHandle); + if (msg != null) { + Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg); + return; } synchronized (mRootNode) { @@ -362,22 +352,15 @@ public final class ContentService extends IContentService.Stub { final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); final int callingUserHandle = UserHandle.getCallingUserId(); - // Notify for any user other than the caller requires uri grant or cross user permission - if (callingUserHandle != userHandle) { - if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, - userHandle) != PackageManager.PERMISSION_GRANTED) { - enforceCrossUserPermission(userHandle, "no permission to notify other users"); - } - } - // We passed the permission check; resolve pseudouser targets as appropriate - if (userHandle < 0) { - if (userHandle == UserHandle.USER_CURRENT) { - userHandle = ActivityManager.getCurrentUser(); - } else if (userHandle != UserHandle.USER_ALL) { - throw new InvalidParameterException("Bad user handle for notifyChange: " - + userHandle); - } + userHandle = handleIncomingUser(uri, pid, uid, + Intent.FLAG_GRANT_WRITE_URI_PERMISSION, userHandle); + + final String msg = LocalServices.getService(ActivityManagerInternal.class) + .checkContentProviderAccess(uri.getAuthority(), userHandle); + if (msg != null) { + Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg); + return; } // This makes it so that future permission checks will be in the context of this @@ -1142,6 +1125,27 @@ public final class ContentService extends IContentService.Stub { } } + private int handleIncomingUser(Uri uri, int pid, int uid, int modeFlags, int userId) { + if (userId == UserHandle.USER_CURRENT) { + userId = ActivityManager.getCurrentUser(); + } + + if (userId == UserHandle.USER_ALL) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); + } else if (userId < 0) { + throw new IllegalArgumentException("Invalid user: " + userId); + } else if (userId != UserHandle.getCallingUserId()) { + if (checkUriPermission(uri, pid, uid, modeFlags, + userId) != PackageManager.PERMISSION_GRANTED) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); + } + } + + return userId; + } + /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS_FULL * permission, if the userHandle is not for the caller. diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp index e6072bb03ccc..a3ab8f67d2fa 100644 --- a/services/core/jni/com_android_server_lights_LightsService.cpp +++ b/services/core/jni/com_android_server_lights_LightsService.cpp @@ -34,6 +34,9 @@ using Brightness = ::android::hardware::light::V2_0::Brightness; using Flash = ::android::hardware::light::V2_0::Flash; using Type = ::android::hardware::light::V2_0::Type; using LightState = ::android::hardware::light::V2_0::LightState; +using Status = ::android::hardware::light::V2_0::Status; +template<typename T> +using Return = ::android::hardware::Return<T>; static sp<ILight> gLight; @@ -108,9 +111,33 @@ static void setLight_native( state.brightnessMode = brightness; + Status status; + { ALOGD_IF_SLOW(50, "Excessive delay setting light"); - gLight->setLight(type, state); + Return<Status> ret = gLight->setLight(type, state); + + // TODO(b/31348667): this is transport specific status + if (!ret.getStatus().isOk()) { + ALOGE("Failed to issue set light command."); + return; + } + + status = static_cast<Status>(ret); // hal status + } + + switch (status) { + case Status::SUCCESS: + break; + case Status::LIGHT_NOT_SUPPORTED: + ALOGE("Light requested not availale on this device."); + break; + case Status::BRIGHTNESS_NOT_SUPPORTED: + ALOGE("Brightness parameter not supported on this device."); + break; + case Status::UNKNOWN: + default: + ALOGE("Unknown error setting light."); } } diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java index 6b919df290bb..f4c9c86fda2a 100644 --- a/services/print/java/com/android/server/print/RemotePrintSpooler.java +++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java @@ -43,6 +43,7 @@ import android.printservice.PrintService; import android.util.Slog; import android.util.TimedRemoteCaller; +import com.android.internal.annotations.GuardedBy; import com.android.internal.os.TransferPipe; import libcore.io.IoUtils; @@ -112,6 +113,10 @@ final class RemotePrintSpooler { private boolean mCanUnbind; + /** Whether a thread is currently trying to {@link #bindLocked() bind to the print service} */ + @GuardedBy("mLock") + private boolean mIsBinding; + public static interface PrintSpoolerCallbacks { public void onPrintJobQueued(PrintJobInfo printJob); public void onAllPrintJobsForServiceHandled(ComponentName printService); @@ -164,10 +169,8 @@ final class RemotePrintSpooler { try { return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(), componentName, state, appId); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error getting print jobs.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error getting print jobs.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error getting print jobs.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()"); @@ -188,10 +191,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().createPrintJob(printJob); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error creating print job.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error creating print job.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error creating print job.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()"); @@ -211,10 +212,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().writePrintJobData(fd, printJobId); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error writing print job data.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error writing print job data.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error writing print job data.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()"); @@ -238,10 +237,8 @@ final class RemotePrintSpooler { try { return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(), printJobId, appId); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error getting print job info.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error getting print job info.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error getting print job info.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()"); @@ -263,10 +260,8 @@ final class RemotePrintSpooler { try { return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(), printJobId, state, error); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error setting print job state.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error setting print job state.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting print job state.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()"); @@ -294,7 +289,7 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().setProgress(printJobId, progress); - } catch (RemoteException|TimeoutException re) { + } catch (RemoteException | TimeoutException | InterruptedException re) { Slog.e(LOG_TAG, "Error setting progress.", re); } finally { if (DEBUG) { @@ -321,8 +316,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().setStatus(printJobId, status); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error setting status.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting status.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); @@ -350,8 +345,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().setStatusRes(printJobId, status, appPackageName); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error setting status.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting status.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); @@ -380,7 +375,7 @@ final class RemotePrintSpooler { try { mCustomPrinterIconLoadedCaller.onCustomPrinterIconLoaded(getRemoteInstanceLazy(), printerId, icon); - } catch (RemoteException|TimeoutException re) { + } catch (RemoteException | TimeoutException | InterruptedException re) { Slog.e(LOG_TAG, "Error loading new custom printer icon.", re); } finally { if (DEBUG) { @@ -412,8 +407,8 @@ final class RemotePrintSpooler { try { return mGetCustomPrinterIconCaller.getCustomPrinterIcon(getRemoteInstanceLazy(), printerId); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error getting custom printer icon.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error getting custom printer icon.", e); return null; } finally { if (DEBUG) { @@ -438,8 +433,8 @@ final class RemotePrintSpooler { } try { mClearCustomPrinterIconCache.clearCustomPrinterIconCache(getRemoteInstanceLazy()); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, @@ -462,10 +457,8 @@ final class RemotePrintSpooler { try { return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(), printJobId, tag); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error setting print job tag.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error setting print job tag.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting print job tag.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()"); @@ -487,10 +480,8 @@ final class RemotePrintSpooler { try { getRemoteInstanceLazy().setPrintJobCancelling(printJobId, cancelling); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error setting print job cancelling.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error setting print job cancelling.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting print job cancelling.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() @@ -516,8 +507,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().pruneApprovedPrintServices(servicesToKeep); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error pruning approved print services.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error pruning approved print services.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() @@ -538,9 +529,7 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().removeObsoletePrintJobs(); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re); - } catch (TimeoutException te) { + } catch (RemoteException | TimeoutException | InterruptedException te) { Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te); } finally { if (DEBUG) { @@ -578,7 +567,7 @@ final class RemotePrintSpooler { try { TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd, new String[] { prefix }); - } catch (IOException | TimeoutException | RemoteException e) { + } catch (IOException | TimeoutException | RemoteException | InterruptedException e) { pw.println("Failed to dump remote instance: " + e); } } @@ -595,7 +584,7 @@ final class RemotePrintSpooler { mCallbacks.onPrintJobStateChanged(printJob); } - private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException { + private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException, InterruptedException { synchronized (mLock) { if (mRemoteInstance != null) { return mRemoteInstance; @@ -605,43 +594,50 @@ final class RemotePrintSpooler { } } - private void bindLocked() throws TimeoutException { + private void bindLocked() throws TimeoutException, InterruptedException { + while (mIsBinding) { + mLock.wait(); + } + if (mRemoteInstance != null) { return; } + + mIsBinding = true; + if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked() " + (mIsLowPriority ? "low priority" : "")); } - int flags; - if (mIsLowPriority) { - flags = Context.BIND_AUTO_CREATE; - } else { - flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; - } + try { + int flags; + if (mIsLowPriority) { + flags = Context.BIND_AUTO_CREATE; + } else { + flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; + } - mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle); + mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle); - final long startMillis = SystemClock.uptimeMillis(); - while (true) { - if (mRemoteInstance != null) { - break; - } - final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; - final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis; - if (remainingMillis <= 0) { - throw new TimeoutException("Cannot get spooler!"); - } - try { + final long startMillis = SystemClock.uptimeMillis(); + while (true) { + if (mRemoteInstance != null) { + break; + } + final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; + final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis; + if (remainingMillis <= 0) { + throw new TimeoutException("Cannot get spooler!"); + } mLock.wait(remainingMillis); - } catch (InterruptedException ie) { - /* ignore */ } - } - mCanUnbind = true; - mLock.notifyAll(); + mCanUnbind = true; + } finally { + mIsBinding = false; + mLock.notifyAll(); + } } private void unbindLocked() { diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java new file mode 100644 index 000000000000..379d4fe00afb --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java @@ -0,0 +1,104 @@ +/* + * 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 com.android.server.pm; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PermissionInfo; +import android.platform.test.annotations.Presubmit; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.util.ArraySet; + +import com.android.internal.os.RoSystemProperties; +import com.android.server.SystemConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static junit.framework.Assert.assertTrue; + + +/** + * Presubmit tests for {@link PackageManager}. + */ +@RunWith(AndroidJUnit4.class) +public class PackageManagerPresubmitTest { + + private Context mContext; + + private PackageManager mPackageManager; + + @Before + public void setUp() { + mContext = InstrumentationRegistry.getContext(); + mPackageManager = mContext.getPackageManager(); + } + + /** + * <p>This test ensures that all signature|privileged permissions are granted to core apps like + * systemui/settings. If CONTROL_PRIVAPP_PERMISSIONS is set, the test also verifies that + * granted permissions are whitelisted in {@link SystemConfig} + */ + @Test + @SmallTest + @Presubmit + public void testPrivAppPermissions() throws PackageManager.NameNotFoundException { + String[] testPackages = {"com.android.settings", "com.android.shell", + "com.android.systemui"}; + for (String testPackage : testPackages) { + testPackagePrivAppPermission(testPackage); + } + } + + private void testPackagePrivAppPermission(String testPackage) + throws PackageManager.NameNotFoundException { + PackageInfo packageInfo = mPackageManager.getPackageInfo(testPackage, + PackageManager.GET_PERMISSIONS); + ArraySet<String> privAppPermissions = SystemConfig.getInstance() + .getPrivAppPermissions(testPackage); + for (int i = 0; i < packageInfo.requestedPermissions.length; i++) { + String pName = packageInfo.requestedPermissions[i]; + int protectionLevel; + boolean platformPermission; + try { + PermissionInfo permissionInfo = mPackageManager.getPermissionInfo(pName, 0); + platformPermission = PackageManagerService.PLATFORM_PACKAGE_NAME.equals( + permissionInfo.packageName); + protectionLevel = permissionInfo.protectionLevel; + } catch (PackageManager.NameNotFoundException e) { + continue; + } + if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { + boolean granted = (packageInfo.requestedPermissionsFlags[i] + & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0; + assertTrue("Permission " + pName + " should be granted to " + testPackage, granted); + // if CONTROL_PRIVAPP_PERMISSIONS enabled, platform permissions must be whitelisted + // in SystemConfig + if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS) { + assertTrue("Permission " + pName + + " should be declared in the xml file for package " + + testPackage, + privAppPermissions.contains(pName)); + } + } + } + } +} diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java index 5d3ad0582f9c..ba493a024a13 100644 --- a/wifi/java/android/net/wifi/aware/PublishConfig.java +++ b/wifi/java/android/net/wifi/aware/PublishConfig.java @@ -32,9 +32,8 @@ import java.util.Arrays; /** * Defines the configuration of a Aware publish session. Built using * {@link PublishConfig.Builder}. A publish session is created using - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * or updated using + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} or updated using * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)}. * * @hide PROPOSED_AWARE_API diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java index 2a6cc93146b4..5e14f8f761e0 100644 --- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java +++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java @@ -32,9 +32,8 @@ import java.util.Arrays; /** * Defines the configuration of a Aware subscribe session. Built using * {@link SubscribeConfig.Builder}. Subscribe is done using - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} - * or + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} or * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. * * @hide PROPOSED_AWARE_API @@ -403,8 +402,8 @@ public final class SubscribeConfig implements Parcelable { * 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(Object, byte[], byte[])} - * ). The options are: only report the first match and ignore the rest + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])}). 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). * diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java index 2cace6143f4f..1e8dbd945b6e 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java @@ -18,7 +18,7 @@ package android.net.wifi.aware; /** * Base class for Aware attach callbacks. Should be extended by applications and set when calling - * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}. These are callbacks + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, 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}. * @@ -27,7 +27,7 @@ package android.net.wifi.aware; public class WifiAwareAttachCallback { /** * Called when Aware attach operation - * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)} + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, 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 @@ public class WifiAwareAttachCallback { /** * Called when Aware attach operation - * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)} failed. + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)} failed. */ public void onAttachFailed() { /* empty */ diff --git a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java index 6232c14e0f18..072ccab1eb96 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java @@ -58,7 +58,8 @@ public class WifiAwareCharacteristics implements Parcelable { * message exchange. Restricts the parameters of the * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])}, * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and - * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} variants. + * {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, byte[])} + * variants. * * @return A positive integer, maximum length of byte array for Aware messaging. */ diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java index 07f752396d3d..e8335d11407a 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java @@ -32,10 +32,10 @@ import java.lang.ref.WeakReference; * {@link WifiAwarePublishDiscoverySession} and {@link WifiAwareSubscribeDiscoverySession}. This * class provides functionality common to both publish and subscribe discovery sessions: * <ul> - * <li>Sending messages: {@link #sendMessage(Object, int, byte[])} or - * {@link #sendMessage(Object, int, byte[], int)} methods. + * <li>Sending messages: {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[])} or + * {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)} methods. * <li>Creating a network-specifier when requesting a Aware connection: - * {@link #createNetworkSpecifier(int, Object, byte[])}. + * {@link #createNetworkSpecifier(int, WifiAwareManager.PeerHandle, byte[])}. * </ul> * The {@link #destroy()} method must be called to destroy discovery sessions once they are * no longer needed. @@ -62,7 +62,7 @@ public class WifiAwareDiscoveryBaseSession { /** * Return the maximum permitted retry count when sending messages using - * {@link #sendMessage(Object, int, byte[], int)}. + * {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)}. * * @return Maximum retry count when sending messages. */ @@ -139,21 +139,24 @@ public class WifiAwareDiscoveryBaseSession { /** * 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(Object, byte[], byte[])} event. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} event. * <p> * Aware messages are not guaranteed delivery. Callbacks on * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully, - * {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed - * (possibly after several retries) - + * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission + * failed (possibly after several retries) - * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}. * <p> * The peer will get a callback indicating a message was received using - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}. + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])}. * * @param peerHandle The peer's handle for the message. Must be a result of an - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} - * or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.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 * failure. The {@code messageId} is not used internally by the Aware service - it @@ -164,8 +167,8 @@ public class WifiAwareDiscoveryBaseSession { * (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 Object peerHandle, int messageId, @Nullable byte[] message, - int retryCount) { + public void sendMessage(@NonNull WifiAwareManager.PeerHandle peerHandle, int messageId, + @Nullable byte[] message, int retryCount) { if (mTerminated) { Log.w(TAG, "sendMessage: called on terminated session"); return; @@ -183,37 +186,43 @@ public class WifiAwareDiscoveryBaseSession { /** * 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(Object, byte[], byte[])} event. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} event. * <p> * Aware messages are not guaranteed delivery. Callbacks on * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully, - * {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed - * (possibly after several retries) - + * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission + * failed (possibly after several retries) - * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}. * <p> - * The peer will get a callback indicating a message was received using - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}. - * Equivalent to {@link #sendMessage(Object, int, byte[], int)} with a {@code retryCount} of - * 0. + * The peer will get a callback indicating a message was received using + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])}. + * Equivalent to {@link #sendMessage(WifiAwareManager.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(Object, byte[], byte[])} - * or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.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 * failure. The {@code messageId} is not used internally by the Aware service - it * can be arbitrary and non-unique. * @param message The message to be transmitted. */ - public void sendMessage(@NonNull Object peerHandle, int messageId, @Nullable byte[] message) { + public void sendMessage(@NonNull WifiAwareManager.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(Object, byte[], byte[])} or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} operation - can + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])} operation - can * only range devices which are part of an ongoing discovery session. * * @param params RTT parameters - each corresponding to a specific peer ID (the array sizes @@ -256,11 +265,12 @@ public class WifiAwareDiscoveryBaseSession { * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER} * @param peerHandle The peer's handle obtained through - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, 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. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.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. * @param token An arbitrary token (message) to be used to match connection initiation request * to a responder setup. A RESPONDER is set up with a {@code token} which must * be matched by the token provided by the INITIATOR. A null token is permitted @@ -274,7 +284,7 @@ public class WifiAwareDiscoveryBaseSession { * [or other varieties of that API]. */ public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role, - @Nullable Object peerHandle, @Nullable byte[] token) { + @Nullable WifiAwareManager.PeerHandle peerHandle, @Nullable byte[] token) { if (mTerminated) { Log.w(TAG, "createNetworkSpecifier: called on terminated session"); return null; diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java index 9dfa24fd7232..6331c9c726c9 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java @@ -26,11 +26,10 @@ import java.lang.annotation.RetentionPolicy; * 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(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * or - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} . + * {@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. * @@ -62,9 +61,8 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a publish operation is started successfully in response to a - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * operation. + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} operation. * * @param session The {@link WifiAwarePublishDiscoverySession} used to control the * discovery session. @@ -75,9 +73,8 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a subscribe operation is started successfully in response to a - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} - * operation. + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} operation. * * @param session The {@link WifiAwareSubscribeDiscoverySession} used to control the * discovery session. @@ -98,12 +95,10 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a publish or subscribe discovery session cannot be created: - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * or - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)}, - * or when a configuration update fails: + * {@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> @@ -138,13 +133,14 @@ public class WifiAwareDiscoverySessionCallback { * @param matchFilter The filter (Tx on advertiser and Rx on listener) which * resulted in this service discovery. */ - public void onServiceDiscovered(Object peerHandle, byte[] serviceSpecificInfo, - byte[] matchFilter) { + public void onServiceDiscovered(WifiAwareManager.PeerHandle peerHandle, + byte[] serviceSpecificInfo, byte[] matchFilter) { /* empty */ } /** - * Called in response to {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} + * 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> @@ -154,18 +150,18 @@ public class WifiAwareDiscoverySessionCallback { * * @param messageId The arbitrary message ID specified when sending the message. */ - public void onMessageSent(@SuppressWarnings("unused") int messageId) { + 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(Object, int, byte[], int)} method) - - * this event is received after all retries are exhausted. + * 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#onMessageSent(int)} will be received + * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)} will be received * - never both. * * @param messageId The arbitrary message ID specified when sending the message. @@ -176,13 +172,14 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a message is received from a discovery session peer - in response to the - * peer's {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} or - * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[], int)}. + * 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(Object peerHandle, byte[] 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 10b70abad9df..a34ef4777d65 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -56,14 +56,14 @@ import java.util.Arrays; * The class provides access to: * <ul> * <li>Initialize a Aware cluster (peer-to-peer synchronization). Refer to - * {@link #attach(Handler, WifiAwareAttachCallback)}. + * {@link #attach(WifiAwareAttachCallback, Handler)}. * <li>Create discovery sessions (publish or subscribe sessions). Refer to - * {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)} and - * {@link WifiAwareSession#subscribe(Handler, SubscribeConfig, WifiAwareDiscoverySessionCallback)}. + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)} and + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, 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(int, Object, byte[])} and + * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])} and * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}. * </ul> * <p> @@ -73,7 +73,7 @@ import java.util.Arrays; * 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(Handler, WifiAwareAttachCallback)} to initialize a + * An application must use {@link #attach(WifiAwareAttachCallback, 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 @@ -86,12 +86,11 @@ import java.util.Arrays; * application detaches. * <p> * Once a Aware attach is confirmed use the - * {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)} + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)} * or - * {@link WifiAwareSession#subscribe(Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} - * to create publish or subscribe Aware discovery sessions. Events are called on the provided - * callback object {@link WifiAwareDiscoverySessionCallback}. Specifically, the + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * 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)} * and * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted( @@ -102,7 +101,7 @@ import java.util.Arrays; * the session {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} and * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can * also be used to send messages using the - * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} APIs. When an + * {@link WifiAwareDiscoveryBaseSession#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. * <p> @@ -115,7 +114,7 @@ import java.util.Arrays; * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}. * <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} or - * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}. + * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])}. * </ul> * * @hide PROPOSED_AWARE_API @@ -225,7 +224,7 @@ public class WifiAwareManager { * Connection creation role is that of INITIATOR. Used to create a network specifier string * when requesting a Aware network. * - * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[]) + * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[]) * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[]) */ public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; @@ -234,7 +233,7 @@ public class WifiAwareManager { * Connection creation role is that of RESPONDER. Used to create a network specifier string * when requesting a Aware network. * - * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[]) + * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[]) * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[]) */ public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; @@ -326,13 +325,13 @@ public class WifiAwareManager { * then this function will simply indicate success immediately using the same {@code * attachCallback}. * + * @param attachCallback A callback for attach events, extended from + * {@link WifiAwareAttachCallback}. * @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. - * @param attachCallback A callback for attach events, extended from - * {@link WifiAwareAttachCallback}. */ - public void attach(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback) { + public void attach(@NonNull WifiAwareAttachCallback attachCallback, @Nullable Handler handler) { attach(handler, null, attachCallback, null); } @@ -352,20 +351,21 @@ public class WifiAwareManager { * 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(Handler, WifiAwareAttachCallback)} version. Note that aside from permission + * {@link #attach(WifiAwareAttachCallback, 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 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. * @param attachCallback A callback for attach events, extended from * {@link WifiAwareAttachCallback}. * @param identityChangedListener A listener for changed identity, extended from * {@link WifiAwareIdentityChangedListener}. + * @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(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback, - @NonNull WifiAwareIdentityChangedListener identityChangedListener) { + public void attach(@NonNull WifiAwareAttachCallback attachCallback, + @NonNull WifiAwareIdentityChangedListener identityChangedListener, + @Nullable Handler handler) { attach(handler, null, attachCallback, identityChangedListener); } @@ -481,7 +481,7 @@ public class WifiAwareManager { } /** @hide */ - public void sendMessage(int clientId, int sessionId, Object peerHandle, byte[] message, + public void sendMessage(int clientId, int sessionId, PeerHandle peerHandle, byte[] message, int messageId, int retryCount) { if (peerHandle == null) { throw new IllegalArgumentException( @@ -490,13 +490,13 @@ public class WifiAwareManager { if (VDBG) { Log.v(TAG, "sendMessage(): clientId=" + clientId + ", sessionId=" + sessionId - + ", peerHandle=" + ((OpaquePeerHandle) peerHandle).peerId + ", messageId=" + + ", peerHandle=" + peerHandle.peerId + ", messageId=" + messageId + ", retryCount=" + retryCount); } try { - mService.sendMessage(clientId, sessionId, ((OpaquePeerHandle) peerHandle).peerId, - message, messageId, retryCount); + mService.sendMessage(clientId, sessionId, peerHandle.peerId, message, messageId, + retryCount); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -524,12 +524,12 @@ public class WifiAwareManager { } /** @hide */ - public String createNetworkSpecifier(int clientId, int role, int sessionId, Object peerHandle, - byte[] token) { + public String createNetworkSpecifier(int clientId, int role, int sessionId, + PeerHandle peerHandle, byte[] token) { if (VDBG) { Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId - + ", peerHandle=" + ((peerHandle == null) ? peerHandle - : ((OpaquePeerHandle) peerHandle).peerId) + ", token=" + token); + + ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId) + + ", token=" + token); } int type; @@ -569,7 +569,7 @@ public class WifiAwareManager { json.put(NETWORK_SPECIFIER_KEY_CLIENT_ID, clientId); json.put(NETWORK_SPECIFIER_KEY_SESSION_ID, sessionId); if (peerHandle != null) { - json.put(NETWORK_SPECIFIER_KEY_PEER_ID, ((OpaquePeerHandle) peerHandle).peerId); + json.put(NETWORK_SPECIFIER_KEY_PEER_ID, peerHandle.peerId); } if (token != null) { json.put(NETWORK_SPECIFIER_KEY_TOKEN, @@ -876,18 +876,18 @@ public class WifiAwareManager { break; case CALLBACK_MATCH: mOriginalCallback.onServiceDiscovered( - new OpaquePeerHandle(msg.arg1), + new PeerHandle(msg.arg1), msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2)); break; case CALLBACK_MESSAGE_SEND_SUCCESS: - mOriginalCallback.onMessageSent(msg.arg1); + mOriginalCallback.onMessageSendSucceeded(msg.arg1); break; case CALLBACK_MESSAGE_SEND_FAIL: mOriginalCallback.onMessageSendFailed(msg.arg1); break; case CALLBACK_MESSAGE_RECEIVED: - mOriginalCallback.onMessageReceived(new OpaquePeerHandle(msg.arg1), + mOriginalCallback.onMessageReceived(new PeerHandle(msg.arg1), (byte[]) msg.obj); break; } @@ -1019,12 +1019,14 @@ public class WifiAwareManager { } } - /** @hide */ - public static class OpaquePeerHandle { - public OpaquePeerHandle(int peerId) { + /** @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/WifiAwarePublishDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java index 610a92ce28b5..68786d17d38d 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java @@ -21,9 +21,8 @@ import android.util.Log; /** * A class representing a Aware publish session. Created when - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * is called and a discovery session is created and returned in + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * 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 * object allows updating an existing/running publish discovery session using diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java index 357bd43f12db..acb60a4480d4 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java @@ -65,7 +65,7 @@ public class WifiAwareSession { * session-wide destroy. * <p> * An application may re-attach after a destroy using - * {@link WifiAwareManager#attach(Handler, WifiAwareAttachCallback)} . + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, Handler)} . */ public void destroy() { WifiAwareManager mgr = mMgr.get(); @@ -116,15 +116,15 @@ public class WifiAwareSession { * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} * permission to start a publish discovery session. * - * @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. * @param publishConfig The {@link PublishConfig} specifying the * configuration of the requested publish session. * @param callback A {@link WifiAwareDiscoverySessionCallback} 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(@Nullable Handler handler, @NonNull PublishConfig publishConfig, - @NonNull WifiAwareDiscoverySessionCallback callback) { + public void publish(@NonNull PublishConfig publishConfig, + @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) { WifiAwareManager mgr = mMgr.get(); if (mgr == null) { Log.e(TAG, "publish: called post GC on WifiAwareManager"); @@ -162,15 +162,15 @@ public class WifiAwareSession { * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} * permission to start a subscribe discovery session. * - * @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. * @param subscribeConfig The {@link SubscribeConfig} specifying the * configuration of the requested subscribe session. * @param callback A {@link WifiAwareDiscoverySessionCallback} 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(@Nullable Handler handler, @NonNull SubscribeConfig subscribeConfig, - @NonNull WifiAwareDiscoverySessionCallback callback) { + public void subscribe(@NonNull SubscribeConfig subscribeConfig, + @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) { WifiAwareManager mgr = mMgr.get(); if (mgr == null) { Log.e(TAG, "publish: called post GC on WifiAwareManager"); @@ -193,7 +193,8 @@ public class WifiAwareSession { * 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(int, Object, byte[])}. + * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, + * WifiAwareManager.PeerHandle, byte[])}. * * @param role The role of this device: * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java index 7c48f549eaf4..a0ec8093a3ab 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java @@ -21,8 +21,8 @@ import android.util.Log; /** * A class representing a Aware subscribe session. Created when - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} + * {@link WifiAwareSession#subscribe(SubscribeConfig, + * WifiAwareDiscoverySessionCallback, 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}. |