Merge "Revert "Support multiple filters per association request""
diff --git a/api/current.txt b/api/current.txt
index 1a5ea85..6a62fde 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47452,17 +47452,27 @@
}
public final class AutoFillManager {
+ method public void registerCallback(android.view.autofill.AutoFillManager.AutofillCallback);
method public void reset();
method public void startAutoFillRequest(android.view.View);
method public void startAutoFillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
method public void stopAutoFillRequest(android.view.View);
method public void stopAutoFillRequestOnVirtualView(android.view.View, int);
+ method public void unregisterCallback(android.view.autofill.AutoFillManager.AutofillCallback);
method public void valueChanged(android.view.View);
method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
}
+ public static abstract class AutoFillManager.AutofillCallback {
+ ctor public AutoFillManager.AutofillCallback();
+ method public void onAutofillEvent(android.view.View, int);
+ method public void onAutofillEventVirtual(android.view.View, int, int);
+ field public static final int EVENT_INPUT_HIDDEN = 2; // 0x2
+ field public static final int EVENT_INPUT_SHOWN = 1; // 0x1
+ }
+
public final class AutoFillType implements android.os.Parcelable {
method public int describeContents();
method public static android.view.autofill.AutoFillType forDate();
diff --git a/api/system-current.txt b/api/system-current.txt
index b5c20e5..6ee593c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -16493,6 +16493,7 @@
method public android.hardware.hdmi.HdmiPlaybackClient getPlaybackClient();
method public android.hardware.hdmi.HdmiTvClient getTvClient();
method public void removeHotplugEventListener(android.hardware.hdmi.HdmiControlManager.HotplugEventListener);
+ method public void setStandbyMode(boolean);
field public static final java.lang.String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE";
field public static final int AVR_VOLUME_MUTED = 101; // 0x65
field public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 162; // 0xa2
@@ -50915,17 +50916,27 @@
}
public final class AutoFillManager {
+ method public void registerCallback(android.view.autofill.AutoFillManager.AutofillCallback);
method public void reset();
method public void startAutoFillRequest(android.view.View);
method public void startAutoFillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
method public void stopAutoFillRequest(android.view.View);
method public void stopAutoFillRequestOnVirtualView(android.view.View, int);
+ method public void unregisterCallback(android.view.autofill.AutoFillManager.AutofillCallback);
method public void valueChanged(android.view.View);
method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
}
+ public static abstract class AutoFillManager.AutofillCallback {
+ ctor public AutoFillManager.AutofillCallback();
+ method public void onAutofillEvent(android.view.View, int);
+ method public void onAutofillEventVirtual(android.view.View, int, int);
+ field public static final int EVENT_INPUT_HIDDEN = 2; // 0x2
+ field public static final int EVENT_INPUT_SHOWN = 1; // 0x1
+ }
+
public final class AutoFillType implements android.os.Parcelable {
method public int describeContents();
method public static android.view.autofill.AutoFillType forDate();
diff --git a/api/test-current.txt b/api/test-current.txt
index 57cc998..fc96532 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -47821,17 +47821,27 @@
}
public final class AutoFillManager {
+ method public void registerCallback(android.view.autofill.AutoFillManager.AutofillCallback);
method public void reset();
method public void startAutoFillRequest(android.view.View);
method public void startAutoFillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
method public void stopAutoFillRequest(android.view.View);
method public void stopAutoFillRequestOnVirtualView(android.view.View, int);
+ method public void unregisterCallback(android.view.autofill.AutoFillManager.AutofillCallback);
method public void valueChanged(android.view.View);
method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
}
+ public static abstract class AutoFillManager.AutofillCallback {
+ ctor public AutoFillManager.AutofillCallback();
+ method public void onAutofillEvent(android.view.View, int);
+ method public void onAutofillEventVirtual(android.view.View, int, int);
+ field public static final int EVENT_INPUT_HIDDEN = 2; // 0x2
+ field public static final int EVENT_INPUT_SHOWN = 1; // 0x1
+ }
+
public final class AutoFillType implements android.os.Parcelable {
method public int describeContents();
method public static android.view.autofill.AutoFillType forDate();
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index 7241e0d..b7545bf 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -170,6 +170,9 @@
protected boolean onCancelLoad() {
if (DEBUG) Log.v(TAG, "onCancelLoad: mTask=" + mTask);
if (mTask != null) {
+ if (!mStarted) {
+ mContentChanged = true;
+ }
if (mCancellingTask != null) {
// There was a pending task already waiting for a previous
// one being canceled; just drop it.
diff --git a/core/java/android/content/om/IOverlayManager.aidl b/core/java/android/content/om/IOverlayManager.aidl
index 4f5d960..86c1aa8 100644
--- a/core/java/android/content/om/IOverlayManager.aidl
+++ b/core/java/android/content/om/IOverlayManager.aidl
@@ -89,6 +89,11 @@
boolean setEnabled(in String packageName, in boolean enable, in int userId);
/**
+ * Version of setEnabled that will also disable any other overlays for the target package.
+ */
+ boolean setEnabledExclusive(in String packageName, in boolean enable, in int userId);
+
+ /**
* Change the priority of the given overlay to be just higher than the
* overlay with package name newParentPackageName. Both overlay packages
* must have the same target and user.
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 493ed8c..7bfb5d0 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -731,7 +731,7 @@
@SystemApi
@TestApi
public static final int SESSION_OPERATION_MODE_NORMAL =
- ICameraDeviceUser.NORMAL_MODE;
+ 0; // ICameraDeviceUser.NORMAL_MODE;
/**
* Constrained high-speed operation mode.
@@ -742,7 +742,7 @@
@SystemApi
@TestApi
public static final int SESSION_OPERATION_MODE_CONSTRAINED_HIGH_SPEED =
- ICameraDeviceUser.CONSTRAINED_HIGH_SPEED_MODE;
+ 1; // ICameraDeviceUser.CONSTRAINED_HIGH_SPEED_MODE;
/**
* First vendor-specific operating mode
@@ -753,7 +753,7 @@
@SystemApi
@TestApi
public static final int SESSION_OPERATION_MODE_VENDOR_START =
- ICameraDeviceUser.VENDOR_MODE_START;
+ 0x8000; // ICameraDeviceUser.VENDOR_MODE_START;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 98a5749..b276008 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -213,6 +213,10 @@
// If true, scales the brightness to half of desired.
public boolean lowPowerMode;
+ // The factor to adjust the screen brightness in low power mode in the range
+ // 0 (screen off) to 1 (no change)
+ public float screenLowPowerBrightnessFactor;
+
// If true, applies a brightness boost.
public boolean boostScreenBrightness;
@@ -235,6 +239,7 @@
useProximitySensor = false;
screenBrightness = PowerManager.BRIGHTNESS_ON;
screenAutoBrightnessAdjustment = 0.0f;
+ screenLowPowerBrightnessFactor = 0.5f;
useAutoBrightness = false;
blockScreenOn = false;
dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
@@ -258,6 +263,7 @@
useProximitySensor = other.useProximitySensor;
screenBrightness = other.screenBrightness;
screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
+ screenLowPowerBrightnessFactor = other.screenLowPowerBrightnessFactor;
brightnessSetByUser = other.brightnessSetByUser;
useAutoBrightness = other.useAutoBrightness;
blockScreenOn = other.blockScreenOn;
@@ -279,6 +285,8 @@
&& useProximitySensor == other.useProximitySensor
&& screenBrightness == other.screenBrightness
&& screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
+ && screenLowPowerBrightnessFactor
+ == other.screenLowPowerBrightnessFactor
&& brightnessSetByUser == other.brightnessSetByUser
&& useAutoBrightness == other.useAutoBrightness
&& blockScreenOn == other.blockScreenOn
@@ -299,6 +307,7 @@
+ ", useProximitySensor=" + useProximitySensor
+ ", screenBrightness=" + screenBrightness
+ ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
+ + ", screenLowPowerBrightnessFactor=" + screenLowPowerBrightnessFactor
+ ", brightnessSetByUser=" + brightnessSetByUser
+ ", useAutoBrightness=" + useAutoBrightness
+ ", blockScreenOn=" + blockScreenOn
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index ff87b67..27e2a50 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -338,6 +338,20 @@
}
/**
+ * Controls standby mode of the system. It will also try to turn on/off the connected devices if
+ * necessary.
+ *
+ * @param isStandbyModeOn target status of the system's standby mode
+ */
+ public void setStandbyMode(boolean isStandbyModeOn) {
+ try {
+ mService.setStandbyMode(isStandbyModeOn);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Listener used to get hotplug event from HDMI port.
*/
public interface HotplugEventListener {
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index c1e924e..67e2d18 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -71,4 +71,5 @@
void clearTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource);
void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data);
void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener);
+ void setStandbyMode(boolean isStandbyModeOn);
}
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index e025494..b09c51c 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -43,9 +43,7 @@
int code, HwParcel request, HwParcel reply, int flags)
throws RemoteException;
- public native final void registerService(
- ArrayList<String> interfaceChain,
- String serviceName)
+ public native final void registerService(String serviceName)
throws RemoteException;
public static native final IHwBinder getService(
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6e1cc26..e3a9d80 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -295,7 +295,9 @@
* In some cases, a matching Activity may not exist, so ensure you
* safeguard against this.
* <p>
- * Input: Nothing.
+ * Input: Optionally, the Intent's data URI can specify the application package name to
+ * directly invoke the management GUI specific to the package name. For example
+ * "package:com.my.app".
* <p>
* Output: Nothing.
*/
diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java
index 32aac13..5c718f1 100644
--- a/core/java/android/util/MathUtils.java
+++ b/core/java/android/util/MathUtils.java
@@ -24,7 +24,6 @@
* @hide Pending API council approval
*/
public final class MathUtils {
- private static final Random sRandom = new Random();
private static final float DEG_TO_RAD = 3.1415926f / 180.0f;
private static final float RAD_TO_DEG = 180.0f / 3.1415926f;
@@ -185,28 +184,6 @@
return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
}
- public static int random(int howbig) {
- return (int) (sRandom.nextFloat() * howbig);
- }
-
- public static int random(int howsmall, int howbig) {
- if (howsmall >= howbig) return howsmall;
- return (int) (sRandom.nextFloat() * (howbig - howsmall) + howsmall);
- }
-
- public static float random(float howbig) {
- return sRandom.nextFloat() * howbig;
- }
-
- public static float random(float howsmall, float howbig) {
- if (howsmall >= howbig) return howsmall;
- return sRandom.nextFloat() * (howbig - howsmall) + howsmall;
- }
-
- public static void randomSeed(long seed) {
- sRandom.setSeed(seed);
- }
-
/**
* Returns the sum of the two parameters, or throws an exception if the resulting sum would
* cause an overflow or underflow.
diff --git a/core/java/android/view/autofill/AutoFillManager.java b/core/java/android/view/autofill/AutoFillManager.java
index e8325e8..8beaf4e 100644
--- a/core/java/android/view/autofill/AutoFillManager.java
+++ b/core/java/android/view/autofill/AutoFillManager.java
@@ -19,7 +19,9 @@
import static android.view.autofill.Helper.DEBUG;
import static android.view.autofill.Helper.VERBOSE;
+import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
@@ -30,7 +32,10 @@
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
+import android.view.WindowManagerGlobal;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -76,6 +81,8 @@
private final IAutoFillManager mService;
private IAutoFillManagerClient mServiceClient;
+ private AutofillCallback mCallback;
+
private Context mContext;
private boolean mHasSession;
@@ -276,11 +283,11 @@
}
}
- private AutoFillId getAutoFillId(View view) {
+ private static AutoFillId getAutoFillId(View view) {
return new AutoFillId(view.getAccessibilityViewId());
}
- private AutoFillId getAutoFillId(View parent, int childId) {
+ private static AutoFillId getAutoFillId(View parent, int childId) {
return new AutoFillId(parent.getAccessibilityViewId(), childId);
}
@@ -289,10 +296,12 @@
if (DEBUG) {
Log.d(TAG, "startSession(): id=" + id + ", bounds=" + bounds + ", value=" + value);
}
+
try {
mService.startSession(mContext.getActivityToken(), windowToken,
- mServiceClient.asBinder(), id, bounds, value, mContext.getUserId());
- AutoFillClient client = getClient();
+ mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
+ mCallback != null);
+ final AutoFillClient client = getClient();
if (client != null) {
client.resetableStateAvailable();
}
@@ -344,6 +353,119 @@
}
}
+ /**
+ * Registers a {@link AutofillCallback} to receive autofill events.
+ *
+ * @param callback callback to receive events.
+ */
+ public void registerCallback(@Nullable AutofillCallback callback) {
+ if (callback == null) return;
+
+ final boolean hadCallback = mCallback != null;
+ mCallback = callback;
+
+ if (mHasSession && !hadCallback) {
+ try {
+ mService.setHasCallback(mContext.getActivityToken(), mContext.getUserId(), true);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Unregisters a {@link AutofillCallback} to receive autofill events.
+ *
+ * @param callback callback to stop receiving events.
+ */
+ public void unregisterCallback(@Nullable AutofillCallback callback) {
+ if (callback == null || mCallback == null || callback != mCallback) return;
+
+ mCallback = null;
+
+ if (mHasSession) {
+ try {
+ mService.setHasCallback(mContext.getActivityToken(), mContext.getUserId(), false);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ private void onAutofillEvent(IBinder windowToken, AutoFillId id, int event) {
+ if (mCallback == null) return;
+ if (id == null) {
+ Log.w(TAG, "onAutofillEvent(): no id for event " + event);
+ return;
+ }
+
+ final View root = WindowManagerGlobal.getInstance().getWindowView(windowToken);
+ if (root == null) {
+ Log.w(TAG, "onAutofillEvent() for " + id + ": root view gone");
+ return;
+ }
+ final View view = root.findViewByAccessibilityIdTraversal(id.getViewId());
+ if (view == null) {
+ Log.w(TAG, "onAutofillEvent() for " + id + ": view gone");
+ return;
+ }
+ if (id.isVirtual()) {
+ mCallback.onAutofillEventVirtual(view, id.getVirtualChildId(), event);
+ } else {
+ mCallback.onAutofillEvent(view, event);
+ }
+ }
+
+ /**
+ * Callback for auto-fill related events.
+ *
+ * <p>Typically used for applications that display their own "auto-complete" views, so they can
+ * enable / disable such views when the auto-fill UI affordance is shown / hidden.
+ */
+ public abstract static class AutofillCallback {
+
+ /** @hide */
+ @IntDef({EVENT_INPUT_SHOWN, EVENT_INPUT_HIDDEN})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AutofillEventType {}
+
+ /**
+ * The auto-fill input UI affordance associated with the view was shown.
+ *
+ * <p>If the view provides its own auto-complete UI affordance and its currently shown, it
+ * should be hidden upon receiving this event.
+ */
+ public static final int EVENT_INPUT_SHOWN = 1;
+
+ /**
+ * The auto-fill input UI affordance associated with the view was hidden.
+ *
+ * <p>If the view provides its own auto-complete UI affordance that was hidden upon a
+ * {@link #EVENT_INPUT_SHOWN} event, it could be shown again now.
+ */
+ public static final int EVENT_INPUT_HIDDEN = 2;
+
+ /**
+ * Called after a change in the autofill state associated with a view.
+ *
+ * @param view view associated with the change.
+ *
+ * @param event currently either {@link #EVENT_INPUT_SHOWN} or {@link #EVENT_INPUT_HIDDEN}.
+ */
+ public void onAutofillEvent(@NonNull View view, @AutofillEventType int event) {}
+
+ /**
+ * Called after a change in the autofill state associated with a virtual view.
+ *
+ * @param view parent view associated with the change.
+ * @param childId id identifying the virtual child inside the parent view.
+ *
+ * @param event currently either {@link #EVENT_INPUT_SHOWN} or {@link #EVENT_INPUT_HIDDEN}.
+ */
+ public void onAutofillEventVirtual(@NonNull View view, int childId,
+ @AutofillEventType int event) {}
+ }
+
private static final class AutoFillManagerClient extends IAutoFillManagerClient.Stub {
private final WeakReference<AutoFillManager> mAutoFillManager;
@@ -385,5 +507,17 @@
});
}
}
+
+ @Override
+ public void onAutofillEvent(IBinder windowToken, AutoFillId id, int event) {
+ final AutoFillManager autoFillManager = mAutoFillManager.get();
+ if (autoFillManager != null) {
+ autoFillManager.mContext.getMainThreadHandler().post(() -> {
+ if (autoFillManager.getClient() != null) {
+ autoFillManager.onAutofillEvent(windowToken, id, event);
+ }
+ });
+ }
+ }
}
}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index d054e97..b36c0f1 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -31,10 +31,12 @@
interface IAutoFillManager {
boolean addClient(in IAutoFillManagerClient client, int userId);
oneway void startSession(in IBinder activityToken, IBinder windowToken, in IBinder appCallback,
- in AutoFillId autoFillId, in Rect bounds, in AutoFillValue value, int userId);
+ in AutoFillId autoFillId, in Rect bounds, in AutoFillValue value, int userId,
+ boolean hasCallback);
oneway void updateSession(in IBinder activityToken, in AutoFillId id, in Rect bounds,
in AutoFillValue value, int flags, int userId);
oneway void finishSession(in IBinder activityToken, int userId);
oneway void setAuthenticationResult(in Bundle data,
in IBinder activityToken, int userId);
+ oneway void setHasCallback(in IBinder activityToken, int userId, boolean hasIt);
}
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 45f363d..9eef7d0 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -20,6 +20,7 @@
import android.content.Intent;
import android.content.IntentSender;
+import android.os.IBinder;
import android.view.autofill.AutoFillId;
import android.view.autofill.AutoFillValue;
@@ -43,4 +44,9 @@
* Authenticates a fill response or a data set.
*/
void authenticate(in IntentSender intent, in Intent fillInIntent);
+
+ /**
+ * Notifies the client when the auto-fill UI changed.
+ */
+ void onAutofillEvent(in IBinder windowToken, in AutoFillId id, int event);
}
diff --git a/core/java/com/android/internal/alsa/AlsaDevicesParser.java b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
index 81b7943..5203723 100644
--- a/core/java/com/android/internal/alsa/AlsaDevicesParser.java
+++ b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
@@ -184,7 +184,7 @@
}
}
- private ArrayList<AlsaDeviceRecord> mDeviceRecords = new ArrayList<AlsaDeviceRecord>();
+ private final ArrayList<AlsaDeviceRecord> mDeviceRecords = new ArrayList<AlsaDeviceRecord>();
public AlsaDevicesParser() {}
@@ -199,9 +199,11 @@
//
// Predicates
//
+/*
public boolean hasPlaybackDevices() {
return mHasPlaybackDevices;
}
+*/
public boolean hasPlaybackDevices(int card) {
for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
@@ -214,9 +216,11 @@
return false;
}
+/*
public boolean hasCaptureDevices() {
return mHasCaptureDevices;
}
+*/
public boolean hasCaptureDevices(int card) {
for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
@@ -229,9 +233,11 @@
return false;
}
+/*
public boolean hasMIDIDevices() {
return mHasMIDIDevices;
}
+*/
public boolean hasMIDIDevices(int card) {
for (AlsaDeviceRecord deviceRecord : mDeviceRecords) {
diff --git a/core/java/com/android/internal/alsa/LineTokenizer.java b/core/java/com/android/internal/alsa/LineTokenizer.java
index 43047a9..b395da9 100644
--- a/core/java/com/android/internal/alsa/LineTokenizer.java
+++ b/core/java/com/android/internal/alsa/LineTokenizer.java
@@ -23,7 +23,7 @@
public class LineTokenizer {
public static final int kTokenNotFound = -1;
- private String mDelimiters = "";
+ private final String mDelimiters;
public LineTokenizer(String delimiters) {
mDelimiters = delimiters;
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index e4493b1..f852194 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -8,6 +8,8 @@
#include "SkImageInfo.h"
#include "SkColor.h"
#include "SkColorPriv.h"
+#include "SkColorSpace.h"
+#include "SkColorSpaceXform.h"
#include "SkHalf.h"
#include "SkMatrix44.h"
#include "SkPM4f.h"
@@ -29,6 +31,7 @@
#include "core_jni_helpers.h"
#include <jni.h>
+#include <string.h>
#include <memory>
#include <string>
@@ -448,11 +451,32 @@
// reset to to actual choice from caller
dst = dstBitmap.getAddr(x, y);
- // now copy/convert each scanline
- for (int y = 0; y < height; y++) {
- proc(dst, src, width, x, y);
- src += srcStride;
- dst = (char*)dst + dstBitmap.rowBytes();
+
+ SkColorSpace* colorSpace = dstBitmap.colorSpace();
+ if (GraphicsJNI::isColorSpaceSRGB(colorSpace)) {
+ // now copy/convert each scanline
+ for (int y = 0; y < height; y++) {
+ proc(dst, src, width, x, y);
+ src += srcStride;
+ dst = (char*)dst + dstBitmap.rowBytes();
+ }
+ } else {
+ auto sRGB = SkColorSpace::MakeSRGB();
+ auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace);
+
+ std::unique_ptr<SkColor[]> row(new SkColor[width]);
+
+ // now copy/convert each scanline
+ for (int y = 0; y < height; y++) {
+ memcpy(row.get(), src, sizeof(SkColor) * width);
+ xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(),
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, row.get(), width,
+ SkAlphaType::kUnpremul_SkAlphaType);
+
+ proc(dst, row.get(), width, x, y);
+ src += srcStride;
+ dst = (char*)dst + dstBitmap.rowBytes();
+ }
}
dstBitmap.notifyPixelsChanged();
@@ -1179,12 +1203,7 @@
if (!bitmapHolder.valid()) return JNI_TRUE;
SkColorSpace* colorSpace = bitmapHolder->info().colorSpace();
- return colorSpace == nullptr ||
- colorSpace == SkColorSpace::MakeSRGB().get() ||
- colorSpace == SkColorSpace::MakeRGB(
- SkColorSpace::kSRGB_RenderTargetGamma,
- SkColorSpace::kSRGB_Gamut,
- SkColorSpace::kNonLinearBlending_ColorSpaceFlag).get();
+ return GraphicsJNI::isColorSpaceSRGB(colorSpace);
}
static jboolean Bitmap_getColorSpace(JNIEnv* env, jobject, jlong bitmapHandle,
@@ -1246,6 +1265,16 @@
SkColor dst[1];
proc(dst, src, 1, bitmap.getColorTable());
+
+ SkColorSpace* colorSpace = bitmap.colorSpace();
+ if (!GraphicsJNI::isColorSpaceSRGB(colorSpace)) {
+ auto sRGB = SkColorSpace::MakeSRGB();
+ auto xform = SkColorSpaceXform::New(colorSpace, sRGB.get());
+ xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &dst[0],
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, &dst[0], 1,
+ SkAlphaType::kUnpremul_SkAlphaType);
+ }
+
return static_cast<jint>(dst[0]);
}
@@ -1268,11 +1297,30 @@
SkColorTable* ctable = bitmap.getColorTable();
jint* dst = env->GetIntArrayElements(pixelArray, NULL);
SkColor* d = (SkColor*)dst + offset;
- while (--height >= 0) {
- proc(d, src, width, ctable);
- d += stride;
- src = (void*)((const char*)src + bitmap.rowBytes());
+
+ SkColorSpace* colorSpace = bitmap.colorSpace();
+ if (GraphicsJNI::isColorSpaceSRGB(colorSpace)) {
+ while (--height >= 0) {
+ proc(d, src, width, ctable);
+ d += stride;
+ src = (void*)((const char*)src + bitmap.rowBytes());
+ }
+ } else {
+ auto sRGB = SkColorSpace::MakeSRGB();
+ auto xform = SkColorSpaceXform::New(colorSpace, sRGB.get());
+
+ while (--height >= 0) {
+ proc(d, src, width, ctable);
+
+ xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, d,
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, d, width,
+ SkAlphaType::kUnpremul_SkAlphaType);
+
+ d += stride;
+ src = (void*)((const char*)src + bitmap.rowBytes());
+ }
}
+
env->ReleaseIntArrayElements(pixelArray, dst, 0);
}
@@ -1293,6 +1341,15 @@
return;
}
+ SkColorSpace* colorSpace = bitmap.colorSpace();
+ if (!GraphicsJNI::isColorSpaceSRGB(colorSpace)) {
+ auto sRGB = SkColorSpace::MakeSRGB();
+ auto xform = SkColorSpaceXform::New(sRGB.get(), colorSpace);
+ xform->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, &color,
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, &color, 1,
+ SkAlphaType::kUnpremul_SkAlphaType);
+ }
+
proc(bitmap.getAddr(x, y), &color, 1, x, y);
bitmap.notifyPixelsChanged();
}
diff --git a/core/jni/android/graphics/GraphicBuffer.cpp b/core/jni/android/graphics/GraphicBuffer.cpp
index e661c21..73e53c6 100644
--- a/core/jni/android/graphics/GraphicBuffer.cpp
+++ b/core/jni/android/graphics/GraphicBuffer.cpp
@@ -30,8 +30,6 @@
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/ISurfaceComposer.h>
#include <hwui/Bitmap.h>
#include <SkCanvas.h>
@@ -111,21 +109,14 @@
static jlong android_graphics_GraphicBuffer_create(JNIEnv* env, jobject clazz,
jint width, jint height, jint format, jint usage) {
- sp<ISurfaceComposer> composer(ComposerService::getComposerService());
- sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
- if (alloc == NULL) {
- if (kDebugGraphicBuffer) {
- ALOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()");
- }
- return NULL;
- }
+ sp<GraphicBuffer> buffer = new GraphicBuffer(
+ uint32_t(width), uint32_t(height), PixelFormat(format), uint32_t(usage),
+ std::string("android_graphics_GraphicBuffer_create pid [") +
+ std::to_string(getpid()) +"]");
- status_t error;
- sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, 1, usage, &error));
- if (buffer == NULL) {
- if (kDebugGraphicBuffer) {
- ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
- }
+ status_t error = buffer->initCheck();
+ if (error < 0) {
+ ALOGW_IF(kDebugGraphicBuffer, "createGraphicBuffer() failed in GraphicBuffer.create()");
return NULL;
}
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 5d73101..7c56c7b 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -460,6 +460,15 @@
}
}
+bool GraphicsJNI::isColorSpaceSRGB(SkColorSpace* colorSpace) {
+ return colorSpace == nullptr
+ || colorSpace == SkColorSpace::MakeSRGB().get()
+ || colorSpace == SkColorSpace::MakeRGB(
+ SkColorSpace::kSRGB_RenderTargetGamma,
+ SkColorSpace::kSRGB_Gamut,
+ SkColorSpace::kNonLinearBlending_ColorSpaceFlag).get();
+}
+
///////////////////////////////////////////////////////////////////////////////
bool HeapAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
mStorage = android::Bitmap::allocateHeapBitmap(bitmap, ctable);
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 8a1ef6e..7d7c881 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -111,6 +111,7 @@
static sk_sp<SkColorSpace> defaultColorSpace();
static sk_sp<SkColorSpace> linearColorSpace();
static sk_sp<SkColorSpace> colorSpaceForType(SkColorType type);
+ static bool isColorSpaceSRGB(SkColorSpace* colorSpace);
};
class HeapAllocator : public SkBRDAllocator {
diff --git a/core/jni/android/graphics/PathEffect.cpp b/core/jni/android/graphics/PathEffect.cpp
index e801da3..a4992de 100644
--- a/core/jni/android/graphics/PathEffect.cpp
+++ b/core/jni/android/graphics/PathEffect.cpp
@@ -20,7 +20,7 @@
jlong outerHandle, jlong innerHandle) {
SkPathEffect* outer = reinterpret_cast<SkPathEffect*>(outerHandle);
SkPathEffect* inner = reinterpret_cast<SkPathEffect*>(innerHandle);
- SkPathEffect* effect = SkComposePathEffect::Make(sk_ref_sp(outer),
+ SkPathEffect* effect = SkPathEffect::MakeCompose(sk_ref_sp(outer),
sk_ref_sp(inner)).release();
return reinterpret_cast<jlong>(effect);
}
@@ -29,7 +29,7 @@
jlong firstHandle, jlong secondHandle) {
SkPathEffect* first = reinterpret_cast<SkPathEffect*>(firstHandle);
SkPathEffect* second = reinterpret_cast<SkPathEffect*>(secondHandle);
- SkPathEffect* effect = SkSumPathEffect::Make(sk_ref_sp(first),
+ SkPathEffect* effect = SkPathEffect::MakeSum(sk_ref_sp(first),
sk_ref_sp(second)).release();
return reinterpret_cast<jlong>(effect);
}
diff --git a/core/jni/android_hardware_HardwareBuffer.cpp b/core/jni/android_hardware_HardwareBuffer.cpp
index b91bd5c..ed0ab60 100644
--- a/core/jni/android_hardware_HardwareBuffer.cpp
+++ b/core/jni/android_hardware_HardwareBuffer.cpp
@@ -31,8 +31,6 @@
#include <binder/Parcel.h>
#include <ui/GraphicBuffer.h>
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
#include <hardware/gralloc1.h>
@@ -73,15 +71,6 @@
static jlong android_hardware_HardwareBuffer_create(JNIEnv* env, jobject clazz,
jint width, jint height, jint format, jint layers, jlong usage) {
- sp<ISurfaceComposer> composer(ComposerService::getComposerService());
- sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
- if (alloc == NULL) {
- if (kDebugGraphicBuffer) {
- ALOGW("createGraphicBufferAlloc() failed in HardwareBuffer.create()");
- }
- return NULL;
- }
-
// TODO: update createGraphicBuffer to take two 64-bit values.
int pixelFormat = android_hardware_HardwareBuffer_convertToPixelFormat(format);
if (pixelFormat == 0) {
@@ -92,14 +81,14 @@
}
uint64_t producerUsage = 0;
uint64_t consumerUsage = 0;
- android_hardware_HardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, usage,
- 0);
- status_t error;
- sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, pixelFormat,
- layers, producerUsage, consumerUsage,
- std::string("HardwareBuffer pid [") + std::to_string(getpid()) +"]",
- &error));
- if (buffer == NULL) {
+ android_hardware_HardwareBuffer_convertToGrallocUsageBits(
+ &producerUsage, &consumerUsage, usage, 0);
+
+ sp<GraphicBuffer> buffer = new GraphicBuffer(width, height, pixelFormat, layers,
+ producerUsage, consumerUsage,
+ std::string("HardwareBuffer pid [") + std::to_string(getpid()) +"]");
+ status_t error = buffer->initCheck();
+ if (error < 0) {
if (kDebugGraphicBuffer) {
ALOGW("createGraphicBuffer() failed in HardwareBuffer.create()");
}
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 2439b82..15b2f35 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -49,12 +49,6 @@
namespace android {
-static jclass gArrayListClass;
-static struct {
- jmethodID size;
- jmethodID get;
-} gArrayListMethods;
-
static jclass gErrorClass;
static struct fields_t {
@@ -239,7 +233,6 @@
static void JHwBinder_native_registerService(
JNIEnv *env,
jobject thiz,
- jobject interfaceChainArrayList,
jstring serviceNameObj) {
if (serviceNameObj == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
@@ -251,24 +244,6 @@
return; // XXX exception already pending?
}
- jint numInterfaces = env->CallIntMethod(interfaceChainArrayList,
- gArrayListMethods.size);
- hidl_string *strings = new hidl_string[numInterfaces];
-
- for (jint i = 0; i < numInterfaces; i++) {
- jstring strObj = static_cast<jstring>(
- env->CallObjectMethod(interfaceChainArrayList,
- gArrayListMethods.get,
- i)
- );
- const char * str = env->GetStringUTFChars(strObj, nullptr);
- strings[i] = hidl_string(str);
- env->ReleaseStringUTFChars(strObj, str);
- }
-
- hidl_vec<hidl_string> interfaceChain;
- interfaceChain.setToExternal(strings, numInterfaces, true /* shouldOwn */);
-
sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz);
/* TODO(b/33440494) this is not right */
@@ -282,7 +257,7 @@
return;
}
- Return<bool> ret = manager->add(interfaceChain, serviceName, base);
+ Return<bool> ret = manager->add(serviceName, base);
env->ReleaseStringUTFChars(serviceNameObj, serviceName);
serviceName = NULL;
@@ -385,7 +360,7 @@
"(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V",
(void *)JHwBinder_native_transact },
- { "registerService", "(Ljava/util/ArrayList;Ljava/lang/String;)V",
+ { "registerService", "(Ljava/lang/String;)V",
(void *)JHwBinder_native_registerService },
{ "getService", "(Ljava/lang/String;Ljava/lang/String;)L" PACKAGE_PATH "/IHwBinder;",
@@ -395,11 +370,6 @@
namespace android {
int register_android_os_HwBinder(JNIEnv *env) {
- jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
- gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
- gArrayListMethods.size = GetMethodIDOrDie(env, arrayListClass, "size", "()I");
- gArrayListMethods.get = GetMethodIDOrDie(env, arrayListClass, "get", "(I)Ljava/lang/Object;");
-
jclass errorClass = FindClassOrDie(env, "java/lang/Error");
gErrorClass = MakeGlobalRefOrDie(env, errorClass);
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 6bb8a2c..3d5ba79 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -522,7 +522,7 @@
* <p>The content of the bitmap is copied into the buffer as-is. This means
* that if this bitmap stores its pixels pre-multiplied
* (see {@link #isPremultiplied()}, the values in the buffer will also be
- * pre-multiplied.</p>
+ * pre-multiplied. The pixels remain in the color space of the bitmap.</p>
* <p>After this method returns, the current position of the buffer is
* updated: the position is incremented by the number of elements written
* in the buffer.</p>
@@ -562,7 +562,8 @@
* <p>Copy the pixels from the buffer, beginning at the current position,
* overwriting the bitmap's pixels. The data in the buffer is not changed
* in any way (unlike setPixels(), which converts from unpremultipled 32bit
- * to whatever the bitmap's native format is.</p>
+ * to whatever the bitmap's native format is. The pixels in the source
+ * buffer are assumed to be in the bitmap's color space.</p>
* <p>After this method returns, the current position of the buffer is
* updated: the position is incremented by the number of elements read from
* the buffer. If you need to read the bitmap from the buffer again you must
@@ -1495,7 +1496,8 @@
/**
* Returns the {@link Color} at the specified location. Throws an exception
* if x or y are out of bounds (negative or >= to the width or height
- * respectively). The returned color is a non-premultiplied ARGB value.
+ * respectively). The returned color is a non-premultiplied ARGB value in
+ * the {@link ColorSpace.Named#SRGB sRGB} color space.
*
* @param x The x coordinate (0...width-1) of the pixel to return
* @param y The y coordinate (0...height-1) of the pixel to return
@@ -1517,7 +1519,8 @@
* a packed int representing a {@link Color}. The stride parameter allows
* the caller to allow for gaps in the returned pixels array between
* rows. For normal packed results, just pass width for the stride value.
- * The returned colors are non-premultiplied ARGB values.
+ * The returned colors are non-premultiplied ARGB values in the
+ * {@link ColorSpace.Named#SRGB sRGB} color space.
*
* @param pixels The array to receive the bitmap's colors
* @param offset The first index to write into pixels[]
@@ -1610,7 +1613,8 @@
/**
* <p>Write the specified {@link Color} into the bitmap (assuming it is
* mutable) at the x,y coordinate. The color must be a
- * non-premultiplied ARGB value.</p>
+ * non-premultiplied ARGB value in the {@link ColorSpace.Named#SRGB sRGB}
+ * color space.</p>
*
* @param x The x coordinate of the pixel to replace (0...width-1)
* @param y The y coordinate of the pixel to replace (0...height-1)
@@ -1632,7 +1636,7 @@
/**
* <p>Replace pixels in the bitmap with the colors in the array. Each element
* in the array is a packed int representing a non-premultiplied ARGB
- * {@link Color}.</p>
+ * {@link Color} in the {@link ColorSpace.Named#SRGB sRGB} color space.</p>
*
* @param pixels The colors to write to the bitmap
* @param offset The index of the first color to read from pixels[]
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 49b69eb..72a9f4e 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -30,8 +30,6 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
#include <binder/IServiceManager.h>
#include <ui/PixelFormat.h>
@@ -219,13 +217,6 @@
renderThread.eglManager().initialize();
uirenderer::Caches& caches = uirenderer::Caches::getInstance();
- sp<ISurfaceComposer> composer(ComposerService::getComposerService());
- sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
- if (alloc == NULL) {
- ALOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()");
- return nullptr;
- }
-
const SkImageInfo& info = skBitmap.info();
if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
@@ -240,12 +231,14 @@
needSRGB, &internalFormat, &format, &type);
PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
- status_t error;
- sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(info.width(), info.height(), pixelFormat,
- 1, GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER
- | GraphicBuffer::USAGE_SW_READ_NEVER , &error);
+ sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
+ GraphicBuffer::USAGE_HW_TEXTURE |
+ GraphicBuffer::USAGE_SW_WRITE_NEVER |
+ GraphicBuffer::USAGE_SW_READ_NEVER,
+ std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
- if (!buffer.get()) {
+ status_t error = buffer->initCheck();
+ if (error < 0) {
ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
return nullptr;
}
diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
index 83b01e9..a461426 100644
--- a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
@@ -17,10 +17,6 @@
#include "TestSceneBase.h"
#include "utils/Color.h"
-#include <gui/IGraphicBufferAlloc.h>
-#include <gui/ISurfaceComposer.h>
-#include <private/gui/ComposerService.h>
-#include <binder/IServiceManager.h>
#include <ui/PixelFormat.h>
#include <SkGradientShader.h>
#include <SkImagePriv.h>
@@ -39,14 +35,11 @@
void createContent(int width, int height, Canvas& canvas) override {
canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
- status_t error;
- sp<ISurfaceComposer> composer(ComposerService::getComposerService());
- sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE
| GraphicBuffer::USAGE_SW_READ_NEVER
| GRALLOC_USAGE_SW_WRITE_RARELY;
- sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(400, 200, PIXEL_FORMAT_RGBA_8888, 1,
- usage, &error);
+
+ sp<GraphicBuffer> buffer = new GraphicBuffer(400, 200, PIXEL_FORMAT_RGBA_8888, usage);
unsigned char* pixels = nullptr;
buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, ((void**)&pixels));
@@ -88,4 +81,4 @@
return image->makeShader(SkShader::TileMode::kClamp_TileMode,
SkShader::TileMode::kClamp_TileMode);
}
-};
\ No newline at end of file
+};
diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java
index cb27d10..796d6f3 100644
--- a/media/java/android/media/VolumeShaper.java
+++ b/media/java/android/media/VolumeShaper.java
@@ -25,6 +25,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.AutoCloseable;
import java.lang.ref.WeakReference;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -115,6 +116,7 @@
* @param configuration
* @param operation
* @return id a non-negative shaper id.
+ * @throws IllegalStateException if the player has been deallocated or is uninitialized.
*/
private int applyPlayer(
@NonNull VolumeShaper.Configuration configuration,
@@ -147,6 +149,7 @@
* Internal call to retrieve the current VolumeShaper state.
* @param id
* @return the current {@vode VolumeShaper.State}
+ * @throws IllegalStateException if the player has been deallocated or is uninitialized.
*/
private @NonNull VolumeShaper.State getStatePlayer(int id) {
final VolumeShaper.State state;
@@ -172,10 +175,10 @@
* <p>
* A {@code VolumeShaper.Configuration} is used by
* {@link VolumeAutomation#createVolumeShaper(Configuration)
- * VolumeAutomation#createVolumeShaper(Configuration)} to create
+ * VolumeAutomation.createVolumeShaper(Configuration)} to create
* a {@code VolumeShaper} and
* by {@link VolumeShaper#replace(Configuration, Operation, boolean)
- * VolumeShaper#replace(Configuration, Operation, boolean)}
+ * VolumeShaper.replace(Configuration, Operation, boolean)}
* to replace an existing {@code configuration}.
*/
public static final class Configuration implements Parcelable {
@@ -365,31 +368,34 @@
private final int mId;
// valid when mType is TYPE_SCALE
- private final int mInterpolatorType;
private final int mOptionFlags;
private final double mDurationMs;
+ private final int mInterpolatorType;
private final float[] mTimes;
private final float[] mVolumes;
@Override
public String toString() {
- return "VolumeShaper.Configuration["
- + "mType=" + mType
+ return "VolumeShaper.Configuration{"
+ + "mType = " + mType
+ + ", mId = " + mId
+ (mType == TYPE_ID
- ? ",mId" + mId
- : ",mInterpolatorType=" + mInterpolatorType
- + ",mOptionFlags=" + mOptionFlags
- + ",mDurationMs=" + mDurationMs
- + ",mTimes[]=" + mTimes
- + ",mVolumes[]=" + mVolumes
- + "]");
+ ? "}"
+ : ", mOptionFlags = 0x" + Integer.toHexString(mOptionFlags).toUpperCase()
+ + ", mDurationMs = " + mDurationMs
+ + ", mInterpolatorType = " + mInterpolatorType
+ + ", mTimes[] = " + Arrays.toString(mTimes)
+ + ", mVolumes[] = " + Arrays.toString(mVolumes)
+ + "}");
}
@Override
public int hashCode() {
return mType == TYPE_ID
? Objects.hash(mType, mId)
- : Objects.hash(mType, mInterpolatorType, mDurationMs, mTimes, mVolumes);
+ : Objects.hash(mType, mId,
+ mOptionFlags, mDurationMs, mInterpolatorType,
+ Arrays.hashCode(mTimes), Arrays.hashCode(mVolumes));
}
@Override
@@ -397,12 +403,17 @@
if (!(o instanceof Configuration)) return false;
if (o == this) return true;
final Configuration other = (Configuration) o;
- return mType == other.mType &&
- (mType == TYPE_ID ? mId == other.mId
- : mInterpolatorType == other.mInterpolatorType
- && mDurationMs == other.mDurationMs
- && mTimes == other.mTimes
- && mVolumes == other.mVolumes);
+ // Note that exact floating point equality may not be guaranteed
+ // for a theoretically idempotent operation; for example,
+ // there are many cases where a + b - b != a.
+ return mType == other.mType
+ && mId == other.mId
+ && (mType == TYPE_ID
+ || (mOptionFlags == other.mOptionFlags
+ && mDurationMs == other.mDurationMs
+ && mInterpolatorType == other.mInterpolatorType
+ && Arrays.equals(mTimes, other.mTimes)
+ && Arrays.equals(mVolumes, other.mVolumes)));
}
@Override
@@ -412,14 +423,22 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
+ // this needs to match the native VolumeShaper.Configuration parceling
dest.writeInt(mType);
dest.writeInt(mId);
if (mType != TYPE_ID) {
- dest.writeInt(mInterpolatorType);
dest.writeInt(mOptionFlags);
dest.writeDouble(mDurationMs);
- dest.writeFloatArray(mTimes);
- dest.writeFloatArray(mVolumes);
+ // this needs to match the native Interpolator parceling
+ dest.writeInt(mInterpolatorType);
+ dest.writeFloat(0.f); // first slope
+ dest.writeFloat(0.f); // last slope
+ // mTimes and mVolumes should have the same length.
+ dest.writeInt(mTimes.length);
+ for (int i = 0; i < mTimes.length; ++i) {
+ dest.writeFloat(mTimes[i]);
+ dest.writeFloat(mVolumes[i]);
+ }
}
}
@@ -427,19 +446,34 @@
= new Parcelable.Creator<VolumeShaper.Configuration>() {
@Override
public VolumeShaper.Configuration createFromParcel(Parcel p) {
+ // this needs to match the native VolumeShaper.Configuration parceling
final int type = p.readInt();
final int id = p.readInt();
if (type == TYPE_ID) {
return new VolumeShaper.Configuration(id);
} else {
+ final int optionFlags = p.readInt();
+ final double durationMs = p.readDouble();
+ // this needs to match the native Interpolator parceling
+ final int interpolatorType = p.readInt();
+ final float firstSlope = p.readFloat(); // ignored
+ final float lastSlope = p.readFloat(); // ignored
+ final int length = p.readInt();
+ final float[] times = new float[length];
+ final float[] volumes = new float[length];
+ for (int i = 0; i < length; ++i) {
+ times[i] = p.readFloat();
+ volumes[i] = p.readFloat();
+ }
+
return new VolumeShaper.Configuration(
type,
- id, // id
- p.readInt(), // interpolatorType
- p.readInt(), // optionFlags
- p.readDouble(), // durationMs
- p.createFloatArray(), // times
- p.createFloatArray()); // volumes
+ id,
+ optionFlags,
+ durationMs,
+ interpolatorType,
+ times,
+ volumes);
}
}
@@ -482,16 +516,16 @@
*/
private Configuration(@Type int type,
int id,
- @InterpolatorType int interpolatorType,
@OptionFlag int optionFlags,
double durationMs,
+ @InterpolatorType int interpolatorType,
@NonNull float[] times,
@NonNull float[] volumes) {
mType = type;
mId = id;
- mInterpolatorType = interpolatorType;
mOptionFlags = optionFlags;
mDurationMs = durationMs;
+ mInterpolatorType = interpolatorType;
// Builder should have cloned these arrays already.
mTimes = times;
mVolumes = volumes;
@@ -568,8 +602,12 @@
* @return null if no error, or the reason in a {@code String} for an error.
*/
private static @Nullable String checkCurveForErrors(
- @NonNull float[] times, @NonNull float[] volumes, boolean log) {
- if (times.length != volumes.length) {
+ @Nullable float[] times, @Nullable float[] volumes, boolean log) {
+ if (times == null) {
+ return "times array must be non-null";
+ } else if (volumes == null) {
+ return "volumes array must be non-null";
+ } else if (times.length != volumes.length) {
return "array length must match";
} else if (times.length < 2) {
return "array length must be at least 2";
@@ -605,7 +643,15 @@
return null; // no errors
}
- private static void checkValidVolume(float volume, boolean log) {
+ private static void checkCurveForErrorsAndThrowException(
+ @Nullable float[] times, @Nullable float[] volumes, boolean log) {
+ final String error = checkCurveForErrors(times, volumes, log);
+ if (error != null) {
+ throw new IllegalArgumentException(error);
+ }
+ }
+
+ private static void checkValidVolumeAndThrowException(float volume, boolean log) {
if (log) {
if (!(volume <= 0.f) /* handle nan */) {
throw new IllegalArgumentException("dbfs volume must be 0.f or less");
@@ -678,17 +724,22 @@
mOptionFlags = configuration.getAllOptionFlags();
mInterpolatorType = configuration.getInterpolatorType();
mDurationMs = configuration.getDurationMs();
- mTimes = configuration.getTimes();
- mVolumes = configuration.getVolumes();
+ mTimes = configuration.getTimes().clone();
+ mVolumes = configuration.getVolumes().clone();
}
/**
* @hide
- * Set the id for system defined shapers.
- * @param id
- * @return
+ * Set the {@code id} for system defined shapers.
+ * @param id the {@code id} to set. If non-negative, then it is used.
+ * If -1, then the system is expected to assign one.
+ * @return the same {@code Builder} instance.
+ * @throws IllegalArgumentException if {@code id} < -1.
*/
public @NonNull Builder setId(int id) {
+ if (id < -1) {
+ throw new IllegalArgumentException("invalid id: " + id);
+ }
mId = id;
return this;
}
@@ -789,11 +840,8 @@
*/
public @NonNull Builder setCurve(@NonNull float[] times, @NonNull float[] volumes) {
- String error = checkCurveForErrors(
+ checkCurveForErrorsAndThrowException(
times, volumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
- if (error != null) {
- throw new IllegalArgumentException(error);
- }
mTimes = times.clone();
mVolumes = volumes.clone();
return this;
@@ -805,13 +853,19 @@
* to the start.
*
* @return the same {@code Builder} instance.
+ * @throws IllegalArgumentException if curve has not been set.
*/
public @NonNull Builder reflectTimes() {
+ checkCurveForErrorsAndThrowException(
+ mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
int i;
for (i = 0; i < mTimes.length / 2; ++i) {
- float temp = mTimes[0];
+ float temp = mTimes[i];
mTimes[i] = 1.f - mTimes[mTimes.length - 1 - i];
mTimes[mTimes.length - 1 - i] = 1.f - temp;
+ temp = mVolumes[i];
+ mVolumes[i] = mVolumes[mVolumes.length - 1 - i];
+ mVolumes[mVolumes.length - 1 - i] = temp;
}
if ((mTimes.length & 1) != 0) {
mTimes[i] = 1.f - mTimes[i];
@@ -824,23 +878,24 @@
* becomes the min volume and vice versa.
*
* @return the same {@code Builder} instance.
+ * @throws IllegalArgumentException if curve has not been set.
*/
public @NonNull Builder invertVolumes() {
- if (mVolumes.length >= 2) {
- float min = mVolumes[0];
- float max = mVolumes[0];
- for (int i = 1; i < mVolumes.length; ++i) {
- if (mVolumes[i] < min) {
- min = mVolumes[i];
- } else if (mVolumes[i] > max) {
- max = mVolumes[i];
- }
+ checkCurveForErrorsAndThrowException(
+ mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
+ float min = mVolumes[0];
+ float max = mVolumes[0];
+ for (int i = 1; i < mVolumes.length; ++i) {
+ if (mVolumes[i] < min) {
+ min = mVolumes[i];
+ } else if (mVolumes[i] > max) {
+ max = mVolumes[i];
}
+ }
- final float maxmin = max + min;
- for (int i = 0; i < mVolumes.length; ++i) {
- mVolumes[i] = maxmin - mVolumes[i];
- }
+ final float maxmin = max + min;
+ for (int i = 0; i < mVolumes.length; ++i) {
+ mVolumes[i] = maxmin - mVolumes[i];
}
return this;
}
@@ -853,11 +908,13 @@
*
* @param volume the target end volume to use.
* @return the same {@code Builder} instance.
- * @throws IllegalArgumentException if {@code volume} is not valid.
+ * @throws IllegalArgumentException if {@code volume}
+ * is not valid or if curve has not been set.
*/
public @NonNull Builder scaleToEndVolume(float volume) {
final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
- checkValidVolume(volume, log);
+ checkCurveForErrorsAndThrowException(mTimes, mVolumes, log);
+ checkValidVolumeAndThrowException(volume, log);
final float startVolume = mVolumes[0];
final float endVolume = mVolumes[mVolumes.length - 1];
if (endVolume == startVolume) {
@@ -885,11 +942,13 @@
*
* @param volume the target start volume to use.
* @return the same {@code Builder} instance.
- * @throws IllegalArgumentException if {@code volume} is not valid.
+ * @throws IllegalArgumentException if {@code volume}
+ * is not valid or if curve has not been set.
*/
public @NonNull Builder scaleToStartVolume(float volume) {
final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
- checkValidVolume(volume, log);
+ checkCurveForErrorsAndThrowException(mTimes, mVolumes, log);
+ checkValidVolumeAndThrowException(volume, log);
final float startVolume = mVolumes[0];
final float endVolume = mVolumes[mVolumes.length - 1];
if (endVolume == startVolume) {
@@ -911,16 +970,14 @@
/**
* Builds a new {@link VolumeShaper} object.
*
- * @return a new {@link VolumeShaper} object
+ * @return a new {@link VolumeShaper} object.
+ * @throws IllegalArgumentException if curve is not properly set.
*/
public @NonNull Configuration build() {
- String error = checkCurveForErrors(
+ checkCurveForErrorsAndThrowException(
mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
- if (error != null) {
- throw new IllegalArgumentException(error);
- }
- return new Configuration(mType, mId, mInterpolatorType, mOptionFlags,
- mDurationMs, mTimes, mVolumes);
+ return new Configuration(mType, mId, mOptionFlags, mDurationMs,
+ mInterpolatorType, mTimes, mVolumes);
}
} // Configuration.Builder
} // Configuration
@@ -1011,10 +1068,10 @@
@Override
public String toString() {
- return "VolumeShaper.Operation["
- + "mFlags=" + mFlags
- + ",mReplaceId" + mReplaceId
- + "]";
+ return "VolumeShaper.Operation{"
+ + "mFlags = 0x" + Integer.toHexString(mFlags).toUpperCase()
+ + ", mReplaceId = " + mReplaceId
+ + "}";
}
@Override
@@ -1027,6 +1084,8 @@
if (!(o instanceof Operation)) return false;
if (o == this) return true;
final Operation other = (Operation) o;
+ // if xOffset (native field only) is brought into Java
+ // we need to do proper NaN comparison as that is allowed.
return mFlags == other.mFlags
&& mReplaceId == other.mReplaceId;
}
@@ -1038,17 +1097,24 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
+ // this needs to match the native VolumeShaper.Operation parceling
dest.writeInt(mFlags);
dest.writeInt(mReplaceId);
+ dest.writeFloat(Float.NaN); // xOffset (ignored at Java level)
}
public static final Parcelable.Creator<VolumeShaper.Operation> CREATOR
= new Parcelable.Creator<VolumeShaper.Operation>() {
@Override
public VolumeShaper.Operation createFromParcel(Parcel p) {
+ // this needs to match the native VolumeShaper.Operation parceling
+ final int flags = p.readInt();
+ final int replaceId = p.readInt();
+ final float xOffset = p.readFloat(); // ignored at Java level
+
return new VolumeShaper.Operation(
- p.readInt() // flags
- , p.readInt()); // replaceId
+ flags
+ , replaceId);
}
@Override
@@ -1154,6 +1220,7 @@
*
* @param flags new value for {@code flags}, consisting of ORed flags.
* @return the same {@code Builder} instance.
+ * @throws IllegalArgumentException if {@code flags} contains invalid set bits.
*/
private @NonNull Builder setFlags(@Flag int flags) {
if ((flags & ~FLAG_PUBLIC_ALL) != 0) {
@@ -1187,10 +1254,10 @@
@Override
public String toString() {
- return "VolumeShaper.State["
- + "mVolume=" + mVolume
- + ",mXOffset" + mXOffset
- + "]";
+ return "VolumeShaper.State{"
+ + "mVolume = " + mVolume
+ + ", mXOffset = " + mXOffset
+ + "}";
}
@Override
diff --git a/media/jni/android_media_VolumeShaper.h b/media/jni/android_media_VolumeShaper.h
index dbbc478..73498a2 100644
--- a/media/jni/android_media_VolumeShaper.h
+++ b/media/jni/android_media_VolumeShaper.h
@@ -29,9 +29,9 @@
jmethodID coConstructId;
jfieldID coTypeId;
jfieldID coIdId;
- jfieldID coInterpolatorTypeId;
jfieldID coOptionFlagsId;
jfieldID coDurationMsId;
+ jfieldID coInterpolatorTypeId;
jfieldID coTimesId;
jfieldID coVolumesId;
@@ -56,12 +56,12 @@
if (coClazz == nullptr) {
return;
}
- coConstructId = env->GetMethodID(coClazz, "<init>", "(IIIID[F[F)V");
+ coConstructId = env->GetMethodID(coClazz, "<init>", "(IIIDI[F[F)V");
coTypeId = env->GetFieldID(coClazz, "mType", "I");
coIdId = env->GetFieldID(coClazz, "mId", "I");
- coInterpolatorTypeId = env->GetFieldID(coClazz, "mInterpolatorType", "I");
coOptionFlagsId = env->GetFieldID(coClazz, "mOptionFlags", "I");
coDurationMsId = env->GetFieldID(coClazz, "mDurationMs", "D");
+ coInterpolatorTypeId = env->GetFieldID(coClazz, "mInterpolatorType", "I");
coTimesId = env->GetFieldID(coClazz, "mTimes", "[F");
coVolumesId = env->GetFieldID(coClazz, "mVolumes", "[F");
env->DeleteLocalRef(lclazz);
@@ -108,14 +108,14 @@
configuration->setId(
(int)env->GetIntField(jshaper, fields.coIdId));
if (configuration->getType() == VolumeShaper::Configuration::TYPE_SCALE) {
- configuration->setInterpolatorType(
- (VolumeShaper::Configuration::InterpolatorType)
- env->GetIntField(jshaper, fields.coInterpolatorTypeId));
configuration->setOptionFlags(
(VolumeShaper::Configuration::OptionFlag)
env->GetIntField(jshaper, fields.coOptionFlagsId));
configuration->setDurationMs(
(double)env->GetDoubleField(jshaper, fields.coDurationMsId));
+ configuration->setInterpolatorType(
+ (VolumeShaper::Configuration::InterpolatorType)
+ env->GetIntField(jshaper, fields.coInterpolatorTypeId));
// convert point arrays
jobject xobj = env->GetObjectField(jshaper, fields.coTimesId);
@@ -165,9 +165,9 @@
jvalue args[7];
args[0].i = (jint)configuration->getType();
args[1].i = (jint)configuration->getId();
- args[2].i = (jint)configuration->getInterpolatorType();
- args[3].i = (jint)configuration->getOptionFlags();
- args[4].d = (jdouble)configuration->getDurationMs();
+ args[2].i = (jint)configuration->getOptionFlags();
+ args[3].d = (jdouble)configuration->getDurationMs();
+ args[4].i = (jint)configuration->getInterpolatorType();
args[5].l = xarray;
args[6].l = yarray;
jobject jshaper = env->NewObjectA(fields.coClazz, fields.coConstructId, args);
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 23a8655..6394c64 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -77,8 +77,8 @@
mCm = ConnectivityManager.from(this);
mNetwork = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
mCaptivePortal = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
- mUserAgent = getIntent().getParcelableExtra(
- ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT);
+ mUserAgent =
+ getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT);
mUrl = getUrl();
if (mUrl == null) {
// getUrl() failed to parse the url provided in the intent: bail out in a way that
@@ -274,8 +274,17 @@
if (mUserAgent != null) {
urlConnection.setRequestProperty("User-Agent", mUserAgent);
}
+ // cannot read request header after connection
+ String requestHeader = urlConnection.getRequestProperties().toString();
+
urlConnection.getInputStream();
httpResponseCode = urlConnection.getResponseCode();
+ if (DBG) {
+ Log.d(TAG, "probe at " + mUrl +
+ " ret=" + httpResponseCode +
+ " request=" + requestHeader +
+ " headers=" + urlConnection.getHeaderFields());
+ }
} catch (IOException e) {
} finally {
if (urlConnection != null) urlConnection.disconnect();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index de79d3f..5f4b239 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -553,23 +553,23 @@
}
private void doWriteState() {
+ boolean wroteState = false;
+ final int version;
+ final ArrayMap<String, Setting> settings;
+
+ synchronized (mLock) {
+ version = mVersion;
+ settings = new ArrayMap<>(mSettings);
+ mDirty = false;
+ mWriteScheduled = false;
+ }
+
synchronized (mWriteLock) {
if (DEBUG_PERSISTENCE) {
Slog.i(LOG_TAG, "[PERSIST START]");
}
AtomicFile destination = new AtomicFile(mStatePersistFile);
-
- final int version;
- final ArrayMap<String, Setting> settings;
-
- synchronized (mLock) {
- version = mVersion;
- settings = new ArrayMap<>(mSettings);
- mDirty = false;
- mWriteScheduled = false;
- }
-
FileOutputStream out = null;
try {
out = destination.startWrite();
@@ -600,9 +600,7 @@
serializer.endDocument();
destination.finishWrite(out);
- synchronized (mLock) {
- addHistoricalOperationLocked(HISTORICAL_OPERATION_PERSIST, null);
- }
+ wroteState = true;
if (DEBUG_PERSISTENCE) {
Slog.i(LOG_TAG, "[PERSIST END]");
@@ -614,6 +612,12 @@
IoUtils.closeQuietly(out);
}
}
+
+ if (wroteState) {
+ synchronized (mLock) {
+ addHistoricalOperationLocked(HISTORICAL_OPERATION_PERSIST, null);
+ }
+ }
}
static void writeSingleSetting(int version, XmlSerializer serializer, String id,
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 62e11f7..93ae763 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1164,6 +1164,8 @@
<string name="volume_stream_content_description_unmute">%1$s. Tap to unmute.</string>
<string name="volume_stream_content_description_vibrate">%1$s. Tap to set to vibrate. Accessibility services may be muted.</string>
<string name="volume_stream_content_description_mute">%1$s. Tap to mute. Accessibility services may be muted.</string>
+ <string name="volume_stream_content_description_vibrate_a11y">%1$s. Tap to set to vibrate.</string>
+ <string name="volume_stream_content_description_mute_a11y">%1$s. Tap to mute.</string>
<string name="volume_dialog_accessibility_shown_message">%s volume controls shown. Swipe up to dismiss.</string>
<string name="volume_dialog_accessibility_dismissed_message">Volume controls hidden</string>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 3559257..9da52d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -263,7 +263,6 @@
public TilePage(Context context, AttributeSet attrs) {
super(context, attrs);
updateResources();
- setContentDescription(getContext().getString(R.string.accessibility_desc_quick_settings));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 3337090..a30b03b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -175,7 +175,8 @@
View view = mQs.getView();
if (count < mNumQuickTiles && mAllowFancy) {
// Quick tiles.
- com.android.systemui.plugins.qs.QSTileView quickTileView = mQuickQsPanel.getTileView(tile);
+ QSTileView quickTileView = mQuickQsPanel.getTileView(tile);
+ if (quickTileView == null) continue;
lastX = loc1[0];
getRelativePosition(loc1, quickTileView.getIcon().getIconView(), view);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 3a93d51..63563b2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -162,8 +162,7 @@
public void setHeaderClickable(boolean clickable) {
if (DEBUG) Log.d(TAG, "setHeaderClickable " + clickable);
- mHeader.setClickable(clickable);
- mFooter.setClickable(clickable);
+ mFooter.getExpandView().setClickable(clickable);
}
public void setExpanded(boolean expanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 8c1c89f..d0d6f61 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -125,9 +125,7 @@
}
public void updateEverything() {
- post(() -> {
- setClickable(false);
- });
+ post(() -> setClickable(false));
}
public void setQSPanel(final QSPanel qsPanel) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index b320d60..1933349a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -426,34 +426,37 @@
});
row.icon = (ImageButton) row.view.findViewById(R.id.volume_row_icon);
row.icon.setImageResource(iconRes);
- row.icon.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, row.stream, row.iconState);
- mController.setActiveStream(row.stream);
- if (row.stream == AudioManager.STREAM_RING) {
- final boolean hasVibrator = mController.hasVibrator();
- if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) {
- if (hasVibrator) {
- mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false);
+ if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) {
+ row.icon.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, row.stream, row.iconState);
+ mController.setActiveStream(row.stream);
+ if (row.stream == AudioManager.STREAM_RING) {
+ final boolean hasVibrator = mController.hasVibrator();
+ if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) {
+ if (hasVibrator) {
+ mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false);
+ } else {
+ final boolean wasZero = row.ss.level == 0;
+ mController.setStreamVolume(stream,
+ wasZero ? row.lastAudibleLevel : 0);
+ }
} else {
- final boolean wasZero = row.ss.level == 0;
- mController.setStreamVolume(stream, wasZero ? row.lastAudibleLevel : 0);
+ mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false);
+ if (row.ss.level == 0) {
+ mController.setStreamVolume(stream, 1);
+ }
}
} else {
- mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false);
- if (row.ss.level == 0) {
- mController.setStreamVolume(stream, 1);
- }
+ final boolean vmute = row.ss.level == row.ss.levelMin;
+ mController.setStreamVolume(stream,
+ vmute ? row.lastAudibleLevel : row.ss.levelMin);
}
- } else {
- final boolean vmute = row.ss.level == row.ss.levelMin;
- mController.setStreamVolume(stream,
- vmute ? row.lastAudibleLevel : row.ss.levelMin);
+ row.userAttempt = 0; // reset the grace period, slider updates immediately
}
- row.userAttempt = 0; // reset the grace period, slider should update immediately
- }
- });
+ });
+ }
}
public void destroy() {
@@ -722,6 +725,7 @@
if (ss.level == row.requestedLevel) {
row.requestedLevel = -1;
}
+ final boolean isA11yStream = row.stream == AudioManager.STREAM_ACCESSIBILITY;
final boolean isRingStream = row.stream == AudioManager.STREAM_RING;
final boolean isSystemStream = row.stream == AudioManager.STREAM_SYSTEM;
final boolean isAlarmStream = row.stream == AudioManager.STREAM_ALARM;
@@ -781,14 +785,20 @@
} else {
if (mController.hasVibrator()) {
row.icon.setContentDescription(mContext.getString(
- R.string.volume_stream_content_description_vibrate,
+ mShowA11yStream
+ ? R.string.volume_stream_content_description_vibrate_a11y
+ : R.string.volume_stream_content_description_vibrate,
getStreamLabelH(ss)));
} else {
row.icon.setContentDescription(mContext.getString(
- R.string.volume_stream_content_description_mute,
+ mShowA11yStream
+ ? R.string.volume_stream_content_description_mute_a11y
+ : R.string.volume_stream_content_description_mute,
getStreamLabelH(ss)));
}
}
+ } else if (isA11yStream) {
+ row.icon.setContentDescription(getStreamLabelH(ss));
} else {
if (ss.muted || mAutomute && ss.level == 0) {
row.icon.setContentDescription(mContext.getString(
@@ -796,7 +806,9 @@
getStreamLabelH(ss)));
} else {
row.icon.setContentDescription(mContext.getString(
- R.string.volume_stream_content_description_mute,
+ mShowA11yStream
+ ? R.string.volume_stream_content_description_mute_a11y
+ : R.string.volume_stream_content_description_mute,
getStreamLabelH(ss)));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysUIRunner.java b/packages/SystemUI/tests/src/com/android/systemui/SysUIRunner.java
index 1607b70..fd99d1d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysUIRunner.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysUIRunner.java
@@ -46,7 +46,7 @@
@Override
protected Statement methodInvoker(FrameworkMethod method, Object test) {
- return UiThreadStatement.shouldRunOnUiThread(method) ? new UiThreadStatement(
+ return shouldRunOnUiThread(method) ? new UiThreadStatement(
methodInvokerInt(method, test), true) : methodInvokerInt(method, test);
}
@@ -84,4 +84,12 @@
private long getTimeout(Test annotation) {
return annotation == null ? 0L : annotation.timeout();
}
+
+ public boolean shouldRunOnUiThread(FrameworkMethod method) {
+ if (mKlass.getAnnotation(UiThreadTest.class) != null) {
+ return true;
+ } else {
+ return UiThreadStatement.shouldRunOnUiThread(method);
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/UiThreadTest.java b/packages/SystemUI/tests/src/com/android/systemui/UiThreadTest.java
new file mode 100644
index 0000000..58369b1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/UiThreadTest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.systemui;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * When applied to a class, all tests, befores, and afters will behave as if
+ * they have @UiThreadTest applied to them.
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UiThreadTest {
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 32afee9..0cccbe1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -37,11 +37,12 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.Display;
+import com.android.systemui.SysUIRunner;
+import com.android.systemui.UiThreadTest;
import com.android.systemui.statusbar.phone.DozeParameters;
import org.junit.Before;
@@ -49,7 +50,8 @@
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(SysUIRunner.class)
+@UiThreadTest
public class DozeMachineTest {
DozeMachine mMachine;
@@ -72,7 +74,6 @@
}
@Test
- @UiThreadTest
public void testInitialize_initializesParts() {
mMachine.requestState(INITIALIZED);
@@ -80,7 +81,6 @@
}
@Test
- @UiThreadTest
public void testInitialize_goesToDoze() {
when(mParamsMock.getAlwaysOn()).thenReturn(false);
@@ -91,7 +91,6 @@
}
@Test
- @UiThreadTest
public void testInitialize_goesToAod() {
when(mParamsMock.getAlwaysOn()).thenReturn(true);
@@ -102,7 +101,6 @@
}
@Test
- @UiThreadTest
public void testPulseDone_goesToDoze() {
when(mParamsMock.getAlwaysOn()).thenReturn(false);
mMachine.requestState(INITIALIZED);
@@ -116,7 +114,6 @@
}
@Test
- @UiThreadTest
public void testPulseDone_goesToAoD() {
when(mParamsMock.getAlwaysOn()).thenReturn(true);
mMachine.requestState(INITIALIZED);
@@ -130,7 +127,6 @@
}
@Test
- @UiThreadTest
public void testFinished_staysFinished() {
mMachine.requestState(INITIALIZED);
mMachine.requestState(FINISH);
@@ -143,7 +139,6 @@
}
@Test
- @UiThreadTest
public void testFinish_finishesService() {
mMachine.requestState(INITIALIZED);
@@ -153,7 +148,6 @@
}
@Test
- @UiThreadTest
public void testWakeLock_heldInTransition() {
doAnswer((inv) -> {
assertTrue(mWakeLockFake.isHeld());
@@ -164,7 +158,6 @@
}
@Test
- @UiThreadTest
public void testWakeLock_heldInPulseStates() {
mMachine.requestState(INITIALIZED);
@@ -176,7 +169,6 @@
}
@Test
- @UiThreadTest
public void testWakeLock_notHeldInDozeStates() {
mMachine.requestState(INITIALIZED);
@@ -188,7 +180,6 @@
}
@Test
- @UiThreadTest
public void testWakeLock_releasedAfterPulse() {
mMachine.requestState(INITIALIZED);
@@ -201,7 +192,6 @@
}
@Test
- @UiThreadTest
public void testPulseDuringPulse_doesntCrash() {
mMachine.requestState(INITIALIZED);
@@ -213,7 +203,6 @@
}
@Test
- @UiThreadTest
public void testSuppressingPulse_doesntCrash() {
mMachine.requestState(INITIALIZED);
@@ -223,7 +212,6 @@
}
@Test
- @UiThreadTest
public void testScreen_offInDoze() {
mMachine.requestState(INITIALIZED);
@@ -233,7 +221,6 @@
}
@Test
- @UiThreadTest
public void testScreen_onInAod() {
mMachine.requestState(INITIALIZED);
@@ -243,7 +230,6 @@
}
@Test
- @UiThreadTest
public void testScreen_onInPulse() {
mMachine.requestState(INITIALIZED);
@@ -254,7 +240,6 @@
}
@Test
- @UiThreadTest
public void testScreen_offInRequestPulseWithoutAoD() {
mMachine.requestState(INITIALIZED);
@@ -265,7 +250,6 @@
}
@Test
- @UiThreadTest
public void testScreen_onInRequestPulseWithoutAoD() {
mMachine.requestState(INITIALIZED);
@@ -276,7 +260,6 @@
}
@Test
- @UiThreadTest
public void testTransitions_canRequestTransitions() {
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
@@ -291,7 +274,6 @@
}
@Test
- @UiThreadTest
public void testWakeUp_wakesUp() {
mMachine.wakeUp();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notification/PropertyAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/notification/PropertyAnimatorTest.java
index 193250f..53053fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notification/PropertyAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/notification/PropertyAnimatorTest.java
@@ -16,7 +16,6 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
-import android.support.test.annotation.UiThreadTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
@@ -28,7 +27,9 @@
import android.view.View;
import android.view.animation.Interpolator;
+import com.android.systemui.SysUIRunner;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.UiThreadTest;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.stack.AnimationFilter;
import com.android.systemui.statusbar.stack.AnimationProperties;
@@ -49,7 +50,8 @@
import static org.mockito.Mockito.when;
@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(SysUIRunner.class)
+@UiThreadTest
public class PropertyAnimatorTest extends SysuiTestCase {
private View mView;
@@ -106,13 +108,11 @@
@Before
- @UiThreadTest
public void setUp() {
mView = new View(getContext());
}
@Test
- @UiThreadTest
public void testAnimationStarted() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
@@ -121,7 +121,6 @@
}
@Test
- @UiThreadTest
public void testNoAnimationStarted() {
mAnimationFilter.reset();
PropertyAnimator.startAnimation(mView, mProperty, 200, mAnimationProperties);
@@ -129,7 +128,6 @@
}
@Test
- @UiThreadTest
public void testEndValueUpdated() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
@@ -139,7 +137,6 @@
}
@Test
- @UiThreadTest
public void testStartTagUpdated() {
mEffectiveProperty.set(mView, 100f);
mAnimationFilter.reset();
@@ -150,7 +147,6 @@
}
@Test
- @UiThreadTest
public void testValueIsSetUnAnimated() {
mAnimationFilter.reset();
PropertyAnimator.startAnimation(mView, mProperty, 200f, mAnimationProperties);
@@ -158,7 +154,6 @@
}
@Test
- @UiThreadTest
public void testAnimationToRightValueUpdated() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
@@ -171,7 +166,6 @@
}
@Test
- @UiThreadTest
public void testAnimationToRightValueUpdateAnimated() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
@@ -185,7 +179,6 @@
}
@Test
- @UiThreadTest
public void testStartTagShiftedWhenChanging() {
mEffectiveProperty.set(mView, 100f);
mAnimationFilter.reset();
@@ -198,7 +191,6 @@
}
@Test
- @UiThreadTest
public void testUsingDuration() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
@@ -210,7 +202,6 @@
}
@Test
- @UiThreadTest
public void testUsingDelay() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
@@ -222,7 +213,6 @@
}
@Test
- @UiThreadTest
public void testUsingInterpolator() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
@@ -234,7 +224,6 @@
}
@Test
- @UiThreadTest
public void testUsingListener() {
mAnimationFilter.reset();
mAnimationFilter.animate(mProperty.getProperty());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 92f8c7c..8520bdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -44,7 +44,6 @@
import android.graphics.drawable.Drawable;
import android.service.notification.StatusBarNotification;
import android.support.test.InstrumentationRegistry;
-import android.support.test.annotation.UiThreadTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
@@ -55,7 +54,10 @@
import android.widget.TextView;
import com.android.internal.util.CharSequences;
import com.android.systemui.R;
+import com.android.systemui.SysUIRunner;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.UiThreadTest;
+
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
@@ -65,7 +67,8 @@
import java.util.concurrent.CountDownLatch;
@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(SysUIRunner.class)
+@UiThreadTest
public class NotificationInfoTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test_package";
private static final String TEST_CHANNEL = "test_channel";
@@ -79,7 +82,6 @@
mock(StatusBarNotification.class);
@Before
- @UiThreadTest
public void setUp() throws Exception {
// Inflate the layout
final LayoutInflater layoutInflater =
@@ -116,7 +118,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -126,7 +127,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsPackageIcon() throws Exception {
final Drawable iconDrawable = mock(Drawable.class);
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
@@ -138,7 +138,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
@@ -150,7 +149,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsGroupNameIfNonNull() throws Exception {
mNotificationChannel.setGroup("test_group_id");
final NotificationChannelGroup notificationChannelGroup =
@@ -169,7 +167,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsGroupName_resId() throws Exception {
when(mMockPackageManager.getText(eq(TEST_PACKAGE_NAME),
eq(R.string.legacy_vpn_name), anyObject())).thenReturn(
@@ -191,7 +188,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
@@ -200,7 +196,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsTextChannelName_resId() throws Exception {
when(mMockPackageManager.getText(eq(TEST_PACKAGE_NAME),
eq(R.string.notification_menu_accessibility), anyObject())).thenReturn(
@@ -216,7 +211,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -231,7 +225,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SettingsTextWithOneChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, (View v, int appUid) -> {}, null,
@@ -242,7 +235,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SettingsTextWithMultipleChannels() throws Exception {
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
@@ -255,7 +247,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -270,7 +261,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_NumChannelsTextHiddenWhenDefaultChannel() throws Exception {
final NotificationChannel defaultChannel = new NotificationChannel(
NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
@@ -283,7 +273,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -295,7 +284,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_NumChannelsTextScalesWithNumberOfChannels()
throws Exception {
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
@@ -308,7 +296,6 @@
}
@Test
- @UiThreadTest
public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
@@ -318,7 +305,6 @@
}
@Test
- @UiThreadTest
public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -333,7 +319,6 @@
}
@Test
- @UiThreadTest
public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
@@ -341,7 +326,6 @@
}
@Test
- @UiThreadTest
public void testHasImportanceChanged_ReturnsTrueAfterChannelDisabled() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -353,7 +337,6 @@
}
@Test
- @UiThreadTest
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
mMockStatusBarNotification, mNotificationChannel, null, null, null);
@@ -362,7 +345,6 @@
}
@Test
- @UiThreadTest
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -375,7 +357,6 @@
}
@Test
- @UiThreadTest
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -387,7 +368,6 @@
}
@Test
- @UiThreadTest
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()
throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
@@ -400,7 +380,6 @@
}
@Test
- @UiThreadTest
public void testEnabledSwitchOnByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -411,7 +390,6 @@
}
@Test
- @UiThreadTest
public void testEnabledButtonOffWhenAlreadyBanned() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -422,7 +400,6 @@
}
@Test
- @UiThreadTest
public void testEnabledSwitchVisibleByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -433,7 +410,6 @@
}
@Test
- @UiThreadTest
public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -445,7 +421,6 @@
}
@Test
- @UiThreadTest
public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -460,7 +435,6 @@
}
@Test
- @UiThreadTest
public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
diff --git a/proto/src/ipconnectivity.proto b/proto/src/ipconnectivity.proto
index b5afc40..76c5418 100644
--- a/proto/src/ipconnectivity.proto
+++ b/proto/src/ipconnectivity.proto
@@ -9,6 +9,8 @@
// NetworkId represents the id given by the system to a physical network on the
// Android device. It is used to relates events to each other for devices with
// multiple networks (WiFi, 4G, ...).
+// Deprecated since version 3, replaced by top-level network_id field in
+// IpConnectivityEvent.
message NetworkId {
// Every network gets assigned a network_id on creation based on order of
// creation. Thus network_id N is assigned to the network created directly
@@ -91,7 +93,8 @@
// This message is associated to android.net.metrics.NetworkEvent.
message NetworkEvent {
// The id of the network on which this event happened.
- optional NetworkId network_id = 1;
+ // Deprecated since version 3.
+ optional NetworkId network_id = 1 [deprecated = true];
// The type of network event, represented by NETWORK_* constants defined in
// android.net.metrics.NetworkEvent.
@@ -107,7 +110,8 @@
// This message is associated to android.net.metrics.ValidationProbeEvent.
message ValidationProbeEvent {
// The id of the network for which the probe was sent.
- optional NetworkId network_id = 1;
+ // Deprecated since version 3.
+ optional NetworkId network_id = 1 [deprecated = true];
// The time it took for that probe to complete or time out.
optional int32 latency_ms = 2;
@@ -167,18 +171,28 @@
// Represents latency and errno statistics of the connect() system call.
// Since version 2.
+// Next tag: 7
message ConnectStatistics {
// The number of connect() operations recorded.
optional int32 connect_count = 1;
+ // The number of connect() operations done in blocking mode.
+ // Since version 3.
+ optional int32 connect_blocking_count = 5;
+
// The number of connect() operations with IPv6 socket address.
optional int32 ipv6_addr_count = 2;
- // The time it took for each successful connect() operation to complete.
- // The number of repeated values can be less than connect_count in case of
- // event rate-limiting.
+ // The time it took for successful blocking connect() operations to complete
+ // The number of repeated values can be less than connect_blocking_count in
+ // case of event rate-limiting.
repeated int32 latencies_ms = 3;
+ // The time it took for successful connect() operation to complete in
+ // non-blocking mode. The number of repeated values can be less than
+ // connect_count - connect_blocking_count in case of event rate-limiting.
+ repeated int32 non_blocking_latencies_ms = 6;
+
// Counts of all error values returned by failed connect() operations.
// The Pair key field is the errno code. The Pair value field is the count
// for that errno code.
@@ -212,10 +226,15 @@
// Represents the generation of an Android Packet Filter program.
// Since version 1.
+// Next tag: 8
message ApfProgramEvent {
- // Lifetime of the program in seconds.
+ // Maximum lifetime of the program in seconds.
optional int64 lifetime = 1;
+ // Effective lifetime of the program in seconds from the time the
+ // program was installed to the time it was replaced or removed.
+ optional int64 effective_lifetime = 7;
+
// Number of RAs filtered by the APF program.
optional int32 filtered_ras = 2;
@@ -236,6 +255,7 @@
// Represents Router Advertisement listening statistics for an interface with
// Android Packet Filter enabled.
// Since version 1.
+// Next tag: 12
message ApfStatistics {
// The time interval in milliseconds these stastistics cover.
optional int64 duration_ms = 1;
@@ -261,6 +281,14 @@
// The maximum APF program size in byte advertised by hardware.
optional int32 max_program_size = 9;
+
+ // The total number of successful APF program updates triggered by any state
+ // change in ApfFilter. Since version 3.
+ optional int32 program_updates_all = 10;
+
+ // The total number of APF program updates triggered when disabling the
+ // multicast filter. Since version 3.
+ optional int32 program_updates_allowing_multicast = 11;
}
// Represents the reception of a Router Advertisement packet for an interface
@@ -308,7 +336,7 @@
}
// Represents one of the IP connectivity event defined in this file.
-// Next tag: 16
+// Next tag: 19
message IpConnectivityEvent {
// Time in ms when the event was recorded.
optional int64 time_ms = 1;
@@ -318,7 +346,27 @@
// Since version 2.
optional LinkLayer link_layer = 15;
- // Event type.
+ // Represents the id given by the system to a physical network on the device.
+ // Every network gets assigned a unique id on creation from a monotonic
+ // counter. The value 0 is never assigned to a network and means no network.
+ // It is used to correlate different types of events to each other for devices
+ // with multiple networks (WiFi, 4G, ...).
+ // Since version 3.
+ optional int32 network_id = 16;
+
+ // The interface name (wlan, rmnet, lo, ...) on which the event happened.
+ // Present if the link_layer field was not inferred from the if_name on
+ // the device, so that post-processing of the serialized proto can backfill
+ // link_layer. Since version 3.
+ optional string if_name = 17;
+
+ // The transport types of the network on which the event happened, expressed
+ // as a bit field of TRANSPORT_* constants as defined in NetworkCapabilities.
+ // Present if the link_layer field was not inferred from the transport types,
+ // so that post-processing of the serialized proto can backfill link_layer
+ // Since version 3.
+ optional int64 transports = 18;
+
oneof event {
// An event about the system default network.
@@ -371,9 +419,10 @@
optional int32 dropped_events = 2;
// The version number of the metrics events being collected.
- // nyc-dev: not populated, implicitly 0.
+ // nyc: not populated, implicitly 0.
// nyc-dr1: not populated, implicitly 1 (sailfish and marlin only).
// nyc-mr1: not populated, implicitly 1.
// nyc-mr2: 2.
+ // oc: 3.
optional int32 version = 3;
};
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index 40491e91..e943c4c 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -305,14 +305,23 @@
}
@Override
+ public void setHasCallback(IBinder activityToken, int userId, boolean hasIt) {
+ synchronized (mLock) {
+ final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+ service.setHasCallback(activityToken, hasIt);
+ }
+ }
+
+ @Override
public void startSession(IBinder activityToken, IBinder windowToken, IBinder appCallback,
- AutoFillId autoFillId, Rect bounds, AutoFillValue value, int userId) {
+ AutoFillId autoFillId, Rect bounds, AutoFillValue value, int userId,
+ boolean hasCallback) {
// TODO(b/33197203): make sure it's called by resumed / focused activity
synchronized (mLock) {
final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
service.startSessionLocked(activityToken, windowToken, appCallback,
- autoFillId, bounds, value);
+ autoFillId, bounds, value, hasCallback);
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index 5e852f1..aa0840c 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -274,15 +274,25 @@
}
}
+ void setHasCallback(IBinder activityToken, boolean hasIt) {
+ if (!hasService()) {
+ return;
+ }
+ final Session session = mSessions.get(activityToken);
+ if (session != null) {
+ session.setHasCallback(hasIt);
+ }
+ }
+
void startSessionLocked(IBinder activityToken, IBinder windowToken, IBinder appCallbackToken,
- AutoFillId autoFillId, Rect bounds, AutoFillValue value) {
+ AutoFillId autoFillId, Rect bounds, AutoFillValue value, boolean hasCallback) {
if (!hasService()) {
return;
}
final String historyItem = "s=" + mInfo.getServiceInfo().packageName
+ " u=" + mUserId + " a=" + activityToken
- + " i=" + autoFillId + " b=" + bounds;
+ + " i=" + autoFillId + " b=" + bounds + " hc=" + hasCallback;
mRequestsHistory.log(historyItem);
// TODO(b/33197203): Handle partitioning
@@ -293,7 +303,7 @@
}
final Session newSession = createSessionByTokenLocked(activityToken,
- windowToken, appCallbackToken);
+ windowToken, appCallbackToken, hasCallback);
newSession.updateLocked(autoFillId, bounds, value, FLAG_START_SESSION);
}
@@ -312,9 +322,9 @@
}
private Session createSessionByTokenLocked(IBinder activityToken, IBinder windowToken,
- IBinder appCallbackToken) {
+ IBinder appCallbackToken, boolean hasCallback) {
final Session newSession = new Session(mContext, activityToken,
- windowToken, appCallbackToken);
+ windowToken, appCallbackToken, hasCallback);
mSessions.put(activityToken, newSession);
/*
@@ -599,12 +609,18 @@
@GuardedBy("mLock")
private AssistStructure mStructure;
+ /**
+ * Whether the client has an {@link android.view.autofill.AutoFillManager.AutofillCallback}.
+ */
+ private boolean mHasCallback;
+
private Session(Context context, IBinder activityToken, IBinder windowToken,
- IBinder client) {
+ IBinder client, boolean hasCallback) {
mRemoteFillService = new RemoteFillService(context,
mInfo.getServiceInfo().getComponentName(), mUserId, this);
mActivityToken = activityToken;
mWindowToken = windowToken;
+ mHasCallback = hasCallback;
mClient = IAutoFillManagerClient.Stub.asInterface(client);
try {
@@ -712,6 +728,22 @@
.sendToTarget();
}
+ // AutoFillUiCallback
+ @Override
+ public void cancelSave() {
+ mHandlerCaller.getHandler().post(() -> {
+ removeSelf();
+ });
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void onEvent(AutoFillId id, int event) {
+ mHandlerCaller.getHandler().post(() -> {
+ notifyChangeToClient(id, event);
+ });
+ }
+
public void setAuthenticationResultLocked(Bundle data) {
if (mCurrentResponse == null || data == null) {
removeSelf();
@@ -731,6 +763,10 @@
}
}
+ public void setHasCallback(boolean hasIt) {
+ mHasCallback = hasIt;
+ }
+
/**
* Show the save UI, when session can be saved.
*/
@@ -814,6 +850,7 @@
node.updateAutoFillValue(value);
}
+ // Sanitize structure before it's sent to service.
mStructure.sanitizeForParceling(false);
if (VERBOSE) {
@@ -871,7 +908,7 @@
if ((flags & FLAG_FOCUS_GAINED) != 0) {
// Remove the UI if the ViewState has changed.
if (mCurrentViewState != viewState) {
- mUi.hideFillUi();
+ mUi.hideFillUi(mCurrentViewState != null ? mCurrentViewState.mId : null);
mCurrentViewState = viewState;
}
@@ -888,7 +925,7 @@
if ((flags & FLAG_FOCUS_LOST) != 0) {
if (mCurrentViewState == viewState) {
- mUi.hideFillUi();
+ mUi.hideFillUi(viewState.mId);
mCurrentViewState = null;
}
return;
@@ -912,6 +949,15 @@
getUiForShowing().showFillUi(filledId, response, bounds, filterText);
}
+ private void notifyChangeToClient(AutoFillId id, int event) {
+ if (!mHasCallback) return;
+ try {
+ mClient.onAutofillEvent(mWindowToken, id, event);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error notifying client on change: id=" + id + ", event=" + event, e);
+ }
+ }
+
private void processResponseLocked(FillResponse response) {
if (DEBUG) {
Slog.d(TAG, "processResponseLocked(auth=" + response.getAuthentication()
@@ -993,7 +1039,7 @@
pw.println("null");
}
}
-
+ pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
mRemoteFillService.dump(prefix, pw);
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 7058248..d9f9721 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -182,11 +182,8 @@
if (mDestroyed || mCompleted) {
return;
}
- if (pendingRequest.isFinal()) {
- mCompleted = true;
- }
if (!isBound()) {
- if (mPendingRequest != null) {
+ if (mPendingRequest != null && mPendingRequest != pendingRequest) {
mPendingRequest.cancel();
}
mPendingRequest = pendingRequest;
@@ -196,6 +193,9 @@
Slog.d(LOG_TAG, "[user: " + mUserId + "] handlePendingRequest()");
}
pendingRequest.run();
+ if (pendingRequest.isFinal()) {
+ mCompleted = true;
+ }
}
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index f00d6c5..599bbfe 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -15,6 +15,9 @@
*/
package com.android.server.autofill.ui;
+import static android.view.autofill.AutoFillManager.AutofillCallback.EVENT_INPUT_HIDDEN;
+import static android.view.autofill.AutoFillManager.AutofillCallback.EVENT_INPUT_SHOWN;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -26,8 +29,8 @@
import android.service.autofill.FillResponse;
import android.service.autofill.SaveInfo;
import android.text.TextUtils;
-import android.util.Slog;
import android.text.format.DateUtils;
+import android.util.Slog;
import android.view.autofill.AutoFillId;
import android.widget.Toast;
@@ -62,6 +65,8 @@
void authenticate(@NonNull IntentSender intent);
void fill(@NonNull Dataset dataset);
void save();
+ void cancelSave();
+ void onEvent(AutoFillId id, int event);
}
public AutoFillUI(@NonNull Context context) {
@@ -97,8 +102,13 @@
/**
* Hides the fill UI.
*/
- public void hideFillUi() {
- mHandler.post(this::hideFillUiUiThread);
+ public void hideFillUi(AutoFillId id) {
+ mHandler.post(() -> {
+ hideFillUiUiThread();
+ if (mCallback != null) {
+ mCallback.onEvent(id, EVENT_INPUT_HIDDEN);
+ }
+ });
}
/**
@@ -175,6 +185,7 @@
// TODO(b/33197203): add MetricsLogger call
}
});
+ mCallback.onEvent(focusedId, EVENT_INPUT_SHOWN);
});
}
@@ -210,6 +221,9 @@
+ listener, e);
}
}
+ if (mCallback != null) {
+ mCallback.cancelSave();
+ }
}
}, mSaveTimeoutMs);
});
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 81f137e..c9dd116 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -678,7 +678,7 @@
pw.println("Battery service (battery) commands:");
pw.println(" help");
pw.println(" Print this help text.");
- pw.println(" set [-f] [ac|usb|wireless|status|level|invalid] <value>");
+ pw.println(" set [-f] [ac|usb|wireless|status|level|present|invalid] <value>");
pw.println(" Force a battery property value, freezing battery state.");
pw.println(" -f: force a battery change broadcast be sent, prints new sequence.");
pw.println(" unplug [-f]");
@@ -748,6 +748,9 @@
}
boolean update = true;
switch (key) {
+ case "present":
+ mBatteryProps.batteryPresent = Integer.parseInt(value) != 0;
+ break;
case "ac":
mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
break;
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index abdcfe7..b3f1548 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -46,9 +46,9 @@
/**
* set to true so the framework enforces ducking itself, without communicating to apps
- * that they lost focus.
+ * that they lost focus for most use cases.
*/
- static final boolean ENFORCE_DUCKING = false;
+ static final boolean ENFORCE_DUCKING = true;
/**
* set to true so the framework enforces muting media/game itself when the device is ringing
* or in a call.
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 6932427..82a0ff6 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -309,7 +309,7 @@
return false;
} else {
try {
- if (DEBUG) { Log.v(TAG, "ducking player " + piid); }
+ Log.v(TAG, "ducking player " + piid);
apc.getPlayerProxy().applyVolumeShaper(
DUCK_VSHAPE,
PLAY_CREATE_IF_NEEDED);
@@ -339,7 +339,7 @@
if (apc != null
&& winner.hasSameUid(apc.getClientUid())) {
try {
- if (DEBUG) { Log.v(TAG, "unducking player" + piid); }
+ Log.v(TAG, "unducking player" + piid);
mDuckedPlayers.remove(new Integer(piid));
apc.getPlayerProxy().applyVolumeShaper(
DUCK_ID,
@@ -381,11 +381,11 @@
}
if (mute) {
try {
- if (DEBUG) { Log.v(TAG, "muting player" + piid); }
+ Log.v(TAG, "call: muting player" + piid);
apc.getPlayerProxy().setVolume(0.0f);
mMutedPlayers.add(piid);
} catch (Exception e) {
- Log.e(TAG, "Error muting player " + piid, e);
+ Log.e(TAG, "call: error muting player " + piid, e);
}
}
}
@@ -405,10 +405,10 @@
final AudioPlaybackConfiguration apc = mPlayers.get(piid);
if (apc != null) {
try {
- if (DEBUG) { Log.v(TAG, "unmuting player" + piid); }
+ Log.v(TAG, "call: unmuting player" + piid);
apc.getPlayerProxy().setVolume(1.0f);
} catch (Exception e) {
- Log.e(TAG, "Error unmuting player " + piid, e);
+ Log.e(TAG, "call: error unmuting player " + piid, e);
}
}
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index fbda901..cf33313 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -790,6 +790,8 @@
if (userAgent != null) {
urlConnection.setRequestProperty("User-Agent", userAgent);
}
+ // cannot read request header after connection
+ String requestHeader = urlConnection.getRequestProperties().toString();
// Time how long it takes to get a response to our request
long requestTimestamp = SystemClock.elapsedRealtime();
@@ -803,6 +805,7 @@
validationLog(ValidationProbeEvent.getProbeName(probeType) + " " + url +
" time=" + (responseTimestamp - requestTimestamp) + "ms" +
" ret=" + httpResponseCode +
+ " request=" + requestHeader +
" headers=" + urlConnection.getHeaderFields());
// NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
// portal. The only example of this seen so far was a captive portal. For
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index bed269c..0ef0561 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -705,11 +705,14 @@
mAppliedDimming = false;
}
- // If low power mode is enabled, cut the brightness level by half
+ // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
// as long as it is above the minimum threshold.
if (mPowerRequest.lowPowerMode) {
if (brightness > mScreenBrightnessRangeMinimum) {
- brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum);
+ final float brightnessFactor =
+ Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
+ final int lowPowerBrightness = (int) (brightness * brightnessFactor);
+ brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
}
if (!mAppliedLowPower) {
slowChange = false;
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 4c6b832..fc86d68 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1659,6 +1659,17 @@
}
@Override
+ public void setStandbyMode(final boolean isStandbyModeOn) {
+ enforceAccessPermission();
+ runOnServiceThread(new Runnable() {
+ @Override
+ public void run() {
+ HdmiControlService.this.setStandbyMode(isStandbyModeOn);
+ }
+ });
+ }
+
+ @Override
protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
@@ -2203,6 +2214,29 @@
}
}
+ void setStandbyMode(boolean isStandbyModeOn) {
+ assertRunOnServiceThread();
+ if (isPowerOnOrTransient() && isStandbyModeOn) {
+ mPowerManager.goToSleep(SystemClock.uptimeMillis(),
+ PowerManager.GO_TO_SLEEP_REASON_HDMI, 0);
+ if (playback() != null) {
+ playback().sendStandby(0 /* unused */);
+ }
+ } else if (isPowerStandbyOrTransient() && !isStandbyModeOn) {
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.hdmi:WAKE");
+ if (playback() != null) {
+ oneTouchPlay(new IHdmiControlCallback.Stub() {
+ @Override
+ public void onComplete(int result) {
+ if (result != HdmiControlManager.RESULT_SUCCESS) {
+ Slog.w(TAG, "Failed to complete 'one touch play'. result=" + result);
+ }
+ }
+ });
+ }
+ }
+ }
+
boolean isProhibitMode() {
synchronized (mLock) {
return mProhibitMode;
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 1af541d..2026c1b 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -504,6 +504,25 @@
}
@Override
+ public boolean setEnabledExclusive(@Nullable final String packageName, final boolean enable,
+ int userId) throws RemoteException {
+ enforceChangeOverlayPackagesPermission("setEnabled");
+ userId = handleIncomingUser(userId, "setEnabled");
+ if (packageName == null) {
+ return false;
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ return mImpl.setEnabledExclusive(packageName, enable, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
public boolean setPriority(@Nullable final String packageName,
@Nullable final String parentPackageName, int userId) throws RemoteException {
enforceChangeOverlayPackagesPermission("setPriority");
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index ed49383..b085179 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -301,6 +301,38 @@
}
}
+ boolean setEnabledExclusive(@NonNull final String packageName, final boolean enable,
+ final int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d",
+ packageName, enable, userId));
+ }
+
+ final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
+ if (overlayPackage == null) {
+ return false;
+ }
+
+ try {
+ final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
+ List<OverlayInfo> allOverlays = getOverlayInfosForTarget(oi.targetPackageName, userId);
+
+ // Disable all other overlays.
+ allOverlays.remove(oi);
+ for (int i = 0; i < allOverlays.size(); i++) {
+ mSettings.setEnabled(allOverlays.get(i).packageName, userId, false);
+ }
+
+ final PackageInfo targetPackage =
+ mPackageManager.getPackageInfo(oi.targetPackageName, userId);
+ mSettings.setEnabled(packageName, userId, enable);
+ updateState(targetPackage, overlayPackage, userId);
+ return true;
+ } catch (OverlayManagerSettings.BadKeyException e) {
+ return false;
+ }
+ }
+
boolean setPriority(@NonNull final String packageName,
@NonNull final String newParentPackageName, final int userId) {
return mSettings.setPriority(packageName, newParentPackageName, userId);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index cd63527..c58b527 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -35,7 +35,6 @@
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
-import android.os.PowerSaveState;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -44,6 +43,7 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
+import android.os.PowerSaveState;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -69,6 +69,7 @@
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.WindowManagerPolicy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BackgroundThread;
@@ -628,6 +629,21 @@
}
}
+ @VisibleForTesting
+ PowerManagerService(Context context, BatterySaverPolicy batterySaverPolicy) {
+ super(context);
+
+ mBatterySaverPolicy = batterySaverPolicy;
+ mContext = context;
+ mHandlerThread = new ServiceThread(TAG,
+ Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
+ mHandlerThread.start();
+ mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
+ mConstants = new Constants(mHandler);
+ mDisplaySuspendBlocker = null;
+ mWakeLockSuspendBlocker = null;
+ }
+
@Override
public void onStart() {
publishBinderService(Context.POWER_SERVICE, new BinderService());
@@ -2260,9 +2276,10 @@
mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
- mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
+ updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
+
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND
@@ -2679,6 +2696,14 @@
}
}
+ @VisibleForTesting
+ void updatePowerRequestFromBatterySaverPolicy(DisplayPowerRequest displayPowerRequest) {
+ PowerSaveState state = mBatterySaverPolicy.
+ getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS, mLowPowerModeEnabled);
+ displayPowerRequest.lowPowerMode = state.batterySaverEnabled;
+ displayPowerRequest.screenLowPowerBrightnessFactor = state.brightnessFactor;
+ }
+
void setStayOnSettingInternal(int val) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 36ae94b..78d8b53 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1175,7 +1175,7 @@
}
sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
- if (gnssNiCbIface != nullptr) {
+ if (gnssNiIface != nullptr) {
gnssNiIface->setCallback(gnssNiCbIface);
} else {
ALOGE("Unable to initialize GNSS NI interface\n");
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
new file mode 100644
index 0000000..967b0a4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.power;
+
+import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.os.PowerSaveState;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link com.android.server.power.PowerManagerService}
+ */
+public class PowerManagerServiceTest extends AndroidTestCase {
+ private static final float PRECISION = 0.001f;
+ private static final float BRIGHTNESS_FACTOR = 0.7f;
+ private static final boolean BATTERY_SAVER_ENABLED = true;
+
+ private @Mock BatterySaverPolicy mBatterySaverPolicy;
+ private PowerManagerService mService;
+ private PowerSaveState mPowerSaveState;
+ private DisplayPowerRequest mDisplayPowerRequest;
+
+ public void setUp() throws Exception {
+ super.setUp();
+ MockitoAnnotations.initMocks(this);
+
+ mPowerSaveState = new PowerSaveState.Builder()
+ .setBatterySaverEnabled(BATTERY_SAVER_ENABLED)
+ .setBrightnessFactor(BRIGHTNESS_FACTOR)
+ .build();
+ when(mBatterySaverPolicy.getBatterySaverPolicy(
+ eq(BatterySaverPolicy.ServiceType.SCREEN_BRIGHTNESS), anyBoolean()))
+ .thenReturn(mPowerSaveState);
+ mDisplayPowerRequest = new DisplayPowerRequest();
+ mService = new PowerManagerService(getContext(), mBatterySaverPolicy);
+ }
+
+ @SmallTest
+ public void testUpdatePowerScreenPolicy_UpdateDisplayPowerRequest() {
+ mService.updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
+ assertThat(mDisplayPowerRequest.lowPowerMode).isEqualTo(BATTERY_SAVER_ENABLED);
+ assertThat(mDisplayPowerRequest.screenLowPowerBrightnessFactor)
+ .isWithin(PRECISION).of(BRIGHTNESS_FACTOR);
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 058de05..40bdaa5 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -497,6 +497,7 @@
//
// Devices List
//
+/*
public ArrayList<UsbAudioDevice> getConnectedDevices() {
ArrayList<UsbAudioDevice> devices = new ArrayList<UsbAudioDevice>(mAudioDevices.size());
for (HashMap.Entry<UsbDevice,UsbAudioDevice> entry : mAudioDevices.entrySet()) {
@@ -504,6 +505,7 @@
}
return devices;
}
+*/
//
// Logging
@@ -519,6 +521,7 @@
}
}
+/*
public void logDevicesList(String title) {
if (DEBUG) {
for (HashMap.Entry<UsbDevice,UsbAudioDevice> entry : mAudioDevices.entrySet()) {
@@ -528,15 +531,19 @@
Slog.i(TAG, "" + entry.getValue());
}
}
- }
+ }
+*/
- // This logs a more terse (and more readable) version of the devices list
- public void logDevices(String title) {
+ // This logs a more terse (and more readable) version of the devices list
+/*
+ public void logDevices(String title) {
if (DEBUG) {
Slog.i(TAG, title);
for (HashMap.Entry<UsbDevice,UsbAudioDevice> entry : mAudioDevices.entrySet()) {
Slog.i(TAG, entry.getValue().toShortString());
}
}
- }
+ }
+*/
+
}
diff --git a/services/usb/java/com/android/server/usb/UsbAudioDevice.java b/services/usb/java/com/android/server/usb/UsbAudioDevice.java
index bdd28e4..70d1fc6 100644
--- a/services/usb/java/com/android/server/usb/UsbAudioDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbAudioDevice.java
@@ -20,10 +20,10 @@
private static final String TAG = "UsbAudioDevice";
protected static final boolean DEBUG = false;
- public int mCard;
- public int mDevice;
- public boolean mHasPlayback;
- public boolean mHasCapture;
+ public final int mCard;
+ public final int mDevice;
+ public final boolean mHasPlayback;
+ public final boolean mHasCapture;
// Device "class" flags
public static final int kAudioDeviceClassMask = 0x00FFFFFF;
@@ -34,7 +34,7 @@
public static final int kAudioDeviceMetaMask = 0xFF000000;
public static final int kAudioDeviceMeta_Alsa = 0x80000000;
// This member is a combination of the above bit-flags
- public int mDeviceClass;
+ public final int mDeviceClass;
public String mDeviceName = "";
public String mDeviceDescription = "";
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index b1df0af..a17676a 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -749,7 +749,7 @@
mMidiCard = scanner.nextInt();
mMidiDevice = scanner.nextInt();
} catch (FileNotFoundException e) {
- Slog.e(TAG, "could not open MIDI PCM file", e);
+ Slog.e(TAG, "could not open MIDI file", e);
enabled = false;
} finally {
if (scanner != null) {
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathDestructionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathDestructionActivity.java
index 4177725..5cede65 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/PathDestructionActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathDestructionActivity.java
@@ -25,6 +25,8 @@
import android.util.MathUtils;
import android.view.View;
+import java.util.Random;
+
/**
* The point of this test is to ensure that we can cause many paths to be created, drawn,
* and destroyed without causing hangs or crashes. This tests the native reference counting
@@ -57,10 +59,11 @@
private Path getRandomPath() {
float left, top, right, bottom;
- left = MathUtils.random(getWidth() - MIN_SIZE);
- top = MathUtils.random(getHeight() - MIN_SIZE);
- right = left + MathUtils.random(getWidth() - left);
- bottom = top + MathUtils.random(getHeight() - top);
+ Random r = new Random();
+ left = r.nextFloat() * (getWidth() - MIN_SIZE);
+ top = r.nextFloat() * (getHeight() - MIN_SIZE);
+ right = left + r.nextFloat() * (getWidth() - left);
+ bottom = top + r.nextFloat() * (getHeight() - top);
Path path = new Path();
path.moveTo(left, top);
path.lineTo(right, top);
@@ -71,9 +74,10 @@
}
private int getRandomColor() {
- int red = MathUtils.random(255);
- int green = MathUtils.random(255);
- int blue = MathUtils.random(255);
+ Random r = new Random();
+ int red = r.nextInt(255);
+ int green = r.nextInt(255);
+ int blue = r.nextInt(255);
return 0xff000000 | red << 16 | green << 8 | blue;
}
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index 415911e..11105d6 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -43,6 +43,7 @@
import java.util.Arrays;
import junit.framework.TestCase;
+// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
public class IpConnectivityEventBuilderTest extends TestCase {
@SmallTest
@@ -58,8 +59,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" default_network_event <",
" network_id <",
" network_id: 102",
@@ -89,8 +93,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" dhcp_event <",
" duration_ms: 192",
" if_name: \"wlan0\"",
@@ -112,8 +119,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" dhcp_event <",
" duration_ms: 0",
" if_name: \"wlan0\"",
@@ -137,8 +147,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" dns_lookup_batch <",
" event_types: 1",
" event_types: 1",
@@ -185,8 +198,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" ip_provisioning_event <",
" event_type: 1",
" if_name: \"wlan0\"",
@@ -208,8 +224,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" ip_reachability_event <",
" event_type: 512",
" if_name: \"wlan0\"",
@@ -231,8 +250,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" network_event <",
" event_type: 5",
" latency_ms: 20410",
@@ -258,8 +280,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" validation_probe_event <",
" latency_ms: 40730",
" network_id <",
@@ -287,11 +312,15 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" apf_program_event <",
" current_ras: 9",
" drop_multicast: true",
+ " effective_lifetime: 0",
" filtered_ras: 7",
" has_ipv4_addr: true",
" lifetime: 200",
@@ -319,8 +348,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" apf_statistics <",
" dropped_ras: 2",
" duration_ms: 45000",
@@ -328,6 +360,8 @@
" max_program_size: 2048",
" parse_errors: 2",
" program_updates: 4",
+ " program_updates_all: 0",
+ " program_updates_allowing_multicast: 0",
" received_ras: 10",
" zero_lifetime_ras: 1",
" >",
@@ -351,8 +385,11 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 1",
+ " transports: 0",
" ra_event <",
" dnssl_lifetime: -1",
" prefix_preferred_lifetime: 300",
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index f56f3f8..1f7c5f4 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -139,6 +139,7 @@
@SmallTest
public void testEndToEndLogging() {
+ // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
Parcelable[] events = {
@@ -158,16 +159,22 @@
String want = joinLines(
"dropped_events: 0",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 100",
+ " transports: 0",
" ip_reachability_event <",
" event_type: 512",
" if_name: \"wlan0\"",
" >",
">",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 200",
+ " transports: 0",
" dhcp_event <",
" duration_ms: 192",
" if_name: \"wlan0\"",
@@ -175,8 +182,11 @@
" >",
">",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 300",
+ " transports: 0",
" default_network_event <",
" network_id <",
" network_id: 102",
@@ -191,8 +201,11 @@
" >",
">",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 400",
+ " transports: 0",
" ip_provisioning_event <",
" event_type: 1",
" if_name: \"wlan0\"",
@@ -200,8 +213,11 @@
" >",
">",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 500",
+ " transports: 0",
" validation_probe_event <",
" latency_ms: 40730",
" network_id <",
@@ -212,8 +228,11 @@
" >",
">",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 600",
+ " transports: 0",
" apf_statistics <",
" dropped_ras: 2",
" duration_ms: 45000",
@@ -221,13 +240,18 @@
" max_program_size: 2048",
" parse_errors: 2",
" program_updates: 4",
+ " program_updates_all: 0",
+ " program_updates_allowing_multicast: 0",
" received_ras: 10",
" zero_lifetime_ras: 1",
" >",
">",
"events <",
+ " if_name: \"\"",
" link_layer: 0",
+ " network_id: 0",
" time_ms: 700",
+ " transports: 0",
" ra_event <",
" dnssl_lifetime: -1",
" prefix_preferred_lifetime: 300",
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index cfd5598..637eaa3 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -213,9 +213,13 @@
IpConnectivityEvent got = events.get(0);
String want = String.join("\n",
+ "if_name: \"\"",
"link_layer: 0",
+ "network_id: 0",
"time_ms: 0",
+ "transports: 0",
"connect_statistics <",
+ " connect_blocking_count: 0",
" connect_count: 12",
" errnos_counters <",
" key: 1",