Merge "Moving the LoadedApk class to its own file."
diff --git a/Android.mk b/Android.mk
index e68b310..22323c5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -182,6 +182,7 @@
core/java/android/hardware/display/IVirtualDisplayCallback.aidl \
core/java/android/hardware/fingerprint/IFingerprintService.aidl \
core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl \
+ core/java/android/hardware/fingerprint/IFingerprintClientActiveCallback.aidl \
core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl \
core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
core/java/android/hardware/hdmi/IHdmiControlService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 0ca9875..869d148 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -349,6 +349,7 @@
field public static final int calendarTextColor = 16843931; // 0x101049b
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
+ field public static final int canCaptureFingerprintGestures = 16844111; // 0x101054f
field public static final int canControlMagnification = 16844039; // 0x1010507
field public static final int canPerformGestures = 16844045; // 0x101050d
field public static final int canRecord = 16844060; // 0x101051c
@@ -2692,6 +2693,7 @@
method public final void disableSelf();
method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+ method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
@@ -2783,6 +2785,7 @@
method public java.lang.String getSettingsActivityName();
method public java.lang.String loadDescription(android.content.pm.PackageManager);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 64; // 0x40
field public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 16; // 0x10
field public static final int CAPABILITY_CAN_PERFORM_GESTURES = 32; // 0x20
field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
@@ -2798,6 +2801,7 @@
field public static final int FEEDBACK_HAPTIC = 2; // 0x2
field public static final int FEEDBACK_SPOKEN = 1; // 0x1
field public static final int FEEDBACK_VISUAL = 8; // 0x8
+ field public static final int FLAG_CAPTURE_FINGERPRINT_GESTURES = 512; // 0x200
field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
@@ -2812,6 +2816,22 @@
field public java.lang.String[] packageNames;
}
+ public final class FingerprintGestureController {
+ method public boolean isGestureDetectionAvailable();
+ method public void registerFingerprintGestureCallback(android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback, android.os.Handler);
+ method public void unregisterFingerprintGestureCallback(android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback);
+ field public static final int FINGERPRINT_GESTURE_SWIPE_DOWN = 8; // 0x8
+ field public static final int FINGERPRINT_GESTURE_SWIPE_LEFT = 2; // 0x2
+ field public static final int FINGERPRINT_GESTURE_SWIPE_RIGHT = 1; // 0x1
+ field public static final int FINGERPRINT_GESTURE_SWIPE_UP = 4; // 0x4
+ }
+
+ public static abstract class FingerprintGestureController.FingerprintGestureCallback {
+ ctor public FingerprintGestureController.FingerprintGestureCallback();
+ method public void onGesture(int);
+ method public void onGestureDetectionAvailabilityChanged(boolean);
+ }
+
public final class GestureDescription {
method public static long getMaxGestureDuration();
method public static int getMaxStrokeCount();
@@ -4516,6 +4536,7 @@
method public final boolean isInLayout();
method public final boolean isRemoving();
method public final boolean isResumed();
+ method public final boolean isStateSaved();
method public final boolean isVisible();
method public void onActivityCreated(android.os.Bundle);
method public void onActivityResult(int, int, android.content.Intent);
@@ -4754,6 +4775,7 @@
method public abstract android.app.FragmentTransaction hide(android.app.Fragment);
method public abstract boolean isAddToBackStackAllowed();
method public abstract boolean isEmpty();
+ method public abstract android.app.FragmentTransaction postOnCommit(java.lang.Runnable);
method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
@@ -32965,7 +32987,7 @@
ctor public ContactsContract.Intents();
field public static final java.lang.String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS = "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
field public static final java.lang.String ATTACH_IMAGE = "com.android.contacts.action.ATTACH_IMAGE";
- field public static final deprecated java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
+ field public static final java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
field public static final java.lang.String EXTRA_CREATE_DESCRIPTION = "com.android.contacts.action.CREATE_DESCRIPTION";
field public static final java.lang.String EXTRA_FORCE_CREATE = "com.android.contacts.action.FORCE_CREATE";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
@@ -33078,7 +33100,6 @@
field public static final java.lang.String DATABASE_CREATION_TIMESTAMP = "database_creation_timestamp";
field public static final java.lang.String STATUS = "status";
field public static final int STATUS_BUSY = 1; // 0x1
- field public static final android.net.Uri STATUS_CHANGE_NOTIFICATION_CONTENT_URI;
field public static final int STATUS_EMPTY = 2; // 0x2
field public static final int STATUS_NORMAL = 0; // 0x0
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 594fa2e..aa49f23 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -461,6 +461,7 @@
field public static final int calendarTextColor = 16843931; // 0x101049b
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
+ field public static final int canCaptureFingerprintGestures = 16844111; // 0x101054f
field public static final int canControlMagnification = 16844039; // 0x1010507
field public static final int canPerformGestures = 16844045; // 0x101050d
field public static final int canRecord = 16844060; // 0x101051c
@@ -2811,6 +2812,7 @@
method public final void disableSelf();
method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+ method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
@@ -2902,6 +2904,7 @@
method public java.lang.String getSettingsActivityName();
method public java.lang.String loadDescription(android.content.pm.PackageManager);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 64; // 0x40
field public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 16; // 0x10
field public static final int CAPABILITY_CAN_PERFORM_GESTURES = 32; // 0x20
field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
@@ -2917,6 +2920,7 @@
field public static final int FEEDBACK_HAPTIC = 2; // 0x2
field public static final int FEEDBACK_SPOKEN = 1; // 0x1
field public static final int FEEDBACK_VISUAL = 8; // 0x8
+ field public static final int FLAG_CAPTURE_FINGERPRINT_GESTURES = 512; // 0x200
field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
@@ -2931,6 +2935,22 @@
field public java.lang.String[] packageNames;
}
+ public final class FingerprintGestureController {
+ method public boolean isGestureDetectionAvailable();
+ method public void registerFingerprintGestureCallback(android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback, android.os.Handler);
+ method public void unregisterFingerprintGestureCallback(android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback);
+ field public static final int FINGERPRINT_GESTURE_SWIPE_DOWN = 8; // 0x8
+ field public static final int FINGERPRINT_GESTURE_SWIPE_LEFT = 2; // 0x2
+ field public static final int FINGERPRINT_GESTURE_SWIPE_RIGHT = 1; // 0x1
+ field public static final int FINGERPRINT_GESTURE_SWIPE_UP = 4; // 0x4
+ }
+
+ public static abstract class FingerprintGestureController.FingerprintGestureCallback {
+ ctor public FingerprintGestureController.FingerprintGestureCallback();
+ method public void onGesture(int);
+ method public void onGestureDetectionAvailabilityChanged(boolean);
+ }
+
public final class GestureDescription {
method public static long getMaxGestureDuration();
method public static int getMaxStrokeCount();
@@ -4676,6 +4696,7 @@
method public final boolean isInLayout();
method public final boolean isRemoving();
method public final boolean isResumed();
+ method public final boolean isStateSaved();
method public final boolean isVisible();
method public void onActivityCreated(android.os.Bundle);
method public void onActivityResult(int, int, android.content.Intent);
@@ -4914,6 +4935,7 @@
method public abstract android.app.FragmentTransaction hide(android.app.Fragment);
method public abstract boolean isAddToBackStackAllowed();
method public abstract boolean isEmpty();
+ method public abstract android.app.FragmentTransaction postOnCommit(java.lang.Runnable);
method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
@@ -33725,7 +33747,6 @@
method public final void attachBaseContext(android.content.Context);
method public final android.os.IBinder onBind(android.content.Intent);
method public abstract java.util.List<android.content.pm.permission.RuntimePermissionPresentationInfo> onGetAppPermissions(java.lang.String);
- method public abstract java.util.List<android.content.pm.ApplicationInfo> onGetAppsUsingPermissions(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.permissionpresenterservice.RuntimePermissionPresenterService";
}
@@ -35835,7 +35856,7 @@
ctor public ContactsContract.Intents();
field public static final java.lang.String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS = "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
field public static final java.lang.String ATTACH_IMAGE = "com.android.contacts.action.ATTACH_IMAGE";
- field public static final deprecated java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
+ field public static final java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
field public static final java.lang.String EXTRA_CREATE_DESCRIPTION = "com.android.contacts.action.CREATE_DESCRIPTION";
field public static final java.lang.String EXTRA_FORCE_CREATE = "com.android.contacts.action.FORCE_CREATE";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
@@ -35978,7 +35999,6 @@
field public static final java.lang.String DATABASE_CREATION_TIMESTAMP = "database_creation_timestamp";
field public static final java.lang.String STATUS = "status";
field public static final int STATUS_BUSY = 1; // 0x1
- field public static final android.net.Uri STATUS_CHANGE_NOTIFICATION_CONTENT_URI;
field public static final int STATUS_EMPTY = 2; // 0x2
field public static final int STATUS_NORMAL = 0; // 0x0
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 0261629..86936d3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -349,6 +349,7 @@
field public static final int calendarTextColor = 16843931; // 0x101049b
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
+ field public static final int canCaptureFingerprintGestures = 16844111; // 0x101054f
field public static final int canControlMagnification = 16844039; // 0x1010507
field public static final int canPerformGestures = 16844045; // 0x101050d
field public static final int canRecord = 16844060; // 0x101051c
@@ -2692,6 +2693,7 @@
method public final void disableSelf();
method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+ method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
@@ -2783,6 +2785,7 @@
method public java.lang.String getSettingsActivityName();
method public java.lang.String loadDescription(android.content.pm.PackageManager);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 64; // 0x40
field public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 16; // 0x10
field public static final int CAPABILITY_CAN_PERFORM_GESTURES = 32; // 0x20
field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
@@ -2798,6 +2801,7 @@
field public static final int FEEDBACK_HAPTIC = 2; // 0x2
field public static final int FEEDBACK_SPOKEN = 1; // 0x1
field public static final int FEEDBACK_VISUAL = 8; // 0x8
+ field public static final int FLAG_CAPTURE_FINGERPRINT_GESTURES = 512; // 0x200
field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
@@ -2812,6 +2816,22 @@
field public java.lang.String[] packageNames;
}
+ public final class FingerprintGestureController {
+ method public boolean isGestureDetectionAvailable();
+ method public void registerFingerprintGestureCallback(android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback, android.os.Handler);
+ method public void unregisterFingerprintGestureCallback(android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback);
+ field public static final int FINGERPRINT_GESTURE_SWIPE_DOWN = 8; // 0x8
+ field public static final int FINGERPRINT_GESTURE_SWIPE_LEFT = 2; // 0x2
+ field public static final int FINGERPRINT_GESTURE_SWIPE_RIGHT = 1; // 0x1
+ field public static final int FINGERPRINT_GESTURE_SWIPE_UP = 4; // 0x4
+ }
+
+ public static abstract class FingerprintGestureController.FingerprintGestureCallback {
+ ctor public FingerprintGestureController.FingerprintGestureCallback();
+ method public void onGesture(int);
+ method public void onGestureDetectionAvailabilityChanged(boolean);
+ }
+
public final class GestureDescription {
method public static long getMaxGestureDuration();
method public static int getMaxStrokeCount();
@@ -4526,6 +4546,7 @@
method public final boolean isInLayout();
method public final boolean isRemoving();
method public final boolean isResumed();
+ method public final boolean isStateSaved();
method public final boolean isVisible();
method public void onActivityCreated(android.os.Bundle);
method public void onActivityResult(int, int, android.content.Intent);
@@ -4764,6 +4785,7 @@
method public abstract android.app.FragmentTransaction hide(android.app.Fragment);
method public abstract boolean isAddToBackStackAllowed();
method public abstract boolean isEmpty();
+ method public abstract android.app.FragmentTransaction postOnCommit(java.lang.Runnable);
method public abstract android.app.FragmentTransaction remove(android.app.Fragment);
method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment);
method public abstract android.app.FragmentTransaction replace(int, android.app.Fragment, java.lang.String);
@@ -33083,7 +33105,7 @@
ctor public ContactsContract.Intents();
field public static final java.lang.String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS = "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
field public static final java.lang.String ATTACH_IMAGE = "com.android.contacts.action.ATTACH_IMAGE";
- field public static final deprecated java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
+ field public static final java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
field public static final java.lang.String EXTRA_CREATE_DESCRIPTION = "com.android.contacts.action.CREATE_DESCRIPTION";
field public static final java.lang.String EXTRA_FORCE_CREATE = "com.android.contacts.action.FORCE_CREATE";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
@@ -33196,7 +33218,6 @@
field public static final java.lang.String DATABASE_CREATION_TIMESTAMP = "database_creation_timestamp";
field public static final java.lang.String STATUS = "status";
field public static final int STATUS_BUSY = 1; // 0x1
- field public static final android.net.Uri STATUS_CHANGE_NOTIFICATION_CONTENT_URI;
field public static final int STATUS_EMPTY = 2; // 0x2
field public static final int STATUS_NORMAL = 0; // 0x0
}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 3e5cc54..a036b6a 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -20,11 +20,13 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.graphics.Region;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -33,11 +35,9 @@
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.Log;
-import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.KeyEvent;
-import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityEvent;
@@ -362,19 +362,22 @@
private static final String LOG_TAG = "AccessibilityService";
/**
+ * Interface used by IAccessibilityServiceWrapper to call the service from its main thread.
* @hide
*/
public interface Callbacks {
- public void onAccessibilityEvent(AccessibilityEvent event);
- public void onInterrupt();
- public void onServiceConnected();
- public void init(int connectionId, IBinder windowToken);
- public boolean onGesture(int gestureId);
- public boolean onKeyEvent(KeyEvent event);
- public void onMagnificationChanged(@NonNull Region region,
+ void onAccessibilityEvent(AccessibilityEvent event);
+ void onInterrupt();
+ void onServiceConnected();
+ void init(int connectionId, IBinder windowToken);
+ boolean onGesture(int gestureId);
+ boolean onKeyEvent(KeyEvent event);
+ void onMagnificationChanged(@NonNull Region region,
float scale, float centerX, float centerY);
- public void onSoftKeyboardShowModeChanged(int showMode);
- public void onPerformGestureResult(int sequence, boolean completedSuccessfully);
+ void onSoftKeyboardShowModeChanged(int showMode);
+ void onPerformGestureResult(int sequence, boolean completedSuccessfully);
+ void onFingerprintCapturingGesturesChanged(boolean active);
+ void onFingerprintGesture(int gesture);
}
/**
@@ -404,6 +407,8 @@
private final Object mLock = new Object();
+ private FingerprintGestureController mFingerprintGestureController;
+
/**
* Callback for {@link android.view.accessibility.AccessibilityEvent}s.
*
@@ -598,6 +603,32 @@
}
/**
+ * Get the controller for fingerprint gestures. This feature requires {@link
+ * AccessibilityServiceInfo#CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES}.
+ *
+ *<strong>Note: </strong> The service must be connected before this method is called.
+ *
+ * @return The controller for fingerprint gestures, or {@code null} if gestures are unavailable.
+ */
+ @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT)
+ public final @Nullable FingerprintGestureController getFingerprintGestureController() {
+ if (mFingerprintGestureController == null) {
+ FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
+ if ((fingerprintManager != null) && fingerprintManager.isHardwareDetected()) {
+ AccessibilityServiceInfo info = getServiceInfo();
+ int fingerprintCapabilityMask =
+ AccessibilityServiceInfo.CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES;
+ if ((info.getCapabilities() & fingerprintCapabilityMask) != 0) {
+ mFingerprintGestureController = new FingerprintGestureController(
+ AccessibilityInteractionClient.getInstance()
+ .getConnection(mConnectionId));
+ }
+ }
+ }
+ return mFingerprintGestureController;
+ }
+
+ /**
* Dispatch a gesture to the touch screen. Any gestures currently in progress, whether from
* the user, this service, or another service, will be cancelled.
* <p>
@@ -694,6 +725,22 @@
}
/**
+ * Callback for fingerprint gesture handling
+ * @param active If gesture detection is active
+ */
+ private void onFingerprintCapturingGesturesChanged(boolean active) {
+ getFingerprintGestureController().onGestureDetectionActiveChanged(active);
+ }
+
+ /**
+ * Callback for fingerprint gesture handling
+ * @param gesture The identifier for the gesture performed
+ */
+ private void onFingerprintGesture(int gesture) {
+ getFingerprintGestureController().onGesture(gesture);
+ }
+
+ /**
* Used to control and query the state of display magnification.
*/
public static final class MagnificationController {
@@ -1486,6 +1533,16 @@
public void onPerformGestureResult(int sequence, boolean completedSuccessfully) {
AccessibilityService.this.onPerformGestureResult(sequence, completedSuccessfully);
}
+
+ @Override
+ public void onFingerprintCapturingGesturesChanged(boolean active) {
+ AccessibilityService.this.onFingerprintCapturingGesturesChanged(active);
+ }
+
+ @Override
+ public void onFingerprintGesture(int gesture) {
+ AccessibilityService.this.onFingerprintGesture(gesture);
+ }
});
}
@@ -1506,6 +1563,8 @@
private static final int DO_ON_MAGNIFICATION_CHANGED = 7;
private static final int DO_ON_SOFT_KEYBOARD_SHOW_MODE_CHANGED = 8;
private static final int DO_GESTURE_COMPLETE = 9;
+ private static final int DO_ON_FINGERPRINT_ACTIVE_CHANGED = 10;
+ private static final int DO_ON_FINGERPRINT_GESTURE = 11;
private final HandlerCaller mCaller;
@@ -1577,6 +1636,15 @@
mCaller.sendMessage(message);
}
+ public void onFingerprintCapturingGesturesChanged(boolean active) {
+ mCaller.sendMessage(mCaller.obtainMessageI(
+ DO_ON_FINGERPRINT_ACTIVE_CHANGED, active ? 1 : 0));
+ }
+
+ public void onFingerprintGesture(int gesture) {
+ mCaller.sendMessage(mCaller.obtainMessageI(DO_ON_FINGERPRINT_GESTURE, gesture));
+ }
+
@Override
public void executeMessage(Message message) {
switch (message.what) {
@@ -1675,6 +1743,12 @@
final boolean successfully = message.arg2 == 1;
mCallback.onPerformGestureResult(message.arg1, successfully);
} return;
+ case DO_ON_FINGERPRINT_ACTIVE_CHANGED: {
+ mCallback.onFingerprintCapturingGesturesChanged(message.arg1 == 1);
+ } return;
+ case DO_ON_FINGERPRINT_GESTURE: {
+ mCallback.onFingerprintGesture(message.arg1);
+ } return;
default :
Log.w(LOG_TAG, "Unknown message type " + message.what);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index b76aeb7..18e57cb 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -25,6 +25,7 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -116,34 +117,13 @@
*/
public static final int CAPABILITY_CAN_PERFORM_GESTURES = 0x00000020;
- private static final SparseArray<CapabilityInfo> sAvailableCapabilityInfos =
- new SparseArray<CapabilityInfo>();
- static {
- sAvailableCapabilityInfos.put(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
- new CapabilityInfo(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
- R.string.capability_title_canRetrieveWindowContent,
- R.string.capability_desc_canRetrieveWindowContent));
- sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
- new CapabilityInfo(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
- R.string.capability_title_canRequestTouchExploration,
- R.string.capability_desc_canRequestTouchExploration));
- sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
- new CapabilityInfo(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
- R.string.capability_title_canRequestEnhancedWebAccessibility,
- R.string.capability_desc_canRequestEnhancedWebAccessibility));
- sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
- new CapabilityInfo(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
- R.string.capability_title_canRequestFilterKeyEvents,
- R.string.capability_desc_canRequestFilterKeyEvents));
- sAvailableCapabilityInfos.put(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
- new CapabilityInfo(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
- R.string.capability_title_canControlMagnification,
- R.string.capability_desc_canControlMagnification));
- sAvailableCapabilityInfos.put(CAPABILITY_CAN_PERFORM_GESTURES,
- new CapabilityInfo(CAPABILITY_CAN_PERFORM_GESTURES,
- R.string.capability_title_canPerformGestures,
- R.string.capability_desc_canPerformGestures));
- }
+ /**
+ * Capability: This accessibility service can capture gestures from the fingerprint sensor
+ * @see android.R.styleable#AccessibilityService_canCaptureFingerprintGestures
+ */
+ public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 0x00000040;
+
+ private static SparseArray<CapabilityInfo> sAvailableCapabilityInfos;
/**
* Denotes spoken feedback.
@@ -326,6 +306,12 @@
*/
public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 0x00000080;
+ /**
+ * This flag requests that all fingerprint gestures be sent to the accessibility service.
+ * It is handled in {@link FingerprintGestureController}
+ */
+ public static final int FLAG_CAPTURE_FINGERPRINT_GESTURES = 0x00000200;
+
/** {@hide} */
public static final int FLAG_FORCE_DIRECT_BOOT_AWARE = 0x00010000;
@@ -535,6 +521,10 @@
.AccessibilityService_canPerformGestures, false)) {
mCapabilities |= CAPABILITY_CAN_PERFORM_GESTURES;
}
+ if (asAttributes.getBoolean(com.android.internal.R.styleable
+ .AccessibilityService_canCaptureFingerprintGestures, false)) {
+ mCapabilities |= CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES;
+ }
TypedValue peekedValue = asAttributes.peekValue(
com.android.internal.R.styleable.AccessibilityService_description);
if (peekedValue != null) {
@@ -946,6 +936,8 @@
return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
case FLAG_ENABLE_ACCESSIBILITY_VOLUME:
return "FLAG_ENABLE_ACCESSIBILITY_VOLUME";
+ case FLAG_CAPTURE_FINGERPRINT_GESTURES:
+ return "FLAG_CAPTURE_FINGERPRINT_GESTURES";
default:
return null;
}
@@ -973,6 +965,8 @@
return "CAPABILITY_CAN_CONTROL_MAGNIFICATION";
case CAPABILITY_CAN_PERFORM_GESTURES:
return "CAPABILITY_CAN_PERFORM_GESTURES";
+ case CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES:
+ return "CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES";
default:
return "UNKNOWN";
}
@@ -981,17 +975,29 @@
/**
* @hide
* @return The list of {@link CapabilityInfo} objects.
+ * @deprecated The version that takes a context works better.
*/
public List<CapabilityInfo> getCapabilityInfos() {
+ return getCapabilityInfos(null);
+ }
+
+ /**
+ * @hide
+ * @param context A valid context
+ * @return The list of {@link CapabilityInfo} objects.
+ */
+ public List<CapabilityInfo> getCapabilityInfos(Context context) {
if (mCapabilities == 0) {
return Collections.emptyList();
}
int capabilities = mCapabilities;
List<CapabilityInfo> capabilityInfos = new ArrayList<CapabilityInfo>();
+ SparseArray<CapabilityInfo> capabilityInfoSparseArray =
+ getCapabilityInfoSparseArray(context);
while (capabilities != 0) {
final int capabilityBit = 1 << Integer.numberOfTrailingZeros(capabilities);
capabilities &= ~capabilityBit;
- CapabilityInfo capabilityInfo = sAvailableCapabilityInfos.get(capabilityBit);
+ CapabilityInfo capabilityInfo = capabilityInfoSparseArray.get(capabilityBit);
if (capabilityInfo != null) {
capabilityInfos.add(capabilityInfo);
}
@@ -999,6 +1005,44 @@
return capabilityInfos;
}
+ private static SparseArray<CapabilityInfo> getCapabilityInfoSparseArray(Context context) {
+ if (sAvailableCapabilityInfos == null) {
+ sAvailableCapabilityInfos = new SparseArray<CapabilityInfo>();
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
+ new CapabilityInfo(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
+ R.string.capability_title_canRetrieveWindowContent,
+ R.string.capability_desc_canRetrieveWindowContent));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
+ new CapabilityInfo(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
+ R.string.capability_title_canRequestTouchExploration,
+ R.string.capability_desc_canRequestTouchExploration));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
+ new CapabilityInfo(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
+ R.string.capability_title_canRequestEnhancedWebAccessibility,
+ R.string.capability_desc_canRequestEnhancedWebAccessibility));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
+ new CapabilityInfo(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
+ R.string.capability_title_canRequestFilterKeyEvents,
+ R.string.capability_desc_canRequestFilterKeyEvents));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
+ new CapabilityInfo(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
+ R.string.capability_title_canControlMagnification,
+ R.string.capability_desc_canControlMagnification));
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_PERFORM_GESTURES,
+ new CapabilityInfo(CAPABILITY_CAN_PERFORM_GESTURES,
+ R.string.capability_title_canPerformGestures,
+ R.string.capability_desc_canPerformGestures));
+ if ((context == null)
+ || context.getSystemService(FingerprintManager.class).isHardwareDetected()) {
+ sAvailableCapabilityInfos.put(CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES,
+ new CapabilityInfo(CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES,
+ R.string.capability_title_canCaptureFingerprintGestures,
+ R.string.capability_desc_canCaptureFingerprintGestures));
+ }
+ }
+ return sAvailableCapabilityInfos;
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/accessibilityservice/FingerprintGestureController.java b/core/java/android/accessibilityservice/FingerprintGestureController.java
new file mode 100644
index 0000000..e203c6d
--- /dev/null
+++ b/core/java/android/accessibilityservice/FingerprintGestureController.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accessibilityservice;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * An {@link AccessibilityService} can capture gestures performed on a device's fingerprint
+ * sensor, as long as the device has a sensor capable of detecting gestures.
+ * <p>
+ * This capability must be declared by the service as
+ * {@link AccessibilityServiceInfo#CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES}. It also requires
+ * the permission {@link android.Manifest.permission#USE_FINGERPRINT}.
+ * <p>
+ * Because capturing fingerprint gestures may have side effects, services with the capability only
+ * capture gestures when {@link AccessibilityServiceInfo#FLAG_CAPTURE_FINGERPRINT_GESTURES} is set.
+ * <p>
+ * <strong>Note: </strong>The fingerprint sensor is used for authentication in critical use cases,
+ * so services must carefully design their user's experience when performing gestures on the sensor.
+ * When the sensor is in use by an app, for example, when authenticating or enrolling a user,
+ * the sensor will not detect gestures. Services need to ensure that users understand when the
+ * sensor is in-use for authentication to prevent users from authenticating unintentionally when
+ * trying to interact with the service. They can use
+ * {@link FingerprintGestureCallback#onGestureDetectionAvailabilityChanged(boolean)} to learn when
+ * gesture detection becomes unavailable.
+ * <p>
+ * Multiple accessibility services may listen for fingerprint gestures simultaneously, so services
+ * should provide a way for the user to disable the use of this feature so multiple services don't
+ * conflict with each other.
+ * <p>
+ * {@see android.hardware.fingerprint.FingerprintManager#isHardwareDetected}
+ */
+public final class FingerprintGestureController {
+ /** Identifier for a swipe right on the fingerprint sensor */
+ public static final int FINGERPRINT_GESTURE_SWIPE_RIGHT = 0x00000001;
+
+ /** Identifier for a swipe left on the fingerprint sensor */
+ public static final int FINGERPRINT_GESTURE_SWIPE_LEFT = 0x00000002;
+
+ /** Identifier for a swipe up on the fingerprint sensor */
+ public static final int FINGERPRINT_GESTURE_SWIPE_UP = 0x00000004;
+
+ /** Identifier for a swipe down on the fingerprint sensor */
+ public static final int FINGERPRINT_GESTURE_SWIPE_DOWN = 0x00000008;
+
+ private static final String LOG_TAG = "FingerprintGestureController";
+ private final Object mLock = new Object();
+ private final IAccessibilityServiceConnection mAccessibilityServiceConnection;
+
+ private final ArrayMap<FingerprintGestureCallback, Handler> mCallbackHandlerMap =
+ new ArrayMap<>(1);
+
+ /**
+ * @param connection The connection to use for system interactions
+ * @hide
+ */
+ @VisibleForTesting
+ public FingerprintGestureController(IAccessibilityServiceConnection connection) {
+ mAccessibilityServiceConnection = connection;
+ }
+
+ /**
+ * Gets if the fingerprint sensor's gesture detection is available.
+ *
+ * @return {@code true} if the sensor's gesture detection is available. {@code false} if it is
+ * not currently detecting gestures (for example, if it is enrolling a finger).
+ */
+ public boolean isGestureDetectionAvailable() {
+ try {
+ return mAccessibilityServiceConnection.isFingerprintGestureDetectionAvailable();
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Failed to check if fingerprint gestures are active", re);
+ re.rethrowFromSystemServer();
+ return false;
+ }
+ }
+
+ /**
+ * Register a callback to be informed of fingerprint sensor gesture events.
+ *
+ * @param callback The listener to be added.
+ * @param handler The handler to use for the callback. If {@code null}, callbacks will happen
+ * on the service's main thread.
+ */
+ public void registerFingerprintGestureCallback(
+ @NonNull FingerprintGestureCallback callback, @Nullable Handler handler) {
+ synchronized (mLock) {
+ mCallbackHandlerMap.put(callback, handler);
+ }
+ }
+
+ /**
+ * Unregister a listener added with {@link #registerFingerprintGestureCallback}.
+ *
+ * @param callback The callback to remove. Removing a callback that was never added has no
+ * effect.
+ */
+ public void unregisterFingerprintGestureCallback(FingerprintGestureCallback callback) {
+ synchronized (mLock) {
+ mCallbackHandlerMap.remove(callback);
+ }
+ }
+
+ /**
+ * Called when gesture detection becomes active or inactive
+ * @hide
+ */
+ public void onGestureDetectionActiveChanged(boolean active) {
+ final ArrayMap<FingerprintGestureCallback, Handler> handlerMap;
+ synchronized (mLock) {
+ handlerMap = new ArrayMap<>(mCallbackHandlerMap);
+ }
+ int numListeners = handlerMap.size();
+ for (int i = 0; i < numListeners; i++) {
+ FingerprintGestureCallback callback = handlerMap.keyAt(i);
+ Handler handler = handlerMap.valueAt(i);
+ if (handler != null) {
+ handler.post(() -> callback.onGestureDetectionAvailabilityChanged(active));
+ } else {
+ callback.onGestureDetectionAvailabilityChanged(active);
+ }
+ }
+ }
+
+ /**
+ * Called when gesture is detected.
+ * @hide
+ */
+ public void onGesture(int gesture) {
+ final ArrayMap<FingerprintGestureCallback, Handler> handlerMap;
+ synchronized (mLock) {
+ handlerMap = new ArrayMap<>(mCallbackHandlerMap);
+ }
+ int numListeners = handlerMap.size();
+ for (int i = 0; i < numListeners; i++) {
+ FingerprintGestureCallback callback = handlerMap.keyAt(i);
+ Handler handler = handlerMap.valueAt(i);
+ if (handler != null) {
+ handler.post(() -> callback.onGesture(gesture));
+ } else {
+ callback.onGesture(gesture);
+ }
+ }
+ }
+
+ /**
+ * Class that is called back when fingerprint gestures are being used for accessibility.
+ */
+ public abstract static class FingerprintGestureCallback {
+ /**
+ * Called when the fingerprint sensor's gesture detection becomes available or unavailable.
+ *
+ * @param available Whether or not the sensor's gesture detection is now available.
+ */
+ public void onGestureDetectionAvailabilityChanged(boolean available) {}
+
+ /**
+ * Called when the fingerprint sensor detects gestures.
+ *
+ * @param gesture The id of the gesture that was detected. For example,
+ * {@link #FINGERPRINT_GESTURE_SWIPE_RIGHT}.
+ */
+ public void onGesture(int gesture) {}
+ }
+}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index da16a65..3f778ad 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -46,4 +46,8 @@
void onSoftKeyboardShowModeChanged(int showMode);
void onPerformGestureResult(int sequence, boolean completedSuccessfully);
+
+ void onFingerprintCapturingGesturesChanged(boolean capturing);
+
+ void onFingerprintGesture(int gesture);
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 81cddba..5499bd5 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -89,4 +89,6 @@
void setSoftKeyboardCallbackEnabled(boolean enabled);
void sendGesture(int sequence, in ParceledListSlice gestureSteps);
+
+ boolean isFingerprintGestureDetectionAvailable();
}
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 08ad976..4ebcc44 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -26,7 +26,7 @@
* This is the superclass for classes which provide basic support for animations which can be
* started, ended, and have <code>AnimatorListeners</code> added to them.
*/
-public abstract class Animator implements Cloneable, AnimationHandler.AnimationFrameCallback {
+public abstract class Animator implements Cloneable {
/**
* The value used to indicate infinite duration (e.g. when Animators repeat infinitely).
@@ -464,24 +464,14 @@
throw new IllegalStateException("Reverse is not supported");
}
- /**
- * @hide
- */
- @Override
- public boolean doAnimationFrame(long frameTime) {
+ // Pulse an animation frame into the animation.
+ boolean pulseAnimationFrame(long frameTime) {
// TODO: Need to find a better signal than this. There's a bug in SystemUI that's preventing
// returning !isStarted() from working.
return false;
}
/**
- * @hide
- */
- @Override
- public void commitAnimationFrame(long frameTime) {}
-
-
- /**
* Internal use only.
* This call starts the animation in regular or reverse direction without requiring them to
* register frame callbacks. The caller will be responsible for all the subsequent animation
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 8aba405..4e3b7d0 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -948,7 +948,8 @@
for (int i = 0; i < mPlayingSet.size(); i++) {
Node node = mPlayingSet.get(i);
if (!node.mEnded) {
- node.mEnded = node.mAnimation.doAnimationFrame(getPlayTimeForNode(playTime, node));
+ node.mEnded = node.mAnimation.pulseAnimationFrame(
+ getPlayTimeForNode(playTime, node));
}
}
@@ -978,6 +979,19 @@
}
/**
+ * @hide
+ */
+ @Override
+ public void commitAnimationFrame(long frameTime) {
+ // No op.
+ }
+
+ @Override
+ boolean pulseAnimationFrame(long frameTime) {
+ return doAnimationFrame(frameTime);
+ }
+
+ /**
* When playing forward, we call start() at the animation's scheduled start time, and make sure
* to pump a frame at the animation's scheduled end time.
*
@@ -993,11 +1007,10 @@
if (event.mEvent == AnimationEvent.ANIMATION_END) {
mPlayingSet.add(event.mNode);
node.mAnimation.startWithoutPulsing(true);
- node.mAnimation.doAnimationFrame(0);
+ pulseFrame(node, 0);
} else if (event.mEvent == AnimationEvent.ANIMATION_DELAY_ENDED && !node.mEnded) {
// end event:
- node.mEnded =
- node.mAnimation.doAnimationFrame(getPlayTimeForNode(playTime, node));
+ pulseFrame(node, getPlayTimeForNode(playTime, node));
}
}
} else {
@@ -1007,16 +1020,21 @@
if (event.mEvent == AnimationEvent.ANIMATION_START) {
mPlayingSet.add(event.mNode);
node.mAnimation.startWithoutPulsing(false);
- node.mAnimation.doAnimationFrame(0);
+ pulseFrame(node, 0);
} else if (event.mEvent == AnimationEvent.ANIMATION_END && !node.mEnded) {
// start event:
- node.mEnded =
- node.mAnimation.doAnimationFrame(getPlayTimeForNode(playTime, node));
+ pulseFrame(node, getPlayTimeForNode(playTime, node));
}
}
}
}
+ private void pulseFrame(Node node, long frameTime) {
+ if (!node.mEnded) {
+ node.mEnded = node.mAnimation.pulseAnimationFrame(frameTime);
+ }
+ }
+
private long getPlayTimeForNode(long overallPlayTime, Node node) {
return getPlayTimeForNode(overallPlayTime, node, mReversing);
}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 470523f..55ac1f4 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -68,7 +68,7 @@
* </div>
*/
@SuppressWarnings("unchecked")
-public class ValueAnimator extends Animator {
+public class ValueAnimator extends Animator implements AnimationHandler.AnimationFrameCallback {
private static final String TAG = "ValueAnimator";
private static final boolean DEBUG = false;
@@ -225,6 +225,12 @@
private boolean mSelfPulse = true;
/**
+ * Whether or not the animator has been requested to start without pulsing. This flag gets set
+ * in startWithoutPulsing(), and reset in start().
+ */
+ private boolean mSuppressSelfPulseRequested = false;
+
+ /**
* The time interpolator to be used. The elapsed fraction of the animation will be passed
* through this interpolator to calculate the interpolated fraction, which is then used to
* calculate the animated values.
@@ -997,12 +1003,12 @@
*
* @param playBackwards Whether the ValueAnimator should start playing in reverse.
*/
- private void start(boolean playBackwards, boolean selfPulse) {
+ private void start(boolean playBackwards) {
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
mReversing = playBackwards;
- mSelfPulse = selfPulse;
+ mSelfPulse = !mSuppressSelfPulseRequested;
// Special case: reversing from seek-to-0 should act as if not seeked at all.
if (playBackwards && mSeekFraction != -1 && mSeekFraction != 0) {
if (mRepeatCount == INFINITE) {
@@ -1041,12 +1047,18 @@
}
void startWithoutPulsing(boolean inReverse) {
- start(inReverse, false);
+ mSuppressSelfPulseRequested = true;
+ if (inReverse) {
+ reverse();
+ } else {
+ start();
+ }
+ mSuppressSelfPulseRequested = false;
}
@Override
public void start() {
- start(false, true);
+ start(false);
}
@Override
@@ -1150,7 +1162,7 @@
mReversing = !mReversing;
end();
} else {
- start(true, true);
+ start(true);
}
}
@@ -1364,6 +1376,11 @@
animateValue(endFraction);
}
+ @Override
+ boolean isInitialized() {
+ return mInitialized;
+ }
+
/**
* Processes a frame of the animation, adjusting the start time if needed.
*
@@ -1430,6 +1447,20 @@
return finished;
}
+ @Override
+ boolean pulseAnimationFrame(long frameTime) {
+ if (mSelfPulse) {
+ // Pulse animation frame will *always* be after calling start(). If mSelfPulse isn't
+ // set to false at this point, that means child animators did not call super's start().
+ // This can happen when the Animator is just a non-animating wrapper around a real
+ // functional animation. In this case, we can't really pulse a frame into the animation,
+ // because the animation cannot necessarily be properly initialized (i.e. no start/end
+ // values set).
+ return false;
+ }
+ return doAnimationFrame(frameTime);
+ }
+
private void addOneShotCommitCallback() {
if (!mSelfPulse) {
return;
@@ -1514,6 +1545,8 @@
anim.mFirstFrameTime = -1;
anim.mOverallFraction = 0;
anim.mCurrentFraction = 0;
+ anim.mSelfPulse = true;
+ anim.mSuppressSelfPulseRequested = false;
PropertyValuesHolder[] oldValues = mValues;
if (oldValues != null) {
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index a27775e..66b2355 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -220,6 +220,8 @@
int mIndex = -1;
boolean mAllowOptimization;
+ ArrayList<Runnable> mCommitRunnables;
+
int mBreadCrumbTitleRes;
CharSequence mBreadCrumbTitleText;
int mBreadCrumbShortTitleRes;
@@ -620,6 +622,28 @@
}
}
+ @Override
+ public FragmentTransaction postOnCommit(Runnable runnable) {
+ if (runnable == null) {
+ throw new IllegalArgumentException("runnable cannot be null");
+ }
+ disallowAddToBackStack();
+ if (mCommitRunnables == null) {
+ mCommitRunnables = new ArrayList<>();
+ }
+ mCommitRunnables.add(runnable);
+ return this;
+ }
+
+ public void runOnCommitRunnables() {
+ if (mCommitRunnables != null) {
+ for (int i = 0, N = mCommitRunnables.size(); i < N; i++) {
+ mCommitRunnables.get(i).run();
+ }
+ mCommitRunnables = null;
+ }
+ }
+
public int commit() {
return commitInternal(false);
}
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 612998d..108ab71 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -714,14 +714,20 @@
}
/**
- * Supply the construction arguments for this fragment. This can only
- * be called before the fragment has been attached to its activity; that
- * is, you should call it immediately after constructing the fragment. The
- * arguments supplied here will be retained across fragment destroy and
+ * Supply the construction arguments for this fragment.
+ * The arguments supplied here will be retained across fragment destroy and
* creation.
+ *
+ * <p>This method cannot be called if the fragment is added to a FragmentManager and
+ * if {@link #isStateSaved()} would return true. Prior to {@link Build.VERSION_CODES#O},
+ * this method may only be called if the fragment has not yet been added to a FragmentManager.
+ * </p>
*/
public void setArguments(Bundle args) {
- if (mIndex >= 0) {
+ // The isStateSaved requirement below was only added in Android O and is compatible
+ // because it loosens previous requirements rather than making them more strict.
+ // See method javadoc.
+ if (mIndex >= 0 && isStateSaved()) {
throw new IllegalStateException("Fragment already active");
}
mArguments = args;
@@ -735,6 +741,21 @@
}
/**
+ * Returns true if this fragment is added and its state has already been saved
+ * by its host. Any operations that would change saved state should not be performed
+ * if this method returns true, and some operations such as {@link #setArguments(Bundle)}
+ * will fail.
+ *
+ * @return true if this fragment's state has already been saved by its host
+ */
+ public final boolean isStateSaved() {
+ if (mFragmentManager == null) {
+ return false;
+ }
+ return mFragmentManager.isStateSaved();
+ }
+
+ /**
* Set the initial saved state that this Fragment should restore itself
* from when first being constructed, as returned by
* {@link FragmentManager#saveFragmentInstanceState(Fragment)
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index b0150bd..4f68ec7 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1787,6 +1787,10 @@
}
}
+ public boolean isStateSaved() {
+ return mStateSaved;
+ }
+
/**
* Adds an action to the queue of pending actions.
*
@@ -2108,6 +2112,7 @@
freeBackStackIndex(record.mIndex);
record.mIndex = -1;
}
+ record.runOnCommitRunnables();
}
if (addToBackStack) {
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 07a313c..c938aa6 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -304,6 +304,22 @@
public abstract FragmentTransaction setAllowOptimization(boolean allowOptimization);
/**
+ * Add a Runnable to this transaction that will be run after this transaction has
+ * been committed. If fragment transactions are {@link #setAllowOptimization(boolean) optimized}
+ * this may be after other subsequent fragment operations have also taken place, or operations
+ * in this transaction may have been optimized out due to the presence of a subsequent
+ * fragment transaction in the batch.
+ *
+ * <p><code>postOnCommit</code> may not be used with transactions
+ * {@link #addToBackStack(String) added to the back stack} as Runnables cannot be persisted
+ * with back stack state.</p>
+ *
+ * @param runnable Runnable to add
+ * @return this FragmentTransaction
+ */
+ public abstract FragmentTransaction postOnCommit(Runnable runnable);
+
+ /**
* Schedules a commit of this transaction. The commit does
* not happen immediately; it will be scheduled as work on the main thread
* to be done the next time that thread is ready.
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 54cc4a0..6d1d1a3 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1108,6 +1108,16 @@
public void onPerformGestureResult(int sequence, boolean completedSuccessfully) {
/* do nothing */
}
+
+ @Override
+ public void onFingerprintCapturingGesturesChanged(boolean active) {
+ /* do nothing */
+ }
+
+ @Override
+ public void onFingerprintGesture(int gesture) {
+ /* do nothing */
+ }
});
}
}
diff --git a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
index 8766508..3c3b84d 100644
--- a/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
+++ b/core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl
@@ -25,5 +25,4 @@
*/
oneway interface IRuntimePermissionPresenter {
void getAppPermissions(String packageName, in RemoteCallback callback);
- void getAppsUsingPermissions(boolean system, in RemoteCallback callback);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 2e39926..6d55d2f 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -72,15 +72,6 @@
List<RuntimePermissionPresentationInfo> permissions) {
/* do nothing - stub */
}
-
- /**
- * The result for {@link #getAppsUsingPermissions(boolean, List)}.
- * @param system Whether to return only the system apps or only the non-system ones.
- * @param apps The apps using runtime permissions.
- */
- public void getAppsUsingPermissions(boolean system, @NonNull List<ApplicationInfo> apps) {
- /* do nothing - stub */
- }
}
private static final Object sLock = new Object();
@@ -127,29 +118,6 @@
mRemoteService.processMessage(message);
}
- /**
- * Gets the system apps that use runtime permissions. System apps are ones
- * that are considered system for presentation purposes instead of ones
- * that are preinstalled on the system image. System apps are ones that
- * are on the system image, haven't been updated (a.k.a factory apps)
- * that do not have a launcher icon.
- *
- * @param system If true only system apps are returned otherwise only
- * non-system ones are returned.
- * @param callback Callback to receive the result.
- * @param handler Handler on which to invoke the callback.
- */
- public void getAppsUsingPermissions(boolean system, @NonNull OnResultCallback callback,
- @Nullable Handler handler) {
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callback;
- args.arg2 = handler;
- args.argi1 = system ? 1 : 0;
- Message message = mRemoteService.obtainMessage(
- RemoteService.MSG_GET_APPS_USING_PERMISSIONS, args);
- mRemoteService.processMessage(message);
- }
-
private static final class RemoteService
extends Handler implements ServiceConnection {
private static final long UNBIND_TIMEOUT_MILLIS = 10000;
@@ -254,51 +222,6 @@
scheduleUnbind();
} break;
- case MSG_GET_APPS_USING_PERMISSIONS: {
- SomeArgs args = (SomeArgs) msg.obj;
- final OnResultCallback callback = (OnResultCallback) args.arg1;
- final Handler handler = (Handler) args.arg2;
- final boolean system = args.argi1 == 1;
- args.recycle();
- final IRuntimePermissionPresenter remoteInstance;
- synchronized (mLock) {
- remoteInstance = mRemoteInstance;
- }
- if (remoteInstance == null) {
- return;
- }
- try {
- remoteInstance.getAppsUsingPermissions(system, new RemoteCallback(
- new RemoteCallback.OnResultListener() {
- @Override
- public void onResult(Bundle result) {
- final List<ApplicationInfo> reportedApps;
- List<ApplicationInfo> apps = null;
- if (result != null) {
- apps = result.getParcelableArrayList(KEY_RESULT);
- }
- if (apps == null) {
- apps = Collections.emptyList();
- }
- reportedApps = apps;
- if (handler != null) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- callback.getAppsUsingPermissions(system, reportedApps);
- }
- });
- } else {
- callback.getAppsUsingPermissions(system, reportedApps);
- }
- }
- }, this));
- } catch (RemoteException re) {
- Log.e(TAG, "Error getting apps using permissions", re);
- }
- scheduleUnbind();
- } break;
-
case MSG_UNBIND: {
synchronized (mLock) {
if (mBound) {
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 612a751..522575f 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -293,7 +293,8 @@
* case is to create a capture session with that output configuration. For example, if the
* camera device uses the same private buffer format between a SurfaceView/SurfaceTexture and a
* MediaRecorder/MediaCodec, {@link CameraDevice#createCaptureSessionByOutputConfigurations}
- * will succeed. Otherwise, it throws {@code IllegalArgumentException}.
+ * will succeed. Otherwise, it fails with {@link
+ * CameraCaptureSession.StateCallback#onConfigureFailed}.
* </ol>
*
* <p>To enable surface sharing, this function must be called before {@link
diff --git a/core/java/android/hardware/fingerprint/IFingerprintClientActiveCallback.aidl b/core/java/android/hardware/fingerprint/IFingerprintClientActiveCallback.aidl
new file mode 100644
index 0000000..5bcf476
--- /dev/null
+++ b/core/java/android/hardware/fingerprint/IFingerprintClientActiveCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.fingerprint;
+
+/**
+ * Callback when clients become active or inactive.
+ * @hide
+ */
+oneway interface IFingerprintClientActiveCallback {
+ void onClientActiveChanged(boolean isActive);
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index ae3fc37..4879d54 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -16,6 +16,7 @@
package android.hardware.fingerprint;
import android.os.Bundle;
+import android.hardware.fingerprint.IFingerprintClientActiveCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
import android.hardware.fingerprint.Fingerprint;
@@ -82,4 +83,13 @@
// Enumerate all fingerprints
void enumerate(IBinder token, int userId, IFingerprintServiceReceiver receiver);
+
+ // Check if a client request is currently being handled
+ boolean isClientActive();
+
+ // Add a callback which gets notified when the service starts and stops handling client requests
+ void addClientActiveCallback(IFingerprintClientActiveCallback callback);
+
+ // Removes a callback set by addClientActiveCallback
+ void removeClientActiveCallback(IFingerprintClientActiveCallback callback);
}
diff --git a/core/java/android/net/NetworkRecommendationProvider.java b/core/java/android/net/NetworkRecommendationProvider.java
index 16ae867..5739c79 100644
--- a/core/java/android/net/NetworkRecommendationProvider.java
+++ b/core/java/android/net/NetworkRecommendationProvider.java
@@ -5,8 +5,6 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
-import android.os.Looper;
-import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
@@ -27,8 +25,6 @@
"android.net.extra.RECOMMENDATION_RESULT";
/** The key into the callback Bundle where the sequence will be found. */
public static final String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
- private static final String EXTRA_RECOMMENDATION_REQUEST =
- "android.net.extra.RECOMMENDATION_REQUEST";
private final IBinder mService;
/**
@@ -39,7 +35,7 @@
if (handler == null) {
throw new IllegalArgumentException("The provided handler cannot be null.");
}
- mService = new ServiceWrapper(new ServiceHandler(handler.getLooper()));
+ mService = new ServiceWrapper(handler);
}
/**
@@ -125,42 +121,10 @@
}
}
- private final class ServiceHandler extends Handler {
- static final int MSG_GET_RECOMMENDATION = 1;
- static final int MSG_REQUEST_SCORES = 2;
-
- ServiceHandler(Looper looper) {
- super(looper, null /*callback*/, true /*async*/);
- }
-
- @Override
- public void handleMessage(Message msg) {
- final int what = msg.what;
- switch (what) {
- case MSG_GET_RECOMMENDATION:
- final IRemoteCallback callback = (IRemoteCallback) msg.obj;
- final int seq = msg.arg1;
- final RecommendationRequest request =
- msg.getData().getParcelable(EXTRA_RECOMMENDATION_REQUEST);
- final ResultCallback resultCallback = new ResultCallback(callback, seq);
- onRequestRecommendation(request, resultCallback);
- break;
-
- case MSG_REQUEST_SCORES:
- final NetworkKey[] networks = (NetworkKey[]) msg.obj;
- onRequestScores(networks);
- break;
-
- default:
- throw new IllegalArgumentException("Unknown message: " + what);
- }
- }
- }
-
/**
- * A wrapper around INetworkRecommendationProvider that sends calls to the internal Handler.
+ * A wrapper around INetworkRecommendationProvider that dispatches to the provided Handler.
*/
- private static final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
+ private final class ServiceWrapper extends INetworkRecommendationProvider.Stub {
private final Handler mHandler;
ServiceWrapper(Handler handler) {
@@ -168,20 +132,26 @@
}
@Override
- public void requestRecommendation(RecommendationRequest request, IRemoteCallback callback,
- int sequence) throws RemoteException {
- final Message msg = mHandler.obtainMessage(
- ServiceHandler.MSG_GET_RECOMMENDATION, sequence, 0 /*arg2*/, callback);
- final Bundle data = new Bundle();
- data.putParcelable(EXTRA_RECOMMENDATION_REQUEST, request);
- msg.setData(data);
- msg.sendToTarget();
+ public void requestRecommendation(final RecommendationRequest request,
+ final IRemoteCallback callback, final int sequence) throws RemoteException {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ResultCallback resultCallback = new ResultCallback(callback, sequence);
+ onRequestRecommendation(request, resultCallback);
+ }
+ });
}
@Override
- public void requestScores(NetworkKey[] networks) throws RemoteException {
+ public void requestScores(final NetworkKey[] networks) throws RemoteException {
if (networks != null && networks.length > 0) {
- mHandler.obtainMessage(ServiceHandler.MSG_REQUEST_SCORES, networks).sendToTarget();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ onRequestScores(networks);
+ }
+ });
}
}
}
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 405be1a..344d947 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -72,14 +72,6 @@
*/
public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
- /**
- * Gets the apps that use runtime permissions.
- *
- * @param system Whether to return only the system apps or only the non-system ones.
- * @return The app list.
- */
- public abstract List<ApplicationInfo> onGetAppsUsingPermissions(boolean system);
-
@Override
public final IBinder onBind(Intent intent) {
return new IRuntimePermissionPresenter.Stub() {
@@ -91,12 +83,6 @@
mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
args).sendToTarget();
}
-
- @Override
- public void getAppsUsingPermissions(boolean system, RemoteCallback callback) {
- mHandler.obtainMessage(MyHandler.MSG_GET_APPS_USING_PERMISSIONS,
- system ? 1 : 0, 0, callback).sendToTarget();
- }
};
}
@@ -127,19 +113,6 @@
callback.sendResult(null);
}
} break;
-
- case MSG_GET_APPS_USING_PERMISSIONS: {
- RemoteCallback callback = (RemoteCallback) msg.obj;
- final boolean system = msg.arg1 == 1;
- List<ApplicationInfo> apps = onGetAppsUsingPermissions(system);
- if (apps != null && !apps.isEmpty()) {
- Bundle result = new Bundle();
- result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT, apps);
- callback.sendResult(result);
- } else {
- callback.sendResult(null);
- }
- } break;
}
}
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1b512c6..a0d16bc 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -19,6 +19,7 @@
import android.accounts.Account;
import android.annotation.SystemApi;
import android.app.Activity;
+import android.content.BroadcastReceiver;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
@@ -30,6 +31,7 @@
import android.content.Entity;
import android.content.EntityIterator;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.database.Cursor;
@@ -8170,29 +8172,11 @@
/**
* The content:// style URI for this table. Requests to this URI can be
* performed on the UI thread because they are always unblocking.
- *
- * <p>Note when you listen on this URI (or any other sub-URIs), you'll be notified for
- * regular contact change notifications too, which will be sent on the root URI.
- * If you only want to be notified for provider status change notifications, listen on
- * {@link #STATUS_CHANGE_NOTIFICATION_CONTENT_URI} instead.
*/
public static final Uri CONTENT_URI =
Uri.withAppendedPath(AUTHORITY_URI, "provider_status");
/**
- * URI to listen to provider status changes without listening to regular
- * contact changes. If a client only wants to monitor {@link ProviderStatus} with
- * {@link android.app.job.JobScheduler}, then this URI should be used instead of
- * {@link #CONTENT_URI}, because a job on {@link #CONTENT_URI} will also be invoked
- * when contacts are changed.
- *
- * <p>Note this URI cannot be queried. A query should be always made on
- * {@link #CONTENT_URI}.
- */
- public static final Uri STATUS_CHANGE_NOTIFICATION_CONTENT_URI =
- Uri.parse("content://com.android.contacts.provider_status");
-
- /**
* The MIME-type of {@link #CONTENT_URI} providing a directory of
* settings.
*/
@@ -8794,13 +8778,13 @@
* This is the intent that is fired when the contacts database is created. <p> The
* READ_CONTACT permission is required to receive these broadcasts.
*
- * <p>As of O, this broadcast will no longer be sent. Applications can use
- * use {@link android.app.job.JobScheduler} to monitor
- * {@link ProviderStatus#STATUS_CHANGE_NOTIFICATION_CONTENT_URI}, and read
- * {@link ProviderStatus#DATABASE_CREATION_TIMESTAMP} to get when
- * the contacts database was initialized.
+ * <p>Because this is an implicit broadcast, apps targeting Android O will no longer
+ * receive this broadcast via a manifest broadcast receiver. (Broadcast receivers
+ * registered at runtime with
+ * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)} will still receive it.)
+ * Instead, an app can use {@link ProviderStatus#DATABASE_CREATION_TIMESTAMP} to see if the
+ * contacts database has been initialized when it starts.
*/
- @Deprecated
public static final String CONTACTS_DATABASE_CREATED =
"android.provider.Contacts.DATABASE_CREATED";
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index bfb8d83..1ef0d17 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -633,6 +633,28 @@
}
/**
+ * Report a fingerprint gesture to accessibility. Only available for the system process.
+ *
+ * @param keyCode The key code of the gesture
+ * @return {@code true} if accessibility consumes the event. {@code false} if not.
+ * @hide
+ */
+ public boolean sendFingerprintGesture(int keyCode) {
+ final IAccessibilityManager service;
+ synchronized (mLock) {
+ service = getServiceLocked();
+ if (service == null) {
+ return false;
+ }
+ }
+ try {
+ return service.sendFingerprintGesture(keyCode);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
* Sets the current state and notifies listeners, if necessary.
*
* @param stateFlags The state flags.
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index ed77f68..136bbbe 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -1,5 +1,4 @@
-/* //device/java/android/android/app/INotificationManager.aidl
-**
+/*
** Copyright 2009, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -62,4 +61,7 @@
// Requires WRITE_SECURE_SETTINGS
void performAccessibilityShortcut();
+
+ // System process only
+ boolean sendFingerprintGesture(int gestureKeyCode);
}
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 34f78f3..c548219 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3392,6 +3392,8 @@
<flag name="flagRetrieveInteractiveWindows" value="0x00000040" />
<!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_ENABLE_ACCESSIBILITY_VOLUME} -->
<flag name="flagEnableAccessibilityVolume" value="0x00000080" />
+ <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_CAPTURE_FINGERPRINT_GESTURES} -->
+ <flag name="flagCaptureFingerprintGestures" value="0x00000200" />
</attr>
<!-- Component name of an activity that allows the user to modify
the settings for this service. This setting cannot be changed at runtime. -->
@@ -3440,6 +3442,14 @@
</p>
-->
<attr name="canPerformGestures" format="boolean" />
+ <!-- Attribute whether the accessibility service wants to be able to capture gestures from
+ the fingerprint sensor.
+ <p>
+ Required to allow setting the {@link android.accessibilityservice
+ #AccessibilityServiceInfo#FLAG_CAN_CAPTURE_FINGERPRINT_GESTURES} flag.
+ </p>
+ -->
+ <attr name="canCaptureFingerprintGestures" format="boolean" />
<!-- Short description of the accessibility service purpose or behavior.-->
<attr name="description" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 737dab0..d795d80 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2791,6 +2791,7 @@
<public name="colorMode" />
<public name="isolatedSplits" />
<public name="targetSandboxVersion" />
+ <public name="canCaptureFingerprintGestures" />
</public-group>
<public-group type="style" first-id="0x010302e0">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2ab0914..8b9b3b2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -681,6 +681,12 @@
<string name="capability_desc_canPerformGestures">Can tap, swipe, pinch, and perform other
gestures.</string>
+ <!-- Title for the capability of an accessibility service to capture fingerprint gestures. -->
+ <string name="capability_title_canCaptureFingerprintGestures">Fingerprint gestures</string>
+ <!-- Description for the capability of an accessibility service to perform gestures. -->
+ <string name="capability_desc_canCaptureFingerprintGestures">Can capture gestures performed on
+ the device's fingerprint sensor.</string>
+
<!-- Permissions -->
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 15011c8..b2e3728 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2836,4 +2836,8 @@
<java-symbol type="id" name="autofill_save_title" />
<java-symbol type="id" name="autofill_save_no" />
<java-symbol type="id" name="autofill_save_yes" />
+
+ <!-- Accessibility fingerprint gestures -->
+ <java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
+ <java-symbol type="string" name="capability_desc_canCaptureFingerprintGestures" />
</resources>
diff --git a/packages/SystemUI/res/layout-land/nav_bar_tuner.xml b/packages/SystemUI/res/layout-land/nav_bar_tuner.xml
deleted file mode 100644
index a430b73..0000000
--- a/packages/SystemUI/res/layout-land/nav_bar_tuner.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:elevation="4dp"
- android:paddingTop="12dp"
- android:paddingBottom="12dp"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- android:background="@android:color/white"
- android:gravity="center"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/preview"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- android:textColor="?android:attr/colorAccent"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
- <FrameLayout
- android:id="@+id/nav_preview_frame"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
- <android.support.v7.widget.RecyclerView
- android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp-land/nav_bar_tuner.xml b/packages/SystemUI/res/layout-sw600dp-land/nav_bar_tuner.xml
deleted file mode 100644
index 5479157..0000000
--- a/packages/SystemUI/res/layout-sw600dp-land/nav_bar_tuner.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:elevation="4dp"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:paddingStart="12dp"
- android:paddingEnd="12dp"
- android:layout_gravity="bottom"
- android:background="@android:color/white"
- android:gravity="center"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/preview"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:textColor="?android:attr/colorAccent"
- android:textAppearance="?android:attr/textAppearanceLarge" />
-
- <FrameLayout
- android:id="@+id/nav_preview_frame"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
- <android.support.v7.widget.RecyclerView
- android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/nav_bar_tuner.xml b/packages/SystemUI/res/layout/nav_bar_tuner.xml
deleted file mode 100644
index 5479157..0000000
--- a/packages/SystemUI/res/layout/nav_bar_tuner.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:elevation="4dp"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:paddingStart="12dp"
- android:paddingEnd="12dp"
- android:layout_gravity="bottom"
- android:background="@android:color/white"
- android:gravity="center"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/preview"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:textColor="?android:attr/colorAccent"
- android:textAppearance="?android:attr/textAppearanceLarge" />
-
- <FrameLayout
- android:id="@+id/nav_preview_frame"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
- <android.support.v7.widget.RecyclerView
- android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
-</LinearLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 018d888..e3149ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1599,8 +1599,11 @@
if (mHeadsUpManager.isHeadsUp(key)) {
// A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the
// sending look longer than it takes.
+ // Also we should not defer the removal if reordering isn't allowed since otherwise
+ // some notifications can't disappear before the panel is closed.
boolean ignoreEarliestRemovalTime = mRemoteInputController.isSpinning(key)
- && !FORCE_REMOTE_INPUT_HISTORY;
+ && !FORCE_REMOTE_INPUT_HISTORY
+ || !mVisualStabilityManager.isReorderingAllowed();
deferRemoval = !mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
}
if (key.equals(mMediaNotificationKey)) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/KeycodeSelectionHelper.java b/packages/SystemUI/src/com/android/systemui/tuner/KeycodeSelectionHelper.java
deleted file mode 100644
index 096ecc0..0000000
--- a/packages/SystemUI/src/com/android/systemui/tuner/KeycodeSelectionHelper.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.tuner;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.view.KeyEvent;
-
-import com.android.systemui.R;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-
-public class KeycodeSelectionHelper {
-
- private static final ArrayList<String> mKeycodeStrings = new ArrayList<>();
- private static final ArrayList<Integer> mKeycodes = new ArrayList<>();
-
- private static final String KEYCODE_STRING = "KEYCODE_";
-
- static {
- Class<KeyEvent> cls = KeyEvent.class;
- for (Field field : cls.getDeclaredFields()) {
- if (Modifier.isStatic(field.getModifiers())
- && field.getName().startsWith(KEYCODE_STRING)
- && field.getType().equals(int.class)) {
- try {
- mKeycodeStrings.add(formatString(field.getName()));
- mKeycodes.add((Integer) field.get(null));
- } catch (IllegalAccessException e) {
- }
- }
- }
- }
-
- // Force the string into something somewhat readable.
- private static String formatString(String name) {
- StringBuilder str = new StringBuilder(name.replace(KEYCODE_STRING, "").replace("_", " ")
- .toLowerCase());
- for (int i = 0; i < str.length(); i++) {
- if (i == 0 || str.charAt(i - 1) == ' ') {
- str.setCharAt(i, Character.toUpperCase(str.charAt(i)));
- }
- }
- return str.toString();
- }
-
- public static void showKeycodeSelect(Context context, final OnSelectionComplete listener) {
- new AlertDialog.Builder(context)
- .setTitle(R.string.select_keycode)
- .setItems(mKeycodeStrings.toArray(new String[0]),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- listener.onSelectionComplete(mKeycodes.get(which));
- }
- }).show();
- }
-
- public static Intent getSelectImageIntent() {
- return new Intent(Intent.ACTION_OPEN_DOCUMENT).addCategory(Intent.CATEGORY_OPENABLE)
- .setType("image/*");
- }
-
- public interface OnSelectionComplete {
- void onSelectionComplete(int code);
- }
-}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index ece5149..b68ac3b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -63,11 +63,13 @@
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.Settings;
+import android.hardware.fingerprint.IFingerprintService;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
import android.util.Slog;
@@ -203,6 +205,8 @@
private MotionEventInjector mMotionEventInjector;
+ private FingerprintGestureDispatcher mFingerprintGestureDispatcher;
+
private final Set<ComponentName> mTempComponentNameSet = new HashSet<>();
private final List<AccessibilityServiceInfo> mTempAccessibilityServiceInfoList =
@@ -1374,6 +1378,10 @@
mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_INPUT_FILTER, userState).sendToTarget();
}
+ private void scheduleUpdateFingerprintGestureHandling(UserState userState) {
+ mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_FINGERPRINT, userState).sendToTarget();
+ }
+
private void updateInputFilter(UserState userState) {
boolean setInputFilter = false;
AccessibilityInputFilter inputFilter = null;
@@ -1501,6 +1509,7 @@
updateDisplayInversionLocked(userState);
updateMagnificationLocked(userState);
updateSoftKeyboardShowModeLocked(userState);
+ scheduleUpdateFingerprintGestureHandling(userState);
scheduleUpdateInputFilter(userState);
scheduleUpdateClientsIfNeededLocked(userState);
}
@@ -1919,6 +1928,35 @@
}
}
+ private void updateFingerprintGestureHandling(UserState userState) {
+ final List<Service> services;
+ synchronized (mLock) {
+ // Only create the controller when a service wants to use the feature
+ services = userState.mBoundServices;
+ int numServices = services.size();
+ for (int i = 0; i < numServices; i++) {
+ if (services.get(i).isCapturingFingerprintGestures()) {
+ final long identity = Binder.clearCallingIdentity();
+ IFingerprintService service = null;
+ try {
+ service = IFingerprintService.Stub.asInterface(
+ ServiceManager.getService(Context.FINGERPRINT_SERVICE));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ if (service != null) {
+ mFingerprintGestureDispatcher = new FingerprintGestureDispatcher(
+ service, mLock);
+ break;
+ }
+ }
+ }
+ }
+ if (mFingerprintGestureDispatcher != null) {
+ mFingerprintGestureDispatcher.updateClientList(services);
+ }
+ }
+
private MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
IBinder windowToken = mGlobalWindowTokens.get(windowId);
if (windowToken == null) {
@@ -2001,6 +2039,27 @@
}
}
+ /**
+ * AIDL-exposed method. System only.
+ * Inform accessibility that a fingerprint gesture was performed
+ *
+ * @param gestureKeyCode The key code corresponding to the fingerprint gesture.
+ * @return {@code true} if accessibility consumes the fingerprint gesture, {@code false} if it
+ * doesn't.
+ */
+ @Override
+ public boolean sendFingerprintGesture(int gestureKeyCode) {
+ synchronized(mLock) {
+ if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
+ throw new SecurityException("Only SYSTEM can call sendFingerprintGesture");
+ }
+ }
+ if (mFingerprintGestureDispatcher == null) {
+ return false;
+ }
+ return mFingerprintGestureDispatcher.onFingerprintGesture(gestureKeyCode);
+ }
+
private class SettingsStringHelper {
private static final String SETTINGS_DELIMITER = ":";
private ContentResolver mContentResolver;
@@ -2131,6 +2190,7 @@
public static final int MSG_SEND_KEY_EVENT_TO_INPUT_FILTER = 8;
public static final int MSG_CLEAR_ACCESSIBILITY_FOCUS = 9;
public static final int MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS = 10;
+ public static final int MSG_UPDATE_FINGERPRINT = 11;
public MainHandler(Looper looper) {
super(looper);
@@ -2199,6 +2259,10 @@
case MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS: {
notifyClientsOfServicesStateChange();
} break;
+
+ case MSG_UPDATE_FINGERPRINT: {
+ updateFingerprintGestureHandling((UserState) msg.obj);
+ } break;
}
}
@@ -2329,7 +2393,8 @@
* connection for the service.
*/
class Service extends IAccessibilityServiceConnection.Stub
- implements ServiceConnection, DeathRecipient, KeyEventDispatcher.KeyEventFilter {;
+ implements ServiceConnection, DeathRecipient, KeyEventDispatcher.KeyEventFilter,
+ FingerprintGestureDispatcher.FingerprintGestureClient {
final int mUserId;
@@ -2359,6 +2424,8 @@
boolean mRetrieveInteractiveWindows;
+ boolean mCaptureFingerprintGestures;
+
int mFetchFlags;
long mNotificationTimeout;
@@ -2438,6 +2505,47 @@
return true;
}
+ @Override
+ public boolean isCapturingFingerprintGestures() {
+ return (mServiceInterface != null)
+ && mSecurityPolicy.canCaptureFingerprintGestures(this)
+ && mCaptureFingerprintGestures;
+ }
+
+ @Override
+ public void onFingerprintGestureDetectionActiveChanged(boolean active) {
+ if (!isCapturingFingerprintGestures()) {
+ return;
+ }
+ IAccessibilityServiceClient serviceInterface;
+ synchronized (mLock) {
+ serviceInterface = mServiceInterface;
+ }
+ if (serviceInterface != null) {
+ try {
+ mServiceInterface.onFingerprintCapturingGesturesChanged(active);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ @Override
+ public void onFingerprintGesture(int gesture) {
+ if (!isCapturingFingerprintGestures()) {
+ return;
+ }
+ IAccessibilityServiceClient serviceInterface;
+ synchronized (mLock) {
+ serviceInterface = mServiceInterface;
+ }
+ if (serviceInterface != null) {
+ try {
+ mServiceInterface.onFingerprintGesture(gesture);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
public void setDynamicallyConfigurableProperties(AccessibilityServiceInfo info) {
mEventTypes = info.eventTypes;
mFeedbackType = info.feedbackType;
@@ -2471,6 +2579,8 @@
& AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
mRetrieveInteractiveWindows = (info.flags
& AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0;
+ mCaptureFingerprintGestures = (info.flags
+ & AccessibilityServiceInfo.FLAG_CAPTURE_FINGERPRINT_GESTURES) != 0;
}
/**
@@ -3060,6 +3170,13 @@
}
@Override
+ public boolean isFingerprintGestureDetectionAvailable() {
+ return isCapturingFingerprintGestures()
+ && (mFingerprintGestureDispatcher != null)
+ && mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable();
+ }
+
+ @Override
public float getMagnificationScale() {
synchronized (mLock) {
if (!isCalledForCurrentUserLocked()) {
@@ -4234,6 +4351,11 @@
& AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES) != 0;
}
+ public boolean canCaptureFingerprintGestures(Service service) {
+ return (service.mAccessibilityServiceInfo.getCapabilities()
+ & AccessibilityServiceInfo.CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES) != 0;
+ }
+
private int resolveProfileParentLocked(int userId) {
if (userId != mCurrentUserId) {
final long identity = Binder.clearCallingIdentity();
diff --git a/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java b/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java
new file mode 100644
index 0000000..fe787b3
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility;
+
+import android.accessibilityservice.FingerprintGestureController;
+import android.hardware.fingerprint.IFingerprintClientActiveCallback;
+import android.hardware.fingerprint.IFingerprintService;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.KeyEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Encapsulate fingerprint gesture logic
+ */
+public class FingerprintGestureDispatcher extends IFingerprintClientActiveCallback.Stub
+ implements Handler.Callback{
+ private static final int MSG_REGISTER = 1;
+ private static final int MSG_UNREGISTER = 2;
+ private static final String LOG_TAG = "FingerprintGestureDispatcher";
+
+ private final List<FingerprintGestureClient> mCapturingClients = new ArrayList<>(0);
+ private final Object mLock;
+ private final IFingerprintService mFingerprintService;
+ private final Handler mHandler;
+
+ // This field is ground truth for whether or not we are registered. Only write to it in handler.
+ private boolean mRegisteredReadOnlyExceptInHandler;
+
+ /**
+ * @param fingerprintService The system's fingerprint service
+ * @param lock A lock to use when managing internal state
+ */
+ public FingerprintGestureDispatcher(IFingerprintService fingerprintService, Object lock) {
+ mFingerprintService = fingerprintService;
+ mLock = lock;
+ mHandler = new Handler(this);
+ }
+
+ /**
+ * @param fingerprintService The system's fingerprint service
+ * @param lock A lock to use when managing internal state
+ * @param handler A handler to use internally. Used for testing.
+ */
+ public FingerprintGestureDispatcher(IFingerprintService fingerprintService, Object lock,
+ Handler handler) {
+ mFingerprintService = fingerprintService;
+ mLock = lock;
+ mHandler = handler;
+ }
+
+ /**
+ * Update the list of clients that are interested in fingerprint gestures.
+ *
+ * @param clientList The list of potential clients.
+ */
+ public void updateClientList(List<? extends FingerprintGestureClient> clientList) {
+ synchronized (mLock) {
+ mCapturingClients.clear();
+ for (int i = 0; i < clientList.size(); i++) {
+ FingerprintGestureClient client = clientList.get(i);
+ if (client.isCapturingFingerprintGestures()) {
+ mCapturingClients.add(client);
+ }
+ }
+ if (mCapturingClients.isEmpty()) {
+ if (mRegisteredReadOnlyExceptInHandler) {
+ mHandler.obtainMessage(MSG_UNREGISTER).sendToTarget();
+ }
+ } else {
+ if(!mRegisteredReadOnlyExceptInHandler) {
+ mHandler.obtainMessage(MSG_REGISTER).sendToTarget();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onClientActiveChanged(boolean nonGestureFingerprintClientActive) {
+ synchronized (mLock) {
+ for (int i = 0; i < mCapturingClients.size(); i++) {
+ mCapturingClients.get(i).onFingerprintGestureDetectionActiveChanged(
+ !nonGestureFingerprintClientActive);
+ }
+ }
+ }
+
+ public boolean isFingerprintGestureDetectionAvailable() {
+ long identity = Binder.clearCallingIdentity();
+ try {
+ return !mFingerprintService.isClientActive();
+ } catch (RemoteException re) {
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Called when the fingerprint sensor detects a gesture
+ *
+ * @param fingerprintKeyCode
+ * @return {@code true} if the gesture is consumed. {@code false} otherwise.
+ */
+ public boolean onFingerprintGesture(int fingerprintKeyCode) {
+ int idForFingerprintGestureManager;
+
+ final List<FingerprintGestureClient> clientList;
+ synchronized (mLock) {
+ if (mCapturingClients.isEmpty()) {
+ return false;
+ }
+ switch (fingerprintKeyCode) {
+ case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP:
+ idForFingerprintGestureManager =
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_UP;
+ break;
+ case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN:
+ idForFingerprintGestureManager =
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_DOWN;
+ break;
+ case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT:
+ idForFingerprintGestureManager =
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_RIGHT;
+ break;
+ case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
+ idForFingerprintGestureManager =
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_LEFT;
+ break;
+ default:
+ return false;
+ }
+ clientList = new ArrayList<>(mCapturingClients);
+ }
+ for (int i = 0; i < clientList.size(); i++) {
+ clientList.get(i).onFingerprintGesture(idForFingerprintGestureManager);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean handleMessage(Message message) {
+ if (message.what == MSG_REGISTER) {
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mFingerprintService.addClientActiveCallback(this);
+ mRegisteredReadOnlyExceptInHandler = true;
+ } catch (RemoteException re) {
+ Slog.e(LOG_TAG, "Failed to register for fingerprint activity callbacks");
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return false;
+ } else if (message.what == MSG_UNREGISTER) {
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mFingerprintService.removeClientActiveCallback(this);
+ } catch (RemoteException re) {
+ Slog.e(LOG_TAG, "Failed to unregister for fingerprint activity callbacks");
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ mRegisteredReadOnlyExceptInHandler = false;
+ } else {
+ Slog.e(LOG_TAG, "Unknown message: " + message.what);
+ return false;
+ }
+ return true;
+ }
+
+ // Interface for potential clients.
+ public interface FingerprintGestureClient {
+ /**
+ * @return {@code true} if the client is capturing fingerprint gestures
+ */
+ boolean isCapturingFingerprintGestures();
+
+ /**
+ * Callback when gesture detection becomes active or inactive.
+ *
+ * @param active {@code true} when detection is active
+ */
+ void onFingerprintGestureDetectionActiveChanged(boolean active);
+
+ /**
+ * Callback when gesture is detected
+ *
+ * @param gesture The identifier for the gesture. For example,
+ * {@link FingerprintGestureController#FINGERPRINT_GESTURE_SWIPE_LEFT}
+ */
+ void onFingerprintGesture(int gesture);
+ }
+}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1f8702a..ebdd8e4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -78,7 +78,7 @@
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
-import android.net.util.AvoidBadWifiTracker;
+import android.net.util.MultinetworkPolicyTracker;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -499,7 +499,7 @@
private final IpConnectivityLog mMetricsLog;
@VisibleForTesting
- final AvoidBadWifiTracker mAvoidBadWifiTracker;
+ final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
/**
* Implements support for the legacy "one network per network type" model.
@@ -849,9 +849,9 @@
LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
- mAvoidBadWifiTracker = createAvoidBadWifiTracker(
+ mMultinetworkPolicyTracker = createMultinetworkPolicyTracker(
mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
- mAvoidBadWifiTracker.start();
+ mMultinetworkPolicyTracker.start();
}
private NetworkRequest createInternetRequestForTransport(
@@ -2784,7 +2784,7 @@
}
public boolean avoidBadWifi() {
- return mAvoidBadWifiTracker.currentValue();
+ return mMultinetworkPolicyTracker.getAvoidBadWifi();
}
private void rematchForAvoidBadWifiUpdate() {
@@ -2797,9 +2797,9 @@
}
// TODO: Evaluate whether this is of interest to other consumers of
- // AvoidBadWifiTracker and worth moving out of here.
+ // MultinetworkPolicyTracker and worth moving out of here.
private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
- final boolean configRestrict = mAvoidBadWifiTracker.configRestrictsAvoidBadWifi();
+ final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
if (!configRestrict) {
pw.println("Bad Wi-Fi avoidance: unrestricted");
return;
@@ -2809,7 +2809,7 @@
pw.increaseIndent();
pw.println("Config restrict: " + configRestrict);
- final String value = mAvoidBadWifiTracker.getSettingsValue();
+ final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
String description;
// Can't use a switch statement because strings are legal case labels, but null is not.
if ("0".equals(value)) {
@@ -2877,7 +2877,7 @@
if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc);
if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
- mAvoidBadWifiTracker.shouldNotifyWifiUnvalidated()) {
+ mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
showValidationNotification(nai, NotificationType.LOST_INTERNET);
}
}
@@ -5545,8 +5545,8 @@
}
@VisibleForTesting
- AvoidBadWifiTracker createAvoidBadWifiTracker(Context c, Handler h, Runnable r) {
- return new AvoidBadWifiTracker(c, h, r);
+ MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
+ return new MultinetworkPolicyTracker(c, h, r);
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index c4666dc..0292db9 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -2634,20 +2634,15 @@
if (!calledFromValidUser()) {
return;
}
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mMethodMap) {
- if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring clearLastInputMethodWindowForTransition due to an "
- + "invalid token. uid:" + uid + " token:" + token);
- return;
- }
+ synchronized (mMethodMap) {
+ if (!calledWithValidToken(token)) {
+ final int uid = Binder.getCallingUid();
+ Slog.e(TAG, "Ignoring clearLastInputMethodWindowForTransition due to an "
+ + "invalid token. uid:" + uid + " token:" + token);
+ return;
}
- mWindowManagerInternal.clearLastInputMethodWindowForTransition();
- } finally {
- Binder.restoreCallingIdentity(ident);
}
+ mWindowManagerInternal.clearLastInputMethodWindowForTransition();
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9ce7ae30..47109f2 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3584,6 +3584,7 @@
|| (prevState == ActivityState.PAUSED
&& (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID))
|| finishingActivityInNonFocusedStack
+ || prevState == ActivityState.STOPPING
|| prevState == ActivityState.STOPPED
|| prevState == ActivityState.INITIALIZING) {
r.makeFinishingLocked();
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index e2e0d6b..d1f7cfd 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -30,6 +30,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.hardware.fingerprint.IFingerprintClientActiveCallback;
import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
import android.os.Binder;
import android.os.Bundle;
@@ -82,6 +83,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* A service to manage multiple clients that want to access the fingerprint HAL API.
@@ -109,6 +111,8 @@
private final ArrayList<FingerprintServiceLockoutResetMonitor> mLockoutMonitors =
new ArrayList<>();
+ private final CopyOnWriteArrayList<IFingerprintClientActiveCallback> mClientActiveCallbacks =
+ new CopyOnWriteArrayList<>();
private final AppOpsManager mAppOps;
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
private static final int MAX_FAILED_ATTEMPTS = 5;
@@ -338,6 +342,9 @@
if (DEBUG) Slog.v(TAG, "Done with client: " + client.getOwnerString());
mCurrentClient = null;
}
+ if (mPendingClient == null) {
+ notifyClientActiveCallbacks(false);
+ }
}
private boolean inLockoutMode() {
@@ -407,6 +414,8 @@
+ newClient.getClass().getSuperclass().getSimpleName()
+ "(" + newClient.getOwnerString() + ")"
+ ", initiatedByClient = " + initiatedByClient + ")");
+ notifyClientActiveCallbacks(true);
+
newClient.start();
}
}
@@ -578,6 +587,18 @@
}
}
+ private void notifyClientActiveCallbacks(boolean isActive) {
+ List<IFingerprintClientActiveCallback> callbacks = mClientActiveCallbacks;
+ for (int i = 0; i < callbacks.size(); i++) {
+ try {
+ callbacks.get(i).onClientActiveChanged(isActive);
+ } catch (RemoteException re) {
+ // If the remote is dead, stop notifying it
+ mClientActiveCallbacks.remove(callbacks.get(i));
+ }
+ }
+ }
+
private void startAuthentication(IBinder token, long opId, int callingUserId, int groupId,
IFingerprintServiceReceiver receiver, int flags, boolean restricted,
String opPackageName) {
@@ -1047,6 +1068,26 @@
}
});
}
+
+ @Override
+ public boolean isClientActive() {
+ checkPermission(MANAGE_FINGERPRINT);
+ synchronized(FingerprintService.this) {
+ return (mCurrentClient != null) || (mPendingClient != null);
+ }
+ }
+
+ @Override
+ public void addClientActiveCallback(IFingerprintClientActiveCallback callback) {
+ checkPermission(MANAGE_FINGERPRINT);
+ mClientActiveCallbacks.add(callback);
+ }
+
+ @Override
+ public void removeClientActiveCallback(IFingerprintClientActiveCallback callback) {
+ checkPermission(MANAGE_FINGERPRINT);
+ mClientActiveCallbacks.remove(callback);
+ }
}
private void dumpInternal(PrintWriter pw) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d623051..37fff68 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6114,13 +6114,18 @@
* @param event
*/
private void interceptSystemNavigationKey(KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_UP && areSystemNavigationKeysEnabled()) {
- IStatusBarService sbar = getStatusBarService();
- if (sbar != null) {
- try {
- sbar.handleSystemNavigationKey(event.getKeyCode());
- } catch (RemoteException e1) {
- // oops, no statusbar. Ignore event.
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ if (!mAccessibilityManager.isEnabled()
+ || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) {
+ if (areSystemNavigationKeysEnabled()) {
+ IStatusBarService sbar = getStatusBarService();
+ if (sbar != null) {
+ try {
+ sbar.handleSystemNavigationKey(event.getKeyCode());
+ } catch (RemoteException e1) {
+ // oops, no statusbar. Ignore event.
+ }
+ }
}
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 70b0bf2..b911d2d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -55,6 +55,7 @@
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
import com.android.internal.policy.EmergencyAffordanceManager;
+import com.android.internal.util.ConcurrentUtils;
import com.android.internal.widget.ILockSettings;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.am.ActivityManagerService;
@@ -117,6 +118,7 @@
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -1580,11 +1582,19 @@
}
traceEnd();
+ // No dependency on Webview preparation in system server. But this should
+ // be completed before allowring 3rd party
+ final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";
+ Future<?> webviewPrep = null;
if (!mOnlyCore) {
- Slog.i(TAG, "WebViewFactory preparation");
- traceBeginAndSlog("WebViewFactoryPreparation");
- mWebViewUpdateService.prepareWebViewInSystemServer();
- traceEnd();
+ webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
+ Slog.i(TAG, WEBVIEW_PREPARATION);
+ BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
+ "SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER);
+ traceLog.traceBegin(WEBVIEW_PREPARATION);
+ mWebViewUpdateService.prepareWebViewInSystemServer();
+ traceLog.traceEnd();
+ }, WEBVIEW_PREPARATION);
}
traceBeginAndSlog("StartSystemUI");
@@ -1641,6 +1651,10 @@
Watchdog.getInstance().start();
traceEnd();
+ if (webviewPrep != null) {
+ ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
+ }
+
// It is now okay to let the various system services start their
// third party code...
traceBeginAndSlog("PhaseThirdPartyAppsCanStart");
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index abdf683..76b1c90 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -33,7 +33,7 @@
import android.net.dhcp.DhcpClient;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpManagerEvent;
-import android.net.util.AvoidBadWifiTracker;
+import android.net.util.MultinetworkPolicyTracker;
import android.os.INetworkManagementService;
import android.os.Message;
import android.os.RemoteException;
@@ -398,7 +398,7 @@
private final NetlinkTracker mNetlinkTracker;
private final WakeupMessage mProvisioningTimeoutAlarm;
private final WakeupMessage mDhcpActionTimeoutAlarm;
- private final AvoidBadWifiTracker mAvoidBadWifiTracker;
+ private final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
private final LocalLog mLocalLog;
private final LocalLog mConnectivityPacketLog;
private final MessageHandlingLogger mMsgStateLogger;
@@ -492,7 +492,7 @@
mLinkProperties = new LinkProperties();
mLinkProperties.setInterfaceName(mInterfaceName);
- mAvoidBadWifiTracker = new AvoidBadWifiTracker(mContext, getHandler(),
+ mMultinetworkPolicyTracker = new MultinetworkPolicyTracker(mContext, getHandler(),
() -> { mLocalLog.log("OBSERVED AvoidBadWifi changed"); });
mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
@@ -527,7 +527,7 @@
Log.e(mTag, "Couldn't register NetlinkTracker: " + e.toString());
}
- mAvoidBadWifiTracker.start();
+ mMultinetworkPolicyTracker.start();
}
@Override
@@ -538,7 +538,7 @@
// Shut down this IpManager instance altogether.
public void shutdown() {
stop();
- mAvoidBadWifiTracker.shutdown();
+ mMultinetworkPolicyTracker.shutdown();
quit();
}
@@ -767,7 +767,7 @@
// Note that we can still be disconnected by IpReachabilityMonitor
// if the IPv6 default gateway (but not the IPv6 DNS servers; see
// accompanying code in IpReachabilityMonitor) is unreachable.
- final boolean ignoreIPv6ProvisioningLoss = !mAvoidBadWifiTracker.currentValue();
+ final boolean ignoreIPv6ProvisioningLoss = !mMultinetworkPolicyTracker.getAvoidBadWifi();
// Additionally:
//
@@ -1045,7 +1045,7 @@
mCallback.onReachabilityLost(logMsg);
}
},
- mAvoidBadWifiTracker);
+ mMultinetworkPolicyTracker);
} catch (IllegalArgumentException iae) {
// Failed to start IpReachabilityMonitor. Log it and call
// onProvisioningFailure() immediately.
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index a883e28..20eac62 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -34,7 +34,7 @@
import android.net.netlink.StructNdaCacheInfo;
import android.net.netlink.StructNdMsg;
import android.net.netlink.StructNlMsgHdr;
-import android.net.util.AvoidBadWifiTracker;
+import android.net.util.MultinetworkPolicyTracker;
import android.os.PowerManager;
import android.os.SystemClock;
import android.system.ErrnoException;
@@ -151,7 +151,7 @@
private final String mInterfaceName;
private final int mInterfaceIndex;
private final Callback mCallback;
- private final AvoidBadWifiTracker mAvoidBadWifiTracker;
+ private final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
private final NetlinkSocketObserver mNetlinkSocketObserver;
private final Thread mObserverThread;
private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
@@ -226,7 +226,7 @@
}
public IpReachabilityMonitor(Context context, String ifName, Callback callback,
- AvoidBadWifiTracker tracker) throws IllegalArgumentException {
+ MultinetworkPolicyTracker tracker) throws IllegalArgumentException {
mInterfaceName = ifName;
int ifIndex = -1;
try {
@@ -238,7 +238,7 @@
mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, TAG + "." + mInterfaceName);
mCallback = callback;
- mAvoidBadWifiTracker = tracker;
+ mMultinetworkPolicyTracker = tracker;
mNetlinkSocketObserver = new NetlinkSocketObserver();
mObserverThread = new Thread(mNetlinkSocketObserver);
mObserverThread.start();
@@ -379,7 +379,7 @@
}
private boolean avoidingBadLinks() {
- return (mAvoidBadWifiTracker != null) ? mAvoidBadWifiTracker.currentValue() : true;
+ return (mMultinetworkPolicyTracker == null) || mMultinetworkPolicyTracker.getAvoidBadWifi();
}
public void probeAll() {
diff --git a/services/net/java/android/net/util/AvoidBadWifiTracker.java b/services/net/java/android/net/util/MultinetworkPolicyTracker.java
similarity index 78%
rename from services/net/java/android/net/util/AvoidBadWifiTracker.java
rename to services/net/java/android/net/util/MultinetworkPolicyTracker.java
index 2abaeb1..ebd131b 100644
--- a/services/net/java/android/net/util/AvoidBadWifiTracker.java
+++ b/services/net/java/android/net/util/MultinetworkPolicyTracker.java
@@ -42,8 +42,8 @@
* This enables the device to switch to another form of connectivity, like
* mobile, if it's available and working.
*
- * The Runnable |cb|, if given, is called on the supplied Handler's thread
- * whether the computed "avoid bad wifi" value changes.
+ * The Runnable |avoidBadWifiCallback|, if given, is posted to the supplied
+ * Handler' whenever the computed "avoid bad wifi" value changes.
*
* Disabling this reverts the device to a level of networking sophistication
* circa 2012-13 by disabling disparate code paths each of which contribute to
@@ -51,28 +51,30 @@
*
* @hide
*/
-public class AvoidBadWifiTracker {
- private static String TAG = AvoidBadWifiTracker.class.getSimpleName();
+public class MultinetworkPolicyTracker {
+ private static String TAG = MultinetworkPolicyTracker.class.getSimpleName();
private final Context mContext;
private final Handler mHandler;
private final Runnable mReevaluateRunnable;
- private final Uri mUri;
+ private final Uri mAvoidBadWifiUri;
private final ContentResolver mResolver;
private final SettingObserver mSettingObserver;
private final BroadcastReceiver mBroadcastReceiver;
private volatile boolean mAvoidBadWifi = true;
- public AvoidBadWifiTracker(Context ctx, Handler handler) {
+ public MultinetworkPolicyTracker(Context ctx, Handler handler) {
this(ctx, handler, null);
}
- public AvoidBadWifiTracker(Context ctx, Handler handler, Runnable cb) {
+ public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) {
mContext = ctx;
mHandler = handler;
- mReevaluateRunnable = () -> { if (update() && cb != null) cb.run(); };
- mUri = Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI);
+ mReevaluateRunnable = () -> {
+ if (updateAvoidBadWifi() && avoidBadWifiCallback != null) avoidBadWifiCallback.run();
+ };
+ mAvoidBadWifiUri = Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI);
mResolver = mContext.getContentResolver();
mSettingObserver = new SettingObserver();
mBroadcastReceiver = new BroadcastReceiver() {
@@ -82,11 +84,11 @@
}
};
- update();
+ updateAvoidBadWifi();
}
public void start() {
- mResolver.registerContentObserver(mUri, false, mSettingObserver);
+ mResolver.registerContentObserver(mAvoidBadWifiUri, false, mSettingObserver);
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
@@ -102,7 +104,7 @@
mContext.unregisterReceiver(mBroadcastReceiver);
}
- public boolean currentValue() {
+ public boolean getAvoidBadWifi() {
return mAvoidBadWifi;
}
@@ -117,10 +119,10 @@
* Whether we should display a notification when wifi becomes unvalidated.
*/
public boolean shouldNotifyWifiUnvalidated() {
- return configRestrictsAvoidBadWifi() && getSettingsValue() == null;
+ return configRestrictsAvoidBadWifi() && getAvoidBadWifiSetting() == null;
}
- public String getSettingsValue() {
+ public String getAvoidBadWifiSetting() {
return Settings.Global.getString(mResolver, NETWORK_AVOID_BAD_WIFI);
}
@@ -129,8 +131,8 @@
mHandler.post(mReevaluateRunnable);
}
- public boolean update() {
- final boolean settingAvoidBadWifi = "1".equals(getSettingsValue());
+ public boolean updateAvoidBadWifi() {
+ final boolean settingAvoidBadWifi = "1".equals(getAvoidBadWifiSetting());
final boolean prev = mAvoidBadWifi;
mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
return mAvoidBadWifi != prev;
@@ -148,7 +150,7 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
- if (!mUri.equals(uri)) return;
+ if (!mAvoidBadWifiUri.equals(uri)) return;
reevaluate();
}
}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index f89fd47..f30c466 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
@@ -345,6 +345,10 @@
um.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user);
// Disallow rebooting in safe mode - controlled by user 0
um.setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM);
+ if (mIsCarrierDemoMode) {
+ // Enable SMS in carrier demo mode.
+ um.setUserRestriction(UserManager.DISALLOW_SMS, false, user);
+ }
Settings.Secure.putIntForUser(mInjector.getContentResolver(),
Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureControllerTest.java
new file mode 100644
index 0000000..cf477f2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureControllerTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility;
+
+import android.accessibilityservice.FingerprintGestureController;
+import android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback;
+import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.os.Looper;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static android.accessibilityservice.FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_DOWN;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for FingerprintGestureController.
+ * TODO: These tests aren't really for server code, so this isn't their ideal home.
+ */
+public class FingerprintGestureControllerTest {
+ @Mock IAccessibilityServiceConnection mMockAccessibilityServiceConnection;
+ @Mock FingerprintGestureCallback mMockFingerprintGestureCallback;
+ FingerprintGestureController mFingerprintGestureController;
+
+ @BeforeClass
+ public static void oneTimeInitialization() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mFingerprintGestureController =
+ new FingerprintGestureController(mMockAccessibilityServiceConnection);
+ }
+
+ @Test
+ public void testIsGestureDetectionActive_returnsValueFromServer() throws Exception {
+ when(mMockAccessibilityServiceConnection.isFingerprintGestureDetectionAvailable())
+ .thenReturn(true);
+ assertTrue(mFingerprintGestureController.isGestureDetectionAvailable());
+ when(mMockAccessibilityServiceConnection.isFingerprintGestureDetectionAvailable())
+ .thenReturn(false);
+ assertFalse(mFingerprintGestureController.isGestureDetectionAvailable());
+ }
+
+ @Test
+ public void testCallbacks_withNoListeners_shouldNotCrash() {
+ mFingerprintGestureController.onGestureDetectionActiveChanged(true);
+ mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+ }
+
+ @Test
+ public void testDetectionActiveCallback_noHandler_shouldCallback() {
+ mFingerprintGestureController.registerFingerprintGestureCallback(
+ mMockFingerprintGestureCallback, null);
+ mFingerprintGestureController.onGestureDetectionActiveChanged(true);
+ verify(mMockFingerprintGestureCallback, times(1))
+ .onGestureDetectionAvailabilityChanged(true);
+ mFingerprintGestureController.onGestureDetectionActiveChanged(false);
+ verify(mMockFingerprintGestureCallback, times(1))
+ .onGestureDetectionAvailabilityChanged(false);
+
+ reset(mMockFingerprintGestureCallback);
+ mFingerprintGestureController.unregisterFingerprintGestureCallback(
+ mMockFingerprintGestureCallback);
+ mFingerprintGestureController.onGestureDetectionActiveChanged(true);
+ mFingerprintGestureController.onGestureDetectionActiveChanged(false);
+ verifyZeroInteractions(mMockFingerprintGestureCallback);
+ }
+
+ @Test
+ public void testDetectionActiveCallback_withHandler_shouldPostRunnableToHandler() {
+ MessageCapturingHandler messageCapturingHandler = new MessageCapturingHandler((message) -> {
+ message.getCallback().run();
+ return true;
+ });
+
+ mFingerprintGestureController.registerFingerprintGestureCallback(
+ mMockFingerprintGestureCallback, messageCapturingHandler);
+ mFingerprintGestureController.onGestureDetectionActiveChanged(true);
+ verify(mMockFingerprintGestureCallback, times(0))
+ .onGestureDetectionAvailabilityChanged(true);
+ messageCapturingHandler.sendLastMessage();
+ verify(mMockFingerprintGestureCallback, times(1))
+ .onGestureDetectionAvailabilityChanged(true);
+
+ mFingerprintGestureController.onGestureDetectionActiveChanged(false);
+ verify(mMockFingerprintGestureCallback, times(0))
+ .onGestureDetectionAvailabilityChanged(false);
+ messageCapturingHandler.sendLastMessage();
+ verify(mMockFingerprintGestureCallback, times(1))
+ .onGestureDetectionAvailabilityChanged(false);
+
+ reset(mMockFingerprintGestureCallback);
+ mFingerprintGestureController.unregisterFingerprintGestureCallback(
+ mMockFingerprintGestureCallback);
+ mFingerprintGestureController.onGestureDetectionActiveChanged(true);
+ mFingerprintGestureController.onGestureDetectionActiveChanged(false);
+ assertFalse(messageCapturingHandler.hasMessages());
+ verifyZeroInteractions(mMockFingerprintGestureCallback);
+ }
+
+ @Test
+ public void testGestureCallback_noHandler_shouldCallListener() {
+ mFingerprintGestureController.registerFingerprintGestureCallback(
+ mMockFingerprintGestureCallback, null);
+ mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+ verify(mMockFingerprintGestureCallback, times(1)).onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+
+ reset(mMockFingerprintGestureCallback);
+ mFingerprintGestureController.unregisterFingerprintGestureCallback(
+ mMockFingerprintGestureCallback);
+ mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+ verifyZeroInteractions(mMockFingerprintGestureCallback);
+ }
+
+ @Test
+ public void testGestureCallback_withHandler_shouldPostRunnableToHandler() {
+ MessageCapturingHandler messageCapturingHandler = new MessageCapturingHandler((message) -> {
+ message.getCallback().run();
+ return true;
+ });
+
+ mFingerprintGestureController.registerFingerprintGestureCallback(
+ mMockFingerprintGestureCallback, messageCapturingHandler);
+ mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+ verify(mMockFingerprintGestureCallback, times(0)).onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+ messageCapturingHandler.sendLastMessage();
+ verify(mMockFingerprintGestureCallback, times(1)).onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+
+ reset(mMockFingerprintGestureCallback);
+ mFingerprintGestureController.unregisterFingerprintGestureCallback(
+ mMockFingerprintGestureCallback);
+ mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
+ assertFalse(messageCapturingHandler.hasMessages());
+ verifyZeroInteractions(mMockFingerprintGestureCallback);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureDispatcherTest.java b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureDispatcherTest.java
new file mode 100644
index 0000000..98bf53c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureDispatcherTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility;
+
+import android.accessibilityservice.FingerprintGestureController;
+import android.hardware.fingerprint.IFingerprintService;
+import android.os.Handler;
+import android.os.Message;
+import android.view.KeyEvent;
+
+import com.android.server.accessibility.FingerprintGestureDispatcher.FingerprintGestureClient;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for FingerprintGestureDispatcher
+ */
+public class FingerprintGestureDispatcherTest {
+
+ private @Mock IFingerprintService mMockFingerprintService;
+ private @Mock FingerprintGestureClient mNonGestureCapturingClient;
+ private @Mock FingerprintGestureClient mGestureCapturingClient;
+ private @Mock FingerprintGestureDispatcher mFingerprintGestureDispatcher;
+ private MessageCapturingHandler mMessageCapturingHandler;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mMessageCapturingHandler = new MessageCapturingHandler(
+ msg -> mFingerprintGestureDispatcher.handleMessage(msg));
+ mFingerprintGestureDispatcher = new FingerprintGestureDispatcher(mMockFingerprintService,
+ new Object(), mMessageCapturingHandler);
+ when(mNonGestureCapturingClient.isCapturingFingerprintGestures()).thenReturn(false);
+ when(mGestureCapturingClient.isCapturingFingerprintGestures()).thenReturn(true);
+ }
+
+ @Test
+ public void testNoServices_doesNotCrashOrConsumeGestures() {
+ mFingerprintGestureDispatcher.onClientActiveChanged(true);
+ mFingerprintGestureDispatcher.onClientActiveChanged(false);
+ assertFalse(mFingerprintGestureDispatcher.onFingerprintGesture(
+ KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP));
+ }
+
+ @Test
+ public void testOneNonCapturingService_doesNotCrashOrConsumeGestures() {
+ mFingerprintGestureDispatcher.updateClientList(
+ Arrays.asList(mNonGestureCapturingClient));
+ mFingerprintGestureDispatcher.onClientActiveChanged(true);
+ mFingerprintGestureDispatcher.onClientActiveChanged(false);
+ assertFalse(mFingerprintGestureDispatcher.onFingerprintGesture(
+ KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP));
+ verify(mNonGestureCapturingClient, times(0))
+ .onFingerprintGestureDetectionActiveChanged(anyBoolean());
+ verify(mNonGestureCapturingClient, times(0)).onFingerprintGesture(anyInt());
+ }
+
+ @Test
+ public void testOneCapturingService_notifiesClientOfActivityChanges() {
+ mFingerprintGestureDispatcher.updateClientList(
+ Arrays.asList(mGestureCapturingClient));
+ mFingerprintGestureDispatcher.onClientActiveChanged(true);
+ // Client active means gesture detection isn't.
+ verify(mGestureCapturingClient, times(1)).onFingerprintGestureDetectionActiveChanged(false);
+ verify(mGestureCapturingClient, times(0)).onFingerprintGestureDetectionActiveChanged(true);
+ mFingerprintGestureDispatcher.onClientActiveChanged(false);
+ verify(mGestureCapturingClient, times(1)).onFingerprintGestureDetectionActiveChanged(false);
+ verify(mGestureCapturingClient, times(1)).onFingerprintGestureDetectionActiveChanged(true);
+ }
+
+ @Test
+ public void testOneCapturingService_consumesGesturesAndPassesThemAlong() {
+ mFingerprintGestureDispatcher.updateClientList(
+ Arrays.asList(mGestureCapturingClient));
+ assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture(
+ KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP));
+ verify(mGestureCapturingClient, times(1)).onFingerprintGesture(
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_UP);
+ assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture(
+ KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN));
+ verify(mGestureCapturingClient, times(1)).onFingerprintGesture(
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_DOWN);
+ assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture(
+ KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT));
+ verify(mGestureCapturingClient, times(1)).onFingerprintGesture(
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_LEFT);
+ assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture(
+ KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT));
+ verify(mGestureCapturingClient, times(1)).onFingerprintGesture(
+ FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_RIGHT);
+ }
+
+ @Test
+ public void testInvalidKeyCodes_areNotCaptured() {
+ mFingerprintGestureDispatcher.updateClientList(
+ Arrays.asList(mGestureCapturingClient));
+ assertFalse(mFingerprintGestureDispatcher.onFingerprintGesture(
+ KeyEvent.KEYCODE_SPACE));
+ verify(mGestureCapturingClient, times(0)).onFingerprintGesture(anyInt());
+ }
+
+ @Test
+ public void testWithCapturingService_registersForFingerprintUpdates() throws Exception {
+ verifyNoMoreInteractions(mMockFingerprintService);
+ mFingerprintGestureDispatcher.updateClientList(
+ Arrays.asList(mGestureCapturingClient));
+ mMessageCapturingHandler.sendOneMessage();
+ verify(mMockFingerprintService).addClientActiveCallback(mFingerprintGestureDispatcher);
+ }
+
+ @Test
+ public void testWhenCapturingServiceStops_unregistersForFingerprintUpdates() throws Exception {
+ verifyNoMoreInteractions(mMockFingerprintService);
+ mFingerprintGestureDispatcher.updateClientList(
+ Arrays.asList(mGestureCapturingClient));
+ mMessageCapturingHandler.sendOneMessage();
+ mFingerprintGestureDispatcher.updateClientList(Collections.emptyList());
+ mMessageCapturingHandler.sendOneMessage();
+ verify(mMockFingerprintService).removeClientActiveCallback(mFingerprintGestureDispatcher);
+ }
+
+ @Test
+ public void testIsGestureDetectionActive_dependsOnFingerprintService() throws Exception {
+ when(mMockFingerprintService.isClientActive()).thenReturn(true);
+ assertFalse(mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable());
+ when(mMockFingerprintService.isClientActive()).thenReturn(false);
+ assertTrue(mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable());
+ }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 2d7a68f..39406a11 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -53,7 +53,7 @@
import android.net.NetworkRequest;
import android.net.RouteInfo;
import android.net.metrics.IpConnectivityLog;
-import android.net.util.AvoidBadWifiTracker;
+import android.net.util.MultinetworkPolicyTracker;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
@@ -155,25 +155,13 @@
/**
* Block until the given handler becomes idle, or until timeoutMs has passed.
*/
- private static void waitForIdleHandler(HandlerThread handler, int timeoutMs) {
+ private static void waitForIdleHandler(HandlerThread handlerThread, int timeoutMs) {
final ConditionVariable cv = new ConditionVariable();
- final MessageQueue queue = handler.getLooper().getQueue();
- final IdleHandler idleHandler = () -> {
- synchronized (queue) {
- cv.open();
- return false; // Remove the idleHandler.
- }
- };
- synchronized (queue) {
- if (queue.isIdle()) {
- return;
- }
- queue.addIdleHandler(idleHandler);
- }
+ final Handler handler = new Handler(handlerThread.getLooper());
+ handler.post(() -> cv.open());
if (!cv.block(timeoutMs)) {
- fail("HandlerThread " + handler.getName() +
+ fail("HandlerThread " + handlerThread.getName() +
" did not become idle after " + timeoutMs + " ms");
- queue.removeIdleHandler(idleHandler);
}
}
@@ -605,10 +593,10 @@
}
}
- private class WrappedAvoidBadWifiTracker extends AvoidBadWifiTracker {
+ private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker {
public volatile boolean configRestrictsAvoidBadWifi;
- public WrappedAvoidBadWifiTracker(Context c, Handler h, Runnable r) {
+ public WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
super(c, h, r);
}
@@ -619,7 +607,7 @@
}
private class WrappedConnectivityService extends ConnectivityService {
- public WrappedAvoidBadWifiTracker wrappedAvoidBadWifiTracker;
+ public WrappedMultinetworkPolicyTracker wrappedMultinetworkPolicyTracker;
private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
public WrappedConnectivityService(Context context, INetworkManagementService netManager,
@@ -666,14 +654,14 @@
}
@Override
- public AvoidBadWifiTracker createAvoidBadWifiTracker(
+ public MultinetworkPolicyTracker createMultinetworkPolicyTracker(
Context c, Handler h, Runnable r) {
- final WrappedAvoidBadWifiTracker tracker = new WrappedAvoidBadWifiTracker(c, h, r);
+ final WrappedMultinetworkPolicyTracker tracker = new WrappedMultinetworkPolicyTracker(c, h, r);
return tracker;
}
- public WrappedAvoidBadWifiTracker getAvoidBadWifiTracker() {
- return (WrappedAvoidBadWifiTracker) mAvoidBadWifiTracker;
+ public WrappedMultinetworkPolicyTracker getMultinetworkPolicyTracker() {
+ return (WrappedMultinetworkPolicyTracker) mMultinetworkPolicyTracker;
}
@Override
@@ -695,22 +683,6 @@
}
}
- private interface Criteria {
- public boolean get();
- }
-
- /**
- * Wait up to 500ms for {@code criteria.get()} to become true, polling.
- * Fails if 500ms goes by before {@code criteria.get()} to become true.
- */
- static private void waitFor(Criteria criteria) {
- int delays = 0;
- while (!criteria.get()) {
- sleepFor(50);
- if (++delays == 10) fail();
- }
- }
-
/**
* Wait up to TIMEOUT_MS for {@code conditionVariable} to open.
* Fails if TIMEOUT_MS goes by before {@code conditionVariable} opens.
@@ -846,8 +818,9 @@
assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) ||
mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork()));
// Test cellular linger timeout.
- waitFor(new Criteria() {
- public boolean get() { return mCm.getAllNetworks().length == 1; } });
+ waitFor(mCellNetworkAgent.getDisconnectedCV());
+ mService.waitForIdle();
+ assertEquals(1, mCm.getAllNetworks().length);
verifyActiveNetwork(TRANSPORT_WIFI);
assertEquals(1, mCm.getAllNetworks().length);
assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork());
@@ -1622,8 +1595,8 @@
ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV();
mCellNetworkAgent.connectWithoutInternet();
waitFor(cv);
- waitFor(new Criteria() {
- public boolean get() { return mCm.getAllNetworks().length == 0; } });
+ mService.waitForIdle();
+ assertEquals(0, mCm.getAllNetworks().length);
verifyNoNetwork();
// Test bringing up validated WiFi.
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1982,7 +1955,6 @@
// Disconnect wifi and check that cell is foreground again.
mWiFiNetworkAgent.disconnect();
- mService.waitForIdle();
callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
fgCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
@@ -2152,7 +2124,7 @@
@SmallTest
public void testAvoidBadWifiSetting() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
- final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
+ final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
tracker.configRestrictsAvoidBadWifi = false;
@@ -2162,7 +2134,7 @@
tracker.reevaluate();
mService.waitForIdle();
String msg = String.format("config=false, setting=%s", values[i]);
- assertEventuallyTrue(() -> mService.avoidBadWifi(), 50);
+ assertTrue(mService.avoidBadWifi());
assertFalse(msg, tracker.shouldNotifyWifiUnvalidated());
}
@@ -2171,26 +2143,26 @@
Settings.Global.putInt(cr, settingName, 0);
tracker.reevaluate();
mService.waitForIdle();
- assertEventuallyTrue(() -> !mService.avoidBadWifi(), 50);
+ assertFalse(mService.avoidBadWifi());
assertFalse(tracker.shouldNotifyWifiUnvalidated());
Settings.Global.putInt(cr, settingName, 1);
tracker.reevaluate();
mService.waitForIdle();
- assertEventuallyTrue(() -> mService.avoidBadWifi(), 50);
+ assertTrue(mService.avoidBadWifi());
assertFalse(tracker.shouldNotifyWifiUnvalidated());
Settings.Global.putString(cr, settingName, null);
tracker.reevaluate();
mService.waitForIdle();
- assertEventuallyTrue(() -> !mService.avoidBadWifi(), 50);
+ assertFalse(mService.avoidBadWifi());
assertTrue(tracker.shouldNotifyWifiUnvalidated());
}
@SmallTest
public void testAvoidBadWifi() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
- final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
+ final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
// Pretend we're on a carrier that restricts switching away from bad wifi.
tracker.configRestrictsAvoidBadWifi = true;
@@ -2404,17 +2376,6 @@
networkCallback.assertNoCallback();
}
- public void assertEventuallyTrue(BooleanSupplier fn, long maxWaitingTimeMs) {
- long start = SystemClock.elapsedRealtime();
- while (SystemClock.elapsedRealtime() <= start + maxWaitingTimeMs) {
- if (fn.getAsBoolean()) {
- return;
- }
- sleepFor(15);
- }
- assertTrue(fn.getAsBoolean());
- }
-
private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
@@ -2575,12 +2536,13 @@
ka = mCm.startNattKeepalive(myNet, 25, callback, myIPv4, 12345, dstIPv4);
callback.expectStarted();
mWiFiNetworkAgent.disconnect();
+ waitFor(mWiFiNetworkAgent.getDisconnectedCV());
callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK);
// ... and that stopping it after that has no adverse effects.
- // TODO: investigate assertEventuallyTrue is needed and waitForIdle() is not enough
+ mService.waitForIdle();
final Network myNetAlias = myNet;
- assertEventuallyTrue(() -> mCm.getNetworkCapabilities(myNetAlias) == null, 100);
+ assertNull(mCm.getNetworkCapabilities(myNetAlias));
ka.stop();
// Reconnect.
@@ -2592,6 +2554,7 @@
callback.expectStarted();
ka.stop();
mWiFiNetworkAgent.disconnect();
+ waitFor(mWiFiNetworkAgent.getDisconnectedCV());
mService.waitForIdle();
callback.expectStopped();
diff --git a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
index 36e4717..04dea1b 100755
--- a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
+++ b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java
@@ -19,16 +19,16 @@
import android.Manifest.permission;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.content.Context;
-import android.os.Handler;
import android.net.INetworkScoreCache;
import android.net.NetworkKey;
import android.net.ScoredNetwork;
+import android.os.Handler;
+import android.os.Process;
import android.util.Log;
-import com.android.internal.util.Preconditions;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -76,7 +76,7 @@
public WifiNetworkScoreCache(Context context, @Nullable CacheListener listener) {
mContext = context.getApplicationContext();
mListener = listener;
- mNetworkCache = new HashMap<String, ScoredNetwork>();
+ mNetworkCache = new HashMap<>();
}
@Override public final void updateScores(List<ScoredNetwork> networks) {
@@ -244,7 +244,9 @@
@Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
- writer.println("WifiNetworkScoreCache");
+ String header = String.format("WifiNetworkScoreCache (%s/%d)",
+ mContext.getPackageName(), Process.myUid());
+ writer.println(header);
writer.println(" All score curves:");
for (ScoredNetwork score : mNetworkCache.values()) {
writer.println(" " + score);
diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java b/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java
index 96db5d0..78b335d 100644
--- a/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java
+++ b/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java
@@ -175,7 +175,7 @@
}
// Credential is needed for storing the certificates and private client key.
- if (config.credential == null) {
+ if (config.getCredential() == null) {
throw new IOException("Passpoint profile missing credential");
}
@@ -183,7 +183,7 @@
byte[] caCertData = mimeParts.get(TYPE_CA_CERT);
if (caCertData != null) {
try {
- config.credential.caCertificate = parseCACert(caCertData);
+ config.getCredential().setCaCertificate(parseCACert(caCertData));
} catch (CertificateException e) {
throw new IOException("Failed to parse CA Certificate");
}
@@ -194,9 +194,9 @@
if (pkcs12Data != null) {
try {
Pair<PrivateKey, List<X509Certificate>> clientKey = parsePkcs12(pkcs12Data);
- config.credential.clientPrivateKey = clientKey.first;
- config.credential.clientCertificateChain =
- clientKey.second.toArray(new X509Certificate[clientKey.second.size()]);
+ config.getCredential().setClientPrivateKey(clientKey.first);
+ config.getCredential().setClientCertificateChain(
+ clientKey.second.toArray(new X509Certificate[clientKey.second.size()]));
} catch(GeneralSecurityException | IOException e) {
throw new IOException("Failed to parse PCKS12 string");
}
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index f1174b6..c2b307d 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -30,6 +30,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
/**
* Class representing Passpoint configuration. This contains configurations specified in
@@ -58,21 +59,58 @@
*/
private static final int NULL_VALUE = -1;
- public HomeSP homeSp = null;
- public Credential credential = null;
- public Policy policy = null;
+ /**
+ * Configurations under HomeSP subtree.
+ */
+ private HomeSP mHomeSp = null;
+ public void setHomeSp(HomeSP homeSp) { mHomeSp = homeSp; }
+ public HomeSP getHomeSp() { return mHomeSp; }
+
+ /**
+ * Configurations under Credential subtree.
+ */
+ private Credential mCredential = null;
+ public void setCredential(Credential credential) {
+ mCredential = credential;
+ }
+ public Credential getCredential() {
+ return mCredential;
+ }
+
+ /**
+ * Configurations under Policy subtree.
+ */
+ private Policy mPolicy = null;
+ public void setPolicy(Policy policy) {
+ mPolicy = policy;
+ }
+ public Policy getPolicy() {
+ return mPolicy;
+ }
/**
* Meta data for performing subscription update.
*/
- public UpdateParameter subscriptionUpdate = null;
+ private UpdateParameter mSubscriptionUpdate = null;
+ public void setSubscriptionUpdate(UpdateParameter subscriptionUpdate) {
+ mSubscriptionUpdate = subscriptionUpdate;
+ }
+ public UpdateParameter getSubscriptionUpdate() {
+ return mSubscriptionUpdate;
+ }
/**
* List of HTTPS URL for retrieving trust root certificate and the corresponding SHA-256
* fingerprint of the certificate. The certificates are used for verifying AAA server's
* identity during EAP authentication.
*/
- public Map<String, byte[]> trustRootCertList = null;
+ private Map<String, byte[]> mTrustRootCertList = null;
+ public void setTrustRootCertList(Map<String, byte[]> trustRootCertList) {
+ mTrustRootCertList = trustRootCertList;
+ }
+ public Map<String, byte[]> getTrustRootCertList() {
+ return mTrustRootCertList;
+ }
/**
* Set by the subscription server, updated every time the configuration is updated by
@@ -80,14 +118,26 @@
*
* Use Integer.MIN_VALUE to indicate unset value.
*/
- public int updateIdentifier = Integer.MIN_VALUE;
+ private int mUpdateIdentifier = Integer.MIN_VALUE;
+ public void setUpdateIdentifier(int updateIdentifier) {
+ mUpdateIdentifier = updateIdentifier;
+ }
+ public int getUpdateIdentififer() {
+ return mUpdateIdentifier;
+ }
/**
* The priority of the credential.
*
* Use Integer.MIN_VALUE to indicate unset value.
*/
- public int credentialPriority = Integer.MIN_VALUE;
+ private int mCredentialPriority = Integer.MIN_VALUE;
+ public void setCredentialPriority(int credentialPriority) {
+ mCredentialPriority = credentialPriority;
+ }
+ public int getCredentialPriority() {
+ return mCredentialPriority;
+ }
/**
* The time this subscription is created. It is in the format of number
@@ -95,7 +145,13 @@
*
* Use Long.MIN_VALUE to indicate unset value.
*/
- public long subscriptionCreationTimeInMs = Long.MIN_VALUE;
+ private long mSubscriptionCreationTimeInMs = Long.MIN_VALUE;
+ public void setSubscriptionCreationTimeInMs(long subscriptionCreationTimeInMs) {
+ mSubscriptionCreationTimeInMs = subscriptionCreationTimeInMs;
+ }
+ public long getSubscriptionCreationTimeInMs() {
+ return mSubscriptionCreationTimeInMs;
+ }
/**
* The time this subscription will expire. It is in the format of number
@@ -103,20 +159,38 @@
*
* Use Long.MIN_VALUE to indicate unset value.
*/
- public long subscriptionExpirationTimeInMs = Long.MIN_VALUE;
+ private long mSubscriptionExpirationTimeInMs = Long.MIN_VALUE;
+ public void setSubscriptionExpirationTimeInMs(long subscriptionExpirationTimeInMs) {
+ mSubscriptionExpirationTimeInMs = subscriptionExpirationTimeInMs;
+ }
+ public long getSubscriptionExpirationTimeInMs() {
+ return mSubscriptionExpirationTimeInMs;
+ }
/**
* The type of the subscription. This is defined by the provider and the value is provider
* specific.
*/
- public String subscriptionType = null;
+ private String mSubscriptionType = null;
+ public void setSubscriptionType(String subscriptionType) {
+ mSubscriptionType = subscriptionType;
+ }
+ public String getSubscriptionType() {
+ return mSubscriptionType;
+ }
/**
* The time period for usage statistics accumulation. A value of zero means that usage
* statistics are not accumulated on a periodic basis (e.g., a one-time limit for
* “pay as you go” - PAYG service). A non-zero value specifies the usage interval in minutes.
*/
- public long usageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE;
+ private long mUsageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE;
+ public void setUsageLimitUsageTimePeriodInMinutes(long usageLimitUsageTimePeriodInMinutes) {
+ mUsageLimitUsageTimePeriodInMinutes = usageLimitUsageTimePeriodInMinutes;
+ }
+ public long getUsageLimitUsageTimePeriodInMinutes() {
+ return mUsageLimitUsageTimePeriodInMinutes;
+ }
/**
* The time at which usage statistic accumulation begins. It is in the format of number
@@ -124,7 +198,13 @@
*
* Use Long.MIN_VALUE to indicate unset value.
*/
- public long usageLimitStartTimeInMs = Long.MIN_VALUE;
+ private long mUsageLimitStartTimeInMs = Long.MIN_VALUE;
+ public void setUsageLimitStartTimeInMs(long usageLimitStartTimeInMs) {
+ mUsageLimitStartTimeInMs = usageLimitStartTimeInMs;
+ }
+ public long getUsageLimitStartTimeInMs() {
+ return mUsageLimitStartTimeInMs;
+ }
/**
* The cumulative data limit in megabytes for the {@link #usageLimitUsageTimePeriodInMinutes}.
@@ -132,14 +212,25 @@
*
* Use Long.MIN_VALUE to indicate unset value.
*/
- public long usageLimitDataLimit = Long.MIN_VALUE;
+ private long mUsageLimitDataLimit = Long.MIN_VALUE;
+ public void setUsageLimitDataLimit(long usageLimitDataLimit) {
+ mUsageLimitDataLimit = usageLimitDataLimit;
+ }
+ public long getUsageLimitDataLimit() {
+ return mUsageLimitDataLimit;
+ }
/**
* The cumulative time limit in minutes for the {@link #usageLimitUsageTimePeriodInMinutes}.
* A value of zero indicate unlimited time usage.
*/
- public long usageLimitTimeLimitInMinutes = Long.MIN_VALUE;
-
+ private long mUsageLimitTimeLimitInMinutes = Long.MIN_VALUE;
+ public void setUsageLimitTimeLimitInMinutes(long usageLimitTimeLimitInMinutes) {
+ mUsageLimitTimeLimitInMinutes = usageLimitTimeLimitInMinutes;
+ }
+ public long getUsageLimitTimeLimitInMinutes() {
+ return mUsageLimitTimeLimitInMinutes;
+ }
/**
* Constructor for creating PasspointConfiguration with default values.
@@ -156,30 +247,30 @@
return;
}
- if (source.homeSp != null) {
- homeSp = new HomeSP(source.homeSp);
+ if (source.mHomeSp != null) {
+ mHomeSp = new HomeSP(source.mHomeSp);
}
- if (source.credential != null) {
- credential = new Credential(source.credential);
+ if (source.mCredential != null) {
+ mCredential = new Credential(source.mCredential);
}
- if (source.policy != null) {
- policy = new Policy(source.policy);
+ if (source.mPolicy != null) {
+ mPolicy = new Policy(source.mPolicy);
}
- if (source.trustRootCertList != null) {
- trustRootCertList = Collections.unmodifiableMap(source.trustRootCertList);
+ if (source.mTrustRootCertList != null) {
+ mTrustRootCertList = Collections.unmodifiableMap(source.mTrustRootCertList);
}
- if (source.subscriptionUpdate != null) {
- subscriptionUpdate = new UpdateParameter(source.subscriptionUpdate);
+ if (source.mSubscriptionUpdate != null) {
+ mSubscriptionUpdate = new UpdateParameter(source.mSubscriptionUpdate);
}
- updateIdentifier = source.updateIdentifier;
- credentialPriority = source.credentialPriority;
- subscriptionCreationTimeInMs = source.subscriptionCreationTimeInMs;
- subscriptionExpirationTimeInMs = source.subscriptionExpirationTimeInMs;
- subscriptionType = source.subscriptionType;
- usageLimitDataLimit = source.usageLimitDataLimit;
- usageLimitStartTimeInMs = source.usageLimitStartTimeInMs;
- usageLimitTimeLimitInMinutes = source.usageLimitTimeLimitInMinutes;
- usageLimitUsageTimePeriodInMinutes = source.usageLimitUsageTimePeriodInMinutes;
+ mUpdateIdentifier = source.mUpdateIdentifier;
+ mCredentialPriority = source.mCredentialPriority;
+ mSubscriptionCreationTimeInMs = source.mSubscriptionCreationTimeInMs;
+ mSubscriptionExpirationTimeInMs = source.mSubscriptionExpirationTimeInMs;
+ mSubscriptionType = source.mSubscriptionType;
+ mUsageLimitDataLimit = source.mUsageLimitDataLimit;
+ mUsageLimitStartTimeInMs = source.mUsageLimitStartTimeInMs;
+ mUsageLimitTimeLimitInMinutes = source.mUsageLimitTimeLimitInMinutes;
+ mUsageLimitUsageTimePeriodInMinutes = source.mUsageLimitUsageTimePeriodInMinutes;
}
@Override
@@ -189,20 +280,20 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(homeSp, flags);
- dest.writeParcelable(credential, flags);
- dest.writeParcelable(policy, flags);
- dest.writeParcelable(subscriptionUpdate, flags);
- writeTrustRootCerts(dest, trustRootCertList);
- dest.writeInt(updateIdentifier);
- dest.writeInt(credentialPriority);
- dest.writeLong(subscriptionCreationTimeInMs);
- dest.writeLong(subscriptionExpirationTimeInMs);
- dest.writeString(subscriptionType);
- dest.writeLong(usageLimitUsageTimePeriodInMinutes);
- dest.writeLong(usageLimitStartTimeInMs);
- dest.writeLong(usageLimitDataLimit);
- dest.writeLong(usageLimitTimeLimitInMinutes);
+ dest.writeParcelable(mHomeSp, flags);
+ dest.writeParcelable(mCredential, flags);
+ dest.writeParcelable(mPolicy, flags);
+ dest.writeParcelable(mSubscriptionUpdate, flags);
+ writeTrustRootCerts(dest, mTrustRootCertList);
+ dest.writeInt(mUpdateIdentifier);
+ dest.writeInt(mCredentialPriority);
+ dest.writeLong(mSubscriptionCreationTimeInMs);
+ dest.writeLong(mSubscriptionExpirationTimeInMs);
+ dest.writeString(mSubscriptionType);
+ dest.writeLong(mUsageLimitUsageTimePeriodInMinutes);
+ dest.writeLong(mUsageLimitStartTimeInMs);
+ dest.writeLong(mUsageLimitDataLimit);
+ dest.writeLong(mUsageLimitTimeLimitInMinutes);
}
@Override
@@ -214,22 +305,30 @@
return false;
}
PasspointConfiguration that = (PasspointConfiguration) thatObject;
- return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp))
- && (credential == null ? that.credential == null
- : credential.equals(that.credential))
- && (policy == null ? that.policy == null : policy.equals(that.policy))
- && (subscriptionUpdate == null ? that.subscriptionUpdate == null
- : subscriptionUpdate.equals(that.subscriptionUpdate))
- && isTrustRootCertListEquals(trustRootCertList, that.trustRootCertList)
- && updateIdentifier == that.updateIdentifier
- && credentialPriority == that.credentialPriority
- && subscriptionCreationTimeInMs == that.subscriptionCreationTimeInMs
- && subscriptionExpirationTimeInMs == that.subscriptionExpirationTimeInMs
- && TextUtils.equals(subscriptionType, that.subscriptionType)
- && usageLimitUsageTimePeriodInMinutes == that.usageLimitUsageTimePeriodInMinutes
- && usageLimitStartTimeInMs == that.usageLimitStartTimeInMs
- && usageLimitDataLimit == that.usageLimitDataLimit
- && usageLimitTimeLimitInMinutes == that .usageLimitTimeLimitInMinutes;
+ return (mHomeSp == null ? that.mHomeSp == null : mHomeSp.equals(that.mHomeSp))
+ && (mCredential == null ? that.mCredential == null
+ : mCredential.equals(that.mCredential))
+ && (mPolicy == null ? that.mPolicy == null : mPolicy.equals(that.mPolicy))
+ && (mSubscriptionUpdate == null ? that.mSubscriptionUpdate == null
+ : mSubscriptionUpdate.equals(that.mSubscriptionUpdate))
+ && isTrustRootCertListEquals(mTrustRootCertList, that.mTrustRootCertList)
+ && mUpdateIdentifier == that.mUpdateIdentifier
+ && mCredentialPriority == that.mCredentialPriority
+ && mSubscriptionCreationTimeInMs == that.mSubscriptionCreationTimeInMs
+ && mSubscriptionExpirationTimeInMs == that.mSubscriptionExpirationTimeInMs
+ && TextUtils.equals(mSubscriptionType, that.mSubscriptionType)
+ && mUsageLimitUsageTimePeriodInMinutes == that.mUsageLimitUsageTimePeriodInMinutes
+ && mUsageLimitStartTimeInMs == that.mUsageLimitStartTimeInMs
+ && mUsageLimitDataLimit == that.mUsageLimitDataLimit
+ && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mHomeSp, mCredential, mPolicy, mSubscriptionUpdate, mTrustRootCertList,
+ mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMs,
+ mSubscriptionExpirationTimeInMs, mUsageLimitUsageTimePeriodInMinutes,
+ mUsageLimitStartTimeInMs, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes);
}
/**
@@ -238,20 +337,20 @@
* @return true on success or false on failure
*/
public boolean validate() {
- if (homeSp == null || !homeSp.validate()) {
+ if (mHomeSp == null || !mHomeSp.validate()) {
return false;
}
- if (credential == null || !credential.validate()) {
+ if (mCredential == null || !mCredential.validate()) {
return false;
}
- if (policy != null && !policy.validate()) {
+ if (mPolicy != null && !mPolicy.validate()) {
return false;
}
- if (subscriptionUpdate != null && !subscriptionUpdate.validate()) {
+ if (mSubscriptionUpdate != null && !mSubscriptionUpdate.validate()) {
return false;
}
- if (trustRootCertList != null) {
- for (Map.Entry<String, byte[]> entry : trustRootCertList.entrySet()) {
+ if (mTrustRootCertList != null) {
+ for (Map.Entry<String, byte[]> entry : mTrustRootCertList.entrySet()) {
String url = entry.getKey();
byte[] certFingerprint = entry.getValue();
if (TextUtils.isEmpty(url)) {
@@ -283,20 +382,20 @@
@Override
public PasspointConfiguration createFromParcel(Parcel in) {
PasspointConfiguration config = new PasspointConfiguration();
- config.homeSp = in.readParcelable(null);
- config.credential = in.readParcelable(null);
- config.policy = in.readParcelable(null);
- config.subscriptionUpdate = in.readParcelable(null);
- config.trustRootCertList = readTrustRootCerts(in);
- config.updateIdentifier = in.readInt();
- config.credentialPriority = in.readInt();
- config.subscriptionCreationTimeInMs = in.readLong();
- config.subscriptionExpirationTimeInMs = in.readLong();
- config.subscriptionType = in.readString();
- config.usageLimitUsageTimePeriodInMinutes = in.readLong();
- config.usageLimitStartTimeInMs = in.readLong();
- config.usageLimitDataLimit = in.readLong();
- config.usageLimitTimeLimitInMinutes = in.readLong();
+ config.setHomeSp(in.readParcelable(null));
+ config.setCredential(in.readParcelable(null));
+ config.setPolicy(in.readParcelable(null));
+ config.setSubscriptionUpdate(in.readParcelable(null));
+ config.setTrustRootCertList(readTrustRootCerts(in));
+ config.setUpdateIdentifier(in.readInt());
+ config.setCredentialPriority(in.readInt());
+ config.setSubscriptionCreationTimeInMs(in.readLong());
+ config.setSubscriptionExpirationTimeInMs(in.readLong());
+ config.setSubscriptionType(in.readString());
+ config.setUsageLimitUsageTimePeriodInMinutes(in.readLong());
+ config.setUsageLimitStartTimeInMs(in.readLong());
+ config.setUsageLimitDataLimit(in.readLong());
+ config.setUsageLimitTimeLimitInMinutes(in.readLong());
return config;
}
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
index 22b0f97..24672d4 100644
--- a/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
@@ -450,7 +450,7 @@
}
}
if (config != null && updateIdentifier != Integer.MIN_VALUE) {
- config.updateIdentifier = updateIdentifier;
+ config.setUpdateIdentifier(updateIdentifier);
}
return config;
}
@@ -606,25 +606,25 @@
for (PPSNode child : root.getChildren()) {
switch(child.getName()) {
case NODE_HOMESP:
- config.homeSp = parseHomeSP(child);
+ config.setHomeSp(parseHomeSP(child));
break;
case NODE_CREDENTIAL:
- config.credential = parseCredential(child);
+ config.setCredential(parseCredential(child));
break;
case NODE_POLICY:
- config.policy = parsePolicy(child);
+ config.setPolicy(parsePolicy(child));
break;
case NODE_AAA_SERVER_TRUST_ROOT:
- config.trustRootCertList = parseAAAServerTrustRootList(child);
+ config.setTrustRootCertList(parseAAAServerTrustRootList(child));
break;
case NODE_SUBSCRIPTION_UPDATE:
- config.subscriptionUpdate = parseUpdateParameter(child);
+ config.setSubscriptionUpdate(parseUpdateParameter(child));
break;
case NODE_SUBSCRIPTION_PARAMETER:
parseSubscriptionParameter(child, config);
break;
case NODE_CREDENTIAL_PRIORITY:
- config.credentialPriority = parseInteger(getPpsNodeValue(child));
+ config.setCredentialPriority(parseInteger(getPpsNodeValue(child)));
break;
default:
throw new ParsingException("Unknown node: " + child.getName());
@@ -649,28 +649,28 @@
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_FQDN:
- homeSp.fqdn = getPpsNodeValue(child);
+ homeSp.setFqdn(getPpsNodeValue(child));
break;
case NODE_FRIENDLY_NAME:
- homeSp.friendlyName = getPpsNodeValue(child);
+ homeSp.setFriendlyName(getPpsNodeValue(child));
break;
case NODE_ROAMING_CONSORTIUM_OI:
- homeSp.roamingConsortiumOIs =
- parseRoamingConsortiumOI(getPpsNodeValue(child));
+ homeSp.setRoamingConsortiumOIs(
+ parseRoamingConsortiumOI(getPpsNodeValue(child)));
break;
case NODE_ICON_URL:
- homeSp.iconUrl = getPpsNodeValue(child);
+ homeSp.setIconUrl(getPpsNodeValue(child));
break;
case NODE_NETWORK_ID:
- homeSp.homeNetworkIds = parseNetworkIds(child);
+ homeSp.setHomeNetworkIds(parseNetworkIds(child));
break;
case NODE_HOME_OI_LIST:
Pair<List<Long>, List<Long>> homeOIs = parseHomeOIList(child);
- homeSp.matchAllOIs = convertFromLongList(homeOIs.first);
- homeSp.matchAnyOIs = convertFromLongList(homeOIs.second);
+ homeSp.setMatchAllOIs(convertFromLongList(homeOIs.first));
+ homeSp.setMatchAnyOIs(convertFromLongList(homeOIs.second));
break;
case NODE_OTHER_HOME_PARTNERS:
- homeSp.otherHomePartners = parseOtherHomePartners(child);
+ homeSp.setOtherHomePartners(parseOtherHomePartners(child));
break;
default:
throw new ParsingException("Unknown node under HomeSP: " + child.getName());
@@ -894,26 +894,26 @@
for (PPSNode child: node.getChildren()) {
switch (child.getName()) {
case NODE_CREATION_DATE:
- credential.creationTimeInMs = parseDate(getPpsNodeValue(child));
+ credential.setCreationTimeInMs(parseDate(getPpsNodeValue(child)));
break;
case NODE_EXPIRATION_DATE:
- credential.expirationTimeInMs = parseDate(getPpsNodeValue(child));
+ credential.setExpirationTimeInMs(parseDate(getPpsNodeValue(child)));
break;
case NODE_USERNAME_PASSWORD:
- credential.userCredential = parseUserCredential(child);
+ credential.setUserCredential(parseUserCredential(child));
break;
case NODE_DIGITAL_CERTIFICATE:
- credential.certCredential = parseCertificateCredential(child);
+ credential.setCertCredential(parseCertificateCredential(child));
break;
case NODE_REALM:
- credential.realm = getPpsNodeValue(child);
+ credential.setRealm(getPpsNodeValue(child));
break;
case NODE_CHECK_AAA_SERVER_CERT_STATUS:
- credential.checkAAAServerCertStatus =
- Boolean.parseBoolean(getPpsNodeValue(child));
+ credential.setCheckAAAServerCertStatus(
+ Boolean.parseBoolean(getPpsNodeValue(child)));
break;
case NODE_SIM:
- credential.simCredential = parseSimCredential(child);
+ credential.setSimCredential(parseSimCredential(child));
break;
default:
throw new ParsingException("Unknown node under Credential: " +
@@ -941,19 +941,19 @@
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_USERNAME:
- userCred.username = getPpsNodeValue(child);
+ userCred.setUsername(getPpsNodeValue(child));
break;
case NODE_PASSWORD:
- userCred.password = getPpsNodeValue(child);
+ userCred.setPassword(getPpsNodeValue(child));
break;
case NODE_MACHINE_MANAGED:
- userCred.machineManaged = Boolean.parseBoolean(getPpsNodeValue(child));
+ userCred.setMachineManaged(Boolean.parseBoolean(getPpsNodeValue(child)));
break;
case NODE_SOFT_TOKEN_APP:
- userCred.softTokenApp = getPpsNodeValue(child);
+ userCred.setSoftTokenApp(getPpsNodeValue(child));
break;
case NODE_ABLE_TO_SHARE:
- userCred.ableToShare = Boolean.parseBoolean(getPpsNodeValue(child));
+ userCred.setAbleToShare(Boolean.parseBoolean(getPpsNodeValue(child)));
break;
case NODE_EAP_METHOD:
parseEAPMethod(child, userCred);
@@ -984,10 +984,10 @@
for (PPSNode child : node.getChildren()) {
switch(child.getName()) {
case NODE_EAP_TYPE:
- userCred.eapType = parseInteger(getPpsNodeValue(child));
+ userCred.setEapType(parseInteger(getPpsNodeValue(child)));
break;
case NODE_INNER_METHOD:
- userCred.nonEapInnerMethod = getPpsNodeValue(child);
+ userCred.setNonEapInnerMethod(getPpsNodeValue(child));
break;
case NODE_VENDOR_ID:
case NODE_VENDOR_TYPE:
@@ -1022,10 +1022,10 @@
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_CERTIFICATE_TYPE:
- certCred.certType = getPpsNodeValue(child);
+ certCred.setCertType(getPpsNodeValue(child));
break;
case NODE_CERT_SHA256_FINGERPRINT:
- certCred.certSha256FingerPrint = parseHexString(getPpsNodeValue(child));
+ certCred.setCertSha256Fingerprint(parseHexString(getPpsNodeValue(child)));
break;
default:
throw new ParsingException("Unknown node under DigitalCertificate: " +
@@ -1053,10 +1053,10 @@
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_SIM_IMSI:
- simCred.imsi = getPpsNodeValue(child);
+ simCred.setImsi(getPpsNodeValue(child));
break;
case NODE_EAP_TYPE:
- simCred.eapType = parseInteger(getPpsNodeValue(child));
+ simCred.setEapType(parseInteger(getPpsNodeValue(child)));
break;
default:
throw new ParsingException("Unknown node under SIM: " + child.getName());
@@ -1081,22 +1081,22 @@
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_PREFERRED_ROAMING_PARTNER_LIST:
- policy.preferredRoamingPartnerList = parsePreferredRoamingPartnerList(child);
+ policy.setPreferredRoamingPartnerList(parsePreferredRoamingPartnerList(child));
break;
case NODE_MIN_BACKHAUL_THRESHOLD:
parseMinBackhaulThreshold(child, policy);
break;
case NODE_POLICY_UPDATE:
- policy.policyUpdate = parseUpdateParameter(child);
+ policy.setPolicyUpdate(parseUpdateParameter(child));
break;
case NODE_SP_EXCLUSION_LIST:
- policy.excludedSsidList = parseSpExclusionList(child);
+ policy.setExcludedSsidList(parseSpExclusionList(child));
break;
case NODE_REQUIRED_PROTO_PORT_TUPLE:
- policy.requiredProtoPortMap = parseRequiredProtoPortTuple(child);
+ policy.setRequiredProtoPortMap(parseRequiredProtoPortTuple(child));
break;
case NODE_MAXIMUM_BSS_LOAD_VALUE:
- policy.maximumBssLoadValue = parseInteger(getPpsNodeValue(child));
+ policy.setMaximumBssLoadValue(parseInteger(getPpsNodeValue(child)));
break;
default:
throw new ParsingException("Unknown node under Policy: " + child.getName());
@@ -1154,20 +1154,20 @@
if (fqdnMatchArray.length != 2) {
throw new ParsingException("Invalid FQDN_Match: " + fqdnMatch);
}
- roamingPartner.fqdn = fqdnMatchArray[0];
+ roamingPartner.setFqdn(fqdnMatchArray[0]);
if (TextUtils.equals(fqdnMatchArray[1], "exactMatch")) {
- roamingPartner.fqdnExactMatch = true;
+ roamingPartner.setFqdnExactMatch(true);
} else if (TextUtils.equals(fqdnMatchArray[1], "includeSubdomains")) {
- roamingPartner.fqdnExactMatch = false;
+ roamingPartner.setFqdnExactMatch(false);
} else {
throw new ParsingException("Invalid FQDN_Match: " + fqdnMatch);
}
break;
case NODE_PRIORITY:
- roamingPartner.priority = parseInteger(getPpsNodeValue(child));
+ roamingPartner.setPriority(parseInteger(getPpsNodeValue(child)));
break;
case NODE_COUNTRY:
- roamingPartner.countries = getPpsNodeValue(child);
+ roamingPartner.setCountries(getPpsNodeValue(child));
break;
default:
throw new ParsingException("Unknown node under PreferredRoamingPartnerList "
@@ -1234,11 +1234,11 @@
}
if (TextUtils.equals(networkType, "home")) {
- policy.minHomeDownlinkBandwidth = downlinkBandwidth;
- policy.minHomeUplinkBandwidth = uplinkBandwidth;
+ policy.setMinHomeDownlinkBandwidth(downlinkBandwidth);
+ policy.setMinHomeUplinkBandwidth(uplinkBandwidth);
} else if (TextUtils.equals(networkType, "roaming")) {
- policy.minRoamingDownlinkBandwidth = downlinkBandwidth;
- policy.minRoamingUplinkBandwidth = uplinkBandwidth;
+ policy.setMinRoamingDownlinkBandwidth(downlinkBandwidth);
+ policy.setMinRoamingUplinkBandwidth(uplinkBandwidth);
} else {
throw new ParsingException("Invalid network type: " + networkType);
}
@@ -1264,26 +1264,26 @@
for (PPSNode child : node.getChildren()) {
switch(child.getName()) {
case NODE_UPDATE_INTERVAL:
- updateParam.updateIntervalInMinutes = parseLong(getPpsNodeValue(child), 10);
+ updateParam.setUpdateIntervalInMinutes(parseLong(getPpsNodeValue(child), 10));
break;
case NODE_UPDATE_METHOD:
- updateParam.updateMethod = getPpsNodeValue(child);
+ updateParam.setUpdateMethod(getPpsNodeValue(child));
break;
case NODE_RESTRICTION:
- updateParam.restriction = getPpsNodeValue(child);
+ updateParam.setRestriction(getPpsNodeValue(child));
break;
case NODE_URI:
- updateParam.serverUri = getPpsNodeValue(child);
+ updateParam.setServerUri(getPpsNodeValue(child));
break;
case NODE_USERNAME_PASSWORD:
Pair<String, String> usernamePassword = parseUpdateUserCredential(child);
- updateParam.username = usernamePassword.first;
- updateParam.base64EncodedPassword = usernamePassword.second;
+ updateParam.setUsername(usernamePassword.first);
+ updateParam.setBase64EncodedPassword(usernamePassword.second);
break;
case NODE_TRUST_ROOT:
Pair<String, byte[]> trustRoot = parseTrustRoot(child);
- updateParam.trustRootCertUrl = trustRoot.first;
- updateParam.trustRootCertSha256Fingerprint = trustRoot.second;
+ updateParam.setTrustRootCertUrl(trustRoot.first);
+ updateParam.setTrustRootCertSha256Fingerprint(trustRoot.second);
break;
case NODE_OTHER:
Log.d(TAG, "Ignore unsupported paramter: " + child.getName());
@@ -1508,13 +1508,13 @@
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_CREATION_DATE:
- config.subscriptionCreationTimeInMs = parseDate(getPpsNodeValue(child));
+ config.setSubscriptionCreationTimeInMs(parseDate(getPpsNodeValue(child)));
break;
case NODE_EXPIRATION_DATE:
- config.subscriptionExpirationTimeInMs = parseDate(getPpsNodeValue(child));
+ config.setSubscriptionExpirationTimeInMs(parseDate(getPpsNodeValue(child)));
break;
case NODE_TYPE_OF_SUBSCRIPTION:
- config.subscriptionType = getPpsNodeValue(child);
+ config.setSubscriptionType(getPpsNodeValue(child));
break;
case NODE_USAGE_LIMITS:
parseUsageLimits(child, config);
@@ -1543,17 +1543,17 @@
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_DATA_LIMIT:
- config.usageLimitDataLimit = parseLong(getPpsNodeValue(child), 10);
+ config.setUsageLimitDataLimit(parseLong(getPpsNodeValue(child), 10));
break;
case NODE_START_DATE:
- config.usageLimitStartTimeInMs = parseDate(getPpsNodeValue(child));
+ config.setUsageLimitStartTimeInMs(parseDate(getPpsNodeValue(child)));
break;
case NODE_TIME_LIMIT:
- config.usageLimitTimeLimitInMinutes = parseLong(getPpsNodeValue(child), 10);
+ config.setUsageLimitTimeLimitInMinutes(parseLong(getPpsNodeValue(child), 10));
break;
case NODE_USAGE_TIME_PERIOD:
- config.usageLimitUsageTimePeriodInMinutes =
- parseLong(getPpsNodeValue(child), 10);
+ config.setUsageLimitUsageTimePeriodInMinutes(
+ parseLong(getPpsNodeValue(child), 10));
break;
default:
throw new ParsingException("Unknown node under UsageLimits"
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
index e87698c..959d505 100644
--- a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java
@@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* A class represent a node in an XML tree. Each node is an XML element.
@@ -100,4 +101,9 @@
TextUtils.equals(mText, that.mText) &&
mChildren.equals(that.mChildren);
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mTag, mText, mChildren);
+ }
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index 3374f42d..ff93486 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -31,6 +31,7 @@
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
/**
@@ -58,28 +59,52 @@
* of milliseconds since January 1, 1970, 00:00:00 GMT.
* Using Long.MIN_VALUE to indicate unset value.
*/
- public long creationTimeInMs = Long.MIN_VALUE;
+ private long mCreationTimeInMs = Long.MIN_VALUE;
+ public void setCreationTimeInMs(long creationTimeInMs) {
+ mCreationTimeInMs = creationTimeInMs;
+ }
+ public long getCreationTimeInMs() {
+ return mCreationTimeInMs;
+ }
/**
* The time this credential will expire. It is in the format of number
* of milliseconds since January 1, 1970, 00:00:00 GMT.
* Using Long.MIN_VALUE to indicate unset value.
*/
- public long expirationTimeInMs = Long.MIN_VALUE;
+ private long mExpirationTimeInMs = Long.MIN_VALUE;
+ public void setExpirationTimeInMs(long expirationTimeInMs) {
+ mExpirationTimeInMs = expirationTimeInMs;
+ }
+ public long getExpirationTimeInMs() {
+ return mExpirationTimeInMs;
+ }
/**
* The realm associated with this credential. It will be used to determine
* if this credential can be used to authenticate with a given hotspot by
* comparing the realm specified in that hotspot's ANQP element.
*/
- public String realm = null;
+ private String mRealm = null;
+ public void setRealm(String realm) {
+ mRealm = realm;
+ }
+ public String getRealm() {
+ return mRealm;
+ }
/**
* When set to true, the device should check AAA (Authentication, Authorization,
* and Accounting) server's certificate during EAP (Extensible Authentication
* Protocol) authentication.
*/
- public boolean checkAAAServerCertStatus = false;
+ private boolean mCheckAAAServerCertStatus = false;
+ public void setCheckAAAServerCertStatus(boolean checkAAAServerCertStatus) {
+ mCheckAAAServerCertStatus = checkAAAServerCertStatus;
+ }
+ public boolean getCheckAAAServerStatus() {
+ return mCheckAAAServerCertStatus;
+ }
/**
* Username-password based credential.
@@ -109,27 +134,57 @@
/**
* Username of the credential.
*/
- public String username = null;
+ private String mUsername = null;
+ public void setUsername(String username) {
+ mUsername = username;
+ }
+ public String getUsername() {
+ return mUsername;
+ }
/**
* Base64-encoded password.
*/
- public String password = null;
+ private String mPassword = null;
+ public void setPassword(String password) {
+ mPassword = password;
+ }
+ public String getPassword() {
+ return mPassword;
+ }
/**
* Flag indicating if the password is machine managed.
*/
- public boolean machineManaged = false;
+ private boolean mMachineManaged = false;
+ public void setMachineManaged(boolean machineManaged) {
+ mMachineManaged = machineManaged;
+ }
+ public boolean getMachineManaged() {
+ return mMachineManaged;
+ }
/**
* The name of the application used to generate the password.
*/
- public String softTokenApp = null;
+ private String mSoftTokenApp = null;
+ public void setSoftTokenApp(String softTokenApp) {
+ mSoftTokenApp = softTokenApp;
+ }
+ public String getSoftTokenApp() {
+ return mSoftTokenApp;
+ }
/**
* Flag indicating if this credential is usable on other mobile devices as well.
*/
- public boolean ableToShare = false;
+ private boolean mAbleToShare = false;
+ public void setAbleToShare(boolean ableToShare) {
+ mAbleToShare = ableToShare;
+ }
+ public boolean getAbleToShare() {
+ return mAbleToShare;
+ }
/**
* EAP (Extensible Authentication Protocol) method type.
@@ -137,12 +192,24 @@
* for valid values.
* Using Integer.MIN_VALUE to indicate unset value.
*/
- public int eapType = Integer.MIN_VALUE;
+ private int mEapType = Integer.MIN_VALUE;
+ public void setEapType(int eapType) {
+ mEapType = eapType;
+ }
+ public int getEapType() {
+ return mEapType;
+ }
/**
* Non-EAP inner authentication method.
*/
- public String nonEapInnerMethod = null;
+ private String mNonEapInnerMethod = null;
+ public void setNonEapInnerMethod(String nonEapInnerMethod) {
+ mNonEapInnerMethod = nonEapInnerMethod;
+ }
+ public String getNonEapInnerMethod() {
+ return mNonEapInnerMethod;
+ }
/**
* Constructor for creating UserCredential with default values.
@@ -156,13 +223,13 @@
*/
public UserCredential(UserCredential source) {
if (source != null) {
- username = source.username;
- password = source.password;
- machineManaged = source.machineManaged;
- softTokenApp = source.softTokenApp;
- ableToShare = source.ableToShare;
- eapType = source.eapType;
- nonEapInnerMethod = source.nonEapInnerMethod;
+ mUsername = source.mUsername;
+ mPassword = source.mPassword;
+ mMachineManaged = source.mMachineManaged;
+ mSoftTokenApp = source.mSoftTokenApp;
+ mAbleToShare = source.mAbleToShare;
+ mEapType = source.mEapType;
+ mNonEapInnerMethod = source.mNonEapInnerMethod;
}
}
@@ -173,13 +240,13 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(username);
- dest.writeString(password);
- dest.writeInt(machineManaged ? 1 : 0);
- dest.writeString(softTokenApp);
- dest.writeInt(ableToShare ? 1 : 0);
- dest.writeInt(eapType);
- dest.writeString(nonEapInnerMethod);
+ dest.writeString(mUsername);
+ dest.writeString(mPassword);
+ dest.writeInt(mMachineManaged ? 1 : 0);
+ dest.writeString(mSoftTokenApp);
+ dest.writeInt(mAbleToShare ? 1 : 0);
+ dest.writeInt(mEapType);
+ dest.writeString(mNonEapInnerMethod);
}
@Override
@@ -192,13 +259,19 @@
}
UserCredential that = (UserCredential) thatObject;
- return TextUtils.equals(username, that.username)
- && TextUtils.equals(password, that.password)
- && machineManaged == that.machineManaged
- && TextUtils.equals(softTokenApp, that.softTokenApp)
- && ableToShare == that.ableToShare
- && eapType == that.eapType
- && TextUtils.equals(nonEapInnerMethod, that.nonEapInnerMethod);
+ return TextUtils.equals(mUsername, that.mUsername)
+ && TextUtils.equals(mPassword, that.mPassword)
+ && mMachineManaged == that.mMachineManaged
+ && TextUtils.equals(mSoftTokenApp, that.mSoftTokenApp)
+ && mAbleToShare == that.mAbleToShare
+ && mEapType == that.mEapType
+ && TextUtils.equals(mNonEapInnerMethod, that.mNonEapInnerMethod);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mUsername, mPassword, mMachineManaged, mSoftTokenApp,
+ mAbleToShare, mEapType, mNonEapInnerMethod);
}
/**
@@ -207,35 +280,35 @@
* @return true on success or false on failure
*/
public boolean validate() {
- if (TextUtils.isEmpty(username)) {
+ if (TextUtils.isEmpty(mUsername)) {
Log.d(TAG, "Missing username");
return false;
}
- if (username.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
+ if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
Log.d(TAG, "username exceeding maximum length: "
- + username.getBytes(StandardCharsets.UTF_8).length);
+ + mUsername.getBytes(StandardCharsets.UTF_8).length);
return false;
}
- if (TextUtils.isEmpty(password)) {
+ if (TextUtils.isEmpty(mPassword)) {
Log.d(TAG, "Missing password");
return false;
}
- if (password.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
+ if (mPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
Log.d(TAG, "password exceeding maximum length: "
- + password.getBytes(StandardCharsets.UTF_8).length);
+ + mPassword.getBytes(StandardCharsets.UTF_8).length);
return false;
}
// Only supports EAP-TTLS for user credential.
- if (eapType != EAPConstants.EAP_TTLS) {
- Log.d(TAG, "Invalid EAP Type for user credential: " + eapType);
+ if (mEapType != EAPConstants.EAP_TTLS) {
+ Log.d(TAG, "Invalid EAP Type for user credential: " + mEapType);
return false;
}
// Verify Non-EAP inner method for EAP-TTLS.
- if (!SUPPORTED_AUTH.contains(nonEapInnerMethod)) {
- Log.d(TAG, "Invalid non-EAP inner method for EAP-TTLS: " + nonEapInnerMethod);
+ if (!SUPPORTED_AUTH.contains(mNonEapInnerMethod)) {
+ Log.d(TAG, "Invalid non-EAP inner method for EAP-TTLS: " + mNonEapInnerMethod);
return false;
}
return true;
@@ -246,13 +319,13 @@
@Override
public UserCredential createFromParcel(Parcel in) {
UserCredential userCredential = new UserCredential();
- userCredential.username = in.readString();
- userCredential.password = in.readString();
- userCredential.machineManaged = in.readInt() != 0;
- userCredential.softTokenApp = in.readString();
- userCredential.ableToShare = in.readInt() != 0;
- userCredential.eapType = in.readInt();
- userCredential.nonEapInnerMethod = in.readString();
+ userCredential.setUsername(in.readString());
+ userCredential.setPassword(in.readString());
+ userCredential.setMachineManaged(in.readInt() != 0);
+ userCredential.setSoftTokenApp(in.readString());
+ userCredential.setAbleToShare(in.readInt() != 0);
+ userCredential.setEapType(in.readInt());
+ userCredential.setNonEapInnerMethod(in.readString());
return userCredential;
}
@@ -262,7 +335,13 @@
}
};
}
- public UserCredential userCredential = null;
+ private UserCredential mUserCredential = null;
+ public void setUserCredential(UserCredential userCredential) {
+ mUserCredential = userCredential;
+ }
+ public UserCredential getUserCredential() {
+ return mUserCredential;
+ }
/**
* Certificate based credential. This is used for EAP-TLS.
@@ -282,12 +361,24 @@
/**
* Certificate type.
*/
- public String certType = null;
+ private String mCertType = null;
+ public void setCertType(String certType) {
+ mCertType = certType;
+ }
+ public String getCertType() {
+ return mCertType;
+ }
/**
* The SHA-256 fingerprint of the certificate.
*/
- public byte[] certSha256FingerPrint = null;
+ private byte[] mCertSha256Fingerprint = null;
+ public void setCertSha256Fingerprint(byte[] certSha256Fingerprint) {
+ mCertSha256Fingerprint = certSha256Fingerprint;
+ }
+ public byte[] getCertSha256Fingerprint() {
+ return mCertSha256Fingerprint;
+ }
/**
* Constructor for creating CertificateCredential with default values.
@@ -301,10 +392,10 @@
*/
public CertificateCredential(CertificateCredential source) {
if (source != null) {
- certType = source.certType;
- if (source.certSha256FingerPrint != null) {
- certSha256FingerPrint = Arrays.copyOf(source.certSha256FingerPrint,
- source.certSha256FingerPrint.length);
+ mCertType = source.mCertType;
+ if (source.mCertSha256Fingerprint != null) {
+ mCertSha256Fingerprint = Arrays.copyOf(source.mCertSha256Fingerprint,
+ source.mCertSha256Fingerprint.length);
}
}
}
@@ -316,8 +407,8 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(certType);
- dest.writeByteArray(certSha256FingerPrint);
+ dest.writeString(mCertType);
+ dest.writeByteArray(mCertSha256Fingerprint);
}
@Override
@@ -330,8 +421,13 @@
}
CertificateCredential that = (CertificateCredential) thatObject;
- return TextUtils.equals(certType, that.certType)
- && Arrays.equals(certSha256FingerPrint, that.certSha256FingerPrint);
+ return TextUtils.equals(mCertType, that.mCertType)
+ && Arrays.equals(mCertSha256Fingerprint, that.mCertSha256Fingerprint);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mCertType, mCertSha256Fingerprint);
}
/**
@@ -340,12 +436,12 @@
* @return true on success or false on failure
*/
public boolean validate() {
- if (!TextUtils.equals(CERT_TYPE_X509V3, certType)) {
- Log.d(TAG, "Unsupported certificate type: " + certType);
+ if (!TextUtils.equals(CERT_TYPE_X509V3, mCertType)) {
+ Log.d(TAG, "Unsupported certificate type: " + mCertType);
return false;
}
- if (certSha256FingerPrint == null
- || certSha256FingerPrint.length != CERT_SHA256_FINGER_PRINT_LENGTH) {
+ if (mCertSha256Fingerprint == null
+ || mCertSha256Fingerprint.length != CERT_SHA256_FINGER_PRINT_LENGTH) {
Log.d(TAG, "Invalid SHA-256 fingerprint");
return false;
}
@@ -357,8 +453,8 @@
@Override
public CertificateCredential createFromParcel(Parcel in) {
CertificateCredential certCredential = new CertificateCredential();
- certCredential.certType = in.readString();
- certCredential.certSha256FingerPrint = in.createByteArray();
+ certCredential.setCertType(in.readString());
+ certCredential.setCertSha256Fingerprint(in.createByteArray());
return certCredential;
}
@@ -368,7 +464,13 @@
}
};
}
- public CertificateCredential certCredential = null;
+ private CertificateCredential mCertCredential = null;
+ public void setCertCredential(CertificateCredential certCredential) {
+ mCertCredential = certCredential;
+ }
+ public CertificateCredential getCertCredential() {
+ return mCertCredential;
+ }
/**
* SIM (Subscriber Identify Module) based credential.
@@ -378,14 +480,20 @@
/**
* Maximum string length for IMSI.
*/
- public static final int MAX_IMSI_LENGTH = 15;
+ private static final int MAX_IMSI_LENGTH = 15;
/**
* International Mobile Subscriber Identity, is used to identify the user
* of a cellular network and is a unique identification associated with all
* cellular networks
*/
- public String imsi = null;
+ private String mImsi = null;
+ public void setImsi(String imsi) {
+ mImsi = imsi;
+ }
+ public String getImsi() {
+ return mImsi;
+ }
/**
* EAP (Extensible Authentication Protocol) method type for using SIM credential.
@@ -393,7 +501,13 @@
* for valid values.
* Using Integer.MIN_VALUE to indicate unset value.
*/
- public int eapType = Integer.MIN_VALUE;
+ private int mEapType = Integer.MIN_VALUE;
+ public void setEapType(int eapType) {
+ mEapType = eapType;
+ }
+ public int getEapType() {
+ return mEapType;
+ }
/**
* Constructor for creating SimCredential with default values.
@@ -407,8 +521,8 @@
*/
public SimCredential(SimCredential source) {
if (source != null) {
- imsi = source.imsi;
- eapType = source.eapType;
+ mImsi = source.mImsi;
+ mEapType = source.mEapType;
}
}
@@ -427,14 +541,19 @@
}
SimCredential that = (SimCredential) thatObject;
- return TextUtils.equals(imsi, that.imsi)
- && eapType == that.eapType;
+ return TextUtils.equals(mImsi, that.mImsi)
+ && mEapType == that.mEapType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mImsi, mEapType);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(imsi);
- dest.writeInt(eapType);
+ dest.writeString(mImsi);
+ dest.writeInt(mEapType);
}
/**
@@ -449,9 +568,9 @@
if (!verifyImsi()) {
return false;
}
- if (eapType != EAPConstants.EAP_SIM && eapType != EAPConstants.EAP_AKA
- && eapType != EAPConstants.EAP_AKA_PRIME) {
- Log.d(TAG, "Invalid EAP Type for SIM credential: " + eapType);
+ if (mEapType != EAPConstants.EAP_SIM && mEapType != EAPConstants.EAP_AKA
+ && mEapType != EAPConstants.EAP_AKA_PRIME) {
+ Log.d(TAG, "Invalid EAP Type for SIM credential: " + mEapType);
return false;
}
return true;
@@ -462,8 +581,8 @@
@Override
public SimCredential createFromParcel(Parcel in) {
SimCredential simCredential = new SimCredential();
- simCredential.imsi = in.readString();
- simCredential.eapType = in.readInt();
+ simCredential.setImsi(in.readString());
+ simCredential.setEapType(in.readInt());
return simCredential;
}
@@ -481,51 +600,75 @@
* @return true if IMSI is valid, false otherwise.
*/
private boolean verifyImsi() {
- if (TextUtils.isEmpty(imsi)) {
+ if (TextUtils.isEmpty(mImsi)) {
Log.d(TAG, "Missing IMSI");
return false;
}
- if (imsi.length() > MAX_IMSI_LENGTH) {
- Log.d(TAG, "IMSI exceeding maximum length: " + imsi.length());
+ if (mImsi.length() > MAX_IMSI_LENGTH) {
+ Log.d(TAG, "IMSI exceeding maximum length: " + mImsi.length());
return false;
}
// Locate the first non-digit character.
int nonDigit;
char stopChar = '\0';
- for (nonDigit = 0; nonDigit < imsi.length(); nonDigit++) {
- stopChar = imsi.charAt(nonDigit);
+ for (nonDigit = 0; nonDigit < mImsi.length(); nonDigit++) {
+ stopChar = mImsi.charAt(nonDigit);
if (stopChar < '0' || stopChar > '9') {
break;
}
}
- if (nonDigit == imsi.length()) {
+ if (nonDigit == mImsi.length()) {
return true;
}
- else if (nonDigit == imsi.length()-1 && stopChar == '*') {
+ else if (nonDigit == mImsi.length()-1 && stopChar == '*') {
// Prefix matching.
return true;
}
return false;
}
}
- public SimCredential simCredential = null;
+ private SimCredential mSimCredential = null;
+ public void setSimCredential(SimCredential simCredential) {
+ mSimCredential = simCredential;
+ }
+ public SimCredential getSimCredential() {
+ return mSimCredential;
+ }
/**
* CA (Certificate Authority) X509 certificate.
*/
- public X509Certificate caCertificate = null;
+ private X509Certificate mCaCertificate = null;
+ public void setCaCertificate(X509Certificate caCertificate) {
+ mCaCertificate = caCertificate;
+ }
+ public X509Certificate getCaCertificate() {
+ return mCaCertificate;
+ }
/**
* Client side X509 certificate chain.
*/
- public X509Certificate[] clientCertificateChain = null;
+ private X509Certificate[] mClientCertificateChain = null;
+ public void setClientCertificateChain(X509Certificate[] certificateChain) {
+ mClientCertificateChain = certificateChain;
+ }
+ public X509Certificate[] getClientCertificateChain() {
+ return mClientCertificateChain;
+ }
/**
* Client side private key.
*/
- public PrivateKey clientPrivateKey = null;
+ private PrivateKey mClientPrivateKey = null;
+ public void setClientPrivateKey(PrivateKey clientPrivateKey) {
+ mClientPrivateKey = clientPrivateKey;
+ }
+ public PrivateKey getClientPrivateKey() {
+ return mClientPrivateKey;
+ }
/**
* Constructor for creating Credential with default values.
@@ -539,25 +682,25 @@
*/
public Credential(Credential source) {
if (source != null) {
- creationTimeInMs = source.creationTimeInMs;
- expirationTimeInMs = source.expirationTimeInMs;
- realm = source.realm;
- checkAAAServerCertStatus = source.checkAAAServerCertStatus;
- if (source.userCredential != null) {
- userCredential = new UserCredential(source.userCredential);
+ mCreationTimeInMs = source.mCreationTimeInMs;
+ mExpirationTimeInMs = source.mExpirationTimeInMs;
+ mRealm = source.mRealm;
+ mCheckAAAServerCertStatus = source.mCheckAAAServerCertStatus;
+ if (source.mUserCredential != null) {
+ mUserCredential = new UserCredential(source.mUserCredential);
}
- if (source.certCredential != null) {
- certCredential = new CertificateCredential(source.certCredential);
+ if (source.mCertCredential != null) {
+ mCertCredential = new CertificateCredential(source.mCertCredential);
}
- if (source.simCredential != null) {
- simCredential = new SimCredential(source.simCredential);
+ if (source.mSimCredential != null) {
+ mSimCredential = new SimCredential(source.mSimCredential);
}
- if (source.clientCertificateChain != null) {
- clientCertificateChain = Arrays.copyOf(source.clientCertificateChain,
- source.clientCertificateChain.length);
+ if (source.mClientCertificateChain != null) {
+ mClientCertificateChain = Arrays.copyOf(source.mClientCertificateChain,
+ source.mClientCertificateChain.length);
}
- caCertificate = source.caCertificate;
- clientPrivateKey = source.clientPrivateKey;
+ mCaCertificate = source.mCaCertificate;
+ mClientPrivateKey = source.mClientPrivateKey;
}
}
@@ -568,16 +711,16 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(creationTimeInMs);
- dest.writeLong(expirationTimeInMs);
- dest.writeString(realm);
- dest.writeInt(checkAAAServerCertStatus ? 1 : 0);
- dest.writeParcelable(userCredential, flags);
- dest.writeParcelable(certCredential, flags);
- dest.writeParcelable(simCredential, flags);
- ParcelUtil.writeCertificate(dest, caCertificate);
- ParcelUtil.writeCertificates(dest, clientCertificateChain);
- ParcelUtil.writePrivateKey(dest, clientPrivateKey);
+ dest.writeLong(mCreationTimeInMs);
+ dest.writeLong(mExpirationTimeInMs);
+ dest.writeString(mRealm);
+ dest.writeInt(mCheckAAAServerCertStatus ? 1 : 0);
+ dest.writeParcelable(mUserCredential, flags);
+ dest.writeParcelable(mCertCredential, flags);
+ dest.writeParcelable(mSimCredential, flags);
+ ParcelUtil.writeCertificate(dest, mCaCertificate);
+ ParcelUtil.writeCertificates(dest, mClientCertificateChain);
+ ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
}
@Override
@@ -590,19 +733,26 @@
}
Credential that = (Credential) thatObject;
- return TextUtils.equals(realm, that.realm)
- && creationTimeInMs == that.creationTimeInMs
- && expirationTimeInMs == that.expirationTimeInMs
- && checkAAAServerCertStatus == that.checkAAAServerCertStatus
- && (userCredential == null ? that.userCredential == null
- : userCredential.equals(that.userCredential))
- && (certCredential == null ? that.certCredential == null
- : certCredential.equals(that.certCredential))
- && (simCredential == null ? that.simCredential == null
- : simCredential.equals(that.simCredential))
- && isX509CertificateEquals(caCertificate, that.caCertificate)
- && isX509CertificatesEquals(clientCertificateChain, that.clientCertificateChain)
- && isPrivateKeyEquals(clientPrivateKey, that.clientPrivateKey);
+ return TextUtils.equals(mRealm, that.mRealm)
+ && mCreationTimeInMs == that.mCreationTimeInMs
+ && mExpirationTimeInMs == that.mExpirationTimeInMs
+ && mCheckAAAServerCertStatus == that.mCheckAAAServerCertStatus
+ && (mUserCredential == null ? that.mUserCredential == null
+ : mUserCredential.equals(that.mUserCredential))
+ && (mCertCredential == null ? that.mCertCredential == null
+ : mCertCredential.equals(that.mCertCredential))
+ && (mSimCredential == null ? that.mSimCredential == null
+ : mSimCredential.equals(that.mSimCredential))
+ && isX509CertificateEquals(mCaCertificate, that.mCaCertificate)
+ && isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain)
+ && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mRealm, mCreationTimeInMs, mExpirationTimeInMs,
+ mCheckAAAServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
+ mCaCertificate, mClientCertificateChain, mClientPrivateKey);
}
/**
@@ -611,26 +761,26 @@
* @return true on success or false on failure
*/
public boolean validate() {
- if (TextUtils.isEmpty(realm)) {
+ if (TextUtils.isEmpty(mRealm)) {
Log.d(TAG, "Missing realm");
return false;
}
- if (realm.getBytes(StandardCharsets.UTF_8).length > MAX_REALM_BYTES) {
+ if (mRealm.getBytes(StandardCharsets.UTF_8).length > MAX_REALM_BYTES) {
Log.d(TAG, "realm exceeding maximum length: "
- + realm.getBytes(StandardCharsets.UTF_8).length);
+ + mRealm.getBytes(StandardCharsets.UTF_8).length);
return false;
}
// Verify the credential.
- if (userCredential != null) {
+ if (mUserCredential != null) {
if (!verifyUserCredential()) {
return false;
}
- } else if (certCredential != null) {
+ } else if (mCertCredential != null) {
if (!verifyCertCredential()) {
return false;
}
- } else if (simCredential != null) {
+ } else if (mSimCredential != null) {
if (!verifySimCredential()) {
return false;
}
@@ -647,16 +797,16 @@
@Override
public Credential createFromParcel(Parcel in) {
Credential credential = new Credential();
- credential.creationTimeInMs = in.readLong();
- credential.expirationTimeInMs = in.readLong();
- credential.realm = in.readString();
- credential.checkAAAServerCertStatus = in.readInt() != 0;
- credential.userCredential = in.readParcelable(null);
- credential.certCredential = in.readParcelable(null);
- credential.simCredential = in.readParcelable(null);
- credential.caCertificate = ParcelUtil.readCertificate(in);
- credential.clientCertificateChain = ParcelUtil.readCertificates(in);
- credential.clientPrivateKey = ParcelUtil.readPrivateKey(in);
+ credential.setCreationTimeInMs(in.readLong());
+ credential.setExpirationTimeInMs(in.readLong());
+ credential.setRealm(in.readString());
+ credential.setCheckAAAServerCertStatus(in.readInt() != 0);
+ credential.setUserCredential(in.readParcelable(null));
+ credential.setCertCredential(in.readParcelable(null));
+ credential.setSimCredential(in.readParcelable(null));
+ credential.setCaCertificate(ParcelUtil.readCertificate(in));
+ credential.setClientCertificateChain(ParcelUtil.readCertificates(in));
+ credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in));
return credential;
}
@@ -672,18 +822,18 @@
* @return true if user credential is valid, false otherwise.
*/
private boolean verifyUserCredential() {
- if (userCredential == null) {
+ if (mUserCredential == null) {
Log.d(TAG, "Missing user credential");
return false;
}
- if (certCredential != null || simCredential != null) {
+ if (mCertCredential != null || mSimCredential != null) {
Log.d(TAG, "Contained more than one type of credential");
return false;
}
- if (!userCredential.validate()) {
+ if (!mUserCredential.validate()) {
return false;
}
- if (caCertificate == null) {
+ if (mCaCertificate == null) {
Log.d(TAG, "Missing CA Certificate for user credential");
return false;
}
@@ -697,32 +847,32 @@
* @return true if certificate credential is valid, false otherwise.
*/
private boolean verifyCertCredential() {
- if (certCredential == null) {
+ if (mCertCredential == null) {
Log.d(TAG, "Missing certificate credential");
return false;
}
- if (userCredential != null || simCredential != null) {
+ if (mUserCredential != null || mSimCredential != null) {
Log.d(TAG, "Contained more than one type of credential");
return false;
}
- if (!certCredential.validate()) {
+ if (!mCertCredential.validate()) {
return false;
}
// Verify required key and certificates for certificate credential.
- if (caCertificate == null) {
+ if (mCaCertificate == null) {
Log.d(TAG, "Missing CA Certificate for certificate credential");
return false;
}
- if (clientPrivateKey == null) {
+ if (mClientPrivateKey == null) {
Log.d(TAG, "Missing client private key for certificate credential");
return false;
}
try {
// Verify SHA-256 fingerprint for client certificate.
- if (!verifySha256Fingerprint(clientCertificateChain,
- certCredential.certSha256FingerPrint)) {
+ if (!verifySha256Fingerprint(mClientCertificateChain,
+ mCertCredential.getCertSha256Fingerprint())) {
Log.d(TAG, "SHA-256 fingerprint mismatch");
return false;
}
@@ -740,15 +890,15 @@
* @return true if SIM credential is valid, false otherwise.
*/
private boolean verifySimCredential() {
- if (simCredential == null) {
+ if (mSimCredential == null) {
Log.d(TAG, "Missing SIM credential");
return false;
}
- if (userCredential != null || certCredential != null) {
+ if (mUserCredential != null || mCertCredential != null) {
Log.d(TAG, "Contained more than one type of credential");
return false;
}
- return simCredential.validate();
+ return mSimCredential.validate();
}
private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) {
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
index 4ddf210..8b3b79c 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
/**
* Class representing HomeSP subtree in PerProviderSubscription (PPS)
@@ -52,17 +53,35 @@
/**
* FQDN (Fully Qualified Domain Name) of this home service provider.
*/
- public String fqdn = null;
+ private String mFqdn = null;
+ public void setFqdn(String fqdn) {
+ mFqdn = fqdn;
+ }
+ public String getFqdn() {
+ return mFqdn;
+ }
/**
* Friendly name of this home service provider.
*/
- public String friendlyName = null;
+ private String mFriendlyName = null;
+ public void setFriendlyName(String friendlyName) {
+ mFriendlyName = friendlyName;
+ }
+ public String getFriendlyName() {
+ return mFriendlyName;
+ }
/**
* Icon URL of this home service provider.
*/
- public String iconUrl = null;
+ private String mIconUrl = null;
+ public void setIconUrl(String iconUrl) {
+ mIconUrl = iconUrl;
+ }
+ public String getIconUrl() {
+ return mIconUrl;
+ }
/**
* <SSID, HESSID> duple of the networks that are consider home networks.
@@ -71,7 +90,13 @@
* all nodes in the PSS MO are encoded using UTF-8 unless stated otherwise. Thus, the SSID
* string is assumed to be encoded using UTF-8.
*/
- public Map<String, Long> homeNetworkIds = null;
+ private Map<String, Long> mHomeNetworkIds = null;
+ public void setHomeNetworkIds(Map<String, Long> homeNetworkIds) {
+ mHomeNetworkIds = homeNetworkIds;
+ }
+ public Map<String, Long> getHomeNetworkIds() {
+ return mHomeNetworkIds;
+ }
/**
* Used for determining if this provider is a member of a given Hotspot provider.
@@ -83,7 +108,13 @@
* Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
* (MO) tree for more detail.
*/
- public long[] matchAllOIs = null;
+ private long[] mMatchAllOIs = null;
+ public void setMatchAllOIs(long[] matchAllOIs) {
+ mMatchAllOIs = matchAllOIs;
+ }
+ public long[] getMatchAllOIs() {
+ return mMatchAllOIs;
+ }
/**
* Used for determining if this provider is a member of a given Hotspot provider.
@@ -92,13 +123,19 @@
* of that Hotspot provider (e.g. successful authentication with such Hotspot
* is possible).
*
- * {@link #matchAllOIs} will have precedence over this one, meaning this list will
- * only be used for matching if {@link #matchAllOIs} is null or empty.
+ * {@link #mMatchAllOIs} will have precedence over this one, meaning this list will
+ * only be used for matching if {@link #mMatchAllOIs} is null or empty.
*
* Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
* (MO) tree for more detail.
*/
- public long[] matchAnyOIs = null;
+ private long[] mMatchAnyOIs = null;
+ public void setMatchAnyOIs(long[] matchAnyOIs) {
+ mMatchAnyOIs = matchAnyOIs;
+ }
+ public long[] getMatchAnysOIs() {
+ return mMatchAnyOIs;
+ }
/**
* List of FQDN (Fully Qualified Domain Name) of partner providers.
@@ -106,13 +143,25 @@
* This relationship is most likely achieved via a commercial agreement or
* operator merges between the providers.
*/
- public String[] otherHomePartners = null;
+ private String[] mOtherHomePartners = null;
+ public void setOtherHomePartners(String[] otherHomePartners) {
+ mOtherHomePartners = otherHomePartners;
+ }
+ public String[] getOtherHomePartners() {
+ return mOtherHomePartners;
+ }
/**
* List of Organization Identifiers (OIs) identifying a roaming consortium of
* which this provider is a member.
*/
- public long[] roamingConsortiumOIs = null;
+ private long[] mRoamingConsortiumOIs = null;
+ public void setRoamingConsortiumOIs(long[] roamingConsortiumOIs) {
+ mRoamingConsortiumOIs = roamingConsortiumOIs;
+ }
+ public long[] getRoamingConsortiumOIs() {
+ return mRoamingConsortiumOIs;
+ }
/**
* Constructor for creating HomeSP with default values.
@@ -128,25 +177,25 @@
if (source == null) {
return;
}
- fqdn = source.fqdn;
- friendlyName = source.friendlyName;
- iconUrl = source.iconUrl;
- if (source.homeNetworkIds != null) {
- homeNetworkIds = Collections.unmodifiableMap(source.homeNetworkIds);
+ mFqdn = source.mFqdn;
+ mFriendlyName = source.mFriendlyName;
+ mIconUrl = source.mIconUrl;
+ if (source.mHomeNetworkIds != null) {
+ mHomeNetworkIds = Collections.unmodifiableMap(source.mHomeNetworkIds);
}
- if (source.matchAllOIs != null) {
- matchAllOIs = Arrays.copyOf(source.matchAllOIs, source.matchAllOIs.length);
+ if (source.mMatchAllOIs != null) {
+ mMatchAllOIs = Arrays.copyOf(source.mMatchAllOIs, source.mMatchAllOIs.length);
}
- if (source.matchAnyOIs != null) {
- matchAnyOIs = Arrays.copyOf(source.matchAnyOIs, source.matchAnyOIs.length);
+ if (source.mMatchAnyOIs != null) {
+ mMatchAnyOIs = Arrays.copyOf(source.mMatchAnyOIs, source.mMatchAnyOIs.length);
}
- if (source.otherHomePartners != null) {
- otherHomePartners = Arrays.copyOf(source.otherHomePartners,
- source.otherHomePartners.length);
+ if (source.mOtherHomePartners != null) {
+ mOtherHomePartners = Arrays.copyOf(source.mOtherHomePartners,
+ source.mOtherHomePartners.length);
}
- if (source.roamingConsortiumOIs != null) {
- roamingConsortiumOIs = Arrays.copyOf(source.roamingConsortiumOIs,
- source.roamingConsortiumOIs.length);
+ if (source.mRoamingConsortiumOIs != null) {
+ mRoamingConsortiumOIs = Arrays.copyOf(source.mRoamingConsortiumOIs,
+ source.mRoamingConsortiumOIs.length);
}
}
@@ -157,14 +206,14 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(fqdn);
- dest.writeString(friendlyName);
- dest.writeString(iconUrl);
- writeHomeNetworkIds(dest, homeNetworkIds);
- dest.writeLongArray(matchAllOIs);
- dest.writeLongArray(matchAnyOIs);
- dest.writeStringArray(otherHomePartners);
- dest.writeLongArray(roamingConsortiumOIs);
+ dest.writeString(mFqdn);
+ dest.writeString(mFriendlyName);
+ dest.writeString(mIconUrl);
+ writeHomeNetworkIds(dest, mHomeNetworkIds);
+ dest.writeLongArray(mMatchAllOIs);
+ dest.writeLongArray(mMatchAnyOIs);
+ dest.writeStringArray(mOtherHomePartners);
+ dest.writeLongArray(mRoamingConsortiumOIs);
}
@Override
@@ -177,15 +226,21 @@
}
HomeSP that = (HomeSP) thatObject;
- return TextUtils.equals(fqdn, that.fqdn)
- && TextUtils.equals(friendlyName, that.friendlyName)
- && TextUtils.equals(iconUrl, that.iconUrl)
- && (homeNetworkIds == null ? that.homeNetworkIds == null
- : homeNetworkIds.equals(that.homeNetworkIds))
- && Arrays.equals(matchAllOIs, that.matchAllOIs)
- && Arrays.equals(matchAnyOIs, that.matchAnyOIs)
- && Arrays.equals(otherHomePartners, that.otherHomePartners)
- && Arrays.equals(roamingConsortiumOIs, that.roamingConsortiumOIs);
+ return TextUtils.equals(mFqdn, that.mFqdn)
+ && TextUtils.equals(mFriendlyName, that.mFriendlyName)
+ && TextUtils.equals(mIconUrl, that.mIconUrl)
+ && (mHomeNetworkIds == null ? that.mHomeNetworkIds == null
+ : mHomeNetworkIds.equals(that.mHomeNetworkIds))
+ && Arrays.equals(mMatchAllOIs, that.mMatchAllOIs)
+ && Arrays.equals(mMatchAnyOIs, that.mMatchAnyOIs)
+ && Arrays.equals(mOtherHomePartners, that.mOtherHomePartners)
+ && Arrays.equals(mRoamingConsortiumOIs, that.mRoamingConsortiumOIs);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFqdn, mFriendlyName, mIconUrl, mHomeNetworkIds, mMatchAllOIs,
+ mMatchAnyOIs, mOtherHomePartners, mRoamingConsortiumOIs);
}
/**
@@ -194,17 +249,17 @@
* @return true on success or false on failure
*/
public boolean validate() {
- if (TextUtils.isEmpty(fqdn)) {
+ if (TextUtils.isEmpty(mFqdn)) {
Log.d(TAG, "Missing FQDN");
return false;
}
- if (TextUtils.isEmpty(friendlyName)) {
+ if (TextUtils.isEmpty(mFriendlyName)) {
Log.d(TAG, "Missing friendly name");
return false;
}
// Verify SSIDs specified in the NetworkID
- if (homeNetworkIds != null) {
- for (Map.Entry<String, Long> entry : homeNetworkIds.entrySet()) {
+ if (mHomeNetworkIds != null) {
+ for (Map.Entry<String, Long> entry : mHomeNetworkIds.entrySet()) {
if (entry.getKey() == null ||
entry.getKey().getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
Log.d(TAG, "Invalid SSID in HomeNetworkIDs");
@@ -220,14 +275,14 @@
@Override
public HomeSP createFromParcel(Parcel in) {
HomeSP homeSp = new HomeSP();
- homeSp.fqdn = in.readString();
- homeSp.friendlyName = in.readString();
- homeSp.iconUrl = in.readString();
- homeSp.homeNetworkIds = readHomeNetworkIds(in);
- homeSp.matchAllOIs = in.createLongArray();
- homeSp.matchAnyOIs = in.createLongArray();
- homeSp.otherHomePartners = in.createStringArray();
- homeSp.roamingConsortiumOIs = in.createLongArray();
+ homeSp.setFqdn(in.readString());
+ homeSp.setFriendlyName(in.readString());
+ homeSp.setIconUrl(in.readString());
+ homeSp.setHomeNetworkIds(readHomeNetworkIds(in));
+ homeSp.setMatchAllOIs(in.createLongArray());
+ homeSp.setMatchAnyOIs(in.createLongArray());
+ homeSp.setOtherHomePartners(in.createStringArray());
+ homeSp.setRoamingConsortiumOIs(in.createLongArray());
return homeSp;
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
index bc29402..ceaada4 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -28,6 +28,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Class representing Policy subtree in PerProviderSubscription (PPS)
@@ -79,8 +80,20 @@
*
* Using Long.MIN_VALUE to indicate unset value.
*/
- public long minHomeDownlinkBandwidth = Long.MIN_VALUE;
- public long minHomeUplinkBandwidth = Long.MIN_VALUE;
+ private long mMinHomeDownlinkBandwidth = Long.MIN_VALUE;
+ public void setMinHomeDownlinkBandwidth(long minHomeDownlinkBandwidth) {
+ mMinHomeDownlinkBandwidth = minHomeDownlinkBandwidth;
+ }
+ public long getMinHomeDownlinkBandWidht() {
+ return mMinHomeDownlinkBandwidth;
+ }
+ private long mMinHomeUplinkBandwidth = Long.MIN_VALUE;
+ public void setMinHomeUplinkBandwidth(long minHomeUplinkBandwidth) {
+ mMinHomeUplinkBandwidth = minHomeUplinkBandwidth;
+ }
+ public long getMinHomeUplinkBandwidth() {
+ return mMinHomeUplinkBandwidth;
+ }
/**
* Minimum available downlink/uplink bandwidth (in kilobits per second) required when
@@ -91,26 +104,56 @@
*
* Using Long.MIN_VALUE to indicate unset value.
*/
- public long minRoamingDownlinkBandwidth = Long.MIN_VALUE;
- public long minRoamingUplinkBandwidth = Long.MIN_VALUE;
+ private long mMinRoamingDownlinkBandwidth = Long.MIN_VALUE;
+ public void setMinRoamingDownlinkBandwidth(long minRoamingDownlinkBandwidth) {
+ mMinRoamingDownlinkBandwidth = minRoamingDownlinkBandwidth;
+ }
+ public long getMinRoamingDownlinkBandwidth() {
+ return mMinRoamingDownlinkBandwidth;
+ }
+ private long mMinRoamingUplinkBandwidth = Long.MIN_VALUE;
+ public void setMinRoamingUplinkBandwidth(long minRoamingUplinkBandwidth) {
+ mMinRoamingUplinkBandwidth = minRoamingUplinkBandwidth;
+ }
+ public long getMinRoamingUplinkBandwidth() {
+ return mMinRoamingUplinkBandwidth;
+ }
/**
* List of SSIDs that are not preferred by the Home SP.
*/
- public String[] excludedSsidList = null;
+ private String[] mExcludedSsidList = null;
+ public void setExcludedSsidList(String[] excludedSsidList) {
+ mExcludedSsidList = excludedSsidList;
+ }
+ public String[] getExcludedSsidList() {
+ return mExcludedSsidList;
+ }
/**
* List of IP protocol and port number required by one or more operator supported application.
* The port string contained one or more port numbers delimited by ",".
*/
- public Map<Integer, String> requiredProtoPortMap = null;
+ private Map<Integer, String> mRequiredProtoPortMap = null;
+ public void setRequiredProtoPortMap(Map<Integer, String> requiredProtoPortMap) {
+ mRequiredProtoPortMap = requiredProtoPortMap;
+ }
+ public Map<Integer, String> getRequiredProtoPortMap() {
+ return mRequiredProtoPortMap;
+ }
/**
* This specifies the maximum acceptable BSS load policy. This is used to prevent device
* from joining an AP whose channel is overly congested with traffic.
* Using Integer.MIN_VALUE to indicate unset value.
*/
- public int maximumBssLoadValue = Integer.MIN_VALUE;
+ private int mMaximumBssLoadValue = Integer.MIN_VALUE;
+ public void setMaximumBssLoadValue(int maximumBssLoadValue) {
+ mMaximumBssLoadValue = maximumBssLoadValue;
+ }
+ public int getMaximumBssLoadValue() {
+ return mMaximumBssLoadValue;
+ }
/**
* Policy associated with a roaming provider. This specifies a priority associated
@@ -122,7 +165,13 @@
/**
* FQDN of the roaming partner.
*/
- public String fqdn = null;
+ private String mFqdn = null;
+ public void setFqdn(String fqdn) {
+ mFqdn = fqdn;
+ }
+ public String getFqdn() {
+ return mFqdn;
+ }
/**
* Flag indicating the exact match of FQDN is required for FQDN matching.
@@ -130,27 +179,45 @@
* When this flag is set to false, sub-domain matching is used. For example, when
* {@link #fqdn} s set to "example.com", "host.example.com" would be a match.
*/
- public boolean fqdnExactMatch = false;
+ private boolean mFqdnExactMatch = false;
+ public void setFqdnExactMatch(boolean fqdnExactMatch) {
+ mFqdnExactMatch = fqdnExactMatch;
+ }
+ public boolean getFqdnExactMatch() {
+ return mFqdnExactMatch;
+ }
/**
* Priority associated with this roaming partner policy.
*/
- public int priority = PREFERRED_ROAMING_PARTNER_DEFAULT_PRIORITY;
+ private int mPriority = PREFERRED_ROAMING_PARTNER_DEFAULT_PRIORITY;
+ public void setPriority(int priority) {
+ mPriority = priority;
+ }
+ public int getPriority() {
+ return mPriority;
+ }
/**
* A string contained One or more, comma delimited (i.e., ",") ISO/IEC 3166-1 two
* character country strings or the country-independent value, "*".
*/
- public String countries = null;
+ private String mCountries = null;
+ public void setCountries(String countries) {
+ mCountries = countries;
+ }
+ public String getCountries() {
+ return mCountries;
+ }
public RoamingPartner() {}
public RoamingPartner(RoamingPartner source) {
if (source != null) {
- fqdn = source.fqdn;
- fqdnExactMatch = source.fqdnExactMatch;
- priority = source.priority;
- countries = source.countries;
+ mFqdn = source.mFqdn;
+ mFqdnExactMatch = source.mFqdnExactMatch;
+ mPriority = source.mPriority;
+ mCountries = source.mCountries;
}
}
@@ -161,10 +228,10 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(fqdn);
- dest.writeInt(fqdnExactMatch ? 1 : 0);
- dest.writeInt(priority);
- dest.writeString(countries);
+ dest.writeString(mFqdn);
+ dest.writeInt(mFqdnExactMatch ? 1 : 0);
+ dest.writeInt(mPriority);
+ dest.writeString(mCountries);
}
@Override
@@ -177,10 +244,15 @@
}
RoamingPartner that = (RoamingPartner) thatObject;
- return TextUtils.equals(fqdn, that.fqdn)
- && fqdnExactMatch == that.fqdnExactMatch
- && priority == that.priority
- && TextUtils.equals(countries, that.countries);
+ return TextUtils.equals(mFqdn, that.mFqdn)
+ && mFqdnExactMatch == that.mFqdnExactMatch
+ && mPriority == that.mPriority
+ && TextUtils.equals(mCountries, that.mCountries);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFqdn, mFqdnExactMatch, mPriority, mCountries);
}
/**
@@ -189,11 +261,11 @@
* @return true on success
*/
public boolean validate() {
- if (TextUtils.isEmpty(fqdn)) {
+ if (TextUtils.isEmpty(mFqdn)) {
Log.d(TAG, "Missing FQDN");
return false;
}
- if (TextUtils.isEmpty(countries)) {
+ if (TextUtils.isEmpty(mCountries)) {
Log.d(TAG, "Missing countries");
return false;
}
@@ -205,10 +277,10 @@
@Override
public RoamingPartner createFromParcel(Parcel in) {
RoamingPartner roamingPartner = new RoamingPartner();
- roamingPartner.fqdn = in.readString();
- roamingPartner.fqdnExactMatch = in.readInt() != 0;
- roamingPartner.priority = in.readInt();
- roamingPartner.countries = in.readString();
+ roamingPartner.setFqdn(in.readString());
+ roamingPartner.setFqdnExactMatch(in.readInt() != 0);
+ roamingPartner.setPriority(in.readInt());
+ roamingPartner.setCountries(in.readString());
return roamingPartner;
}
@@ -218,12 +290,24 @@
}
};
}
- public List<RoamingPartner> preferredRoamingPartnerList = null;
+ private List<RoamingPartner> mPreferredRoamingPartnerList = null;
+ public void setPreferredRoamingPartnerList(List<RoamingPartner> partnerList) {
+ mPreferredRoamingPartnerList = partnerList;
+ }
+ public List<RoamingPartner> getPreferredRoamingPartnerList() {
+ return mPreferredRoamingPartnerList;
+ }
/**
* Meta data used for policy update.
*/
- public UpdateParameter policyUpdate = null;
+ private UpdateParameter mPolicyUpdate = null;
+ public void setPolicyUpdate(UpdateParameter policyUpdate) {
+ mPolicyUpdate = policyUpdate;
+ }
+ public UpdateParameter getPolicyUpdate() {
+ return mPolicyUpdate;
+ }
/**
* Constructor for creating Policy with default values.
@@ -239,24 +323,24 @@
if (source == null) {
return;
}
- minHomeDownlinkBandwidth = source.minHomeDownlinkBandwidth;
- minHomeUplinkBandwidth = source.minHomeUplinkBandwidth;
- minRoamingDownlinkBandwidth = source.minRoamingDownlinkBandwidth;
- minRoamingUplinkBandwidth = source.minRoamingUplinkBandwidth;
- maximumBssLoadValue = source.maximumBssLoadValue;
- if (source.excludedSsidList != null) {
- excludedSsidList = Arrays.copyOf(source.excludedSsidList,
- source.excludedSsidList.length);
+ mMinHomeDownlinkBandwidth = source.mMinHomeDownlinkBandwidth;
+ mMinHomeUplinkBandwidth = source.mMinHomeUplinkBandwidth;
+ mMinRoamingDownlinkBandwidth = source.mMinRoamingDownlinkBandwidth;
+ mMinRoamingUplinkBandwidth = source.mMinRoamingUplinkBandwidth;
+ mMaximumBssLoadValue = source.mMaximumBssLoadValue;
+ if (source.mExcludedSsidList != null) {
+ mExcludedSsidList = Arrays.copyOf(source.mExcludedSsidList,
+ source.mExcludedSsidList.length);
}
- if (source.requiredProtoPortMap != null) {
- requiredProtoPortMap = Collections.unmodifiableMap(source.requiredProtoPortMap);
+ if (source.mRequiredProtoPortMap != null) {
+ mRequiredProtoPortMap = Collections.unmodifiableMap(source.mRequiredProtoPortMap);
}
- if (source.preferredRoamingPartnerList != null) {
- preferredRoamingPartnerList = Collections.unmodifiableList(
- source.preferredRoamingPartnerList);
+ if (source.mPreferredRoamingPartnerList != null) {
+ mPreferredRoamingPartnerList = Collections.unmodifiableList(
+ source.mPreferredRoamingPartnerList);
}
- if (source.policyUpdate != null) {
- policyUpdate = new UpdateParameter(source.policyUpdate);
+ if (source.mPolicyUpdate != null) {
+ mPolicyUpdate = new UpdateParameter(source.mPolicyUpdate);
}
}
@@ -267,15 +351,15 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(minHomeDownlinkBandwidth);
- dest.writeLong(minHomeUplinkBandwidth);
- dest.writeLong(minRoamingDownlinkBandwidth);
- dest.writeLong(minRoamingUplinkBandwidth);
- dest.writeStringArray(excludedSsidList);
- writeProtoPortMap(dest, requiredProtoPortMap);
- dest.writeInt(maximumBssLoadValue);
- writeRoamingPartnerList(dest, flags, preferredRoamingPartnerList);
- dest.writeParcelable(policyUpdate, flags);
+ dest.writeLong(mMinHomeDownlinkBandwidth);
+ dest.writeLong(mMinHomeUplinkBandwidth);
+ dest.writeLong(mMinRoamingDownlinkBandwidth);
+ dest.writeLong(mMinRoamingUplinkBandwidth);
+ dest.writeStringArray(mExcludedSsidList);
+ writeProtoPortMap(dest, mRequiredProtoPortMap);
+ dest.writeInt(mMaximumBssLoadValue);
+ writeRoamingPartnerList(dest, flags, mPreferredRoamingPartnerList);
+ dest.writeParcelable(mPolicyUpdate, flags);
}
@Override
@@ -288,18 +372,27 @@
}
Policy that = (Policy) thatObject;
- return minHomeDownlinkBandwidth == that.minHomeDownlinkBandwidth
- && minHomeUplinkBandwidth == that.minHomeUplinkBandwidth
- && minRoamingDownlinkBandwidth == that.minRoamingDownlinkBandwidth
- && minRoamingUplinkBandwidth == that.minRoamingUplinkBandwidth
- && Arrays.equals(excludedSsidList, that.excludedSsidList)
- && (requiredProtoPortMap == null ? that.requiredProtoPortMap == null
- : requiredProtoPortMap.equals(that.requiredProtoPortMap))
- && maximumBssLoadValue == that.maximumBssLoadValue
- && (preferredRoamingPartnerList == null ? that.preferredRoamingPartnerList == null
- : preferredRoamingPartnerList.equals(that.preferredRoamingPartnerList))
- && (policyUpdate == null ? that.policyUpdate == null
- : policyUpdate.equals(that.policyUpdate));
+ return mMinHomeDownlinkBandwidth == that.mMinHomeDownlinkBandwidth
+ && mMinHomeUplinkBandwidth == that.mMinHomeUplinkBandwidth
+ && mMinRoamingDownlinkBandwidth == that.mMinRoamingDownlinkBandwidth
+ && mMinRoamingUplinkBandwidth == that.mMinRoamingUplinkBandwidth
+ && Arrays.equals(mExcludedSsidList, that.mExcludedSsidList)
+ && (mRequiredProtoPortMap == null ? that.mRequiredProtoPortMap == null
+ : mRequiredProtoPortMap.equals(that.mRequiredProtoPortMap))
+ && mMaximumBssLoadValue == that.mMaximumBssLoadValue
+ && (mPreferredRoamingPartnerList == null
+ ? that.mPreferredRoamingPartnerList == null
+ : mPreferredRoamingPartnerList.equals(that.mPreferredRoamingPartnerList))
+ && (mPolicyUpdate == null ? that.mPolicyUpdate == null
+ : mPolicyUpdate.equals(that.mPolicyUpdate));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mMinHomeDownlinkBandwidth, mMinHomeUplinkBandwidth,
+ mMinRoamingDownlinkBandwidth, mMinRoamingUplinkBandwidth, mExcludedSsidList,
+ mRequiredProtoPortMap, mMaximumBssLoadValue, mPreferredRoamingPartnerList,
+ mPolicyUpdate);
}
/**
@@ -308,22 +401,22 @@
* @return true on success
*/
public boolean validate() {
- if (policyUpdate == null) {
+ if (mPolicyUpdate == null) {
Log.d(TAG, "PolicyUpdate not specified");
return false;
}
- if (!policyUpdate.validate()) {
+ if (!mPolicyUpdate.validate()) {
return false;
}
// Validate SSID exclusion list.
- if (excludedSsidList != null) {
- if (excludedSsidList.length > MAX_EXCLUSION_SSIDS) {
+ if (mExcludedSsidList != null) {
+ if (mExcludedSsidList.length > MAX_EXCLUSION_SSIDS) {
Log.d(TAG, "SSID exclusion list size exceeded the max: "
- + excludedSsidList.length);
+ + mExcludedSsidList.length);
return false;
}
- for (String ssid : excludedSsidList) {
+ for (String ssid : mExcludedSsidList) {
if (ssid.getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
Log.d(TAG, "Invalid SSID: " + ssid);
return false;
@@ -331,8 +424,8 @@
}
}
// Validate required protocol to port map.
- if (requiredProtoPortMap != null) {
- for (Map.Entry<Integer, String> entry : requiredProtoPortMap.entrySet()) {
+ if (mRequiredProtoPortMap != null) {
+ for (Map.Entry<Integer, String> entry : mRequiredProtoPortMap.entrySet()) {
String portNumber = entry.getValue();
if (portNumber.getBytes(StandardCharsets.UTF_8).length > MAX_PORT_STRING_BYTES) {
Log.d(TAG, "PortNumber string bytes exceeded the max: " + portNumber);
@@ -341,8 +434,8 @@
}
}
// Validate preferred roaming partner list.
- if (preferredRoamingPartnerList != null) {
- for (RoamingPartner partner : preferredRoamingPartnerList) {
+ if (mPreferredRoamingPartnerList != null) {
+ for (RoamingPartner partner : mPreferredRoamingPartnerList) {
if (!partner.validate()) {
return false;
}
@@ -356,15 +449,15 @@
@Override
public Policy createFromParcel(Parcel in) {
Policy policy = new Policy();
- policy.minHomeDownlinkBandwidth = in.readLong();
- policy.minHomeUplinkBandwidth = in.readLong();
- policy.minRoamingDownlinkBandwidth = in.readLong();
- policy.minRoamingUplinkBandwidth = in.readLong();
- policy.excludedSsidList = in.createStringArray();
- policy.requiredProtoPortMap = readProtoPortMap(in);
- policy.maximumBssLoadValue = in.readInt();
- policy.preferredRoamingPartnerList = readRoamingPartnerList(in);
- policy.policyUpdate = in.readParcelable(null);
+ policy.setMinHomeDownlinkBandwidth(in.readLong());
+ policy.setMinHomeUplinkBandwidth(in.readLong());
+ policy.setMinRoamingDownlinkBandwidth(in.readLong());
+ policy.setMinRoamingUplinkBandwidth(in.readLong());
+ policy.setExcludedSsidList(in.createStringArray());
+ policy.setRequiredProtoPortMap(readProtoPortMap(in));
+ policy.setMaximumBssLoadValue(in.readInt());
+ policy.setPreferredRoamingPartnerList(readRoamingPartnerList(in));
+ policy.setPolicyUpdate(in.readParcelable(null));
return policy;
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
index a390df7..17fbf9f 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
@@ -24,6 +24,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Objects;
/**
* Class representing configuration parameters for subscription or policy update in
@@ -88,45 +89,93 @@
*
* Using Long.MIN_VALUE to indicate unset value.
*/
- public long updateIntervalInMinutes = Long.MIN_VALUE;
+ private long mUpdateIntervalInMinutes = Long.MIN_VALUE;
+ public void setUpdateIntervalInMinutes(long updateIntervalInMinutes) {
+ mUpdateIntervalInMinutes = updateIntervalInMinutes;
+ }
+ public long getUpdateIntervalInMinutes() {
+ return mUpdateIntervalInMinutes;
+ }
/**
* The method used to update the policy. Permitted values are "OMA-DM-ClientInitiated"
* and "SPP-ClientInitiated".
*/
- public String updateMethod = null;
+ private String mUpdateMethod = null;
+ public void setUpdateMethod(String updateMethod) {
+ mUpdateMethod = updateMethod;
+ }
+ public String getUpdateMethod() {
+ return mUpdateMethod;
+ }
/**
* This specifies the hotspots at which the subscription update is permitted. Permitted
* values are "HomeSP", "RoamingPartner", or "Unrestricted";
*/
- public String restriction = null;
+ private String mRestriction = null;
+ public void setRestriction(String restriction) {
+ mRestriction = restriction;
+ }
+ public String getRestriction() {
+ return mRestriction;
+ }
/**
* The URI of the update server.
*/
- public String serverUri = null;
+ private String mServerUri = null;
+ public void setServerUri(String serverUri) {
+ mServerUri = serverUri;
+ }
+ public String getServerUri() {
+ return mServerUri;
+ }
/**
* Username used to authenticate with the policy server.
*/
- public String username = null;
+ private String mUsername = null;
+ public void setUsername(String username) {
+ mUsername = username;
+ }
+ public String getUsername() {
+ return mUsername;
+ }
/**
* Base64 encoded password used to authenticate with the policy server.
*/
- public String base64EncodedPassword = null;
+ private String mBase64EncodedPassword = null;
+ public void setBase64EncodedPassword(String password) {
+ mBase64EncodedPassword = password;
+ }
+ public String getBase64EncodedPassword() {
+ return mBase64EncodedPassword;
+ }
/**
* HTTPS URL for retrieving certificate for trust root. The trust root is used to validate
* policy server's identity.
*/
- public String trustRootCertUrl = null;
+ private String mTrustRootCertUrl = null;
+ public void setTrustRootCertUrl(String trustRootCertUrl) {
+ mTrustRootCertUrl = trustRootCertUrl;
+ }
+ public String getTrustRootCertUrl() {
+ return mTrustRootCertUrl;
+ }
/**
* SHA-256 fingerprint of the certificate located at {@link #trustRootCertUrl}
*/
- public byte[] trustRootCertSha256Fingerprint = null;
+ private byte[] mTrustRootCertSha256Fingerprint = null;
+ public void setTrustRootCertSha256Fingerprint(byte[] fingerprint) {
+ mTrustRootCertSha256Fingerprint = fingerprint;
+ }
+ public byte[] getTrustRootCertSha256Fingerprint() {
+ return mTrustRootCertSha256Fingerprint;
+ }
/**
* Constructor for creating Policy with default values.
@@ -142,16 +191,16 @@
if (source == null) {
return;
}
- updateIntervalInMinutes = source.updateIntervalInMinutes;
- updateMethod = source.updateMethod;
- restriction = source.restriction;
- serverUri = source.serverUri;
- username = source.username;
- base64EncodedPassword = source.base64EncodedPassword;
- trustRootCertUrl = source.trustRootCertUrl;
- if (source.trustRootCertSha256Fingerprint != null) {
- trustRootCertSha256Fingerprint = Arrays.copyOf(source.trustRootCertSha256Fingerprint,
- source.trustRootCertSha256Fingerprint.length);
+ mUpdateIntervalInMinutes = source.mUpdateIntervalInMinutes;
+ mUpdateMethod = source.mUpdateMethod;
+ mRestriction = source.mRestriction;
+ mServerUri = source.mServerUri;
+ mUsername = source.mUsername;
+ mBase64EncodedPassword = source.mBase64EncodedPassword;
+ mTrustRootCertUrl = source.mTrustRootCertUrl;
+ if (source.mTrustRootCertSha256Fingerprint != null) {
+ mTrustRootCertSha256Fingerprint = Arrays.copyOf(source.mTrustRootCertSha256Fingerprint,
+ source.mTrustRootCertSha256Fingerprint.length);
}
}
@@ -162,14 +211,14 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(updateIntervalInMinutes);
- dest.writeString(updateMethod);
- dest.writeString(restriction);
- dest.writeString(serverUri);
- dest.writeString(username);
- dest.writeString(base64EncodedPassword);
- dest.writeString(trustRootCertUrl);
- dest.writeByteArray(trustRootCertSha256Fingerprint);
+ dest.writeLong(mUpdateIntervalInMinutes);
+ dest.writeString(mUpdateMethod);
+ dest.writeString(mRestriction);
+ dest.writeString(mServerUri);
+ dest.writeString(mUsername);
+ dest.writeString(mBase64EncodedPassword);
+ dest.writeString(mTrustRootCertUrl);
+ dest.writeByteArray(mTrustRootCertSha256Fingerprint);
}
@Override
@@ -182,15 +231,22 @@
}
UpdateParameter that = (UpdateParameter) thatObject;
- return updateIntervalInMinutes == that.updateIntervalInMinutes
- && TextUtils.equals(updateMethod, that.updateMethod)
- && TextUtils.equals(restriction, that.restriction)
- && TextUtils.equals(serverUri, that.serverUri)
- && TextUtils.equals(username, that.username)
- && TextUtils.equals(base64EncodedPassword, that.base64EncodedPassword)
- && TextUtils.equals(trustRootCertUrl, that.trustRootCertUrl)
- && Arrays.equals(trustRootCertSha256Fingerprint,
- that.trustRootCertSha256Fingerprint);
+ return mUpdateIntervalInMinutes == that.mUpdateIntervalInMinutes
+ && TextUtils.equals(mUpdateMethod, that.mUpdateMethod)
+ && TextUtils.equals(mRestriction, that.mRestriction)
+ && TextUtils.equals(mServerUri, that.mServerUri)
+ && TextUtils.equals(mUsername, that.mUsername)
+ && TextUtils.equals(mBase64EncodedPassword, that.mBase64EncodedPassword)
+ && TextUtils.equals(mTrustRootCertUrl, that.mTrustRootCertUrl)
+ && Arrays.equals(mTrustRootCertSha256Fingerprint,
+ that.mTrustRootCertSha256Fingerprint);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mUpdateIntervalInMinutes, mUpdateMethod, mRestriction, mServerUri,
+ mUsername, mBase64EncodedPassword, mTrustRootCertUrl,
+ mTrustRootCertSha256Fingerprint);
}
/**
@@ -199,81 +255,81 @@
* @return true on success
*/
public boolean validate() {
- if (updateIntervalInMinutes == Long.MIN_VALUE) {
+ if (mUpdateIntervalInMinutes == Long.MIN_VALUE) {
Log.d(TAG, "Update interval not specified");
return false;
}
// Update not applicable.
- if (updateIntervalInMinutes == UPDATE_CHECK_INTERVAL_NEVER) {
+ if (mUpdateIntervalInMinutes == UPDATE_CHECK_INTERVAL_NEVER) {
return true;
}
- if (!TextUtils.equals(updateMethod, UPDATE_METHOD_OMADM)
- && !TextUtils.equals(updateMethod, UPDATE_METHOD_SSP)) {
- Log.d(TAG, "Unknown update method: " + updateMethod);
+ if (!TextUtils.equals(mUpdateMethod, UPDATE_METHOD_OMADM)
+ && !TextUtils.equals(mUpdateMethod, UPDATE_METHOD_SSP)) {
+ Log.d(TAG, "Unknown update method: " + mUpdateMethod);
return false;
}
- if (!TextUtils.equals(restriction, UPDATE_RESTRICTION_HOMESP)
- && !TextUtils.equals(restriction, UPDATE_RESTRICTION_ROAMING_PARTNER)
- && !TextUtils.equals(restriction, UPDATE_RESTRICTION_UNRESTRICTED)) {
- Log.d(TAG, "Unknown restriction: " + restriction);
+ if (!TextUtils.equals(mRestriction, UPDATE_RESTRICTION_HOMESP)
+ && !TextUtils.equals(mRestriction, UPDATE_RESTRICTION_ROAMING_PARTNER)
+ && !TextUtils.equals(mRestriction, UPDATE_RESTRICTION_UNRESTRICTED)) {
+ Log.d(TAG, "Unknown restriction: " + mRestriction);
return false;
}
- if (TextUtils.isEmpty(serverUri)) {
+ if (TextUtils.isEmpty(mServerUri)) {
Log.d(TAG, "Missing update server URI");
return false;
}
- if (serverUri.getBytes(StandardCharsets.UTF_8).length > MAX_URI_BYTES) {
+ if (mServerUri.getBytes(StandardCharsets.UTF_8).length > MAX_URI_BYTES) {
Log.d(TAG, "URI bytes exceeded the max: "
- + serverUri.getBytes(StandardCharsets.UTF_8).length);
+ + mServerUri.getBytes(StandardCharsets.UTF_8).length);
return false;
}
- if (TextUtils.isEmpty(username)) {
+ if (TextUtils.isEmpty(mUsername)) {
Log.d(TAG, "Missing username");
return false;
}
- if (username.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
+ if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
Log.d(TAG, "Username bytes exceeded the max: "
- + username.getBytes(StandardCharsets.UTF_8).length);
+ + mUsername.getBytes(StandardCharsets.UTF_8).length);
return false;
}
- if (TextUtils.isEmpty(base64EncodedPassword)) {
+ if (TextUtils.isEmpty(mBase64EncodedPassword)) {
Log.d(TAG, "Missing username");
return false;
}
- if (base64EncodedPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
+ if (mBase64EncodedPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
Log.d(TAG, "Password bytes exceeded the max: "
- + base64EncodedPassword.getBytes(StandardCharsets.UTF_8).length);
+ + mBase64EncodedPassword.getBytes(StandardCharsets.UTF_8).length);
return false;
}
try {
- Base64.decode(base64EncodedPassword, Base64.DEFAULT);
+ Base64.decode(mBase64EncodedPassword, Base64.DEFAULT);
} catch (IllegalArgumentException e) {
- Log.d(TAG, "Invalid encoding for password: " + base64EncodedPassword);
+ Log.d(TAG, "Invalid encoding for password: " + mBase64EncodedPassword);
return false;
}
- if (TextUtils.isEmpty(trustRootCertUrl)) {
+ if (TextUtils.isEmpty(mTrustRootCertUrl)) {
Log.d(TAG, "Missing trust root certificate URL");
return false;
}
- if (trustRootCertUrl.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) {
+ if (mTrustRootCertUrl.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) {
Log.d(TAG, "Trust root cert URL bytes exceeded the max: "
- + trustRootCertUrl.getBytes(StandardCharsets.UTF_8).length);
+ + mTrustRootCertUrl.getBytes(StandardCharsets.UTF_8).length);
return false;
}
- if (trustRootCertSha256Fingerprint == null) {
+ if (mTrustRootCertSha256Fingerprint == null) {
Log.d(TAG, "Missing trust root certificate SHA-256 fingerprint");
return false;
}
- if (trustRootCertSha256Fingerprint.length != CERTIFICATE_SHA256_BYTES) {
+ if (mTrustRootCertSha256Fingerprint.length != CERTIFICATE_SHA256_BYTES) {
Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: "
- + trustRootCertSha256Fingerprint.length);
+ + mTrustRootCertSha256Fingerprint.length);
return false;
}
return true;
@@ -284,14 +340,14 @@
@Override
public UpdateParameter createFromParcel(Parcel in) {
UpdateParameter updateParam = new UpdateParameter();
- updateParam.updateIntervalInMinutes = in.readLong();
- updateParam.updateMethod = in.readString();
- updateParam.restriction = in.readString();
- updateParam.serverUri = in.readString();
- updateParam.username = in.readString();
- updateParam.base64EncodedPassword = in.readString();
- updateParam.trustRootCertUrl = in.readString();
- updateParam.trustRootCertSha256Fingerprint = in.createByteArray();
+ updateParam.setUpdateIntervalInMinutes(in.readLong());
+ updateParam.setUpdateMethod(in.readString());
+ updateParam.setRestriction(in.readString());
+ updateParam.setServerUri(in.readString());
+ updateParam.setUsername(in.readString());
+ updateParam.setBase64EncodedPassword(in.readString());
+ updateParam.setTrustRootCertUrl(in.readString());
+ updateParam.setTrustRootCertSha256Fingerprint(in.createByteArray());
return updateParam;
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java
index 6095929..f7dbf7e 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java
@@ -83,27 +83,33 @@
PasspointConfiguration config = new PasspointConfiguration();
// HomeSP configuration.
- config.homeSp = new HomeSP();
- config.homeSp.friendlyName = "Century House";
- config.homeSp.fqdn = "mi6.co.uk";
- config.homeSp.roamingConsortiumOIs = new long[] {0x112233L, 0x445566L};
+ HomeSP homeSp = new HomeSP();
+ homeSp.setFriendlyName("Century House");
+ homeSp.setFqdn("mi6.co.uk");
+ homeSp.setRoamingConsortiumOIs(new long[] {0x112233L, 0x445566L});
+ config.setHomeSp(homeSp);
// Credential configuration.
- config.credential = new Credential();
- config.credential.realm = "shaken.stirred.com";
- config.credential.userCredential = new Credential.UserCredential();
- config.credential.userCredential.username = "james";
- config.credential.userCredential.password = "Ym9uZDAwNw==";
- config.credential.userCredential.eapType = 21;
- config.credential.userCredential.nonEapInnerMethod = "MS-CHAP-V2";
- config.credential.certCredential = new Credential.CertificateCredential();
- config.credential.certCredential.certType = "x509v3";
- config.credential.certCredential.certSha256FingerPrint = new byte[32];
- Arrays.fill(config.credential.certCredential.certSha256FingerPrint, (byte)0x1f);
- config.credential.simCredential = new Credential.SimCredential();
- config.credential.simCredential.imsi = "imsi";
- config.credential.simCredential.eapType = 24;
- config.credential.caCertificate = FakeKeys.CA_CERT0;
+ Credential credential = new Credential();
+ credential.setRealm("shaken.stirred.com");
+ Credential.UserCredential userCredential = new Credential.UserCredential();
+ userCredential.setUsername("james");
+ userCredential.setPassword("Ym9uZDAwNw==");
+ userCredential.setEapType(21);
+ userCredential.setNonEapInnerMethod("MS-CHAP-V2");
+ credential.setUserCredential(userCredential);
+ Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
+ certCredential.setCertType("x509v3");
+ byte[] certSha256Fingerprint = new byte[32];
+ Arrays.fill(certSha256Fingerprint, (byte)0x1f);
+ certCredential.setCertSha256Fingerprint(certSha256Fingerprint);
+ credential.setCertCredential(certCredential);
+ Credential.SimCredential simCredential = new Credential.SimCredential();
+ simCredential.setImsi("imsi");
+ simCredential.setEapType(24);
+ credential.setSimCredential(simCredential);
+ credential.setCaCertificate(FakeKeys.CA_CERT0);
+ config.setCredential(credential);
return config;
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index 1eb08e0..3aed918 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -34,6 +34,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* Unit tests for {@link android.net.wifi.hotspot2.PasspointConfiguration}.
@@ -50,9 +52,9 @@
*/
private static HomeSP createHomeSp() {
HomeSP homeSp = new HomeSP();
- homeSp.fqdn = "fqdn";
- homeSp.friendlyName = "friendly name";
- homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66};
+ homeSp.setFqdn("fqdn");
+ homeSp.setFriendlyName("friendly name");
+ homeSp.setRoamingConsortiumOIs(new long[] {0x55, 0x66});
return homeSp;
}
@@ -63,15 +65,15 @@
*/
private static Credential createCredential() {
Credential cred = new Credential();
- cred.realm = "realm";
- cred.userCredential = null;
- cred.certCredential = null;
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.imsi = "1234*";
- cred.simCredential.eapType = EAPConstants.EAP_SIM;
- cred.caCertificate = null;
- cred.clientCertificateChain = null;
- cred.clientPrivateKey = null;
+ cred.setRealm("realm");
+ cred.setUserCredential(null);
+ cred.setCertCredential(null);
+ cred.setSimCredential(new Credential.SimCredential());
+ cred.getSimCredential().setImsi("1234*");
+ cred.getSimCredential().setEapType(EAPConstants.EAP_SIM);
+ cred.setCaCertificate(null);
+ cred.setClientCertificateChain(null);
+ cred.setClientPrivateKey(null);
return cred;
}
@@ -82,56 +84,59 @@
*/
private static Policy createPolicy() {
Policy policy = new Policy();
- policy.minHomeDownlinkBandwidth = 123;
- policy.minHomeUplinkBandwidth = 345;
- policy.minRoamingDownlinkBandwidth = 567;
- policy.minRoamingUplinkBandwidth = 789;
- policy.maximumBssLoadValue = 12;
- policy.excludedSsidList = new String[] {"ssid1", "ssid2"};
- policy.requiredProtoPortMap = new HashMap<>();
- policy.requiredProtoPortMap.put(12, "23,342,123");
- policy.requiredProtoPortMap.put(23, "789,372,1235");
+ policy.setMinHomeDownlinkBandwidth(123);
+ policy.setMinHomeUplinkBandwidth(345);
+ policy.setMinRoamingDownlinkBandwidth(567);
+ policy.setMinRoamingUplinkBandwidth(789);
+ policy.setMaximumBssLoadValue(12);
+ policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
+ HashMap<Integer, String> requiredProtoPortMap = new HashMap<>();
+ requiredProtoPortMap.put(12, "23,342,123");
+ requiredProtoPortMap.put(23, "789,372,1235");
+ policy.setRequiredProtoPortMap(requiredProtoPortMap);
- policy.preferredRoamingPartnerList = new ArrayList<>();
+ List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
- partner1.fqdn = "partner1.com";
- partner1.fqdnExactMatch = true;
- partner1.priority = 12;
- partner1.countries = "us,jp";
+ partner1.setFqdn("partner1.com");
+ partner1.setFqdnExactMatch(true);
+ partner1.setPriority(12);
+ partner1.setCountries("us,jp");
Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
- partner2.fqdn = "partner2.com";
- partner2.fqdnExactMatch = false;
- partner2.priority = 42;
- partner2.countries = "ca,fr";
- policy.preferredRoamingPartnerList.add(partner1);
- policy.preferredRoamingPartnerList.add(partner2);
+ partner2.setFqdn("partner2.com");
+ partner2.setFqdnExactMatch(false);
+ partner2.setPriority(42);
+ partner2.setCountries("ca,fr");
+ preferredRoamingPartnerList.add(partner1);
+ preferredRoamingPartnerList.add(partner2);
+ policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
- policy.policyUpdate = new UpdateParameter();
- policy.policyUpdate.updateIntervalInMinutes = 1712;
- policy.policyUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_OMADM;
- policy.policyUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_HOMESP;
- policy.policyUpdate.serverUri = "policy.update.com";
- policy.policyUpdate.username = "username";
- policy.policyUpdate.base64EncodedPassword =
- Base64.encodeToString("password".getBytes(), Base64.DEFAULT);
- policy.policyUpdate.trustRootCertUrl = "trust.cert.com";
- policy.policyUpdate.trustRootCertSha256Fingerprint =
- new byte[CERTIFICATE_FINGERPRINT_BYTES];
+ UpdateParameter policyUpdate = new UpdateParameter();
+ policyUpdate.setUpdateIntervalInMinutes(1712);
+ policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
+ policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
+ policyUpdate.setServerUri("policy.update.com");
+ policyUpdate.setUsername("username");
+ policyUpdate.setBase64EncodedPassword(
+ Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
+ policyUpdate.setTrustRootCertUrl("trust.cert.com");
+ policyUpdate.setTrustRootCertSha256Fingerprint(
+ new byte[CERTIFICATE_FINGERPRINT_BYTES]);
+ policy.setPolicyUpdate(policyUpdate);
return policy;
}
private static UpdateParameter createSubscriptionUpdate() {
UpdateParameter subUpdate = new UpdateParameter();
- subUpdate.updateIntervalInMinutes = 9021;
- subUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP;
- subUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER;
- subUpdate.serverUri = "subscription.update.com";
- subUpdate.username = "subUsername";
- subUpdate.base64EncodedPassword =
- Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT);
- subUpdate.trustRootCertUrl = "subscription.trust.cert.com";
- subUpdate.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_FINGERPRINT_BYTES];
+ subUpdate.setUpdateIntervalInMinutes(9021);
+ subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
+ subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
+ subUpdate.setServerUri("subscription.update.com");
+ subUpdate.setUsername("subUsername");
+ subUpdate.setBase64EncodedPassword(
+ Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT));
+ subUpdate.setTrustRootCertUrl("subscription.trust.cert.com");
+ subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]);
return subUpdate;
}
/**
@@ -141,24 +146,25 @@
*/
private static PasspointConfiguration createConfig() {
PasspointConfiguration config = new PasspointConfiguration();
- config.homeSp = createHomeSp();
- config.credential = createCredential();
- config.policy = createPolicy();
- config.subscriptionUpdate = createSubscriptionUpdate();
- config.trustRootCertList = new HashMap<>();
- config.trustRootCertList.put("trustRoot.cert1.com",
+ config.setHomeSp(createHomeSp());
+ config.setCredential(createCredential());
+ config.setPolicy(createPolicy());
+ config.setSubscriptionUpdate(createSubscriptionUpdate());
+ Map<String, byte[]> trustRootCertList = new HashMap<>();
+ trustRootCertList.put("trustRoot.cert1.com",
new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- config.trustRootCertList.put("trustRoot.cert2.com",
+ trustRootCertList.put("trustRoot.cert2.com",
new byte[CERTIFICATE_FINGERPRINT_BYTES]);
- config.updateIdentifier = 1;
- config.credentialPriority = 120;
- config.subscriptionCreationTimeInMs = 231200;
- config.subscriptionExpirationTimeInMs = 2134232;
- config.subscriptionType = "Gold";
- config.usageLimitUsageTimePeriodInMinutes = 3600;
- config.usageLimitStartTimeInMs = 124214213;
- config.usageLimitDataLimit = 14121;
- config.usageLimitTimeLimitInMinutes = 78912;
+ config.setTrustRootCertList(trustRootCertList);
+ config.setUpdateIdentifier(1);
+ config.setCredentialPriority(120);
+ config.setSubscriptionCreationTimeInMs(231200);
+ config.setSubscriptionExpirationTimeInMs(2134232);
+ config.setSubscriptionType("Gold");
+ config.setUsageLimitUsageTimePeriodInMinutes(3600);
+ config.setUsageLimitStartTimeInMs(124214213);
+ config.setUsageLimitDataLimit(14121);
+ config.setUsageLimitTimeLimitInMinutes(78912);
return config;
}
@@ -206,7 +212,7 @@
@Test
public void verifyParcelWithoutHomeSP() throws Exception {
PasspointConfiguration config = createConfig();
- config.homeSp = null;
+ config.setHomeSp(null);
verifyParcel(config);
}
@@ -218,7 +224,7 @@
@Test
public void verifyParcelWithoutCredential() throws Exception {
PasspointConfiguration config = createConfig();
- config.credential = null;
+ config.setCredential(null);
verifyParcel(config);
}
@@ -230,7 +236,7 @@
@Test
public void verifyParcelWithoutPolicy() throws Exception {
PasspointConfiguration config = createConfig();
- config.policy = null;
+ config.setPolicy(null);
verifyParcel(config);
}
@@ -242,7 +248,7 @@
@Test
public void verifyParcelWithoutSubscriptionUpdate() throws Exception {
PasspointConfiguration config = createConfig();
- config.subscriptionUpdate = null;
+ config.setSubscriptionUpdate(null);
verifyParcel(config);
}
@@ -255,7 +261,7 @@
@Test
public void verifyParcelWithoutTrustRootCertList() throws Exception {
PasspointConfiguration config = createConfig();
- config.trustRootCertList = null;
+ config.setTrustRootCertList(null);
verifyParcel(config);
}
@@ -289,7 +295,7 @@
@Test
public void validateConfigWithoutCredential() throws Exception {
PasspointConfiguration config = createConfig();
- config.credential = null;
+ config.setCredential(null);
assertFalse(config.validate());
}
@@ -301,7 +307,7 @@
@Test
public void validateConfigWithoutHomeSp() throws Exception {
PasspointConfiguration config = createConfig();
- config.homeSp = null;
+ config.setHomeSp(null);
assertFalse(config.validate());
}
@@ -314,7 +320,7 @@
@Test
public void validateConfigWithoutPolicy() throws Exception {
PasspointConfiguration config = createConfig();
- config.policy = null;
+ config.setPolicy(null);
assertTrue(config.validate());
}
@@ -327,7 +333,7 @@
@Test
public void validateConfigWithoutSubscriptionUpdate() throws Exception {
PasspointConfiguration config = createConfig();
- config.subscriptionUpdate = null;
+ config.setSubscriptionUpdate(null);
assertTrue(config.validate());
}
@@ -341,13 +347,16 @@
public void validateConfigWithInvalidTrustRootCertUrl() throws Exception {
PasspointConfiguration config = createConfig();
byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
+ Map<String, byte[]> trustRootCertList = new HashMap<>();
Arrays.fill(rawUrlBytes, (byte) 'a');
- config.trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8),
+ trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8),
new byte[CERTIFICATE_FINGERPRINT_BYTES]);
+ config.setTrustRootCertList(trustRootCertList);
assertFalse(config.validate());
- config.trustRootCertList = new HashMap<>();
- config.trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]);
+ trustRootCertList = new HashMap<>();
+ trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]);
+ config.setTrustRootCertList(trustRootCertList);
assertFalse(config.validate());
}
@@ -359,16 +368,19 @@
@Test
public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception {
PasspointConfiguration config = createConfig();
- config.trustRootCertList = new HashMap<>();
- config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]);
+ Map<String, byte[]> trustRootCertList = new HashMap<>();
+ trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]);
+ config.setTrustRootCertList(trustRootCertList);
assertFalse(config.validate());
- config.trustRootCertList = new HashMap<>();
- config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]);
+ trustRootCertList = new HashMap<>();
+ trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]);
+ config.setTrustRootCertList(trustRootCertList);
assertFalse(config.validate());
- config.trustRootCertList = new HashMap<>();
- config.trustRootCertList.put("test.cert.com", null);
+ trustRootCertList = new HashMap<>();
+ trustRootCertList.put("test.cert.com", null);
+ config.setTrustRootCertList(trustRootCertList);
assertFalse(config.validate());
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
index 055204c..15de5c7 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
@@ -39,6 +39,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* Unit tests for {@link android.net.wifi.hotspot2.omadm.PPSMOParser}.
@@ -86,107 +88,115 @@
*/
private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-
- PasspointConfiguration config = new PasspointConfiguration();
- config.updateIdentifier = 12;
- config.credentialPriority = 99;
-
- // AAA Server trust root.
- config.trustRootCertList = new HashMap<>();
byte[] certFingerprint = new byte[32];
Arrays.fill(certFingerprint, (byte) 0x1f);
- config.trustRootCertList.put("server1.trust.root.com", certFingerprint);
+
+ PasspointConfiguration config = new PasspointConfiguration();
+ config.setUpdateIdentifier(12);
+ config.setCredentialPriority(99);
+
+ // AAA Server trust root.
+ Map<String, byte[]> trustRootCertList = new HashMap<>();
+ trustRootCertList.put("server1.trust.root.com", certFingerprint);
+ config.setTrustRootCertList(trustRootCertList);
// Subscription update.
- config.subscriptionUpdate = new UpdateParameter();
- config.subscriptionUpdate.updateIntervalInMinutes = 120;
- config.subscriptionUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP;
- config.subscriptionUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER;
- config.subscriptionUpdate.serverUri = "subscription.update.com";
- config.subscriptionUpdate.username = "subscriptionUser";
- config.subscriptionUpdate.base64EncodedPassword = "subscriptionPass";
- config.subscriptionUpdate.trustRootCertUrl = "subscription.update.cert.com";
- config.subscriptionUpdate.trustRootCertSha256Fingerprint = new byte[32];
- Arrays.fill(config.subscriptionUpdate.trustRootCertSha256Fingerprint, (byte) 0x1f);
+ UpdateParameter subscriptionUpdate = new UpdateParameter();
+ subscriptionUpdate.setUpdateIntervalInMinutes(120);
+ subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
+ subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
+ subscriptionUpdate.setServerUri("subscription.update.com");
+ subscriptionUpdate.setUsername("subscriptionUser");
+ subscriptionUpdate.setBase64EncodedPassword("subscriptionPass");
+ subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com");
+ subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
+ config.setSubscriptionUpdate(subscriptionUpdate);
// Subscription parameters.
- config.subscriptionCreationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime();
- config.subscriptionExpirationTimeInMs = format.parse("2016-03-01T10:00:00Z").getTime();
- config.subscriptionType = "Gold";
- config.usageLimitDataLimit = 921890;
- config.usageLimitStartTimeInMs = format.parse("2016-12-01T10:00:00Z").getTime();
- config.usageLimitTimeLimitInMinutes = 120;
- config.usageLimitUsageTimePeriodInMinutes = 99910;
+ config.setSubscriptionCreationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime());
+ config.setSubscriptionExpirationTimeInMs(format.parse("2016-03-01T10:00:00Z").getTime());
+ config.setSubscriptionType("Gold");
+ config.setUsageLimitDataLimit(921890);
+ config.setUsageLimitStartTimeInMs(format.parse("2016-12-01T10:00:00Z").getTime());
+ config.setUsageLimitTimeLimitInMinutes(120);
+ config.setUsageLimitUsageTimePeriodInMinutes(99910);
// HomeSP configuration.
- config.homeSp = new HomeSP();
- config.homeSp.friendlyName = "Century House";
- config.homeSp.fqdn = "mi6.co.uk";
- config.homeSp.roamingConsortiumOIs = new long[] {0x112233L, 0x445566L};
- config.homeSp.iconUrl = "icon.test.com";
- config.homeSp.homeNetworkIds = new HashMap<>();
- config.homeSp.homeNetworkIds.put("TestSSID", 0x12345678L);
- config.homeSp.homeNetworkIds.put("NullHESSID", null);
- config.homeSp.matchAllOIs = new long[] {0x11223344};
- config.homeSp.matchAnyOIs = new long[] {0x55667788};
- config.homeSp.otherHomePartners = new String[] {"other.fqdn.com"};
+ HomeSP homeSp = new HomeSP();
+ homeSp.setFriendlyName("Century House");
+ homeSp.setFqdn("mi6.co.uk");
+ homeSp.setRoamingConsortiumOIs(new long[] {0x112233L, 0x445566L});
+ homeSp.setIconUrl("icon.test.com");
+ Map<String, Long> homeNetworkIds = new HashMap<>();
+ homeNetworkIds.put("TestSSID", 0x12345678L);
+ homeNetworkIds.put("NullHESSID", null);
+ homeSp.setHomeNetworkIds(homeNetworkIds);
+ homeSp.setMatchAllOIs(new long[] {0x11223344});
+ homeSp.setMatchAnyOIs(new long[] {0x55667788});
+ homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"});
+ config.setHomeSp(homeSp);
// Credential configuration.
- config.credential = new Credential();
- config.credential.creationTimeInMs = format.parse("2016-01-01T10:00:00Z").getTime();
- config.credential.expirationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime();
- config.credential.realm = "shaken.stirred.com";
- config.credential.checkAAAServerCertStatus = true;
- config.credential.userCredential = new Credential.UserCredential();
- config.credential.userCredential.username = "james";
- config.credential.userCredential.password = "Ym9uZDAwNw==";
- config.credential.userCredential.machineManaged = true;
- config.credential.userCredential.softTokenApp = "TestApp";
- config.credential.userCredential.ableToShare = true;
- config.credential.userCredential.eapType = 21;
- config.credential.userCredential.nonEapInnerMethod = "MS-CHAP-V2";
- config.credential.certCredential = new Credential.CertificateCredential();
- config.credential.certCredential.certType = "x509v3";
- config.credential.certCredential.certSha256FingerPrint = new byte[32];
- Arrays.fill(config.credential.certCredential.certSha256FingerPrint, (byte)0x1f);
- config.credential.simCredential = new Credential.SimCredential();
- config.credential.simCredential.imsi = "imsi";
- config.credential.simCredential.eapType = 24;
+ Credential credential = new Credential();
+ credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime());
+ credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime());
+ credential.setRealm("shaken.stirred.com");
+ credential.setCheckAAAServerCertStatus(true);
+ Credential.UserCredential userCredential = new Credential.UserCredential();
+ userCredential.setUsername("james");
+ userCredential.setPassword("Ym9uZDAwNw==");
+ userCredential.setMachineManaged(true);
+ userCredential.setSoftTokenApp("TestApp");
+ userCredential.setAbleToShare(true);
+ userCredential.setEapType(21);
+ userCredential.setNonEapInnerMethod("MS-CHAP-V2");
+ credential.setUserCredential(userCredential);
+ Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
+ certCredential.setCertType("x509v3");
+ certCredential.setCertSha256Fingerprint(certFingerprint);
+ credential.setCertCredential(certCredential);
+ Credential.SimCredential simCredential = new Credential.SimCredential();
+ simCredential.setImsi("imsi");
+ simCredential.setEapType(24);
+ credential.setSimCredential(simCredential);
+ config.setCredential(credential);
// Policy configuration.
- config.policy = new Policy();
- config.policy.preferredRoamingPartnerList = new ArrayList<>();
+ Policy policy = new Policy();
+ List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
- partner1.fqdn = "test1.fqdn.com";
- partner1.fqdnExactMatch = true;
- partner1.priority = 127;
- partner1.countries = "us,fr";
+ partner1.setFqdn("test1.fqdn.com");
+ partner1.setFqdnExactMatch(true);
+ partner1.setPriority(127);
+ partner1.setCountries("us,fr");
Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
- partner2.fqdn = "test2.fqdn.com";
- partner2.fqdnExactMatch = false;
- partner2.priority = 200;
- partner2.countries = "*";
- config.policy.preferredRoamingPartnerList.add(partner1);
- config.policy.preferredRoamingPartnerList.add(partner2);
- config.policy.minHomeDownlinkBandwidth = 23412;
- config.policy.minHomeUplinkBandwidth = 9823;
- config.policy.minRoamingDownlinkBandwidth = 9271;
- config.policy.minRoamingUplinkBandwidth = 2315;
- config.policy.excludedSsidList = new String[] {"excludeSSID"};
- config.policy.requiredProtoPortMap = new HashMap<>();
- config.policy.requiredProtoPortMap.put(12, "34,92,234");
- config.policy.maximumBssLoadValue = 23;
- config.policy.policyUpdate = new UpdateParameter();
- config.policy.policyUpdate.updateIntervalInMinutes = 120;
- config.policy.policyUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_OMADM;
- config.policy.policyUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_HOMESP;
- config.policy.policyUpdate.serverUri = "policy.update.com";
- config.policy.policyUpdate.username = "updateUser";
- config.policy.policyUpdate.base64EncodedPassword = "updatePass";
- config.policy.policyUpdate.trustRootCertUrl = "update.cert.com";
- config.policy.policyUpdate.trustRootCertSha256Fingerprint = new byte[32];
- Arrays.fill(config.policy.policyUpdate.trustRootCertSha256Fingerprint, (byte) 0x1f);
-
+ partner2.setFqdn("test2.fqdn.com");
+ partner2.setFqdnExactMatch(false);
+ partner2.setPriority(200);
+ partner2.setCountries("*");
+ preferredRoamingPartnerList.add(partner1);
+ preferredRoamingPartnerList.add(partner2);
+ policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
+ policy.setMinHomeDownlinkBandwidth(23412);
+ policy.setMinHomeUplinkBandwidth(9823);
+ policy.setMinRoamingDownlinkBandwidth(9271);
+ policy.setMinRoamingUplinkBandwidth(2315);
+ policy.setExcludedSsidList(new String[] {"excludeSSID"});
+ Map<Integer, String> requiredProtoPortMap = new HashMap<>();
+ requiredProtoPortMap.put(12, "34,92,234");
+ policy.setRequiredProtoPortMap(requiredProtoPortMap);
+ policy.setMaximumBssLoadValue(23);
+ UpdateParameter policyUpdate = new UpdateParameter();
+ policyUpdate.setUpdateIntervalInMinutes(120);
+ policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
+ policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
+ policyUpdate.setServerUri("policy.update.com");
+ policyUpdate.setUsername("updateUser");
+ policyUpdate.setBase64EncodedPassword("updatePass");
+ policyUpdate.setTrustRootCertUrl("update.cert.com");
+ policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
+ policy.setPolicyUpdate(policyUpdate);
+ config.setPolicy(policy);
return config;
}
@@ -249,10 +259,3 @@
loadResourceFile(PPS_MO_XML_FILE_INVALID_NAME)));
}
}
-
-
-
-
-
-
-
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index f571c7fc..6f68e1c 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -23,10 +23,11 @@
import android.net.wifi.FakeKeys;
import android.os.Parcel;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
@@ -55,16 +56,16 @@
X509Certificate[] clientCertificateChain,
PrivateKey clientPrivateKey) {
Credential cred = new Credential();
- cred.creationTimeInMs = 123455L;
- cred.expirationTimeInMs = 2310093L;
- cred.realm = "realm";
- cred.checkAAAServerCertStatus = true;
- cred.userCredential = userCred;
- cred.certCredential = certCred;
- cred.simCredential = simCred;
- cred.caCertificate = caCert;
- cred.clientCertificateChain = clientCertificateChain;
- cred.clientPrivateKey = clientPrivateKey;
+ cred.setCreationTimeInMs(123455L);
+ cred.setExpirationTimeInMs(2310093L);
+ cred.setRealm("realm");
+ cred.setCheckAAAServerCertStatus(true);
+ cred.setUserCredential(userCred);
+ cred.setCertCredential(certCred);
+ cred.setSimCredential(simCred);
+ cred.setCaCertificate(caCert);
+ cred.setClientCertificateChain(clientCertificateChain);
+ cred.setClientPrivateKey(clientPrivateKey);
return cred;
}
@@ -73,10 +74,12 @@
*
* @return {@link Credential}
*/
- private static Credential createCredentialWithCertificateCredential() {
+ private static Credential createCredentialWithCertificateCredential()
+ throws NoSuchAlgorithmException, CertificateEncodingException {
Credential.CertificateCredential certCred = new Credential.CertificateCredential();
- certCred.certType = "x509v3";
- certCred.certSha256FingerPrint = new byte[32];
+ certCred.setCertType("x509v3");
+ certCred.setCertSha256Fingerprint(
+ MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
return createCredential(null, certCred, null, FakeKeys.CA_CERT0,
new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1);
}
@@ -88,8 +91,8 @@
*/
private static Credential createCredentialWithSimCredential() {
Credential.SimCredential simCred = new Credential.SimCredential();
- simCred.imsi = "1234*";
- simCred.eapType = EAPConstants.EAP_SIM;
+ simCred.setImsi("1234*");
+ simCred.setEapType(EAPConstants.EAP_SIM);
return createCredential(null, null, simCred, null, null, null);
}
@@ -100,15 +103,14 @@
*/
private static Credential createCredentialWithUserCredential() {
Credential.UserCredential userCred = new Credential.UserCredential();
- userCred.username = "username";
- userCred.password = "password";
- userCred.machineManaged = true;
- userCred.ableToShare = true;
- userCred.softTokenApp = "TestApp";
- userCred.eapType = EAPConstants.EAP_TTLS;
- userCred.nonEapInnerMethod = "MS-CHAP";
- return createCredential(userCred, null, null, FakeKeys.CA_CERT0,
- new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1);
+ userCred.setUsername("username");
+ userCred.setPassword("password");
+ userCred.setMachineManaged(true);
+ userCred.setAbleToShare(true);
+ userCred.setSoftTokenApp("TestApp");
+ userCred.setEapType(EAPConstants.EAP_TTLS);
+ userCred.setNonEapInnerMethod("MS-CHAP");
+ return createCredential(userCred, null, null, FakeKeys.CA_CERT0, null, null);
}
private static void verifyParcel(Credential writeCred) {
@@ -166,14 +168,7 @@
*/
@Test
public void validateUserCredential() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.username = "username";
- cred.userCredential.password = "password";
- cred.userCredential.eapType = EAPConstants.EAP_TTLS;
- cred.userCredential.nonEapInnerMethod = "MS-CHAP";
- cred.caCertificate = FakeKeys.CA_CERT0;
+ Credential cred = createCredentialWithUserCredential();
assertTrue(cred.validate());
}
@@ -184,13 +179,8 @@
*/
@Test
public void validateUserCredentialWithoutCaCert() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.username = "username";
- cred.userCredential.password = "password";
- cred.userCredential.eapType = EAPConstants.EAP_TTLS;
- cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+ Credential cred = createCredentialWithUserCredential();
+ cred.setCaCertificate(null);
assertFalse(cred.validate());
}
@@ -201,14 +191,8 @@
*/
@Test
public void validateUserCredentialWithEapTls() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.username = "username";
- cred.userCredential.password = "password";
- cred.userCredential.eapType = EAPConstants.EAP_TLS;
- cred.userCredential.nonEapInnerMethod = "MS-CHAP";
- cred.caCertificate = FakeKeys.CA_CERT0;
+ Credential cred = createCredentialWithUserCredential();
+ cred.getUserCredential().setEapType(EAPConstants.EAP_TLS);
assertFalse(cred.validate());
}
@@ -220,13 +204,8 @@
*/
@Test
public void validateUserCredentialWithoutRealm() throws Exception {
- Credential cred = new Credential();
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.username = "username";
- cred.userCredential.password = "password";
- cred.userCredential.eapType = EAPConstants.EAP_TTLS;
- cred.userCredential.nonEapInnerMethod = "MS-CHAP";
- cred.caCertificate = FakeKeys.CA_CERT0;
+ Credential cred = createCredentialWithUserCredential();
+ cred.setRealm(null);
assertFalse(cred.validate());
}
@@ -237,13 +216,8 @@
*/
@Test
public void validateUserCredentialWithoutUsername() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.password = "password";
- cred.userCredential.eapType = EAPConstants.EAP_TTLS;
- cred.userCredential.nonEapInnerMethod = "MS-CHAP";
- cred.caCertificate = FakeKeys.CA_CERT0;
+ Credential cred = createCredentialWithUserCredential();
+ cred.getUserCredential().setUsername(null);
assertFalse(cred.validate());
}
@@ -254,13 +228,8 @@
*/
@Test
public void validateUserCredentialWithoutPassword() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.username = "username";
- cred.userCredential.eapType = EAPConstants.EAP_TTLS;
- cred.userCredential.nonEapInnerMethod = "MS-CHAP";
- cred.caCertificate = FakeKeys.CA_CERT0;
+ Credential cred = createCredentialWithUserCredential();
+ cred.getUserCredential().setPassword(null);
assertFalse(cred.validate());
}
@@ -271,13 +240,8 @@
*/
@Test
public void validateUserCredentialWithoutAuthMethod() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.username = "username";
- cred.userCredential.password = "password";
- cred.userCredential.eapType = EAPConstants.EAP_TTLS;
- cred.caCertificate = FakeKeys.CA_CERT0;
+ Credential cred = createCredentialWithUserCredential();
+ cred.getUserCredential().setNonEapInnerMethod(null);
assertFalse(cred.validate());
}
@@ -290,17 +254,7 @@
*/
@Test
public void validateCertCredential() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup certificate credential.
- cred.certCredential = new Credential.CertificateCredential();
- cred.certCredential.certType = "x509v3";
- cred.certCredential.certSha256FingerPrint =
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
- // Setup certificates and private key.
- cred.caCertificate = FakeKeys.CA_CERT0;
- cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
- cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+ Credential cred = createCredentialWithCertificateCredential();
assertTrue(cred.validate());
}
@@ -310,16 +264,8 @@
* @throws Exception
*/
public void validateCertCredentialWithoutCaCert() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup certificate credential.
- cred.certCredential = new Credential.CertificateCredential();
- cred.certCredential.certType = "x509v3";
- cred.certCredential.certSha256FingerPrint =
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
- // Setup certificates and private key.
- cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
- cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+ Credential cred = createCredentialWithCertificateCredential();
+ cred.setCaCertificate(null);
assertFalse(cred.validate());
}
@@ -330,16 +276,8 @@
*/
@Test
public void validateCertCredentialWithoutClientCertChain() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup certificate credential.
- cred.certCredential = new Credential.CertificateCredential();
- cred.certCredential.certType = "x509v3";
- cred.certCredential.certSha256FingerPrint =
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
- // Setup certificates and private key.
- cred.caCertificate = FakeKeys.CA_CERT0;
- cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+ Credential cred = createCredentialWithCertificateCredential();
+ cred.setClientCertificateChain(null);
assertFalse(cred.validate());
}
@@ -350,16 +288,8 @@
*/
@Test
public void validateCertCredentialWithoutClientPrivateKey() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup certificate credential.
- cred.certCredential = new Credential.CertificateCredential();
- cred.certCredential.certType = "x509v3";
- cred.certCredential.certSha256FingerPrint =
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
- // Setup certificates and private key.
- cred.caCertificate = FakeKeys.CA_CERT0;
- cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
+ Credential cred = createCredentialWithCertificateCredential();
+ cred.setClientPrivateKey(null);
assertFalse(cred.validate());
}
@@ -371,17 +301,8 @@
*/
@Test
public void validateCertCredentialWithMismatchFingerprint() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup certificate credential.
- cred.certCredential = new Credential.CertificateCredential();
- cred.certCredential.certType = "x509v3";
- cred.certCredential.certSha256FingerPrint = new byte[32];
- Arrays.fill(cred.certCredential.certSha256FingerPrint, (byte)0);
- // Setup certificates and private key.
- cred.caCertificate = FakeKeys.CA_CERT0;
- cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
- cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+ Credential cred = createCredentialWithCertificateCredential();
+ cred.getCertCredential().setCertSha256Fingerprint(new byte[32]);
assertFalse(cred.validate());
}
@@ -392,12 +313,7 @@
*/
@Test
public void validateSimCredentialWithEapSim() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup SIM credential.
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.imsi = "1234*";
- cred.simCredential.eapType = EAPConstants.EAP_SIM;
+ Credential cred = createCredentialWithSimCredential();
assertTrue(cred.validate());
}
@@ -408,12 +324,8 @@
*/
@Test
public void validateSimCredentialWithEapAka() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup SIM credential.
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.imsi = "1234*";
- cred.simCredential.eapType = EAPConstants.EAP_AKA;
+ Credential cred = createCredentialWithSimCredential();
+ cred.getSimCredential().setEapType(EAPConstants.EAP_AKA);
assertTrue(cred.validate());
}
@@ -424,12 +336,8 @@
*/
@Test
public void validateSimCredentialWithEapAkaPrime() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup SIM credential.
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.imsi = "1234*";
- cred.simCredential.eapType = EAPConstants.EAP_AKA_PRIME;
+ Credential cred = createCredentialWithSimCredential();
+ cred.getSimCredential().setEapType(EAPConstants.EAP_AKA_PRIME);
assertTrue(cred.validate());
}
@@ -440,11 +348,8 @@
*/
@Test
public void validateSimCredentialWithoutIMSI() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup SIM credential.
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.eapType = EAPConstants.EAP_SIM;
+ Credential cred = createCredentialWithSimCredential();
+ cred.getSimCredential().setImsi(null);
assertFalse(cred.validate());
}
@@ -455,12 +360,8 @@
*/
@Test
public void validateSimCredentialWithInvalidIMSI() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup SIM credential.
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.imsi = "dummy";
- cred.simCredential.eapType = EAPConstants.EAP_SIM;
+ Credential cred = createCredentialWithSimCredential();
+ cred.getSimCredential().setImsi("dummy");
assertFalse(cred.validate());
}
@@ -471,12 +372,8 @@
*/
@Test
public void validateSimCredentialWithEapTls() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup SIM credential.
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.imsi = "1234*";
- cred.simCredential.eapType = EAPConstants.EAP_TLS;
+ Credential cred = createCredentialWithSimCredential();
+ cred.getSimCredential().setEapType(EAPConstants.EAP_TLS);
assertFalse(cred.validate());
}
@@ -487,19 +384,12 @@
*/
@Test
public void validateCredentialWithUserAndSimCredential() throws Exception {
- Credential cred = new Credential();
- cred.realm = "realm";
- // Setup user credential with EAP-TTLS.
- cred.userCredential = new Credential.UserCredential();
- cred.userCredential.username = "username";
- cred.userCredential.password = "password";
- cred.userCredential.eapType = EAPConstants.EAP_TTLS;
- cred.userCredential.nonEapInnerMethod = "MS-CHAP";
- cred.caCertificate = FakeKeys.CA_CERT0;
+ Credential cred = createCredentialWithUserCredential();
// Setup SIM credential.
- cred.simCredential = new Credential.SimCredential();
- cred.simCredential.imsi = "1234*";
- cred.simCredential.eapType = EAPConstants.EAP_SIM;
+ Credential.SimCredential simCredential = new Credential.SimCredential();
+ simCredential.setImsi("1234*");
+ simCredential.setEapType(EAPConstants.EAP_SIM);
+ cred.setSimCredential(simCredential);
assertFalse(cred.validate());
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
index 45fdbea..92e94ee 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
@@ -55,14 +55,14 @@
*/
private static HomeSP createHomeSp(Map<String, Long> homeNetworkIds) {
HomeSP homeSp = new HomeSP();
- homeSp.fqdn = "fqdn";
- homeSp.friendlyName = "friendly name";
- homeSp.iconUrl = "icon.url";
- homeSp.homeNetworkIds = homeNetworkIds;
- homeSp.matchAllOIs = new long[] {0x11L, 0x22L};
- homeSp.matchAnyOIs = new long[] {0x33L, 0x44L};
- homeSp.otherHomePartners = new String[] {"partner1", "partner2"};
- homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66};
+ homeSp.setFqdn("fqdn");
+ homeSp.setFriendlyName("friendly name");
+ homeSp.setIconUrl("icon.url");
+ homeSp.setHomeNetworkIds(homeNetworkIds);
+ homeSp.setMatchAllOIs(new long[] {0x11L, 0x22L});
+ homeSp.setMatchAnyOIs(new long[] {0x33L, 0x44L});
+ homeSp.setOtherHomePartners(new String[] {"partner1", "partner2"});
+ homeSp.setRoamingConsortiumOIs(new long[] {0x55, 0x66});
return homeSp;
}
@@ -136,9 +136,7 @@
*/
@Test
public void validateValidHomeSP() throws Exception {
- HomeSP homeSp = new HomeSP();
- homeSp.fqdn = "fqdn";
- homeSp.friendlyName = "friendly name";
+ HomeSP homeSp = createHomeSpWithHomeNetworkIds();
assertTrue(homeSp.validate());
}
@@ -149,8 +147,8 @@
*/
@Test
public void validateHomeSpWithoutFqdn() throws Exception {
- HomeSP homeSp = new HomeSP();
- homeSp.friendlyName = "friendly name";
+ HomeSP homeSp = createHomeSpWithHomeNetworkIds();
+ homeSp.setFqdn(null);
assertFalse(homeSp.validate());
}
@@ -161,36 +159,9 @@
*/
@Test
public void validateHomeSpWithoutFriendlyName() throws Exception {
- HomeSP homeSp = new HomeSP();
- homeSp.fqdn = "fqdn";
- assertFalse(homeSp.validate());
- }
-
- /**
- * Verify that a HomeSP is valid when the optional Roaming Consortium OIs are
- * provided.
- *
- * @throws Exception
- */
- @Test
- public void validateHomeSpWithRoamingConsoritums() throws Exception {
- HomeSP homeSp = new HomeSP();
- homeSp.fqdn = "fqdn";
- homeSp.friendlyName = "friendly name";
- homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66};
- assertTrue(homeSp.validate());
- }
-
- /**
- * Verify that a HomeSP is valid when the optional Home Network IDs are
- * provided.
- *
- * @throws Exception
- */
- @Test
- public void validateHomeSpWithHomeNetworkIds() throws Exception {
HomeSP homeSp = createHomeSpWithHomeNetworkIds();
- assertTrue(homeSp.validate());
+ homeSp.setFriendlyName(null);
+ assertFalse(homeSp.validate());
}
/**
@@ -213,14 +184,14 @@
*/
@Test
public void validateHomeSpWithInvalidHomeNetworkIds() throws Exception {
- HomeSP homeSp = new HomeSP();
- homeSp.fqdn = "fqdn";
- homeSp.friendlyName = "friendly name";
- homeSp.homeNetworkIds = new HashMap<>();
+ HomeSP homeSp = createHomeSpWithoutHomeNetworkIds();
+ // HomeNetworkID with SSID exceeding the maximum length.
+ Map<String, Long> homeNetworkIds = new HashMap<>();
byte[] rawSsidBytes = new byte[33];
Arrays.fill(rawSsidBytes, (byte) 'a');
- homeSp.homeNetworkIds.put(
+ homeNetworkIds.put(
StringFactory.newStringFromBytes(rawSsidBytes, StandardCharsets.UTF_8), 0x1234L);
+ homeSp.setHomeNetworkIds(homeNetworkIds);
assertFalse(homeSp.validate());
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java
index c371c49..2a36764 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/PolicyTest.java
@@ -30,6 +30,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -48,40 +49,43 @@
*/
private static Policy createPolicy() {
Policy policy = new Policy();
- policy.minHomeDownlinkBandwidth = 123;
- policy.minHomeUplinkBandwidth = 345;
- policy.minRoamingDownlinkBandwidth = 567;
- policy.minRoamingUplinkBandwidth = 789;
- policy.excludedSsidList = new String[] {"ssid1", "ssid2"};
- policy.requiredProtoPortMap = new HashMap<>();
- policy.requiredProtoPortMap.put(12, "23,342,123");
- policy.requiredProtoPortMap.put(23, "789,372,1235");
- policy.maximumBssLoadValue = 12;
+ policy.setMinHomeDownlinkBandwidth(123);
+ policy.setMinHomeUplinkBandwidth(345);
+ policy.setMinRoamingDownlinkBandwidth(567);
+ policy.setMinRoamingUplinkBandwidth(789);
+ policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
+ Map<Integer, String> requiredProtoPortMap = new HashMap<>();
+ requiredProtoPortMap.put(12, "23,342,123");
+ requiredProtoPortMap.put(23, "789,372,1235");
+ policy.setRequiredProtoPortMap(requiredProtoPortMap);
+ policy.setMaximumBssLoadValue(12);
- policy.preferredRoamingPartnerList = new ArrayList<>();
+ List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
- partner1.fqdn = "partner1.com";
- partner1.fqdnExactMatch = true;
- partner1.priority = 12;
- partner1.countries = "us,jp";
+ partner1.setFqdn("partner1.com");
+ partner1.setFqdnExactMatch(true);
+ partner1.setPriority(12);
+ partner1.setCountries("us,jp");
Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
- partner2.fqdn = "partner2.com";
- partner2.fqdnExactMatch = false;
- partner2.priority = 42;
- partner2.countries = "ca,fr";
- policy.preferredRoamingPartnerList.add(partner1);
- policy.preferredRoamingPartnerList.add(partner2);
+ partner2.setFqdn("partner2.com");
+ partner2.setFqdnExactMatch(false);
+ partner2.setPriority(42);
+ partner2.setCountries("ca,fr");
+ preferredRoamingPartnerList.add(partner1);
+ preferredRoamingPartnerList.add(partner2);
+ policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
- policy.policyUpdate = new UpdateParameter();
- policy.policyUpdate.updateIntervalInMinutes = 1712;
- policy.policyUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_OMADM;
- policy.policyUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_HOMESP;
- policy.policyUpdate.serverUri = "policy.update.com";
- policy.policyUpdate.username = "username";
- policy.policyUpdate.base64EncodedPassword =
- Base64.encodeToString("password".getBytes(), Base64.DEFAULT);
- policy.policyUpdate.trustRootCertUrl = "trust.cert.com";
- policy.policyUpdate.trustRootCertSha256Fingerprint = new byte[32];
+ UpdateParameter policyUpdate = new UpdateParameter();
+ policyUpdate.setUpdateIntervalInMinutes(1712);
+ policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
+ policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
+ policyUpdate.setServerUri("policy.update.com");
+ policyUpdate.setUsername("username");
+ policyUpdate.setBase64EncodedPassword(
+ Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
+ policyUpdate.setTrustRootCertUrl("trust.cert.com");
+ policyUpdate.setTrustRootCertSha256Fingerprint(new byte[32]);
+ policy.setPolicyUpdate(policyUpdate);
return policy;
}
@@ -128,7 +132,7 @@
@Test
public void verifyParcelWithoutProtoPortMap() throws Exception {
Policy policy = createPolicy();
- policy.requiredProtoPortMap = null;
+ policy.setRequiredProtoPortMap(null);
verifyParcel(policy);
}
@@ -140,7 +144,7 @@
@Test
public void verifyParcelWithoutPreferredRoamingPartnerList() throws Exception {
Policy policy = createPolicy();
- policy.preferredRoamingPartnerList = null;
+ policy.setPreferredRoamingPartnerList(null);
verifyParcel(policy);
}
@@ -152,7 +156,7 @@
@Test
public void verifyParcelWithoutPolicyUpdate() throws Exception {
Policy policy = createPolicy();
- policy.policyUpdate = null;
+ policy.setPolicyUpdate(null);
verifyParcel(policy);
}
@@ -212,7 +216,7 @@
@Test
public void validatePolicyWithoutPolicyUpdate() throws Exception {
Policy policy = createPolicy();
- policy.policyUpdate = null;
+ policy.setPolicyUpdate(null);
assertFalse(policy.validate());
}
@@ -224,7 +228,7 @@
@Test
public void validatePolicyWithInvalidPolicyUpdate() throws Exception {
Policy policy = createPolicy();
- policy.policyUpdate = new UpdateParameter();
+ policy.setPolicyUpdate(new UpdateParameter());
assertFalse(policy.validate());
}
@@ -237,10 +241,10 @@
public void validatePolicyWithRoamingPartnerWithoutFQDN() throws Exception {
Policy policy = createPolicy();
Policy.RoamingPartner partner = new Policy.RoamingPartner();
- partner.fqdnExactMatch = true;
- partner.priority = 12;
- partner.countries = "us,jp";
- policy.preferredRoamingPartnerList.add(partner);
+ partner.setFqdnExactMatch(true);
+ partner.setPriority(12);
+ partner.setCountries("us,jp");
+ policy.getPreferredRoamingPartnerList().add(partner);
assertFalse(policy.validate());
}
@@ -254,10 +258,10 @@
public void validatePolicyWithRoamingPartnerWithoutCountries() throws Exception {
Policy policy = createPolicy();
Policy.RoamingPartner partner = new Policy.RoamingPartner();
- partner.fqdn = "test.com";
- partner.fqdnExactMatch = true;
- partner.priority = 12;
- policy.preferredRoamingPartnerList.add(partner);
+ partner.setFqdn("test.com");
+ partner.setFqdnExactMatch(true);
+ partner.setPriority(12);
+ policy.getPreferredRoamingPartnerList().add(partner);
assertFalse(policy.validate());
}
@@ -271,7 +275,8 @@
public void validatePolicyWithInvalidPortStringInProtoPortMap() throws Exception {
Policy policy = createPolicy();
byte[] rawPortBytes = new byte[MAX_PORT_STRING_BYTES + 1];
- policy.requiredProtoPortMap.put(324, new String(rawPortBytes, StandardCharsets.UTF_8));
+ policy.getRequiredProtoPortMap().put(
+ 324, new String(rawPortBytes, StandardCharsets.UTF_8));
assertFalse(policy.validate());
}
@@ -283,8 +288,9 @@
@Test
public void validatePolicyWithSsidExclusionListSizeExceededMax() throws Exception {
Policy policy = createPolicy();
- policy.excludedSsidList = new String[MAX_NUMBER_OF_EXCLUDED_SSIDS + 1];
- Arrays.fill(policy.excludedSsidList, "ssid");
+ String[] excludedSsidList = new String[MAX_NUMBER_OF_EXCLUDED_SSIDS + 1];
+ Arrays.fill(excludedSsidList, "ssid");
+ policy.setExcludedSsidList(excludedSsidList);
assertFalse(policy.validate());
}
@@ -298,7 +304,9 @@
Policy policy = createPolicy();
byte[] rawSsidBytes = new byte[MAX_SSID_BYTES + 1];
Arrays.fill(rawSsidBytes, (byte) 'a');
- policy.excludedSsidList = new String[] {new String(rawSsidBytes, StandardCharsets.UTF_8)};
+ String[] excludedSsidList = new String[] {
+ new String(rawSsidBytes, StandardCharsets.UTF_8)};
+ policy.setExcludedSsidList(excludedSsidList);
assertFalse(policy.validate());
}
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java
index 6bf0db1b..551ed43 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/UpdateParameterTest.java
@@ -50,15 +50,15 @@
*/
private static UpdateParameter createUpdateParameter() {
UpdateParameter updateParam = new UpdateParameter();
- updateParam.updateIntervalInMinutes = 1712;
- updateParam.updateMethod = UpdateParameter.UPDATE_METHOD_OMADM;
- updateParam.restriction = UpdateParameter.UPDATE_RESTRICTION_HOMESP;
- updateParam.serverUri = "server.pdate.com";
- updateParam.username = "username";
- updateParam.base64EncodedPassword =
- Base64.encodeToString("password".getBytes(), Base64.DEFAULT);
- updateParam.trustRootCertUrl = "trust.cert.com";
- updateParam.trustRootCertSha256Fingerprint = new byte[32];
+ updateParam.setUpdateIntervalInMinutes(1712);
+ updateParam.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
+ updateParam.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
+ updateParam.setServerUri("server.pdate.com");
+ updateParam.setUsername("username");
+ updateParam.setBase64EncodedPassword(
+ Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
+ updateParam.setTrustRootCertUrl("trust.cert.com");
+ updateParam.setTrustRootCertSha256Fingerprint(new byte[32]);
return updateParam;
}
@@ -152,7 +152,7 @@
@Test
public void validateUpdateParameterWithUnknowMethod() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.updateMethod = "adsfasd";
+ updateParam.setUpdateMethod("adsfasd");
assertFalse(updateParam.validate());
}
@@ -164,7 +164,7 @@
@Test
public void validateUpdateParameterWithUnknowRestriction() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.restriction = "adsfasd";
+ updateParam.setRestriction("adsfasd");
assertFalse(updateParam.validate());
}
@@ -178,7 +178,7 @@
UpdateParameter updateParam = createUpdateParameter();
byte[] rawUsernameBytes = new byte[MAX_USERNAME_BYTES + 1];
Arrays.fill(rawUsernameBytes, (byte) 'a');
- updateParam.username = new String(rawUsernameBytes, StandardCharsets.UTF_8);
+ updateParam.setUsername(new String(rawUsernameBytes, StandardCharsets.UTF_8));
assertFalse(updateParam.validate());
}
@@ -190,7 +190,7 @@
@Test
public void validateUpdateParameterWithEmptyUsername() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.username = null;
+ updateParam.setUsername(null);
assertFalse(updateParam.validate());
}
@@ -204,7 +204,7 @@
UpdateParameter updateParam = createUpdateParameter();
byte[] rawPasswordBytes = new byte[MAX_PASSWORD_BYTES + 1];
Arrays.fill(rawPasswordBytes, (byte) 'a');
- updateParam.base64EncodedPassword = new String(rawPasswordBytes, StandardCharsets.UTF_8);
+ updateParam.setBase64EncodedPassword(new String(rawPasswordBytes, StandardCharsets.UTF_8));
assertFalse(updateParam.validate());
}
@@ -216,7 +216,7 @@
@Test
public void validateUpdateParameterWithEmptyPassword() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.base64EncodedPassword = null;
+ updateParam.setBase64EncodedPassword(null);
assertFalse(updateParam.validate());
}
@@ -229,7 +229,7 @@
@Test
public void validateUpdateParameterWithPasswordContainedInvalidPadding() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.base64EncodedPassword = updateParam.base64EncodedPassword + "=";
+ updateParam.setBase64EncodedPassword(updateParam.getBase64EncodedPassword() + "=");
assertFalse(updateParam.validate());
}
@@ -241,7 +241,7 @@
@Test
public void validateUpdateParameterWithoutTrustRootCertUrl() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.trustRootCertUrl = null;
+ updateParam.setTrustRootCertUrl(null);
assertFalse(updateParam.validate());
}
@@ -255,7 +255,7 @@
UpdateParameter updateParam = createUpdateParameter();
byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
Arrays.fill(rawUrlBytes, (byte) 'a');
- updateParam.trustRootCertUrl = new String(rawUrlBytes, StandardCharsets.UTF_8);
+ updateParam.setTrustRootCertUrl(new String(rawUrlBytes, StandardCharsets.UTF_8));
assertFalse(updateParam.validate());
}
@@ -268,7 +268,7 @@
@Test
public void validateUpdateParameterWithouttrustRootCertSha256Fingerprint() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.trustRootCertSha256Fingerprint = null;
+ updateParam.setTrustRootCertSha256Fingerprint(null);
assertFalse(updateParam.validate());
}
@@ -281,10 +281,10 @@
@Test
public void validateUpdateParameterWithInvalidtrustRootCertSha256Fingerprint() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_SHA256_BYTES + 1];
+ updateParam.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_SHA256_BYTES + 1]);
assertFalse(updateParam.validate());
- updateParam.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_SHA256_BYTES - 1];
+ updateParam.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_SHA256_BYTES - 1]);
assertFalse(updateParam.validate());
}
@@ -296,7 +296,7 @@
@Test
public void validateUpdateParameterWithoutServerUri() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.serverUri = null;
+ updateParam.setServerUri(null);
assertFalse(updateParam.validate());
}
@@ -310,7 +310,7 @@
UpdateParameter updateParam = createUpdateParameter();
byte[] rawUriBytes = new byte[MAX_URI_BYTES + 1];
Arrays.fill(rawUriBytes, (byte) 'a');
- updateParam.serverUri = new String(rawUriBytes, StandardCharsets.UTF_8);
+ updateParam.setServerUri(new String(rawUriBytes, StandardCharsets.UTF_8));
assertFalse(updateParam.validate());
}
@@ -323,14 +323,14 @@
@Test
public void validateUpdateParameterWithNoServerCheck() throws Exception {
UpdateParameter updateParam = new UpdateParameter();
- updateParam.updateIntervalInMinutes = UpdateParameter.UPDATE_CHECK_INTERVAL_NEVER;
- updateParam.username = null;
- updateParam.base64EncodedPassword = null;
- updateParam.updateMethod = null;
- updateParam.restriction = null;
- updateParam.serverUri = null;
- updateParam.trustRootCertUrl = null;
- updateParam.trustRootCertSha256Fingerprint = null;
+ updateParam.setUpdateIntervalInMinutes(UpdateParameter.UPDATE_CHECK_INTERVAL_NEVER);
+ updateParam.setUsername(null);
+ updateParam.setBase64EncodedPassword(null);
+ updateParam.setUpdateMethod(null);
+ updateParam.setRestriction(null);
+ updateParam.setServerUri(null);
+ updateParam.setTrustRootCertUrl(null);
+ updateParam.setTrustRootCertSha256Fingerprint(null);
assertTrue(updateParam.validate());
}
@@ -342,7 +342,7 @@
@Test
public void validateUpdateParameterWithoutUpdateInterval() throws Exception {
UpdateParameter updateParam = createUpdateParameter();
- updateParam.updateIntervalInMinutes = Long.MIN_VALUE;
+ updateParam.setUpdateIntervalInMinutes(Long.MIN_VALUE);
assertFalse(updateParam.validate());
}
}