Merge "Add hidden API on light greylist" into pi-dev
diff --git a/api/current.txt b/api/current.txt
index 60a81c8..7b627a8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21545,10 +21545,10 @@
method public int getAccumulatedDeltaRangeState();
method public double getAccumulatedDeltaRangeUncertaintyMeters();
method public double getAutomaticGainControlLevelDb();
- method public long getCarrierCycles();
+ method public deprecated long getCarrierCycles();
method public float getCarrierFrequencyHz();
- method public double getCarrierPhase();
- method public double getCarrierPhaseUncertainty();
+ method public deprecated double getCarrierPhase();
+ method public deprecated double getCarrierPhaseUncertainty();
method public double getCn0DbHz();
method public int getConstellationType();
method public int getMultipathIndicator();
@@ -21561,13 +21561,15 @@
method public int getSvid();
method public double getTimeOffsetNanos();
method public boolean hasAutomaticGainControlLevelDb();
- method public boolean hasCarrierCycles();
+ method public deprecated boolean hasCarrierCycles();
method public boolean hasCarrierFrequencyHz();
- method public boolean hasCarrierPhase();
- method public boolean hasCarrierPhaseUncertainty();
+ method public deprecated boolean hasCarrierPhase();
+ method public deprecated boolean hasCarrierPhaseUncertainty();
method public boolean hasSnrInDb();
method public void writeToParcel(android.os.Parcel, int);
field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4
+ field public static final int ADR_STATE_HALF_CYCLE_REPORTED = 16; // 0x10
+ field public static final int ADR_STATE_HALF_CYCLE_RESOLVED = 8; // 0x8
field public static final int ADR_STATE_RESET = 2; // 0x2
field public static final int ADR_STATE_UNKNOWN = 0; // 0x0
field public static final int ADR_STATE_VALID = 1; // 0x1
diff --git a/api/system-current.txt b/api/system-current.txt
index fa32383..d602b56 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4349,11 +4349,14 @@
}
public final class KeyDerivationParams implements android.os.Parcelable {
+ method public static android.security.keystore.recovery.KeyDerivationParams createScryptParams(byte[], int);
method public static android.security.keystore.recovery.KeyDerivationParams createSha256Params(byte[]);
method public int describeContents();
method public int getAlgorithm();
+ method public int getMemoryDifficulty();
method public byte[] getSalt();
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ALGORITHM_SCRYPT = 2; // 0x2
field public static final int ALGORITHM_SHA256 = 1; // 0x1
field public static final android.os.Parcelable.Creator<android.security.keystore.recovery.KeyDerivationParams> CREATOR;
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 81cebf0..dd16771 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -416,20 +416,20 @@
ctor public GnssMeasurement();
method public void reset();
method public void resetAutomaticGainControlLevel();
- method public void resetCarrierCycles();
+ method public deprecated void resetCarrierCycles();
method public void resetCarrierFrequencyHz();
- method public void resetCarrierPhase();
- method public void resetCarrierPhaseUncertainty();
+ method public deprecated void resetCarrierPhase();
+ method public deprecated void resetCarrierPhaseUncertainty();
method public void resetSnrInDb();
method public void set(android.location.GnssMeasurement);
method public void setAccumulatedDeltaRangeMeters(double);
method public void setAccumulatedDeltaRangeState(int);
method public void setAccumulatedDeltaRangeUncertaintyMeters(double);
method public void setAutomaticGainControlLevelInDb(double);
- method public void setCarrierCycles(long);
+ method public deprecated void setCarrierCycles(long);
method public void setCarrierFrequencyHz(float);
- method public void setCarrierPhase(double);
- method public void setCarrierPhaseUncertainty(double);
+ method public deprecated void setCarrierPhase(double);
+ method public deprecated void setCarrierPhaseUncertainty(double);
method public void setCn0DbHz(double);
method public void setConstellationType(int);
method public void setMultipathIndicator(int);
@@ -441,6 +441,7 @@
method public void setState(int);
method public void setSvid(int);
method public void setTimeOffsetNanos(double);
+ field public static final int ADR_STATE_ALL = 31; // 0x1f
}
public final class GnssMeasurementsEvent implements android.os.Parcelable {
diff --git a/core/java/android/security/keystore/recovery/KeyDerivationParams.java b/core/java/android/security/keystore/recovery/KeyDerivationParams.java
index 428eaaa..8cb8e51 100644
--- a/core/java/android/security/keystore/recovery/KeyDerivationParams.java
+++ b/core/java/android/security/keystore/recovery/KeyDerivationParams.java
@@ -38,7 +38,7 @@
public final class KeyDerivationParams implements Parcelable {
private final int mAlgorithm;
private final byte[] mSalt;
- private final int mDifficulty;
+ private final int mMemoryDifficulty;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -53,25 +53,32 @@
/**
* SCRYPT.
- *
- * @hide
*/
public static final int ALGORITHM_SCRYPT = 2;
/**
- * Creates instance of the class to to derive key using salted SHA256 hash.
+ * Creates instance of the class to to derive keys using salted SHA256 hash.
+ *
+ * <p>The salted SHA256 hash is computed over the concatenation of four byte strings, salt_len +
+ * salt + key_material_len + key_material, where salt_len and key_material_len are one-byte, and
+ * denote the number of bytes for salt and key_material, respectively.
*/
public static KeyDerivationParams createSha256Params(@NonNull byte[] salt) {
return new KeyDerivationParams(ALGORITHM_SHA256, salt);
}
/**
- * Creates instance of the class to to derive key using the password hashing algorithm SCRYPT.
+ * Creates instance of the class to to derive keys using the password hashing algorithm SCRYPT.
*
- * @hide
+ * <p>We expose only one tuning parameter of SCRYPT, which is the memory cost parameter (i.e. N
+ * in <a href="https://www.tarsnap.com/scrypt/scrypt.pdf">the SCRYPT paper</a>). Regular/default
+ * values are used for the other parameters, to keep the overall running time low. Specifically,
+ * the parallelization parameter p is 1, the block size parameter r is 8, and the hashing output
+ * length is 32-byte.
*/
- public static KeyDerivationParams createScryptParams(@NonNull byte[] salt, int difficulty) {
- return new KeyDerivationParams(ALGORITHM_SCRYPT, salt, difficulty);
+ public static KeyDerivationParams createScryptParams(
+ @NonNull byte[] salt, int memoryDifficulty) {
+ return new KeyDerivationParams(ALGORITHM_SCRYPT, salt, memoryDifficulty);
}
/**
@@ -79,17 +86,17 @@
*/
// TODO: Make private once legacy API is removed
public KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt) {
- this(algorithm, salt, /*difficulty=*/ 0);
+ this(algorithm, salt, /*memoryDifficulty=*/ -1);
}
/**
* @hide
*/
KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt,
- int difficulty) {
+ int memoryDifficulty) {
mAlgorithm = algorithm;
mSalt = Preconditions.checkNotNull(salt);
- mDifficulty = difficulty;
+ mMemoryDifficulty = memoryDifficulty;
}
/**
@@ -107,12 +114,16 @@
}
/**
- * Gets hashing difficulty.
+ * Gets the memory difficulty parameter for the hashing algorithm.
*
- * @hide
+ * <p>The effect of this parameter depends on the algorithm in use. For example, please see
+ * {@link #createScryptParams(byte[], int)} for choosing the parameter for SCRYPT.
+ *
+ * <p>If the specific algorithm does not support such a memory difficulty parameter, its value
+ * should be -1.
*/
- public int getDifficulty() {
- return mDifficulty;
+ public int getMemoryDifficulty() {
+ return mMemoryDifficulty;
}
public static final Parcelable.Creator<KeyDerivationParams> CREATOR =
@@ -130,7 +141,7 @@
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mAlgorithm);
out.writeByteArray(mSalt);
- out.writeInt(mDifficulty);
+ out.writeInt(mMemoryDifficulty);
}
/**
@@ -139,7 +150,7 @@
protected KeyDerivationParams(Parcel in) {
mAlgorithm = in.readInt();
mSalt = in.createByteArray();
- mDifficulty = in.readInt();
+ mMemoryDifficulty = in.readInt();
}
@Override
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index 4901080..f0e7796 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -115,6 +115,14 @@
command.append(' ');
command.append(appProcess);
+ // Generate bare minimum of debug information to be able to backtrace through JITed code.
+ // We assume that if the invoke wrapper is used, backtraces are desirable:
+ // * The wrap.sh script can only be used by debuggable apps, which would enable this flag
+ // without the script anyway (the fork-zygote path). So this makes the two consistent.
+ // * The wrap.* property can only be used on userdebug builds and is likely to be used by
+ // developers (e.g. enable debug-malloc), in which case backtraces are also useful.
+ command.append(" -Xcompiler-option --generate-mini-debug-info");
+
command.append(" /system/bin --application");
if (niceName != null) {
command.append(" '--nice-name=").append(niceName).append("'");
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 953da17..89665db 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -228,6 +228,7 @@
optional SettingProto ble_scan_low_power_interval_ms = 161 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto ble_scan_balanced_interval_ms = 162 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto ble_scan_low_latency_interval_ms = 163 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto ble_scan_background_mode = 389 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto wifi_saved_state = 164 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto wifi_supplicant_scan_interval_ms = 165 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto wifi_enhanced_auto_join = 166 [ (android.privacy).dest = DEST_AUTOMATIC ];
@@ -507,7 +508,7 @@
optional SettingsProto backup_agent_timeout_parameters = 386;
// Please insert fields in the same order as in
// frameworks/base/core/java/android/provider/Settings.java.
- // Next tag = 389;
+ // Next tag = 390;
}
message SecureSettingsProto {
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 412cc29..2152e1e 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -83,6 +83,20 @@
*/
public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2;
+ /**
+ * GNSS measurement tracking loop state
+ * @hide
+ */
+ @IntDef(flag = true, prefix = { "STATE_" }, value = {
+ STATE_CODE_LOCK, STATE_BIT_SYNC, STATE_SUBFRAME_SYNC,
+ STATE_TOW_DECODED, STATE_MSEC_AMBIGUOUS, STATE_SYMBOL_SYNC, STATE_GLO_STRING_SYNC,
+ STATE_GLO_TOD_DECODED, STATE_BDS_D2_BIT_SYNC, STATE_BDS_D2_SUBFRAME_SYNC,
+ STATE_GAL_E1BC_CODE_LOCK, STATE_GAL_E1C_2ND_CODE_LOCK, STATE_GAL_E1B_PAGE_SYNC,
+ STATE_SBAS_SYNC, STATE_TOW_KNOWN, STATE_GLO_TOD_KNOWN
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface State {}
+
/** This GNSS measurement's tracking state is invalid or unknown. */
public static final int STATE_UNKNOWN = 0;
/** This GNSS measurement's tracking state has code lock. */
@@ -133,29 +147,68 @@
private static final int STATE_ALL = 0x3fff; // 2 bits + 4 bits + 4 bits + 4 bits = 14 bits
/**
- * The state of the 'Accumulated Delta Range' is invalid or unknown.
+ * GNSS measurement accumulated delta range state
+ * @hide
+ */
+ @IntDef(flag = true, prefix = { "ADR_STATE_" }, value = {
+ ADR_STATE_VALID, ADR_STATE_RESET, ADR_STATE_CYCLE_SLIP, ADR_STATE_HALF_CYCLE_RESOLVED,
+ ADR_STATE_HALF_CYCLE_REPORTED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AdrState {}
+
+ /**
+ * The state of the value {@link #getAccumulatedDeltaRangeMeters()} is invalid or unknown.
*/
public static final int ADR_STATE_UNKNOWN = 0;
/**
- * The state of the 'Accumulated Delta Range' is valid.
+ * The state of the {@link #getAccumulatedDeltaRangeMeters()} is valid.
*/
public static final int ADR_STATE_VALID = (1<<0);
/**
- * The state of the 'Accumulated Delta Range' has detected a reset.
+ * The state of the {@link #getAccumulatedDeltaRangeMeters()} has detected a reset.
*/
public static final int ADR_STATE_RESET = (1<<1);
/**
- * The state of the 'Accumulated Delta Range' has a cycle slip detected.
+ * The state of the {@link #getAccumulatedDeltaRangeMeters()} has a cycle slip detected.
*/
public static final int ADR_STATE_CYCLE_SLIP = (1<<2);
/**
- * All the 'Accumulated Delta Range' flags.
+ * Reports whether the value {@link #getAccumulatedDeltaRangeMeters()} has resolved the half
+ * cycle ambiguity.
+ *
+ * <p> When this bit is set, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
+ * carrier phase measurement plus an accumulated integer number of carrier full cycles.
+ *
+ * <p> When this bit is unset, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
+ * carrier phase measurement plus an accumulated integer number of carrier half cycles.
*/
- private static final int ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
+ public static final int ADR_STATE_HALF_CYCLE_RESOLVED = (1<<3);
+
+ /**
+ * Reports whether the flag {@link #ADR_STATE_HALF_CYCLE_RESOLVED} has been reported by the
+ * GNSS hardware.
+ *
+ * <p> When this bit is set, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
+ * can be low (centimeter level) whether or not the half cycle ambiguity is resolved.
+ *
+ * <p> When this bit is unset, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
+ * is larger, to cover the potential error due to half cycle ambiguity being unresolved.
+ */
+ public static final int ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
+
+ /**
+ * All the 'Accumulated Delta Range' flags.
+ * @hide
+ */
+ @TestApi
+ public static final int ADR_STATE_ALL =
+ ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP |
+ ADR_STATE_HALF_CYCLE_RESOLVED | ADR_STATE_HALF_CYCLE_REPORTED;
// End enumerations in sync with gps.h
@@ -278,6 +331,7 @@
*
* <p>This value helps interpret {@link #getReceivedSvTimeNanos()}.
*/
+ @State
public int getState() {
return mState;
}
@@ -287,7 +341,7 @@
* @hide
*/
@TestApi
- public void setState(int value) {
+ public void setState(@State int value) {
mState = value;
}
@@ -557,6 +611,7 @@
* <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
* cycle slip (indicating 'loss of lock').
*/
+ @AdrState
public int getAccumulatedDeltaRangeState() {
return mAccumulatedDeltaRangeState;
}
@@ -566,7 +621,7 @@
* @hide
*/
@TestApi
- public void setAccumulatedDeltaRangeState(int value) {
+ public void setAccumulatedDeltaRangeState(@AdrState int value) {
mAccumulatedDeltaRangeState = value;
}
@@ -589,7 +644,15 @@
if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
builder.append("CycleSlip|");
}
- int remainingStates = mAccumulatedDeltaRangeState & ~ADR_ALL;
+ if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_RESOLVED) ==
+ ADR_STATE_HALF_CYCLE_RESOLVED) {
+ builder.append("HalfCycleResolved|");
+ }
+ if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_REPORTED)
+ == ADR_STATE_HALF_CYCLE_REPORTED) {
+ builder.append("HalfCycleReported|");
+ }
+ int remainingStates = mAccumulatedDeltaRangeState & ~ADR_STATE_ALL;
if (remainingStates > 0) {
builder.append("Other(");
builder.append(Integer.toBinaryString(remainingStates));
@@ -674,7 +737,7 @@
* L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
* common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
*
- * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two raw
+ * <p> For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two raw
* measurement objects will be reported for this same satellite, in one of the measurement
* objects, all the values related to L1 will be filled, and in the other all of the values
* related to L5 will be filled.
@@ -709,7 +772,10 @@
/**
* Returns {@code true} if {@link #getCarrierCycles()} is available, {@code false} otherwise.
+ *
+ * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
*/
+ @Deprecated
public boolean hasCarrierCycles() {
return isFlagSet(HAS_CARRIER_CYCLES);
}
@@ -720,16 +786,24 @@
* <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
*
* <p>The value is only available if {@link #hasCarrierCycles()} is {@code true}.
+ *
+ * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
*/
+ @Deprecated
public long getCarrierCycles() {
return mCarrierCycles;
}
/**
* Sets the number of full carrier cycles between the satellite and the receiver.
+ *
+ * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+ * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+ *
* @hide
*/
@TestApi
+ @Deprecated
public void setCarrierCycles(long value) {
setFlag(HAS_CARRIER_CYCLES);
mCarrierCycles = value;
@@ -737,9 +811,13 @@
/**
* Resets the number of full carrier cycles between the satellite and the receiver.
+ *
+ * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+ * and {@link #setAccumulatedDeltaRangeState(int)} instead.
* @hide
*/
@TestApi
+ @Deprecated
public void resetCarrierCycles() {
resetFlag(HAS_CARRIER_CYCLES);
mCarrierCycles = Long.MIN_VALUE;
@@ -747,7 +825,10 @@
/**
* Returns {@code true} if {@link #getCarrierPhase()} is available, {@code false} otherwise.
+ *
+ * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
*/
+ @Deprecated
public boolean hasCarrierPhase() {
return isFlagSet(HAS_CARRIER_PHASE);
}
@@ -764,16 +845,24 @@
* <p>The error estimate for this value is {@link #getCarrierPhaseUncertainty()}.
*
* <p>The value is only available if {@link #hasCarrierPhase()} is {@code true}.
+ *
+ * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
*/
+ @Deprecated
public double getCarrierPhase() {
return mCarrierPhase;
}
/**
* Sets the RF phase detected by the receiver.
+ *
+ * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+ * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+ *
* @hide
*/
@TestApi
+ @Deprecated
public void setCarrierPhase(double value) {
setFlag(HAS_CARRIER_PHASE);
mCarrierPhase = value;
@@ -781,9 +870,14 @@
/**
* Resets the RF phase detected by the receiver.
+ *
+ * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+ * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+ *
* @hide
*/
@TestApi
+ @Deprecated
public void resetCarrierPhase() {
resetFlag(HAS_CARRIER_PHASE);
mCarrierPhase = Double.NaN;
@@ -792,7 +886,10 @@
/**
* Returns {@code true} if {@link #getCarrierPhaseUncertainty()} is available, {@code false}
* otherwise.
+ *
+ * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
*/
+ @Deprecated
public boolean hasCarrierPhaseUncertainty() {
return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
}
@@ -803,16 +900,24 @@
* <p>The uncertainty is represented as an absolute (single sided) value.
*
* <p>The value is only available if {@link #hasCarrierPhaseUncertainty()} is {@code true}.
+ *
+ * @deprecated use {@link #getAccumulatedDeltaRangeUncertaintyMeters()} instead.
*/
+ @Deprecated
public double getCarrierPhaseUncertainty() {
return mCarrierPhaseUncertainty;
}
/**
* Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
+ *
+ * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
+ * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+ *
* @hide
*/
@TestApi
+ @Deprecated
public void setCarrierPhaseUncertainty(double value) {
setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
mCarrierPhaseUncertainty = value;
@@ -820,9 +925,14 @@
/**
* Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
+ *
+ * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
+ * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+ *
* @hide
*/
@TestApi
+ @Deprecated
public void resetCarrierPhaseUncertainty() {
resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
mCarrierPhaseUncertainty = Double.NaN;
@@ -859,7 +969,7 @@
case MULTIPATH_INDICATOR_NOT_DETECTED:
return "NotDetected";
default:
- return "<Invalid:" + mMultipathIndicator + ">";
+ return "<Invalid: " + mMultipathIndicator + ">";
}
}
@@ -916,11 +1026,12 @@
* number. Hence in cases of strong jamming, in the band of this signal, this value will go more
* negative.
*
- * <p>Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
+ * <p> Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
* components) may also affect the typical output of of this value on any given hardware design
* in an open sky test - the important aspect of this output is that changes in this value are
* indicative of changes on input signal power in the frequency band for this measurement.
- * <p>The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
+ *
+ * <p> The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
*/
public double getAutomaticGainControlLevelDb() {
return mAutomaticGainControlLevelInDb;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 3467df5..2047f58 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -578,6 +578,9 @@
Settings.Global.BLE_SCAN_LOW_LATENCY_INTERVAL_MS,
GlobalSettingsProto.BLE_SCAN_LOW_LATENCY_INTERVAL_MS);
dumpSetting(s, p,
+ Settings.Global.BLE_SCAN_BACKGROUND_MODE,
+ GlobalSettingsProto.BLE_SCAN_BACKGROUND_MODE);
+ dumpSetting(s, p,
Settings.Global.WIFI_SAVED_STATE,
GlobalSettingsProto.WIFI_SAVED_STATE);
dumpSetting(s, p,
diff --git a/packages/SystemUI/res/layout/mobile_signal_group.xml b/packages/SystemUI/res/layout/mobile_signal_group.xml
index 2da03d2..cc6e3bf 100644
--- a/packages/SystemUI/res/layout/mobile_signal_group.xml
+++ b/packages/SystemUI/res/layout/mobile_signal_group.xml
@@ -50,6 +50,7 @@
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
+ android:paddingEnd="1dp"
android:visibility="gone" />
<Space
android:id="@+id/mobile_roaming_space"
diff --git a/packages/SystemUI/res/values-sw600dp/bools.xml b/packages/SystemUI/res/values-sw600dp/bools.xml
new file mode 100644
index 0000000..05e38bd
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp/bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2018, 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.
+*/
+-->
+<resources>
+ <!-- Whether to show the user switcher in quick settings when only a single user is present. -->
+ <bool name="qs_show_user_switcher_for_single_user">true</bool>
+</resources>
diff --git a/packages/SystemUI/res/values/bools.xml b/packages/SystemUI/res/values/bools.xml
new file mode 100644
index 0000000..499e24e
--- /dev/null
+++ b/packages/SystemUI/res/values/bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2018, 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.
+*/
+-->
+<resources>
+ <!-- Whether to show the user switcher in quick settings when only a single user is present. -->
+ <bool name="qs_show_user_switcher_for_single_user">false</bool>
+</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index dbf1745..0fa6597 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
+import android.content.pm.UserInfo;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.PorterDuff.Mode;
@@ -49,7 +50,6 @@
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.qs.TouchAnimator.Builder;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.MultiUserSwitch;
import com.android.systemui.statusbar.phone.SettingsButton;
@@ -257,17 +257,31 @@
mSettingsContainer.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
-
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
-
-
- mMultiUserSwitch.setVisibility(mExpanded
- && UserManager.get(mContext).isUserSwitcherEnabled()
- ? View.VISIBLE : View.INVISIBLE);
-
+ mMultiUserSwitch.setVisibility(showUserSwitcher(isDemo) ? View.VISIBLE : View.INVISIBLE);
mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
}
+ private boolean showUserSwitcher(boolean isDemo) {
+ if (!mExpanded || isDemo || !UserManager.supportsMultipleUsers()) {
+ return false;
+ }
+ UserManager userManager = UserManager.get(mContext);
+ if (userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)) {
+ return false;
+ }
+ int switchableUserCount = 0;
+ for (UserInfo user : userManager.getUsers(true)) {
+ if (user.supportsSwitchToByUser()) {
+ ++switchableUserCount;
+ if (switchableUserCount > 1) {
+ return true;
+ }
+ }
+ }
+ return getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user);
+ }
+
private void updateListeners() {
if (mListening) {
mUserInfoController.addCallback(this);
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 83fe1c9..ad32ed3 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -264,13 +264,9 @@
}
public void grantDefaultPermissions(int userId) {
- if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED, 0)) {
- grantAllRuntimePermissions(userId);
- } else {
- grantPermissionsToSysComponentsAndPrivApps(userId);
- grantDefaultSystemHandlerPermissions(userId);
- grantDefaultPermissionExceptions(userId);
- }
+ grantPermissionsToSysComponentsAndPrivApps(userId);
+ grantDefaultSystemHandlerPermissions(userId);
+ grantDefaultPermissionExceptions(userId);
}
private void grantRuntimePermissionsForPackage(int userId, PackageParser.Package pkg) {
@@ -1247,6 +1243,13 @@
if (dir.isDirectory() && dir.canRead()) {
Collections.addAll(ret, dir.listFiles());
}
+ // For IoT devices, we check the oem partition for default permissions for each app.
+ if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED, 0)) {
+ dir = new File(Environment.getOemDirectory(), "etc/default-permissions");
+ if (dir.isDirectory() && dir.canRead()) {
+ Collections.addAll(ret, dir.listFiles());
+ }
+ }
return ret.isEmpty() ? null : ret.toArray(new File[0]);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 4c9b585..4dc68ac 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -72,6 +72,7 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -2583,7 +2584,14 @@
/** {@inheritDoc} */
@Override
public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
- int type = attrs.type;
+ final int type = attrs.type;
+ final boolean isRoundedCornerOverlay =
+ (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
+
+ if (isRoundedCornerOverlay && mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
+ != PERMISSION_GRANTED) {
+ return ADD_PERMISSION_DENIED;
+ }
outAppOp[0] = AppOpsManager.OP_NONE;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a76857e..85436da 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1698,7 +1698,10 @@
stack.getBounds(mTmpRect);
mTmpRect.offsetTo(0, 0);
}
- if (mService.mAppTransition.getRemoteAnimationController() != null) {
+
+ // Delaying animation start isn't compatible with remote animations at all.
+ if (mService.mAppTransition.getRemoteAnimationController() != null
+ && !mSurfaceAnimator.isAnimationStartDelayed()) {
adapter = mService.mAppTransition.getRemoteAnimationController()
.createAnimationAdapter(this, mTmpPoint, mTmpRect);
} else {
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index d7f480b..c590067 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -99,6 +99,10 @@
mFinishedCallback = new FinishedCallback(this);
final RemoteAnimationTarget[] animations = createAnimations();
+ if (animations.length == 0) {
+ onAnimationFinished();
+ return;
+ }
mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
try {
mRemoteAnimationAdapter.getRunner().onAnimationStart(animations,
@@ -132,6 +136,8 @@
mPendingAnimations.get(i).createRemoteAppAnimation();
if (target != null) {
targets.add(target);
+ } else {
+ mPendingAnimations.remove(i);
}
}
return targets.toArray(new RemoteAnimationTarget[targets.size()]);
@@ -225,10 +231,8 @@
RemoteAnimationTarget createRemoteAppAnimation() {
final Task task = mAppWindowToken.getTask();
final WindowState mainWindow = mAppWindowToken.findMainWindow();
- if (task == null) {
- return null;
- }
- if (mainWindow == null) {
+ if (task == null || mainWindow == null || mCapturedFinishCallback == null
+ || mCapturedLeash == null) {
return null;
}
mTarget = new RemoteAnimationTarget(task.mTaskId, getMode(),
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index e5928b1..ba3d091 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -234,6 +234,10 @@
mService.mAnimationTransferMap.put(mAnimation, this);
}
+ boolean isAnimationStartDelayed() {
+ return mAnimationStartDelayed;
+ }
+
/**
* Cancels the animation, and resets the leash.
*
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a22bb00..56b314f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -48,6 +48,7 @@
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -1214,8 +1215,10 @@
}
}
final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();
+ final boolean isRoundedCornerOverlay =
+ (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
token = new WindowToken(this, binder, type, false, displayContent,
- session.mCanAddInternalSystemWindow);
+ session.mCanAddInternalSystemWindow, isRoundedCornerOverlay);
} else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
atoken = token.asAppWindowToken();
if (atoken == null) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index f727296..14680d9 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
@@ -53,6 +54,9 @@
// The type of window this token is for, as per WindowManager.LayoutParams.
final int windowType;
+ /** {@code true} if this holds the rounded corner overlay */
+ final boolean mRoundedCornerOverlay;
+
// Set if this token was explicitly added by a client, so should
// persist (not be removed) when all windows are removed.
boolean mPersistOnEmpty;
@@ -105,11 +109,18 @@
WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
DisplayContent dc, boolean ownerCanManageAppTokens) {
+ this(service, _token, type, persistOnEmpty, dc, ownerCanManageAppTokens,
+ false /* roundedCornersOverlay */);
+ }
+
+ WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
+ DisplayContent dc, boolean ownerCanManageAppTokens, boolean roundedCornerOverlay) {
super(service);
token = _token;
windowType = type;
mPersistOnEmpty = persistOnEmpty;
mOwnerCanManageAppTokens = ownerCanManageAppTokens;
+ mRoundedCornerOverlay = roundedCornerOverlay;
onDisplayChanged(dc);
}
@@ -259,6 +270,12 @@
dc.reParentWindowToken(this);
mDisplayContent = dc;
+ // The rounded corner overlay should not be rotated. We ensure that by moving it outside
+ // the windowing layer.
+ if (mRoundedCornerOverlay) {
+ mDisplayContent.reparentToOverlay(mPendingTransaction, mSurfaceControl);
+ }
+
// TODO(b/36740756): One day this should perhaps be hooked
// up with goodToGo, so we don't move a window
// to another display before the window behind
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index cf42c0c..dcee151 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -125,6 +125,9 @@
}
};
+// Must match the value from GnssMeasurement.java
+static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
+
sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
sp<IGnss_V1_0> gnssHal = nullptr;
sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
@@ -807,7 +810,8 @@
SET(PseudorangeRateUncertaintyMetersPerSecond,
measurement->pseudorangeRateUncertaintyMps);
SET(AccumulatedDeltaRangeState,
- (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
+ (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
+ !ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
SET(AccumulatedDeltaRangeUncertaintyMeters,
measurement->accumulatedDeltaRangeUncertaintyM);
@@ -888,9 +892,10 @@
if (measurements_v1_1 != NULL) {
translateGnssMeasurement_V1_0(env, &(measurements_v1_1[i].v1_0), object);
- // Set the V1_1 flag
+ // Set the V1_1 flag, and mark that new field has valid information for Java Layer
SET(AccumulatedDeltaRangeState,
- static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState));
+ (static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState) |
+ ADR_STATE_HALF_CYCLE_REPORTED));
} else {
translateGnssMeasurement_V1_0(env, &(measurements_v1_0[i]), object);
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java
index 9213268..e3e61ac 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java
@@ -16,9 +16,8 @@
package com.android.server.devicepolicy;
-import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER;
-
-
+import static com.android.server.devicepolicy.TransferOwnershipMetadataManager
+ .ADMIN_TYPE_DEVICE_OWNER;
import static com.android.server.devicepolicy.TransferOwnershipMetadataManager
.OWNER_TRANSFER_METADATA_XML;
import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.TAG_ADMIN_TYPE;
@@ -32,6 +31,7 @@
import android.os.Environment;
import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import com.android.server.devicepolicy.TransferOwnershipMetadataManager.Injector;
import com.android.server.devicepolicy.TransferOwnershipMetadataManager.Metadata;
@@ -57,6 +57,7 @@
@RunWith(AndroidJUnit4.class)
public class TransferOwnershipMetadataManagerTest {
+ private final static String TAG = TransferOwnershipMetadataManagerTest.class.getName();
private final static String SOURCE_COMPONENT =
"com.dummy.admin.package/com.dummy.admin.package.SourceClassName";
private final static String TARGET_COMPONENT =
@@ -106,6 +107,22 @@
@Test
public void testLoad() {
TransferOwnershipMetadataManager paramsManager = getOwnerTransferParams();
+ final File transferOwnershipMetadataFile =
+ new File(mMockInjector.getOwnerTransferMetadataDir(), OWNER_TRANSFER_METADATA_XML);
+ Log.d(TAG, "testLoad: file path is " + transferOwnershipMetadataFile.getAbsolutePath());
+ Log.d(TAG, "testLoad: file exists? " + transferOwnershipMetadataFile.exists());
+ Log.d(TAG, "testLoad: file mkdir?" + transferOwnershipMetadataFile.mkdir());
+ try {
+ File canonicalFile = transferOwnershipMetadataFile.getCanonicalFile();
+ File parentFile = canonicalFile.getParentFile();
+ Log.d(TAG, "testLoad: file getCanonicalFile?" + canonicalFile);
+ Log.d(TAG, "testLoad: getCanonicalFile.getParentFile " + parentFile);
+ Log.d(TAG, "testLoad: parent mkdirs? " + parentFile.mkdirs());
+ Log.d(TAG, "testLoad: parent exists? " + parentFile.exists());
+ Log.d(TAG, "testLoad: canonical file.mkdir()? " + canonicalFile.mkdir());
+ } catch (IOException e) {
+ Log.d(TAG, "testLoad: failed to get canonical file");
+ }
paramsManager.saveMetadataFile(TEST_PARAMS);
assertEquals(TEST_PARAMS, paramsManager.loadMetadataFile());
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 26a7313..64501e4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -68,6 +68,7 @@
super.setUp();
MockitoAnnotations.initMocks(this);
mAdapter = new RemoteAnimationAdapter(mMockRunner, 100, 50);
+ mAdapter.setCallingPid(123);
sWm.mH.runWithScissors(() -> {
mHandler = new TestHandler(null, mClock);
}, 0);
@@ -83,7 +84,7 @@
new Point(50, 100), new Rect(50, 100, 150, 150));
adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
mController.goodToGo();
-
+ sWm.mAnimator.executeAfterPrepareSurfacesRunnables();
final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
@@ -167,4 +168,33 @@
mController.goodToGo();
verifyZeroInteractions(mMockRunner);
}
+
+ @Test
+ public void testNotReallyStarted() throws Exception {
+ final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+ mController.createAnimationAdapter(win.mAppToken,
+ new Point(50, 100), new Rect(50, 100, 150, 150));
+ mController.goodToGo();
+ verifyZeroInteractions(mMockRunner);
+ }
+
+ @Test
+ public void testOneNotStarted() throws Exception {
+ final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1");
+ final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2");
+ mController.createAnimationAdapter(win1.mAppToken,
+ new Point(50, 100), new Rect(50, 100, 150, 150));
+ final AnimationAdapter adapter = mController.createAnimationAdapter(win2.mAppToken,
+ new Point(50, 100), new Rect(50, 100, 150, 150));
+ adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+ mController.goodToGo();
+ sWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+ final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
+ ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
+ final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
+ ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
+ verify(mMockRunner).onAnimationStart(appsCaptor.capture(), finishedCaptor.capture());
+ assertEquals(1, appsCaptor.getValue().length);
+ assertEquals(mMockLeash, appsCaptor.getValue()[0].leash);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 6506872..16b8458 100644
--- a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -134,6 +134,7 @@
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
verifyZeroInteractions(mSpec);
assertAnimating(mAnimatable);
+ assertTrue(mAnimatable.mSurfaceAnimator.isAnimationStartDelayed());
mAnimatable.mSurfaceAnimator.endDelayingAnimationStart();
verify(mSpec).startAnimation(any(), any(), any());
}