diff options
22 files changed, 458 insertions, 100 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 80c22e1a4222..7b7518d05345 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -333,6 +333,8 @@ package android { } public static final class R.string { + field public static final int config_customMediaKeyDispatcher = 17039404; // 0x104002c + field public static final int config_customMediaSessionPolicyProvider = 17039405; // 0x104002d field public static final int config_defaultAssistant = 17039393; // 0x1040021 field public static final int config_defaultBrowser = 17039394; // 0x1040022 field public static final int config_defaultCallRedirection = 17039397; // 0x1040025 diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index d7587bdce997..bd99348b235a 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -117,6 +117,9 @@ public class WallpaperManager { private static final String PROP_LOCK_WALLPAPER = "ro.config.lock_wallpaper"; /** {@hide} */ private static final String PROP_WALLPAPER_COMPONENT = "ro.config.wallpaper_component"; + /** {@hide} */ + private static final String VALUE_CMF_COLOR = + android.os.SystemProperties.get("ro.boot.hardware.color"); /** * Activity Action: Show settings for choosing wallpaper. Do not use directly to construct @@ -2064,7 +2067,11 @@ public class WallpaperManager { return null; } else { whichProp = PROP_WALLPAPER; - defaultResId = com.android.internal.R.drawable.default_wallpaper; + final int defaultColorResId = context.getResources().getIdentifier( + "default_wallpaper_" + VALUE_CMF_COLOR, "drawable", "android"); + defaultResId = + defaultColorResId == 0 ? com.android.internal.R.drawable.default_wallpaper + : defaultColorResId; } final String path = SystemProperties.get(whichProp); if (!TextUtils.isEmpty(path)) { diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 59285d794045..9a917b72a5fd 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4592,11 +4592,12 @@ <item>com.android.systemui</item> </string-array> - <!-- Package name of custom media key dispatcher class used by MediaSessionService. --> + <!-- Component name of custom media key dispatcher class used by MediaSessionService. --> <string name="config_customMediaKeyDispatcher"></string> - <!-- Package name of custom session policy provider class used by MediaSessionService. --> - <string name="config_customSessionPolicyProvider"></string> + <!-- Component name of custom media session policy provider class used by + MediaSessionService. --> + <string name="config_customMediaSessionPolicyProvider"></string> <!-- The max scale for the wallpaper when it's zoomed in --> <item name="config_wallpaperMaxScale" format="float" type="dimen">1.10</item> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 22dce9b9935c..a1ea61c447c0 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3153,6 +3153,10 @@ <public name="config_systemShell" /> <!-- @hide @SystemApi --> <public name="config_systemContacts" /> + <!-- @hide @SystemApi --> + <public name="config_customMediaKeyDispatcher" /> + <!-- @hide @SystemApi --> + <public name="config_customMediaSessionPolicyProvider" /> </public-group> <public-group type="id" first-id="0x01020055"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 70b358fd4d77..b5af5240b843 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4115,8 +4115,6 @@ <java-symbol type="string" name="notification_history_title_placeholder" /> - <java-symbol type="string" name="config_customMediaKeyDispatcher" /> - <java-symbol type="string" name="config_customSessionPolicyProvider" /> <!-- The max scale for the wallpaper when it's zoomed in --> <java-symbol type="dimen" name="config_wallpaperMaxScale"/> diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java index 21d23b1b2575..50a90820117d 100644 --- a/keystore/java/android/security/Authorization.java +++ b/keystore/java/android/security/Authorization.java @@ -33,20 +33,12 @@ import android.util.Log; */ public class Authorization { private static final String TAG = "KeystoreAuthorization"; - private static IKeystoreAuthorization sIKeystoreAuthorization; public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR; - public Authorization() { - sIKeystoreAuthorization = null; - } - - private static synchronized IKeystoreAuthorization getService() { - if (sIKeystoreAuthorization == null) { - sIKeystoreAuthorization = IKeystoreAuthorization.Stub.asInterface( + private static IKeystoreAuthorization getService() { + return IKeystoreAuthorization.Stub.asInterface( ServiceManager.checkService("android.security.authorization")); - } - return sIKeystoreAuthorization; } /** @@ -55,12 +47,12 @@ public class Authorization { * @param authToken created by Android authenticators. * @return 0 if successful or {@code ResponseCode.SYSTEM_ERROR}. */ - public int addAuthToken(@NonNull HardwareAuthToken authToken) { + public static int addAuthToken(@NonNull HardwareAuthToken authToken) { if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0; try { getService().addAuthToken(authToken); return 0; - } catch (RemoteException e) { + } catch (RemoteException | NullPointerException e) { Log.w(TAG, "Can not connect to keystore", e); return SYSTEM_ERROR; } catch (ServiceSpecificException e) { @@ -73,7 +65,7 @@ public class Authorization { * @param authToken * @return 0 if successful or a {@code ResponseCode}. */ - public int addAuthToken(@NonNull byte[] authToken) { + public static int addAuthToken(@NonNull byte[] authToken) { return addAuthToken(AuthTokenUtils.toHardwareAuthToken(authToken)); } @@ -86,7 +78,7 @@ public class Authorization { * * @return 0 if successful or a {@code ResponseCode}. */ - public int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId, + public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId, @Nullable byte[] syntheticPassword) { if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0; try { @@ -96,7 +88,7 @@ public class Authorization { getService().onLockScreenEvent(LockScreenEvent.UNLOCK, userId, syntheticPassword); } return 0; - } catch (RemoteException e) { + } catch (RemoteException | NullPointerException e) { Log.w(TAG, "Can not connect to keystore", e); return SYSTEM_ERROR; } catch (ServiceSpecificException e) { diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index e19d88c182ff..198df40c7d7b 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -996,7 +996,7 @@ public class KeyStore { */ public int addAuthToken(byte[] authToken) { try { - new Authorization().addAuthToken(authToken); + Authorization.addAuthToken(authToken); return mBinder.addAuthToken(authToken); } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java index f7477bf92c81..476e4d7b7b18 100644 --- a/keystore/java/android/security/KeyStore2.java +++ b/keystore/java/android/security/KeyStore2.java @@ -107,7 +107,6 @@ public class KeyStore2 { try { return request.execute(service); } catch (ServiceSpecificException e) { - Log.e(TAG, "KeyStore exception", e); throw getKeyStoreException(e.errorCode); } catch (RemoteException e) { if (firstTry) { diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index 04e3a1cb887e..b2884023a83d 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -194,6 +194,25 @@ SkiaCanvas::PaintCoW&& SkiaRecordingCanvas::filterBitmap(PaintCoW&& paint) { return filterPaint(std::move(paint)); } +static BlurDrawLooper* get_looper(const Paint* paint) { + return paint ? paint->getLooper() : nullptr; +} + +template <typename Proc> +void applyLooper(BlurDrawLooper* looper, const SkPaint* paint, Proc proc) { + if (looper) { + SkPaint p; + if (paint) { + p = *paint; + } + looper->apply(p, [&](SkPoint offset, const SkPaint& modifiedPaint) { + proc(offset.fX, offset.fY, &modifiedPaint); + }); + } else { + proc(0, 0, paint); + } +} + static SkFilterMode Paint_to_filter(const SkPaint* paint) { return paint && paint->getFilterQuality() != kNone_SkFilterQuality ? SkFilterMode::kLinear : SkFilterMode::kNearest; @@ -207,7 +226,8 @@ static SkSamplingOptions Paint_to_sampling(const SkPaint* paint) { void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) { sk_sp<SkImage> image = bitmap.makeImage(); - applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) { + applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y, + const SkPaint* p) { mRecorder.drawImage(image, left + x, top + y, Paint_to_sampling(p), p, bitmap.palette()); }); @@ -225,7 +245,8 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, con sk_sp<SkImage> image = bitmap.makeImage(); - applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) { + applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y, + const SkPaint* p) { mRecorder.drawImage(image, x, y, Paint_to_sampling(p), p, bitmap.palette()); }); @@ -242,7 +263,8 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop sk_sp<SkImage> image = bitmap.makeImage(); - applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) { + applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y, + const SkPaint* p) { mRecorder.drawImageRect(image, srcRect, dstRect.makeOffset(x, y), Paint_to_sampling(p), p, SkCanvas::kFast_SrcRectConstraint, bitmap.palette()); }); @@ -281,7 +303,8 @@ void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& ch // HWUI always draws 9-patches with linear filtering, regardless of the Paint. const SkFilterMode filter = SkFilterMode::kLinear; - applyLooper(paint, [&](SkScalar x, SkScalar y, const SkPaint* p) { + applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y, + const SkPaint* p) { mRecorder.drawImageLattice(image, lattice, dst.makeOffset(x, y), filter, p, bitmap.palette()); }); diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h index deeae6a030d3..8d7a21a732dd 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h @@ -87,19 +87,6 @@ private: std::unique_ptr<SkiaDisplayList> mDisplayList; StartReorderBarrierDrawable* mCurrentBarrier; - template <typename Proc> - void applyLooper(const Paint* paint, Proc proc) { - const SkPaint* sk_paint = filterBitmap(paint); - const BlurDrawLooper* looper = paint ? paint->getLooper() : nullptr; - if (looper) { - looper->apply(*sk_paint, [&](SkPoint offset, const SkPaint& modifiedPaint) { - proc(offset.fX, offset.fY, &modifiedPaint); - }); - } else { - proc(0, 0, sk_paint); - } - } - /** * A new SkiaDisplayList is created or recycled if available. * diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index 66d579408db0..dc476b873786 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -73,8 +73,10 @@ interface ISessionManager { void setOnMediaKeyListener(in IOnMediaKeyListener listener); boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid); - void setCustomMediaKeyDispatcherForTesting(String name); - void setCustomSessionPolicyProviderForTesting(String name); + void setCustomMediaKeyDispatcher(String name); + void setCustomMediaSessionPolicyProvider(String name); + boolean hasCustomMediaKeyDispatcher(String componentName); + boolean hasCustomMediaSessionPolicyProvider(String componentName); int getSessionPolicies(in MediaSession.Token token); void setSessionPolicies(in MediaSession.Token token, int policies); } diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 13a3436569aa..8de5e42e93b2 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -958,9 +958,9 @@ public final class MediaSessionManager { * @hide */ @VisibleForTesting - public void setCustomMediaKeyDispatcherForTesting(@Nullable String name) { + public void setCustomMediaKeyDispatcher(@Nullable String name) { try { - mService.setCustomMediaKeyDispatcherForTesting(name); + mService.setCustomMediaKeyDispatcher(name); } catch (RemoteException e) { Log.e(TAG, "Failed to set custom media key dispatcher name", e); } @@ -968,22 +968,58 @@ public final class MediaSessionManager { /** * Set the component name for the custom - * {@link com.android.server.media.SessionPolicyProvider} class. Set to null to restore to the - * custom {@link com.android.server.media.SessionPolicyProvider} class name retrieved from the - * config value. + * {@link com.android.server.media.MediaSessionPolicyProvider} class. Set to null to restore to + * the custom {@link com.android.server.media.MediaSessionPolicyProvider} class name retrieved + * from the config value. * * @hide */ @VisibleForTesting - public void setCustomSessionPolicyProviderForTesting(@Nullable String name) { + public void setCustomMediaSessionPolicyProvider(@Nullable String name) { try { - mService.setCustomSessionPolicyProviderForTesting(name); + mService.setCustomMediaSessionPolicyProvider(name); } catch (RemoteException e) { Log.e(TAG, "Failed to set custom session policy provider name", e); } } /** + * Get the component name for the custom {@link com.android.server.media.MediaKeyDispatcher} + * class. + * + * @hide + */ + @VisibleForTesting + public boolean hasCustomMediaKeyDispatcher(@NonNull String componentName) { + Objects.requireNonNull(componentName, "componentName shouldn't be null"); + try { + return mService.hasCustomMediaKeyDispatcher(componentName); + } catch (RemoteException e) { + Log.e(TAG, "Failed to check if custom media key dispatcher with given component" + + " name exists", e); + } + return false; + } + + /** + * Get the component name for the custom + * {@link com.android.server.media.MediaSessionPolicyProvider} class. + * + * @hide + */ + @VisibleForTesting + public boolean hasCustomMediaSessionPolicyProvider(@NonNull String componentName) { + Objects.requireNonNull(componentName, "componentName shouldn't be null"); + try { + return mService.hasCustomMediaSessionPolicyProvider(componentName); + } catch (RemoteException e) { + Log.e(TAG, "Failed to check if custom media session policy provider with given" + + " component name exists", e); + } + return false; + } + + /** * Get session policies of the specified {@link MediaSession.Token}. * * @hide diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f54551e3f61f..9d86f4eaa520 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -9033,7 +9033,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private void updateDefaultNetworksForOemNetworkPreference( @NonNull final Set<NetworkRequestInfo> nris) { - handleRemoveNetworkRequests(mDefaultNetworkRequests); + // Pass in a defensive copy as this collection will be updated on remove. + handleRemoveNetworkRequests(new ArraySet<>(mDefaultNetworkRequests)); addPerAppDefaultNetworkRequests(nris); } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 1baca10c35cf..2dd54482e2d8 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1276,7 +1276,7 @@ public class LockSettingsService extends ILockSettings.Stub { private void unlockKeystore(byte[] password, int userHandle) { if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle); - new Authorization().onLockScreenEvent(false, userHandle, password); + Authorization.onLockScreenEvent(false, userHandle, password); // TODO(b/120484642): Update keystore to accept byte[] passwords String passwordString = password == null ? null : new String(password); final KeyStore ks = KeyStore.getInstance(); diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java index 7ef4924879bf..55511ad637ac 100644 --- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java +++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java @@ -77,7 +77,7 @@ public abstract class MediaKeyDispatcher { mOverriddenKeyEvents.put(KeyEvent.KEYCODE_VOLUME_MUTE, 0); } - // TODO: Move this method into SessionPolicyProvider.java for better readability. + // TODO: Move this method into MediaSessionPolicyProvider.java for better readability. /** * Implement this to customize the logic for which MediaSession should consume which key event. * diff --git a/services/core/java/com/android/server/media/SessionPolicyProvider.java b/services/core/java/com/android/server/media/MediaSessionPolicyProvider.java index 332c85adec01..ceadb596dd42 100644 --- a/services/core/java/com/android/server/media/SessionPolicyProvider.java +++ b/services/core/java/com/android/server/media/MediaSessionPolicyProvider.java @@ -31,7 +31,7 @@ import java.lang.annotation.RetentionPolicy; * without any parameters. */ // TODO: Move this class to apex/media/ -public abstract class SessionPolicyProvider { +public abstract class MediaSessionPolicyProvider { @IntDef(value = { SESSION_POLICY_IGNORE_BUTTON_RECEIVER, SESSION_POLICY_IGNORE_BUTTON_SESSION @@ -55,7 +55,7 @@ public abstract class SessionPolicyProvider { */ static final int SESSION_POLICY_IGNORE_BUTTON_SESSION = 1 << 1; - public SessionPolicyProvider(Context context) { + public MediaSessionPolicyProvider(Context context) { // Constructor used for reflection } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index c462a9274117..0a074e1e7c50 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -895,7 +895,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR throws RemoteException { final long token = Binder.clearCallingIdentity(); try { - if ((mPolicies & SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) + if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) != 0) { return; } @@ -911,7 +911,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR public void setMediaButtonBroadcastReceiver(ComponentName receiver) throws RemoteException { final long token = Binder.clearCallingIdentity(); try { - if ((mPolicies & SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) + if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) != 0) { return; } diff --git a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java index 032523ef9694..3c50597b8cfc 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java +++ b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java @@ -20,7 +20,7 @@ import android.media.AudioManager; import android.os.ResultReceiver; import android.view.KeyEvent; -import com.android.server.media.SessionPolicyProvider.SessionPolicy; +import com.android.server.media.MediaSessionPolicyProvider.SessionPolicy; import java.io.PrintWriter; diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 6c1d3991c4e9..18f2d8450246 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -148,7 +148,7 @@ public class MediaSessionService extends SystemService implements Monitor { final RemoteCallbackList<IRemoteSessionCallback> mRemoteVolumeControllers = new RemoteCallbackList<>(); - private SessionPolicyProvider mCustomSessionPolicyProvider; + private MediaSessionPolicyProvider mCustomMediaSessionPolicyProvider; private MediaKeyDispatcher mCustomMediaKeyDispatcher; public MediaSessionService(Context context) { @@ -191,8 +191,10 @@ public class MediaSessionService extends SystemService implements Monitor { updateUser(); - instantiateCustomProvider(null); - instantiateCustomDispatcher(null); + instantiateCustomProvider(mContext.getResources().getString( + R.string.config_customMediaSessionPolicyProvider)); + instantiateCustomDispatcher(mContext.getResources().getString( + R.string.config_customMediaKeyDispatcher)); mRecordThread.start(); final IntentFilter filter = new IntentFilter( @@ -589,8 +591,8 @@ public class MediaSessionService extends SystemService implements Monitor { String callerPackageName, ISessionCallback cb, String tag, Bundle sessionInfo) { synchronized (mLock) { int policies = 0; - if (mCustomSessionPolicyProvider != null) { - policies = mCustomSessionPolicyProvider.getSessionPoliciesForApplication( + if (mCustomMediaSessionPolicyProvider != null) { + policies = mCustomMediaSessionPolicyProvider.getSessionPoliciesForApplication( callerUid, callerPackageName); } @@ -778,16 +780,13 @@ public class MediaSessionService extends SystemService implements Monitor { return null; } - private void instantiateCustomDispatcher(String nameFromTesting) { + private void instantiateCustomDispatcher(String componentName) { synchronized (mLock) { mCustomMediaKeyDispatcher = null; - String customDispatcherClassName = (nameFromTesting == null) - ? mContext.getResources().getString(R.string.config_customMediaKeyDispatcher) - : nameFromTesting; try { - if (!TextUtils.isEmpty(customDispatcherClassName)) { - Class customDispatcherClass = Class.forName(customDispatcherClassName); + if (componentName != null && !TextUtils.isEmpty(componentName)) { + Class customDispatcherClass = Class.forName(componentName); Constructor constructor = customDispatcherClass.getDeclaredConstructor(Context.class); mCustomMediaKeyDispatcher = @@ -801,20 +800,17 @@ public class MediaSessionService extends SystemService implements Monitor { } } - private void instantiateCustomProvider(String nameFromTesting) { + private void instantiateCustomProvider(String componentName) { synchronized (mLock) { - mCustomSessionPolicyProvider = null; + mCustomMediaSessionPolicyProvider = null; - String customProviderClassName = (nameFromTesting == null) - ? mContext.getResources().getString(R.string.config_customSessionPolicyProvider) - : nameFromTesting; try { - if (!TextUtils.isEmpty(customProviderClassName)) { - Class customProviderClass = Class.forName(customProviderClassName); + if (componentName != null && !TextUtils.isEmpty(componentName)) { + Class customProviderClass = Class.forName(componentName); Constructor constructor = customProviderClass.getDeclaredConstructor(Context.class); - mCustomSessionPolicyProvider = - (SessionPolicyProvider) constructor.newInstance(mContext); + mCustomMediaSessionPolicyProvider = + (MediaSessionPolicyProvider) constructor.newInstance(mContext); } } catch (ClassNotFoundException | InstantiationException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { @@ -1933,16 +1929,30 @@ public class MediaSessionService extends SystemService implements Monitor { } @Override - public void setCustomMediaKeyDispatcherForTesting(String name) { + public void setCustomMediaKeyDispatcher(String name) { instantiateCustomDispatcher(name); } @Override - public void setCustomSessionPolicyProviderForTesting(String name) { + public void setCustomMediaSessionPolicyProvider(String name) { instantiateCustomProvider(name); } @Override + public boolean hasCustomMediaKeyDispatcher(String componentName) { + return mCustomMediaKeyDispatcher == null ? false + : TextUtils.equals(componentName, + mCustomMediaKeyDispatcher.getClass().getName()); + } + + @Override + public boolean hasCustomMediaSessionPolicyProvider(String componentName) { + return mCustomMediaSessionPolicyProvider == null ? false + : TextUtils.equals(componentName, + mCustomMediaSessionPolicyProvider.getClass().getName()); + } + + @Override public int getSessionPolicies(MediaSession.Token token) { synchronized (mLock) { MediaSessionRecord record = getMediaSessionRecordLocked(token); diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java index f8ff5b5f8e66..50eed19389dc 100644 --- a/services/core/java/com/android/server/media/MediaSessionStack.java +++ b/services/core/java/com/android/server/media/MediaSessionStack.java @@ -16,7 +16,7 @@ package com.android.server.media; -import static com.android.server.media.SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_SESSION; +import static com.android.server.media.MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_SESSION; import android.media.Session2Token; import android.media.session.MediaSession; diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index da3e48ad2c0d..4fbc79507b95 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -703,7 +703,7 @@ public class TrustManagerService extends SystemService { if (changed) { dispatchDeviceLocked(userId, locked); - mAuthorizationService.onLockScreenEvent(locked, userId, null); + Authorization.onLockScreenEvent(locked, userId, null); KeyStore.getInstance().onUserLockedStateChanged(userId, locked); // Also update the user's profiles who have unified challenge, since they // share the same unlocked state (see {@link #isDeviceLocked(int)}) @@ -1261,7 +1261,7 @@ public class TrustManagerService extends SystemService { mDeviceLockedForUser.put(userId, locked); } - mAuthorizationService.onLockScreenEvent(locked, userId, null); + Authorization.onLockScreenEvent(locked, userId, null); KeyStore.getInstance().onUserLockedStateChanged(userId, locked); if (locked) { diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index ad2b3a15d608..24e559225027 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -84,6 +84,11 @@ import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED; import static android.net.NetworkPolicyManager.RULE_NONE; import static android.net.NetworkPolicyManager.RULE_REJECT_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; +import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; +import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; +import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; +import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; +import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.os.Process.INVALID_UID; import static android.system.OsConstants.IPPROTO_TCP; @@ -355,6 +360,7 @@ public class ConnectivityServiceTest { private static final long TIMESTAMP = 1234L; private static final int NET_ID = 110; + private static final int OEM_PREF_ANY_NET_ID = -1; // Set a non-zero value to verify the flow to set tcp init rwnd value. private static final int TEST_TCP_INIT_RWND = 60; @@ -9488,7 +9494,7 @@ public class ConnectivityServiceTest { public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() throws PackageManager.NameNotFoundException { @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED; + OEM_NETWORK_PREFERENCE_UNINITIALIZED; // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() assertThrows(IllegalArgumentException.class, @@ -9505,7 +9511,7 @@ public class ConnectivityServiceTest { final int expectedNumOfRequests = 3; @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; + OEM_NETWORK_PREFERENCE_OEM_PAID; // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() final ArraySet<ConnectivityService.NetworkRequestInfo> nris = @@ -9534,7 +9540,7 @@ public class ConnectivityServiceTest { final int expectedNumOfRequests = 2; @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; + OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() final ArraySet<ConnectivityService.NetworkRequestInfo> nris = @@ -9560,7 +9566,7 @@ public class ConnectivityServiceTest { final int expectedNumOfRequests = 1; @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() final ArraySet<ConnectivityService.NetworkRequestInfo> nris = @@ -9583,7 +9589,7 @@ public class ConnectivityServiceTest { final int expectedNumOfRequests = 1; @OemNetworkPreferences.OemNetworkPreference final int prefToTest = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences() final ArraySet<ConnectivityService.NetworkRequestInfo> nris = @@ -9611,8 +9617,8 @@ public class ConnectivityServiceTest { mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID); // Build OemNetworkPreferences object - final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; - final int testOemPref2 = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; + final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; + final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) .addNetworkPreference(testPackageName2, testOemPref2) @@ -9636,8 +9642,8 @@ public class ConnectivityServiceTest { mockGetApplicationInfo(testPackageName2, testPackageNameUid2); // Build OemNetworkPreferences object - final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; - final int testOemPref2 = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; + final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; + final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) .addNetworkPreference(testPackageName2, testOemPref2) @@ -9671,7 +9677,7 @@ public class ConnectivityServiceTest { mockGetApplicationInfo(testPackageName2, testPackageNameUid2); // Build OemNetworkPreferences object - final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; + final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID; final OemNetworkPreferences pref = new OemNetworkPreferences.Builder() .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref) .addNetworkPreference(testPackageName2, testOemPref) @@ -9689,8 +9695,6 @@ public class ConnectivityServiceTest { @Test public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() { mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; // Act on ConnectivityService.setOemNetworkPreference() assertThrows(NullPointerException.class, @@ -9704,7 +9708,7 @@ public class ConnectivityServiceTest { throws Exception { mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; // Act on ConnectivityService.setOemNetworkPreference() assertThrows(UnsupportedOperationException.class, @@ -9870,7 +9874,7 @@ public class ConnectivityServiceTest { @Test public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception { @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; final int expectedOemPrefRequestSize = 1; // Setup the test process to use networkPref for their default network. @@ -9891,7 +9895,7 @@ public class ConnectivityServiceTest { @Test public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception { @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; final int expectedOemPrefRequestSize = 1; // Setup the test process to use networkPref for their default network. @@ -9918,7 +9922,7 @@ public class ConnectivityServiceTest { @Test public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception { @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; final int expectedOemPrefRequestSize = 1; final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); @@ -9955,7 +9959,7 @@ public class ConnectivityServiceTest { @Test public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception { @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; final int expectedOemPrefRequestSize = 1; final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); @@ -9992,7 +9996,7 @@ public class ConnectivityServiceTest { @Test public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception { @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; + OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; final int expectedOemPrefRequestSize = 1; final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); final int userId = UserHandle.getUserId(Process.myUid()); @@ -10042,4 +10046,296 @@ public class ConnectivityServiceTest { // Confirm we can unregister without issues. mCm.unregisterNetworkCallback(defaultNetworkCallback); } + + private void verifySetOemNetworkPreferenceForPreference( + @NonNull final UidRangeParcel[] uidRanges, + final int addUidRangesNetId, + final int addUidRangesTimes, + final int removeUidRangesNetId, + final int removeUidRangesTimes, + final boolean shouldDestroyNetwork) throws RemoteException { + final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId; + final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId; + + // Validate netd. + verify(mMockNetd, times(addUidRangesTimes)) + .networkAddUidRanges( + (useAnyIdForAdd ? anyInt() : eq(addUidRangesNetId)), eq(uidRanges)); + verify(mMockNetd, times(removeUidRangesTimes)) + .networkRemoveUidRanges( + (useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId)), eq(uidRanges)); + if (shouldDestroyNetwork) { + verify(mMockNetd, times(1)) + .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId))); + } + reset(mMockNetd); + } + + /** + * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). + * @throws Exception + */ + @Test + public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { + @OemNetworkPreferences.OemNetworkPreference int networkPref = + OEM_NETWORK_PREFERENCE_OEM_PAID; + final int testPackageUid = 123; + final String testPackageName = "com.google.apps.contacts"; + final UidRangeParcel[] uidRanges = + toUidRangeStableParcels(uidRangesForUid(testPackageUid)); + + // Validate the starting requests only includes the fallback request. + assertEquals(1, mService.mDefaultNetworkRequests.size()); + + // Add an OEM default network request to track. + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); + + // Two requests should exist, one for the fallback and one for the pref. + assertEquals(2, mService.mDefaultNetworkRequests.size()); + + networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName); + + // Two requests should still exist validating the previous per-app request was replaced. + assertEquals(2, mService.mDefaultNetworkRequests.size()); + } + + /** + * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID following in order: + * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback + * @throws Exception + */ + @Test + public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() + throws Exception { + @OemNetworkPreferences.OemNetworkPreference final int networkPref = + OEM_NETWORK_PREFERENCE_OEM_PAID; + + // Arrange PackageManager mocks + final int testPackageNameUid = 123; + final UidRangeParcel[] uidRanges = + toUidRangeStableParcels(uidRangesForUid(testPackageNameUid)); + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + + // Verify the starting state. No networks should be connected. + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Test lowest to highest priority requests. + // Bring up metered cellular. This will satisfy the fallback network. + setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mCellNetworkAgent.getNetwork().netId, 1 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. + setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, + mCellNetworkAgent.getNetwork().netId, 1 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. + setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, + mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, + false /* shouldDestroyNetwork */); + + // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered. + setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); + // netd should not be called as default networks haven't changed. + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Disconnecting unmetered should put PANS on lowest priority fallback request. + setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mCellNetworkAgent.getNetwork().netId, 1 /* times */, + mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, + true /* shouldDestroyNetwork */); + + // Disconnecting the fallback network should result in no connectivity. + setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + mCellNetworkAgent.getNetwork().netId, 0 /* times */, + true /* shouldDestroyNetwork */); + } + + /** + * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK following in order: + * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID + * @throws Exception + */ + @Test + public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() + throws Exception { + @OemNetworkPreferences.OemNetworkPreference final int networkPref = + OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; + + // Arrange PackageManager mocks + final int testPackageNameUid = 123; + final UidRangeParcel[] uidRanges = + toUidRangeStableParcels(uidRangesForUid(testPackageNameUid)); + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + + // Verify the starting state. This preference doesn't support using the fallback network + // therefore should be on the disconnected network as it has no networks to connect to. + verifySetOemNetworkPreferenceForPreference(uidRanges, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Test lowest to highest priority requests. + // Bring up metered cellular. This will satisfy the fallback network. + // This preference should not use this network as it doesn't support fallback usage. + setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. + setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. + setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mWiFiNetworkAgent.getNetwork().netId, 1 /* times */, + mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, + false /* shouldDestroyNetwork */); + + // Disconnecting unmetered should put PANS on OEM_PAID. + setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, + mWiFiNetworkAgent.getNetwork().netId, 0 /* times */, + true /* shouldDestroyNetwork */); + + // Disconnecting OEM_PAID should result in no connectivity. + // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network. + setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, + true /* shouldDestroyNetwork */); + } + + /** + * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY following in order: + * NET_CAPABILITY_OEM_PAID + * This preference should only apply to OEM_PAID networks. + * @throws Exception + */ + @Test + public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() + throws Exception { + @OemNetworkPreferences.OemNetworkPreference final int networkPref = + OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; + + // Arrange PackageManager mocks + final int testPackageNameUid = 123; + final UidRangeParcel[] uidRanges = + toUidRangeStableParcels(uidRangesForUid(testPackageNameUid)); + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + + // Verify the starting state. This preference doesn't support using the fallback network + // therefore should be on the disconnected network as it has no networks to connect to. + verifySetOemNetworkPreferenceForPreference(uidRanges, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up metered cellular. This should not apply to this preference. + setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up unmetered Wi-Fi. This should not apply to this preference. + setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. + setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + false /* shouldDestroyNetwork */); + + // Disconnecting OEM_PAID should result in no connectivity. + setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, + true /* shouldDestroyNetwork */); + } + + /** + * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY following in order: + * NET_CAPABILITY_OEM_PRIVATE + * This preference should only apply to OEM_PRIVATE networks. + * @throws Exception + */ + @Test + public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() + throws Exception { + @OemNetworkPreferences.OemNetworkPreference final int networkPref = + OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; + + // Arrange PackageManager mocks + final int testPackageNameUid = 123; + final UidRangeParcel[] uidRanges = + toUidRangeStableParcels(uidRangesForUid(testPackageNameUid)); + setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME); + + // Verify the starting state. This preference doesn't support using the fallback network + // therefore should be on the disconnected network as it has no networks to connect to. + verifySetOemNetworkPreferenceForPreference(uidRanges, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up metered cellular. This should not apply to this preference. + setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up unmetered Wi-Fi. This should not apply to this preference. + setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); + verifySetOemNetworkPreferenceForPreference(uidRanges, + OEM_PREF_ANY_NET_ID, 0 /* times */, + OEM_PREF_ANY_NET_ID, 0 /* times */, + false /* shouldDestroyNetwork */); + + // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. + startOemManagedNetwork(false); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mEthernetNetworkAgent.getNetwork().netId, 1 /* times */, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + false /* shouldDestroyNetwork */); + + // Disconnecting OEM_PRIVATE should result in no connectivity. + stopOemManagedNetwork(); + verifySetOemNetworkPreferenceForPreference(uidRanges, + mService.mNoServiceNetwork.network.getNetId(), 1 /* times */, + mEthernetNetworkAgent.getNetwork().netId, 0 /* times */, + true /* shouldDestroyNetwork */); + } } |