Merge "Make sure perceptible services are in the default sched group." into nyc-dev
diff --git a/Android.mk b/Android.mk
index 2ee7600..3ac5889 100644
--- a/Android.mk
+++ b/Android.mk
@@ -150,14 +150,14 @@
core/java/android/content/pm/IPackageStatsObserver.aidl \
core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
core/java/android/database/IContentObserver.aidl \
- core/java/android/hardware/ICameraService.aidl \
- core/java/android/hardware/ICameraServiceListener.aidl \
- core/java/android/hardware/ICameraServiceProxy.aidl \
- core/java/android/hardware/ICamera.aidl \
- core/java/android/hardware/ICameraClient.aidl \
+ ../av/camera/aidl/android/hardware/ICameraService.aidl \
+ ../av/camera/aidl/android/hardware/ICameraServiceListener.aidl \
+ ../av/camera/aidl/android/hardware/ICameraServiceProxy.aidl \
+ ../av/camera/aidl/android/hardware/ICamera.aidl \
+ ../av/camera/aidl/android/hardware/ICameraClient.aidl \
+ ../av/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl \
+ ../av/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl \
core/java/android/hardware/IConsumerIrService.aidl \
- core/java/android/hardware/camera2/ICameraDeviceUser.aidl \
- core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl \
core/java/android/hardware/ISerialManager.aidl \
core/java/android/hardware/display/IDisplayManager.aidl \
core/java/android/hardware/display/IDisplayManagerCallback.aidl \
@@ -455,6 +455,10 @@
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
frameworks/native/aidl/binder
+LOCAL_AIDL_INCLUDES += \
+ frameworks/av/camera/aidl \
+ frameworks/native/aidl/gui
+
LOCAL_INTERMEDIATE_SOURCES := \
$(framework_res_source_path)/android/R.java \
$(framework_res_source_path)/android/Manifest.java \
@@ -577,7 +581,7 @@
frameworks/base/core/java/android/view/Display.aidl \
frameworks/base/core/java/android/view/InputDevice.aidl \
frameworks/base/core/java/android/view/InputEvent.aidl \
- frameworks/base/core/java/android/view/Surface.aidl \
+ frameworks/native/aidl/gui/android/view/Surface.aidl \
frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
frameworks/base/core/java/android/view/inputmethod/InputMethodSubtype.aidl \
frameworks/base/core/java/android/view/inputmethod/CursorAnchorInfo.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2fe5cbe..cee8fdb 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -240,6 +240,7 @@
$(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IRemoteControlDisplay.*)
$(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit1_intermediates/src/com/android/test/split/feature/R.java)
$(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit2_intermediates/src/com/android/test/split/feature/R.java)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
diff --git a/api/current.txt b/api/current.txt
index 9292816..a4f6607 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5610,8 +5610,6 @@
method public void enableCarMode(int);
method public int getCurrentModeType();
method public int getNightMode();
- method public boolean isNightModeLocked();
- method public boolean isUiModeLocked();
method public void setNightMode(int);
field public static java.lang.String ACTION_ENTER_CAR_MODE;
field public static java.lang.String ACTION_ENTER_DESK_MODE;
@@ -5713,6 +5711,7 @@
public class WallpaperManager {
method public void clear() throws java.io.IOException;
+ method public void clear(int) throws java.io.IOException;
method public void clearWallpaperOffsets(android.os.IBinder);
method public void forgetLoadedWallpaper();
method public android.graphics.drawable.Drawable getBuiltInDrawable();
@@ -19157,168 +19156,110 @@
public final class GnssClock implements android.os.Parcelable {
method public int describeContents();
- method public double getBiasInNs();
- method public double getBiasUncertaintyInNs();
- method public double getDriftInNsPerSec();
- method public double getDriftUncertaintyInNsPerSec();
- method public long getFullBiasInNs();
+ method public double getBiasNanos();
+ method public double getBiasUncertaintyNanos();
+ method public double getDriftNanosPerSecond();
+ method public double getDriftUncertaintyNanosPerSecond();
+ method public long getFullBiasNanos();
method public int getHardwareClockDiscontinuityCount();
- method public short getLeapSecond();
- method public long getTimeInNs();
- method public double getTimeUncertaintyInNs();
- method public boolean hasBiasInNs();
- method public boolean hasBiasUncertaintyInNs();
- method public boolean hasDriftInNsPerSec();
- method public boolean hasDriftUncertaintyInNsPerSec();
- method public boolean hasFullBiasInNs();
+ method public int getLeapSecond();
+ method public long getTimeNanos();
+ method public double getTimeUncertaintyNanos();
+ method public boolean hasBiasNanos();
+ method public boolean hasBiasUncertaintyNanos();
+ method public boolean hasDriftNanosPerSecond();
+ method public boolean hasDriftUncertaintyNanosPerSecond();
+ method public boolean hasFullBiasNanos();
method public boolean hasLeapSecond();
- method public boolean hasTimeUncertaintyInNs();
+ method public boolean hasTimeUncertaintyNanos();
method public void reset();
- method public void resetBiasInNs();
- method public void resetBiasUncertaintyInNs();
- method public void resetDriftInNsPerSec();
- method public void resetDriftUncertaintyInNsPerSec();
- method public void resetFullBiasInNs();
+ method public void resetBiasNanos();
+ method public void resetBiasUncertaintyNanos();
+ method public void resetDriftNanosPerSecond();
+ method public void resetDriftUncertaintyNanosPerSecond();
+ method public void resetFullBiasNanos();
method public void resetLeapSecond();
- method public void resetTimeUncertaintyInNs();
+ method public void resetTimeUncertaintyNanos();
method public void set(android.location.GnssClock);
- method public void setBiasInNs(double);
- method public void setBiasUncertaintyInNs(double);
- method public void setDriftInNsPerSec(double);
- method public void setDriftUncertaintyInNsPerSec(double);
- method public void setFullBiasInNs(long);
+ method public void setBiasNanos(double);
+ method public void setBiasUncertaintyNanos(double);
+ method public void setDriftNanosPerSecond(double);
+ method public void setDriftUncertaintyNanosPerSecond(double);
+ method public void setFullBiasNanos(long);
method public void setHardwareClockDiscontinuityCount(int);
- method public void setLeapSecond(short);
- method public void setTimeInNs(long);
- method public void setTimeUncertaintyInNs(double);
+ method public void setLeapSecond(int);
+ method public void setTimeNanos(long);
+ method public void setTimeUncertaintyNanos(double);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssClock> CREATOR;
}
public final class GnssMeasurement implements android.os.Parcelable {
method public int describeContents();
- method public double getAccumulatedDeltaRangeInMeters();
- method public short getAccumulatedDeltaRangeState();
- method public double getAccumulatedDeltaRangeUncertaintyInMeters();
- method public double getAzimuthInDeg();
- method public double getAzimuthUncertaintyInDeg();
- method public int getBitNumber();
+ method public double getAccumulatedDeltaRangeMeters();
+ method public int getAccumulatedDeltaRangeState();
+ method public double getAccumulatedDeltaRangeUncertaintyMeters();
method public long getCarrierCycles();
- method public float getCarrierFrequencyInHz();
+ method public float getCarrierFrequencyHz();
method public double getCarrierPhase();
method public double getCarrierPhaseUncertainty();
- method public double getCn0InDbHz();
- method public double getCodePhaseInChips();
- method public double getCodePhaseUncertaintyInChips();
- method public byte getConstellationType();
- method public double getDopplerShiftInHz();
- method public double getDopplerShiftUncertaintyInHz();
- method public double getElevationInDeg();
- method public double getElevationUncertaintyInDeg();
- method public byte getLossOfLock();
- method public byte getMultipathIndicator();
- method public double getPseudorangeInMeters();
- method public double getPseudorangeRateInMetersPerSec();
- method public double getPseudorangeRateUncertaintyInMetersPerSec();
- method public double getPseudorangeUncertaintyInMeters();
- method public long getReceivedSvTimeInNs();
- method public long getReceivedSvTimeUncertaintyInNs();
+ method public double getCn0DbHz();
+ method public int getConstellationType();
+ method public int getMultipathIndicator();
+ method public double getPseudorangeRateMetersPerSecond();
+ method public double getPseudorangeRateUncertaintyMetersPerSecond();
+ method public long getReceivedSvTimeNanos();
+ method public long getReceivedSvTimeUncertaintyNanos();
method public double getSnrInDb();
- method public short getState();
- method public short getSvid();
- method public short getTimeFromLastBitInMs();
- method public double getTimeOffsetInNs();
- method public boolean hasAzimuthInDeg();
- method public boolean hasAzimuthUncertaintyInDeg();
- method public boolean hasBitNumber();
+ method public int getState();
+ method public int getSvid();
+ method public double getTimeOffsetNanos();
method public boolean hasCarrierCycles();
- method public boolean hasCarrierFrequencyInHz();
+ method public boolean hasCarrierFrequencyHz();
method public boolean hasCarrierPhase();
method public boolean hasCarrierPhaseUncertainty();
- method public boolean hasCodePhaseInChips();
- method public boolean hasCodePhaseUncertaintyInChips();
- method public boolean hasDopplerShiftInHz();
- method public boolean hasDopplerShiftUncertaintyInHz();
- method public boolean hasElevationInDeg();
- method public boolean hasElevationUncertaintyInDeg();
- method public boolean hasPseudorangeInMeters();
- method public boolean hasPseudorangeUncertaintyInMeters();
method public boolean hasSnrInDb();
- method public boolean hasTimeFromLastBitInMs();
method public boolean isPseudorangeRateCorrected();
- method public boolean isUsedInFix();
method public void reset();
- method public void resetAzimuthInDeg();
- method public void resetAzimuthUncertaintyInDeg();
- method public void resetBitNumber();
method public void resetCarrierCycles();
- method public void resetCarrierFrequencyInHz();
+ method public void resetCarrierFrequencyHz();
method public void resetCarrierPhase();
method public void resetCarrierPhaseUncertainty();
- method public void resetCodePhaseInChips();
- method public void resetCodePhaseUncertaintyInChips();
- method public void resetDopplerShiftInHz();
- method public void resetDopplerShiftUncertaintyInHz();
- method public void resetElevationInDeg();
- method public void resetElevationUncertaintyInDeg();
- method public void resetPseudorangeInMeters();
- method public void resetPseudorangeUncertaintyInMeters();
method public void resetSnrInDb();
- method public void resetTimeFromLastBitInMs();
method public void set(android.location.GnssMeasurement);
- method public void setAccumulatedDeltaRangeInMeters(double);
- method public void setAccumulatedDeltaRangeState(short);
- method public void setAccumulatedDeltaRangeUncertaintyInMeters(double);
- method public void setAzimuthInDeg(double);
- method public void setAzimuthUncertaintyInDeg(double);
- method public void setBitNumber(int);
+ method public void setAccumulatedDeltaRangeMeters(double);
+ method public void setAccumulatedDeltaRangeState(int);
+ method public void setAccumulatedDeltaRangeUncertaintyMeters(double);
method public void setCarrierCycles(long);
- method public void setCarrierFrequencyInHz(float);
+ method public void setCarrierFrequencyHz(float);
method public void setCarrierPhase(double);
method public void setCarrierPhaseUncertainty(double);
- method public void setCn0InDbHz(double);
- method public void setCodePhaseInChips(double);
- method public void setCodePhaseUncertaintyInChips(double);
- method public void setConstellationType(byte);
- method public void setDopplerShiftInHz(double);
- method public void setDopplerShiftUncertaintyInHz(double);
- method public void setElevationInDeg(double);
- method public void setElevationUncertaintyInDeg(double);
- method public void setLossOfLock(byte);
- method public void setMultipathIndicator(byte);
- method public void setPseudorangeInMeters(double);
- method public void setPseudorangeRateInMetersPerSec(double);
- method public void setPseudorangeRateUncertaintyInMetersPerSec(double);
- method public void setPseudorangeUncertaintyInMeters(double);
- method public void setReceivedSvTimeInNs(long);
- method public void setReceivedSvTimeUncertaintyInNs(long);
+ method public void setCn0DbHz(double);
+ method public void setConstellationType(int);
+ method public void setMultipathIndicator(int);
+ method public void setPseudorangeRateMetersPerSecond(double);
+ method public void setPseudorangeRateUncertaintyMetersPerSecond(double);
+ method public void setReceivedSvTimeNanos(long);
+ method public void setReceivedSvTimeUncertaintyNanos(long);
method public void setSnrInDb(double);
- method public void setState(short);
- method public void setSvid(short);
- method public void setTimeFromLastBitInMs(short);
- method public void setTimeOffsetInNs(double);
- method public void setUsedInFix(boolean);
+ method public void setState(int);
+ method public void setSvid(int);
+ method public void setTimeOffsetNanos(double);
method public void writeToParcel(android.os.Parcel, int);
- field public static final short ADR_STATE_CYCLE_SLIP = 4; // 0x4
- field public static final short ADR_STATE_RESET = 2; // 0x2
- field public static final short ADR_STATE_UNKNOWN = 0; // 0x0
- field public static final short ADR_STATE_VALID = 1; // 0x1
+ field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4
+ 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
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
- field public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2; // 0x2
- field public static final byte LOSS_OF_LOCK_OK = 1; // 0x1
- field public static final byte LOSS_OF_LOCK_UNKNOWN = 0; // 0x0
- field public static final byte MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
- field public static final byte MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
- field public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
- field public static final short STATE_BIT_SYNC = 2; // 0x2
- field public static final short STATE_CODE_LOCK = 1; // 0x1
- field public static final short STATE_MSEC_AMBIGUOUS = 16; // 0x10
- field public static final short STATE_SUBFRAME_SYNC = 4; // 0x4
- field public static final short STATE_TOW_DECODED = 8; // 0x8
- field public static final short STATE_UNKNOWN = 0; // 0x0
- }
-
- public static abstract class GnssMeasurement.LossOfLockStatus implements java.lang.annotation.Annotation {
+ field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
+ field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+ field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BIT_SYNC = 2; // 0x2
+ field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_TOW_DECODED = 8; // 0x8
+ field public static final int STATE_UNKNOWN = 0; // 0x0
}
public static abstract class GnssMeasurement.MultipathIndicator implements java.lang.annotation.Annotation {
@@ -19331,7 +19272,7 @@
method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
- field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
@@ -19348,34 +19289,34 @@
public final class GnssNavigationMessage implements android.os.Parcelable {
method public int describeContents();
method public byte[] getData();
- method public short getMessageId();
- method public short getStatus();
- method public short getSubmessageId();
- method public short getSvid();
- method public short getType();
+ method public int getMessageId();
+ method public int getStatus();
+ method public int getSubmessageId();
+ method public int getSvid();
+ method public int getType();
method public void reset();
method public void set(android.location.GnssNavigationMessage);
method public void setData(byte[]);
- method public void setMessageId(short);
- method public void setStatus(short);
- method public void setSubmessageId(short);
- method public void setSvid(short);
- method public void setType(short);
+ method public void setMessageId(int);
+ method public void setStatus(int);
+ method public void setSubmessageId(int);
+ method public void setSvid(int);
+ method public void setType(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
- field public static final short MESSAGE_TYPE_BDS_D1 = 1281; // 0x501
- field public static final short MESSAGE_TYPE_BDS_D2 = 1282; // 0x502
- field public static final short MESSAGE_TYPE_GAL_F = 1538; // 0x602
- field public static final short MESSAGE_TYPE_GAL_I = 1537; // 0x601
- field public static final short MESSAGE_TYPE_GLO_L1CA = 769; // 0x301
- field public static final short MESSAGE_TYPE_GPS_CNAV2 = 260; // 0x104
- field public static final short MESSAGE_TYPE_GPS_L1CA = 257; // 0x101
- field public static final short MESSAGE_TYPE_GPS_L2CNAV = 258; // 0x102
- field public static final short MESSAGE_TYPE_GPS_L5CNAV = 259; // 0x103
- field public static final short MESSAGE_TYPE_UNKNOWN = 0; // 0x0
- field public static final short STATUS_PARITY_PASSED = 1; // 0x1
- field public static final short STATUS_PARITY_REBUILT = 2; // 0x2
- field public static final short STATUS_UNKNOWN = 0; // 0x0
+ field public static final int STATUS_PARITY_PASSED = 1; // 0x1
+ field public static final int STATUS_PARITY_REBUILT = 2; // 0x2
+ field public static final int STATUS_UNKNOWN = 0; // 0x0
+ field public static final int TYPE_BDS_D1 = 1281; // 0x501
+ field public static final int TYPE_BDS_D2 = 1282; // 0x502
+ field public static final int TYPE_GAL_F = 1538; // 0x602
+ field public static final int TYPE_GAL_I = 1537; // 0x601
+ field public static final int TYPE_GLO_L1CA = 769; // 0x301
+ field public static final int TYPE_GPS_CNAV2 = 260; // 0x104
+ field public static final int TYPE_GPS_L1CA = 257; // 0x101
+ field public static final int TYPE_GPS_L2CNAV = 258; // 0x102
+ field public static final int TYPE_GPS_L5CNAV = 259; // 0x103
+ field public static final int TYPE_UNKNOWN = 0; // 0x0
}
public static abstract class GnssNavigationMessage.GnssNavigationMessageType implements java.lang.annotation.Annotation {
@@ -19387,7 +19328,7 @@
method public android.location.GnssNavigationMessage getNavigationMessage();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
- field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
@@ -19406,22 +19347,22 @@
}
public final class GnssStatus {
- method public float getAzimuth(int);
- method public byte getConstellationType(int);
- method public float getElevation(int);
+ method public float getAzimuthDegrees(int);
+ method public float getCn0DbHz(int);
+ method public int getConstellationType(int);
+ method public float getElevationDegrees(int);
method public int getNumSatellites();
- method public float getSnr(int);
method public int getSvid(int);
method public boolean hasAlmanac(int);
method public boolean hasEphemeris(int);
method public boolean usedInFix(int);
- field public static final byte CONSTELLATION_BEIDOU = 5; // 0x5
- field public static final byte CONSTELLATION_GALILEO = 6; // 0x6
- field public static final byte CONSTELLATION_GLONASS = 3; // 0x3
- field public static final byte CONSTELLATION_GPS = 1; // 0x1
- field public static final byte CONSTELLATION_QZSS = 4; // 0x4
- field public static final byte CONSTELLATION_SBAS = 2; // 0x2
- field public static final byte CONSTELLATION_UNKNOWN = 0; // 0x0
+ field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
+ field public static final int CONSTELLATION_GALILEO = 6; // 0x6
+ field public static final int CONSTELLATION_GLONASS = 3; // 0x3
+ field public static final int CONSTELLATION_GPS = 1; // 0x1
+ field public static final int CONSTELLATION_QZSS = 4; // 0x4
+ field public static final int CONSTELLATION_SBAS = 2; // 0x2
+ field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
}
public static abstract class GnssStatus.ConstellationType implements java.lang.annotation.Annotation {
@@ -19536,8 +19477,8 @@
method public java.util.List<java.lang.String> getProviders(boolean);
method public java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
method public boolean isProviderEnabled(java.lang.String);
- method public boolean registerGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback);
- method public boolean registerGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
+ method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
+ method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
@@ -19562,7 +19503,7 @@
method public void setTestProviderEnabled(java.lang.String, boolean);
method public void setTestProviderLocation(java.lang.String, android.location.Location);
method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
- method public void unregisterGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback);
+ method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
field public static final java.lang.String GPS_PROVIDER = "gps";
@@ -20994,6 +20935,7 @@
field public static final java.lang.String KEY_SLICE_HEIGHT = "slice-height";
field public static final java.lang.String KEY_STRIDE = "stride";
field public static final java.lang.String KEY_TEMPORAL_LAYERING = "ts-schema";
+ field public static final java.lang.String KEY_TRACK_ID = "track-id";
field public static final java.lang.String KEY_WIDTH = "width";
field public static final java.lang.String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
field public static final java.lang.String MIMETYPE_AUDIO_AC3 = "audio/ac3";
@@ -29106,6 +29048,8 @@
ctor public Process();
method public static final long getElapsedCpuTime();
method public static final int getGidForName(java.lang.String);
+ method public static final long getStartElapsedRealtime();
+ method public static final long getStartUptimeMillis();
method public static final int getThreadPriority(int) throws java.lang.IllegalArgumentException;
method public static final int getUidForName(java.lang.String);
method public static final boolean is64Bit();
@@ -58070,6 +58014,54 @@
method public abstract void update(java.util.Observable, java.lang.Object);
}
+ public final class Optional {
+ method public static java.util.Optional<T> empty();
+ method public java.util.Optional<T> filter(java.util.function.Predicate<? super T>);
+ method public java.util.Optional<U> flatMap(java.util.function.Function<? super T, java.util.Optional<U>>);
+ method public T get();
+ method public void ifPresent(java.util.function.Consumer<? super T>);
+ method public boolean isPresent();
+ method public java.util.Optional<U> map(java.util.function.Function<? super T, ? extends U>);
+ method public static java.util.Optional<T> of(T);
+ method public static java.util.Optional<T> ofNullable(T);
+ method public T orElse(T);
+ method public T orElseGet(java.util.function.Supplier<? extends T>);
+ method public T orElseThrow(java.util.function.Supplier<? extends X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalDouble {
+ method public static java.util.OptionalDouble empty();
+ method public double getAsDouble();
+ method public void ifPresent(java.util.function.DoubleConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalDouble of(double);
+ method public double orElse(double);
+ method public double orElseGet(java.util.function.DoubleSupplier);
+ method public double orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalInt {
+ method public static java.util.OptionalInt empty();
+ method public int getAsInt();
+ method public void ifPresent(java.util.function.IntConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalInt of(int);
+ method public int orElse(int);
+ method public int orElseGet(java.util.function.IntSupplier);
+ method public int orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalLong {
+ method public static java.util.OptionalLong empty();
+ method public long getAsLong();
+ method public void ifPresent(java.util.function.LongConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalLong of(long);
+ method public long orElse(long);
+ method public long orElseGet(java.util.function.LongSupplier);
+ method public long orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable {
ctor public PriorityQueue();
ctor public PriorityQueue(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 3771b4e..2d5e7f6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5742,8 +5742,6 @@
method public void enableCarMode(int);
method public int getCurrentModeType();
method public int getNightMode();
- method public boolean isNightModeLocked();
- method public boolean isUiModeLocked();
method public void setNightMode(int);
field public static java.lang.String ACTION_ENTER_CAR_MODE;
field public static java.lang.String ACTION_ENTER_DESK_MODE;
@@ -5845,6 +5843,7 @@
public class WallpaperManager {
method public void clear() throws java.io.IOException;
+ method public void clear(int) throws java.io.IOException;
method public void clearWallpaper();
method public void clearWallpaper(int, int);
method public void clearWallpaperOffsets(android.os.IBinder);
@@ -20328,168 +20327,110 @@
public final class GnssClock implements android.os.Parcelable {
method public int describeContents();
- method public double getBiasInNs();
- method public double getBiasUncertaintyInNs();
- method public double getDriftInNsPerSec();
- method public double getDriftUncertaintyInNsPerSec();
- method public long getFullBiasInNs();
+ method public double getBiasNanos();
+ method public double getBiasUncertaintyNanos();
+ method public double getDriftNanosPerSecond();
+ method public double getDriftUncertaintyNanosPerSecond();
+ method public long getFullBiasNanos();
method public int getHardwareClockDiscontinuityCount();
- method public short getLeapSecond();
- method public long getTimeInNs();
- method public double getTimeUncertaintyInNs();
- method public boolean hasBiasInNs();
- method public boolean hasBiasUncertaintyInNs();
- method public boolean hasDriftInNsPerSec();
- method public boolean hasDriftUncertaintyInNsPerSec();
- method public boolean hasFullBiasInNs();
+ method public int getLeapSecond();
+ method public long getTimeNanos();
+ method public double getTimeUncertaintyNanos();
+ method public boolean hasBiasNanos();
+ method public boolean hasBiasUncertaintyNanos();
+ method public boolean hasDriftNanosPerSecond();
+ method public boolean hasDriftUncertaintyNanosPerSecond();
+ method public boolean hasFullBiasNanos();
method public boolean hasLeapSecond();
- method public boolean hasTimeUncertaintyInNs();
+ method public boolean hasTimeUncertaintyNanos();
method public void reset();
- method public void resetBiasInNs();
- method public void resetBiasUncertaintyInNs();
- method public void resetDriftInNsPerSec();
- method public void resetDriftUncertaintyInNsPerSec();
- method public void resetFullBiasInNs();
+ method public void resetBiasNanos();
+ method public void resetBiasUncertaintyNanos();
+ method public void resetDriftNanosPerSecond();
+ method public void resetDriftUncertaintyNanosPerSecond();
+ method public void resetFullBiasNanos();
method public void resetLeapSecond();
- method public void resetTimeUncertaintyInNs();
+ method public void resetTimeUncertaintyNanos();
method public void set(android.location.GnssClock);
- method public void setBiasInNs(double);
- method public void setBiasUncertaintyInNs(double);
- method public void setDriftInNsPerSec(double);
- method public void setDriftUncertaintyInNsPerSec(double);
- method public void setFullBiasInNs(long);
+ method public void setBiasNanos(double);
+ method public void setBiasUncertaintyNanos(double);
+ method public void setDriftNanosPerSecond(double);
+ method public void setDriftUncertaintyNanosPerSecond(double);
+ method public void setFullBiasNanos(long);
method public void setHardwareClockDiscontinuityCount(int);
- method public void setLeapSecond(short);
- method public void setTimeInNs(long);
- method public void setTimeUncertaintyInNs(double);
+ method public void setLeapSecond(int);
+ method public void setTimeNanos(long);
+ method public void setTimeUncertaintyNanos(double);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssClock> CREATOR;
}
public final class GnssMeasurement implements android.os.Parcelable {
method public int describeContents();
- method public double getAccumulatedDeltaRangeInMeters();
- method public short getAccumulatedDeltaRangeState();
- method public double getAccumulatedDeltaRangeUncertaintyInMeters();
- method public double getAzimuthInDeg();
- method public double getAzimuthUncertaintyInDeg();
- method public int getBitNumber();
+ method public double getAccumulatedDeltaRangeMeters();
+ method public int getAccumulatedDeltaRangeState();
+ method public double getAccumulatedDeltaRangeUncertaintyMeters();
method public long getCarrierCycles();
- method public float getCarrierFrequencyInHz();
+ method public float getCarrierFrequencyHz();
method public double getCarrierPhase();
method public double getCarrierPhaseUncertainty();
- method public double getCn0InDbHz();
- method public double getCodePhaseInChips();
- method public double getCodePhaseUncertaintyInChips();
- method public byte getConstellationType();
- method public double getDopplerShiftInHz();
- method public double getDopplerShiftUncertaintyInHz();
- method public double getElevationInDeg();
- method public double getElevationUncertaintyInDeg();
- method public byte getLossOfLock();
- method public byte getMultipathIndicator();
- method public double getPseudorangeInMeters();
- method public double getPseudorangeRateInMetersPerSec();
- method public double getPseudorangeRateUncertaintyInMetersPerSec();
- method public double getPseudorangeUncertaintyInMeters();
- method public long getReceivedSvTimeInNs();
- method public long getReceivedSvTimeUncertaintyInNs();
+ method public double getCn0DbHz();
+ method public int getConstellationType();
+ method public int getMultipathIndicator();
+ method public double getPseudorangeRateMetersPerSecond();
+ method public double getPseudorangeRateUncertaintyMetersPerSecond();
+ method public long getReceivedSvTimeNanos();
+ method public long getReceivedSvTimeUncertaintyNanos();
method public double getSnrInDb();
- method public short getState();
- method public short getSvid();
- method public short getTimeFromLastBitInMs();
- method public double getTimeOffsetInNs();
- method public boolean hasAzimuthInDeg();
- method public boolean hasAzimuthUncertaintyInDeg();
- method public boolean hasBitNumber();
+ method public int getState();
+ method public int getSvid();
+ method public double getTimeOffsetNanos();
method public boolean hasCarrierCycles();
- method public boolean hasCarrierFrequencyInHz();
+ method public boolean hasCarrierFrequencyHz();
method public boolean hasCarrierPhase();
method public boolean hasCarrierPhaseUncertainty();
- method public boolean hasCodePhaseInChips();
- method public boolean hasCodePhaseUncertaintyInChips();
- method public boolean hasDopplerShiftInHz();
- method public boolean hasDopplerShiftUncertaintyInHz();
- method public boolean hasElevationInDeg();
- method public boolean hasElevationUncertaintyInDeg();
- method public boolean hasPseudorangeInMeters();
- method public boolean hasPseudorangeUncertaintyInMeters();
method public boolean hasSnrInDb();
- method public boolean hasTimeFromLastBitInMs();
method public boolean isPseudorangeRateCorrected();
- method public boolean isUsedInFix();
method public void reset();
- method public void resetAzimuthInDeg();
- method public void resetAzimuthUncertaintyInDeg();
- method public void resetBitNumber();
method public void resetCarrierCycles();
- method public void resetCarrierFrequencyInHz();
+ method public void resetCarrierFrequencyHz();
method public void resetCarrierPhase();
method public void resetCarrierPhaseUncertainty();
- method public void resetCodePhaseInChips();
- method public void resetCodePhaseUncertaintyInChips();
- method public void resetDopplerShiftInHz();
- method public void resetDopplerShiftUncertaintyInHz();
- method public void resetElevationInDeg();
- method public void resetElevationUncertaintyInDeg();
- method public void resetPseudorangeInMeters();
- method public void resetPseudorangeUncertaintyInMeters();
method public void resetSnrInDb();
- method public void resetTimeFromLastBitInMs();
method public void set(android.location.GnssMeasurement);
- method public void setAccumulatedDeltaRangeInMeters(double);
- method public void setAccumulatedDeltaRangeState(short);
- method public void setAccumulatedDeltaRangeUncertaintyInMeters(double);
- method public void setAzimuthInDeg(double);
- method public void setAzimuthUncertaintyInDeg(double);
- method public void setBitNumber(int);
+ method public void setAccumulatedDeltaRangeMeters(double);
+ method public void setAccumulatedDeltaRangeState(int);
+ method public void setAccumulatedDeltaRangeUncertaintyMeters(double);
method public void setCarrierCycles(long);
- method public void setCarrierFrequencyInHz(float);
+ method public void setCarrierFrequencyHz(float);
method public void setCarrierPhase(double);
method public void setCarrierPhaseUncertainty(double);
- method public void setCn0InDbHz(double);
- method public void setCodePhaseInChips(double);
- method public void setCodePhaseUncertaintyInChips(double);
- method public void setConstellationType(byte);
- method public void setDopplerShiftInHz(double);
- method public void setDopplerShiftUncertaintyInHz(double);
- method public void setElevationInDeg(double);
- method public void setElevationUncertaintyInDeg(double);
- method public void setLossOfLock(byte);
- method public void setMultipathIndicator(byte);
- method public void setPseudorangeInMeters(double);
- method public void setPseudorangeRateInMetersPerSec(double);
- method public void setPseudorangeRateUncertaintyInMetersPerSec(double);
- method public void setPseudorangeUncertaintyInMeters(double);
- method public void setReceivedSvTimeInNs(long);
- method public void setReceivedSvTimeUncertaintyInNs(long);
+ method public void setCn0DbHz(double);
+ method public void setConstellationType(int);
+ method public void setMultipathIndicator(int);
+ method public void setPseudorangeRateMetersPerSecond(double);
+ method public void setPseudorangeRateUncertaintyMetersPerSecond(double);
+ method public void setReceivedSvTimeNanos(long);
+ method public void setReceivedSvTimeUncertaintyNanos(long);
method public void setSnrInDb(double);
- method public void setState(short);
- method public void setSvid(short);
- method public void setTimeFromLastBitInMs(short);
- method public void setTimeOffsetInNs(double);
- method public void setUsedInFix(boolean);
+ method public void setState(int);
+ method public void setSvid(int);
+ method public void setTimeOffsetNanos(double);
method public void writeToParcel(android.os.Parcel, int);
- field public static final short ADR_STATE_CYCLE_SLIP = 4; // 0x4
- field public static final short ADR_STATE_RESET = 2; // 0x2
- field public static final short ADR_STATE_UNKNOWN = 0; // 0x0
- field public static final short ADR_STATE_VALID = 1; // 0x1
+ field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4
+ 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
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
- field public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2; // 0x2
- field public static final byte LOSS_OF_LOCK_OK = 1; // 0x1
- field public static final byte LOSS_OF_LOCK_UNKNOWN = 0; // 0x0
- field public static final byte MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
- field public static final byte MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
- field public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
- field public static final short STATE_BIT_SYNC = 2; // 0x2
- field public static final short STATE_CODE_LOCK = 1; // 0x1
- field public static final short STATE_MSEC_AMBIGUOUS = 16; // 0x10
- field public static final short STATE_SUBFRAME_SYNC = 4; // 0x4
- field public static final short STATE_TOW_DECODED = 8; // 0x8
- field public static final short STATE_UNKNOWN = 0; // 0x0
- }
-
- public static abstract class GnssMeasurement.LossOfLockStatus implements java.lang.annotation.Annotation {
+ field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
+ field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+ field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BIT_SYNC = 2; // 0x2
+ field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_TOW_DECODED = 8; // 0x8
+ field public static final int STATE_UNKNOWN = 0; // 0x0
}
public static abstract class GnssMeasurement.MultipathIndicator implements java.lang.annotation.Annotation {
@@ -20502,7 +20443,7 @@
method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
- field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
@@ -20519,34 +20460,34 @@
public final class GnssNavigationMessage implements android.os.Parcelable {
method public int describeContents();
method public byte[] getData();
- method public short getMessageId();
- method public short getStatus();
- method public short getSubmessageId();
- method public short getSvid();
- method public short getType();
+ method public int getMessageId();
+ method public int getStatus();
+ method public int getSubmessageId();
+ method public int getSvid();
+ method public int getType();
method public void reset();
method public void set(android.location.GnssNavigationMessage);
method public void setData(byte[]);
- method public void setMessageId(short);
- method public void setStatus(short);
- method public void setSubmessageId(short);
- method public void setSvid(short);
- method public void setType(short);
+ method public void setMessageId(int);
+ method public void setStatus(int);
+ method public void setSubmessageId(int);
+ method public void setSvid(int);
+ method public void setType(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
- field public static final short MESSAGE_TYPE_BDS_D1 = 1281; // 0x501
- field public static final short MESSAGE_TYPE_BDS_D2 = 1282; // 0x502
- field public static final short MESSAGE_TYPE_GAL_F = 1538; // 0x602
- field public static final short MESSAGE_TYPE_GAL_I = 1537; // 0x601
- field public static final short MESSAGE_TYPE_GLO_L1CA = 769; // 0x301
- field public static final short MESSAGE_TYPE_GPS_CNAV2 = 260; // 0x104
- field public static final short MESSAGE_TYPE_GPS_L1CA = 257; // 0x101
- field public static final short MESSAGE_TYPE_GPS_L2CNAV = 258; // 0x102
- field public static final short MESSAGE_TYPE_GPS_L5CNAV = 259; // 0x103
- field public static final short MESSAGE_TYPE_UNKNOWN = 0; // 0x0
- field public static final short STATUS_PARITY_PASSED = 1; // 0x1
- field public static final short STATUS_PARITY_REBUILT = 2; // 0x2
- field public static final short STATUS_UNKNOWN = 0; // 0x0
+ field public static final int STATUS_PARITY_PASSED = 1; // 0x1
+ field public static final int STATUS_PARITY_REBUILT = 2; // 0x2
+ field public static final int STATUS_UNKNOWN = 0; // 0x0
+ field public static final int TYPE_BDS_D1 = 1281; // 0x501
+ field public static final int TYPE_BDS_D2 = 1282; // 0x502
+ field public static final int TYPE_GAL_F = 1538; // 0x602
+ field public static final int TYPE_GAL_I = 1537; // 0x601
+ field public static final int TYPE_GLO_L1CA = 769; // 0x301
+ field public static final int TYPE_GPS_CNAV2 = 260; // 0x104
+ field public static final int TYPE_GPS_L1CA = 257; // 0x101
+ field public static final int TYPE_GPS_L2CNAV = 258; // 0x102
+ field public static final int TYPE_GPS_L5CNAV = 259; // 0x103
+ field public static final int TYPE_UNKNOWN = 0; // 0x0
}
public static abstract class GnssNavigationMessage.GnssNavigationMessageType implements java.lang.annotation.Annotation {
@@ -20558,7 +20499,7 @@
method public android.location.GnssNavigationMessage getNavigationMessage();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
- field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
@@ -20577,22 +20518,22 @@
}
public final class GnssStatus {
- method public float getAzimuth(int);
- method public byte getConstellationType(int);
- method public float getElevation(int);
+ method public float getAzimuthDegrees(int);
+ method public float getCn0DbHz(int);
+ method public int getConstellationType(int);
+ method public float getElevationDegrees(int);
method public int getNumSatellites();
- method public float getSnr(int);
method public int getSvid(int);
method public boolean hasAlmanac(int);
method public boolean hasEphemeris(int);
method public boolean usedInFix(int);
- field public static final byte CONSTELLATION_BEIDOU = 5; // 0x5
- field public static final byte CONSTELLATION_GALILEO = 6; // 0x6
- field public static final byte CONSTELLATION_GLONASS = 3; // 0x3
- field public static final byte CONSTELLATION_GPS = 1; // 0x1
- field public static final byte CONSTELLATION_QZSS = 4; // 0x4
- field public static final byte CONSTELLATION_SBAS = 2; // 0x2
- field public static final byte CONSTELLATION_UNKNOWN = 0; // 0x0
+ field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
+ field public static final int CONSTELLATION_GALILEO = 6; // 0x6
+ field public static final int CONSTELLATION_GLONASS = 3; // 0x3
+ field public static final int CONSTELLATION_GPS = 1; // 0x1
+ field public static final int CONSTELLATION_QZSS = 4; // 0x4
+ field public static final int CONSTELLATION_SBAS = 2; // 0x2
+ field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
}
public static abstract class GnssStatus.ConstellationType implements java.lang.annotation.Annotation {
@@ -20954,8 +20895,8 @@
method public java.util.List<java.lang.String> getProviders(boolean);
method public java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
method public boolean isProviderEnabled(java.lang.String);
- method public boolean registerGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback);
- method public boolean registerGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
+ method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
+ method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
@@ -20984,7 +20925,7 @@
method public void setTestProviderEnabled(java.lang.String, boolean);
method public void setTestProviderLocation(java.lang.String, android.location.Location);
method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
- method public void unregisterGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback);
+ method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
field public static final java.lang.String GPS_PROVIDER = "gps";
@@ -22484,6 +22425,7 @@
field public static final java.lang.String KEY_SLICE_HEIGHT = "slice-height";
field public static final java.lang.String KEY_STRIDE = "stride";
field public static final java.lang.String KEY_TEMPORAL_LAYERING = "ts-schema";
+ field public static final java.lang.String KEY_TRACK_ID = "track-id";
field public static final java.lang.String KEY_WIDTH = "width";
field public static final java.lang.String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
field public static final java.lang.String MIMETYPE_AUDIO_AC3 = "audio/ac3";
@@ -26721,7 +26663,6 @@
method public boolean reconnect();
method public boolean removeNetwork(int);
method public boolean saveConfiguration();
- method public boolean setMetered(int, boolean);
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
@@ -31398,6 +31339,8 @@
ctor public Process();
method public static final long getElapsedCpuTime();
method public static final int getGidForName(java.lang.String);
+ method public static final long getStartElapsedRealtime();
+ method public static final long getStartUptimeMillis();
method public static final int getThreadPriority(int) throws java.lang.IllegalArgumentException;
method public static final int getUidForName(java.lang.String);
method public static final boolean is64Bit();
@@ -61173,6 +61116,54 @@
method public abstract void update(java.util.Observable, java.lang.Object);
}
+ public final class Optional {
+ method public static java.util.Optional<T> empty();
+ method public java.util.Optional<T> filter(java.util.function.Predicate<? super T>);
+ method public java.util.Optional<U> flatMap(java.util.function.Function<? super T, java.util.Optional<U>>);
+ method public T get();
+ method public void ifPresent(java.util.function.Consumer<? super T>);
+ method public boolean isPresent();
+ method public java.util.Optional<U> map(java.util.function.Function<? super T, ? extends U>);
+ method public static java.util.Optional<T> of(T);
+ method public static java.util.Optional<T> ofNullable(T);
+ method public T orElse(T);
+ method public T orElseGet(java.util.function.Supplier<? extends T>);
+ method public T orElseThrow(java.util.function.Supplier<? extends X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalDouble {
+ method public static java.util.OptionalDouble empty();
+ method public double getAsDouble();
+ method public void ifPresent(java.util.function.DoubleConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalDouble of(double);
+ method public double orElse(double);
+ method public double orElseGet(java.util.function.DoubleSupplier);
+ method public double orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalInt {
+ method public static java.util.OptionalInt empty();
+ method public int getAsInt();
+ method public void ifPresent(java.util.function.IntConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalInt of(int);
+ method public int orElse(int);
+ method public int orElseGet(java.util.function.IntSupplier);
+ method public int orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalLong {
+ method public static java.util.OptionalLong empty();
+ method public long getAsLong();
+ method public void ifPresent(java.util.function.LongConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalLong of(long);
+ method public long orElse(long);
+ method public long orElseGet(java.util.function.LongSupplier);
+ method public long orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable {
ctor public PriorityQueue();
ctor public PriorityQueue(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 1039fed..dcb2f32 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5715,6 +5715,7 @@
public class WallpaperManager {
method public void clear() throws java.io.IOException;
+ method public void clear(int) throws java.io.IOException;
method public void clearWallpaperOffsets(android.os.IBinder);
method public void forgetLoadedWallpaper();
method public android.graphics.drawable.Drawable getBuiltInDrawable();
@@ -19165,168 +19166,110 @@
public final class GnssClock implements android.os.Parcelable {
method public int describeContents();
- method public double getBiasInNs();
- method public double getBiasUncertaintyInNs();
- method public double getDriftInNsPerSec();
- method public double getDriftUncertaintyInNsPerSec();
- method public long getFullBiasInNs();
+ method public double getBiasNanos();
+ method public double getBiasUncertaintyNanos();
+ method public double getDriftNanosPerSecond();
+ method public double getDriftUncertaintyNanosPerSecond();
+ method public long getFullBiasNanos();
method public int getHardwareClockDiscontinuityCount();
- method public short getLeapSecond();
- method public long getTimeInNs();
- method public double getTimeUncertaintyInNs();
- method public boolean hasBiasInNs();
- method public boolean hasBiasUncertaintyInNs();
- method public boolean hasDriftInNsPerSec();
- method public boolean hasDriftUncertaintyInNsPerSec();
- method public boolean hasFullBiasInNs();
+ method public int getLeapSecond();
+ method public long getTimeNanos();
+ method public double getTimeUncertaintyNanos();
+ method public boolean hasBiasNanos();
+ method public boolean hasBiasUncertaintyNanos();
+ method public boolean hasDriftNanosPerSecond();
+ method public boolean hasDriftUncertaintyNanosPerSecond();
+ method public boolean hasFullBiasNanos();
method public boolean hasLeapSecond();
- method public boolean hasTimeUncertaintyInNs();
+ method public boolean hasTimeUncertaintyNanos();
method public void reset();
- method public void resetBiasInNs();
- method public void resetBiasUncertaintyInNs();
- method public void resetDriftInNsPerSec();
- method public void resetDriftUncertaintyInNsPerSec();
- method public void resetFullBiasInNs();
+ method public void resetBiasNanos();
+ method public void resetBiasUncertaintyNanos();
+ method public void resetDriftNanosPerSecond();
+ method public void resetDriftUncertaintyNanosPerSecond();
+ method public void resetFullBiasNanos();
method public void resetLeapSecond();
- method public void resetTimeUncertaintyInNs();
+ method public void resetTimeUncertaintyNanos();
method public void set(android.location.GnssClock);
- method public void setBiasInNs(double);
- method public void setBiasUncertaintyInNs(double);
- method public void setDriftInNsPerSec(double);
- method public void setDriftUncertaintyInNsPerSec(double);
- method public void setFullBiasInNs(long);
+ method public void setBiasNanos(double);
+ method public void setBiasUncertaintyNanos(double);
+ method public void setDriftNanosPerSecond(double);
+ method public void setDriftUncertaintyNanosPerSecond(double);
+ method public void setFullBiasNanos(long);
method public void setHardwareClockDiscontinuityCount(int);
- method public void setLeapSecond(short);
- method public void setTimeInNs(long);
- method public void setTimeUncertaintyInNs(double);
+ method public void setLeapSecond(int);
+ method public void setTimeNanos(long);
+ method public void setTimeUncertaintyNanos(double);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssClock> CREATOR;
}
public final class GnssMeasurement implements android.os.Parcelable {
method public int describeContents();
- method public double getAccumulatedDeltaRangeInMeters();
- method public short getAccumulatedDeltaRangeState();
- method public double getAccumulatedDeltaRangeUncertaintyInMeters();
- method public double getAzimuthInDeg();
- method public double getAzimuthUncertaintyInDeg();
- method public int getBitNumber();
+ method public double getAccumulatedDeltaRangeMeters();
+ method public int getAccumulatedDeltaRangeState();
+ method public double getAccumulatedDeltaRangeUncertaintyMeters();
method public long getCarrierCycles();
- method public float getCarrierFrequencyInHz();
+ method public float getCarrierFrequencyHz();
method public double getCarrierPhase();
method public double getCarrierPhaseUncertainty();
- method public double getCn0InDbHz();
- method public double getCodePhaseInChips();
- method public double getCodePhaseUncertaintyInChips();
- method public byte getConstellationType();
- method public double getDopplerShiftInHz();
- method public double getDopplerShiftUncertaintyInHz();
- method public double getElevationInDeg();
- method public double getElevationUncertaintyInDeg();
- method public byte getLossOfLock();
- method public byte getMultipathIndicator();
- method public double getPseudorangeInMeters();
- method public double getPseudorangeRateInMetersPerSec();
- method public double getPseudorangeRateUncertaintyInMetersPerSec();
- method public double getPseudorangeUncertaintyInMeters();
- method public long getReceivedSvTimeInNs();
- method public long getReceivedSvTimeUncertaintyInNs();
+ method public double getCn0DbHz();
+ method public int getConstellationType();
+ method public int getMultipathIndicator();
+ method public double getPseudorangeRateMetersPerSecond();
+ method public double getPseudorangeRateUncertaintyMetersPerSecond();
+ method public long getReceivedSvTimeNanos();
+ method public long getReceivedSvTimeUncertaintyNanos();
method public double getSnrInDb();
- method public short getState();
- method public short getSvid();
- method public short getTimeFromLastBitInMs();
- method public double getTimeOffsetInNs();
- method public boolean hasAzimuthInDeg();
- method public boolean hasAzimuthUncertaintyInDeg();
- method public boolean hasBitNumber();
+ method public int getState();
+ method public int getSvid();
+ method public double getTimeOffsetNanos();
method public boolean hasCarrierCycles();
- method public boolean hasCarrierFrequencyInHz();
+ method public boolean hasCarrierFrequencyHz();
method public boolean hasCarrierPhase();
method public boolean hasCarrierPhaseUncertainty();
- method public boolean hasCodePhaseInChips();
- method public boolean hasCodePhaseUncertaintyInChips();
- method public boolean hasDopplerShiftInHz();
- method public boolean hasDopplerShiftUncertaintyInHz();
- method public boolean hasElevationInDeg();
- method public boolean hasElevationUncertaintyInDeg();
- method public boolean hasPseudorangeInMeters();
- method public boolean hasPseudorangeUncertaintyInMeters();
method public boolean hasSnrInDb();
- method public boolean hasTimeFromLastBitInMs();
method public boolean isPseudorangeRateCorrected();
- method public boolean isUsedInFix();
method public void reset();
- method public void resetAzimuthInDeg();
- method public void resetAzimuthUncertaintyInDeg();
- method public void resetBitNumber();
method public void resetCarrierCycles();
- method public void resetCarrierFrequencyInHz();
+ method public void resetCarrierFrequencyHz();
method public void resetCarrierPhase();
method public void resetCarrierPhaseUncertainty();
- method public void resetCodePhaseInChips();
- method public void resetCodePhaseUncertaintyInChips();
- method public void resetDopplerShiftInHz();
- method public void resetDopplerShiftUncertaintyInHz();
- method public void resetElevationInDeg();
- method public void resetElevationUncertaintyInDeg();
- method public void resetPseudorangeInMeters();
- method public void resetPseudorangeUncertaintyInMeters();
method public void resetSnrInDb();
- method public void resetTimeFromLastBitInMs();
method public void set(android.location.GnssMeasurement);
- method public void setAccumulatedDeltaRangeInMeters(double);
- method public void setAccumulatedDeltaRangeState(short);
- method public void setAccumulatedDeltaRangeUncertaintyInMeters(double);
- method public void setAzimuthInDeg(double);
- method public void setAzimuthUncertaintyInDeg(double);
- method public void setBitNumber(int);
+ method public void setAccumulatedDeltaRangeMeters(double);
+ method public void setAccumulatedDeltaRangeState(int);
+ method public void setAccumulatedDeltaRangeUncertaintyMeters(double);
method public void setCarrierCycles(long);
- method public void setCarrierFrequencyInHz(float);
+ method public void setCarrierFrequencyHz(float);
method public void setCarrierPhase(double);
method public void setCarrierPhaseUncertainty(double);
- method public void setCn0InDbHz(double);
- method public void setCodePhaseInChips(double);
- method public void setCodePhaseUncertaintyInChips(double);
- method public void setConstellationType(byte);
- method public void setDopplerShiftInHz(double);
- method public void setDopplerShiftUncertaintyInHz(double);
- method public void setElevationInDeg(double);
- method public void setElevationUncertaintyInDeg(double);
- method public void setLossOfLock(byte);
- method public void setMultipathIndicator(byte);
- method public void setPseudorangeInMeters(double);
- method public void setPseudorangeRateInMetersPerSec(double);
- method public void setPseudorangeRateUncertaintyInMetersPerSec(double);
- method public void setPseudorangeUncertaintyInMeters(double);
- method public void setReceivedSvTimeInNs(long);
- method public void setReceivedSvTimeUncertaintyInNs(long);
+ method public void setCn0DbHz(double);
+ method public void setConstellationType(int);
+ method public void setMultipathIndicator(int);
+ method public void setPseudorangeRateMetersPerSecond(double);
+ method public void setPseudorangeRateUncertaintyMetersPerSecond(double);
+ method public void setReceivedSvTimeNanos(long);
+ method public void setReceivedSvTimeUncertaintyNanos(long);
method public void setSnrInDb(double);
- method public void setState(short);
- method public void setSvid(short);
- method public void setTimeFromLastBitInMs(short);
- method public void setTimeOffsetInNs(double);
- method public void setUsedInFix(boolean);
+ method public void setState(int);
+ method public void setSvid(int);
+ method public void setTimeOffsetNanos(double);
method public void writeToParcel(android.os.Parcel, int);
- field public static final short ADR_STATE_CYCLE_SLIP = 4; // 0x4
- field public static final short ADR_STATE_RESET = 2; // 0x2
- field public static final short ADR_STATE_UNKNOWN = 0; // 0x0
- field public static final short ADR_STATE_VALID = 1; // 0x1
+ field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4
+ 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
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurement> CREATOR;
- field public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2; // 0x2
- field public static final byte LOSS_OF_LOCK_OK = 1; // 0x1
- field public static final byte LOSS_OF_LOCK_UNKNOWN = 0; // 0x0
- field public static final byte MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
- field public static final byte MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
- field public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
- field public static final short STATE_BIT_SYNC = 2; // 0x2
- field public static final short STATE_CODE_LOCK = 1; // 0x1
- field public static final short STATE_MSEC_AMBIGUOUS = 16; // 0x10
- field public static final short STATE_SUBFRAME_SYNC = 4; // 0x4
- field public static final short STATE_TOW_DECODED = 8; // 0x8
- field public static final short STATE_UNKNOWN = 0; // 0x0
- }
-
- public static abstract class GnssMeasurement.LossOfLockStatus implements java.lang.annotation.Annotation {
+ field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
+ field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
+ field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BIT_SYNC = 2; // 0x2
+ field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_TOW_DECODED = 8; // 0x8
+ field public static final int STATE_UNKNOWN = 0; // 0x0
}
public static abstract class GnssMeasurement.MultipathIndicator implements java.lang.annotation.Annotation {
@@ -19339,7 +19282,7 @@
method public java.util.Collection<android.location.GnssMeasurement> getMeasurements();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementsEvent> CREATOR;
- field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
@@ -19356,34 +19299,34 @@
public final class GnssNavigationMessage implements android.os.Parcelable {
method public int describeContents();
method public byte[] getData();
- method public short getMessageId();
- method public short getStatus();
- method public short getSubmessageId();
- method public short getSvid();
- method public short getType();
+ method public int getMessageId();
+ method public int getStatus();
+ method public int getSubmessageId();
+ method public int getSvid();
+ method public int getType();
method public void reset();
method public void set(android.location.GnssNavigationMessage);
method public void setData(byte[]);
- method public void setMessageId(short);
- method public void setStatus(short);
- method public void setSubmessageId(short);
- method public void setSvid(short);
- method public void setType(short);
+ method public void setMessageId(int);
+ method public void setStatus(int);
+ method public void setSubmessageId(int);
+ method public void setSvid(int);
+ method public void setType(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
- field public static final short MESSAGE_TYPE_BDS_D1 = 1281; // 0x501
- field public static final short MESSAGE_TYPE_BDS_D2 = 1282; // 0x502
- field public static final short MESSAGE_TYPE_GAL_F = 1538; // 0x602
- field public static final short MESSAGE_TYPE_GAL_I = 1537; // 0x601
- field public static final short MESSAGE_TYPE_GLO_L1CA = 769; // 0x301
- field public static final short MESSAGE_TYPE_GPS_CNAV2 = 260; // 0x104
- field public static final short MESSAGE_TYPE_GPS_L1CA = 257; // 0x101
- field public static final short MESSAGE_TYPE_GPS_L2CNAV = 258; // 0x102
- field public static final short MESSAGE_TYPE_GPS_L5CNAV = 259; // 0x103
- field public static final short MESSAGE_TYPE_UNKNOWN = 0; // 0x0
- field public static final short STATUS_PARITY_PASSED = 1; // 0x1
- field public static final short STATUS_PARITY_REBUILT = 2; // 0x2
- field public static final short STATUS_UNKNOWN = 0; // 0x0
+ field public static final int STATUS_PARITY_PASSED = 1; // 0x1
+ field public static final int STATUS_PARITY_REBUILT = 2; // 0x2
+ field public static final int STATUS_UNKNOWN = 0; // 0x0
+ field public static final int TYPE_BDS_D1 = 1281; // 0x501
+ field public static final int TYPE_BDS_D2 = 1282; // 0x502
+ field public static final int TYPE_GAL_F = 1538; // 0x602
+ field public static final int TYPE_GAL_I = 1537; // 0x601
+ field public static final int TYPE_GLO_L1CA = 769; // 0x301
+ field public static final int TYPE_GPS_CNAV2 = 260; // 0x104
+ field public static final int TYPE_GPS_L1CA = 257; // 0x101
+ field public static final int TYPE_GPS_L2CNAV = 258; // 0x102
+ field public static final int TYPE_GPS_L5CNAV = 259; // 0x103
+ field public static final int TYPE_UNKNOWN = 0; // 0x0
}
public static abstract class GnssNavigationMessage.GnssNavigationMessageType implements java.lang.annotation.Annotation {
@@ -19395,7 +19338,7 @@
method public android.location.GnssNavigationMessage getNavigationMessage();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessageEvent> CREATOR;
- field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_GNSS_LOCATION_DISABLED = 2; // 0x2
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
@@ -19414,22 +19357,22 @@
}
public final class GnssStatus {
- method public float getAzimuth(int);
- method public byte getConstellationType(int);
- method public float getElevation(int);
+ method public float getAzimuthDegrees(int);
+ method public float getCn0DbHz(int);
+ method public int getConstellationType(int);
+ method public float getElevationDegrees(int);
method public int getNumSatellites();
- method public float getSnr(int);
method public int getSvid(int);
method public boolean hasAlmanac(int);
method public boolean hasEphemeris(int);
method public boolean usedInFix(int);
- field public static final byte CONSTELLATION_BEIDOU = 5; // 0x5
- field public static final byte CONSTELLATION_GALILEO = 6; // 0x6
- field public static final byte CONSTELLATION_GLONASS = 3; // 0x3
- field public static final byte CONSTELLATION_GPS = 1; // 0x1
- field public static final byte CONSTELLATION_QZSS = 4; // 0x4
- field public static final byte CONSTELLATION_SBAS = 2; // 0x2
- field public static final byte CONSTELLATION_UNKNOWN = 0; // 0x0
+ field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
+ field public static final int CONSTELLATION_GALILEO = 6; // 0x6
+ field public static final int CONSTELLATION_GLONASS = 3; // 0x3
+ field public static final int CONSTELLATION_GPS = 1; // 0x1
+ field public static final int CONSTELLATION_QZSS = 4; // 0x4
+ field public static final int CONSTELLATION_SBAS = 2; // 0x2
+ field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
}
public static abstract class GnssStatus.ConstellationType implements java.lang.annotation.Annotation {
@@ -19545,8 +19488,8 @@
method public java.util.List<java.lang.String> getProviders(boolean);
method public java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
method public boolean isProviderEnabled(java.lang.String);
- method public boolean registerGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback);
- method public boolean registerGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
+ method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
+ method public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback, android.os.Handler);
method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback);
@@ -19571,7 +19514,7 @@
method public void setTestProviderEnabled(java.lang.String, boolean);
method public void setTestProviderLocation(java.lang.String, android.location.Location);
method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
- method public void unregisterGnssMeasurementCallback(android.location.GnssMeasurementsEvent.Callback);
+ method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessageEvent.Callback);
method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback);
field public static final java.lang.String GPS_PROVIDER = "gps";
@@ -21003,6 +20946,7 @@
field public static final java.lang.String KEY_SLICE_HEIGHT = "slice-height";
field public static final java.lang.String KEY_STRIDE = "stride";
field public static final java.lang.String KEY_TEMPORAL_LAYERING = "ts-schema";
+ field public static final java.lang.String KEY_TRACK_ID = "track-id";
field public static final java.lang.String KEY_WIDTH = "width";
field public static final java.lang.String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
field public static final java.lang.String MIMETYPE_AUDIO_AC3 = "audio/ac3";
@@ -29115,6 +29059,8 @@
ctor public Process();
method public static final long getElapsedCpuTime();
method public static final int getGidForName(java.lang.String);
+ method public static final long getStartElapsedRealtime();
+ method public static final long getStartUptimeMillis();
method public static final int getThreadPriority(int) throws java.lang.IllegalArgumentException;
method public static final int getUidForName(java.lang.String);
method public static final boolean is64Bit();
@@ -58087,6 +58033,54 @@
method public abstract void update(java.util.Observable, java.lang.Object);
}
+ public final class Optional {
+ method public static java.util.Optional<T> empty();
+ method public java.util.Optional<T> filter(java.util.function.Predicate<? super T>);
+ method public java.util.Optional<U> flatMap(java.util.function.Function<? super T, java.util.Optional<U>>);
+ method public T get();
+ method public void ifPresent(java.util.function.Consumer<? super T>);
+ method public boolean isPresent();
+ method public java.util.Optional<U> map(java.util.function.Function<? super T, ? extends U>);
+ method public static java.util.Optional<T> of(T);
+ method public static java.util.Optional<T> ofNullable(T);
+ method public T orElse(T);
+ method public T orElseGet(java.util.function.Supplier<? extends T>);
+ method public T orElseThrow(java.util.function.Supplier<? extends X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalDouble {
+ method public static java.util.OptionalDouble empty();
+ method public double getAsDouble();
+ method public void ifPresent(java.util.function.DoubleConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalDouble of(double);
+ method public double orElse(double);
+ method public double orElseGet(java.util.function.DoubleSupplier);
+ method public double orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalInt {
+ method public static java.util.OptionalInt empty();
+ method public int getAsInt();
+ method public void ifPresent(java.util.function.IntConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalInt of(int);
+ method public int orElse(int);
+ method public int orElseGet(java.util.function.IntSupplier);
+ method public int orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
+ public final class OptionalLong {
+ method public static java.util.OptionalLong empty();
+ method public long getAsLong();
+ method public void ifPresent(java.util.function.LongConsumer);
+ method public boolean isPresent();
+ method public static java.util.OptionalLong of(long);
+ method public long orElse(long);
+ method public long orElseGet(java.util.function.LongSupplier);
+ method public long orElseThrow(java.util.function.Supplier<X>) throws java.lang.Throwable;
+ }
+
public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable {
ctor public PriorityQueue();
ctor public PriorityQueue(int);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index be89b20..b87e9fa2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6599,7 +6599,8 @@
if (isAppDebuggable || isDlwarningEnabled) {
String dlwarning = getDlWarning();
if (dlwarning != null) {
- String appName = getString(mApplication.getApplicationInfo().labelRes);
+ String appName = getApplicationInfo().loadLabel(getPackageManager())
+ .toString();
String warning = "Detected problems with app native libraries\n" +
"(please consult log for detail):\n" + dlwarning;
if (isAppDebuggable) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 4aab163..4676cc4 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -647,6 +647,16 @@
return stackId != PINNED_STACK_ID && stackId != FREEFORM_WORKSPACE_STACK_ID
&& stackId != DOCKED_STACK_ID;
}
+
+ /**
+ * Returns true if the input stack id should only be present on a device that supports
+ * multi-window mode.
+ * @see android.app.ActivityManager#supportsMultiWindow
+ */
+ public static boolean isMultiWindowStack(int stackId) {
+ return isStaticStack(stackId) || stackId == PINNED_STACK_ID
+ || stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == DOCKED_STACK_ID;
+ }
}
/**
@@ -868,6 +878,17 @@
}
/**
+ * Returns true if the system supports at least one form of multi-window.
+ * E.g. freeform, split-screen, picture-in-picture.
+ * @hide
+ */
+ static public boolean supportsMultiWindow() {
+ return !isLowRamDeviceStatic()
+ && Resources.getSystem().getBoolean(
+ com.android.internal.R.bool.config_supportsMultiWindow);
+ }
+
+ /**
* Information you can set and retrieve about the current activity within the recent task list.
*/
public static class TaskDescription implements Parcelable {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b264e8e..9d8dca60 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -792,8 +792,9 @@
if (hasBounds) {
bounds = Rect.CREATOR.createFromParcel(data);
}
- moveTaskToDockedStack(taskId, createMode, toTop, animate, bounds);
+ boolean res = moveTaskToDockedStack(taskId, createMode, toTop, animate, bounds);
reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
return true;
}
@@ -3809,7 +3810,7 @@
reply.recycle();
}
@Override
- public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
+ public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
Rect initialBounds) throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -3827,8 +3828,10 @@
}
mRemote.transact(MOVE_TASK_TO_DOCKED_STACK_TRANSACTION, data, reply, 0);
reply.readException();
+ boolean res = reply.readInt() > 0;
data.recycle();
reply.recycle();
+ return res;
}
@Override
public boolean moveTopActivityToPinnedStack(int stackId, Rect r)
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1e95c98..2415ce1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4909,6 +4909,9 @@
DdmVmInternal.enableRecentAllocations(true);
}
+ // Note when this process has started.
+ Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
+
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 53cc9ca..c841111 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1093,6 +1093,14 @@
}
@Override
+ public Drawable getManagedUserBadgedDrawable(Drawable drawable, Rect badgeLocation,
+ int badgeDensity) {
+ Drawable badgeDrawable = getDrawableForDensity(
+ com.android.internal.R.drawable.ic_corp_badge, badgeDensity);
+ return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
+ }
+
+ @Override
public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
if (badgeResId == 0) {
@@ -1114,24 +1122,27 @@
@Override
public Drawable getUserBadgeForDensity(UserHandle user, int density) {
- return getManagedProfileIconForDensity(user, density,
- com.android.internal.R.drawable.ic_corp_badge);
+ return getManagedProfileIconForDensity(user, com.android.internal.R.drawable.ic_corp_badge,
+ density);
}
@Override
public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
- return getManagedProfileIconForDensity(user, density,
- com.android.internal.R.drawable.ic_corp_badge_no_background);
+ return getManagedProfileIconForDensity(user,
+ com.android.internal.R.drawable.ic_corp_badge_no_background, density);
}
- private Drawable getManagedProfileIconForDensity(UserHandle user, int density,
- int drawableId) {
+ private Drawable getDrawableForDensity(int drawableId, int density) {
+ if (density <= 0) {
+ density = mContext.getResources().getDisplayMetrics().densityDpi;
+ }
+ return Resources.getSystem().getDrawableForDensity(drawableId, density);
+ }
+
+ private Drawable getManagedProfileIconForDensity(UserHandle user, int drawableId, int density) {
UserInfo userInfo = getUserIfProfile(user.getIdentifier());
if (userInfo != null && userInfo.isManagedProfile()) {
- if (density <= 0) {
- density = mContext.getResources().getDisplayMetrics().densityDpi;
- }
- return Resources.getSystem().getDrawableForDensity(drawableId, density);
+ return getDrawableForDensity(drawableId, density);
}
return null;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 4bfd049..d78f59f 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -143,7 +143,7 @@
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
public void moveTaskBackwards(int task) throws RemoteException;
public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
- public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
+ public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
Rect initialBounds) throws RemoteException;
public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) throws RemoteException;
public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 73fb55f..69e8df8 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -17,6 +17,7 @@
package android.app;
import android.annotation.IntDef;
+import android.annotation.TestApi;
import android.content.Context;
import android.content.res.Configuration;
import android.os.RemoteException;
@@ -266,7 +267,9 @@
/**
* @return If UI mode is locked or not. When UI mode is locked, calls to change UI mode
* like {@link #enableCarMode(int)} will silently fail.
+ * @hide
*/
+ @TestApi
public boolean isUiModeLocked() {
if (mService != null) {
try {
@@ -286,7 +289,9 @@
* mode will fail silently.
*
* @return {@code true} if night mode is locked or {@code false} otherwise
+ * @hide
*/
+ @TestApi
public boolean isNightModeLocked() {
if (mService != null) {
try {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 4d8d96b0..6bc03f7 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1433,6 +1433,25 @@
}
/**
+ * Remove one or more currently set wallpapers, reverting to the system default
+ * display for each one. If {@link #FLAG_SET_SYSTEM} is set in the {@code which}
+ * parameter, the intent {@link Intent#ACTION_WALLPAPER_CHANGED} will be broadcast
+ * upon success.
+ *
+ * @param which A bitwise combination of {@link #FLAG_SET_SYSTEM} or
+ * {@link #FLAG_SET_LOCK}
+ * @throws IOException If an error occurs reverting to the built-in wallpaper.
+ */
+ public void clear(int which) throws IOException {
+ if ((which & FLAG_SET_SYSTEM) != 0) {
+ clear();
+ }
+ if ((which & FLAG_SET_LOCK) != 0) {
+ clearWallpaper(FLAG_SET_LOCK, mContext.getUserId());
+ }
+ }
+
+ /**
* Open stream representing the default static image wallpaper.
*
* @hide
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 5285d52..a1ad590 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2750,7 +2750,7 @@
* @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
* {@code null} if calling from a delegated certificate installer.
* @param alias The private key alias under which the certificate is installed.
- * @return {@code true} if the keys were both removed, {@code false} otherwise.
+ * @return {@code true} if the certificate alias no longer exists, {@code false} otherwise.
*/
public boolean removeKeyPair(@Nullable ComponentName admin, @NonNull String alias) {
try {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c2d1bdd..27056a3 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4339,6 +4339,32 @@
throws NameNotFoundException;
/**
+ * Returns a managed-user-style badged copy of the given drawable allowing the user to
+ * distinguish it from the original drawable.
+ * The caller can specify the location in the bounds of the drawable to be
+ * badged where the badge should be applied as well as the density of the
+ * badge to be used.
+ * <p>
+ * If the original drawable is a BitmapDrawable and the backing bitmap is
+ * mutable as per {@link android.graphics.Bitmap#isMutable()}, the badging
+ * is performed in place and the original drawable is returned.
+ * </p>
+ *
+ * @param drawable The drawable to badge.
+ * @param badgeLocation Where in the bounds of the badged drawable to place
+ * the badge. If it's {@code null}, the badge is applied on top of the entire
+ * drawable being badged.
+ * @param badgeDensity The optional desired density for the badge as per
+ * {@link android.util.DisplayMetrics#densityDpi}. If it's not positive,
+ * the density of the display is used.
+ * @return A drawable that combines the original drawable and a badge as
+ * determined by the system.
+ * @hide
+ */
+ public abstract Drawable getManagedUserBadgedDrawable(Drawable drawable, Rect badgeLocation,
+ int badgeDensity);
+
+ /**
* If the target user is a managed profile of the calling user or if the
* target user is the caller and is itself a managed profile, then this
* returns a badged copy of the given icon to be able to distinguish it from
@@ -4367,17 +4393,17 @@
* badge to be used.
* <p>
* If the original drawable is a BitmapDrawable and the backing bitmap is
- * mutable as per {@link android.graphics.Bitmap#isMutable()}, the bading
+ * mutable as per {@link android.graphics.Bitmap#isMutable()}, the badging
* is performed in place and the original drawable is returned.
* </p>
*
* @param drawable The drawable to badge.
* @param user The target user.
* @param badgeLocation Where in the bounds of the badged drawable to place
- * the badge. If not provided, the badge is applied on top of the entire
+ * the badge. If it's {@code null}, the badge is applied on top of the entire
* drawable being badged.
* @param badgeDensity The optional desired density for the badge as per
- * {@link android.util.DisplayMetrics#densityDpi}. If not provided,
+ * {@link android.util.DisplayMetrics#densityDpi}. If it's not positive,
* the density of the display is used.
* @return A drawable that combines the original drawable and a badge as
* determined by the system.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ce6ddfd..0588a9d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4690,9 +4690,6 @@
// preferred up order.
public int mPreferredOrder = 0;
- // For use by package manager to keep track of where it needs to do dexopt.
- public final ArraySet<String> mDexOptPerformed = new ArraySet<>(4);
-
// For use by package manager to keep track of when a package was last used.
public long mLastPackageUsageTimeInMills;
diff --git a/core/java/android/hardware/CameraInfo.aidl b/core/java/android/hardware/CameraInfo.aidl
deleted file mode 100644
index e21e694..0000000
--- a/core/java/android/hardware/CameraInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/** @hide */
-parcelable CameraInfo;
diff --git a/core/java/android/hardware/ICamera.aidl b/core/java/android/hardware/ICamera.aidl
deleted file mode 100644
index d4f64f8..0000000
--- a/core/java/android/hardware/ICamera.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/** @hide */
-interface ICamera
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICamera.h
- */
- void disconnect();
-}
diff --git a/core/java/android/hardware/ICameraClient.aidl b/core/java/android/hardware/ICameraClient.aidl
deleted file mode 100644
index d7877b4..0000000
--- a/core/java/android/hardware/ICameraClient.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/** @hide */
-interface ICameraClient
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICameraClient.h
- */
- // TODO: consider implementing this.
-}
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
deleted file mode 100644
index 0b165cd..0000000
--- a/core/java/android/hardware/ICameraService.aidl
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-import android.hardware.ICamera;
-import android.hardware.ICameraClient;
-import android.hardware.camera2.ICameraDeviceUser;
-import android.hardware.camera2.ICameraDeviceCallbacks;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.utils.BinderHolder;
-import android.hardware.ICameraServiceListener;
-import android.hardware.CameraInfo;
-
-/**
- * Binder interface for the native camera service running in mediaserver.
- *
- * @hide
- */
-interface ICameraService
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICameraService.h
- */
- int getNumberOfCameras(int type);
-
- // rest of 'int' return values in this file are actually status_t
-
- int getCameraInfo(int cameraId, out CameraInfo info);
-
- int connect(ICameraClient client, int cameraId,
- String opPackageName,
- int clientUid,
- // Container for an ICamera object
- out BinderHolder device);
-
- int connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,
- String opPackageName,
- int clientUid,
- // Container for an ICameraDeviceUser object
- out BinderHolder device);
-
- int addListener(ICameraServiceListener listener);
- int removeListener(ICameraServiceListener listener);
-
- int getCameraCharacteristics(int cameraId, out CameraMetadataNative info);
-
- /**
- * The java stubs for this method are not intended to be used. Please use
- * the native stub in frameworks/av/include/camera/ICameraService.h instead.
- * The BinderHolder output is being used as a placeholder, and will not be
- * well-formatted in the generated java method.
- */
- int getCameraVendorTagDescriptor(out BinderHolder desc);
-
- // Writes the camera1 parameters into a single-element array.
- int getLegacyParameters(int cameraId, out String[] parameters);
- // Determines if a particular API version is supported; see ICameraService.h for version defines
- int supportsCameraApi(int cameraId, int apiVersion);
-
- int connectLegacy(ICameraClient client, int cameraId,
- int halVersion,
- String opPackageName,
- int clientUid,
- // Container for an ICamera object
- out BinderHolder device);
-
- int setTorchMode(String CameraId, boolean enabled, IBinder clientBinder);
-
- /**
- * Notify the camera service of a system event. Should only be called from system_server.
- *
- * Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
- */
- oneway void notifySystemEvent(int eventId, in int[] args);
-}
diff --git a/core/java/android/hardware/ICameraServiceListener.aidl b/core/java/android/hardware/ICameraServiceListener.aidl
deleted file mode 100644
index 49278b6..0000000
--- a/core/java/android/hardware/ICameraServiceListener.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/** @hide */
-interface ICameraServiceListener
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/ICameraServiceListener.h
- */
- void onStatusChanged(int status, int cameraId);
-
- void onTorchStatusChanged(int status, String cameraId);
-}
diff --git a/core/java/android/hardware/ICameraServiceProxy.aidl b/core/java/android/hardware/ICameraServiceProxy.aidl
deleted file mode 100644
index 0e654d5..0000000
--- a/core/java/android/hardware/ICameraServiceProxy.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/**
- * Binder interface for the camera service proxy running in system_server.
- *
- * Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h
- *
- * @hide
- */
-interface ICameraServiceProxy
-{
- /**
- * Ping the service proxy to update the valid users for the camera service.
- */
- oneway void pingForUserUpdate();
-
- /**
- * Update the status of a camera device
- */
- oneway void notifyCameraState(String cameraId, int newCameraState);
-}
diff --git a/core/java/android/hardware/SensorEventListener.java b/core/java/android/hardware/SensorEventListener.java
index 0d859fb9..0c059ba 100644
--- a/core/java/android/hardware/SensorEventListener.java
+++ b/core/java/android/hardware/SensorEventListener.java
@@ -18,28 +18,33 @@
/**
* Used for receiving notifications from the SensorManager when
- * sensor values have changed.
+ * there is new sensor data.
*/
public interface SensorEventListener {
/**
- * Called when sensor values have changed.
+ * Called when there is a new sensor event. Note that "on changed"
+ * is somewhat of a misnomer, as this will also be called if we have a
+ * new reading from a sensor with the exact same sensor values (but a
+ * newer timestamp).
+ *
* <p>See {@link android.hardware.SensorManager SensorManager}
* for details on possible sensor types.
* <p>See also {@link android.hardware.SensorEvent SensorEvent}.
- *
+ *
* <p><b>NOTE:</b> The application doesn't own the
* {@link android.hardware.SensorEvent event}
* object passed as a parameter and therefore cannot hold on to it.
* The object may be part of an internal pool and may be reused by
* the framework.
*
- * @param event the {@link android.hardware.SensorEvent SensorEvent}.
+ * @param event the {@link android.hardware.SensorEvent SensorEvent}.
*/
public void onSensorChanged(SensorEvent event);
/**
- * Called when the accuracy of the registered sensor has changed.
+ * Called when the accuracy of the registered sensor has changed. Unlike
+ * onSensorChanged(), this is only called when this accuracy value changes.
*
* <p>See the SENSOR_STATUS_* constants in
* {@link android.hardware.SensorManager SensorManager} for details.
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index f0b17c30..5684aa5 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -46,7 +46,7 @@
* is an example of a trigger sensor.
* </p>
* <pre class="prettyprint">
- * public class SensorActivity extends Activity, implements SensorEventListener {
+ * public class SensorActivity extends Activity implements SensorEventListener {
* private final SensorManager mSensorManager;
* private final Sensor mAccelerometer;
*
diff --git a/core/java/android/hardware/camera2/CameraAccessException.java b/core/java/android/hardware/camera2/CameraAccessException.java
index 933ce0d..f9b659c 100644
--- a/core/java/android/hardware/camera2/CameraAccessException.java
+++ b/core/java/android/hardware/camera2/CameraAccessException.java
@@ -114,12 +114,12 @@
}
public CameraAccessException(@AccessError int problem, String message) {
- super(message);
+ super(getCombinedMessage(problem, message));
mReason = problem;
}
public CameraAccessException(@AccessError int problem, String message, Throwable cause) {
- super(message, cause);
+ super(getCombinedMessage(problem, message), cause);
mReason = problem;
}
@@ -151,4 +151,37 @@
}
return null;
}
+
+ private static String getCombinedMessage(@AccessError int problem, String message) {
+ String problemString = getProblemString(problem);
+ return String.format("%s (%d): %s", problemString, problem, message);
+ }
+
+ private static String getProblemString(int problem) {
+ String problemString;
+ switch (problem) {
+ case CAMERA_IN_USE:
+ problemString = "CAMERA_IN_USE";
+ break;
+ case MAX_CAMERAS_IN_USE:
+ problemString = "MAX_CAMERAS_IN_USE";
+ break;
+ case CAMERA_DISCONNECTED:
+ problemString = "CAMERA_DISCONNECTED";
+ break;
+ case CAMERA_DISABLED:
+ problemString = "CAMERA_DISABLED";
+ break;
+ case CAMERA_ERROR:
+ problemString = "CAMERA_ERROR";
+ break;
+ case CAMERA_DEPRECATED_HAL:
+ problemString = "CAMERA_DEPRECATED_HAL";
+ break;
+ default:
+ problemString = "<UNKNOWN ERROR>";
+ }
+ return problemString;
+ }
+
}
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 51796eb..b3c8e3b 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -26,15 +26,14 @@
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.legacy.CameraDeviceUserShim;
import android.hardware.camera2.legacy.LegacyMetadataMapper;
-import android.hardware.camera2.utils.CameraServiceBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.hardware.camera2.utils.BinderHolder;
import android.os.IBinder;
import android.os.Binder;
+import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.ArrayMap;
@@ -240,25 +239,19 @@
if (!supportsCamera2ApiLocked(cameraId)) {
// Legacy backwards compatibility path; build static info from the camera
// parameters
- String[] outParameters = new String[1];
+ String parameters = cameraService.getLegacyParameters(id);
- cameraService.getLegacyParameters(id, /*out*/outParameters);
- String parameters = outParameters[0];
-
- CameraInfo info = new CameraInfo();
- cameraService.getCameraInfo(id, /*out*/info);
+ CameraInfo info = cameraService.getCameraInfo(id);
characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info);
} else {
// Normal path: Get the camera characteristics directly from the camera service
- CameraMetadataNative info = new CameraMetadataNative();
-
- cameraService.getCameraCharacteristics(id, info);
+ CameraMetadataNative info = cameraService.getCameraCharacteristics(id);
characteristics = new CameraCharacteristics(info);
}
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
+ } catch (ServiceSpecificException e) {
+ throwAsPublicException(e);
} catch (RemoteException e) {
// Camera service died - act as if the camera was disconnected
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
@@ -292,85 +285,83 @@
throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
- try {
- synchronized (mLock) {
+ synchronized (mLock) {
- ICameraDeviceUser cameraUser = null;
+ ICameraDeviceUser cameraUser = null;
- android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
- new android.hardware.camera2.impl.CameraDeviceImpl(
- cameraId,
- callback,
- handler,
- characteristics);
+ android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
+ new android.hardware.camera2.impl.CameraDeviceImpl(
+ cameraId,
+ callback,
+ handler,
+ characteristics);
- BinderHolder holder = new BinderHolder();
+ ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
- ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
- int id = Integer.parseInt(cameraId);
- try {
- if (supportsCamera2ApiLocked(cameraId)) {
- // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
- ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
- if (cameraService == null) {
- throw new CameraRuntimeException(
- CameraAccessException.CAMERA_DISCONNECTED,
- "Camera service is currently unavailable");
- }
- cameraService.connectDevice(callbacks, id,
- mContext.getOpPackageName(), USE_CALLING_UID, holder);
- cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
- } else {
- // Use legacy camera implementation for HAL1 devices
- Log.i(TAG, "Using legacy camera HAL.");
- cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
- }
- } catch (CameraRuntimeException e) {
- if (e.getReason() == CameraAccessException.CAMERA_DEPRECATED_HAL) {
- throw new AssertionError("Should've gone down the shim path");
- } else if (e.getReason() == CameraAccessException.CAMERA_IN_USE ||
- e.getReason() == CameraAccessException.MAX_CAMERAS_IN_USE ||
- e.getReason() == CameraAccessException.CAMERA_DISABLED ||
- e.getReason() == CameraAccessException.CAMERA_DISCONNECTED ||
- e.getReason() == CameraAccessException.CAMERA_ERROR) {
- // Received one of the known connection errors
- // The remote camera device cannot be connected to, so
- // set the local camera to the startup error state
- deviceImpl.setRemoteFailure(e);
-
- if (e.getReason() == CameraAccessException.CAMERA_DISABLED ||
- e.getReason() == CameraAccessException.CAMERA_DISCONNECTED ||
- e.getReason() == CameraAccessException.CAMERA_IN_USE) {
- // Per API docs, these failures call onError and throw
- throw e.asChecked();
- }
- } else {
- // Unexpected failure - rethrow
- throw e;
- }
- } catch (RemoteException e) {
- // Camera service died - act as if it's a CAMERA_DISCONNECTED case
- CameraRuntimeException ce = new CameraRuntimeException(
- CameraAccessException.CAMERA_DISCONNECTED,
- "Camera service is currently unavailable", e);
- deviceImpl.setRemoteFailure(ce);
- throw ce.asChecked();
- }
-
- // TODO: factor out callback to be non-nested, then move setter to constructor
- // For now, calling setRemoteDevice will fire initial
- // onOpened/onUnconfigured callbacks.
- deviceImpl.setRemoteDevice(cameraUser);
- device = deviceImpl;
+ int id;
+ try {
+ id = Integer.parseInt(cameraId);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
+ + cameraId);
}
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
- + cameraId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
+ try {
+ if (supportsCamera2ApiLocked(cameraId)) {
+ // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
+ ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
+ if (cameraService == null) {
+ throw new ServiceSpecificException(
+ ICameraService.ERROR_DISCONNECTED,
+ "Camera service is currently unavailable");
+ }
+ cameraUser = cameraService.connectDevice(callbacks, id,
+ mContext.getOpPackageName(), USE_CALLING_UID);
+ } else {
+ // Use legacy camera implementation for HAL1 devices
+ Log.i(TAG, "Using legacy camera HAL.");
+ cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
+ }
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
+ throw new AssertionError("Should've gone down the shim path");
+ } else if (e.errorCode == ICameraService.ERROR_CAMERA_IN_USE ||
+ e.errorCode == ICameraService.ERROR_MAX_CAMERAS_IN_USE ||
+ e.errorCode == ICameraService.ERROR_DISABLED ||
+ e.errorCode == ICameraService.ERROR_DISCONNECTED ||
+ e.errorCode == ICameraService.ERROR_INVALID_OPERATION) {
+ // Received one of the known connection errors
+ // The remote camera device cannot be connected to, so
+ // set the local camera to the startup error state
+ deviceImpl.setRemoteFailure(e);
+
+ if (e.errorCode == ICameraService.ERROR_DISABLED ||
+ e.errorCode == ICameraService.ERROR_DISCONNECTED ||
+ e.errorCode == ICameraService.ERROR_CAMERA_IN_USE) {
+ // Per API docs, these failures call onError and throw
+ throwAsPublicException(e);
+ }
+ } else {
+ // Unexpected failure - rethrow
+ throwAsPublicException(e);
+ }
+ } catch (RemoteException e) {
+ // Camera service died - act as if it's a CAMERA_DISCONNECTED case
+ ServiceSpecificException sse = new ServiceSpecificException(
+ ICameraService.ERROR_DISCONNECTED,
+ "Camera service is currently unavailable");
+ deviceImpl.setRemoteFailure(sse);
+ throwAsPublicException(sse);
+ }
+
+ // TODO: factor out callback to be non-nested, then move setter to constructor
+ // For now, calling setRemoteDevice will fire initial
+ // onOpened/onUnconfigured callbacks.
+ deviceImpl.setRemoteDevice(cameraUser);
+ device = deviceImpl;
}
+
return device;
}
@@ -602,6 +593,56 @@
}
/**
+ * Convert ServiceSpecificExceptions and Binder RemoteExceptions from camera binder interfaces
+ * into the correct public exceptions.
+ *
+ * @hide
+ */
+ public static void throwAsPublicException(Throwable t) throws CameraAccessException {
+ if (t instanceof ServiceSpecificException) {
+ ServiceSpecificException e = (ServiceSpecificException) t;
+ int reason = CameraAccessException.CAMERA_ERROR;
+ switch(e.errorCode) {
+ case ICameraService.ERROR_DISCONNECTED:
+ reason = CameraAccessException.CAMERA_DISCONNECTED;
+ break;
+ case ICameraService.ERROR_DISABLED:
+ reason = CameraAccessException.CAMERA_DISABLED;
+ break;
+ case ICameraService.ERROR_CAMERA_IN_USE:
+ reason = CameraAccessException.CAMERA_IN_USE;
+ break;
+ case ICameraService.ERROR_MAX_CAMERAS_IN_USE:
+ reason = CameraAccessException.MAX_CAMERAS_IN_USE;
+ break;
+ case ICameraService.ERROR_DEPRECATED_HAL:
+ reason = CameraAccessException.CAMERA_DEPRECATED_HAL;
+ break;
+ case ICameraService.ERROR_ILLEGAL_ARGUMENT:
+ case ICameraService.ERROR_ALREADY_EXISTS:
+ throw new IllegalArgumentException(e.getMessage(), e);
+ case ICameraService.ERROR_PERMISSION_DENIED:
+ throw new SecurityException(e.getMessage(), e);
+ case ICameraService.ERROR_TIMED_OUT:
+ case ICameraService.ERROR_INVALID_OPERATION:
+ default:
+ reason = CameraAccessException.CAMERA_ERROR;
+ }
+ throw new CameraAccessException(reason, e.getMessage(), e);
+ } else if (t instanceof DeadObjectException) {
+ throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
+ "Camera service has died unexpectedly",
+ t);
+ } else if (t instanceof RemoteException) {
+ throw new UnsupportedOperationException("An unknown RemoteException was thrown" +
+ " which should never happen.", t);
+ } else if (t instanceof RuntimeException) {
+ RuntimeException e = (RuntimeException) t;
+ throw e;
+ }
+ }
+
+ /**
* Return or create the list of currently connected camera devices.
*
* <p>In case of errors connecting to the camera service, will return an empty list.</p>
@@ -619,34 +660,32 @@
try {
numCameras = cameraService.getNumberOfCameras(CAMERA_TYPE_ALL);
- } catch(CameraRuntimeException e) {
- throw e.asChecked();
+ } catch(ServiceSpecificException e) {
+ throwAsPublicException(e);
} catch (RemoteException e) {
// camera service just died - if no camera service, then no devices
return deviceIdList;
}
- CameraMetadataNative info = new CameraMetadataNative();
for (int i = 0; i < numCameras; ++i) {
// Non-removable cameras use integers starting at 0 for their
// identifiers
boolean isDeviceSupported = false;
try {
- cameraService.getCameraCharacteristics(i, info);
+ CameraMetadataNative info = cameraService.getCameraCharacteristics(i);
if (!info.isEmpty()) {
isDeviceSupported = true;
} else {
throw new AssertionError("Expected to get non-empty characteristics");
}
- } catch(IllegalArgumentException e) {
- // Got a BAD_VALUE from service, meaning that this
- // device is not supported.
- } catch(CameraRuntimeException e) {
+ } catch(ServiceSpecificException e) {
// DISCONNECTED means that the HAL reported an low-level error getting the
- // device info; skip listing the device. Other errors,
+ // device info; ILLEGAL_ARGUMENT means that this devices is not supported.
+ // Skip listing the device. Other errors,
// propagate exception onward
- if (e.getReason() != CameraAccessException.CAMERA_DISCONNECTED) {
- throw e.asChecked();
+ if (e.errorCode != ICameraService.ERROR_DISCONNECTED ||
+ e.errorCode != ICameraService.ERROR_ILLEGAL_ARGUMENT) {
+ throwAsPublicException(e);
}
} catch(RemoteException e) {
// Camera service died - no devices to list
@@ -699,17 +738,7 @@
// If no camera service, no support
if (cameraService == null) return false;
- int res = cameraService.supportsCameraApi(id, apiVersion);
-
- if (res != CameraServiceBinderDecorator.NO_ERROR) {
- throw new AssertionError("Unexpected value " + res);
- }
- return true;
- } catch (CameraRuntimeException e) {
- if (e.getReason() != CameraAccessException.CAMERA_DEPRECATED_HAL) {
- throw e;
- }
- // API level is not supported
+ return cameraService.supportsCameraApi(id, apiVersion);
} catch (RemoteException e) {
// Camera service is now down, no support for any API level
}
@@ -737,21 +766,6 @@
*/
private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
- // Keep up-to-date with ICameraServiceListener.h
-
- // Device physically unplugged
- public static final int STATUS_NOT_PRESENT = 0;
- // Device physically has been plugged in
- // and the camera can be used exclusively
- public static final int STATUS_PRESENT = 1;
- // Device physically has been plugged in
- // but it will not be connect-able until enumeration is complete
- public static final int STATUS_ENUMERATING = 2;
- // Camera is in use by another app and cannot be used exclusively
- public static final int STATUS_NOT_AVAILABLE = 0x80000000;
-
- // End enums shared with ICameraServiceListener.h
-
// Camera ID -> Status map
private final ArrayMap<String, Integer> mDeviceStatus = new ArrayMap<String, Integer>();
@@ -759,17 +773,6 @@
private final ArrayMap<AvailabilityCallback, Handler> mCallbackMap =
new ArrayMap<AvailabilityCallback, Handler>();
- // Keep up-to-date with ICameraServiceListener.h
-
- // torch mode has become not available to set via setTorchMode().
- public static final int TORCH_STATUS_NOT_AVAILABLE = 0;
- // torch mode is off and available to be turned on via setTorchMode().
- public static final int TORCH_STATUS_AVAILABLE_OFF = 1;
- // torch mode is on and available to be turned off via setTorchMode().
- public static final int TORCH_STATUS_AVAILABLE_ON = 2;
-
- // End enums shared with ICameraServiceListener.h
-
// torch client binder to set the torch mode with.
private Binder mTorchClientBinder = new Binder();
@@ -839,29 +842,20 @@
return;
}
- ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
-
- /**
- * Wrap the camera service in a decorator which automatically translates return codes
- * into exceptions.
- */
- ICameraService cameraService =
- CameraServiceBinderDecorator.newInstance(cameraServiceRaw);
+ ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
try {
- CameraServiceBinderDecorator.throwOnError(
- CameraMetadataNative.nativeSetupGlobalVendorTagDescriptor());
- } catch (CameraRuntimeException e) {
- handleRecoverableSetupErrors(e, "Failed to set up vendor tags");
+ CameraMetadataNative.setupGlobalVendorTagDescriptor();
+ } catch (ServiceSpecificException e) {
+ handleRecoverableSetupErrors(e);
}
try {
cameraService.addListener(this);
mCameraService = cameraService;
- } catch(CameraRuntimeException e) {
+ } catch(ServiceSpecificException e) {
// Unexpected failure
- throw new IllegalStateException("Failed to register a camera service listener",
- e.asChecked());
+ throw new IllegalStateException("Failed to register a camera service listener", e);
} catch (RemoteException e) {
// Camera service is now down, leave mCameraService as null
}
@@ -881,16 +875,9 @@
}
try {
- int status = cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder);
- } catch(CameraRuntimeException e) {
- int problem = e.getReason();
- switch (problem) {
- case CameraAccessException.CAMERA_ERROR:
- throw new IllegalArgumentException(
- "the camera device doesn't have a flash unit.");
- default:
- throw e.asChecked();
- }
+ cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder);
+ } catch(ServiceSpecificException e) {
+ throwAsPublicException(e);
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable");
@@ -898,21 +885,19 @@
}
}
- private void handleRecoverableSetupErrors(CameraRuntimeException e, String msg) {
- int problem = e.getReason();
- switch (problem) {
- case CameraAccessException.CAMERA_DISCONNECTED:
- String errorMsg = CameraAccessException.getDefaultMessage(problem);
- Log.w(TAG, msg + ": " + errorMsg);
+ private void handleRecoverableSetupErrors(ServiceSpecificException e) {
+ switch (e.errorCode) {
+ case ICameraService.ERROR_DISCONNECTED:
+ Log.w(TAG, e.getMessage());
break;
default:
- throw new IllegalStateException(msg, e.asChecked());
+ throw new IllegalStateException(e);
}
}
private boolean isAvailable(int status) {
switch (status) {
- case STATUS_PRESENT:
+ case ICameraServiceListener.STATUS_PRESENT:
return true;
default:
return false;
@@ -921,10 +906,10 @@
private boolean validStatus(int status) {
switch (status) {
- case STATUS_NOT_PRESENT:
- case STATUS_PRESENT:
- case STATUS_ENUMERATING:
- case STATUS_NOT_AVAILABLE:
+ case ICameraServiceListener.STATUS_NOT_PRESENT:
+ case ICameraServiceListener.STATUS_PRESENT:
+ case ICameraServiceListener.STATUS_ENUMERATING:
+ case ICameraServiceListener.STATUS_NOT_AVAILABLE:
return true;
default:
return false;
@@ -933,9 +918,9 @@
private boolean validTorchStatus(int status) {
switch (status) {
- case TORCH_STATUS_NOT_AVAILABLE:
- case TORCH_STATUS_AVAILABLE_ON:
- case TORCH_STATUS_AVAILABLE_OFF:
+ case ICameraServiceListener.TORCH_STATUS_NOT_AVAILABLE:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_ON:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_OFF:
return true;
default:
return false;
@@ -966,14 +951,14 @@
private void postSingleTorchUpdate(final TorchCallback callback, final Handler handler,
final String id, final int status) {
switch(status) {
- case TORCH_STATUS_AVAILABLE_ON:
- case TORCH_STATUS_AVAILABLE_OFF:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_ON:
+ case ICameraServiceListener.TORCH_STATUS_AVAILABLE_OFF:
handler.post(
new Runnable() {
@Override
public void run() {
callback.onTorchModeChanged(id, status ==
- TORCH_STATUS_AVAILABLE_ON);
+ ICameraServiceListener.TORCH_STATUS_AVAILABLE_ON);
}
});
break;
@@ -1220,11 +1205,12 @@
// and torch statuses will be updated.
for (int i = 0; i < mDeviceStatus.size(); i++) {
String cameraId = mDeviceStatus.keyAt(i);
- onStatusChangedLocked(STATUS_NOT_PRESENT, cameraId);
+ onStatusChangedLocked(ICameraServiceListener.STATUS_NOT_PRESENT, cameraId);
}
for (int i = 0; i < mTorchStatus.size(); i++) {
String cameraId = mTorchStatus.keyAt(i);
- onTorchStatusChangedLocked(TORCH_STATUS_NOT_AVAILABLE, cameraId);
+ onTorchStatusChangedLocked(ICameraServiceListener.TORCH_STATUS_NOT_AVAILABLE,
+ cameraId);
}
scheduleCameraServiceReconnectionLocked();
diff --git a/core/java/android/hardware/camera2/CaptureRequest.aidl b/core/java/android/hardware/camera2/CaptureRequest.aidl
deleted file mode 100644
index 0b7d5ba..0000000
--- a/core/java/android/hardware/camera2/CaptureRequest.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2;
-
-/** @hide */
-parcelable CaptureRequest;
diff --git a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
deleted file mode 100644
index 151c918..0000000
--- a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2;
-
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.impl.CaptureResultExtras;
-
-/** @hide */
-interface ICameraDeviceCallbacks
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h
- */
-
- oneway void onDeviceError(int errorCode, in CaptureResultExtras resultExtras);
- oneway void onDeviceIdle();
- oneway void onCaptureStarted(in CaptureResultExtras resultExtras, long timestamp);
- oneway void onResultReceived(in CameraMetadataNative result,
- in CaptureResultExtras resultExtras);
- oneway void onPrepared(int streamId);
-}
diff --git a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
deleted file mode 100644
index c9c9abc..0000000
--- a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2;
-
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.utils.LongParcelable;
-import android.view.Surface;
-
-/** @hide */
-interface ICameraDeviceUser
-{
- /**
- * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceUser.h and
- * frameworks/base/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
- */
- void disconnect();
-
- // ints here are status_t
-
- // non-negative value is the requestId. negative value is status_t
- int submitRequest(in CaptureRequest request, boolean streaming,
- out LongParcelable lastFrameNumber);
-
- int submitRequestList(in List<CaptureRequest> requestList, boolean streaming,
- out LongParcelable lastFrameNumber);
-
- int cancelRequest(int requestId, out LongParcelable lastFrameNumber);
-
- /**
- * Begin the device configuration.
- *
- * <p>
- * beginConfigure must be called before any call to deleteStream, createStream,
- * or endConfigure. It is not valid to call this when the device is not idle.
- * <p>
- */
- int beginConfigure();
-
- /**
- * End the device configuration.
- *
- * <p>
- * endConfigure must be called after stream configuration is complete (i.e. after
- * a call to beginConfigure and subsequent createStream/deleteStream calls). This
- * must be called before any requests can be submitted.
- * <p>
- */
- int endConfigure(boolean isConstrainedHighSpeed);
-
- int deleteStream(int streamId);
-
- // non-negative value is the stream ID. negative value is status_t
- int createStream(in OutputConfiguration outputConfiguration);
-
- /**
- * Create an input stream
- *
- * <p>Create an input stream of width, height, and format</p>
- *
- * @param width Width of the input buffers
- * @param height Height of the input buffers
- * @param format Format of the input buffers. One of HAL_PIXEL_FORMAT_*.
- *
- * @return stream ID if it's a non-negative value. status_t if it's a negative value.
- */
- int createInputStream(int width, int height, int format);
-
- /**
- * Get the surface of the input stream.
- *
- * <p>It's valid to call this method only after a stream configuration is completed
- * successfully and the stream configuration includes a input stream.</p>
- *
- * @param surface An output argument for the surface of the input stream buffer queue.
- */
- int getInputSurface(out Surface surface);
-
- int createDefaultRequest(int templateId, out CameraMetadataNative request);
-
- int getCameraInfo(out CameraMetadataNative info);
-
- int waitUntilIdle();
-
- int flush(out LongParcelable lastFrameNumber);
-
- int prepare(int streamId);
-
- int tearDown(int streamId);
-
- int prepare2(int maxCount, int streamId);
-}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 3aba0d1..00dd780 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -33,14 +33,14 @@
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.ReprocessFormatsMap;
import android.hardware.camera2.params.StreamConfigurationMap;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.hardware.camera2.utils.SurfaceUtils;
+import android.hardware.ICameraService;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Range;
import android.util.Size;
@@ -70,7 +70,7 @@
private static final int REQUEST_ID_NONE = -1;
// TODO: guard every function with if (!mRemoteDevice) check (if it was closed)
- private ICameraDeviceUser mRemoteDevice;
+ private ICameraDeviceUserWrapper mRemoteDevice;
// Lock to synchronize cross-thread access to device public interface
final Object mInterfaceLock = new Object(); // access from this class and Session only!
@@ -267,7 +267,7 @@
// If setRemoteFailure already called, do nothing
if (mInError) return;
- mRemoteDevice = CameraBinderDecorator.newInstance(remoteDevice);
+ mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
mDeviceHandler.post(mCallOnOpened);
mDeviceHandler.post(mCallOnUnconfigured);
@@ -280,28 +280,29 @@
* <p>This places the camera device in the error state and informs the callback.
* Use in place of setRemoteDevice() when startup fails.</p>
*/
- public void setRemoteFailure(final CameraRuntimeException failure) {
+ public void setRemoteFailure(final ServiceSpecificException failure) {
int failureCode = StateCallback.ERROR_CAMERA_DEVICE;
boolean failureIsError = true;
- switch (failure.getReason()) {
- case CameraAccessException.CAMERA_IN_USE:
+ switch (failure.errorCode) {
+ case ICameraService.ERROR_CAMERA_IN_USE:
failureCode = StateCallback.ERROR_CAMERA_IN_USE;
break;
- case CameraAccessException.MAX_CAMERAS_IN_USE:
+ case ICameraService.ERROR_MAX_CAMERAS_IN_USE:
failureCode = StateCallback.ERROR_MAX_CAMERAS_IN_USE;
break;
- case CameraAccessException.CAMERA_DISABLED:
+ case ICameraService.ERROR_DISABLED:
failureCode = StateCallback.ERROR_CAMERA_DISABLED;
break;
- case CameraAccessException.CAMERA_DISCONNECTED:
+ case ICameraService.ERROR_DISCONNECTED:
failureIsError = false;
break;
- case CameraAccessException.CAMERA_ERROR:
+ case ICameraService.ERROR_INVALID_OPERATION:
failureCode = StateCallback.ERROR_CAMERA_DEVICE;
break;
default:
- Log.wtf(TAG, "Unknown failure in opening camera device: " + failure.getReason());
+ Log.e(TAG, "Unexpected failure in opening camera device: " + failure.errorCode +
+ failure.getMessage());
break;
}
final int code = failureCode;
@@ -430,27 +431,20 @@
}
}
- try {
- mRemoteDevice.endConfigure(isConstrainedHighSpeed);
- }
- catch (IllegalArgumentException e) {
- // OK. camera service can reject stream config if it's not supported by HAL
- // This is only the result of a programmer misusing the camera2 api.
- Log.w(TAG, "Stream configuration failed");
- return false;
- }
+ mRemoteDevice.endConfigure(isConstrainedHighSpeed);
success = true;
- } catch (CameraRuntimeException e) {
- if (e.getReason() == CAMERA_IN_USE) {
- throw new IllegalStateException("The camera is currently busy." +
- " You must wait until the previous operation completes.");
- }
-
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
+ } catch (IllegalArgumentException e) {
+ // OK. camera service can reject stream config if it's not supported by HAL
+ // This is only the result of a programmer misusing the camera2 api.
+ Log.w(TAG, "Stream configuration failed due to: " + e.getMessage());
return false;
+ } catch (CameraAccessException e) {
+ if (e.getReason() == CameraAccessException.CAMERA_IN_USE) {
+ throw new IllegalStateException("The camera is currently busy." +
+ " You must wait until the previous operation completes.", e);
+ }
+ throw e;
} finally {
if (success && outputs.size() > 0) {
mDeviceHandler.post(mCallOnIdle);
@@ -594,12 +588,7 @@
configureSuccess = configureStreamsChecked(inputConfig, outputConfigurations,
isConstrainedHighSpeed);
if (configureSuccess == true && inputConfig != null) {
- input = new Surface();
- try {
- mRemoteDevice.getInputSurface(/*out*/input);
- } catch (CameraRuntimeException e) {
- e.asChecked();
- }
+ input = mRemoteDevice.getInputSurface();
}
} catch (CameraAccessException e) {
configureSuccess = false;
@@ -608,9 +597,6 @@
if (DEBUG) {
Log.v(TAG, "createCaptureSession - failed with exception ", e);
}
- } catch (RemoteException e) {
- // impossible
- return;
}
List<Surface> outSurfaces = new ArrayList<>(outputConfigurations.size());
@@ -655,16 +641,9 @@
synchronized(mInterfaceLock) {
checkIfCameraClosedOrInError();
- CameraMetadataNative templatedRequest = new CameraMetadataNative();
+ CameraMetadataNative templatedRequest = null;
- try {
- mRemoteDevice.createDefaultRequest(templateType, /*out*/templatedRequest);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return null;
- }
+ templatedRequest = mRemoteDevice.createDefaultRequest(templateType);
CaptureRequest.Builder builder = new CaptureRequest.Builder(
templatedRequest, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
@@ -701,14 +680,8 @@
if (streamId == -1) {
throw new IllegalArgumentException("Surface is not part of this session");
}
- try {
- mRemoteDevice.prepare(streamId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.prepare(streamId);
}
}
@@ -728,14 +701,8 @@
if (streamId == -1) {
throw new IllegalArgumentException("Surface is not part of this session");
}
- try {
- mRemoteDevice.prepare2(maxCount, streamId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.prepare2(maxCount, streamId);
}
}
@@ -753,14 +720,8 @@
if (streamId == -1) {
throw new IllegalArgumentException("Surface is not part of this session");
}
- try {
- mRemoteDevice.tearDown(streamId);
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.tearDown(streamId);
}
}
@@ -875,45 +836,37 @@
synchronized(mInterfaceLock) {
checkIfCameraClosedOrInError();
- int requestId;
-
if (repeating) {
stopRepeating();
}
- LongParcelable lastFrameNumberRef = new LongParcelable();
- try {
- requestId = mRemoteDevice.submitRequestList(requestList, repeating,
- /*out*/lastFrameNumberRef);
- if (DEBUG) {
- Log.v(TAG, "last frame number " + lastFrameNumberRef.getNumber());
- }
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return -1;
+ SubmitInfo requestInfo;
+
+ CaptureRequest[] requestArray = requestList.toArray(new CaptureRequest[requestList.size()]);
+ requestInfo = mRemoteDevice.submitRequestList(requestArray, repeating);
+ if (DEBUG) {
+ Log.v(TAG, "last frame number " + requestInfo.getLastFrameNumber());
}
if (callback != null) {
- mCaptureCallbackMap.put(requestId, new CaptureCallbackHolder(callback,
- requestList, handler, repeating, mNextSessionId - 1));
+ mCaptureCallbackMap.put(requestInfo.getRequestId(),
+ new CaptureCallbackHolder(
+ callback, requestList, handler, repeating, mNextSessionId - 1));
} else {
if (DEBUG) {
- Log.d(TAG, "Listen for request " + requestId + " is null");
+ Log.d(TAG, "Listen for request " + requestInfo.getRequestId() + " is null");
}
}
- long lastFrameNumber = lastFrameNumberRef.getNumber();
-
if (repeating) {
if (mRepeatingRequestId != REQUEST_ID_NONE) {
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber);
+ checkEarlyTriggerSequenceComplete(mRepeatingRequestId,
+ requestInfo.getLastFrameNumber());
}
- mRepeatingRequestId = requestId;
+ mRepeatingRequestId = requestInfo.getRequestId();
} else {
- mRequestLastFrameNumbersList.add(new RequestLastFrameNumbersHolder(requestList,
- requestId, lastFrameNumber));
+ mRequestLastFrameNumbersList.add(
+ new RequestLastFrameNumbersHolder(requestList, requestInfo));
}
if (mIdle) {
@@ -921,7 +874,7 @@
}
mIdle = false;
- return requestId;
+ return requestInfo.getRequestId();
}
}
@@ -949,19 +902,9 @@
int requestId = mRepeatingRequestId;
mRepeatingRequestId = REQUEST_ID_NONE;
- try {
- LongParcelable lastFrameNumberRef = new LongParcelable();
- mRemoteDevice.cancelRequest(requestId, /*out*/lastFrameNumberRef);
- long lastFrameNumber = lastFrameNumberRef.getNumber();
+ long lastFrameNumber = mRemoteDevice.cancelRequest(requestId);
- checkEarlyTriggerSequenceComplete(requestId, lastFrameNumber);
-
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+ checkEarlyTriggerSequenceComplete(requestId, lastFrameNumber);
}
}
}
@@ -974,14 +917,8 @@
if (mRepeatingRequestId != REQUEST_ID_NONE) {
throw new IllegalStateException("Active repeating request ongoing");
}
- try {
- mRemoteDevice.waitUntilIdle();
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
- }
+
+ mRemoteDevice.waitUntilIdle();
}
}
@@ -997,19 +934,11 @@
mDeviceHandler.post(mCallOnIdle);
return;
}
- try {
- LongParcelable lastFrameNumberRef = new LongParcelable();
- mRemoteDevice.flush(/*out*/lastFrameNumberRef);
- if (mRepeatingRequestId != REQUEST_ID_NONE) {
- long lastFrameNumber = lastFrameNumberRef.getNumber();
- checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber);
- mRepeatingRequestId = REQUEST_ID_NONE;
- }
- } catch (CameraRuntimeException e) {
- throw e.asChecked();
- } catch (RemoteException e) {
- // impossible
- return;
+
+ long lastFrameNumber = mRemoteDevice.flush();
+ if (mRepeatingRequestId != REQUEST_ID_NONE) {
+ checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber);
+ mRepeatingRequestId = REQUEST_ID_NONE;
}
}
}
@@ -1021,14 +950,8 @@
return;
}
- try {
- if (mRemoteDevice != null) {
- mRemoteDevice.disconnect();
- }
- } catch (CameraRuntimeException e) {
- Log.e(TAG, "Exception while closing: ", e.asChecked());
- } catch (RemoteException e) {
- // impossible
+ if (mRemoteDevice != null) {
+ mRemoteDevice.disconnect();
}
// Only want to fire the onClosed callback once;
@@ -1297,14 +1220,14 @@
* Create a request-last-frame-numbers holder with a list of requests, request ID, and
* the last frame number returned by camera service.
*/
- public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, int requestId,
- long lastFrameNumber) {
+ public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, SubmitInfo requestInfo) {
long lastRegularFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
long lastReprocessFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
- long frameNumber = lastFrameNumber;
+ long frameNumber = requestInfo.getLastFrameNumber();
- if (lastFrameNumber < requestList.size() - 1) {
- throw new IllegalArgumentException("lastFrameNumber: " + lastFrameNumber +
+ if (requestInfo.getLastFrameNumber() < requestList.size() - 1) {
+ throw new IllegalArgumentException(
+ "lastFrameNumber: " + requestInfo.getLastFrameNumber() +
" should be at least " + (requestList.size() - 1) + " for the number of " +
" requests in the list: " + requestList.size());
}
@@ -1330,7 +1253,7 @@
mLastRegularFrameNumber = lastRegularFrameNumber;
mLastReprocessFrameNumber = lastReprocessFrameNumber;
- mRequestId = requestId;
+ mRequestId = requestInfo.getRequestId();
}
/**
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl b/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl
deleted file mode 100644
index 4a89129..0000000
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.impl;
-
-/** @hide */
-parcelable CameraMetadataNative;
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 12a2910..79eac26 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -58,6 +58,7 @@
import android.location.LocationManager;
import android.os.Parcelable;
import android.os.Parcel;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Size;
@@ -363,13 +364,24 @@
* Set the global client-side vendor tag descriptor to allow use of vendor
* tags in camera applications.
*
- * @return int A native status_t value corresponding to one of the
- * {@link CameraBinderDecorator} integer constants.
- * @see CameraBinderDecorator#throwOnError
- *
+ * @throws ServiceSpecificException
* @hide
*/
- public static native int nativeSetupGlobalVendorTagDescriptor();
+ public static void setupGlobalVendorTagDescriptor() throws ServiceSpecificException {
+ int err = nativeSetupGlobalVendorTagDescriptor();
+ if (err != 0) {
+ throw new ServiceSpecificException(err, "Failure to set up global vendor tags");
+ }
+ }
+
+ /**
+ * Set the global client-side vendor tag descriptor to allow use of vendor
+ * tags in camera applications.
+ *
+ * @return int An error code corresponding to one of the
+ * {@link ICameraService} error constants, or 0 on success.
+ */
+ private static native int nativeSetupGlobalVendorTagDescriptor();
/**
* Set a camera metadata field to a value. The field definitions can be
diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl b/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl
deleted file mode 100644
index ebc812a..0000000
--- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.impl;
-
-/** @hide */
-parcelable CaptureResultExtras;
diff --git a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
new file mode 100644
index 0000000..ddc3fd1
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera2.impl;
+
+import static android.hardware.camera2.CameraAccessException.CAMERA_DISABLED;
+import static android.hardware.camera2.CameraAccessException.CAMERA_DISCONNECTED;
+import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
+import static android.hardware.camera2.CameraAccessException.CAMERA_ERROR;
+import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
+import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
+
+import android.hardware.ICameraService;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.ICameraDeviceUser;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.params.OutputConfiguration;
+import android.hardware.camera2.utils.SubmitInfo;
+import android.os.RemoteException;
+import android.view.Surface;
+
+/**
+ * A wrapper around ICameraDeviceUser.
+ *
+ * Mainly used to convert ServiceSpecificExceptions to the correct
+ * checked / unchecked exception.
+ *
+ * @hide
+ */
+public class ICameraDeviceUserWrapper {
+
+ private final ICameraDeviceUser mRemoteDevice;
+
+ public ICameraDeviceUserWrapper(ICameraDeviceUser remoteDevice) {
+ if (remoteDevice == null) {
+ throw new NullPointerException("Remote device may not be null");
+ }
+ mRemoteDevice = remoteDevice;
+ }
+
+ public void disconnect() {
+ try {
+ mRemoteDevice.disconnect();
+ } catch (RemoteException t) {
+ // ignore binder errors for disconnect
+ }
+ }
+
+ public SubmitInfo submitRequest(CaptureRequest request, boolean streaming)
+ throws CameraAccessException {
+ try {
+ return mRemoteDevice.submitRequest(request, streaming);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public SubmitInfo submitRequestList(CaptureRequest[] requestList, boolean streaming)
+ throws CameraAccessException {
+ try {
+ return mRemoteDevice.submitRequestList(requestList, streaming);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public long cancelRequest(int requestId) throws CameraAccessException {
+ try {
+ return mRemoteDevice.cancelRequest(requestId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void beginConfigure() throws CameraAccessException {
+ try {
+ mRemoteDevice.beginConfigure();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void endConfigure(boolean isConstrainedHighSpeed) throws CameraAccessException {
+ try {
+ mRemoteDevice.endConfigure(isConstrainedHighSpeed);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void deleteStream(int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.deleteStream(streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public int createStream(OutputConfiguration outputConfiguration)
+ throws CameraAccessException {
+ try {
+ return mRemoteDevice.createStream(outputConfiguration);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public int createInputStream(int width, int height, int format) throws CameraAccessException {
+ try {
+ return mRemoteDevice.createInputStream(width, height, format);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public Surface getInputSurface() throws CameraAccessException {
+ try {
+ return mRemoteDevice.getInputSurface();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public CameraMetadataNative createDefaultRequest(int templateId) throws CameraAccessException {
+ try {
+ return mRemoteDevice.createDefaultRequest(templateId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public CameraMetadataNative getCameraInfo() throws CameraAccessException {
+ try {
+ return mRemoteDevice.getCameraInfo();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void waitUntilIdle() throws CameraAccessException {
+ try {
+ mRemoteDevice.waitUntilIdle();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public long flush() throws CameraAccessException {
+ try {
+ return mRemoteDevice.flush();
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void prepare(int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.prepare(streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void tearDown(int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.tearDown(streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+ public void prepare2(int maxCount, int streamId) throws CameraAccessException {
+ try {
+ mRemoteDevice.prepare2(maxCount, streamId);
+ } catch (Throwable t) {
+ CameraManager.throwAsPublicException(t);
+ throw new UnsupportedOperationException("Unexpected exception", t);
+ }
+ }
+
+
+}
diff --git a/core/java/android/hardware/camera2/legacy/BurstHolder.java b/core/java/android/hardware/camera2/legacy/BurstHolder.java
index e7b3682..23efe15 100644
--- a/core/java/android/hardware/camera2/legacy/BurstHolder.java
+++ b/core/java/android/hardware/camera2/legacy/BurstHolder.java
@@ -35,10 +35,10 @@
*
* @param requestId id of the burst request.
* @param repeating true if this burst is repeating.
- * @param requests a {@link List} of {@link CaptureRequest}s in this burst.
+ * @param requests the array of {@link CaptureRequest}s for this burst.
* @param jpegSurfaceIds a {@link Collection} of IDs for the surfaces that have jpeg outputs.
*/
- public BurstHolder(int requestId, boolean repeating, List<CaptureRequest> requests,
+ public BurstHolder(int requestId, boolean repeating, CaptureRequest[] requests,
Collection<Long> jpegSurfaceIds) {
mRequestBuilders = new ArrayList<>();
int i = 0;
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 798c941..d01c275 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -16,6 +16,7 @@
package android.hardware.camera2.legacy;
+import android.hardware.ICameraService;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.camera2.CameraAccessException;
@@ -23,12 +24,10 @@
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
-import android.hardware.camera2.utils.LongParcelable;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
+import android.hardware.camera2.utils.SubmitInfo;
import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.Looper;
@@ -36,6 +35,7 @@
import android.os.HandlerThread;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.SparseArray;
import android.view.Surface;
@@ -93,7 +93,7 @@
private static int translateErrorsFromCamera1(int errorCode) {
if (errorCode == -EACCES) {
- return CameraBinderDecorator.PERMISSION_DENIED;
+ return ICameraService.ERROR_PERMISSION_DENIED;
}
return errorCode;
@@ -173,7 +173,7 @@
*
* @return int error code
*
- * @throws CameraRuntimeException if the camera open times out with ({@code CAMERA_ERROR})
+ * @throws ServiceSpecificException if the camera open times out with ({@code CAMERA_ERROR})
*/
public int waitForOpen(int timeoutMs) {
// Block until the camera is open asynchronously
@@ -186,7 +186,7 @@
Log.e(TAG, "connectBinderShim - Failed to release camera after timeout ", e);
}
- throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION);
}
return mInitErrors;
@@ -344,7 +344,7 @@
Camera legacyCamera = init.getCamera();
// Check errors old HAL initialization
- CameraBinderDecorator.throwOnError(initErrors);
+ LegacyExceptionUtils.throwOnServiceError(initErrors);
// Disable shutter sounds (this will work unconditionally) for api2 clients
legacyCamera.disableShutterSound();
@@ -356,8 +356,8 @@
try {
legacyParameters = legacyCamera.getParameters();
} catch (RuntimeException e) {
- throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR,
- "Unable to get initial parameters", e);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION,
+ "Unable to get initial parameters: " + e.getMessage());
}
CameraCharacteristics characteristics =
@@ -386,101 +386,106 @@
}
@Override
- public int submitRequest(CaptureRequest request, boolean streaming,
- /*out*/LongParcelable lastFrameNumber) {
+ public SubmitInfo submitRequest(CaptureRequest request, boolean streaming) {
if (DEBUG) {
Log.d(TAG, "submitRequest called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot submit request, device has been closed.");
- return -ENODEV;
+ String err = "Cannot submit request, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot submit request, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot submit request, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- return mLegacyDevice.submitRequest(request, streaming, lastFrameNumber);
+ return mLegacyDevice.submitRequest(request, streaming);
}
@Override
- public int submitRequestList(List<CaptureRequest> request, boolean streaming,
- /*out*/LongParcelable lastFrameNumber) {
+ public SubmitInfo submitRequestList(CaptureRequest[] request, boolean streaming) {
if (DEBUG) {
Log.d(TAG, "submitRequestList called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot submit request list, device has been closed.");
- return -ENODEV;
+ String err = "Cannot submit request list, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot submit request, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot submit request, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- return mLegacyDevice.submitRequestList(request, streaming, lastFrameNumber);
+ return mLegacyDevice.submitRequestList(request, streaming);
}
@Override
- public int cancelRequest(int requestId, /*out*/LongParcelable lastFrameNumber) {
+ public long cancelRequest(int requestId) {
if (DEBUG) {
Log.d(TAG, "cancelRequest called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot cancel request, device has been closed.");
- return -ENODEV;
+ String err = "Cannot cancel request, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot cancel request, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot cancel request, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- long lastFrame = mLegacyDevice.cancelRequest(requestId);
- lastFrameNumber.setNumber(lastFrame);
- return CameraBinderDecorator.NO_ERROR;
+ return mLegacyDevice.cancelRequest(requestId);
}
@Override
- public int beginConfigure() {
+ public void beginConfigure() {
if (DEBUG) {
Log.d(TAG, "beginConfigure called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot begin configure, device has been closed.");
- return -ENODEV;
+ String err = "Cannot begin configure, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot begin configure, configuration change already in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot begin configure, configuration change already in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
mConfiguring = true;
}
- return CameraBinderDecorator.NO_ERROR;
}
@Override
- public int endConfigure(boolean isConstrainedHighSpeed) {
+ public void endConfigure(boolean isConstrainedHighSpeed) {
if (DEBUG) {
Log.d(TAG, "endConfigure called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot end configure, device has been closed.");
- return -ENODEV;
+ String err = "Cannot end configure, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
ArrayList<Surface> surfaces = null;
synchronized(mConfigureLock) {
if (!mConfiguring) {
- Log.e(TAG, "Cannot end configure, no configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot end configure, no configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
int numSurfaces = mSurfaces.size();
if (numSurfaces > 0) {
@@ -491,32 +496,34 @@
}
mConfiguring = false;
}
- return mLegacyDevice.configureOutputs(surfaces);
+ mLegacyDevice.configureOutputs(surfaces);
}
@Override
- public int deleteStream(int streamId) {
+ public void deleteStream(int streamId) {
if (DEBUG) {
Log.d(TAG, "deleteStream called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot delete stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot delete stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (!mConfiguring) {
- Log.e(TAG, "Cannot delete stream, beginConfigure hasn't been called yet.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot delete stream, no configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
int index = mSurfaces.indexOfKey(streamId);
if (index < 0) {
- Log.e(TAG, "Cannot delete stream, stream id " + streamId + " doesn't exist.");
- return CameraBinderDecorator.BAD_VALUE;
+ String err = "Cannot delete stream, stream id " + streamId + " doesn't exist.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
}
mSurfaces.removeAt(index);
}
- return CameraBinderDecorator.NO_ERROR;
}
@Override
@@ -525,18 +532,21 @@
Log.d(TAG, "createStream called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot create stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot create stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (!mConfiguring) {
- Log.e(TAG, "Cannot create stream, beginConfigure hasn't been called yet.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot create stream, beginConfigure hasn't been called yet.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
if (outputConfiguration.getRotation() != OutputConfiguration.ROTATION_0) {
- Log.e(TAG, "Cannot create stream, stream rotation is not supported.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot create stream, stream rotation is not supported.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
}
int id = ++mSurfaceIdCounter;
mSurfaces.put(id, outputConfiguration.getSurface());
@@ -546,24 +556,27 @@
@Override
public int createInputStream(int width, int height, int format) {
- Log.e(TAG, "creating input stream is not supported on legacy devices");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Creating input stream is not supported on legacy devices";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
@Override
- public int getInputSurface(/*out*/ Surface surface) {
- Log.e(TAG, "getting input surface is not supported on legacy devices");
- return CameraBinderDecorator.INVALID_OPERATION;
+ public Surface getInputSurface() {
+ String err = "Getting input surface is not supported on legacy devices";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
@Override
- public int createDefaultRequest(int templateId, /*out*/CameraMetadataNative request) {
+ public CameraMetadataNative createDefaultRequest(int templateId) {
if (DEBUG) {
Log.d(TAG, "createDefaultRequest called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot create default request, device has been closed.");
- return -ENODEV;
+ String err = "Cannot create default request, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
CameraMetadataNative template;
@@ -571,99 +584,96 @@
template =
LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId);
} catch (IllegalArgumentException e) {
- Log.e(TAG, "createDefaultRequest - invalid templateId specified");
- return CameraBinderDecorator.BAD_VALUE;
+ String err = "createDefaultRequest - invalid templateId specified";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
}
- request.swap(template);
- return CameraBinderDecorator.NO_ERROR;
+ return template;
}
@Override
- public int getCameraInfo(/*out*/CameraMetadataNative info) {
+ public CameraMetadataNative getCameraInfo() {
if (DEBUG) {
Log.d(TAG, "getCameraInfo called.");
}
// TODO: implement getCameraInfo.
Log.e(TAG, "getCameraInfo unimplemented.");
- return CameraBinderDecorator.NO_ERROR;
+ return null;
}
@Override
- public int waitUntilIdle() throws RemoteException {
+ public void waitUntilIdle() throws RemoteException {
if (DEBUG) {
Log.d(TAG, "waitUntilIdle called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot wait until idle, device has been closed.");
- return -ENODEV;
+ String err = "Cannot wait until idle, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot wait until idle, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot wait until idle, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
mLegacyDevice.waitUntilIdle();
- return CameraBinderDecorator.NO_ERROR;
}
@Override
- public int flush(/*out*/LongParcelable lastFrameNumber) {
+ public long flush() {
if (DEBUG) {
Log.d(TAG, "flush called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot flush, device has been closed.");
- return -ENODEV;
+ String err = "Cannot flush, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
synchronized(mConfigureLock) {
if (mConfiguring) {
- Log.e(TAG, "Cannot flush, configuration change in progress.");
- return CameraBinderDecorator.INVALID_OPERATION;
+ String err = "Cannot flush, configuration change in progress.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
}
}
- long lastFrame = mLegacyDevice.flush();
- if (lastFrameNumber != null) {
- lastFrameNumber.setNumber(lastFrame);
- }
- return CameraBinderDecorator.NO_ERROR;
+ return mLegacyDevice.flush();
}
- public int prepare(int streamId) {
+ public void prepare(int streamId) {
if (DEBUG) {
Log.d(TAG, "prepare called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot prepare stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot prepare stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
// LEGACY doesn't support actual prepare, just signal success right away
mCameraCallbacks.onPrepared(streamId);
-
- return CameraBinderDecorator.NO_ERROR;
}
- public int prepare2(int maxCount, int streamId) {
+ public void prepare2(int maxCount, int streamId) {
// We don't support this in LEGACY mode.
- return prepare(streamId);
+ prepare(streamId);
}
- public int tearDown(int streamId) {
+ public void tearDown(int streamId) {
if (DEBUG) {
Log.d(TAG, "tearDown called.");
}
if (mLegacyDevice.isClosed()) {
- Log.e(TAG, "Cannot tear down stream, device has been closed.");
- return -ENODEV;
+ String err = "Cannot tear down stream, device has been closed.";
+ Log.e(TAG, err);
+ throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
}
// LEGACY doesn't support actual teardown, so just a no-op
-
- return CameraBinderDecorator.NO_ERROR;
}
@Override
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index fddfbde..e62df3c 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -26,14 +26,13 @@
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.camera2.utils.ArrayUtils;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.utils.CameraRuntimeException;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
@@ -45,7 +44,6 @@
import java.util.List;
import static android.hardware.camera2.legacy.LegacyExceptionUtils.*;
-import static android.hardware.camera2.utils.CameraBinderDecorator.*;
import static com.android.internal.util.Preconditions.*;
/**
@@ -357,9 +355,9 @@
if (success) {
mConfiguredSurfaces = outputs != null ? new ArrayList<>(outputs) : null;
} else {
- return CameraBinderDecorator.INVALID_OPERATION;
+ return LegacyExceptionUtils.INVALID_OPERATION;
}
- return CameraBinderDecorator.NO_ERROR;
+ return LegacyExceptionUtils.NO_ERROR;
}
/**
@@ -367,17 +365,16 @@
*
* @param requestList a list of capture requests to execute.
* @param repeating {@code true} if this burst is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * burst is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public int submitRequestList(List<CaptureRequest> requestList, boolean repeating,
- /*out*/LongParcelable frameNumber) {
- if (requestList == null || requestList.isEmpty()) {
+ public SubmitInfo submitRequestList(CaptureRequest[] requestList, boolean repeating) {
+ if (requestList == null || requestList.length == 0) {
Log.e(TAG, "submitRequestList - Empty/null requests are not allowed");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - Empty/null requests are not allowed");
}
List<Long> surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() :
@@ -388,28 +385,33 @@
if (request.getTargets().isEmpty()) {
Log.e(TAG, "submitRequestList - "
+ "Each request must have at least one Surface target");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - "
+ + "Each request must have at least one Surface target");
}
for (Surface surface : request.getTargets()) {
if (surface == null) {
Log.e(TAG, "submitRequestList - Null Surface targets are not allowed");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - Null Surface targets are not allowed");
} else if (mConfiguredSurfaces == null) {
Log.e(TAG, "submitRequestList - must configure " +
" device with valid surfaces before submitting requests");
- return INVALID_OPERATION;
+ throw new ServiceSpecificException(INVALID_OPERATION,
+ "submitRequestList - must configure " +
+ " device with valid surfaces before submitting requests");
} else if (!containsSurfaceId(surface, surfaceIds)) {
Log.e(TAG, "submitRequestList - cannot use a surface that wasn't configured");
- return BAD_VALUE;
+ throw new ServiceSpecificException(BAD_VALUE,
+ "submitRequestList - cannot use a surface that wasn't configured");
}
}
}
// TODO: further validation of request here
mIdle.close();
- return mRequestThreadManager.submitCaptureRequests(requestList, repeating,
- frameNumber);
+ return mRequestThreadManager.submitCaptureRequests(requestList, repeating);
}
/**
@@ -417,17 +419,14 @@
*
* @param request the capture request to execute.
* @param repeating {@code true} if this request is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * request is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public int submitRequest(CaptureRequest request, boolean repeating,
- /*out*/LongParcelable frameNumber) {
- ArrayList<CaptureRequest> requestList = new ArrayList<CaptureRequest>();
- requestList.add(request);
- return submitRequestList(requestList, repeating, frameNumber);
+ public SubmitInfo submitRequest(CaptureRequest request, boolean repeating) {
+ CaptureRequest[] requestList = { request };
+ return submitRequestList(requestList, repeating);
}
/**
@@ -493,7 +492,7 @@
protected void finalize() throws Throwable {
try {
close();
- } catch (CameraRuntimeException e) {
+ } catch (ServiceSpecificException e) {
Log.e(TAG, "Got error while trying to finalize, ignoring: " + e.getMessage());
} finally {
super.finalize();
diff --git a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
index 4501e81..93d6001 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
@@ -16,10 +16,11 @@
package android.hardware.camera2.legacy;
-import android.hardware.camera2.utils.CameraBinderDecorator;
+import android.hardware.ICameraService;
+import android.os.ServiceSpecificException;
import android.util.AndroidException;
-import static android.system.OsConstants.ENODEV;
+import static android.system.OsConstants.*;
/**
* Utility class containing exception handling used solely by the compatibility mode shim.
@@ -27,6 +28,14 @@
public class LegacyExceptionUtils {
private static final String TAG = "LegacyExceptionUtils";
+ public static final int NO_ERROR = 0;
+ public static final int PERMISSION_DENIED = -EPERM;
+ public static final int ALREADY_EXISTS = -EEXIST;
+ public static final int BAD_VALUE = -EINVAL;
+ public static final int DEAD_OBJECT = -ENOSYS;
+ public static final int INVALID_OPERATION = -EPIPE;
+ public static final int TIMED_OUT = -ETIMEDOUT;
+
/**
* Checked exception thrown when a BufferQueue has been abandoned by its consumer.
*/
@@ -58,8 +67,8 @@
* @return {@code errorFlag} if the value was non-negative, throws otherwise.
*/
public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException {
- if (errorFlag == CameraBinderDecorator.NO_ERROR) {
- return CameraBinderDecorator.NO_ERROR;
+ if (errorFlag == NO_ERROR) {
+ return NO_ERROR;
} else if (errorFlag == -ENODEV) {
throw new BufferQueueAbandonedException();
}
@@ -70,6 +79,59 @@
return errorFlag;
}
+ /**
+ * Throw error codes returned by the camera service as exceptions.
+ *
+ * @param errorFlag error to throw as an exception.
+ */
+ public static void throwOnServiceError(int errorFlag) {
+ int errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ String errorMsg;
+
+ if (errorFlag >= NO_ERROR) {
+ return;
+ } else if (errorFlag == PERMISSION_DENIED) {
+ errorCode = ICameraService.ERROR_PERMISSION_DENIED;
+ errorMsg = "Lacking privileges to access camera service";
+ } else if (errorFlag == ALREADY_EXISTS) {
+ // This should be handled at the call site. Typically this isn't bad,
+ // just means we tried to do an operation that already completed.
+ return;
+ } else if (errorFlag == BAD_VALUE) {
+ errorCode = ICameraService.ERROR_ILLEGAL_ARGUMENT;
+ errorMsg = "Bad argument passed to camera service";
+ } else if (errorFlag == DEAD_OBJECT) {
+ errorCode = ICameraService.ERROR_DISCONNECTED;
+ errorMsg = "Camera service not available";
+ } else if (errorFlag == TIMED_OUT) {
+ errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ errorMsg = "Operation timed out in camera service";
+ } else if (errorFlag == -EACCES) {
+ errorCode = ICameraService.ERROR_DISABLED;
+ errorMsg = "Camera disabled by policy";
+ } else if (errorFlag == -EBUSY) {
+ errorCode = ICameraService.ERROR_CAMERA_IN_USE;
+ errorMsg = "Camera already in use";
+ } else if (errorFlag == -EUSERS) {
+ errorCode = ICameraService.ERROR_MAX_CAMERAS_IN_USE;
+ errorMsg = "Maximum number of cameras in use";
+ } else if (errorFlag == -ENODEV) {
+ errorCode = ICameraService.ERROR_DISCONNECTED;
+ errorMsg = "Camera device not available";
+ } else if (errorFlag == -EOPNOTSUPP) {
+ errorCode = ICameraService.ERROR_DEPRECATED_HAL;
+ errorMsg = "Deprecated camera HAL does not support this";
+ } else if (errorFlag == INVALID_OPERATION) {
+ errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ errorMsg = "Illegal state encountered in camera service.";
+ } else {
+ errorCode = ICameraService.ERROR_INVALID_OPERATION;
+ errorMsg = "Unknown camera device error " + errorFlag;
+ }
+
+ throw new ServiceSpecificException(errorCode, errorMsg);
+ }
+
private LegacyExceptionUtils() {
throw new AssertionError();
}
diff --git a/core/java/android/hardware/camera2/legacy/RequestQueue.java b/core/java/android/hardware/camera2/legacy/RequestQueue.java
index c995029..8f252a1 100644
--- a/core/java/android/hardware/camera2/legacy/RequestQueue.java
+++ b/core/java/android/hardware/camera2/legacy/RequestQueue.java
@@ -16,7 +16,7 @@
package android.hardware.camera2.legacy;
import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.util.Log;
import android.util.Pair;
@@ -111,31 +111,29 @@
*
* @param requests the burst of requests to add to the queue.
* @param repeating true if the burst is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * burst is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public synchronized int submit(List<CaptureRequest> requests, boolean repeating,
- /*out*/LongParcelable frameNumber) {
+ public synchronized SubmitInfo submit(CaptureRequest[] requests, boolean repeating) {
int requestId = mCurrentRequestId++;
BurstHolder burst = new BurstHolder(requestId, repeating, requests, mJpegSurfaceIds);
- long ret = INVALID_FRAME;
+ long lastFrame = INVALID_FRAME;
if (burst.isRepeating()) {
Log.i(TAG, "Repeating capture request set.");
if (mRepeatingRequest != null) {
- ret = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME :
+ lastFrame = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME :
mCurrentRepeatingFrameNumber - 1;
}
mCurrentRepeatingFrameNumber = INVALID_FRAME;
mRepeatingRequest = burst;
} else {
mRequestQueue.offer(burst);
- ret = calculateLastFrame(burst.getRequestId());
+ lastFrame = calculateLastFrame(burst.getRequestId());
}
- frameNumber.setNumber(ret);
- return requestId;
+ SubmitInfo info = new SubmitInfo(requestId, lastFrame);
+ return info;
}
private long calculateLastFrame(int requestId) {
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 4866598..1ca7ddf 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -21,7 +21,7 @@
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.impl.CameraDeviceImpl;
-import android.hardware.camera2.utils.LongParcelable;
+import android.hardware.camera2.utils.SubmitInfo;
import android.hardware.camera2.utils.SizeAreaComparator;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.os.ConditionVariable;
@@ -1008,21 +1008,19 @@
*
* @param requests the burst of requests to add to the queue.
* @param repeating true if the burst is repeating.
- * @param frameNumber an output argument that contains either the frame number of the last frame
- * that will be returned for this request, or the frame number of the last
- * frame that will be returned for the current repeating request if this
- * burst is set to be repeating.
- * @return the request id.
+ * @return the submission info, including the new request id, and the last frame number, which
+ * contains either the frame number of the last frame that will be returned for this request,
+ * or the frame number of the last frame that will be returned for the current repeating
+ * request if this burst is set to be repeating.
*/
- public int submitCaptureRequests(List<CaptureRequest> requests, boolean repeating,
- /*out*/LongParcelable frameNumber) {
+ public SubmitInfo submitCaptureRequests(CaptureRequest[] requests, boolean repeating) {
Handler handler = mRequestThread.waitAndGetHandler();
- int ret;
+ SubmitInfo info;
synchronized (mIdleLock) {
- ret = mRequestQueue.submit(requests, repeating, frameNumber);
+ info = mRequestQueue.submit(requests, repeating);
handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST);
}
- return ret;
+ return info;
}
/**
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.aidl b/core/java/android/hardware/camera2/params/OutputConfiguration.aidl
deleted file mode 100644
index 0921cd8..0000000
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.params;
-
-/** @hide */
-parcelable OutputConfiguration;
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 4407e55..cd0c474 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -21,11 +21,11 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.utils.HashCodeHelpers;
import android.hardware.camera2.utils.SurfaceUtils;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
-import android.os.Parcel;
-import android.os.Parcelable;
import static com.android.internal.util.Preconditions.*;
diff --git a/core/java/android/hardware/camera2/params/VendorTagDescriptor.java b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java
new file mode 100644
index 0000000..ea424e5
--- /dev/null
+++ b/core/java/android/hardware/camera2/params/VendorTagDescriptor.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera2.params;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * A class for describing the vendor tags declared by a camera HAL module.
+ * Generally only used by the native side of
+ * android.hardware.camera2.impl.CameraMetadataNative
+ *
+ * @hide
+ */
+public final class VendorTagDescriptor implements Parcelable {
+
+ private VendorTagDescriptor(Parcel source) {
+ }
+
+ public static final Parcelable.Creator<VendorTagDescriptor> CREATOR =
+ new Parcelable.Creator<VendorTagDescriptor>() {
+ @Override
+ public VendorTagDescriptor createFromParcel(Parcel source) {
+ try {
+ VendorTagDescriptor vendorDescriptor = new VendorTagDescriptor(source);
+ return vendorDescriptor;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception creating VendorTagDescriptor from parcel", e);
+ return null;
+ }
+ }
+
+ @Override
+ public VendorTagDescriptor[] newArray(int size) {
+ return new VendorTagDescriptor[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (dest == null) {
+ throw new IllegalArgumentException("dest must not be null");
+ }
+ }
+
+ private static final String TAG = "VendorTagDescriptor";
+}
diff --git a/core/java/android/hardware/camera2/utils/BinderHolder.aidl b/core/java/android/hardware/camera2/utils/BinderHolder.aidl
deleted file mode 100644
index f39d645..0000000
--- a/core/java/android/hardware/camera2/utils/BinderHolder.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.utils;
-
-/** @hide */
-parcelable BinderHolder;
diff --git a/core/java/android/hardware/camera2/utils/BinderHolder.java b/core/java/android/hardware/camera2/utils/BinderHolder.java
deleted file mode 100644
index 9eea390..0000000
--- a/core/java/android/hardware/camera2/utils/BinderHolder.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.utils;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.IBinder;
-
-/**
- * @hide
- */
-public class BinderHolder implements Parcelable {
- private IBinder mBinder = null;
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeStrongBinder(mBinder);
- }
-
- public void readFromParcel(Parcel src) {
- mBinder = src.readStrongBinder();
- }
-
- public static final Parcelable.Creator<BinderHolder> CREATOR =
- new Parcelable.Creator<BinderHolder>() {
- @Override
- public BinderHolder createFromParcel(Parcel in) {
- return new BinderHolder(in);
- }
-
- @Override
- public BinderHolder[] newArray(int size) {
- return new BinderHolder[size];
- }
- };
-
- public IBinder getBinder() {
- return mBinder;
- }
-
- public void setBinder(IBinder binder) {
- mBinder = binder;
- }
-
- public BinderHolder() {}
-
- public BinderHolder(IBinder binder) {
- mBinder = binder;
- }
-
- private BinderHolder(Parcel in) {
- mBinder = in.readStrongBinder();
- }
-}
-
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
deleted file mode 100644
index 162edc9..0000000
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.utils;
-
-import static android.hardware.camera2.CameraAccessException.CAMERA_DISABLED;
-import static android.hardware.camera2.CameraAccessException.CAMERA_DISCONNECTED;
-import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
-import static android.hardware.camera2.CameraAccessException.CAMERA_ERROR;
-import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
-import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
-import static android.system.OsConstants.*;
-
-import android.os.DeadObjectException;
-import android.os.RemoteException;
-
-import java.lang.reflect.Method;
-
-/**
- * Translate camera device status_t return values into exceptions.
- *
- * @see android.hardware.camera2.utils.CameraBinderDecorator#newInstance
- * @hide
- */
-public class CameraBinderDecorator {
-
- public static final int NO_ERROR = 0;
- public static final int PERMISSION_DENIED = -EPERM;
- public static final int ALREADY_EXISTS = -EEXIST;
- public static final int BAD_VALUE = -EINVAL;
- public static final int DEAD_OBJECT = -ENOSYS;
- public static final int INVALID_OPERATION = -EPIPE;
- public static final int TIMED_OUT = -ETIMEDOUT;
-
- /**
- * TODO: add as error codes in Errors.h
- * - POLICY_PROHIBITS
- * - RESOURCE_BUSY
- * - NO_SUCH_DEVICE
- * - NOT_SUPPORTED
- * - TOO_MANY_USERS
- */
-
- static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
-
- @Override
- public void onBeforeInvocation(Method m, Object[] args) {
- }
-
- @Override
- public void onAfterInvocation(Method m, Object[] args, Object result) {
- // int return type => status_t => convert to exception
- if (m.getReturnType() == Integer.TYPE) {
- int returnValue = (Integer) result;
- throwOnError(returnValue);
- }
- }
-
- @Override
- public boolean onCatchException(Method m, Object[] args, Throwable t) {
-
- if (t instanceof DeadObjectException) {
- throw new CameraRuntimeException(CAMERA_DISCONNECTED,
- "Process hosting the camera service has died unexpectedly",
- t);
- } else if (t instanceof RemoteException) {
- throw new UnsupportedOperationException("An unknown RemoteException was thrown" +
- " which should never happen.", t);
- }
-
- return false;
- }
-
- @Override
- public void onFinally(Method m, Object[] args) {
- }
-
- }
-
- /**
- * Throw error codes returned by the camera service as exceptions.
- *
- * @param errorFlag error to throw as an exception.
- */
- public static void throwOnError(int errorFlag) {
- if (errorFlag == NO_ERROR) {
- return;
- } else if (errorFlag == PERMISSION_DENIED) {
- throw new SecurityException("Lacking privileges to access camera service");
- } else if (errorFlag == ALREADY_EXISTS) {
- // This should be handled at the call site. Typically this isn't bad,
- // just means we tried to do an operation that already completed.
- return;
- } else if (errorFlag == BAD_VALUE) {
- throw new IllegalArgumentException("Bad argument passed to camera service");
- } else if (errorFlag == DEAD_OBJECT) {
- throw new CameraRuntimeException(CAMERA_DISCONNECTED);
- } else if (errorFlag == TIMED_OUT) {
- throw new CameraRuntimeException(CAMERA_ERROR,
- "Operation timed out in camera service");
- } else if (errorFlag == -EACCES) {
- throw new CameraRuntimeException(CAMERA_DISABLED);
- } else if (errorFlag == -EBUSY) {
- throw new CameraRuntimeException(CAMERA_IN_USE);
- } else if (errorFlag == -EUSERS) {
- throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
- } else if (errorFlag == -ENODEV) {
- throw new CameraRuntimeException(CAMERA_DISCONNECTED);
- } else if (errorFlag == -EOPNOTSUPP) {
- throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
- } else if (errorFlag == INVALID_OPERATION) {
- throw new CameraRuntimeException(CAMERA_ERROR,
- "Illegal state encountered in camera service.");
- }
-
- /**
- * Trap the rest of the negative return values. If we have known
- * error codes i.e. ALREADY_EXISTS that aren't really runtime
- * errors, then add them to the top switch statement
- */
- if (errorFlag < 0) {
- throw new CameraRuntimeException(CAMERA_ERROR,
- String.format("Unknown camera device error %d", errorFlag));
- }
- }
-
- /**
- * <p>
- * Wraps the type T with a proxy that will check 'status_t' return codes
- * from the native side of the camera service, and throw Java exceptions
- * automatically based on the code.
- * </p>
- * <p>
- * In addition it also rewrites binder's RemoteException into either a
- * CameraAccessException or an UnsupportedOperationException.
- * </p>
- * <p>
- * As a result of calling any method on the proxy, RemoteException is
- * guaranteed never to be thrown.
- * </p>
- *
- * @param obj object that will serve as the target for all method calls
- * @param <T> the type of the element you want to wrap. This must be an interface.
- * @return a proxy that will intercept all invocations to obj
- */
- public static <T> T newInstance(T obj) {
- return Decorator.<T> newInstance(obj, new CameraBinderDecoratorListener());
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/CameraRuntimeException.java b/core/java/android/hardware/camera2/utils/CameraRuntimeException.java
deleted file mode 100644
index 9ed88a9..0000000
--- a/core/java/android/hardware/camera2/utils/CameraRuntimeException.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package android.hardware.camera2.utils;
-
-import android.hardware.camera2.CameraAccessException;
-
-/**
- * @hide
- */
-public class CameraRuntimeException extends RuntimeException {
-
- private final int mReason;
- private String mMessage;
- private Throwable mCause;
-
- public final int getReason() {
- return mReason;
- }
-
- public CameraRuntimeException(int problem) {
- super();
- mReason = problem;
- }
-
- public CameraRuntimeException(int problem, String message) {
- super(message);
- mReason = problem;
- mMessage = message;
- }
-
- public CameraRuntimeException(int problem, String message, Throwable cause) {
- super(message, cause);
- mReason = problem;
- mMessage = message;
- mCause = cause;
- }
-
- public CameraRuntimeException(int problem, Throwable cause) {
- super(cause);
- mReason = problem;
- mCause = cause;
- }
-
- /**
- * Recreate this exception as the CameraAccessException equivalent.
- * @return CameraAccessException
- */
- public CameraAccessException asChecked() {
- CameraAccessException e;
-
- if (mMessage != null && mCause != null) {
- e = new CameraAccessException(mReason, mMessage, mCause);
- } else if (mMessage != null) {
- e = new CameraAccessException(mReason, mMessage);
- } else if (mCause != null) {
- e = new CameraAccessException(mReason, mCause);
- } else {
- e = new CameraAccessException(mReason);
- }
- // throw and catch, so java has a chance to fill out the stack trace
- e.setStackTrace(this.getStackTrace());
-
- return e;
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/CameraServiceBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraServiceBinderDecorator.java
deleted file mode 100644
index c1fb6b1..0000000
--- a/core/java/android/hardware/camera2/utils/CameraServiceBinderDecorator.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.utils;
-
-import android.os.DeadObjectException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.reflect.Method;
-
-/**
- * Translate camera service status_t return values into exceptions.
- *
- * @see android.hardware.camera2.utils.CameraBinderDecorator#newInstance
- * @hide
- */
-public class CameraServiceBinderDecorator extends CameraBinderDecorator {
-
- private static final String TAG = "CameraServiceBinderDecorator";
-
- static class CameraServiceBinderDecoratorListener
- extends CameraBinderDecorator.CameraBinderDecoratorListener {
-
- // Pass through remote exceptions, unlike CameraBinderDecorator
- @Override
- public boolean onCatchException(Method m, Object[] args, Throwable t) {
-
- if (t instanceof DeadObjectException) {
- // Can sometimes happen (camera service died)
- // Pass on silently
- } else if (t instanceof RemoteException) {
- // Some other kind of remote exception - this is not normal, so let's at least
- // note it before moving on
- Log.e(TAG, "Unexpected RemoteException from camera service call.", t);
- }
- // All other exceptions also get sent onward
- return false;
- }
-
- }
-
- /**
- * <p>
- * Wraps the type T with a proxy that will check 'status_t' return codes
- * from the native side of the camera service, and throw Java exceptions
- * automatically based on the code.
- * </p>
- *
- * @param obj object that will serve as the target for all method calls
- * @param <T> the type of the element you want to wrap. This must be an interface.
- * @return a proxy that will intercept all invocations to obj
- */
- public static <T> T newInstance(T obj) {
- return Decorator.<T> newInstance(obj, new CameraServiceBinderDecoratorListener());
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/Decorator.java b/core/java/android/hardware/camera2/utils/Decorator.java
deleted file mode 100644
index 5826497..0000000
--- a/core/java/android/hardware/camera2/utils/Decorator.java
+++ /dev/null
@@ -1,92 +0,0 @@
-
-package android.hardware.camera2.utils;
-
-import java.lang.reflect.*;
-
-/**
- * This is an implementation of the 'decorator' design pattern using Java's proxy mechanism.
- *
- * @see android.hardware.camera2.utils.Decorator#newInstance
- *
- * @hide
- */
-public class Decorator<T> implements InvocationHandler {
-
- public interface DecoratorListener {
- /**
- * This method is called before the target method is invoked
- * @param args arguments to target method
- * @param m Method being called
- */
- void onBeforeInvocation(Method m, Object[] args);
- /**
- * This function is called after the target method is invoked
- * if there were no uncaught exceptions
- * @param args arguments to target method
- * @param m Method being called
- * @param result return value of target method
- */
- void onAfterInvocation(Method m, Object[] args, Object result);
- /**
- * This method is called only if there was an exception thrown by the target method
- * during its invocation.
- *
- * @param args arguments to target method
- * @param m Method being called
- * @param t Throwable that was thrown
- * @return false to rethrow exception, true if the exception was handled
- */
- boolean onCatchException(Method m, Object[] args, Throwable t);
- /**
- * This is called after the target method is invoked, regardless of whether or not
- * there were any exceptions.
- * @param args arguments to target method
- * @param m Method being called
- */
- void onFinally(Method m, Object[] args);
- }
-
- private final T mObject;
- private final DecoratorListener mListener;
-
- /**
- * Create a decorator wrapping the specified object's method calls.
- *
- * @param obj the object whose method calls you want to intercept
- * @param listener the decorator handler for intercepted method calls
- * @param <T> the type of the element you want to wrap. This must be an interface.
- * @return a wrapped interface-compatible T
- */
- @SuppressWarnings("unchecked")
- public static<T> T newInstance(T obj, DecoratorListener listener) {
- return (T)java.lang.reflect.Proxy.newProxyInstance(
- obj.getClass().getClassLoader(),
- obj.getClass().getInterfaces(),
- new Decorator<T>(obj, listener));
- }
-
- private Decorator(T obj, DecoratorListener listener) {
- this.mObject = obj;
- this.mListener = listener;
- }
-
- @Override
- public Object invoke(Object proxy, Method m, Object[] args)
- throws Throwable
- {
- Object result = null;
- try {
- mListener.onBeforeInvocation(m, args);
- result = m.invoke(mObject, args);
- mListener.onAfterInvocation(m, args, result);
- } catch (InvocationTargetException e) {
- Throwable t = e.getTargetException();
- if (!mListener.onCatchException(m, args, t)) {
- throw t;
- }
- } finally {
- mListener.onFinally(m, args);
- }
- return result;
- }
-}
diff --git a/core/java/android/hardware/camera2/utils/LongParcelable.aidl b/core/java/android/hardware/camera2/utils/LongParcelable.aidl
deleted file mode 100644
index 98ad1b2..0000000
--- a/core/java/android/hardware/camera2/utils/LongParcelable.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.utils;
-
-/** @hide */
-parcelable LongParcelable;
diff --git a/core/java/android/hardware/camera2/utils/SubmitInfo.java b/core/java/android/hardware/camera2/utils/SubmitInfo.java
new file mode 100644
index 0000000..d1692b5
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/SubmitInfo.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.camera2.utils;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.hardware.camera2.ICameraDeviceUser;
+
+/**
+ * The status information returned for a successful capture request submission.
+ *
+ * Includes the request ID for the newly submitted capture request, and the
+ * last frame number of either the previous repeating request (for repeating
+ * requests), or of the request(s) just submitted (for single-shot capture).
+ *
+ * @hide
+ */
+public class SubmitInfo implements Parcelable {
+
+ private int mRequestId;
+ private long mLastFrameNumber;
+
+ public SubmitInfo() {
+ mRequestId = -1;
+ mLastFrameNumber = ICameraDeviceUser.NO_IN_FLIGHT_REPEATING_FRAMES;
+ }
+
+ public SubmitInfo(int requestId, long lastFrameNumber) {
+ mRequestId = requestId;
+ mLastFrameNumber = lastFrameNumber;
+ }
+
+ public static final Parcelable.Creator<SubmitInfo> CREATOR =
+ new Parcelable.Creator<SubmitInfo>() {
+ @Override
+ public SubmitInfo createFromParcel(Parcel in) {
+ return new SubmitInfo(in);
+ }
+
+ @Override
+ public SubmitInfo[] newArray(int size) {
+ return new SubmitInfo[size];
+ }
+ };
+
+ private SubmitInfo(Parcel in) {
+ readFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mRequestId);
+ dest.writeLong(mLastFrameNumber);
+ }
+
+ public void readFromParcel(Parcel in) {
+ mRequestId = in.readInt();
+ mLastFrameNumber = in.readLong();
+ }
+
+ /**
+ * Return the request ID for the submitted capture request/burst.
+ *
+ * This is used to track the completion status of the requested captures,
+ * and to cancel repeating requests.
+ */
+ public int getRequestId() {
+ return mRequestId;
+ }
+
+ /**
+ * Return the last frame number for the submitted capture request/burst.
+ *
+ * For a repeating request, this is the last frame number of the _prior_
+ * repeating request, to indicate when to fire the sequence completion callback
+ * for the prior repeating request.
+ *
+ * For a single-shot capture, this is the last frame number of _this_
+ * burst, to indicate when to fire the sequence completion callback for the request itself.
+ *
+ * For a repeating request, may be NO_IN_FLIGHT_REPEATING_FRAMES, if no
+ * instances of a prior repeating request were actually issued to the camera device.
+ */
+ public long getLastFrameNumber() {
+ return mLastFrameNumber;
+ }
+
+}
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index cc2b764..b635088 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -689,12 +689,19 @@
return false;
if (triggerInData != other.triggerInData)
return false;
- if (captureFormat.getSampleRate() != other.captureFormat.getSampleRate())
- return false;
- if (captureFormat.getEncoding() != other.captureFormat.getEncoding())
- return false;
- if (captureFormat.getChannelMask() != other.captureFormat.getChannelMask())
- return false;
+ if (captureFormat == null) {
+ if (other.captureFormat != null)
+ return false;
+ } else {
+ if (other.captureFormat == null)
+ return false;
+ if (captureFormat.getSampleRate() != other.captureFormat.getSampleRate())
+ return false;
+ if (captureFormat.getEncoding() != other.captureFormat.getEncoding())
+ return false;
+ if (captureFormat.getChannelMask() != other.captureFormat.getChannelMask())
+ return false;
+ }
return true;
}
@@ -1002,10 +1009,10 @@
int encoding = in.readInt();
int channelMask = in.readInt();
captureFormat = (new AudioFormat.Builder())
- .setChannelMask(channelMask)
- .setEncoding(encoding)
- .setSampleRate(sampleRate)
- .build();
+ .setChannelMask(channelMask)
+ .setEncoding(encoding)
+ .setSampleRate(sampleRate)
+ .build();
}
byte[] data = in.readBlob();
KeyphraseRecognitionExtra[] keyphraseExtras =
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 20c2168..9e360e1 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -200,6 +200,14 @@
*/
public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
+ /**
+ * Sent by ConnectivityService to the NetworkAgent to install an APF program in the network
+ * chipset for use to filter packets.
+ *
+ * obj = byte[] containing the APF program bytecode.
+ */
+ public static final int CMD_PUSH_APF_PROGRAM = BASE + 16;
+
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score) {
this(looper, context, logTag, ni, nc, lp, score, null);
@@ -319,6 +327,10 @@
preventAutomaticReconnect();
break;
}
+ case CMD_PUSH_APF_PROGRAM: {
+ installPacketFilter((byte[]) msg.obj);
+ break;
+ }
}
}
@@ -494,6 +506,15 @@
protected void preventAutomaticReconnect() {
}
+ /**
+ * Install a packet filter.
+ * @param filter an APF program to filter incoming packets.
+ * @return {@code true} if filter successfully installed, {@code false} otherwise.
+ */
+ protected boolean installPacketFilter(byte[] filter) {
+ return false;
+ }
+
protected void log(String s) {
Log.d(LOG_TAG, "NetworkAgent: " + s);
}
diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java
index 5511a24..748699e 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -56,6 +56,22 @@
*/
public String subscriberId;
+ /**
+ * Version of APF instruction set supported for packet filtering. 0 indicates no support for
+ * packet filtering using APF programs.
+ */
+ public int apfVersionSupported;
+
+ /**
+ * Maximum size of APF program allowed.
+ */
+ public int maximumApfProgramSize;
+
+ /**
+ * Format of packets passed to APF filter. Should be one of ARPHRD_*
+ */
+ public int apfPacketFormat;
+
public NetworkMisc() {
}
@@ -65,6 +81,9 @@
explicitlySelected = nm.explicitlySelected;
acceptUnvalidated = nm.acceptUnvalidated;
subscriberId = nm.subscriberId;
+ apfVersionSupported = nm.apfVersionSupported;
+ maximumApfProgramSize = nm.maximumApfProgramSize;
+ apfPacketFormat = nm.apfPacketFormat;
}
}
@@ -79,6 +98,9 @@
out.writeInt(explicitlySelected ? 1 : 0);
out.writeInt(acceptUnvalidated ? 1 : 0);
out.writeString(subscriberId);
+ out.writeInt(apfVersionSupported);
+ out.writeInt(maximumApfProgramSize);
+ out.writeInt(apfPacketFormat);
}
public static final Creator<NetworkMisc> CREATOR = new Creator<NetworkMisc>() {
@@ -89,6 +111,9 @@
networkMisc.explicitlySelected = in.readInt() != 0;
networkMisc.acceptUnvalidated = in.readInt() != 0;
networkMisc.subscriberId = in.readString();
+ networkMisc.apfVersionSupported = in.readInt();
+ networkMisc.maximumApfProgramSize = in.readInt();
+ networkMisc.apfPacketFormat = in.readInt();
return networkMisc;
}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index c6d919f..555032d 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -62,6 +62,13 @@
public native static void attachDhcpFilter(FileDescriptor fd) throws SocketException;
/**
+ * Attaches a socket filter that accepts ICMP6 router advertisement packets to the given socket.
+ * @param fd the socket's {@link FileDescriptor}.
+ * @param packetType the hardware address type, one of ARPHRD_*.
+ */
+ public native static void attachRaFilter(FileDescriptor fd, int packetType) throws SocketException;
+
+ /**
* Binds the current process to the network designated by {@code netId}. All sockets created
* in the future (and not explicitly bound via a bound {@link SocketFactory} (see
* {@link Network#getSocketFactory}) will be bound to this network. Note that if this
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 9984755..8fd3b0c 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -383,6 +383,9 @@
public static final int SIGNAL_KILL = 9;
public static final int SIGNAL_USR1 = 10;
+ private static long sStartElapsedRealtime;
+ private static long sStartUptimeMillis;
+
/**
* State for communicating with the zygote process.
*
@@ -772,6 +775,26 @@
public static final native long getElapsedCpuTime();
/**
+ * Return the {@link SystemClock#elapsedRealtime()} at which this process was started.
+ */
+ public static final long getStartElapsedRealtime() {
+ return sStartElapsedRealtime;
+ }
+
+ /**
+ * Return the {@link SystemClock#uptimeMillis()} at which this process was started.
+ */
+ public static final long getStartUptimeMillis() {
+ return sStartUptimeMillis;
+ }
+
+ /** @hide */
+ public static final void setStartTimes(long elapsedRealtime, long uptimeMillis) {
+ sStartElapsedRealtime = elapsedRealtime;
+ sStartUptimeMillis = uptimeMillis;
+ }
+
+ /**
* Returns true if the current process is a 64-bit runtime.
*/
public static final boolean is64Bit() {
diff --git a/core/java/android/os/ServiceSpecificException.java b/core/java/android/os/ServiceSpecificException.java
index 20f237a5..04fca19 100644
--- a/core/java/android/os/ServiceSpecificException.java
+++ b/core/java/android/os/ServiceSpecificException.java
@@ -20,20 +20,23 @@
*
* <p>This exception includes an error code specific to the throwing
* service. This is mostly used by system services to indicate
- * domain specific error conditions.
+ * domain specific error conditions.</p>
+ *
+ * <p>Since these exceptions are designed to be passed through Binder
+ * interfaces, and to be generated by native-code Binder services,
+ * they do not support exception chaining.</p>
*
* @hide
*/
public class ServiceSpecificException extends RuntimeException {
public final int errorCode;
- ServiceSpecificException(int errorCode, String message) {
+ public ServiceSpecificException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
- ServiceSpecificException(int errorCode) {
+ public ServiceSpecificException(int errorCode) {
this.errorCode = errorCode;
}
}
-
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 6e9e456..7223dfb 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1658,7 +1658,7 @@
* android.graphics.drawable.Drawable, UserHandle, android.graphics.Rect, int)}.
* <p>
* If the original drawable is a BitmapDrawable and the backing bitmap is
- * mutable as per {@link android.graphics.Bitmap#isMutable()}, the bading
+ * mutable as per {@link android.graphics.Bitmap#isMutable()}, the badging
* is performed in place and the original drawable is returned.
* </p>
*
@@ -1681,17 +1681,17 @@
* badge to be used.
* <p>
* If the original drawable is a BitmapDrawable and the backing bitmap is
- * mutable as per {@link android.graphics.Bitmap#isMutable()}, the bading
+ * mutable as per {@link android.graphics.Bitmap#isMutable()}, the badging
* is performed in place and the original drawable is returned.
* </p>
*
* @param badgedDrawable The drawable to badge.
* @param user The target user.
* @param badgeLocation Where in the bounds of the badged drawable to place
- * the badge. If not provided, the badge is applied on top of the entire
+ * the badge. If it's {@code null}, the badge is applied on top of the entire
* drawable being badged.
* @param badgeDensity The optional desired density for the badge as per
- * {@link android.util.DisplayMetrics#densityDpi}. If not provided,
+ * {@link android.util.DisplayMetrics#densityDpi}. If it's not positive,
* the density of the display is used.
* @return A drawable that combines the original drawable and a badge as
* determined by the system.
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 4b70649..ea0597d 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -438,10 +438,6 @@
final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(uri);
-
- // note that docsui treats this as *force* show advanced. So sending
- // false permits advanced to be shown based on user preferences.
- intent.putExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, isPrimary());
intent.putExtra(DocumentsContract.EXTRA_SHOW_FILESIZE, true);
return intent;
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 904b393..4b43f53 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8763,6 +8763,15 @@
* <li><em>Note: Some apps may choose to use phone number as the unique contact ID in DATA1.
* If this applies to you and you’d like phone number to be shown below the Contact Name by
* the Voice Assistant, then you may choose to leave DATA3 empty.</em></li>
+ * <li><em>Note: If your app also uses DATA3 to display contact details in the Contacts App,
+ * make sure it does not include prefix text such as "Message +<phone>" or "Free Message
+ * +<phone>", etc. If you must show the prefix text in the Contacts App, please use a
+ * different DATA# column, and update your contacts.xml to point to this new column. </em>
+ * </li>
+ * <li>Everytime the user sends a message to a contact, your app may choose to update the
+ * {@link ContactOptionsColumns#TIMES_CONTACTED} entry through DataUsageFeedback class.
+ * Doing this will allow Voice Assistant to bias speech recognition to contacts frequently
+ * contacted, this is particularly useful for contact names that are hard to pronounce.</li>
* </ul>
* <p>
* Input: {@link android.content.Intent#getType} is the MIME type of the data being sent.
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 3700098..03a1ca6 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -93,9 +93,6 @@
public static final String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
/** {@hide} */
- public static final String EXTRA_SHOW_ADVANCED = "android.content.extra.SHOW_ADVANCED";
-
- /** {@hide} */
public static final String EXTRA_SHOW_FILESIZE = "android.content.extra.SHOW_FILESIZE";
/** {@hide} */
@@ -564,22 +561,29 @@
public static final int FLAG_EMPTY = 1 << 16;
/**
- * Flag indicating that this root should only be visible to advanced
- * users.
- *
- * @see #COLUMN_FLAGS
- * @hide
- */
- public static final int FLAG_ADVANCED = 1 << 17;
-
- /**
* Flag indicating that this root has settings.
*
* @see #COLUMN_FLAGS
* @see DocumentsContract#ACTION_DOCUMENT_ROOT_SETTINGS
* @hide
*/
- public static final int FLAG_HAS_SETTINGS = 1 << 18;
+ public static final int FLAG_HAS_SETTINGS = 1 << 17;
+
+ /**
+ * Flag indicating that this root is on removable SD card storage.
+ *
+ * @see #COLUMN_FLAGS
+ * @hide
+ */
+ public static final int FLAG_REMOVABLE_SD = 1 << 18;
+
+ /**
+ * Flag indicating that this root is on removable USB storage.
+ *
+ * @see #COLUMN_FLAGS
+ * @hide
+ */
+ public static final int FLAG_REMOVABLE_USB = 1 << 19;
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cb45deb..f13f242 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4522,6 +4522,13 @@
public static final String USER_SETUP_COMPLETE = "user_setup_complete";
/**
+ * Prefix for category name that marks whether a suggested action from that category was
+ * completed.
+ * @hide
+ */
+ public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category.";
+
+ /**
* List of input methods that are currently enabled. This is a string
* containing the IDs of all enabled input methods, each ID separated
* by ':'.
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index e79dfca..3564e11 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -16,6 +16,7 @@
package android.text.method;
+import android.graphics.Paint;
import android.icu.lang.UCharacter;
import android.icu.lang.UProperty;
import android.view.KeyEvent;
@@ -25,6 +26,8 @@
import android.text.style.ReplacementSpan;
import android.widget.TextView;
+import com.android.internal.annotations.GuardedBy;
+
import java.text.BreakIterator;
import java.util.Arrays;
import java.util.Collections;
@@ -45,6 +48,11 @@
implements KeyListener {
/* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete();
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ static Paint sCachedPaint = null;
+
/**
* Performs the action that happens when you press the {@link KeyEvent#KEYCODE_DEL} key in
* a {@link TextView}. If there is a selection, deletes the selection; otherwise,
@@ -258,20 +266,15 @@
}
// Returns the end offset to be deleted by a forward delete key from the given offset.
- private static int getOffsetForForwardDeleteKey(CharSequence text, int offset) {
+ private static int getOffsetForForwardDeleteKey(CharSequence text, int offset, Paint paint) {
final int len = text.length();
if (offset >= len - 1) {
return len;
}
- int codePoint = Character.codePointAt(text, offset);
- offset += Character.charCount(codePoint);
- if (offset == len) {
- return len;
- }
-
- // TODO: Handle emoji, combining chars, etc.
+ offset = paint.getTextRunCursor(text, offset, len, Paint.DIRECTION_LTR /* not used */,
+ offset, Paint.CURSOR_AFTER);
return adjustReplacementSpan(text, offset, false /* move to the end */);
}
@@ -311,7 +314,18 @@
final int start = Selection.getSelectionEnd(content);
final int end;
if (isForwardDelete) {
- end = getOffsetForForwardDeleteKey(content, start);
+ final Paint paint;
+ if (view instanceof TextView) {
+ paint = ((TextView)view).getPaint();
+ } else {
+ synchronized (mLock) {
+ if (sCachedPaint == null) {
+ sCachedPaint = new Paint();
+ }
+ paint = sCachedPaint;
+ }
+ }
+ end = getOffsetForForwardDeleteKey(content, start, paint);
} else {
end = getOffsetForBackspaceKey(content, start);
}
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index fbd9924..bd376ea 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -224,7 +224,7 @@
}
if ((mask & EMAIL_ADDRESSES) != 0) {
- gatherLinks(links, text, Patterns.EMAIL_ADDRESS,
+ gatherLinks(links, text, Patterns.AUTOLINK_EMAIL_ADDRESS,
new String[] { "mailto:" },
null, null);
}
diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java
index 9f2bcfd..9ed4850 100644
--- a/core/java/android/util/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -394,6 +394,36 @@
public static final Pattern AUTOLINK_WEB_URL = Pattern.compile(
"(" + WEB_URL_WITH_PROTOCOL + "|" + WEB_URL_WITHOUT_PROTOCOL + ")");
+ /**
+ * Regular expression for valid email characters. Does not include some of the valid characters
+ * defined in RFC5321: #&~!^`{}/=$*?|
+ */
+ private static final String EMAIL_CHAR = LABEL_CHAR + "\\+\\-_%'";
+
+ /**
+ * Regular expression for local part of an email address. RFC5321 section 4.5.3.1.1 limits
+ * the local part to be at most 64 octets.
+ */
+ private static final String EMAIL_ADDRESS_LOCAL_PART =
+ "[" + EMAIL_CHAR + "]" + "(?:[" + EMAIL_CHAR + "\\.]{1,62}[" + EMAIL_CHAR + "])?";
+
+ /**
+ * Regular expression for the domain part of an email address. RFC5321 section 4.5.3.1.2 limits
+ * the domain to be at most 255 octets.
+ */
+ private static final String EMAIL_ADDRESS_DOMAIN =
+ "(?=.{1,255}(?:\\s|$|^))" + HOST_NAME;
+
+ /**
+ * Regular expression pattern to match email addresses. It excludes double quoted local parts
+ * and the special characters #&~!^`{}/=$*?| that are included in RFC5321.
+ * @hide
+ */
+ public static final Pattern AUTOLINK_EMAIL_ADDRESS = Pattern.compile("(" + WORD_BOUNDARY +
+ "(?:" + EMAIL_ADDRESS_LOCAL_PART + "@" + EMAIL_ADDRESS_DOMAIN + ")" +
+ WORD_BOUNDARY + ")"
+ );
+
public static final Pattern EMAIL_ADDRESS
= Pattern.compile(
"[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
diff --git a/core/java/android/view/Surface.aidl b/core/java/android/view/Surface.aidl
deleted file mode 100644
index 90bf37a..0000000
--- a/core/java/android/view/Surface.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/Surface.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.view;
-
-parcelable Surface;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index b58c68f..aa86c03 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -36,6 +36,7 @@
throws OutOfResourcesException;
private static native void nativeRelease(long nativeObject);
private static native void nativeDestroy(long nativeObject);
+ private static native void nativeDisconnect(long nativeObject);
private static native Bitmap nativeScreenshot(IBinder displayToken,
Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
@@ -341,6 +342,15 @@
mCloseGuard.close();
}
+ /**
+ * Disconnect any client still connected to the surface.
+ */
+ public void disconnect() {
+ if (mNativeObject != 0) {
+ nativeDisconnect(mNativeObject);
+ }
+ }
+
private void checkNotReleased() {
if (mNativeObject == 0) throw new NullPointerException(
"mNativeObject is null. Have you called release() already?");
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index 65c7654..42d1442 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -21,13 +21,22 @@
import android.view.KeyEvent;
/**
- * <p>Wrapper class for proxying calls to another InputConnection. Subclass
- * and have fun!
+ * <p>Wrapper class for proxying calls to another InputConnection. Subclass and have fun!
*/
public class InputConnectionWrapper implements InputConnection {
private InputConnection mTarget;
final boolean mMutable;
-
+
+ /**
+ * Initializes a wrapper.
+ *
+ * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some
+ * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that
+ * has {@code null} in {@code target}.</p>
+ * @param target the {@link InputConnection} to be proxied.
+ * @param mutable set {@code true} to protect this object from being reconfigured to target
+ * another {@link InputConnection}. Note that this is ignored while the target is {@code null}.
+ */
public InputConnectionWrapper(InputConnection target, boolean mutable) {
mMutable = mutable;
mTarget = target;
@@ -35,6 +44,12 @@
/**
* Change the target of the input connection.
+ *
+ * <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some
+ * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that
+ * has {@code null} in {@code target}.</p>
+ * @param target the {@link InputConnection} to be proxied.
+ * @throws SecurityException when this wrapper has non-null target and is immutable.
*/
public void setTarget(InputConnection target) {
if (mTarget != null && !mMutable) {
@@ -42,99 +57,195 @@
}
mTarget = target;
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public CharSequence getTextBeforeCursor(int n, int flags) {
return mTarget.getTextBeforeCursor(n, flags);
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public CharSequence getTextAfterCursor(int n, int flags) {
return mTarget.getTextAfterCursor(n, flags);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public CharSequence getSelectedText(int flags) {
return mTarget.getSelectedText(flags);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public int getCursorCapsMode(int reqModes) {
return mTarget.getCursorCapsMode(reqModes);
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
return mTarget.getExtractedText(request, flags);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
return mTarget.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
return mTarget.deleteSurroundingText(beforeLength, afterLength);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean setComposingText(CharSequence text, int newCursorPosition) {
return mTarget.setComposingText(text, newCursorPosition);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean setComposingRegion(int start, int end) {
return mTarget.setComposingRegion(start, end);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean finishComposingText() {
return mTarget.finishComposingText();
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean commitText(CharSequence text, int newCursorPosition) {
return mTarget.commitText(text, newCursorPosition);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean commitCompletion(CompletionInfo text) {
return mTarget.commitCompletion(text);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean commitCorrection(CorrectionInfo correctionInfo) {
return mTarget.commitCorrection(correctionInfo);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean setSelection(int start, int end) {
return mTarget.setSelection(start, end);
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean performEditorAction(int editorAction) {
return mTarget.performEditorAction(editorAction);
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean performContextMenuAction(int id) {
return mTarget.performContextMenuAction(id);
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean beginBatchEdit() {
return mTarget.beginBatchEdit();
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean endBatchEdit() {
return mTarget.endBatchEdit();
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean sendKeyEvent(KeyEvent event) {
return mTarget.sendKeyEvent(event);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean clearMetaKeyStates(int states) {
return mTarget.clearMetaKeyStates(states);
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean reportFullscreenMode(boolean enabled) {
return mTarget.reportFullscreenMode(enabled);
}
-
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean performPrivateCommand(String action, Bundle data) {
return mTarget.performPrivateCommand(action, data);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public boolean requestCursorUpdates(int cursorUpdateMode) {
return mTarget.requestCursorUpdates(cursorUpdateMode);
}
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException if the target is {@code null}.
+ */
public Handler getHandler() {
return mTarget.getHandler();
}
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 1d242d3..434e3eb 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -117,6 +117,16 @@
Selection.extendSelection(getText(), index);
}
+ /**
+ * Causes words in the text that are longer than the view's width to be ellipsized instead of
+ * broken in the middle. {@link TextUtils.TruncateAt#MARQUEE
+ * TextUtils.TruncateAt#MARQUEE} is not supported.
+ *
+ * @param ellipsis Type of ellipsis to be applied.
+ * @throws IllegalArgumentException When the value of <code>ellipsis</code> parameter is
+ * {@link TextUtils.TruncateAt#MARQUEE}.
+ * @see TextView#setEllipsize(TextUtils.TruncateAt)
+ */
@Override
public void setEllipsize(TextUtils.TruncateAt ellipsis) {
if (ellipsis == TextUtils.TruncateAt.MARQUEE) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f19bf02..18f1ae5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -20,6 +20,7 @@
import android.R;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
+import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
@@ -5835,8 +5836,7 @@
final int layoutDirection = getLayoutDirection();
final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
- if (mEllipsize == TextUtils.TruncateAt.MARQUEE &&
- mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {
+ if (isMarqueeFadeEnabled()) {
if (!mSingleLine && getLineCount() == 1 && canMarquee() &&
(absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) {
final int width = mRight - mLeft;
@@ -7888,7 +7888,7 @@
}
/**
- * Causes words in the text that are longer than the view is wide
+ * Causes words in the text that are longer than the view's width
* to be ellipsized instead of broken in the middle. You may also
* want to {@link #setSingleLine} or {@link #setHorizontallyScrolling}
* to constrain the text to a single line. Use <code>null</code>
@@ -8616,78 +8616,59 @@
@Override
protected float getLeftFadingEdgeStrength() {
- if (mEllipsize == TextUtils.TruncateAt.MARQUEE &&
- mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {
- if (mMarquee != null && !mMarquee.isStopped()) {
- final Marquee marquee = mMarquee;
- if (marquee.shouldDrawLeftFade()) {
- final float scroll = marquee.getScroll();
- return scroll / getHorizontalFadingEdgeLength();
- } else {
- return 0.0f;
- }
- } else if (getLineCount() == 1) {
- final int layoutDirection = getLayoutDirection();
- final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
- switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
- case Gravity.LEFT:
- return 0.0f;
- case Gravity.RIGHT:
- return (mLayout.getLineRight(0) - (mRight - mLeft) -
- getCompoundPaddingLeft() - getCompoundPaddingRight() -
- mLayout.getLineLeft(0)) / getHorizontalFadingEdgeLength();
- case Gravity.CENTER_HORIZONTAL:
- case Gravity.FILL_HORIZONTAL:
- final int textDirection = mLayout.getParagraphDirection(0);
- if (textDirection == Layout.DIR_LEFT_TO_RIGHT) {
- return 0.0f;
- } else {
- return (mLayout.getLineRight(0) - (mRight - mLeft) -
- getCompoundPaddingLeft() - getCompoundPaddingRight() -
- mLayout.getLineLeft(0)) / getHorizontalFadingEdgeLength();
- }
- }
+ if (isMarqueeFadeEnabled() && mMarquee != null && !mMarquee.isStopped()) {
+ final Marquee marquee = mMarquee;
+ if (marquee.shouldDrawLeftFade()) {
+ return getHorizontalFadingEdgeStrength(marquee.getScroll(), 0.0f);
+ } else {
+ return 0.0f;
}
+ } else if (getLineCount() == 1) {
+ final float lineLeft = getLayout().getLineLeft(0);
+ if(lineLeft > mScrollX) return 0.0f;
+ return getHorizontalFadingEdgeStrength(mScrollX, lineLeft);
}
return super.getLeftFadingEdgeStrength();
}
@Override
protected float getRightFadingEdgeStrength() {
- if (mEllipsize == TextUtils.TruncateAt.MARQUEE &&
- mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) {
- if (mMarquee != null && !mMarquee.isStopped()) {
- final Marquee marquee = mMarquee;
- final float maxFadeScroll = marquee.getMaxFadeScroll();
- final float scroll = marquee.getScroll();
- return (maxFadeScroll - scroll) / getHorizontalFadingEdgeLength();
- } else if (getLineCount() == 1) {
- final int layoutDirection = getLayoutDirection();
- final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
- switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
- case Gravity.LEFT:
- final int textWidth = (mRight - mLeft) - getCompoundPaddingLeft() -
- getCompoundPaddingRight();
- final float lineWidth = mLayout.getLineWidth(0);
- return (lineWidth - textWidth) / getHorizontalFadingEdgeLength();
- case Gravity.RIGHT:
- return 0.0f;
- case Gravity.CENTER_HORIZONTAL:
- case Gravity.FILL_HORIZONTAL:
- final int textDirection = mLayout.getParagraphDirection(0);
- if (textDirection == Layout.DIR_RIGHT_TO_LEFT) {
- return 0.0f;
- } else {
- return (mLayout.getLineWidth(0) - ((mRight - mLeft) -
- getCompoundPaddingLeft() - getCompoundPaddingRight())) /
- getHorizontalFadingEdgeLength();
- }
- }
- }
+ if (isMarqueeFadeEnabled() && mMarquee != null && !mMarquee.isStopped()) {
+ final Marquee marquee = mMarquee;
+ return getHorizontalFadingEdgeStrength(marquee.getMaxFadeScroll(), marquee.getScroll());
+ } else if (getLineCount() == 1) {
+ final float rightEdge = mScrollX + (getWidth() - getCompoundPaddingLeft() -
+ getCompoundPaddingRight());
+ final float lineRight = getLayout().getLineRight(0);
+ if(lineRight < rightEdge) return 0.0f;
+ return getHorizontalFadingEdgeStrength(rightEdge, lineRight);
}
return super.getRightFadingEdgeStrength();
}
+ /**
+ * Calculates the fading edge strength as the ratio of the distance between two
+ * horizontal positions to {@link View#getHorizontalFadingEdgeLength()}. Uses the absolute
+ * value for the distance calculation.
+ *
+ * @param position1 A horizontal position.
+ * @param position2 A horizontal position.
+ * @return Fading edge strength between [0.0f, 1.0f].
+ */
+ @FloatRange(from=0.0, to=1.0)
+ private final float getHorizontalFadingEdgeStrength(float position1, float position2) {
+ final int horizontalFadingEdgeLength = getHorizontalFadingEdgeLength();
+ if(horizontalFadingEdgeLength == 0) return 0.0f;
+ final float diff = Math.abs(position1 - position2);
+ if(diff > horizontalFadingEdgeLength) return 1.0f;
+ return diff / horizontalFadingEdgeLength;
+ }
+
+ private final boolean isMarqueeFadeEnabled() {
+ return mEllipsize == TextUtils.TruncateAt.MARQUEE &&
+ mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS;
+ }
+
@Override
protected int computeHorizontalScrollRange() {
if (mLayout != null) {
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 4e48e45..f04bcf2 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -547,23 +547,25 @@
LocaleUtils.filterByLanguage(keyboardSubtypes, sSubtypeToLocale, systemLocales,
applicableSubtypes);
- boolean hasAsciiCapableKeyboard = false;
- final int numApplicationSubtypes = applicableSubtypes.size();
- for (int i = 0; i < numApplicationSubtypes; ++i) {
- final InputMethodSubtype subtype = applicableSubtypes.get(i);
- if (subtype.containsExtraValueKey(TAG_ASCII_CAPABLE)) {
- hasAsciiCapableKeyboard = true;
- break;
+ if (!applicableSubtypes.isEmpty()) {
+ boolean hasAsciiCapableKeyboard = false;
+ final int numApplicationSubtypes = applicableSubtypes.size();
+ for (int i = 0; i < numApplicationSubtypes; ++i) {
+ final InputMethodSubtype subtype = applicableSubtypes.get(i);
+ if (subtype.containsExtraValueKey(TAG_ASCII_CAPABLE)) {
+ hasAsciiCapableKeyboard = true;
+ break;
+ }
}
- }
- if (!hasAsciiCapableKeyboard) {
- final int numKeyboardSubtypes = keyboardSubtypes.size();
- for (int i = 0; i < numKeyboardSubtypes; ++i) {
- final InputMethodSubtype subtype = keyboardSubtypes.get(i);
- final String mode = subtype.getMode();
- if (SUBTYPE_MODE_KEYBOARD.equals(mode) && subtype.containsExtraValueKey(
- TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE)) {
- applicableSubtypes.add(subtype);
+ if (!hasAsciiCapableKeyboard) {
+ final int numKeyboardSubtypes = keyboardSubtypes.size();
+ for (int i = 0; i < numKeyboardSubtypes; ++i) {
+ final InputMethodSubtype subtype = keyboardSubtypes.get(i);
+ final String mode = subtype.getMode();
+ if (SUBTYPE_MODE_KEYBOARD.equals(mode) && subtype.containsExtraValueKey(
+ TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE)) {
+ applicableSubtypes.add(subtype);
+ }
}
}
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index eb509c2..3abea26 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -499,11 +499,11 @@
try {
for (String classPathElement : classPathElements) {
+ // System server is fully AOTed and never profiled
+ // for profile guided compilation.
final int dexoptNeeded = DexFile.getDexOptNeeded(
- classPathElement, "*", instructionSet, false /* defer */);
+ classPathElement, instructionSet, DexFile.COMPILATION_TYPE_FULL);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
- // System server is fully AOTed and never profiled
- // for profile guided compilation.
installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
dexoptNeeded, 0 /*dexFlags*/, null /*volumeUuid*/,
false /*useProfiles*/);
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index ed3fe42..816a2c4 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -190,7 +190,6 @@
$(call include-path-for, bluedroid) \
$(call include-path-for, libhardware)/hardware \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
- $(TOP)/frameworks/av/include \
$(TOP)/frameworks/base/media/jni \
$(TOP)/system/core/base/include \
$(TOP)/system/core/include \
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 7930027..afccfcf 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -33,9 +33,9 @@
#include "core_jni_helpers.h"
#include "android_runtime/android_hardware_camera2_CameraMetadata.h"
+#include <android/hardware/ICameraService.h>
#include <binder/IServiceManager.h>
#include <camera/CameraMetadata.h>
-#include <camera/ICameraService.h>
#include <camera/VendorTagDescriptor.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/ScopedPrimitiveArray.h>
@@ -906,32 +906,36 @@
static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz) {
const String16 NAME("media.camera");
- sp<ICameraService> cameraService;
+ sp<hardware::ICameraService> cameraService;
status_t err = getService(NAME, /*out*/&cameraService);
if (err != OK) {
ALOGE("%s: Failed to get camera service, received error %s (%d)", __FUNCTION__,
strerror(-err), err);
- return err;
+ return hardware::ICameraService::ERROR_DISCONNECTED;
}
- sp<VendorTagDescriptor> desc;
- err = cameraService->getCameraVendorTagDescriptor(/*out*/desc);
+ sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
+ binder::Status res = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
- if (err == -EOPNOTSUPP) {
+ if (res.serviceSpecificErrorCode() == hardware::ICameraService::ERROR_DEPRECATED_HAL) {
ALOGW("%s: Camera HAL too old; does not support vendor tags", __FUNCTION__);
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
return OK;
- } else if (err != OK) {
- ALOGE("%s: Failed to setup vendor tag descriptors, received error %s (%d)",
- __FUNCTION__, strerror(-err), err);
- return err;
+ } else if (!res.isOk()) {
+ ALOGE("%s: Failed to setup vendor tag descriptors: %s: %s",
+ __FUNCTION__, res.serviceSpecificErrorCode(),
+ res.toString8().string());
+ return res.serviceSpecificErrorCode();
}
err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
- return err;
+ if (err != OK) {
+ return hardware::ICameraService::ERROR_INVALID_OPERATION;
+ }
+ return OK;
}
} // extern "C"
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index defb88a..880a79c 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -26,10 +26,13 @@
#include <net/if.h>
#include <linux/filter.h>
#include <linux/if.h>
+#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/if_ether.h>
+#include <netinet/icmp6.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <netinet/udp.h>
#include <cutils/properties.h>
@@ -64,10 +67,9 @@
static void android_net_utils_attachDhcpFilter(JNIEnv *env, jobject clazz, jobject javaFd)
{
- int fd = jniGetFDFromFileDescriptor(env, javaFd);
uint32_t ip_offset = sizeof(ether_header);
uint32_t proto_offset = ip_offset + offsetof(iphdr, protocol);
- uint32_t flags_offset = ip_offset + offsetof(iphdr, frag_off);
+ uint32_t flags_offset = ip_offset + offsetof(iphdr, frag_off);
uint32_t dport_indirect_offset = ip_offset + offsetof(udphdr, dest);
struct sock_filter filter_code[] = {
// Check the protocol is UDP.
@@ -94,6 +96,45 @@
filter_code,
};
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
+ jniThrowExceptionFmt(env, "java/net/SocketException",
+ "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
+ }
+}
+
+static void android_net_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobject javaFd,
+ jint hardwareAddressType)
+{
+ if (hardwareAddressType != ARPHRD_ETHER) {
+ jniThrowExceptionFmt(env, "java/net/SocketException",
+ "attachRaFilter only supports ARPHRD_ETHER");
+ return;
+ }
+
+ uint32_t ipv6_offset = sizeof(ether_header);
+ uint32_t ipv6_next_header_offset = ipv6_offset + offsetof(ip6_hdr, ip6_nxt);
+ uint32_t icmp6_offset = ipv6_offset + sizeof(ip6_hdr);
+ uint32_t icmp6_type_offset = icmp6_offset + offsetof(icmp6_hdr, icmp6_type);
+ struct sock_filter filter_code[] = {
+ // Check IPv6 Next Header is ICMPv6.
+ BPF_STMT(BPF_LD | BPF_B | BPF_ABS, ipv6_next_header_offset),
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, IPPROTO_ICMPV6, 0, 3),
+
+ // Check ICMPv6 type is Router Advertisement.
+ BPF_STMT(BPF_LD | BPF_B | BPF_ABS, icmp6_type_offset),
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ND_ROUTER_ADVERT, 0, 1),
+
+ // Accept or reject.
+ BPF_STMT(BPF_RET | BPF_K, 0xffff),
+ BPF_STMT(BPF_RET | BPF_K, 0)
+ };
+ struct sock_fprog filter = {
+ sizeof(filter_code) / sizeof(filter_code[0]),
+ filter_code,
+ };
+
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
jniThrowExceptionFmt(env, "java/net/SocketException",
"setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
@@ -148,6 +189,7 @@
{ "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
{ "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
{ "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
+ { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachRaFilter },
};
int register_android_net_NetworkUtils(JNIEnv* env)
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index cf68449..b7701d6 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -411,22 +411,27 @@
return 0;
}
+ android::view::Surface surfaceShim;
+
+ // Calling code in Surface.java has already read the name of the Surface
+ // from the Parcel
+ surfaceShim.readFromParcel(parcel, /*nameAlreadyRead*/true);
+
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
- sp<IBinder> binder(parcel->readStrongBinder());
// update the Surface only if the underlying IGraphicBufferProducer
// has changed.
- if (self != NULL
- && (IInterface::asBinder(self->getIGraphicBufferProducer()) == binder)) {
+ if (self != nullptr
+ && (IInterface::asBinder(self->getIGraphicBufferProducer()) ==
+ IInterface::asBinder(surfaceShim.graphicBufferProducer))) {
// same IGraphicBufferProducer, return ourselves
return jlong(self.get());
}
sp<Surface> sur;
- sp<IGraphicBufferProducer> gbp(interface_cast<IGraphicBufferProducer>(binder));
- if (gbp != NULL) {
+ if (surfaceShim.graphicBufferProducer != nullptr) {
// we have a new IGraphicBufferProducer, create a new Surface for it
- sur = new Surface(gbp, true);
+ sur = new Surface(surfaceShim.graphicBufferProducer, true);
// and keep a reference before passing to java
sur->incStrong(&sRefBaseOwner);
}
@@ -447,7 +452,13 @@
return;
}
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
- parcel->writeStrongBinder( self != 0 ? IInterface::asBinder(self->getIGraphicBufferProducer()) : NULL);
+ android::view::Surface surfaceShim;
+ if (self != nullptr) {
+ surfaceShim.graphicBufferProducer = self->getIGraphicBufferProducer();
+ }
+ // Calling code in Surface.java has already written the name of the Surface
+ // to the Parcel
+ surfaceShim.writeToParcel(parcel, /*nameAlreadyWritten*/true);
}
static jint nativeGetWidth(JNIEnv* env, jclass clazz, jlong nativeObject) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 1dfe40a..c838d03 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -110,6 +110,13 @@
ctrl->decStrong((void *)nativeCreate);
}
+static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ if (ctrl != NULL) {
+ ctrl->disconnect();
+ }
+}
+
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
@@ -595,6 +602,8 @@
(void*)nativeRelease },
{"nativeDestroy", "(J)V",
(void*)nativeDestroy },
+ {"nativeDisconnect", "(J)V",
+ (void*)nativeDisconnect },
{"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
(void*)nativeScreenshotBitmap },
{"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 588e738..8f85d4a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -87,6 +87,7 @@
<protected-broadcast android:name="android.os.action.DEVICE_IDLE_MODE_CHANGED" />
<protected-broadcast android:name="android.os.action.POWER_SAVE_WHITELIST_CHANGED" />
<protected-broadcast android:name="android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED" />
+ <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED_INTERNAL" />
<protected-broadcast android:name="android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED" />
@@ -265,6 +266,7 @@
<protected-broadcast android:name="com.android.server.WifiManager.action.START_SCAN" />
<protected-broadcast android:name="com.android.server.WifiManager.action.START_PNO" />
<protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
+ <protected-broadcast android:name="com.android.server.WifiManager.action.DEVICE_IDLE" />
<protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" />
<protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" />
<protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
@@ -374,7 +376,10 @@
<protected-broadcast android:name="android.app.action.ACTION_PASSWORD_FAILED" />
<protected-broadcast android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED" />
<protected-broadcast android:name="com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION" />
+
<protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_ADDED" />
+ <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNLOCKED" />
+ <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_REMOVED" />
<protected-broadcast android:name="android.bluetooth.adapter.action.BLE_STATE_CHANGED" />
<protected-broadcast android:name="android.content.jobscheduler.JOB_DELAY_EXPIRED" />
@@ -432,7 +437,6 @@
<protected-broadcast android:name="android.intent.action.DYNAMIC_SENSOR_CHANGED" />
<protected-broadcast android:name="android.intent.action.ACTION_RADIO_OFF" />
- <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNLOCKED" />
<protected-broadcast android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
<protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
@@ -450,6 +454,10 @@
<protected-broadcast android:name="android.intent.action.TWILIGHT_CHANGED" />
+ <protected-broadcast android:name="com.android.server.fingerprint.ACTION_LOCKOUT_RESET" />
+ <protected-broadcast android:name="android.net.wifi.PASSPOINT_ICON_RECEIVED" />
+ <protected-broadcast android:name="com.android.server.notification.CountdownConditionProvider" />
+
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
<!-- ====================================================================== -->
diff --git a/core/res/res/drawable-nodpi/default_wallpaper.png b/core/res/res/drawable-nodpi/default_wallpaper.png
index 91ad252..e9c4d5c 100644
--- a/core/res/res/drawable-nodpi/default_wallpaper.png
+++ b/core/res/res/drawable-nodpi/default_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png b/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
index af8e251..9f3efa5 100644
--- a/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
+++ b/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png b/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
index cb00d82..8199e70 100644
--- a/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
+++ b/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
Binary files differ
diff --git a/core/res/res/drawable/work_widget_mask_view_background.xml b/core/res/res/drawable/work_widget_mask_view_background.xml
deleted file mode 100644
index 17f0dbc..0000000
--- a/core/res/res/drawable/work_widget_mask_view_background.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2015 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.
--->
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
- <padding android:left="5dp" android:right="5dp" android:top="5dp" android:bottom="5dp"/>
- <stroke android:width="1dp" android:color="#CCCCCC" />
- </shape>
diff --git a/core/res/res/layout/work_widget_mask_view.xml b/core/res/res/layout/work_widget_mask_view.xml
index ce86ddc..3c47705 100644
--- a/core/res/res/layout/work_widget_mask_view.xml
+++ b/core/res/res/layout/work_widget_mask_view.xml
@@ -15,20 +15,24 @@
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/work_widget_mask_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="#F3374248" >
+ android:background="#F3374248"
+ android:clickable="true" >
<ImageView android:id="@+id/work_widget_app_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"/>
+ android:layout_gravity="center"
+ android:clickable="false" />
- <ImageView
+ <ImageView android:id="@+id/work_widget_badge_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="4dp"
android:layout_marginRight="4dp"
- android:src="@drawable/ic_corp_badge_off" />
+ android:src="@drawable/ic_corp_badge_off"
+ android:clickable="false" />
</FrameLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b65f19b..9a2a6eb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -443,6 +443,9 @@
<!-- Boolean indicating whether or not wifi firmware debugging is enabled -->
<bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">true</bool>
+ <!-- Integer size limit, in KB, for a single WifiLogger ringbuffer -->
+ <integer translatable="false" name="config_wifi_logger_ring_buffer_size_limit_kb">32</integer>
+
<!-- Boolean indicating whether or not wifi should turn off when emergency call is made -->
<bool translatable="false" name="config_wifi_turn_off_during_emergency_call">false</bool>
@@ -2479,4 +2482,8 @@
handle wallpaper cropping.
-->
<string name="config_wallpaperCropperPackage" translatable="false">com.android.wallpapercropper</string>
+
+ <!-- True if the device supports at least one form of multi-window.
+ E.g. freeform, split-screen, picture-in-picture. -->
+ <bool name="config_supportsMultiWindow">true</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 44a7a8d..11f42ec 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -298,11 +298,13 @@
<java-symbol type="bool" name="config_wifi_enable_5GHz_preference" />
<java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
<java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
+ <java-symbol type="integer" name="config_wifi_logger_ring_buffer_size_limit_kb" />
<java-symbol type="bool" name="config_wifi_turn_off_during_emergency_call" />
<java-symbol type="bool" name="config_supportMicNearUltrasound" />
<java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
<java-symbol type="bool" name="config_supportAudioSourceUnprocessed" />
<java-symbol type="bool" name="config_freeformWindowManagement" />
+ <java-symbol type="bool" name="config_supportsMultiWindow" />
<java-symbol type="bool" name="config_guestUserEphemeral" />
<java-symbol type="string" name="config_defaultPictureInPictureBounds" />
<java-symbol type="string" name="config_centeredPictureInPictureBounds" />
@@ -2431,8 +2433,9 @@
<java-symbol type="string" name="importance_from_person" />
<java-symbol type="layout" name="work_widget_mask_view" />
+ <java-symbol type="id" name="work_widget_mask_frame" />
<java-symbol type="id" name="work_widget_app_icon" />
- <java-symbol type="drawable" name="work_widget_mask_view_background" />
+ <java-symbol type="id" name="work_widget_badge_icon" />
<java-symbol type="id" name="aerr_report" />
<java-symbol type="id" name="aerr_reset" />
diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml
index 8bf635e..478d66c 100644
--- a/core/res/res/values/themes_micro.xml
+++ b/core/res/res/values/themes_micro.xml
@@ -24,7 +24,6 @@
<item name="windowBackground">@color/black</item>
<item name="windowContentOverlay">@null</item>
<item name="windowIsFloating">false</item>
- <item name="windowSwipeToDismiss">true</item>
<!-- Required to force windowInsets dispatch through application UI. -->
<item name="windowOverscan">true</item>
</style>
@@ -42,7 +41,6 @@
<item name="windowBackground">@color/white</item>
<item name="windowContentOverlay">@null</item>
<item name="windowIsFloating">false</item>
- <item name="windowSwipeToDismiss">true</item>
<!-- Required to force windowInsets dispatch through application UI. -->
<item name="windowOverscan">true</item>
</style>
diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
new file mode 100644
index 0000000..da17045
--- /dev/null
+++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.method;
+
+import android.app.Activity;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.text.InputType;
+import android.text.method.BaseKeyListener;
+import android.text.method.KeyListenerTestCase;
+import android.view.KeyEvent;
+import android.widget.EditText;
+import android.widget.TextView.BufferType;
+
+/**
+ * Test forward delete key handling of {@link android.text.method.BaseKeyListener}.
+ *
+ * TODO: Move some of test cases to the CTS.
+ */
+public class ForwardDeleteTest extends KeyListenerTestCase {
+ private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
+ public int getInputType() {
+ return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
+ }
+ };
+
+ // Sync the state to the TextView and call onKeyDown with KEYCODE_FORWARD_DEL key event.
+ // Then update the state to the result of TextView.
+ private void forwardDelete(final EditorState state, int modifiers) {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mTextView.setText(state.mText, BufferType.EDITABLE);
+ mTextView.setKeyListener(mKeyListener);
+ mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ assertTrue(mTextView.hasWindowFocus());
+
+ final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_FORWARD_DEL, modifiers);
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ state.mText = mTextView.getText();
+ state.mSelectionStart = mTextView.getSelectionStart();
+ state.mSelectionEnd = mTextView.getSelectionEnd();
+ }
+
+ @SmallTest
+ public void testSurrogatePairs() {
+ EditorState state = new EditorState();
+
+ // U+1F441 is EYE
+ state.setByString("| U+1F441");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // U+1F5E8 is LEFT SPEECH BUBBLE
+ state.setByString("| U+1F441 U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // TODO: introduce edge cases.
+ }
+
+ @SmallTest
+ public void testReplacementSpan() {
+ EditorState state = new EditorState();
+
+ state.setByString("| 'abc' ( 'de' ) 'fg'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'bc' ( 'de' ) 'fg'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'c' ( 'de' ) 'fg'");
+ forwardDelete(state, 0);
+ state.assertEquals("| ( 'de' ) 'fg'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'fg'");
+ forwardDelete(state, 0);
+ state.assertEquals("| 'g'");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("'abc' [ ( 'de' ) ] 'fg'");
+ forwardDelete(state, 0);
+ state.assertEquals("'abc' | 'fg'");
+ forwardDelete(state, 0);
+ state.assertEquals("'abc' | 'g'");
+ forwardDelete(state, 0);
+ state.assertEquals("'abc' |");
+ forwardDelete(state, 0);
+ state.assertEquals("'abc' |");
+
+ state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'");
+ forwardDelete(state, 0);
+ state.assertEquals("'ab' | 'g'");
+ forwardDelete(state, 0);
+ state.assertEquals("'ab' |");
+ forwardDelete(state, 0);
+ state.assertEquals("'ab' |");
+
+ // TODO: introduce edge cases.
+ }
+
+ @SmallTest
+ public void testCombiningEnclosingKeycaps() {
+ EditorState state = new EditorState();
+
+ // U+20E3 is COMBINING ENCLOSING KEYCAP.
+ state.setByString("| '1' U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Edge cases
+ // multiple COMBINING ENCLOSING KEYCAP
+ state.setByString("| '1' U+20E3 U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Isolated COMBINING ENCLOSING KEYCAP
+ state.setByString("| U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Isolated multiple COMBINING ENCLOSING KEYCAP
+ state.setByString("| U+20E3 U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+ }
+
+ @SmallTest
+ public void testVariationSelector() {
+ EditorState state = new EditorState();
+
+ // U+FE0F is VARIATION SELECTOR-16.
+ state.setByString("| '#' U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // U+E0100 is VARIATION SELECTOR-17.
+ state.setByString("| U+845B U+E0100");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Edge cases
+ // Isolated variation selectors
+ state.setByString("| U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+E0100");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Isolated multiple variation selectors
+ state.setByString("| U+FE0F U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+FE0F U+E0100");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+E0100 U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+E0100 U+E0100");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Multiple variation selectors
+ state.setByString("| '#' U+FE0F U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| '#' U+FE0F U+E0100");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+845B U+E0100 U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+845B U+E0100 U+E0100");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+ }
+
+ @SmallTest
+ public void testEmojiZeroWidthJoinerSequence() {
+ EditorState state = new EditorState();
+
+ // U+200D is ZERO WIDTH JOINER.
+ state.setByString("| U+1F441 U+200D U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Edge cases
+ // End with ZERO WIDTH JOINER
+ state.setByString("| U+1F441 U+200D");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Start with ZERO WIDTH JOINER
+ state.setByString("| U+200D U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Multiple ZERO WIDTH JOINER
+ state.setByString("| U+1F441 U+200D U+200D U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Isolated ZERO WIDTH JOINER
+ state.setByString("| U+200D");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Isolated multiple ZERO WIDTH JOINER
+ state.setByString("| U+200D U+200D");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+ }
+
+ @SmallTest
+ public void testFlags() {
+ EditorState state = new EditorState();
+
+ // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U.
+ // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S.
+ state.setByString("| U+1F1FA U+1F1F8");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ state.setByString("| U+1F1FA U+1F1F8 U+1F1FA U+1F1F8");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA U+1F1F8");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Edge cases
+ // Isolated regional indicator symbol
+ state.setByString("| U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Odd numbered regional indicator symbols
+ state.setByString("| U+1F1FA U+1F1F8 U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+ }
+
+ @SmallTest
+ public void testEmojiModifier() {
+ EditorState state = new EditorState();
+
+ // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
+ state.setByString("| U+1F466 U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Edge cases
+ // Isolated emoji modifier
+ state.setByString("| U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Isolated multiple emoji modifier
+ state.setByString("| U+1F3FB U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Multiple emoji modifiers
+ state.setByString("| U+1F466 U+1F3FB U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+ }
+
+ @SmallTest
+ public void testMixedEdgeCases() {
+ EditorState state = new EditorState();
+
+ // COMBINING ENCLOSING KEYCAP + variation selector
+ state.setByString("| '1' U+20E3 U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Variation selector + COMBINING ENCLOSING KEYCAP
+ state.setByString("| U+2665 U+FE0F U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // COMBINING ENCLOSING KEYCAP + ending with ZERO WIDTH JOINER
+ state.setByString("| '1' U+20E3 U+200D");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // COMBINING ENCLOSING KEYCAP + ZERO WIDTH JOINER
+ state.setByString("| '1' U+20E3 U+200D U+1F5E8");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F5E8 ");
+
+ // Start with ZERO WIDTH JOINER + COMBINING ENCLOSING KEYCAP
+ state.setByString("| U+200D U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // ZERO WIDTH JOINER + COMBINING ENCLOSING KEYCAP
+ state.setByString("| U+1F441 U+200D U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // COMBINING ENCLOSING KEYCAP + regional indicator symbol
+ state.setByString("| '1' U+20E3 U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Regional indicator symbol + COMBINING ENCLOSING KEYCAP
+ state.setByString("| U+1F1FA U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // COMBINING ENCLOSING KEYCAP + emoji modifier
+ state.setByString("| '1' U+20E3 U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3FB");
+
+ // Emoji modifier + COMBINING ENCLOSING KEYCAP
+ state.setByString("| U+1F466 U+1F3FB U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Variation selector + end with ZERO WIDTH JOINER
+ state.setByString("| U+2665 U+FE0F U+200D");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Variation selector + ZERO WIDTH JOINER
+ state.setByString("| U+1F469 U+200D U+2764 U+FE0F U+200D U+1F469");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Start with ZERO WIDTH JOINER + variation selector
+ state.setByString("| U+200D U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // ZERO WIDTH JOINER + variation selector
+ state.setByString("| U+1F469 U+200D U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Variation selector + regional indicator symbol
+ state.setByString("| U+2665 U+FE0F U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Regional indicator symbol + variation selector
+ state.setByString("| U+1F1FA U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Variation selector + emoji modifier
+ state.setByString("| U+2665 U+FE0F U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3FB");
+
+ // Emoji modifier + variation selector
+ state.setByString("| U+1F466 U+1F3FB U+FE0F");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Start with ZERO WIDTH JOINER + regional indicator symbol
+ state.setByString("| U+200D U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // ZERO WIDTH JOINER + regional indicator symbol
+ state.setByString("| U+1F469 U+200D U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA");
+
+ // Regional indicator symbol + end with ZERO WIDTH JOINER
+ state.setByString("| U+1F1FA U+200D");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Regional indicator symbol + ZERO WIDTH JOINER
+ state.setByString("| U+1F1FA U+200D U+1F469");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F469");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Start with ZERO WIDTH JOINER + emoji modifier
+ state.setByString("| U+200D U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3FB");
+
+ // ZERO WIDTH JOINER + emoji modifier
+ state.setByString("| U+1F469 U+200D U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3FB");
+
+ // Emoji modifier + end with ZERO WIDTH JOINER
+ state.setByString("| U+1F466 U+1F3FB U+200D");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Emoji modifier + ZERO WIDTH JOINER
+ state.setByString("| U+1F466 U+1F3FB U+200D U+1F469");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F469");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Regional indicator symbol + emoji modifier
+ state.setByString("| U+1F1FA U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F3FB");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+
+ // Emoji modifier + regional indicator symbol
+ state.setByString("| U+1F466 U+1F3FB U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
+ }
+}
diff --git a/core/tests/coretests/src/android/util/PatternsTest.java b/core/tests/coretests/src/android/util/PatternsTest.java
index d383775..348f8fd 100644
--- a/core/tests/coretests/src/android/util/PatternsTest.java
+++ b/core/tests/coretests/src/android/util/PatternsTest.java
@@ -25,7 +25,7 @@
public class PatternsTest extends TestCase {
- //Tests for Patterns.TOP_LEVEL_DOMAIN
+ // Tests for Patterns.TOP_LEVEL_DOMAIN
@SmallTest
public void testTldPattern() throws Exception {
@@ -56,7 +56,7 @@
assertFalse("Matched invalid TLD!", t);
}
- //Tests for Patterns.IANA_TOP_LEVEL_DOMAINS
+ // Tests for Patterns.IANA_TOP_LEVEL_DOMAINS
@SmallTest
public void testIanaTopLevelDomains_matchesValidTld() throws Exception {
@@ -94,7 +94,7 @@
assertFalse("Should not match invalid Punycode TLD", pattern.matcher("xn").matches());
}
- //Tests for Patterns.WEB_URL
+ // Tests for Patterns.WEB_URL
@SmallTest
public void testWebUrl_matchesValidUrlWithSchemeAndHostname() throws Exception {
@@ -208,7 +208,7 @@
Patterns.WEB_URL.matcher(url).matches());
}
- //Tests for Patterns.AUTOLINK_WEB_URL
+ // Tests for Patterns.AUTOLINK_WEB_URL
@SmallTest
public void testAutoLinkWebUrl_matchesValidUrlWithSchemeAndHostname() throws Exception {
@@ -419,7 +419,7 @@
Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
}
- //Tests for Patterns.IP_ADDRESS
+ // Tests for Patterns.IP_ADDRESS
@SmallTest
public void testIpPattern() throws Exception {
@@ -432,7 +432,7 @@
assertFalse("Invalid IP", t);
}
- //Tests for Patterns.DOMAIN_NAME
+ // Tests for Patterns.DOMAIN_NAME
@SmallTest
public void testDomain_matchesPunycodeTld() throws Exception {
@@ -508,7 +508,227 @@
Patterns.DOMAIN_NAME.matcher(domain).matches());
}
- //Tests for Patterns.PHONE
+ // Tests for Patterns.AUTOLINK_EMAIL_ADDRESS
+
+ public void testAutoLinkEmailAddress_matchesShortValidEmail() throws Exception {
+ String email = "a@a.co";
+ assertTrue("Should match short valid email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesRegularEmail() throws Exception {
+ String email = "email@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesEmailWithMultipleSubdomains() throws Exception {
+ String email = "email@e.somelongdomainnameforandroid.abc.uk";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithDot() throws Exception {
+ String email = "e.mail@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithPlus() throws Exception {
+ String email = "e+mail@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithUnderscore() throws Exception {
+ String email = "e_mail@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithDash() throws Exception {
+ String email = "e-mail@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithApostrophe() throws Exception {
+ String email = "e'mail@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithDigits() throws Exception {
+ String email = "123@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesUnicodeLocalPart() throws Exception {
+ String email = "\uD604\uAE08\uC601\uC218\uC99D@android.kr";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithEmoji() throws Exception {
+ String email = "smiley\u263A@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartWithSurrogatePairs() throws Exception {
+ String email = "\uD83C\uDF38@android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesDomainWithDash() throws Exception {
+ String email = "email@an-droid.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesUnicodeDomain() throws Exception {
+ String email = "email@\uD604\uAE08\uC601\uC218\uC99D.kr";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesUnicodeLocalPartAndDomain() throws Exception {
+ String email = "\uD604\uAE08\uC601\uC218\uC99D@\uD604\uAE08\uC601\uC218\uC99D.kr";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesDomainWithEmoji() throws Exception {
+ String email = "smiley@\u263Aandroid.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesDomainWithSurrogatePairs() throws Exception {
+ String email = "email@\uD83C\uDF38android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartAndDomainWithSurrogatePairs()
+ throws Exception {
+ String email = "\uD83C\uDF38@\uD83C\uDF38android.com";
+ assertTrue("Should match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchStringWithoutAtSign() throws Exception {
+ String email = "android.com";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchPlainString() throws Exception {
+ String email = "email";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchStringWithMultipleAtSigns() throws Exception {
+ String email = "email@android@android.com";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchEmailWithoutTld() throws Exception {
+ String email = "email@android";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchLocalPartEndingWithDot() throws Exception {
+ String email = "email.@android.com";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchLocalPartStartingWithDot() throws Exception {
+ String email = ".email@android.com";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchDomainStartingWithDash() throws Exception {
+ String email = "email@-android.com";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchDomainWithConsecutiveDots() throws Exception {
+ String email = "email@android..com";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchEmailWithIpAsDomain() throws Exception {
+ String email = "email@127.0.0.1";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_doesNotMatchEmailWithInvalidTld() throws Exception {
+ String email = "email@android.c";
+ assertFalse("Should not match email: " + email,
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesLocalPartUpTo64Chars() throws Exception {
+ String localPart = "";
+ for (int i = 0; i < 64; i++) {
+ localPart += "a";
+ }
+ String email = localPart + "@android.com";
+
+ assertTrue("Should match local part of length: " + localPart.length(),
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+
+ email = localPart + "a@android.com";
+ assertFalse("Should not match local part of length: " + localPart.length(),
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesSubdomainUpTo63Chars() throws Exception {
+ String subdomain = "";
+ for (int i = 0; i < 63; i++) {
+ subdomain += "a";
+ }
+ String email = "email@" + subdomain + ".com";
+
+ assertTrue("Should match subdomain of length: " + subdomain.length(),
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+
+ subdomain += "a";
+ email = "email@" + subdomain + ".com";
+ assertFalse("Should not match local part of length: " + subdomain.length(),
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ public void testAutoLinkEmailAddress_matchesDomainUpTo255Chars() throws Exception {
+ String longDomain = "";
+ while (longDomain.length() <= 250) {
+ longDomain += "d.";
+ }
+ longDomain += "com";
+ assertEquals(255, longDomain.length());
+ String email = "a@" + longDomain;
+
+ assertTrue("Should match domain of length: " + longDomain.length(),
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+
+ email = email + "m";
+ assertEquals(258, email.length());
+ assertFalse("Should not match domain of length: " + longDomain.length(),
+ Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
+ }
+
+ // Tests for Patterns.PHONE
@SmallTest
public void testPhonePattern() throws Exception {
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
index ac020e4..719b274 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
@@ -70,6 +70,7 @@
private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_MODE_VOICE = "voice";
+ private static final String SUBTYPE_MODE_HANDWRITING = "handwriting";
private static final String SUBTYPE_MODE_ANY = null;
private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
private static final String EXTRA_VALUE_ASCII_CAPABLE = "AsciiCapable";
@@ -215,6 +216,12 @@
final InputMethodSubtype nonAutoJa = createDummyInputMethodSubtype("ja",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
!IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
+ final InputMethodSubtype nonAutoHi = createDummyInputMethodSubtype("hi",
+ SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
+ !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
+ final InputMethodSubtype nonAutoHandwritingEn = createDummyInputMethodSubtype("en",
+ SUBTYPE_MODE_HANDWRITING, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
+ !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype =
createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
@@ -349,6 +356,57 @@
verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2, result.get(2));
}
+ // Make sure that if there is no subtype that matches the language requested, then we just
+ // use the first keyboard subtype.
+ {
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
+ subtypes.add(nonAutoHi);
+ subtypes.add(nonAutoEnUS);
+ subtypes.add(nonAutoHandwritingEn);
+ subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
+ final InputMethodInfo imi = createDummyInputMethodInfo(
+ "com.android.apps.inputmethod.latin",
+ "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ subtypes);
+ final ArrayList<InputMethodSubtype> result =
+ InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+ getResourcesForLocales(LOCALE_JA_JP), imi);
+ assertEquals(1, result.size());
+ verifyEquality(nonAutoHi, result.get(0));
+ }
+ {
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
+ subtypes.add(nonAutoEnUS);
+ subtypes.add(nonAutoHi);
+ subtypes.add(nonAutoHandwritingEn);
+ subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
+ final InputMethodInfo imi = createDummyInputMethodInfo(
+ "com.android.apps.inputmethod.latin",
+ "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ subtypes);
+ final ArrayList<InputMethodSubtype> result =
+ InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+ getResourcesForLocales(LOCALE_JA_JP), imi);
+ assertEquals(1, result.size());
+ verifyEquality(nonAutoEnUS, result.get(0));
+ }
+ {
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
+ subtypes.add(nonAutoHandwritingEn);
+ subtypes.add(nonAutoEnUS);
+ subtypes.add(nonAutoHi);
+ subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
+ final InputMethodInfo imi = createDummyInputMethodInfo(
+ "com.android.apps.inputmethod.latin",
+ "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ subtypes);
+ final ArrayList<InputMethodSubtype> result =
+ InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+ getResourcesForLocales(LOCALE_JA_JP), imi);
+ assertEquals(1, result.size());
+ verifyEquality(nonAutoEnUS, result.get(0));
+ }
+
// Make sure that 3-letter language code can be handled.
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
diff --git a/data/keyboards/qwerty2.kcm b/data/keyboards/qwerty2.kcm
index d96914f..b981d83 100644
--- a/data/keyboards/qwerty2.kcm
+++ b/data/keyboards/qwerty2.kcm
@@ -23,8 +23,8 @@
number: '2'
base: 'a'
shift, capslock: 'A'
- alt: 'a'
- shift+alt, capslock+alt: 'A'
+ alt: '\u00e1'
+ shift+alt, capslock+alt: '\u00c1'
}
key B {
@@ -41,8 +41,8 @@
number: '2'
base: 'c'
shift, capslock: 'C'
- alt: '\u00e7'
- shift+alt, capslock+alt: '\u00e7'
+ alt: '\u00a9'
+ shift+alt, capslock+alt: '\u00a2'
}
key D {
@@ -50,8 +50,8 @@
number: '3'
base: 'd'
shift, capslock: 'D'
- alt: '\''
- shift+alt, capslock+alt: '\''
+ alt: '\u00f0'
+ shift+alt, capslock+alt: '\u00d0'
}
key E {
@@ -59,8 +59,8 @@
number: '3'
base: 'e'
shift, capslock: 'E'
- alt: '"'
- shift+alt, capslock+alt: '\u0301'
+ alt: '\u00e9'
+ shift+alt, capslock+alt: '\u00c9'
}
key F {
@@ -95,8 +95,8 @@
number: '4'
base: 'i'
shift, capslock: 'I'
- alt: '-'
- shift+alt, capslock+alt: '\u0302'
+ alt: '\u00ed'
+ shift+alt, capslock+alt: '\u00cd'
}
key J {
@@ -122,8 +122,8 @@
number: '5'
base: 'l'
shift, capslock: 'L'
- alt: ':'
- shift+alt, capslock+alt: '`'
+ alt: '\u00f8'
+ shift+alt, capslock+alt: '\u00d8'
}
key M {
@@ -131,7 +131,7 @@
number: '6'
base: 'm'
shift, capslock: 'M'
- alt: '%'
+ alt: '\u00b5'
shift+alt, capslock+alt: none
}
@@ -140,8 +140,8 @@
number: '6'
base: 'n'
shift, capslock: 'N'
- alt: none
- shift+alt, capslock+alt: '\u0303'
+ alt: '\u00f1'
+ shift+alt, capslock+alt: '\u00d1'
}
key O {
@@ -149,8 +149,8 @@
number: '6'
base: 'o'
shift, capslock: 'O'
- alt: '+'
- shift+alt, capslock+alt: '+'
+ alt: '\u00f3'
+ shift+alt, capslock+alt: '\u00d3'
}
key P {
@@ -158,8 +158,8 @@
number: '7'
base: 'p'
shift, capslock: 'P'
- alt: '='
- shift+alt, capslock+alt: '\u00a5'
+ alt: '\u00f6'
+ shift+alt, capslock+alt: '\u00d6'
}
key Q {
@@ -167,8 +167,8 @@
number: '7'
base: 'q'
shift, capslock: 'Q'
- alt: '|'
- shift+alt, capslock+alt: '\u0300'
+ alt: '\u00e4'
+ shift+alt, capslock+alt: '\u00c4'
}
key R {
@@ -176,8 +176,8 @@
number: '7'
base: 'r'
shift, capslock: 'R'
- alt: '`'
- shift+alt, capslock+alt: '\u20ac'
+ alt: '\u00ae'
+ shift+alt, capslock+alt: 'R'
}
key S {
@@ -185,8 +185,8 @@
number: '7'
base: 's'
shift, capslock: 'S'
- alt: '\\'
- shift+alt, capslock+alt: '\u00df'
+ alt: '\u00df'
+ shift+alt, capslock+alt: '\u00a7'
}
key T {
@@ -194,8 +194,8 @@
number: '8'
base: 't'
shift, capslock: 'T'
- alt: '{'
- shift+alt, capslock+alt: '\u00a3'
+ alt: '\u00fe'
+ shift+alt, capslock+alt: '\u00de'
}
key U {
@@ -203,8 +203,8 @@
number: '8'
base: 'u'
shift, capslock: 'U'
- alt: '_'
- shift+alt, capslock+alt: '\u0308'
+ alt: '\u00fa'
+ shift+alt, capslock+alt: '\u00da'
}
key V {
@@ -221,8 +221,8 @@
number: '9'
base: 'w'
shift, capslock: 'W'
- alt: '~'
- shift+alt, capslock+alt: '~'
+ alt: '\u00e5'
+ shift+alt, capslock+alt: '\u00c5'
}
key X {
@@ -239,8 +239,8 @@
number: '9'
base: 'y'
shift, capslock: 'Y'
- alt: '}'
- shift+alt, capslock+alt: '\u00a1'
+ alt: '\u00fc'
+ shift+alt, capslock+alt: '\u00dc'
}
key Z {
@@ -248,8 +248,8 @@
number: '9'
base: 'z'
shift, capslock: 'Z'
- alt: 'z'
- shift+alt, capslock+alt: 'Z'
+ alt: '\u00e6'
+ shift+alt, capslock+alt: '\u00c6'
}
key COMMA {
@@ -257,8 +257,8 @@
number: ','
base: ','
shift: '<'
- alt: ','
- shift+alt: ','
+ alt: '\u00e7'
+ shift+alt: '\u00c7'
}
key PERIOD {
@@ -284,7 +284,7 @@
number: '/'
base: '/'
shift: '?'
- alt: '?'
+ alt: '\u00bf'
shift+alt: '?'
}
@@ -320,7 +320,7 @@
number: '0'
base: '0'
shift: ')'
- alt: ')'
+ alt: '\u02bc'
shift+alt: ')'
}
@@ -329,8 +329,8 @@
number: '1'
base: '1'
shift: '!'
- alt: '!'
- shift+alt: '!'
+ alt: '\u00a1'
+ shift+alt: '\u00b9'
}
key 2 {
@@ -338,7 +338,7 @@
number: '2'
base: '2'
shift: '@'
- alt: '@'
+ alt: '\u00b2'
shift+alt: '@'
}
@@ -347,7 +347,7 @@
number: '3'
base: '3'
shift: '#'
- alt: '#'
+ alt: '\u00b3'
shift+alt: '#'
}
@@ -356,8 +356,8 @@
number: '4'
base: '4'
shift: '$'
- alt: '$'
- shift+alt: '$'
+ alt: '\u00a4'
+ shift+alt: '\u00a3'
}
key 5 {
@@ -365,7 +365,7 @@
number: '5'
base: '5'
shift: '%'
- alt: '%'
+ alt: '\u20ac'
shift+alt: '%'
}
@@ -374,8 +374,8 @@
number: '6'
base: '6'
shift: '^'
- alt: '^'
- shift+alt: '^'
+ alt: '\u00bc'
+ shift+alt: '\u0302'
}
key 7 {
@@ -383,7 +383,7 @@
number: '7'
base: '7'
shift: '&'
- alt: '&'
+ alt: '\u00bd'
shift+alt: '&'
}
@@ -392,7 +392,7 @@
number: '8'
base: '8'
shift: '*'
- alt: '*'
+ alt: '\u00be'
shift+alt: '*'
}
@@ -401,7 +401,7 @@
number: '9'
base: '9'
shift: '('
- alt: '('
+ alt: '\u02bb'
shift+alt: '('
}
@@ -410,8 +410,8 @@
number: '`'
base: '`'
shift: '~'
- alt: '`'
- shift+alt: '~'
+ alt: '\u0300'
+ shift+alt: '\u0303'
}
key MINUS {
@@ -419,7 +419,7 @@
number: '-'
base: '-'
shift: '_'
- alt: '-'
+ alt: '\u00a5'
shift+alt: '_'
}
@@ -428,8 +428,8 @@
number: '='
base: '='
shift: '+'
- alt: '='
- shift+alt: '+'
+ alt: '\u00d7'
+ shift+alt: '\u00f7'
}
key LEFT_BRACKET {
@@ -437,7 +437,7 @@
number: '['
base: '['
shift: '{'
- alt: '['
+ alt: '\u00ab'
shift+alt: '{'
}
@@ -446,7 +446,7 @@
number: ']'
base: ']'
shift: '}'
- alt: ']'
+ alt: '\u00bb'
shift+alt: '}'
}
@@ -455,8 +455,8 @@
number: '\\'
base: '\\'
shift: '|'
- alt: '\\'
- shift+alt: '|'
+ alt: '\u00ac'
+ shift+alt: '\u00a6'
}
key SEMICOLON {
@@ -464,8 +464,8 @@
number: ';'
base: ';'
shift: ':'
- alt: ';'
- shift+alt: ':'
+ alt: '\u00b6'
+ shift+alt: '\u00b0'
}
key APOSTROPHE {
@@ -473,8 +473,8 @@
number: '\''
base: '\''
shift: '"'
- alt: '\''
- shift+alt: '"'
+ alt: '\u0301'
+ shift+alt: '\u0308'
}
key STAR {
diff --git a/docs/html/guide/topics/sensors/sensors_overview.jd b/docs/html/guide/topics/sensors/sensors_overview.jd
index 0b3cb2b..53faca0 100644
--- a/docs/html/guide/topics/sensors/sensors_overview.jd
+++ b/docs/html/guide/topics/sensors/sensors_overview.jd
@@ -465,6 +465,7 @@
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+mSensor = null;
if (mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
List<Sensor> gravSensors = mSensorManager.getSensorList(Sensor.TYPE_GRAVITY);
@@ -476,7 +477,7 @@
}
}
}
-else{
+if (mSensor == null){
// Use the accelerometer.
if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 3901af3..ca214ab 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -40,6 +40,7 @@
import android.os.Build;
import android.util.ArrayMap;
import android.util.AttributeSet;
+import android.util.IntArray;
import android.util.Log;
import android.util.LongArray;
import android.util.PathParser;
@@ -629,12 +630,24 @@
*/
public void reset() {
ensureAnimatorSet();
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.w(LOGTAG, "calling reset on AVD: " +
+ ((VectorDrawable.VectorDrawableState) ((AnimatedVectorDrawableState)
+ getConstantState()).mVectorDrawable.getConstantState()).mRootName
+ + ", at: " + this);
+ }
mAnimatorSet.reset();
}
@Override
public void start() {
ensureAnimatorSet();
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.w(LOGTAG, "calling start on AVD: " +
+ ((VectorDrawable.VectorDrawableState) ((AnimatedVectorDrawableState)
+ getConstantState()).mVectorDrawable.getConstantState()).mRootName
+ + ", at: " + this);
+ }
mAnimatorSet.start();
}
@@ -652,6 +665,12 @@
@Override
public void stop() {
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.w(LOGTAG, "calling stop on AVD: " +
+ ((VectorDrawable.VectorDrawableState) ((AnimatedVectorDrawableState)
+ getConstantState()).mVectorDrawable.getConstantState())
+ .mRootName + ", at: " + this);
+ }
mAnimatorSet.end();
}
@@ -864,9 +883,10 @@
* @hide
*/
public static class VectorDrawableAnimatorRT implements VectorDrawableAnimator {
- private static final int NONE = 0;
private static final int START_ANIMATION = 1;
private static final int REVERSE_ANIMATION = 2;
+ private static final int RESET_ANIMATION = 3;
+ private static final int END_ANIMATION = 4;
private AnimatorListener mListener = null;
private final LongArray mStartDelays = new LongArray();
private PropertyValuesHolder.PropertyValues mTmpValues =
@@ -882,7 +902,7 @@
private final VirtualRefBasePtr mSetRefBasePtr;
private WeakReference<RenderNode> mLastSeenTarget = null;
private int mLastListenerId = 0;
- private int mPendingAnimationAction = NONE;
+ private final IntArray mPendingAnimationActions = new IntArray();
private final Drawable mDrawable;
VectorDrawableAnimatorRT(AnimatedVectorDrawable drawable) {
@@ -1139,16 +1159,29 @@
protected void recordLastSeenTarget(DisplayListCanvas canvas) {
mLastSeenTarget = new WeakReference<RenderNode>(
RenderNodeAnimatorSetHelper.getTarget(canvas));
- if (mPendingAnimationAction != NONE) {
+ if (mPendingAnimationActions.size() > 0 && useLastSeenTarget()) {
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
Log.d(LOGTAG, "Target is set in the next frame");
}
- if (mPendingAnimationAction == START_ANIMATION) {
- start();
- } else if (mPendingAnimationAction == REVERSE_ANIMATION) {
- reverse();
+ for (int i = 0; i < mPendingAnimationActions.size(); i++) {
+ handlePendingAction(mPendingAnimationActions.get(i));
}
- mPendingAnimationAction = NONE;
+ mPendingAnimationActions.clear();
+ }
+ }
+
+ private void handlePendingAction(int pendingAnimationAction) {
+ if (pendingAnimationAction == START_ANIMATION) {
+ startAnimation();
+ } else if (pendingAnimationAction == REVERSE_ANIMATION) {
+ reverseAnimation();
+ } else if (pendingAnimationAction == RESET_ANIMATION) {
+ resetAnimation();
+ } else if (pendingAnimationAction == END_ANIMATION) {
+ endAnimation();
+ } else {
+ throw new UnsupportedOperationException("Animation action " +
+ pendingAnimationAction + "is not supported");
}
}
@@ -1167,45 +1200,51 @@
mDrawable.invalidateSelf();
}
+ private void addPendingAction(int pendingAnimationAction) {
+ invalidateOwningView();
+ mPendingAnimationActions.add(pendingAnimationAction);
+ }
+
@Override
public void start() {
if (!mInitialized) {
return;
}
- if (!useLastSeenTarget()) {
- invalidateOwningView();
- mPendingAnimationAction = START_ANIMATION;
- return;
+ if (useLastSeenTarget()) {
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.d(LOGTAG, "Target is set. Starting VDAnimatorSet from java");
+ }
+ startAnimation();
+ } else {
+ addPendingAction(START_ANIMATION);
}
- if (DBG_ANIMATION_VECTOR_DRAWABLE) {
- Log.d(LOGTAG, "Target is set. Starting VDAnimatorSet from java");
- }
-
- mStarted = true;
- nStart(mSetPtr, this, ++mLastListenerId);
- invalidateOwningView();
- if (mListener != null) {
- mListener.onAnimationStart(null);
- }
}
@Override
public void end() {
- if (mInitialized && useLastSeenTarget()) {
- // If no target has ever been set, no-op
- nEnd(mSetPtr);
- invalidateOwningView();
+ if (!mInitialized) {
+ return;
+ }
+
+ if (useLastSeenTarget()) {
+ endAnimation();
+ } else {
+ addPendingAction(END_ANIMATION);
}
}
@Override
public void reset() {
- if (mInitialized && useLastSeenTarget()) {
- // If no target has ever been set, no-op
- nReset(mSetPtr);
- invalidateOwningView();
+ if (!mInitialized) {
+ return;
+ }
+
+ if (useLastSeenTarget()) {
+ resetAnimation();
+ } else {
+ addPendingAction(RESET_ANIMATION);
}
}
@@ -1216,15 +1255,53 @@
if (!mIsReversible || !mInitialized) {
return;
}
- if (!useLastSeenTarget()) {
- invalidateOwningView();
- mPendingAnimationAction = REVERSE_ANIMATION;
- return;
+ if (useLastSeenTarget()) {
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.d(LOGTAG, "Target is set. Reversing VDAnimatorSet from java");
+ }
+ reverseAnimation();
+ } else {
+ addPendingAction(REVERSE_ANIMATION);
}
+ }
+
+ // This should only be called after animator has been added to the RenderNode target.
+ private void startAnimation() {
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
- Log.d(LOGTAG, "Target is set. Reversing VDAnimatorSet from java");
+ Log.w(LOGTAG, "starting animation on VD: " +
+ ((VectorDrawable.VectorDrawableState) ((AnimatedVectorDrawableState)
+ mDrawable.getConstantState()).mVectorDrawable.getConstantState())
+ .mRootName);
}
mStarted = true;
+ nStart(mSetPtr, this, ++mLastListenerId);
+ invalidateOwningView();
+ if (mListener != null) {
+ mListener.onAnimationStart(null);
+ }
+ }
+
+ // This should only be called after animator has been added to the RenderNode target.
+ private void endAnimation() {
+ if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+ Log.w(LOGTAG, "ending animation on VD: " +
+ ((VectorDrawable.VectorDrawableState) ((AnimatedVectorDrawableState)
+ mDrawable.getConstantState()).mVectorDrawable.getConstantState())
+ .mRootName);
+ }
+ nEnd(mSetPtr);
+ invalidateOwningView();
+ }
+
+ // This should only be called after animator has been added to the RenderNode target.
+ private void resetAnimation() {
+ nReset(mSetPtr);
+ invalidateOwningView();
+ }
+
+ // This should only be called after animator has been added to the RenderNode target.
+ private void reverseAnimation() {
+ mStarted = true;
nReverse(mSetPtr, this, ++mLastListenerId);
invalidateOwningView();
if (mListener != null) {
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index d8801b8..16bea79 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1896,6 +1896,13 @@
mutable Mutex mLock;
+ // Mutex that controls access to the list of pre-filtered configurations
+ // to check when looking up entries.
+ // When iterating over a bag, the mLock mutex is locked. While mLock is locked,
+ // we do resource lookups.
+ // Mutex is not reentrant, so we must use a different lock than mLock.
+ mutable Mutex mFilteredConfigLock;
+
status_t mError;
ResTable_config mParams;
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 7adad8a..0886487 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -547,11 +547,8 @@
Intent intent = new Intent(IKeyChainService.class.getName());
ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
intent.setComponent(comp);
- boolean isBound = context.bindServiceAsUser(intent,
- keyChainServiceConnection,
- Context.BIND_AUTO_CREATE,
- user);
- if (!isBound) {
+ if (comp == null || !context.bindServiceAsUser(
+ intent, keyChainServiceConnection, Context.BIND_AUTO_CREATE, user)) {
throw new AssertionError("could not bind to KeyChainService");
}
return new KeyChainConnection(context, keyChainServiceConnection, q.take());
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 3277c36..c73bb584 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -25,6 +25,7 @@
#include <string.h>
#include <limits>
+#include <memory>
#include <type_traits>
#include <androidfw/ByteBucketArray.h>
@@ -3146,6 +3147,9 @@
StringPoolRef keyStr;
};
+template <typename T>
+using SharedVector = std::shared_ptr<Vector<T>>;
+
struct ResTable::Type
{
Type(const Header* _header, const Package* _package, size_t count)
@@ -3158,6 +3162,10 @@
const uint32_t* typeSpecFlags;
IdmapEntries idmapEntries;
Vector<const ResTable_type*> configs;
+
+ // The set of configurations that match the current parameters.
+ // This will be swapped with a new set when the parameters change.
+ SharedVector<const ResTable_type*> filteredConfigs;
};
struct ResTable::Package
@@ -4430,18 +4438,44 @@
void ResTable::setParameters(const ResTable_config* params)
{
- mLock.lock();
+ AutoMutex _lock(mLock);
+ AutoMutex _lock2(mFilteredConfigLock);
+
if (kDebugTableGetEntry) {
ALOGI("Setting parameters: %s\n", params->toString().string());
}
mParams = *params;
- for (size_t i=0; i<mPackageGroups.size(); i++) {
+ for (size_t p = 0; p < mPackageGroups.size(); p++) {
+ PackageGroup* packageGroup = mPackageGroups.editItemAt(p);
if (kDebugTableNoisy) {
- ALOGI("CLEARING BAGS FOR GROUP %zu!", i);
+ ALOGI("CLEARING BAGS FOR GROUP %zu!", p);
}
- mPackageGroups[i]->clearBagCache();
+ packageGroup->clearBagCache();
+
+ for (size_t t = 0; t < packageGroup->types.size(); t++) {
+ TypeList& typeList = packageGroup->types.editItemAt(t);
+ for (size_t ts = 0; ts < typeList.size(); ts++) {
+ Type* type = typeList.editItemAt(ts);
+
+ SharedVector<const ResTable_type*> newFilteredConfigs =
+ std::make_shared<Vector<const ResTable_type*>>();
+ for (size_t ti = 0; ti < type->configs.size(); ti++) {
+ ResTable_config config;
+ config.copyFromDtoH(type->configs[ti]->config);
+
+ if (config.match(mParams)) {
+ newFilteredConfigs->add(type->configs[ti]);
+ }
+ }
+
+ if (kDebugTableNoisy) {
+ ALOGD("Updating pkg=%zu type=%zu with %zu filtered configs",
+ p, t, newFilteredConfigs->size());
+ }
+ type->filteredConfigs = newFilteredConfigs;
+ }
+ }
}
- mLock.unlock();
}
void ResTable::getParameters(ResTable_config* params) const
@@ -5974,9 +6008,29 @@
specFlags = -1;
}
- const size_t numConfigs = typeSpec->configs.size();
+ const Vector<const ResTable_type*>* candidateConfigs = &typeSpec->configs;
+
+ SharedVector<const ResTable_type*> filteredConfigs;
+ if (config && memcmp(&mParams, config, sizeof(mParams)) == 0) {
+ // Grab the lock first so we can safely get the current filtered list.
+ AutoMutex _lock(mFilteredConfigLock);
+
+ // This configuration is equal to the one we have previously cached for,
+ // so use the filtered configs.
+
+ if (typeSpec->filteredConfigs) {
+ // Grab a reference to the shared_ptr so it doesn't get destroyed while
+ // going through this list.
+ filteredConfigs = typeSpec->filteredConfigs;
+
+ // Use this filtered list.
+ candidateConfigs = filteredConfigs.get();
+ }
+ }
+
+ const size_t numConfigs = candidateConfigs->size();
for (size_t c = 0; c < numConfigs; c++) {
- const ResTable_type* const thisType = typeSpec->configs[c];
+ const ResTable_type* const thisType = candidateConfigs->itemAt(c);
if (thisType == NULL) {
continue;
}
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 1aab3c7..06b712e 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -30,6 +30,7 @@
#include <algorithm>
#include <math.h>
#include <SkPaintDefaults.h>
+#include <SkPathOps.h>
namespace android {
namespace uirenderer {
@@ -60,7 +61,10 @@
for (size_t i = 0; i < opList.count; i++) {
const BakedOpState& state = *(opList.states[i]);
TextureVertex* rectVerts = &vertices[i * 4];
- Rect opBounds = state.computedState.clippedBounds;
+
+ // calculate unclipped bounds, since they'll determine texture coordinates
+ Rect opBounds = state.op->unmappedBounds;
+ state.computedState.transform.mapRect(opBounds);
if (CC_LIKELY(state.computedState.transform.isPureTranslate())) {
// pure translate, so snap (same behavior as onBitmapOp)
opBounds.snapToPixelBoundaries();
@@ -527,6 +531,12 @@
SkPath path;
SkRect rect = getBoundsOfFill(op);
path.addOval(rect);
+
+ if (state.computedState.localProjectionPathMask != nullptr) {
+ // Mask the ripple path by the local space projection mask in local space.
+ // Note that this can create CCW paths.
+ Op(path, *state.computedState.localProjectionPathMask, kIntersect_SkPathOp, &path);
+ }
renderConvexPath(renderer, state, path, *(op.paint));
}
}
diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp
index 682bd04..26653f7 100644
--- a/libs/hwui/BakedOpState.cpp
+++ b/libs/hwui/BakedOpState.cpp
@@ -63,9 +63,22 @@
clipState = nullptr;
clippedBounds.setEmpty();
} else {
- // Not rejected! compute true clippedBounds and clipSideFlags
+ // Not rejected! compute true clippedBounds, clipSideFlags, and path mask
clipSideFlags = computeClipSideFlags(clipRect, clippedBounds);
clippedBounds.doIntersect(clipRect);
+
+ if (CC_UNLIKELY(snapshot.projectionPathMask)) {
+ // map projection path mask from render target space into op space,
+ // so intersection with op geometry is possible
+ Matrix4 inverseTransform;
+ inverseTransform.loadInverse(transform);
+ SkMatrix skInverseTransform;
+ inverseTransform.copyTo(skInverseTransform);
+
+ auto localMask = allocator.create<SkPath>();
+ snapshot.projectionPathMask->transform(skInverseTransform, localMask);
+ localProjectionPathMask = localMask;
+ }
}
}
@@ -73,13 +86,15 @@
: transform(*snapshot.transform)
, clipState(snapshot.mutateClipArea().serializeClip(allocator))
, clippedBounds(clipState->rect)
- , clipSideFlags(OpClipSideFlags::Full) {}
+ , clipSideFlags(OpClipSideFlags::Full)
+ , localProjectionPathMask(nullptr) {}
ResolvedRenderState::ResolvedRenderState(const ClipRect* clipRect, const Rect& dstRect)
: transform(Matrix4::identity())
, clipState(clipRect)
, clippedBounds(dstRect)
- , clipSideFlags(computeClipSideFlags(clipRect->rect, dstRect)) {
+ , clipSideFlags(computeClipSideFlags(clipRect->rect, dstRect))
+ , localProjectionPathMask(nullptr) {
clippedBounds.doIntersect(clipRect->rect);
}
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
index 4365ef8..ffe2901 100644
--- a/libs/hwui/BakedOpState.h
+++ b/libs/hwui/BakedOpState.h
@@ -88,6 +88,7 @@
const ClipBase* clipState = nullptr;
Rect clippedBounds;
int clipSideFlags = 0;
+ const SkPath* localProjectionPathMask = nullptr;
};
/**
@@ -154,7 +155,6 @@
// simple state (straight pointer/value storage):
const float alpha;
const RoundRectClipState* roundRectClipState;
- const ProjectionPathMask* projectionPathMask;
const RecordedOp* op;
private:
@@ -165,21 +165,18 @@
: computedState(allocator, snapshot, recordedOp, expandForStroke)
, alpha(snapshot.alpha)
, roundRectClipState(snapshot.roundRectClipState)
- , projectionPathMask(snapshot.projectionPathMask)
, op(&recordedOp) {}
BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr)
: computedState(allocator, snapshot)
, alpha(snapshot.alpha)
, roundRectClipState(snapshot.roundRectClipState)
- , projectionPathMask(snapshot.projectionPathMask)
, op(shadowOpPtr) {}
BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp)
: computedState(clipRect, dstRect)
, alpha(1.0f)
, roundRectClipState(nullptr)
- , projectionPathMask(nullptr)
, op(&recordedOp) {}
};
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 04de98a..5642170 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -389,34 +389,38 @@
}
void FrameBuilder::deferProjectedChildren(const RenderNode& renderNode) {
- const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath();
int count = mCanvasState.save(SaveFlags::MatrixClip);
+ const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath();
- // can't be null, since DL=null node rejection happens before deferNodePropsAndOps
- const DisplayList& displayList = *(renderNode.getDisplayList());
-
- const RecordedOp* op = (displayList.getOps()[displayList.projectionReceiveIndex]);
- const RenderNodeOp* backgroundOp = static_cast<const RenderNodeOp*>(op);
- const RenderProperties& backgroundProps = backgroundOp->renderNode->properties();
-
- // Transform renderer to match background we're projecting onto
- // (by offsetting canvas by translationX/Y of background rendernode, since only those are set)
- mCanvasState.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY());
-
- // If the projection receiver has an outline, we mask projected content to it
- // (which we know, apriori, are all tessellated paths)
- mCanvasState.setProjectionPathMask(mAllocator, projectionReceiverOutline);
-
- // draw projected nodes
- for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) {
- RenderNodeOp* childOp = renderNode.mProjectedNodes[i];
-
- int restoreTo = mCanvasState.save(SaveFlags::Matrix);
- mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor);
- deferRenderNodeOpImpl(*childOp);
- mCanvasState.restoreToCount(restoreTo);
+ SkPath transformedMaskPath; // on stack, since BakedOpState makes a deep copy
+ if (projectionReceiverOutline) {
+ // transform the mask for this projector into render target space
+ // TODO: consider combining both transforms by stashing transform instead of applying
+ SkMatrix skCurrentTransform;
+ mCanvasState.currentTransform()->copyTo(skCurrentTransform);
+ projectionReceiverOutline->transform(
+ skCurrentTransform,
+ &transformedMaskPath);
+ mCanvasState.setProjectionPathMask(mAllocator, &transformedMaskPath);
}
+ for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) {
+ RenderNodeOp* childOp = renderNode.mProjectedNodes[i];
+ RenderNode& childNode = *childOp->renderNode;
+
+ // Draw child if it has content, but ignore state in childOp - matrix already applied to
+ // transformFromCompositingAncestor, and record-time clip is ignored when projecting
+ if (!childNode.nothingToDraw()) {
+ int restoreTo = mCanvasState.save(SaveFlags::MatrixClip);
+
+ // Apply transform between ancestor and projected descendant
+ mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor);
+
+ deferNodePropsAndOps(childNode);
+
+ mCanvasState.restoreToCount(restoreTo);
+ }
+ }
mCanvasState.restoreToCount(count);
}
@@ -513,10 +517,6 @@
BakedOpState* bakedState = tryBakeOpState(op);
if (!bakedState) return; // quick rejected
- currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
-
- // TODO: Fix this ( b/26569206 )
-/*
// Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
// Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
// MergingDrawBatch::canMergeWith()
@@ -531,7 +531,6 @@
} else {
currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
}
-*/
}
void FrameBuilder::deferBitmapMeshOp(const BitmapMeshOp& op) {
diff --git a/libs/hwui/LayerBuilder.cpp b/libs/hwui/LayerBuilder.cpp
index bc39621..c5af279 100644
--- a/libs/hwui/LayerBuilder.cpp
+++ b/libs/hwui/LayerBuilder.cpp
@@ -140,7 +140,10 @@
// Identical round rect clip state means both ops will clip in the same way, or not at all.
// As the state objects are const, we can compare their pointers to determine mergeability
if (lhs->roundRectClipState != rhs->roundRectClipState) return false;
- if (lhs->projectionPathMask != rhs->projectionPathMask) return false;
+
+ // Local masks prevent merge, since they're potentially in different coordinate spaces
+ if (lhs->computedState.localProjectionPathMask
+ || rhs->computedState.localProjectionPathMask) return false;
/* Clipping compatibility check
*
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b7a5923..7693fdc 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1148,7 +1148,9 @@
// always store/restore, since these are just pointers
state.mRoundRectClipState = currentSnapshot()->roundRectClipState;
+#if !HWUI_NEW_OPS
state.mProjectionPathMask = currentSnapshot()->projectionPathMask;
+#endif
return false;
}
@@ -1156,7 +1158,9 @@
setGlobalMatrix(state.mMatrix);
writableSnapshot()->alpha = state.mAlpha;
writableSnapshot()->roundRectClipState = state.mRoundRectClipState;
+#if !HWUI_NEW_OPS
writableSnapshot()->projectionPathMask = state.mProjectionPathMask;
+#endif
if (state.mClipValid && !skipClipRestore) {
writableSnapshot()->setClip(state.mClip.left, state.mClip.top,
@@ -1833,6 +1837,7 @@
path.addCircle(x, y, radius);
}
+#if !HWUI_NEW_OPS
if (CC_UNLIKELY(currentSnapshot()->projectionPathMask != nullptr)) {
// mask ripples with projection mask
SkPath maskPath = *(currentSnapshot()->projectionPathMask->projectionMask);
@@ -1852,6 +1857,7 @@
// in local space. Note that this can create CCW paths.
Op(path, maskPath, kIntersect_SkPathOp, &path);
}
+#endif
drawConvexPath(path, p);
}
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 27fea1f..cf5e69a 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -146,6 +146,9 @@
}
void Snapshot::buildScreenSpaceTransform(Matrix4* outTransform) const {
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL("not supported - not needed by new ops");
+#else
// build (reverse ordered) list of the stack of snapshots, terminated with a NULL
Vector<const Snapshot*> snapshotList;
snapshotList.push(nullptr);
@@ -171,6 +174,7 @@
outTransform->multiply(*(current->transform));
}
}
+#endif
}
///////////////////////////////////////////////////////////////////////////////
@@ -223,15 +227,19 @@
}
void Snapshot::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) {
+#if HWUI_NEW_OPS
+ // TODO: remove allocator param for HWUI_NEW_OPS
+ projectionPathMask = path;
+#else
if (path) {
ProjectionPathMask* mask = new (allocator) ProjectionPathMask;
mask->projectionMask = path;
buildScreenSpaceTransform(&(mask->projectionMaskTransform));
-
projectionPathMask = mask;
} else {
projectionPathMask = nullptr;
}
+#endif
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index b03643f..3a01d04 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -63,6 +63,7 @@
float radius;
};
+// TODO: remove for HWUI_NEW_OPS
class ProjectionPathMask {
public:
static void* operator new(size_t size) = delete;
@@ -219,6 +220,7 @@
* Fills outTransform with the current, total transform to screen space,
* across layer boundaries.
*/
+ // TODO: remove for HWUI_NEW_OPS
void buildScreenSpaceTransform(Matrix4* outTransform) const;
/**
@@ -294,9 +296,13 @@
const RoundRectClipState* roundRectClipState;
/**
- * Current projection masking path - used exclusively to mask tessellated circles.
+ * Current projection masking path - used exclusively to mask projected, tessellated circles.
*/
+#if HWUI_NEW_OPS
+ const SkPath* projectionPathMask;
+#else
const ProjectionPathMask* projectionPathMask;
+#endif
void dump() const;
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index f86898f..4c56a22 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -216,8 +216,7 @@
<< "Expect number of ops = 2 * loop count";
}
-// TODO: Disabled due to b/26793764
-TEST(FrameBuilder, DISABLED_clippedMerging) {
+TEST(FrameBuilder, clippedMerging) {
class ClippedMergingTestRenderer : public TestRendererBase {
public:
void onMergedBitmapOps(const MergedBakedOpList& opList) override {
@@ -990,21 +989,26 @@
EXPECT_EQ(Rect(100, 100), op.unmappedBounds);
EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
expectedMatrix.loadIdentity();
+ EXPECT_EQ(nullptr, state.computedState.localProjectionPathMask);
break;
case 1:
EXPECT_EQ(Rect(-10, -10, 60, 60), op.unmappedBounds);
EXPECT_EQ(SK_ColorDKGRAY, op.paint->getColor());
- expectedMatrix.loadTranslate(50, 50, 0); // TODO: should scroll be respected here?
+ expectedMatrix.loadTranslate(50 - scrollX, 50 - scrollY, 0);
+ ASSERT_NE(nullptr, state.computedState.localProjectionPathMask);
+ EXPECT_EQ(Rect(-35, -30, 45, 50),
+ Rect(state.computedState.localProjectionPathMask->getBounds()));
break;
case 2:
EXPECT_EQ(Rect(100, 50), op.unmappedBounds);
EXPECT_EQ(SK_ColorBLUE, op.paint->getColor());
expectedMatrix.loadTranslate(-scrollX, 50 - scrollY, 0);
+ EXPECT_EQ(nullptr, state.computedState.localProjectionPathMask);
break;
default:
ADD_FAILURE();
}
- EXPECT_MATRIX_APPROX_EQ(expectedMatrix, state.computedState.transform);
+ EXPECT_EQ(expectedMatrix, state.computedState.transform);
}
};
@@ -1045,6 +1049,9 @@
});
auto parent = TestUtils::createNode(0, 0, 100, 100,
[&receiverBackground, &child](RenderProperties& properties, RecordingCanvas& canvas) {
+ // Set a rect outline for the projecting ripple to be masked against.
+ properties.mutableOutline().setRoundRect(10, 10, 90, 90, 5, 1.0f);
+
canvas.save(SaveFlags::MatrixClip);
canvas.translate(-scrollX, -scrollY); // Apply scroll (note: bg undoes this internally)
canvas.drawRenderNode(receiverBackground.get());
@@ -1059,6 +1066,145 @@
EXPECT_EQ(3, renderer.getIndex());
}
+RENDERTHREAD_TEST(FrameBuilder, projectionHwLayer) {
+ static const int scrollX = 5;
+ static const int scrollY = 10;
+ class ProjectionHwLayerTestRenderer : public TestRendererBase {
+ public:
+ void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
+ EXPECT_EQ(0, mIndex++);
+ }
+ void onArcOp(const ArcOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(1, mIndex++);
+ ASSERT_EQ(nullptr, state.computedState.localProjectionPathMask);
+ }
+ void endLayer() override {
+ EXPECT_EQ(2, mIndex++);
+ }
+ void onRectOp(const RectOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(3, mIndex++);
+ ASSERT_EQ(nullptr, state.computedState.localProjectionPathMask);
+ }
+ void onOvalOp(const OvalOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(4, mIndex++);
+ ASSERT_NE(nullptr, state.computedState.localProjectionPathMask);
+ Matrix4 expected;
+ expected.loadTranslate(100 - scrollX, 100 - scrollY, 0);
+ EXPECT_EQ(expected, state.computedState.transform);
+ EXPECT_EQ(Rect(-85, -80, 295, 300),
+ Rect(state.computedState.localProjectionPathMask->getBounds()));
+ }
+ void onLayerOp(const LayerOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(5, mIndex++);
+ ASSERT_EQ(nullptr, state.computedState.localProjectionPathMask);
+ }
+ };
+ auto receiverBackground = TestUtils::createNode(0, 0, 400, 400,
+ [](RenderProperties& properties, RecordingCanvas& canvas) {
+ properties.setProjectionReceiver(true);
+ // scroll doesn't apply to background, so undone via translationX/Y
+ // NOTE: translationX/Y only! no other transform properties may be set for a proj receiver!
+ properties.setTranslationX(scrollX);
+ properties.setTranslationY(scrollY);
+
+ canvas.drawRect(0, 0, 400, 400, SkPaint());
+ });
+ auto projectingRipple = TestUtils::createNode(0, 0, 200, 200,
+ [](RenderProperties& properties, RecordingCanvas& canvas) {
+ properties.setProjectBackwards(true);
+ properties.setClipToBounds(false);
+ canvas.drawOval(100, 100, 300, 300, SkPaint()); // drawn mostly out of layer bounds
+ });
+ auto child = TestUtils::createNode(100, 100, 300, 300,
+ [&projectingRipple](RenderProperties& properties, RecordingCanvas& canvas) {
+ properties.mutateLayerProperties().setType(LayerType::RenderLayer);
+ canvas.drawRenderNode(projectingRipple.get());
+ canvas.drawArc(0, 0, 200, 200, 0.0f, 280.0f, true, SkPaint());
+ });
+ auto parent = TestUtils::createNode(0, 0, 400, 400,
+ [&receiverBackground, &child](RenderProperties& properties, RecordingCanvas& canvas) {
+ // Set a rect outline for the projecting ripple to be masked against.
+ properties.mutableOutline().setRoundRect(10, 10, 390, 390, 0, 1.0f);
+ canvas.translate(-scrollX, -scrollY); // Apply scroll (note: bg undoes this internally)
+ canvas.drawRenderNode(receiverBackground.get());
+ canvas.drawRenderNode(child.get());
+ });
+
+ OffscreenBuffer** layerHandle = child->getLayerHandle();
+
+ // create RenderNode's layer here in same way prepareTree would, setting windowTransform
+ OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200, 200);
+ Matrix4 windowTransform;
+ windowTransform.loadTranslate(100, 100, 0); // total transform of layer's origin
+ layer.setWindowTransform(windowTransform);
+ *layerHandle = &layer;
+
+ auto syncedList = TestUtils::createSyncedNodeList(parent);
+ LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
+ layerUpdateQueue.enqueueLayerWithDamage(child.get(), Rect(200, 200));
+ FrameBuilder frameBuilder(layerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
+ syncedList, sLightGeometry, nullptr);
+ ProjectionHwLayerTestRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+ EXPECT_EQ(6, renderer.getIndex());
+
+ // clean up layer pointer, so we can safely destruct RenderNode
+ *layerHandle = nullptr;
+}
+
+RENDERTHREAD_TEST(FrameBuilder, projectionChildScroll) {
+ static const int scrollX = 500000;
+ static const int scrollY = 0;
+ class ProjectionChildScrollTestRenderer : public TestRendererBase {
+ public:
+ void onRectOp(const RectOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(0, mIndex++);
+ EXPECT_TRUE(state.computedState.transform.isIdentity());
+ }
+ void onOvalOp(const OvalOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(1, mIndex++);
+ ASSERT_NE(nullptr, state.computedState.clipState);
+ ASSERT_EQ(ClipMode::Rectangle, state.computedState.clipState->mode);
+ ASSERT_EQ(Rect(400, 400), state.computedState.clipState->rect);
+ EXPECT_TRUE(state.computedState.transform.isIdentity());
+ }
+ };
+ auto receiverBackground = TestUtils::createNode(0, 0, 400, 400,
+ [](RenderProperties& properties, RecordingCanvas& canvas) {
+ properties.setProjectionReceiver(true);
+ canvas.drawRect(0, 0, 400, 400, SkPaint());
+ });
+ auto projectingRipple = TestUtils::createNode(0, 0, 200, 200,
+ [](RenderProperties& properties, RecordingCanvas& canvas) {
+ // scroll doesn't apply to background, so undone via translationX/Y
+ // NOTE: translationX/Y only! no other transform properties may be set for a proj receiver!
+ properties.setTranslationX(scrollX);
+ properties.setTranslationY(scrollY);
+ properties.setProjectBackwards(true);
+ properties.setClipToBounds(false);
+ canvas.drawOval(0, 0, 200, 200, SkPaint());
+ });
+ auto child = TestUtils::createNode(0, 0, 400, 400,
+ [&projectingRipple](RenderProperties& properties, RecordingCanvas& canvas) {
+ // Record time clip will be ignored by projectee
+ canvas.clipRect(100, 100, 300, 300, SkRegion::kIntersect_Op);
+
+ canvas.translate(-scrollX, -scrollY); // Apply scroll (note: bg undoes this internally)
+ canvas.drawRenderNode(projectingRipple.get());
+ });
+ auto parent = TestUtils::createNode(0, 0, 400, 400,
+ [&receiverBackground, &child](RenderProperties& properties, RecordingCanvas& canvas) {
+ canvas.drawRenderNode(receiverBackground.get());
+ canvas.drawRenderNode(child.get());
+ });
+
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
+ TestUtils::createSyncedNodeList(parent), sLightGeometry, nullptr);
+ ProjectionChildScrollTestRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+ EXPECT_EQ(2, renderer.getIndex());
+}
+
// creates a 100x100 shadow casting node with provided translationZ
static sp<RenderNode> createWhiteRectShadowCaster(float translationZ) {
return TestUtils::createNode(0, 0, 100, 100,
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index 3c8a78d..6a7801e 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -26,26 +26,26 @@
public final class GnssClock implements Parcelable {
// The following enumerations must be in sync with the values declared in gps.h
- private static final short HAS_NO_FLAGS = 0;
- private static final short HAS_LEAP_SECOND = (1<<0);
- private static final short HAS_TIME_UNCERTAINTY = (1<<1);
- private static final short HAS_FULL_BIAS = (1<<2);
- private static final short HAS_BIAS = (1<<3);
- private static final short HAS_BIAS_UNCERTAINTY = (1<<4);
- private static final short HAS_DRIFT = (1<<5);
- private static final short HAS_DRIFT_UNCERTAINTY = (1<<6);
+ private static final int HAS_NO_FLAGS = 0;
+ private static final int HAS_LEAP_SECOND = (1<<0);
+ private static final int HAS_TIME_UNCERTAINTY = (1<<1);
+ private static final int HAS_FULL_BIAS = (1<<2);
+ private static final int HAS_BIAS = (1<<3);
+ private static final int HAS_BIAS_UNCERTAINTY = (1<<4);
+ private static final int HAS_DRIFT = (1<<5);
+ private static final int HAS_DRIFT_UNCERTAINTY = (1<<6);
// End enumerations in sync with gps.h
- private short mFlags;
- private short mLeapSecond;
- private long mTimeInNs;
- private double mTimeUncertaintyInNs;
- private long mFullBiasInNs;
- private double mBiasInNs;
- private double mBiasUncertaintyInNs;
- private double mDriftInNsPerSec;
- private double mDriftUncertaintyInNsPerSec;
+ private int mFlags;
+ private int mLeapSecond;
+ private long mTimeNanos;
+ private double mTimeUncertaintyNanos;
+ private long mFullBiasNanos;
+ private double mBiasNanos;
+ private double mBiasUncertaintyNanos;
+ private double mDriftNanosPerSecond;
+ private double mDriftUncertaintyNanosPerSecond;
private int mHardwareClockDiscontinuityCount;
GnssClock() {
@@ -58,13 +58,13 @@
public void set(GnssClock clock) {
mFlags = clock.mFlags;
mLeapSecond = clock.mLeapSecond;
- mTimeInNs = clock.mTimeInNs;
- mTimeUncertaintyInNs = clock.mTimeUncertaintyInNs;
- mFullBiasInNs = clock.mFullBiasInNs;
- mBiasInNs = clock.mBiasInNs;
- mBiasUncertaintyInNs = clock.mBiasUncertaintyInNs;
- mDriftInNsPerSec = clock.mDriftInNsPerSec;
- mDriftUncertaintyInNsPerSec = clock.mDriftUncertaintyInNsPerSec;
+ mTimeNanos = clock.mTimeNanos;
+ mTimeUncertaintyNanos = clock.mTimeUncertaintyNanos;
+ mFullBiasNanos = clock.mFullBiasNanos;
+ mBiasNanos = clock.mBiasNanos;
+ mBiasUncertaintyNanos = clock.mBiasUncertaintyNanos;
+ mDriftNanosPerSecond = clock.mDriftNanosPerSecond;
+ mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond;
mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount;
}
@@ -89,14 +89,14 @@
*
* The value is only available if {@link #hasLeapSecond()} is true.
*/
- public short getLeapSecond() {
+ public int getLeapSecond() {
return mLeapSecond;
}
/**
* Sets the leap second associated with the clock's time.
*/
- public void setLeapSecond(short leapSecond) {
+ public void setLeapSecond(int leapSecond) {
setFlag(HAS_LEAP_SECOND);
mLeapSecond = leapSecond;
}
@@ -106,7 +106,7 @@
*/
public void resetLeapSecond() {
resetFlag(HAS_LEAP_SECOND);
- mLeapSecond = Short.MIN_VALUE;
+ mLeapSecond = Integer.MIN_VALUE;
}
/**
@@ -114,30 +114,30 @@
*
* For 'local hardware clock' this value is expected to be monotonically increasing during the
* reporting session. The real GPS time can be derived by compensating
- * {@link #getFullBiasInNs()} (when it is available) from this value.
+ * {@link #getFullBiasNanos()} (when it is available) from this value.
*
* For 'GPS time' this value is expected to be the best estimation of current GPS time that GPS
- * receiver can achieve. {@link #getTimeUncertaintyInNs()} should be available when GPS time is
+ * receiver can achieve. {@link #getTimeUncertaintyNanos()} should be available when GPS time is
* specified.
*
- * Sub-nanosecond accuracy can be provided by means of {@link #getBiasInNs()}.
- * The reported time includes {@link #getTimeUncertaintyInNs()}.
+ * Sub-nanosecond accuracy can be provided by means of {@link #getBiasNanos()}.
+ * The reported time includes {@link #getTimeUncertaintyNanos()}.
*/
- public long getTimeInNs() {
- return mTimeInNs;
+ public long getTimeNanos() {
+ return mTimeNanos;
}
/**
- * Sets the GPS receiver internal clock in nanoseconds.
+ * Sets the GNSS receiver internal clock in nanoseconds.
*/
- public void setTimeInNs(long timeInNs) {
- mTimeInNs = timeInNs;
+ public void setTimeNanos(long timeNanos) {
+ mTimeNanos = timeNanos;
}
/**
- * Returns true if {@link #getTimeUncertaintyInNs()} is available, false otherwise.
+ * Returns true if {@link #getTimeUncertaintyNanos()} is available, false otherwise.
*/
- public boolean hasTimeUncertaintyInNs() {
+ public boolean hasTimeUncertaintyNanos() {
return isFlagSet(HAS_TIME_UNCERTAINTY);
}
@@ -145,189 +145,189 @@
* Gets the clock's time Uncertainty (1-Sigma) in nanoseconds.
* The uncertainty is represented as an absolute (single sided) value.
*
- * The value is only available if {@link #hasTimeUncertaintyInNs()} is true.
+ * The value is only available if {@link #hasTimeUncertaintyNanos()} is true.
*/
- public double getTimeUncertaintyInNs() {
- return mTimeUncertaintyInNs;
+ public double getTimeUncertaintyNanos() {
+ return mTimeUncertaintyNanos;
}
/**
* Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
*/
- public void setTimeUncertaintyInNs(double timeUncertaintyInNs) {
+ public void setTimeUncertaintyNanos(double timeUncertaintyNanos) {
setFlag(HAS_TIME_UNCERTAINTY);
- mTimeUncertaintyInNs = timeUncertaintyInNs;
+ mTimeUncertaintyNanos = timeUncertaintyNanos;
}
/**
* Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
*/
- public void resetTimeUncertaintyInNs() {
+ public void resetTimeUncertaintyNanos() {
resetFlag(HAS_TIME_UNCERTAINTY);
- mTimeUncertaintyInNs = Double.NaN;
+ mTimeUncertaintyNanos = Double.NaN;
}
/**
- * Returns true if {@link #getFullBiasInNs()} is available, false otherwise.
+ * Returns true if {@link #getFullBiasNanos()} is available, false otherwise.
*/
- public boolean hasFullBiasInNs() {
+ public boolean hasFullBiasNanos() {
return isFlagSet(HAS_FULL_BIAS);
}
/**
- * Gets the difference between hardware clock ({@link #getTimeInNs()}) inside GPS receiver and
+ * Gets the difference between hardware clock ({@link #getTimeNanos()}) inside GPS receiver and
* the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
*
* This value is available if the receiver has estimated GPS time. If the computed time is for a
* non-GPS constellation, the time offset of that constellation to GPS has to be applied to fill
- * this value. The value contains the 'bias uncertainty' {@link #getBiasUncertaintyInNs()} in
+ * this value. The value contains the 'bias uncertainty' {@link #getBiasUncertaintyNanos()} in
* it, and it should be used for quality check. The value is only available if
- * {@link #hasFullBiasInNs()} is true.
+ * {@link #hasFullBiasNanos()} is true.
*
* The sign of the value is defined by the following equation:
* local estimate of GPS time = time_ns + (full_bias_ns + bias_ns)
*/
- public long getFullBiasInNs() {
- return mFullBiasInNs;
+ public long getFullBiasNanos() {
+ return mFullBiasNanos;
}
/**
* Sets the full bias in nanoseconds.
*/
- public void setFullBiasInNs(long value) {
+ public void setFullBiasNanos(long value) {
setFlag(HAS_FULL_BIAS);
- mFullBiasInNs = value;
+ mFullBiasNanos = value;
}
/**
* Resets the full bias in nanoseconds.
*/
- public void resetFullBiasInNs() {
+ public void resetFullBiasNanos() {
resetFlag(HAS_FULL_BIAS);
- mFullBiasInNs = Long.MIN_VALUE;
+ mFullBiasNanos = Long.MIN_VALUE;
}
/**
- * Returns true if {@link #getBiasInNs()} is available, false otherwise.
+ * Returns true if {@link #getBiasNanos()} is available, false otherwise.
*/
- public boolean hasBiasInNs() {
+ public boolean hasBiasNanos() {
return isFlagSet(HAS_BIAS);
}
/**
* Gets the clock's sub-nanosecond bias.
- * The reported bias includes {@link #getBiasUncertaintyInNs()}.
+ * The reported bias includes {@link #getBiasUncertaintyNanos()}.
*
- * The value is only available if {@link #hasBiasInNs()} is true.
+ * The value is only available if {@link #hasBiasNanos()} is true.
*/
- public double getBiasInNs() {
- return mBiasInNs;
+ public double getBiasNanos() {
+ return mBiasNanos;
}
/**
* Sets the sub-nanosecond bias.
*/
- public void setBiasInNs(double biasInNs) {
+ public void setBiasNanos(double biasNanos) {
setFlag(HAS_BIAS);
- mBiasInNs = biasInNs;
+ mBiasNanos = biasNanos;
}
/**
* Resets the clock's Bias in nanoseconds.
*/
- public void resetBiasInNs() {
+ public void resetBiasNanos() {
resetFlag(HAS_BIAS);
- mBiasInNs = Double.NaN;
+ mBiasNanos = Double.NaN;
}
/**
- * Returns true if {@link #getBiasUncertaintyInNs()} is available, false otherwise.
+ * Returns true if {@link #getBiasUncertaintyNanos()} is available, false otherwise.
*/
- public boolean hasBiasUncertaintyInNs() {
+ public boolean hasBiasUncertaintyNanos() {
return isFlagSet(HAS_BIAS_UNCERTAINTY);
}
/**
* Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
*
- * The value is only available if {@link #hasBiasUncertaintyInNs()} is true.
+ * The value is only available if {@link #hasBiasUncertaintyNanos()} is true.
*/
- public double getBiasUncertaintyInNs() {
- return mBiasUncertaintyInNs;
+ public double getBiasUncertaintyNanos() {
+ return mBiasUncertaintyNanos;
}
/**
* Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
*/
- public void setBiasUncertaintyInNs(double biasUncertaintyInNs) {
+ public void setBiasUncertaintyNanos(double biasUncertaintyNanos) {
setFlag(HAS_BIAS_UNCERTAINTY);
- mBiasUncertaintyInNs = biasUncertaintyInNs;
+ mBiasUncertaintyNanos = biasUncertaintyNanos;
}
/**
* Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
*/
- public void resetBiasUncertaintyInNs() {
+ public void resetBiasUncertaintyNanos() {
resetFlag(HAS_BIAS_UNCERTAINTY);
- mBiasUncertaintyInNs = Double.NaN;
+ mBiasUncertaintyNanos = Double.NaN;
}
/**
- * Returns true if {@link #getDriftInNsPerSec()} is available, false otherwise.
+ * Returns true if {@link #getDriftNanosPerSecond()} is available, false otherwise.
*/
- public boolean hasDriftInNsPerSec() {
+ public boolean hasDriftNanosPerSecond() {
return isFlagSet(HAS_DRIFT);
}
/**
* Gets the clock's Drift in nanoseconds per second.
* A positive value indicates that the frequency is higher than the nominal frequency.
- * The reported drift includes {@link #getDriftUncertaintyInNsPerSec()}.
+ * The reported drift includes {@link #getDriftUncertaintyNanosPerSecond()}.
*
- * The value is only available if {@link #hasDriftInNsPerSec()} is true.
+ * The value is only available if {@link #hasDriftNanosPerSecond()} is true.
*/
- public double getDriftInNsPerSec() {
- return mDriftInNsPerSec;
+ public double getDriftNanosPerSecond() {
+ return mDriftNanosPerSecond;
}
/**
* Sets the clock's Drift in nanoseconds per second.
*/
- public void setDriftInNsPerSec(double driftInNsPerSec) {
+ public void setDriftNanosPerSecond(double driftNanosPerSecond) {
setFlag(HAS_DRIFT);
- mDriftInNsPerSec = driftInNsPerSec;
+ mDriftNanosPerSecond = driftNanosPerSecond;
}
/**
* Resets the clock's Drift in nanoseconds per second.
*/
- public void resetDriftInNsPerSec() {
+ public void resetDriftNanosPerSecond() {
resetFlag(HAS_DRIFT);
- mDriftInNsPerSec = Double.NaN;
+ mDriftNanosPerSecond = Double.NaN;
}
/**
- * Returns true if {@link #getDriftUncertaintyInNsPerSec()} is available, false otherwise.
+ * Returns true if {@link #getDriftUncertaintyNanosPerSecond()} is available, false otherwise.
*/
- public boolean hasDriftUncertaintyInNsPerSec() {
+ public boolean hasDriftUncertaintyNanosPerSecond() {
return isFlagSet(HAS_DRIFT_UNCERTAINTY);
}
/**
* Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
*
- * The value is only available if {@link #hasDriftUncertaintyInNsPerSec()} is true.
+ * The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is true.
*/
- public double getDriftUncertaintyInNsPerSec() {
- return mDriftUncertaintyInNsPerSec;
+ public double getDriftUncertaintyNanosPerSecond() {
+ return mDriftUncertaintyNanosPerSecond;
}
/**
* Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
*/
- public void setDriftUncertaintyInNsPerSec(double driftUncertaintyInNsPerSec) {
+ public void setDriftUncertaintyNanosPerSecond(double driftUncertaintyNanosPerSecond) {
setFlag(HAS_DRIFT_UNCERTAINTY);
- mDriftUncertaintyInNsPerSec = driftUncertaintyInNsPerSec;
+ mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond;
}
/**
@@ -347,9 +347,9 @@
/**
* Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
*/
- public void resetDriftUncertaintyInNsPerSec() {
+ public void resetDriftUncertaintyNanosPerSecond() {
resetFlag(HAS_DRIFT_UNCERTAINTY);
- mDriftUncertaintyInNsPerSec = Double.NaN;
+ mDriftUncertaintyNanosPerSecond = Double.NaN;
}
public static final Creator<GnssClock> CREATOR = new Creator<GnssClock>() {
@@ -357,15 +357,15 @@
public GnssClock createFromParcel(Parcel parcel) {
GnssClock gpsClock = new GnssClock();
- gpsClock.mFlags = (short) parcel.readInt();
- gpsClock.mLeapSecond = (short) parcel.readInt();
- gpsClock.mTimeInNs = parcel.readLong();
- gpsClock.mTimeUncertaintyInNs = parcel.readDouble();
- gpsClock.mFullBiasInNs = parcel.readLong();
- gpsClock.mBiasInNs = parcel.readDouble();
- gpsClock.mBiasUncertaintyInNs = parcel.readDouble();
- gpsClock.mDriftInNsPerSec = parcel.readDouble();
- gpsClock.mDriftUncertaintyInNsPerSec = parcel.readDouble();
+ gpsClock.mFlags = parcel.readInt();
+ gpsClock.mLeapSecond = parcel.readInt();
+ gpsClock.mTimeNanos = parcel.readLong();
+ gpsClock.mTimeUncertaintyNanos = parcel.readDouble();
+ gpsClock.mFullBiasNanos = parcel.readLong();
+ gpsClock.mBiasNanos = parcel.readDouble();
+ gpsClock.mBiasUncertaintyNanos = parcel.readDouble();
+ gpsClock.mDriftNanosPerSecond = parcel.readDouble();
+ gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble();
gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt();
return gpsClock;
@@ -381,13 +381,13 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mFlags);
parcel.writeInt(mLeapSecond);
- parcel.writeLong(mTimeInNs);
- parcel.writeDouble(mTimeUncertaintyInNs);
- parcel.writeLong(mFullBiasInNs);
- parcel.writeDouble(mBiasInNs);
- parcel.writeDouble(mBiasUncertaintyInNs);
- parcel.writeDouble(mDriftInNsPerSec);
- parcel.writeDouble(mDriftUncertaintyInNsPerSec);
+ parcel.writeLong(mTimeNanos);
+ parcel.writeDouble(mTimeUncertaintyNanos);
+ parcel.writeLong(mFullBiasNanos);
+ parcel.writeDouble(mBiasNanos);
+ parcel.writeDouble(mBiasUncertaintyNanos);
+ parcel.writeDouble(mDriftNanosPerSecond);
+ parcel.writeDouble(mDriftUncertaintyNanosPerSecond);
parcel.writeInt(mHardwareClockDiscontinuityCount);
}
@@ -406,29 +406,29 @@
builder.append(String.format(
formatWithUncertainty,
- "TimeInNs",
- mTimeInNs,
- "TimeUncertaintyInNs",
- hasTimeUncertaintyInNs() ? mTimeUncertaintyInNs : null));
+ "TimeNanos",
+ mTimeNanos,
+ "TimeUncertaintyNanos",
+ hasTimeUncertaintyNanos() ? mTimeUncertaintyNanos : null));
builder.append(String.format(
format,
- "FullBiasInNs",
- hasFullBiasInNs() ? mFullBiasInNs : null));
+ "FullBiasNanos",
+ hasFullBiasNanos() ? mFullBiasNanos : null));
builder.append(String.format(
formatWithUncertainty,
- "BiasInNs",
- hasBiasInNs() ? mBiasInNs : null,
- "BiasUncertaintyInNs",
- hasBiasUncertaintyInNs() ? mBiasUncertaintyInNs : null));
+ "BiasNanos",
+ hasBiasNanos() ? mBiasNanos : null,
+ "BiasUncertaintyNanos",
+ hasBiasUncertaintyNanos() ? mBiasUncertaintyNanos : null));
builder.append(String.format(
formatWithUncertainty,
- "DriftInNsPerSec",
- hasDriftInNsPerSec() ? mDriftInNsPerSec : null,
- "DriftUncertaintyInNsPerSec",
- hasDriftUncertaintyInNsPerSec() ? mDriftUncertaintyInNsPerSec : null));
+ "DriftNanosPerSecond",
+ hasDriftNanosPerSecond() ? mDriftNanosPerSecond : null,
+ "DriftUncertaintyNanosPerSecond",
+ hasDriftUncertaintyNanosPerSecond() ? mDriftUncertaintyNanosPerSecond : null));
return builder.toString();
}
@@ -436,25 +436,25 @@
private void initialize() {
mFlags = HAS_NO_FLAGS;
resetLeapSecond();
- setTimeInNs(Long.MIN_VALUE);
- resetTimeUncertaintyInNs();
- resetFullBiasInNs();
- resetBiasInNs();
- resetBiasUncertaintyInNs();
- resetDriftInNsPerSec();
- resetDriftUncertaintyInNsPerSec();
+ setTimeNanos(Long.MIN_VALUE);
+ resetTimeUncertaintyNanos();
+ resetFullBiasNanos();
+ resetBiasNanos();
+ resetBiasUncertaintyNanos();
+ resetDriftNanosPerSecond();
+ resetDriftUncertaintyNanosPerSecond();
setHardwareClockDiscontinuityCount(Integer.MIN_VALUE);
}
- private void setFlag(short flag) {
+ private void setFlag(int flag) {
mFlags |= flag;
}
- private void resetFlag(short flag) {
+ private void resetFlag(int flag) {
mFlags &= ~flag;
}
- private boolean isFlagSet(short flag) {
+ private boolean isFlagSet(int flag) {
return (mFlags & flag) == flag;
}
}
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index abdc13c..367c52f 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -28,82 +28,35 @@
*/
public final class GnssMeasurement implements Parcelable {
private int mFlags;
- private short mSvid;
- private byte mConstellationType;
- private double mTimeOffsetInNs;
- private short mState;
- private long mReceivedSvTimeInNs;
- private long mReceivedSvTimeUncertaintyInNs;
- private double mCn0InDbHz;
- private double mPseudorangeRateInMetersPerSec;
- private double mPseudorangeRateUncertaintyInMetersPerSec;
- private short mAccumulatedDeltaRangeState;
- private double mAccumulatedDeltaRangeInMeters;
- private double mAccumulatedDeltaRangeUncertaintyInMeters;
- private double mPseudorangeInMeters;
- private double mPseudorangeUncertaintyInMeters;
- private double mCodePhaseInChips;
- private double mCodePhaseUncertaintyInChips;
- private float mCarrierFrequencyInHz;
+ private int mSvid;
+ private int mConstellationType;
+ private double mTimeOffsetNanos;
+ private int mState;
+ private long mReceivedSvTimeNanos;
+ private long mReceivedSvTimeUncertaintyNanos;
+ private double mCn0DbHz;
+ private double mPseudorangeRateMetersPerSecond;
+ private double mPseudorangeRateUncertaintyMetersPerSecond;
+ private int mAccumulatedDeltaRangeState;
+ private double mAccumulatedDeltaRangeMeters;
+ private double mAccumulatedDeltaRangeUncertaintyMeters;
+ private float mCarrierFrequencyHz;
private long mCarrierCycles;
private double mCarrierPhase;
private double mCarrierPhaseUncertainty;
- private byte mLossOfLock;
- private int mBitNumber;
- private short mTimeFromLastBitInMs;
- private double mDopplerShiftInHz;
- private double mDopplerShiftUncertaintyInHz;
- private byte mMultipathIndicator;
+ private int mMultipathIndicator;
private double mSnrInDb;
- private double mElevationInDeg;
- private double mElevationUncertaintyInDeg;
- private double mAzimuthInDeg;
- private double mAzimuthUncertaintyInDeg;
- private boolean mUsedInFix;
// The following enumerations must be in sync with the values declared in gps.h
private static final int HAS_NO_FLAGS = 0;
private static final int HAS_SNR = (1<<0);
- private static final int HAS_ELEVATION = (1<<1);
- private static final int HAS_ELEVATION_UNCERTAINTY = (1<<2);
- private static final int HAS_AZIMUTH = (1<<3);
- private static final int HAS_AZIMUTH_UNCERTAINTY = (1<<4);
- private static final int HAS_PSEUDORANGE = (1<<5);
- private static final int HAS_PSEUDORANGE_UNCERTAINTY = (1<<6);
- private static final int HAS_CODE_PHASE = (1<<7);
- private static final int HAS_CODE_PHASE_UNCERTAINTY = (1<<8);
private static final int HAS_CARRIER_FREQUENCY = (1<<9);
private static final int HAS_CARRIER_CYCLES = (1<<10);
private static final int HAS_CARRIER_PHASE = (1<<11);
private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
- private static final int HAS_BIT_NUMBER = (1<<13);
- private static final int HAS_TIME_FROM_LAST_BIT = (1<<14);
- private static final int HAS_DOPPLER_SHIFT = (1<<15);
- private static final int HAS_DOPPLER_SHIFT_UNCERTAINTY = (1<<16);
- // private static final int HAS_USED_IN_FIX = (1<<17);
private static final int HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18);
- /** The status of 'loss of lock'. */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({LOSS_OF_LOCK_UNKNOWN, LOSS_OF_LOCK_OK, LOSS_OF_LOCK_CYCLE_SLIP})
- public @interface LossOfLockStatus {}
-
- /**
- * The indicator is not available or it is unknown.
- */
- public static final byte LOSS_OF_LOCK_UNKNOWN = 0;
-
- /**
- * The measurement does not present any indication of 'loss of lock'.
- */
- public static final byte LOSS_OF_LOCK_OK = 1;
-
- /**
- * 'Loss of lock' detected between the previous and current observation: cycle slip possible.
- */
- public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2;
-
/** The status of multipath. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({MULTIPATH_INDICATOR_UNKNOWN, MULTIPATH_INDICATOR_DETECTED,
@@ -113,78 +66,78 @@
/**
* The indicator is not available or it is unknown.
*/
- public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0;
+ public static final int MULTIPATH_INDICATOR_UNKNOWN = 0;
/**
* The measurement has been indicated to use multi-path.
*/
- public static final byte MULTIPATH_INDICATOR_DETECTED = 1;
+ public static final int MULTIPATH_INDICATOR_DETECTED = 1;
/**
* The measurement has been indicated not tu use multi-path.
*/
- public static final byte MULTIPATH_INDICATOR_NOT_USED = 2;
+ public static final int MULTIPATH_INDICATOR_NOT_USED = 2;
/**
* The state of GNSS receiver the measurement is invalid or unknown.
*/
- public static final short STATE_UNKNOWN = 0;
+ public static final int STATE_UNKNOWN = 0;
/**
* The state of the GNSS receiver is ranging code lock.
*/
- public static final short STATE_CODE_LOCK = (1<<0);
+ public static final int STATE_CODE_LOCK = (1<<0);
/**
* The state of the GNSS receiver is in bit sync.
*/
- public static final short STATE_BIT_SYNC = (1<<1);
+ public static final int STATE_BIT_SYNC = (1<<1);
/**
*The state of the GNSS receiver is in sub-frame sync.
*/
- public static final short STATE_SUBFRAME_SYNC = (1<<2);
+ public static final int STATE_SUBFRAME_SYNC = (1<<2);
/**
* The state of the GNSS receiver has TOW decoded.
*/
- public static final short STATE_TOW_DECODED = (1<<3);
+ public static final int STATE_TOW_DECODED = (1<<3);
/**
* The state of the GNSS receiver contains millisecond ambiguity.
*/
- public static final short STATE_MSEC_AMBIGUOUS = (1<<4);
+ public static final int STATE_MSEC_AMBIGUOUS = (1<<4);
/**
* All the GNSS receiver state flags.
*/
- private static final short STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
+ private static final int STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
| STATE_TOW_DECODED | STATE_MSEC_AMBIGUOUS;
/**
* The state of the 'Accumulated Delta Range' is invalid or unknown.
*/
- public static final short ADR_STATE_UNKNOWN = 0;
+ public static final int ADR_STATE_UNKNOWN = 0;
/**
* The state of the 'Accumulated Delta Range' is valid.
*/
- public static final short ADR_STATE_VALID = (1<<0);
+ public static final int ADR_STATE_VALID = (1<<0);
/**
* The state of the 'Accumulated Delta Range' has detected a reset.
*/
- public static final short ADR_STATE_RESET = (1<<1);
+ public static final int ADR_STATE_RESET = (1<<1);
/**
* The state of the 'Accumulated Delta Range' has a cycle slip detected.
*/
- public static final short ADR_STATE_CYCLE_SLIP = (1<<2);
+ public static final int ADR_STATE_CYCLE_SLIP = (1<<2);
/**
* All the 'Accumulated Delta Range' flags.
*/
- private static final short ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
+ private static final int ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
// End enumerations in sync with gps.h
@@ -199,38 +152,24 @@
mFlags = measurement.mFlags;
mSvid = measurement.mSvid;
mConstellationType = measurement.mConstellationType;
- mTimeOffsetInNs = measurement.mTimeOffsetInNs;
+ mTimeOffsetNanos = measurement.mTimeOffsetNanos;
mState = measurement.mState;
- mReceivedSvTimeInNs = measurement.mReceivedSvTimeInNs;
- mReceivedSvTimeUncertaintyInNs = measurement.mReceivedSvTimeUncertaintyInNs;
- mCn0InDbHz = measurement.mCn0InDbHz;
- mPseudorangeRateInMetersPerSec = measurement.mPseudorangeRateInMetersPerSec;
- mPseudorangeRateUncertaintyInMetersPerSec =
- measurement.mPseudorangeRateUncertaintyInMetersPerSec;
+ mReceivedSvTimeNanos = measurement.mReceivedSvTimeNanos;
+ mReceivedSvTimeUncertaintyNanos = measurement.mReceivedSvTimeUncertaintyNanos;
+ mCn0DbHz = measurement.mCn0DbHz;
+ mPseudorangeRateMetersPerSecond = measurement.mPseudorangeRateMetersPerSecond;
+ mPseudorangeRateUncertaintyMetersPerSecond =
+ measurement.mPseudorangeRateUncertaintyMetersPerSecond;
mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
- mAccumulatedDeltaRangeInMeters = measurement.mAccumulatedDeltaRangeInMeters;
- mAccumulatedDeltaRangeUncertaintyInMeters =
- measurement.mAccumulatedDeltaRangeUncertaintyInMeters;
- mPseudorangeInMeters = measurement.mPseudorangeInMeters;
- mPseudorangeUncertaintyInMeters = measurement.mPseudorangeUncertaintyInMeters;
- mCodePhaseInChips = measurement.mCodePhaseInChips;
- mCodePhaseUncertaintyInChips = measurement.mCodePhaseUncertaintyInChips;
- mCarrierFrequencyInHz = measurement.mCarrierFrequencyInHz;
+ mAccumulatedDeltaRangeMeters = measurement.mAccumulatedDeltaRangeMeters;
+ mAccumulatedDeltaRangeUncertaintyMeters =
+ measurement.mAccumulatedDeltaRangeUncertaintyMeters;
+ mCarrierFrequencyHz = measurement.mCarrierFrequencyHz;
mCarrierCycles = measurement.mCarrierCycles;
mCarrierPhase = measurement.mCarrierPhase;
mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
- mLossOfLock = measurement.mLossOfLock;
- mBitNumber = measurement.mBitNumber;
- mTimeFromLastBitInMs = measurement.mTimeFromLastBitInMs;
- mDopplerShiftInHz = measurement.mDopplerShiftInHz;
- mDopplerShiftUncertaintyInHz = measurement.mDopplerShiftUncertaintyInHz;
mMultipathIndicator = measurement.mMultipathIndicator;
mSnrInDb = measurement.mSnrInDb;
- mElevationInDeg = measurement.mElevationInDeg;
- mElevationUncertaintyInDeg = measurement.mElevationUncertaintyInDeg;
- mAzimuthInDeg = measurement.mAzimuthInDeg;
- mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg;
- mUsedInFix = measurement.mUsedInFix;
}
/**
@@ -244,14 +183,14 @@
* Gets the Pseudo-random number (PRN).
* Range: [1, 32]
*/
- public short getSvid() {
+ public int getSvid() {
return mSvid;
}
/**
* Sets the Pseud-random number (PRN).
*/
- public void setSvid(short value) {
+ public void setSvid(int value) {
mSvid = value;
}
@@ -259,14 +198,14 @@
* Getst the constellation type.
*/
@GnssStatus.ConstellationType
- public byte getConstellationType() {
+ public int getConstellationType() {
return mConstellationType;
}
/**
* Sets the constellation type.
*/
- public void setConstellationType(@GnssStatus.ConstellationType byte value) {
+ public void setConstellationType(@GnssStatus.ConstellationType int value) {
mConstellationType = value;
}
@@ -274,7 +213,7 @@
* Gets the time offset at which the measurement was taken in nanoseconds.
*
* The reference receiver's time from which this is offset is specified by
- * {@link GnssClock#getTimeInNs()}.
+ * {@link GnssClock#getTimeNanos()}.
*
* The sign of this value is given by the following equation:
* measurement time = time_ns + time_offset_ns
@@ -282,31 +221,31 @@
* The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
* accuracy.
*/
- public double getTimeOffsetInNs() {
- return mTimeOffsetInNs;
+ public double getTimeOffsetNanos() {
+ return mTimeOffsetNanos;
}
/**
* Sets the time offset at which the measurement was taken in nanoseconds.
*/
- public void setTimeOffsetInNs(double value) {
- mTimeOffsetInNs = value;
+ public void setTimeOffsetNanos(double value) {
+ mTimeOffsetNanos = value;
}
/**
* Gets per-satellite sync state.
* It represents the current sync state for the associated satellite.
*
- * This value helps interpret {@link #getReceivedSvTimeInNs()}.
+ * This value helps interpret {@link #getReceivedSvTimeNanos()}.
*/
- public short getState() {
+ public int getState() {
return mState;
}
/**
* Sets the sync state.
*/
- public void setState(short value) {
+ public void setState(int value) {
mState = value;
}
@@ -408,29 +347,29 @@
* Symbol sync : [ 0 2ms ] : STATE_SYMBOL_SYNC is set
* Message : [ 0 1s ] : STATE_SBAS_SYNC is set
*/
- public long getReceivedSvTimeInNs() {
- return mReceivedSvTimeInNs;
+ public long getReceivedSvTimeNanos() {
+ return mReceivedSvTimeNanos;
}
/**
* Sets the received GNSS time in nanoseconds.
*/
- public void setReceivedSvTimeInNs(long value) {
- mReceivedSvTimeInNs = value;
+ public void setReceivedSvTimeNanos(long value) {
+ mReceivedSvTimeNanos = value;
}
/**
* Gets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
*/
- public long getReceivedSvTimeUncertaintyInNs() {
- return mReceivedSvTimeUncertaintyInNs;
+ public long getReceivedSvTimeUncertaintyNanos() {
+ return mReceivedSvTimeUncertaintyNanos;
}
/**
* Sets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
*/
- public void setReceivedSvTimeUncertaintyInNs(long value) {
- mReceivedSvTimeUncertaintyInNs = value;
+ public void setReceivedSvTimeUncertaintyNanos(long value) {
+ mReceivedSvTimeUncertaintyNanos = value;
}
/**
@@ -439,45 +378,46 @@
*
* The value contains the measured C/N0 for the signal at the antenna input.
*/
- public double getCn0InDbHz() {
- return mCn0InDbHz;
+ public double getCn0DbHz() {
+ return mCn0DbHz;
}
/**
* Sets the carrier-to-noise density in dB-Hz.
*/
- public void setCn0InDbHz(double value) {
- mCn0InDbHz = value;
+ public void setCn0DbHz(double value) {
+ mCn0DbHz = value;
}
/**
* Gets the Pseudorange rate at the timestamp in m/s.
- * The reported value includes {@link #getPseudorangeRateUncertaintyInMetersPerSec()}.
*
- * The correction of a given Pseudorange Rate value includes corrections from receiver and
- * satellite clock frequency errors.
- * {@link #isPseudorangeRateCorrected()} identifies the type of value reported.
+ * The reported value includes {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
*
- * A positive 'uncorrected' value indicates that the SV is moving away from the receiver.
- * The sign of the 'uncorrected' Pseudorange Rate and its relation to the sign of
- * {@link #getDopplerShiftInHz()} is given by the equation:
+ * The value is uncorrected, hence corrections for receiver and satellite clock frequency errors
+ * should not be included.
+ *
+ * A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
+ * sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler shift'
+ * is given by the equation:
+ *
* pseudorange rate = -k * doppler shift (where k is a constant)
*/
- public double getPseudorangeRateInMetersPerSec() {
- return mPseudorangeRateInMetersPerSec;
+ public double getPseudorangeRateMetersPerSecond() {
+ return mPseudorangeRateMetersPerSecond;
}
/**
* Sets the pseudorange rate at the timestamp in m/s.
*/
- public void setPseudorangeRateInMetersPerSec(double value) {
- mPseudorangeRateInMetersPerSec = value;
+ public void setPseudorangeRateMetersPerSecond(double value) {
+ mPseudorangeRateMetersPerSecond = value;
}
/**
- * See {@link #getPseudorangeRateInMetersPerSec()} for more details.
+ * See {@link #getPseudorangeRateMetersPerSecond()} for more details.
*
- * @return {@code true} if {@link #getPseudorangeRateInMetersPerSec()} contains a corrected
+ * @return {@code true} if {@link #getPseudorangeRateMetersPerSecond()} contains a corrected
* value, {@code false} if it contains an uncorrected value.
*/
public boolean isPseudorangeRateCorrected() {
@@ -488,30 +428,30 @@
* Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
* The uncertainty is represented as an absolute (single sided) value.
*/
- public double getPseudorangeRateUncertaintyInMetersPerSec() {
- return mPseudorangeRateUncertaintyInMetersPerSec;
+ public double getPseudorangeRateUncertaintyMetersPerSecond() {
+ return mPseudorangeRateUncertaintyMetersPerSecond;
}
/**
* Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
*/
- public void setPseudorangeRateUncertaintyInMetersPerSec(double value) {
- mPseudorangeRateUncertaintyInMetersPerSec = value;
+ public void setPseudorangeRateUncertaintyMetersPerSecond(double value) {
+ mPseudorangeRateUncertaintyMetersPerSecond = value;
}
/**
* Gets 'Accumulated Delta Range' state.
- * It indicates whether {@link #getAccumulatedDeltaRangeInMeters()} is reset or there is a
+ * It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
* cycle slip (indicating 'loss of lock').
*/
- public short getAccumulatedDeltaRangeState() {
+ public int getAccumulatedDeltaRangeState() {
return mAccumulatedDeltaRangeState;
}
/**
* Sets the 'Accumulated Delta Range' state.
*/
- public void setAccumulatedDeltaRangeState(short value) {
+ public void setAccumulatedDeltaRangeState(int value) {
mAccumulatedDeltaRangeState = value;
}
@@ -545,24 +485,24 @@
/**
* Gets the accumulated delta range since the last channel reset, in meters.
- * The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyInMeters()}.
+ * The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
*
* The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*
* A positive value indicates that the SV is moving away from the receiver.
- * The sign of {@link #getAccumulatedDeltaRangeInMeters()} and its relation to the sign of
+ * The sign of {@link #getAccumulatedDeltaRangeMeters()} and its relation to the sign of
* {@link #getCarrierPhase()} is given by the equation:
* accumulated delta range = -k * carrier phase (where k is a constant)
*/
- public double getAccumulatedDeltaRangeInMeters() {
- return mAccumulatedDeltaRangeInMeters;
+ public double getAccumulatedDeltaRangeMeters() {
+ return mAccumulatedDeltaRangeMeters;
}
/**
* Sets the accumulated delta range in meters.
*/
- public void setAccumulatedDeltaRangeInMeters(double value) {
- mAccumulatedDeltaRangeInMeters = value;
+ public void setAccumulatedDeltaRangeMeters(double value) {
+ mAccumulatedDeltaRangeMeters = value;
}
/**
@@ -571,8 +511,8 @@
*
* The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*/
- public double getAccumulatedDeltaRangeUncertaintyInMeters() {
- return mAccumulatedDeltaRangeUncertaintyInMeters;
+ public double getAccumulatedDeltaRangeUncertaintyMeters() {
+ return mAccumulatedDeltaRangeUncertaintyMeters;
}
/**
@@ -580,149 +520,14 @@
*
* The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
*/
- public void setAccumulatedDeltaRangeUncertaintyInMeters(double value) {
- mAccumulatedDeltaRangeUncertaintyInMeters = value;
+ public void setAccumulatedDeltaRangeUncertaintyMeters(double value) {
+ mAccumulatedDeltaRangeUncertaintyMeters = value;
}
/**
- * Returns true if {@link #getPseudorangeInMeters()} is available, false otherwise.
+ * Returns true if {@link #getCarrierFrequencyHz()} is available, false otherwise.
*/
- public boolean hasPseudorangeInMeters() {
- return isFlagSet(HAS_PSEUDORANGE);
- }
-
- /**
- * Gets the best derived pseudorange by the chipset, in meters.
- * The reported pseudorange includes {@link #getPseudorangeUncertaintyInMeters()}.
- *
- * The value is only available if {@link #hasPseudorangeInMeters()} is true.
- */
- public double getPseudorangeInMeters() {
- return mPseudorangeInMeters;
- }
-
- /**
- * Sets the Pseudo-range in meters.
- */
- public void setPseudorangeInMeters(double value) {
- setFlag(HAS_PSEUDORANGE);
- mPseudorangeInMeters = value;
- }
-
- /**
- * Resets the Pseudo-range in meters.
- */
- public void resetPseudorangeInMeters() {
- resetFlag(HAS_PSEUDORANGE);
- mPseudorangeInMeters = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getPseudorangeUncertaintyInMeters()} is available, false otherwise.
- */
- public boolean hasPseudorangeUncertaintyInMeters() {
- return isFlagSet(HAS_PSEUDORANGE_UNCERTAINTY);
- }
-
- /**
- * Gets the pseudorange's uncertainty (1-Sigma) in meters.
- * The value contains the 'pseudorange' and 'clock' uncertainty in it.
- * The uncertainty is represented as an absolute (single sided) value.
- *
- * The value is only available if {@link #hasPseudorangeUncertaintyInMeters()} is true.
- */
- public double getPseudorangeUncertaintyInMeters() {
- return mPseudorangeUncertaintyInMeters;
- }
-
- /**
- * Sets the pseudo-range's uncertainty (1-Sigma) in meters.
- */
- public void setPseudorangeUncertaintyInMeters(double value) {
- setFlag(HAS_PSEUDORANGE_UNCERTAINTY);
- mPseudorangeUncertaintyInMeters = value;
- }
-
- /**
- * Resets the pseudo-range's uncertainty (1-Sigma) in meters.
- */
- public void resetPseudorangeUncertaintyInMeters() {
- resetFlag(HAS_PSEUDORANGE_UNCERTAINTY);
- mPseudorangeUncertaintyInMeters = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getCodePhaseInChips()} is available, false otherwise.
- */
- public boolean hasCodePhaseInChips() {
- return isFlagSet(HAS_CODE_PHASE);
- }
-
- /**
- * Gets the fraction of the current C/A code cycle.
- * Range: [0, 1023]
- * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
- * The reported code-phase includes {@link #getCodePhaseUncertaintyInChips()}.
- *
- * The value is only available if {@link #hasCodePhaseInChips()} is true.
- */
- public double getCodePhaseInChips() {
- return mCodePhaseInChips;
- }
-
- /**
- * Sets the Code-phase in chips.
- */
- public void setCodePhaseInChips(double value) {
- setFlag(HAS_CODE_PHASE);
- mCodePhaseInChips = value;
- }
-
- /**
- * Resets the Code-phase in chips.
- */
- public void resetCodePhaseInChips() {
- resetFlag(HAS_CODE_PHASE);
- mCodePhaseInChips = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getCodePhaseUncertaintyInChips()} is available, false otherwise.
- */
- public boolean hasCodePhaseUncertaintyInChips() {
- return isFlagSet(HAS_CODE_PHASE_UNCERTAINTY);
- }
-
- /**
- * Gets the code-phase's uncertainty (1-Sigma) as a fraction of chips.
- * The uncertainty is represented as an absolute (single sided) value.
- *
- * The value is only available if {@link #hasCodePhaseUncertaintyInChips()} is true.
- */
- public double getCodePhaseUncertaintyInChips() {
- return mCodePhaseUncertaintyInChips;
- }
-
- /**
- * Sets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
- */
- public void setCodePhaseUncertaintyInChips(double value) {
- setFlag(HAS_CODE_PHASE_UNCERTAINTY);
- mCodePhaseUncertaintyInChips = value;
- }
-
- /**
- * Resets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
- */
- public void resetCodePhaseUncertaintyInChips() {
- resetFlag(HAS_CODE_PHASE_UNCERTAINTY);
- mCodePhaseUncertaintyInChips = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getCarrierFrequencyInHz()} is available, false otherwise.
- */
- public boolean hasCarrierFrequencyInHz() {
+ public boolean hasCarrierFrequencyHz() {
return isFlagSet(HAS_CARRIER_FREQUENCY);
}
@@ -730,26 +535,26 @@
* Gets the carrier frequency at which codes and messages are modulated, it can be L1 or L2.
* If the field is not set, the carrier frequency corresponds to L1.
*
- * The value is only available if {@link #hasCarrierFrequencyInHz()} is true.
+ * The value is only available if {@link #hasCarrierFrequencyHz()} is true.
*/
- public float getCarrierFrequencyInHz() {
- return mCarrierFrequencyInHz;
+ public float getCarrierFrequencyHz() {
+ return mCarrierFrequencyHz;
}
/**
* Sets the Carrier frequency (L1 or L2) in Hz.
*/
- public void setCarrierFrequencyInHz(float carrierFrequencyInHz) {
+ public void setCarrierFrequencyHz(float carrierFrequencyHz) {
setFlag(HAS_CARRIER_FREQUENCY);
- mCarrierFrequencyInHz = carrierFrequencyInHz;
+ mCarrierFrequencyHz = carrierFrequencyHz;
}
/**
* Resets the Carrier frequency (L1 or L2) in Hz.
*/
- public void resetCarrierFrequencyInHz() {
+ public void resetCarrierFrequencyHz() {
resetFlag(HAS_CARRIER_FREQUENCY);
- mCarrierFrequencyInHz = Float.NaN;
+ mCarrierFrequencyHz = Float.NaN;
}
/**
@@ -761,7 +566,7 @@
/**
* The number of full carrier cycles between the satellite and the receiver.
- * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
+ * The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
*
* The value is only available if {@link #hasCarrierCycles()} is true.
*/
@@ -797,7 +602,7 @@
* Range: [0.0, 1.0].
* This is usually the fractional part of the complete carrier phase measurement.
*
- * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
+ * The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
* The reported carrier-phase includes {@link #getCarrierPhaseUncertainty()}.
*
* The value is only available if {@link #hasCarrierPhase()} is true.
@@ -856,183 +661,17 @@
}
/**
- * Gets a value indicating the 'loss of lock' state of the event.
- */
- @LossOfLockStatus
- public byte getLossOfLock() {
- return mLossOfLock;
- }
-
- /**
- * Sets the 'loss of lock' status.
- */
- public void setLossOfLock(@LossOfLockStatus byte value) {
- mLossOfLock = value;
- }
-
- /**
- * Gets a string representation of the 'loss of lock'.
- * For internal and logging use only.
- */
- private String getLossOfLockString() {
- switch (mLossOfLock) {
- case LOSS_OF_LOCK_UNKNOWN:
- return "Unknown";
- case LOSS_OF_LOCK_OK:
- return "Ok";
- case LOSS_OF_LOCK_CYCLE_SLIP:
- return "CycleSlip";
- default:
- return "<Invalid:" + mLossOfLock + ">";
- }
- }
-
- /**
- * Returns true if {@link #getBitNumber()} is available, false otherwise.
- */
- public boolean hasBitNumber() {
- return isFlagSet(HAS_BIT_NUMBER);
- }
-
- /**
- * Gets the number of GPS bits transmitted since Sat-Sun midnight (GPS week).
- *
- * The value is only available if {@link #hasBitNumber()} is true.
- */
- public int getBitNumber() {
- return mBitNumber;
- }
-
- /**
- * Sets the bit number within the broadcast frame.
- */
- public void setBitNumber(int bitNumber) {
- setFlag(HAS_BIT_NUMBER);
- mBitNumber = bitNumber;
- }
-
- /**
- * Resets the bit number within the broadcast frame.
- */
- public void resetBitNumber() {
- resetFlag(HAS_BIT_NUMBER);
- mBitNumber = Integer.MIN_VALUE;
- }
-
- /**
- * Returns true if {@link #getTimeFromLastBitInMs()} is available, false otherwise.
- */
- public boolean hasTimeFromLastBitInMs() {
- return isFlagSet(HAS_TIME_FROM_LAST_BIT);
- }
-
- /**
- * Gets the elapsed time since the last received bit in milliseconds.
- * Range: [0, 20].
- *
- * The value is only available if {@link #hasTimeFromLastBitInMs()} is true.
- */
- public short getTimeFromLastBitInMs() {
- return mTimeFromLastBitInMs;
- }
-
- /**
- * Sets the elapsed time since the last received bit in milliseconds.
- */
- public void setTimeFromLastBitInMs(short value) {
- setFlag(HAS_TIME_FROM_LAST_BIT);
- mTimeFromLastBitInMs = value;
- }
-
- /**
- * Resets the elapsed time since the last received bit in milliseconds.
- */
- public void resetTimeFromLastBitInMs() {
- resetFlag(HAS_TIME_FROM_LAST_BIT);
- mTimeFromLastBitInMs = Short.MIN_VALUE;
- }
-
- /**
- * Returns true if {@link #getDopplerShiftInHz()} is available, false otherwise.
- */
- public boolean hasDopplerShiftInHz() {
- return isFlagSet(HAS_DOPPLER_SHIFT);
- }
-
- /**
- * Gets the Doppler Shift in Hz.
- * A positive value indicates that the SV is moving toward the receiver.
- *
- * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
- * The reported doppler shift includes {@link #getDopplerShiftUncertaintyInHz()}.
- *
- * The value is only available if {@link #hasDopplerShiftInHz()} is true.
- */
- public double getDopplerShiftInHz() {
- return mDopplerShiftInHz;
- }
-
- /**
- * Sets the Doppler shift in Hz.
- */
- public void setDopplerShiftInHz(double value) {
- setFlag(HAS_DOPPLER_SHIFT);
- mDopplerShiftInHz = value;
- }
-
- /**
- * Resets the Doppler shift in Hz.
- */
- public void resetDopplerShiftInHz() {
- resetFlag(HAS_DOPPLER_SHIFT);
- mDopplerShiftInHz = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getDopplerShiftUncertaintyInHz()} is available, false otherwise.
- */
- public boolean hasDopplerShiftUncertaintyInHz() {
- return isFlagSet(HAS_DOPPLER_SHIFT_UNCERTAINTY);
- }
-
- /**
- * Gets the Doppler's Shift uncertainty (1-Sigma) in Hz.
- * The uncertainty is represented as an absolute (single sided) value.
- *
- * The value is only available if {@link #hasDopplerShiftUncertaintyInHz()} is true.
- */
- public double getDopplerShiftUncertaintyInHz() {
- return mDopplerShiftUncertaintyInHz;
- }
-
- /**
- * Sets the Doppler's shift uncertainty (1-Sigma) in Hz.
- */
- public void setDopplerShiftUncertaintyInHz(double value) {
- setFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
- mDopplerShiftUncertaintyInHz = value;
- }
-
- /**
- * Resets the Doppler's shift uncertainty (1-Sigma) in Hz.
- */
- public void resetDopplerShiftUncertaintyInHz() {
- resetFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
- mDopplerShiftUncertaintyInHz = Double.NaN;
- }
-
- /**
* Gets a value indicating the 'multipath' state of the event.
*/
@MultipathIndicator
- public byte getMultipathIndicator() {
+ public int getMultipathIndicator() {
return mMultipathIndicator;
}
/**
* Sets the 'multi-path' indicator.
*/
- public void setMultipathIndicator(@MultipathIndicator byte value) {
+ public void setMultipathIndicator(@MultipathIndicator int value) {
mMultipathIndicator = value;
}
@@ -1085,200 +724,30 @@
mSnrInDb = Double.NaN;
}
- /**
- * Returns true if {@link #getElevationInDeg()} is available, false otherwise.
- */
- public boolean hasElevationInDeg() {
- return isFlagSet(HAS_ELEVATION);
- }
-
- /**
- * Gets the Elevation in degrees.
- * Range: [-90, 90]
- * The reported elevation includes {@link #getElevationUncertaintyInDeg()}.
- *
- * The value is only available if {@link #hasElevationInDeg()} is true.
- */
- public double getElevationInDeg() {
- return mElevationInDeg;
- }
-
- /**
- * Sets the Elevation in degrees.
- */
- public void setElevationInDeg(double elevationInDeg) {
- setFlag(HAS_ELEVATION);
- mElevationInDeg = elevationInDeg;
- }
-
- /**
- * Resets the Elevation in degrees.
- */
- public void resetElevationInDeg() {
- resetFlag(HAS_ELEVATION);
- mElevationInDeg = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getElevationUncertaintyInDeg()} is available, false otherwise.
- */
- public boolean hasElevationUncertaintyInDeg() {
- return isFlagSet(HAS_ELEVATION_UNCERTAINTY);
- }
-
- /**
- * Gets the elevation's uncertainty (1-Sigma) in degrees.
- * Range: [0, 90]
- *
- * The uncertainty is represented as an absolute (single sided) value.
- *
- * The value is only available if {@link #hasElevationUncertaintyInDeg()} is true.
- */
- public double getElevationUncertaintyInDeg() {
- return mElevationUncertaintyInDeg;
- }
-
- /**
- * Sets the elevation's uncertainty (1-Sigma) in degrees.
- */
- public void setElevationUncertaintyInDeg(double value) {
- setFlag(HAS_ELEVATION_UNCERTAINTY);
- mElevationUncertaintyInDeg = value;
- }
-
- /**
- * Resets the elevation's uncertainty (1-Sigma) in degrees.
- */
- public void resetElevationUncertaintyInDeg() {
- resetFlag(HAS_ELEVATION_UNCERTAINTY);
- mElevationUncertaintyInDeg = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getAzimuthInDeg()} is available, false otherwise.
- */
- public boolean hasAzimuthInDeg() {
- return isFlagSet(HAS_AZIMUTH);
- }
-
- /**
- * Gets the azimuth in degrees.
- * Range: [0, 360).
- *
- * The reported azimuth includes {@link #getAzimuthUncertaintyInDeg()}.
- *
- * The value is only available if {@link #hasAzimuthInDeg()} is true.
- */
- public double getAzimuthInDeg() {
- return mAzimuthInDeg;
- }
-
- /**
- * Sets the Azimuth in degrees.
- */
- public void setAzimuthInDeg(double value) {
- setFlag(HAS_AZIMUTH);
- mAzimuthInDeg = value;
- }
-
- /**
- * Resets the Azimuth in degrees.
- */
- public void resetAzimuthInDeg() {
- resetFlag(HAS_AZIMUTH);
- mAzimuthInDeg = Double.NaN;
- }
-
- /**
- * Returns true if {@link #getAzimuthUncertaintyInDeg()} is available, false otherwise.
- */
- public boolean hasAzimuthUncertaintyInDeg() {
- return isFlagSet(HAS_AZIMUTH_UNCERTAINTY);
- }
-
- /**
- * Gets the azimuth's uncertainty (1-Sigma) in degrees.
- * Range: [0, 180].
- *
- * The uncertainty is represented as an absolute (single sided) value.
- *
- * The value is only available if {@link #hasAzimuthUncertaintyInDeg()} is true.
- */
- public double getAzimuthUncertaintyInDeg() {
- return mAzimuthUncertaintyInDeg;
- }
-
- /**
- * Sets the Azimuth's uncertainty (1-Sigma) in degrees.
- */
- public void setAzimuthUncertaintyInDeg(double value) {
- setFlag(HAS_AZIMUTH_UNCERTAINTY);
- mAzimuthUncertaintyInDeg = value;
- }
-
- /**
- * Resets the Azimuth's uncertainty (1-Sigma) in degrees.
- */
- public void resetAzimuthUncertaintyInDeg() {
- resetFlag(HAS_AZIMUTH_UNCERTAINTY);
- mAzimuthUncertaintyInDeg = Double.NaN;
- }
-
- /**
- * Gets a flag indicating whether the GNSS represented by the measurement was used for computing
- * the most recent fix.
- *
- * @return A non-null value if the data is available, null otherwise.
- */
- public boolean isUsedInFix() {
- return mUsedInFix;
- }
-
- /**
- * Sets the Used-in-Fix flag.
- */
- public void setUsedInFix(boolean value) {
- mUsedInFix = value;
- }
-
public static final Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
@Override
public GnssMeasurement createFromParcel(Parcel parcel) {
GnssMeasurement gnssMeasurement = new GnssMeasurement();
gnssMeasurement.mFlags = parcel.readInt();
- gnssMeasurement.mSvid = (short) parcel.readInt();
- gnssMeasurement.mConstellationType = parcel.readByte();
- gnssMeasurement.mTimeOffsetInNs = parcel.readDouble();
- gnssMeasurement.mState = (short) parcel.readInt();
- gnssMeasurement.mReceivedSvTimeInNs = parcel.readLong();
- gnssMeasurement.mReceivedSvTimeUncertaintyInNs = parcel.readLong();
- gnssMeasurement.mCn0InDbHz = parcel.readDouble();
- gnssMeasurement.mPseudorangeRateInMetersPerSec = parcel.readDouble();
- gnssMeasurement.mPseudorangeRateUncertaintyInMetersPerSec = parcel.readDouble();
- gnssMeasurement.mAccumulatedDeltaRangeState = (short) parcel.readInt();
- gnssMeasurement.mAccumulatedDeltaRangeInMeters = parcel.readDouble();
- gnssMeasurement.mAccumulatedDeltaRangeUncertaintyInMeters = parcel.readDouble();
- gnssMeasurement.mPseudorangeInMeters = parcel.readDouble();
- gnssMeasurement.mPseudorangeUncertaintyInMeters = parcel.readDouble();
- gnssMeasurement.mCodePhaseInChips = parcel.readDouble();
- gnssMeasurement.mCodePhaseUncertaintyInChips = parcel.readDouble();
- gnssMeasurement.mCarrierFrequencyInHz = parcel.readFloat();
+ gnssMeasurement.mSvid = parcel.readInt();
+ gnssMeasurement.mConstellationType = parcel.readInt();
+ gnssMeasurement.mTimeOffsetNanos = parcel.readDouble();
+ gnssMeasurement.mState = parcel.readInt();
+ gnssMeasurement.mReceivedSvTimeNanos = parcel.readLong();
+ gnssMeasurement.mReceivedSvTimeUncertaintyNanos = parcel.readLong();
+ gnssMeasurement.mCn0DbHz = parcel.readDouble();
+ gnssMeasurement.mPseudorangeRateMetersPerSecond = parcel.readDouble();
+ gnssMeasurement.mPseudorangeRateUncertaintyMetersPerSecond = parcel.readDouble();
+ gnssMeasurement.mAccumulatedDeltaRangeState = parcel.readInt();
+ gnssMeasurement.mAccumulatedDeltaRangeMeters = parcel.readDouble();
+ gnssMeasurement.mAccumulatedDeltaRangeUncertaintyMeters = parcel.readDouble();
+ gnssMeasurement.mCarrierFrequencyHz = parcel.readFloat();
gnssMeasurement.mCarrierCycles = parcel.readLong();
gnssMeasurement.mCarrierPhase = parcel.readDouble();
gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
- gnssMeasurement.mLossOfLock = parcel.readByte();
- gnssMeasurement.mBitNumber = parcel.readInt();
- gnssMeasurement.mTimeFromLastBitInMs = (short) parcel.readInt();
- gnssMeasurement.mDopplerShiftInHz = parcel.readDouble();
- gnssMeasurement.mDopplerShiftUncertaintyInHz = parcel.readDouble();
- gnssMeasurement.mMultipathIndicator = parcel.readByte();
+ gnssMeasurement.mMultipathIndicator = parcel.readInt();
gnssMeasurement.mSnrInDb = parcel.readDouble();
- gnssMeasurement.mElevationInDeg = parcel.readDouble();
- gnssMeasurement.mElevationUncertaintyInDeg = parcel.readDouble();
- gnssMeasurement.mAzimuthInDeg = parcel.readDouble();
- gnssMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble();
- gnssMeasurement.mUsedInFix = parcel.readInt() != 0;
return gnssMeasurement;
}
@@ -1293,37 +762,23 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mFlags);
parcel.writeInt(mSvid);
- parcel.writeByte(mConstellationType);
- parcel.writeDouble(mTimeOffsetInNs);
+ parcel.writeInt(mConstellationType);
+ parcel.writeDouble(mTimeOffsetNanos);
parcel.writeInt(mState);
- parcel.writeLong(mReceivedSvTimeInNs);
- parcel.writeLong(mReceivedSvTimeUncertaintyInNs);
- parcel.writeDouble(mCn0InDbHz);
- parcel.writeDouble(mPseudorangeRateInMetersPerSec);
- parcel.writeDouble(mPseudorangeRateUncertaintyInMetersPerSec);
+ parcel.writeLong(mReceivedSvTimeNanos);
+ parcel.writeLong(mReceivedSvTimeUncertaintyNanos);
+ parcel.writeDouble(mCn0DbHz);
+ parcel.writeDouble(mPseudorangeRateMetersPerSecond);
+ parcel.writeDouble(mPseudorangeRateUncertaintyMetersPerSecond);
parcel.writeInt(mAccumulatedDeltaRangeState);
- parcel.writeDouble(mAccumulatedDeltaRangeInMeters);
- parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyInMeters);
- parcel.writeDouble(mPseudorangeInMeters);
- parcel.writeDouble(mPseudorangeUncertaintyInMeters);
- parcel.writeDouble(mCodePhaseInChips);
- parcel.writeDouble(mCodePhaseUncertaintyInChips);
- parcel.writeFloat(mCarrierFrequencyInHz);
+ parcel.writeDouble(mAccumulatedDeltaRangeMeters);
+ parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyMeters);
+ parcel.writeFloat(mCarrierFrequencyHz);
parcel.writeLong(mCarrierCycles);
parcel.writeDouble(mCarrierPhase);
parcel.writeDouble(mCarrierPhaseUncertainty);
- parcel.writeByte(mLossOfLock);
- parcel.writeInt(mBitNumber);
- parcel.writeInt(mTimeFromLastBitInMs);
- parcel.writeDouble(mDopplerShiftInHz);
- parcel.writeDouble(mDopplerShiftUncertaintyInHz);
- parcel.writeByte(mMultipathIndicator);
+ parcel.writeInt(mMultipathIndicator);
parcel.writeDouble(mSnrInDb);
- parcel.writeDouble(mElevationInDeg);
- parcel.writeDouble(mElevationUncertaintyInDeg);
- parcel.writeDouble(mAzimuthInDeg);
- parcel.writeDouble(mAzimuthUncertaintyInDeg);
- parcel.writeInt(mUsedInFix ? 1 : 0);
}
@Override
@@ -1339,25 +794,25 @@
builder.append(String.format(format, "Svid", mSvid));
builder.append(String.format(format, "ConstellationType", mConstellationType));
- builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
+ builder.append(String.format(format, "TimeOffsetNanos", mTimeOffsetNanos));
builder.append(String.format(format, "State", getStateString()));
builder.append(String.format(
formatWithUncertainty,
- "ReceivedSvTimeInNs",
- mReceivedSvTimeInNs,
- "ReceivedSvTimeUncertaintyInNs",
- mReceivedSvTimeUncertaintyInNs));
+ "ReceivedSvTimeNanos",
+ mReceivedSvTimeNanos,
+ "ReceivedSvTimeUncertaintyNanos",
+ mReceivedSvTimeUncertaintyNanos));
- builder.append(String.format(format, "Cn0InDbHz", mCn0InDbHz));
+ builder.append(String.format(format, "Cn0DbHz", mCn0DbHz));
builder.append(String.format(
formatWithUncertainty,
- "PseudorangeRateInMetersPerSec",
- mPseudorangeRateInMetersPerSec,
- "PseudorangeRateUncertaintyInMetersPerSec",
- mPseudorangeRateUncertaintyInMetersPerSec));
+ "PseudorangeRateMetersPerSecond",
+ mPseudorangeRateMetersPerSecond,
+ "PseudorangeRateUncertaintyMetersPerSecond",
+ mPseudorangeRateUncertaintyMetersPerSecond));
builder.append(String.format(
format,
"PseudorangeRateIsCorrected",
@@ -1370,29 +825,15 @@
builder.append(String.format(
formatWithUncertainty,
- "AccumulatedDeltaRangeInMeters",
- mAccumulatedDeltaRangeInMeters,
- "AccumulatedDeltaRangeUncertaintyInMeters",
- mAccumulatedDeltaRangeUncertaintyInMeters));
-
- builder.append(String.format(
- formatWithUncertainty,
- "PseudorangeInMeters",
- hasPseudorangeInMeters() ? mPseudorangeInMeters : null,
- "PseudorangeUncertaintyInMeters",
- hasPseudorangeUncertaintyInMeters() ? mPseudorangeUncertaintyInMeters : null));
-
- builder.append(String.format(
- formatWithUncertainty,
- "CodePhaseInChips",
- hasCodePhaseInChips() ? mCodePhaseInChips : null,
- "CodePhaseUncertaintyInChips",
- hasCodePhaseUncertaintyInChips() ? mCodePhaseUncertaintyInChips : null));
+ "AccumulatedDeltaRangeMeters",
+ mAccumulatedDeltaRangeMeters,
+ "AccumulatedDeltaRangeUncertaintyMeters",
+ mAccumulatedDeltaRangeUncertaintyMeters));
builder.append(String.format(
format,
- "CarrierFrequencyInHz",
- hasCarrierFrequencyInHz() ? mCarrierFrequencyInHz : null));
+ "CarrierFrequencyHz",
+ hasCarrierFrequencyHz() ? mCarrierFrequencyHz : null));
builder.append(String.format(
format,
@@ -1406,25 +847,6 @@
"CarrierPhaseUncertainty",
hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
- builder.append(String.format(format, "LossOfLock", getLossOfLockString()));
-
- builder.append(String.format(
- format,
- "BitNumber",
- hasBitNumber() ? mBitNumber : null));
-
- builder.append(String.format(
- format,
- "TimeFromLastBitInMs",
- hasTimeFromLastBitInMs() ? mTimeFromLastBitInMs : null));
-
- builder.append(String.format(
- formatWithUncertainty,
- "DopplerShiftInHz",
- hasDopplerShiftInHz() ? mDopplerShiftInHz : null,
- "DopplerShiftUncertaintyInHz",
- hasDopplerShiftUncertaintyInHz() ? mDopplerShiftUncertaintyInHz : null));
-
builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
builder.append(String.format(
@@ -1432,58 +854,28 @@
"SnrInDb",
hasSnrInDb() ? mSnrInDb : null));
- builder.append(String.format(
- formatWithUncertainty,
- "ElevationInDeg",
- hasElevationInDeg() ? mElevationInDeg : null,
- "ElevationUncertaintyInDeg",
- hasElevationUncertaintyInDeg() ? mElevationUncertaintyInDeg : null));
-
- builder.append(String.format(
- formatWithUncertainty,
- "AzimuthInDeg",
- hasAzimuthInDeg() ? mAzimuthInDeg : null,
- "AzimuthUncertaintyInDeg",
- hasAzimuthUncertaintyInDeg() ? mAzimuthUncertaintyInDeg : null));
-
- builder.append(String.format(format, "UsedInFix", mUsedInFix));
-
return builder.toString();
}
private void initialize() {
mFlags = HAS_NO_FLAGS;
- setSvid((short) 0);
- setTimeOffsetInNs(Long.MIN_VALUE);
+ setSvid(0);
+ setTimeOffsetNanos(Long.MIN_VALUE);
setState(STATE_UNKNOWN);
- setReceivedSvTimeInNs(Long.MIN_VALUE);
- setReceivedSvTimeUncertaintyInNs(Long.MAX_VALUE);
- setCn0InDbHz(Double.MIN_VALUE);
- setPseudorangeRateInMetersPerSec(Double.MIN_VALUE);
- setPseudorangeRateUncertaintyInMetersPerSec(Double.MIN_VALUE);
+ setReceivedSvTimeNanos(Long.MIN_VALUE);
+ setReceivedSvTimeUncertaintyNanos(Long.MAX_VALUE);
+ setCn0DbHz(Double.MIN_VALUE);
+ setPseudorangeRateMetersPerSecond(Double.MIN_VALUE);
+ setPseudorangeRateUncertaintyMetersPerSecond(Double.MIN_VALUE);
setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
- setAccumulatedDeltaRangeInMeters(Double.MIN_VALUE);
- setAccumulatedDeltaRangeUncertaintyInMeters(Double.MIN_VALUE);
- resetPseudorangeInMeters();
- resetPseudorangeUncertaintyInMeters();
- resetCodePhaseInChips();
- resetCodePhaseUncertaintyInChips();
- resetCarrierFrequencyInHz();
+ setAccumulatedDeltaRangeMeters(Double.MIN_VALUE);
+ setAccumulatedDeltaRangeUncertaintyMeters(Double.MIN_VALUE);
+ resetCarrierFrequencyHz();
resetCarrierCycles();
resetCarrierPhase();
resetCarrierPhaseUncertainty();
- setLossOfLock(LOSS_OF_LOCK_UNKNOWN);
- resetBitNumber();
- resetTimeFromLastBitInMs();
- resetDopplerShiftInHz();
- resetDopplerShiftUncertaintyInHz();
setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
resetSnrInDb();
- resetElevationInDeg();
- resetElevationUncertaintyInDeg();
- resetAzimuthInDeg();
- resetAzimuthUncertaintyInDeg();
- setUsedInFix(false);
}
private void setFlag(int flag) {
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index b744a03..86841ff 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -33,46 +33,46 @@
* Events are delivered to registered instances of {@link Callback}.
*/
public final class GnssMeasurementsEvent implements Parcelable {
- /** The status of GPS measurements event. */
+ /** The status of GNSS measurements event. */
@Retention(RetentionPolicy.SOURCE)
- @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GPS_LOCATION_DISABLED})
+ @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GNSS_LOCATION_DISABLED})
public @interface GnssMeasurementsStatus {}
/**
- * The system does not support tracking of GPS Measurements. This status will not change in the
+ * The system does not support tracking of GNSS Measurements. This status will not change in the
* future.
*/
public static final int STATUS_NOT_SUPPORTED = 0;
/**
- * GPS Measurements are successfully being tracked, it will receive updates once they are
+ * GNSS Measurements are successfully being tracked, it will receive updates once they are
* available.
*/
public static final int STATUS_READY = 1;
/**
- * GPS provider or Location is disabled, updates will not be received until they are enabled.
+ * GNSS provider or Location is disabled, updates will not be received until they are enabled.
*/
- public static final int STATUS_GPS_LOCATION_DISABLED = 2;
+ public static final int STATUS_GNSS_LOCATION_DISABLED = 2;
private final GnssClock mClock;
private final Collection<GnssMeasurement> mReadOnlyMeasurements;
/**
- * Used for receiving GPS satellite measurements from the GPS engine.
+ * Used for receiving GNSS satellite measurements from the GNSS engine.
* Each measurement contains raw and computed data identifying a satellite.
* You can implement this interface and call
- * {@link LocationManager#registerGnssMeasurementCallback}.
+ * {@link LocationManager#registerGnssMeasurementsCallback}.
*/
public static abstract class Callback {
/**
- * Returns the latest collected GPS Measurements.
+ * Reports the latest collected GNSS Measurements.
*/
public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {}
/**
- * Returns the latest status of the GPS Measurements sub-system.
+ * Reports the latest status of the GNSS Measurements sub-system.
*/
public void onStatusChanged(@GnssMeasurementsStatus int status) {}
}
diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java
index faefd0bb..c0608e0 100644
--- a/location/java/android/location/GnssNavigationMessage.java
+++ b/location/java/android/location/GnssNavigationMessage.java
@@ -34,58 +34,57 @@
/** The type of the GPS Clock. */
@Retention(RetentionPolicy.SOURCE)
- @IntDef({MESSAGE_TYPE_UNKNOWN, MESSAGE_TYPE_GPS_L1CA, MESSAGE_TYPE_GPS_L2CNAV,
- MESSAGE_TYPE_GPS_L5CNAV, MESSAGE_TYPE_GPS_CNAV2, MESSAGE_TYPE_GLO_L1CA, MESSAGE_TYPE_BDS_D1,
- MESSAGE_TYPE_BDS_D2, MESSAGE_TYPE_GAL_I, MESSAGE_TYPE_GAL_F})
+ @IntDef({TYPE_UNKNOWN, TYPE_GPS_L1CA, TYPE_GPS_L2CNAV, TYPE_GPS_L5CNAV, TYPE_GPS_CNAV2,
+ TYPE_GLO_L1CA, TYPE_BDS_D1, TYPE_BDS_D2, TYPE_GAL_I, TYPE_GAL_F})
public @interface GnssNavigationMessageType {}
// The following enumerations must be in sync with the values declared in gps.h
/** Message type unknown */
- public static final short MESSAGE_TYPE_UNKNOWN = 0;
+ public static final int TYPE_UNKNOWN = 0;
/** GPS L1 C/A message contained in the structure. */
- public static final short MESSAGE_TYPE_GPS_L1CA = 0x0101;
+ public static final int TYPE_GPS_L1CA = 0x0101;
/** GPS L2-CNAV message contained in the structure. */
- public static final short MESSAGE_TYPE_GPS_L2CNAV = 0x0102;
+ public static final int TYPE_GPS_L2CNAV = 0x0102;
/** GPS L5-CNAV message contained in the structure. */
- public static final short MESSAGE_TYPE_GPS_L5CNAV = 0x0103;
+ public static final int TYPE_GPS_L5CNAV = 0x0103;
/** GPS CNAV-2 message contained in the structure. */
- public static final short MESSAGE_TYPE_GPS_CNAV2 = 0x0104;
+ public static final int TYPE_GPS_CNAV2 = 0x0104;
/** Glonass L1 CA message contained in the structure. */
- public static final short MESSAGE_TYPE_GLO_L1CA = 0x0301;
+ public static final int TYPE_GLO_L1CA = 0x0301;
/** Beidou D1 message contained in the structure. */
- public static final short MESSAGE_TYPE_BDS_D1 = 0x0501;
+ public static final int TYPE_BDS_D1 = 0x0501;
/** Beidou D2 message contained in the structure. */
- public static final short MESSAGE_TYPE_BDS_D2 = 0x0502;
+ public static final int TYPE_BDS_D2 = 0x0502;
/** Galileo I/NAV message contained in the structure. */
- public static final short MESSAGE_TYPE_GAL_I = 0x0601;
+ public static final int TYPE_GAL_I = 0x0601;
/** Galileo F/NAV message contained in the structure. */
- public static final short MESSAGE_TYPE_GAL_F = 0x0602;
+ public static final int TYPE_GAL_F = 0x0602;
/**
* The Navigation Message Status is 'unknown'.
*/
- public static final short STATUS_UNKNOWN = 0;
+ public static final int STATUS_UNKNOWN = 0;
/**
* The Navigation Message was received without any parity error in its navigation words.
*/
- public static final short STATUS_PARITY_PASSED = (1<<0);
+ public static final int STATUS_PARITY_PASSED = (1<<0);
/**
* The Navigation Message was received with words that failed parity check, but the receiver was
* able to correct those words.
*/
- public static final short STATUS_PARITY_REBUILT = (1<<1);
+ public static final int STATUS_PARITY_REBUILT = (1<<1);
// End enumerations in sync with gps.h
- private short mType;
- private short mSvid;
- private short mMessageId;
- private short mSubmessageId;
+ private int mType;
+ private int mSvid;
+ private int mMessageId;
+ private int mSubmessageId;
private byte[] mData;
- private short mStatus;
+ private int mStatus;
GnssNavigationMessage() {
initialize();
@@ -114,14 +113,14 @@
* Gets the type of the navigation message contained in the object.
*/
@GnssNavigationMessageType
- public short getType() {
+ public int getType() {
return mType;
}
/**
* Sets the type of the navigation message.
*/
- public void setType(@GnssNavigationMessageType short value) {
+ public void setType(@GnssNavigationMessageType int value) {
mType = value;
}
@@ -131,25 +130,25 @@
*/
private String getTypeString() {
switch (mType) {
- case MESSAGE_TYPE_UNKNOWN:
+ case TYPE_UNKNOWN:
return "Unknown";
- case MESSAGE_TYPE_GPS_L1CA:
+ case TYPE_GPS_L1CA:
return "GPS L1 C/A";
- case MESSAGE_TYPE_GPS_L2CNAV:
+ case TYPE_GPS_L2CNAV:
return "GPS L2-CNAV";
- case MESSAGE_TYPE_GPS_L5CNAV:
+ case TYPE_GPS_L5CNAV:
return "GPS L5-CNAV";
- case MESSAGE_TYPE_GPS_CNAV2:
+ case TYPE_GPS_CNAV2:
return "GPS CNAV2";
- case MESSAGE_TYPE_GLO_L1CA:
+ case TYPE_GLO_L1CA:
return "Glonass L1 C/A";
- case MESSAGE_TYPE_BDS_D1:
+ case TYPE_BDS_D1:
return "Beidou D1";
- case MESSAGE_TYPE_BDS_D2:
+ case TYPE_BDS_D2:
return "Beidou D2";
- case MESSAGE_TYPE_GAL_I:
+ case TYPE_GAL_I:
return "Galileo I";
- case MESSAGE_TYPE_GAL_F:
+ case TYPE_GAL_F:
return "Galileo F";
default:
return "<Invalid:" + mType + ">";
@@ -160,14 +159,14 @@
* Gets the Pseudo-random number.
* Range: [1, 32].
*/
- public short getSvid() {
+ public int getSvid() {
return mSvid;
}
/**
* Sets the Pseud-random number.
*/
- public void setSvid(short value) {
+ public void setSvid(int value) {
mSvid = value;
}
@@ -177,14 +176,14 @@
* subframe 4 and 5, this value corresponds to the 'frame id' of the navigation message.
* Subframe 1, 2, 3 does not contain a 'frame id' and this might be reported as -1.
*/
- public short getMessageId() {
+ public int getMessageId() {
return mMessageId;
}
/**
* Sets the Message Identifier.
*/
- public void setMessageId(short value) {
+ public void setMessageId(int value) {
mMessageId = value;
}
@@ -194,14 +193,14 @@
* (or frame) that is being transmitted. i.e. for L1 C/A the sub-message identifier corresponds
* to the sub-frame Id of the navigation message.
*/
- public short getSubmessageId() {
+ public int getSubmessageId() {
return mSubmessageId;
}
/**
* Sets the Sub-message identifier.
*/
- public void setSubmessageId(short value) {
+ public void setSubmessageId(int value) {
mSubmessageId = value;
}
@@ -228,14 +227,14 @@
/**
* Gets the Status of the navigation message contained in the object.
*/
- public short getStatus() {
+ public int getStatus() {
return mStatus;
}
/**
* Sets the status of the navigation message.
*/
- public void setStatus(short value) {
+ public void setStatus(int value) {
mStatus = value;
}
@@ -262,10 +261,10 @@
public GnssNavigationMessage createFromParcel(Parcel parcel) {
GnssNavigationMessage navigationMessage = new GnssNavigationMessage();
- navigationMessage.setType((short) parcel.readInt());
- navigationMessage.setSvid((short) parcel.readInt());
- navigationMessage.setMessageId((short) parcel.readInt());
- navigationMessage.setSubmessageId((short) parcel.readInt());
+ navigationMessage.setType(parcel.readInt());
+ navigationMessage.setSvid(parcel.readInt());
+ navigationMessage.setMessageId(parcel.readInt());
+ navigationMessage.setSubmessageId(parcel.readInt());
int dataLength = parcel.readInt();
byte[] data = new byte[dataLength];
@@ -274,7 +273,7 @@
if (parcel.dataAvail() >= Integer.SIZE) {
int status = parcel.readInt();
- navigationMessage.setStatus((short) status);
+ navigationMessage.setStatus(status);
} else {
navigationMessage.setStatus(STATUS_UNKNOWN);
}
@@ -328,7 +327,7 @@
}
private void initialize() {
- mType = MESSAGE_TYPE_UNKNOWN;
+ mType = TYPE_UNKNOWN;
mSvid = 0;
mMessageId = -1;
mSubmessageId = -1;
diff --git a/location/java/android/location/GnssNavigationMessageEvent.java b/location/java/android/location/GnssNavigationMessageEvent.java
index 19c82e9..0df730d 100644
--- a/location/java/android/location/GnssNavigationMessageEvent.java
+++ b/location/java/android/location/GnssNavigationMessageEvent.java
@@ -32,7 +32,7 @@
public final class GnssNavigationMessageEvent implements Parcelable {
/** The status of GPS measurements event. */
@Retention(RetentionPolicy.SOURCE)
- @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GPS_LOCATION_DISABLED})
+ @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GNSS_LOCATION_DISABLED})
public @interface GnssNavigationMessageStatus {}
/**
@@ -50,7 +50,7 @@
/**
* GPS provider or Location is disabled, updated will not be received until they are enabled.
*/
- public static final int STATUS_GPS_LOCATION_DISABLED = 2;
+ public static final int STATUS_GNSS_LOCATION_DISABLED = 2;
private final GnssNavigationMessage mNavigationMessage;
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index 06ce30c..2a42fc6 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -27,19 +27,19 @@
*/
public final class GnssStatus {
/** Unknown constellation type. */
- public static final byte CONSTELLATION_UNKNOWN = 0;
+ public static final int CONSTELLATION_UNKNOWN = 0;
/** Constellation type constant for GPS. */
- public static final byte CONSTELLATION_GPS = 1;
+ public static final int CONSTELLATION_GPS = 1;
/** Constellation type constant for SBAS. */
- public static final byte CONSTELLATION_SBAS = 2;
+ public static final int CONSTELLATION_SBAS = 2;
/** Constellation type constant for Glonass. */
- public static final byte CONSTELLATION_GLONASS = 3;
+ public static final int CONSTELLATION_GLONASS = 3;
/** Constellation type constant for QZSS. */
- public static final byte CONSTELLATION_QZSS = 4;
+ public static final int CONSTELLATION_QZSS = 4;
/** Constellation type constant for Beidou. */
- public static final byte CONSTELLATION_BEIDOU = 5;
+ public static final int CONSTELLATION_BEIDOU = 5;
/** Constellation type constant for Galileo. */
- public static final byte CONSTELLATION_GALILEO = 6;
+ public static final int CONSTELLATION_GALILEO = 6;
/** Constellation type. */
@Retention(RetentionPolicy.SOURCE)
@@ -66,16 +66,16 @@
/* These package private values are modified by the LocationManager class */
/* package */ int[] mSvidWithFlags;
- /* package */ float[] mSnrs;
+ /* package */ float[] mCn0DbHz;
/* package */ float[] mElevations;
/* package */ float[] mAzimuths;
/* package */ int mSvCount;
- GnssStatus(int svCount, int[] svidWithFlags, float[] snrs, float[] elevations,
+ GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
float[] azimuths) {
mSvCount = svCount;
mSvidWithFlags = svidWithFlags;
- mSnrs = snrs;
+ mCn0DbHz = cn0s;
mElevations = elevations;
mAzimuths = azimuths;
}
@@ -92,8 +92,8 @@
* @param satIndex the index of the satellite in the list.
*/
@ConstellationType
- public byte getConstellationType(int satIndex) {
- return (byte) ((mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
+ public int getConstellationType(int satIndex) {
+ return ((mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
& CONSTELLATION_TYPE_MASK);
}
@@ -109,15 +109,15 @@
* Retrieves the signal-noise ration of the satellite at the specified position.
* @param satIndex the index of the satellite in the list.
*/
- public float getSnr(int satIndex) {
- return mSnrs[satIndex];
+ public float getCn0DbHz(int satIndex) {
+ return mCn0DbHz[satIndex];
}
/**
* Retrieves the elevation of the satellite at the specified position.
* @param satIndex the index of the satellite in the list.
*/
- public float getElevation(int satIndex) {
+ public float getElevationDegrees(int satIndex) {
return 0f;
}
@@ -125,7 +125,7 @@
* Retrieves the azimuth the satellite at the specified position.
* @param satIndex the index of the satellite in the list.
*/
- public float getAzimuth(int satIndex) {
+ public float getAzimuthDegrees(int satIndex) {
return mAzimuths[satIndex];
}
diff --git a/location/java/android/location/GnssStatusCallback.java b/location/java/android/location/GnssStatusCallback.java
index b86171b..0d2955a 100644
--- a/location/java/android/location/GnssStatusCallback.java
+++ b/location/java/android/location/GnssStatusCallback.java
@@ -32,13 +32,13 @@
/**
* Called when the GNSS system has received its first fix since starting.
- * @param ttff the time from start to first fix.
+ * @param ttffMillis the time from start to first fix in milliseconds.
*/
- public void onFirstFix(int ttff) {}
+ public void onFirstFix(int ttffMillis) {}
/**
* Called periodically to report GNSS satellite status.
* @param status the current status of all satellites.
*/
public void onSatelliteStatusChanged(GnssStatus status) {}
-}
\ No newline at end of file
+}
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 7b3dd7d..bc518f9 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -138,7 +138,7 @@
// For API-compat a public ctor() is not available
GpsStatus() {}
- private void setStatus(int svCount, int[] svidWithFlags, float[] snrs, float[] elevations,
+ private void setStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
float[] azimuths) {
clearSatellites();
for (int i = 0; i < svCount; i++) {
@@ -158,7 +158,7 @@
}
satellite.mValid = true;
- satellite.mSnr = snrs[i];
+ satellite.mSnr = cn0s[i];
satellite.mElevation = elevations[i];
satellite.mAzimuth = azimuths[i];
satellite.mHasEphemeris =
@@ -179,7 +179,7 @@
*/
void setStatus(GnssStatus status, int timeToFirstFix) {
mTimeToFirstFix = timeToFirstFix;
- setStatus(status.mSvCount, status.mSvidWithFlags, status.mSnrs, status.mElevations,
+ setStatus(status.mSvCount, status.mSvidWithFlags, status.mCn0DbHz, status.mElevations,
status.mAzimuths);
}
diff --git a/location/java/android/location/IGnssStatusListener.aidl b/location/java/android/location/IGnssStatusListener.aidl
index 8c7d06e..d84614f 100644
--- a/location/java/android/location/IGnssStatusListener.aidl
+++ b/location/java/android/location/IGnssStatusListener.aidl
@@ -26,7 +26,7 @@
void onGnssStarted();
void onGnssStopped();
void onFirstFix(int ttff);
- void onSvStatusChanged(int svCount, in int[] svidWithFlags, in float[] snrs,
+ void onSvStatusChanged(int svCount, in int[] svidWithFlags, in float[] cn0s,
in float[] elevations, in float[] azimuths);
void onNmeaReceived(long timestamp, String nmea);
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 3cd47e7..28db099 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1554,9 +1554,9 @@
@Override
public void onSvStatusChanged(int svCount, int[] prnWithFlags,
- float[] snrs, float[] elevations, float[] azimuths) {
+ float[] cn0s, float[] elevations, float[] azimuths) {
if (mGnssCallback != null) {
- mGnssStatus = new GnssStatus(svCount, prnWithFlags, snrs, elevations, azimuths);
+ mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths);
Message msg = Message.obtain();
msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
@@ -1805,7 +1805,7 @@
/**
* No-op method to keep backward-compatibility.
- * Don't use it. Use {@link #registerGnssMeasurementCallback} instead.
+ * Don't use it. Use {@link #registerGnssMeasurementsCallback} instead.
* @hide
* @deprecated
*/
@@ -1822,8 +1822,8 @@
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssMeasurementCallback(GnssMeasurementsEvent.Callback callback) {
- return registerGnssMeasurementCallback(callback, null);
+ public boolean registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback) {
+ return registerGnssMeasurementsCallback(callback, null);
}
/**
@@ -1834,14 +1834,14 @@
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssMeasurementCallback(GnssMeasurementsEvent.Callback callback,
+ public boolean registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback,
Handler handler) {
return mGnssMeasurementCallbackTransport.add(callback, handler);
}
/**
* No-op method to keep backward-compatibility.
- * Don't use it. Use {@link #unregisterGnssMeasurementCallback} instead.
+ * Don't use it. Use {@link #unregisterGnssMeasurementsCallback} instead.
* @hide
* @deprecated
*/
@@ -1855,7 +1855,7 @@
*
* @param callback a {@link GnssMeasurementsEvent.Callback} object to remove.
*/
- public void unregisterGnssMeasurementCallback(GnssMeasurementsEvent.Callback callback) {
+ public void unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback) {
mGnssMeasurementCallbackTransport.remove(callback);
}
diff --git a/location/tests/locationtests/src/android/location/GpsStatusTest.java b/location/tests/locationtests/src/android/location/GpsStatusTest.java
index 4808faf..316e88d 100644
--- a/location/tests/locationtests/src/android/location/GpsStatusTest.java
+++ b/location/tests/locationtests/src/android/location/GpsStatusTest.java
@@ -40,7 +40,7 @@
private GpsStatus mStatus;
private int mCount;
private int[] mPrns;
- private float[] mSnrs;
+ private float[] mCn0s;
private float[] mElevations;
private float[] mAzimuth;
private int mEphemerisMask;
@@ -179,7 +179,7 @@
private void verifySatellites(GpsStatus status) {
verifySatelliteCount(status, mCount);
- verifySatellites(status, mCount, mPrns, mSnrs, mElevations, mAzimuth, mEphemerisMask,
+ verifySatellites(status, mCount, mPrns, mCn0s, mElevations, mAzimuth, mEphemerisMask,
mAlmanacMask, mUsedInFixMask);
}
@@ -187,7 +187,7 @@
GpsStatus status,
int count,
int[] prns,
- float[] snrs,
+ float[] cn0s,
float[] elevations,
float[] azimuth,
int ephemerisMask,
@@ -197,7 +197,7 @@
int prn = prns[i];
GpsSatellite satellite = getSatellite(status, prn);
assertNotNull(getSatelliteAssertInfo(i, prn, "non-null"), satellite);
- assertEquals(getSatelliteAssertInfo(i, prn, "Snr"), snrs[i], satellite.getSnr());
+ assertEquals(getSatelliteAssertInfo(i, prn, "Snr"), cn0s[i], satellite.getSnr());
assertEquals(
getSatelliteAssertInfo(i, prn, "Elevation"),
elevations[i],
@@ -247,7 +247,7 @@
}
private void setSatellites(GpsStatus status) throws Exception {
- set(status, mCount, mPrns, mSnrs, mElevations, mAzimuth, mEphemerisMask, mAlmanacMask,
+ set(status, mCount, mPrns, mCn0s, mElevations, mAzimuth, mEphemerisMask, mAlmanacMask,
mUsedInFixMask);
}
@@ -255,7 +255,7 @@
GpsStatus status,
int count,
int[] prns,
- float[] snrs,
+ float[] cn0s,
float[] elevations,
float[] azimuth,
int ephemerisMask,
@@ -279,7 +279,7 @@
status,
count,
prns,
- snrs,
+ cn0s,
elevations,
azimuth,
ephemerisMask,
@@ -333,7 +333,7 @@
if (!reusePrns) {
mPrns = generateIntArray(count);
}
- mSnrs = generateFloatArray(count);
+ mCn0s = generateFloatArray(count);
mElevations = generateFloatArray(count);
mAzimuth = generateFloatArray(count);
mEphemerisMask = generateMask(mPrns);
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 646ab4e..a0e2481 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -644,6 +644,21 @@
/** Full range. Y, Cr and Cb component values range from 0 to 255 for 8-bit content. */
public static final int COLOR_RANGE_FULL = 1;
+ /**
+ * A key describing a unique ID for the content of a media track.
+ *
+ * <p>This key is used by {@link MediaExtractor}. Some extractors provide multiple encodings
+ * of the same track (e.g. float audio tracks for FLAC and WAV may be expressed as two
+ * tracks via MediaExtractor: a normal PCM track for backward compatibility, and a float PCM
+ * track for added fidelity. Similarly, Dolby Vision extractor may provide a baseline SDR
+ * version of a DV track.) This key can be used to identify which MediaExtractor tracks refer
+ * to the same underlying content.
+ * </p>
+ *
+ * The associated value is an integer.
+ */
+ public static final String KEY_TRACK_ID = "track-id";
+
/* package private */ MediaFormat(Map<String, Object> map) {
mMap = map;
}
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index fa9c48c..29739ca 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -64,7 +64,6 @@
frameworks/av/media/mtp \
frameworks/native/include/media/openmax \
$(call include-path-for, libhardware)/hardware \
- system/media/camera/include \
$(PV_INCLUDES) \
$(JNI_H_INCLUDE)
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index 3b892cb..537b56d 100644
--- a/media/jni/android_media_MediaDataSource.cpp
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -116,7 +116,8 @@
return UNKNOWN_ERROR;
}
if (mSizeIsCached) {
- return mCachedSize;
+ *size = mCachedSize;
+ return OK;
}
JNIEnv* env = AndroidRuntime::getJNIEnv();
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 701f7ac..922ad79 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -26,7 +26,6 @@
#include <utils/Log.h>
#include <gui/Surface.h>
-#include <camera/ICameraService.h>
#include <camera/Camera.h>
#include <media/mediarecorder.h>
#include <media/stagefright/PersistentSurface.h>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
index 61dede3..9be7004 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
@@ -60,10 +60,7 @@
}
private void addCameraUnitTests(TestSuite suite) {
- suite.addTestSuite(CameraUtilsDecoratorTest.class);
- suite.addTestSuite(CameraUtilsRuntimeExceptionTest.class);
suite.addTestSuite(CameraUtilsUncheckedThrowTest.class);
- suite.addTestSuite(CameraUtilsBinderDecoratorTest.class);
suite.addTestSuite(CameraUtilsTypeReferenceTest.class);
suite.addTestSuite(CameraMetadataTest.class);
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 6f74203..9a0946e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -19,16 +19,16 @@
import android.hardware.CameraInfo;
import android.hardware.ICamera;
import android.hardware.ICameraClient;
+import android.hardware.ICameraService;
import android.hardware.ICameraServiceListener;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
-import android.hardware.camera2.utils.BinderHolder;
-import android.hardware.camera2.utils.CameraBinderDecorator;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
@@ -84,14 +84,7 @@
public void testCameraInfo() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- CameraInfo info = new CameraInfo();
- info.info.facing = -1;
- info.info.orientation = -1;
-
- assertTrue(
- "Camera service returned info for camera " + cameraId,
- mUtils.getCameraService().getCameraInfo(cameraId, info) ==
- CameraBinderTestUtils.NO_ERROR);
+ CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId);
assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
assertTrue("Orientation was not set for camera " + cameraId,
info.info.orientation != -1);
@@ -105,20 +98,17 @@
public void testGetLegacyParameters() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- String[] parameters = new String[1];
- assertEquals("Camera service returned parameters for camera " + cameraId,
- CameraBinderTestUtils.NO_ERROR,
- mUtils.getCameraService().getLegacyParameters(cameraId, /*out*/parameters));
- assertNotNull(parameters[0]);
+ String parameters = mUtils.getCameraService().getLegacyParameters(cameraId);
+ assertNotNull(parameters);
assertTrue("Parameters should have at least one character in it",
- parameters[0].length() > 0);
+ parameters.length() > 0);
- int end = parameters[0].length();
+ int end = parameters.length();
if (end > MAX_PARAMETERS_LENGTH) {
end = MAX_PARAMETERS_LENGTH;
}
- Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters[0].substring(0, end));
+ Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters.substring(0, end));
}
}
@@ -127,14 +117,8 @@
public void testSupportsCamera2Api() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2);
+ boolean supports = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2);
- if (res != CameraBinderTestUtils.NO_ERROR && res != -android.system.OsConstants.EOPNOTSUPP) {
- fail("Camera service returned bad value when queried if it supports camera2 api: "
- + res + " for camera ID " + cameraId);
- }
-
- boolean supports = res == CameraBinderTestUtils.NO_ERROR;
Log.v(TAG, "Camera " + cameraId + " supports api2: " + supports);
}
}
@@ -144,10 +128,10 @@
public void testSupportsCamera1Api() throws Exception {
for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
- int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_1);
- assertEquals(
- "Camera service returned bad value when queried if it supports camera1 api: "
- + res + " for camera ID " + cameraId, CameraBinderTestUtils.NO_ERROR, res);
+ boolean supports = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_1);
+ assertTrue(
+ "Camera service returned false when queried if it supports camera1 api " +
+ " for camera ID " + cameraId, supports);
}
}
@@ -169,11 +153,10 @@
String clientPackageName = getContext().getPackageName();
- BinderHolder holder = new BinderHolder();
- CameraBinderDecorator.newInstance(mUtils.getCameraService())
+ ICamera cameraUser = mUtils.getCameraService()
.connect(dummyCallbacks, cameraId, clientPackageName,
- CameraBinderTestUtils.USE_CALLING_UID, holder);
- ICamera cameraUser = ICamera.Stub.asInterface(holder.getBinder());
+ ICameraService.USE_CALLING_UID,
+ ICameraService.USE_CALLING_PID);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
Log.v(TAG, String.format("Camera %s connected", cameraId));
@@ -191,14 +174,11 @@
String clientPackageName = getContext().getPackageName();
- BinderHolder holder = new BinderHolder();
-
try {
- CameraBinderDecorator.newInstance(mUtils.getCameraService())
+ cameraUser = mUtils.getCameraService()
.connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0,
- clientPackageName,
- CameraBinderTestUtils.USE_CALLING_UID, holder);
- cameraUser = ICamera.Stub.asInterface(holder.getBinder());
+ clientPackageName,
+ ICameraService.USE_CALLING_UID);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId));
@@ -284,11 +264,11 @@
String clientPackageName = getContext().getPackageName();
- BinderHolder holder = new BinderHolder();
- CameraBinderDecorator.newInstance(mUtils.getCameraService())
- .connectDevice(dummyCallbacks, cameraId,
- clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
- ICameraDeviceUser cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
+ ICameraDeviceUser cameraUser =
+ mUtils.getCameraService().connectDevice(
+ dummyCallbacks, cameraId,
+ clientPackageName,
+ ICameraService.USE_CALLING_UID);
assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
Log.v(TAG, String.format("Camera %s connected", cameraId));
@@ -323,27 +303,33 @@
ICameraServiceListener listener = new DummyCameraServiceListener();
- assertTrue(
- "Listener was removed before added",
- mUtils.getCameraService().removeListener(listener) ==
- CameraBinderTestUtils.BAD_VALUE);
+ try {
+ mUtils.getCameraService().removeListener(listener);
+ fail("Listener was removed before added");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Listener was removed before added",
+ e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
+ }
- assertTrue("Listener was not added",
- mUtils.getCameraService().addListener(listener) ==
- CameraBinderTestUtils.NO_ERROR);
- assertTrue(
- "Listener was wrongly added again",
- mUtils.getCameraService().addListener(listener) ==
- CameraBinderTestUtils.ALREADY_EXISTS);
+ mUtils.getCameraService().addListener(listener);
- assertTrue(
- "Listener was not removed",
- mUtils.getCameraService().removeListener(listener) ==
- CameraBinderTestUtils.NO_ERROR);
- assertTrue(
- "Listener was wrongly removed again",
- mUtils.getCameraService().removeListener(listener) ==
- CameraBinderTestUtils.BAD_VALUE);
+ try {
+ mUtils.getCameraService().addListener(listener);
+ fail("Listener was wrongly added again");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Listener was wrongly added again",
+ e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
+ }
+
+ mUtils.getCameraService().removeListener(listener);
+
+ try {
+ mUtils.getCameraService().removeListener(listener);
+ fail("Listener was wrongly removed twice");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Listener was wrongly removed twice",
+ e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
+ }
}
}
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
index 5c4b23b..38fc49f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
@@ -18,10 +18,6 @@
static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
- protected static final int USE_CALLING_UID = -1;
- protected static final int BAD_VALUE = -EINVAL;
- protected static final int INVALID_OPERATION = -ENOSYS;
- protected static final int ALREADY_EXISTS = -EEXIST;
public static final int NO_ERROR = 0;
private final Context mContext;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index d71b44b..5c1d8a7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -18,6 +18,7 @@
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
+import android.hardware.ICameraService;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@@ -27,12 +28,13 @@
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.utils.BinderHolder;
+import android.hardware.camera2.utils.SubmitInfo;
import android.media.Image;
import android.media.ImageReader;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -164,11 +166,10 @@
}
private CaptureRequest.Builder createDefaultBuilder(boolean needStream) throws Exception {
- CameraMetadataNative metadata = new CameraMetadataNative();
+ CameraMetadataNative metadata = null;
assertTrue(metadata.isEmpty());
- int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ metadata = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW);
assertFalse(metadata.isEmpty());
CaptureRequest.Builder request = new CaptureRequest.Builder(metadata, /*reprocess*/false,
@@ -183,12 +184,13 @@
return request;
}
- private int submitCameraRequest(CaptureRequest request, boolean streaming) throws Exception {
- int requestId = mCameraUser.submitRequest(request, streaming, null);
+ private SubmitInfo submitCameraRequest(CaptureRequest request, boolean streaming) throws Exception {
+ SubmitInfo requestInfo = mCameraUser.submitRequest(request, streaming);
assertTrue(
- "Request IDs should be non-negative (expected: >= 0, actual: " + requestId + ")",
- requestId >= 0);
- return requestId;
+ "Request IDs should be non-negative (expected: >= 0, actual: " +
+ requestInfo.getRequestId() + ")",
+ requestInfo.getRequestId() >= 0);
+ return requestInfo;
}
@Override
@@ -214,10 +216,8 @@
mMockCb = spy(dummyCallbacks);
- BinderHolder holder = new BinderHolder();
- mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
- clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
- mCameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
+ mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
+ clientPackageName, ICameraService.USE_CALLING_UID);
assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
@@ -238,11 +238,10 @@
@SmallTest
public void testCreateDefaultRequest() throws Exception {
- CameraMetadataNative metadata = new CameraMetadataNative();
+ CameraMetadataNative metadata = null;
assertTrue(metadata.isEmpty());
- int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ metadata = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW);
assertFalse(metadata.isEmpty());
}
@@ -252,18 +251,28 @@
int streamId = mCameraUser.createStream(mOutputConfiguration);
assertEquals(0, streamId);
- assertEquals(CameraBinderTestUtils.ALREADY_EXISTS,
- mCameraUser.createStream(mOutputConfiguration));
+ try {
+ mCameraUser.createStream(mOutputConfiguration);
+ fail("Creating same stream twice");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Creating same stream twice",
+ e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
+ }
- assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId));
+ mCameraUser.deleteStream(streamId);
}
@SmallTest
public void testDeleteInvalidStream() throws Exception {
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(-1));
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0));
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(1));
- assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0xC0FFEE));
+ int[] badStreams = { -1, 0, 1, 0xC0FFEE };
+ for (int badStream : badStreams) {
+ try {
+ mCameraUser.deleteStream(badStream);
+ fail("Allowed bad stream delete");
+ } catch (ServiceSpecificException e) {
+ assertEquals(e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
+ }
+ }
}
@SmallTest
@@ -273,8 +282,13 @@
int streamId = mCameraUser.createStream(mOutputConfiguration);
assertEquals(0, streamId);
- assertEquals(CameraBinderTestUtils.ALREADY_EXISTS,
- mCameraUser.createStream(mOutputConfiguration));
+ try {
+ mCameraUser.createStream(mOutputConfiguration);
+ fail("Created same stream twice");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Created same stream twice",
+ ICameraService.ERROR_ALREADY_EXISTS, e.errorCode);
+ }
// Create second stream with a different surface.
SurfaceTexture surfaceTexture = new SurfaceTexture(/* ignored */0);
@@ -286,8 +300,8 @@
assertEquals(1, streamId2);
// Clean up streams
- assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId));
- assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId2));
+ mCameraUser.deleteStream(streamId);
+ mCameraUser.deleteStream(streamId2);
}
@SmallTest
@@ -295,16 +309,25 @@
CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */false);
CaptureRequest request1 = builder.build();
- int status = mCameraUser.submitRequest(request1, /* streaming */false, null);
- assertEquals("Expected submitRequest to return BAD_VALUE " +
- "since we had 0 surface targets set.", CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ SubmitInfo requestInfo = mCameraUser.submitRequest(request1, /* streaming */false);
+ fail("Exception expected");
+ } catch(ServiceSpecificException e) {
+ assertEquals("Expected submitRequest to throw ServiceSpecificException with BAD_VALUE " +
+ "since we had 0 surface targets set.", ICameraService.ERROR_ILLEGAL_ARGUMENT,
+ e.errorCode);
+ }
builder.addTarget(mSurface);
CaptureRequest request2 = builder.build();
- status = mCameraUser.submitRequest(request2, /* streaming */false, null);
- assertEquals("Expected submitRequest to return BAD_VALUE since " +
- "the target surface wasn't registered with createStream.",
- CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ SubmitInfo requestInfo = mCameraUser.submitRequest(request2, /* streaming */false);
+ fail("Exception expected");
+ } catch(ServiceSpecificException e) {
+ assertEquals("Expected submitRequest to throw ILLEGAL_ARGUMENT " +
+ "ServiceSpecificException since the target wasn't registered with createStream.",
+ ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
+ }
}
@SmallTest
@@ -314,9 +337,10 @@
CaptureRequest request = builder.build();
// Submit valid request twice.
- int requestId1 = submitCameraRequest(request, /* streaming */false);
- int requestId2 = submitCameraRequest(request, /* streaming */false);
- assertNotSame("Request IDs should be unique for multiple requests", requestId1, requestId2);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
+ assertNotSame("Request IDs should be unique for multiple requests",
+ requestInfo1.getRequestId(), requestInfo2.getRequestId());
}
@@ -329,32 +353,35 @@
// Submit valid request once (non-streaming), and another time
// (streaming)
- int requestId1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
- int requestIdStreaming = submitCameraRequest(request, /* streaming */true);
- assertNotSame("Request IDs should be unique for multiple requests", requestId1,
- requestIdStreaming);
+ SubmitInfo requestInfoStreaming = submitCameraRequest(request, /* streaming */true);
+ assertNotSame("Request IDs should be unique for multiple requests",
+ requestInfo1.getRequestId(),
+ requestInfoStreaming.getRequestId());
- int status = mCameraUser.cancelRequest(-1, null);
- assertEquals("Invalid request IDs should not be cancellable",
- CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ long lastFrameNumber = mCameraUser.cancelRequest(-1);
+ fail("Expected exception");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Invalid request IDs should not be cancellable",
+ ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
+ }
- status = mCameraUser.cancelRequest(requestId1, null);
- assertEquals("Non-streaming request IDs should not be cancellable",
- CameraBinderTestUtils.BAD_VALUE, status);
+ try {
+ long lastFrameNumber = mCameraUser.cancelRequest(requestInfo1.getRequestId());
+ fail("Expected exception");
+ } catch (ServiceSpecificException e) {
+ assertEquals("Non-streaming request IDs should not be cancellable",
+ ICameraService.ERROR_ILLEGAL_ARGUMENT, e.errorCode);
+ }
- status = mCameraUser.cancelRequest(requestIdStreaming, null);
- assertEquals("Streaming request IDs should be cancellable", CameraBinderTestUtils.NO_ERROR,
- status);
-
+ long lastFrameNumber = mCameraUser.cancelRequest(requestInfoStreaming.getRequestId());
}
@SmallTest
public void testCameraInfo() throws RemoteException {
- CameraMetadataNative info = new CameraMetadataNative();
-
- int status = mCameraUser.getCameraInfo(/*out*/info);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ CameraMetadataNative info = mCameraUser.getCameraInfo();
assertFalse(info.isEmpty());
assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
@@ -362,10 +389,7 @@
@SmallTest
public void testCameraCharacteristics() throws RemoteException {
- CameraMetadataNative info = new CameraMetadataNative();
-
- int status = mUtils.getCameraService().getCameraCharacteristics(mCameraId, /*out*/info);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ CameraMetadataNative info = mUtils.getCameraService().getCameraCharacteristics(mCameraId);
assertFalse(info.isEmpty());
assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
@@ -374,18 +398,19 @@
@SmallTest
public void testWaitUntilIdle() throws Exception {
CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
- int requestIdStreaming = submitCameraRequest(builder.build(), /* streaming */true);
+ SubmitInfo requestInfoStreaming = submitCameraRequest(builder.build(), /* streaming */true);
// Test Bad case first: waitUntilIdle when there is active repeating request
- int status = mCameraUser.waitUntilIdle();
- assertEquals("waitUntilIdle is invalid operation when there is active repeating request",
- CameraBinderTestUtils.INVALID_OPERATION, status);
+ try {
+ mCameraUser.waitUntilIdle();
+ } catch (ServiceSpecificException e) {
+ assertEquals("waitUntilIdle is invalid operation when there is active repeating request",
+ ICameraService.ERROR_INVALID_OPERATION, e.errorCode);
+ }
// Test good case, waitUntilIdle when there is no active repeating request
- status = mCameraUser.cancelRequest(requestIdStreaming, null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
- status = mCameraUser.waitUntilIdle();
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ long lastFrameNumber = mCameraUser.cancelRequest(requestInfoStreaming.getRequestId());
+ mCameraUser.waitUntilIdle();
}
@SmallTest
@@ -411,12 +436,12 @@
ArgumentCaptor<Long> timestamps = ArgumentCaptor.forClass(Long.class);
// Test both single request and streaming request.
- int requestId1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).times(1)).onCaptureStarted(
any(CaptureResultExtras.class),
anyLong());
- int streamingId = submitCameraRequest(request, /* streaming */true);
+ SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).atLeast(NUM_CALLBACKS_CHECKED))
.onCaptureStarted(
any(CaptureResultExtras.class),
@@ -436,22 +461,22 @@
CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
// Try streaming
- int streamingId = submitCameraRequest(request, /* streaming */true);
+ SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
// Wait a bit to fill up the queue
SystemClock.sleep(WAIT_FOR_WORK_MS);
// Cancel and make sure we eventually quiesce
- status = mCameraUser.cancelRequest(streamingId, null);
+ long lastFrameNumber = mCameraUser.cancelRequest(streamingInfo.getRequestId());
verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(1)).onDeviceIdle();
// Submit a few capture requests
- int requestId1 = submitCameraRequest(request, /* streaming */false);
- int requestId2 = submitCameraRequest(request, /* streaming */false);
- int requestId3 = submitCameraRequest(request, /* streaming */false);
- int requestId4 = submitCameraRequest(request, /* streaming */false);
- int requestId5 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo3 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo4 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo5 = submitCameraRequest(request, /* streaming */false);
// And wait for more idle
verify(mMockCb, timeout(WAIT_FOR_IDLE_TIMEOUT_MS).times(2)).onDeviceIdle();
@@ -463,38 +488,34 @@
int status;
// Initial flush should work
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ long lastFrameNumber = mCameraUser.flush();
// Then set up a stream
CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
// Flush should still be a no-op, really
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ lastFrameNumber = mCameraUser.flush();
// Submit a few capture requests
- int requestId1 = submitCameraRequest(request, /* streaming */false);
- int requestId2 = submitCameraRequest(request, /* streaming */false);
- int requestId3 = submitCameraRequest(request, /* streaming */false);
- int requestId4 = submitCameraRequest(request, /* streaming */false);
- int requestId5 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo1 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo2 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo3 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo4 = submitCameraRequest(request, /* streaming */false);
+ SubmitInfo requestInfo5 = submitCameraRequest(request, /* streaming */false);
// Then flush and wait for idle
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ lastFrameNumber = mCameraUser.flush();
verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(1)).onDeviceIdle();
// Now a streaming request
- int streamingId = submitCameraRequest(request, /* streaming */true);
+ SubmitInfo streamingInfo = submitCameraRequest(request, /* streaming */true);
// Wait a bit to fill up the queue
SystemClock.sleep(WAIT_FOR_WORK_MS);
// Then flush and wait for the idle callback
- status = mCameraUser.flush(null);
- assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+ lastFrameNumber = mCameraUser.flush();
verify(mMockCb, timeout(WAIT_FOR_FLUSH_TIMEOUT_MS).times(2)).onDeviceIdle();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
deleted file mode 100644
index 33c6388..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2013 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.mediaframeworktest.unit;
-
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.utils.CameraBinderDecorator;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.os.DeadObjectException;
-import android.os.RemoteException;
-import android.os.TransactionTooLargeException;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import static org.mockito.Mockito.*;
-import static android.hardware.camera2.utils.CameraBinderDecorator.*;
-import static android.hardware.camera2.CameraAccessException.*;
-import static android.system.OsConstants.*;
-
-import junit.framework.Assert;
-
-public class CameraUtilsBinderDecoratorTest extends junit.framework.TestCase {
-
- private interface ICameraBinderStereotype {
-
- double doNothing();
-
- // int is a 'status_t'
- int doSomethingPositive();
-
- int doSomethingNoError();
-
- int doSomethingPermissionDenied();
-
- int doSomethingAlreadyExists();
-
- int doSomethingBadValue();
-
- int doSomethingDeadObject() throws CameraRuntimeException;
-
- int doSomethingBadPolicy() throws CameraRuntimeException;
-
- int doSomethingDeviceBusy() throws CameraRuntimeException;
-
- int doSomethingNoSuchDevice() throws CameraRuntimeException;
-
- int doSomethingUnknownErrorCode();
-
- int doSomethingThrowDeadObjectException() throws RemoteException;
-
- int doSomethingThrowTransactionTooLargeException() throws RemoteException;
- }
-
- private static final double SOME_ARBITRARY_DOUBLE = 1.0;
- private static final int SOME_ARBITRARY_POSITIVE_INT = 5;
- private static final int SOME_ARBITRARY_NEGATIVE_INT = -0xC0FFEE;
-
- @SmallTest
- public void testStereotypes() {
-
- ICameraBinderStereotype mock = mock(ICameraBinderStereotype.class);
- try {
- when(mock.doNothing()).thenReturn(SOME_ARBITRARY_DOUBLE);
- when(mock.doSomethingPositive()).thenReturn(SOME_ARBITRARY_POSITIVE_INT);
- when(mock.doSomethingNoError()).thenReturn(NO_ERROR);
- when(mock.doSomethingPermissionDenied()).thenReturn(PERMISSION_DENIED);
- when(mock.doSomethingAlreadyExists()).thenReturn(ALREADY_EXISTS);
- when(mock.doSomethingBadValue()).thenReturn(BAD_VALUE);
- when(mock.doSomethingDeadObject()).thenReturn(DEAD_OBJECT);
- when(mock.doSomethingBadPolicy()).thenReturn(-EACCES);
- when(mock.doSomethingDeviceBusy()).thenReturn(-EBUSY);
- when(mock.doSomethingNoSuchDevice()).thenReturn(-ENODEV);
- when(mock.doSomethingUnknownErrorCode()).thenReturn(SOME_ARBITRARY_NEGATIVE_INT);
- when(mock.doSomethingThrowDeadObjectException()).thenThrow(new DeadObjectException());
- when(mock.doSomethingThrowTransactionTooLargeException()).thenThrow(
- new TransactionTooLargeException());
- } catch (RemoteException e) {
- Assert.fail("Unreachable");
- }
-
- ICameraBinderStereotype decoratedMock = CameraBinderDecorator.newInstance(mock);
-
- // ignored by decorator because return type is double, not int
- assertEquals(SOME_ARBITRARY_DOUBLE, decoratedMock.doNothing());
-
- // pass through for positive values
- assertEquals(SOME_ARBITRARY_POSITIVE_INT, decoratedMock.doSomethingPositive());
-
- // pass through NO_ERROR
- assertEquals(NO_ERROR, decoratedMock.doSomethingNoError());
-
- try {
- decoratedMock.doSomethingPermissionDenied();
- Assert.fail("Should've thrown SecurityException");
- } catch (SecurityException e) {
- }
-
- assertEquals(ALREADY_EXISTS, decoratedMock.doSomethingAlreadyExists());
-
- try {
- decoratedMock.doSomethingBadValue();
- Assert.fail("Should've thrown IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- }
-
- try {
- decoratedMock.doSomethingDeadObject();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISCONNECTED, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingBadPolicy();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISABLED, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingDeviceBusy();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_IN_USE, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingNoSuchDevice();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISCONNECTED, e.getReason());
- }
-
- try {
- decoratedMock.doSomethingUnknownErrorCode();
- Assert.fail("Should've thrown UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- assertEquals(String.format("Unknown error %d",
- SOME_ARBITRARY_NEGATIVE_INT), e.getMessage());
- }
-
- try {
- decoratedMock.doSomethingThrowDeadObjectException();
- Assert.fail("Should've thrown CameraRuntimeException");
- } catch (CameraRuntimeException e) {
- assertEquals(CAMERA_DISCONNECTED, e.getReason());
- } catch (RemoteException e) {
- Assert.fail("Should not throw a DeadObjectException directly, but rethrow");
- }
-
- try {
- decoratedMock.doSomethingThrowTransactionTooLargeException();
- Assert.fail("Should've thrown UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- assertTrue(e.getCause() instanceof TransactionTooLargeException);
- } catch (RemoteException e) {
- Assert.fail("Should not throw a TransactionTooLargeException directly, but rethrow");
- }
- }
-
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java
deleted file mode 100644
index c3b6006..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2013 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.mediaframeworktest.unit;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import android.hardware.camera2.utils.*;
-import android.hardware.camera2.utils.Decorator.DecoratorListener;
-
-import junit.framework.Assert;
-
-import java.lang.reflect.Method;
-
-/**
- * adb shell am instrument -e class 'com.android.mediaframeworktest.unit.CameraUtilsDecoratorTest' \
- * -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
- */
-public class CameraUtilsDecoratorTest extends junit.framework.TestCase {
- private DummyListener mDummyListener;
- private DummyInterface mIface;
-
- @Override
- public void setUp() {
- mDummyListener = new DummyListener();
- mIface = Decorator.newInstance(new DummyImpl(), mDummyListener);
- }
-
- interface DummyInterface {
- int addValues(int x, int y, int z);
-
- void raiseException() throws Exception;
-
- void raiseUnsupportedOperationException() throws UnsupportedOperationException;
- }
-
- class DummyImpl implements DummyInterface {
- @Override
- public int addValues(int x, int y, int z) {
- return x + y + z;
- }
-
- @Override
- public void raiseException() throws Exception {
- throw new Exception("Test exception");
- }
-
- @Override
- public void raiseUnsupportedOperationException() throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Test exception");
- }
- }
-
- class DummyListener implements DecoratorListener {
-
- public boolean beforeCalled = false;
- public boolean afterCalled = false;
- public boolean catchCalled = false;
- public boolean finallyCalled = false;
- public Object resultValue = null;
-
- public boolean raiseException = false;
-
- @Override
- public void onBeforeInvocation(Method m, Object[] args) {
- beforeCalled = true;
- }
-
- @Override
- public void onAfterInvocation(Method m, Object[] args, Object result) {
- afterCalled = true;
- resultValue = result;
-
- if (raiseException) {
- throw new UnsupportedOperationException("Test exception");
- }
- }
-
- @Override
- public boolean onCatchException(Method m, Object[] args, Throwable t) {
- catchCalled = true;
- return false;
- }
-
- @Override
- public void onFinally(Method m, Object[] args) {
- finallyCalled = true;
- }
-
- };
-
- @SmallTest
- public void testDecorator() {
-
- // TODO rewrite this using mocks
-
- assertTrue(mIface.addValues(1, 2, 3) == 6);
- assertTrue(mDummyListener.beforeCalled);
- assertTrue(mDummyListener.afterCalled);
-
- int resultValue = (Integer)mDummyListener.resultValue;
- assertTrue(resultValue == 6);
- assertTrue(mDummyListener.finallyCalled);
- assertFalse(mDummyListener.catchCalled);
- }
-
- @SmallTest
- public void testDecoratorExceptions() {
-
- boolean gotExceptions = false;
- try {
- mIface.raiseException();
- } catch (Exception e) {
- gotExceptions = true;
- assertTrue(e.getMessage() == "Test exception");
- }
- assertTrue(gotExceptions);
- assertTrue(mDummyListener.beforeCalled);
- assertFalse(mDummyListener.afterCalled);
- assertTrue(mDummyListener.catchCalled);
- assertTrue(mDummyListener.finallyCalled);
- }
-
- @SmallTest
- public void testDecoratorUnsupportedOperationException() {
-
- boolean gotExceptions = false;
- try {
- mIface.raiseUnsupportedOperationException();
- } catch (UnsupportedOperationException e) {
- gotExceptions = true;
- assertTrue(e.getMessage() == "Test exception");
- }
- assertTrue(gotExceptions);
- assertTrue(mDummyListener.beforeCalled);
- assertFalse(mDummyListener.afterCalled);
- assertTrue(mDummyListener.catchCalled);
- assertTrue(mDummyListener.finallyCalled);
- }
-
- @SmallTest
- public void testDecoratorRaisesException() {
-
- boolean gotExceptions = false;
- try {
- mDummyListener.raiseException = true;
- mIface.addValues(1, 2, 3);
- Assert.fail("unreachable");
- } catch (UnsupportedOperationException e) {
- gotExceptions = true;
- assertTrue(e.getMessage() == "Test exception");
- }
- assertTrue(gotExceptions);
- assertTrue(mDummyListener.beforeCalled);
- assertTrue(mDummyListener.afterCalled);
- assertFalse(mDummyListener.catchCalled);
- assertTrue(mDummyListener.finallyCalled);
- }
-}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java
deleted file mode 100644
index 02c9f2a..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 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.mediaframeworktest.unit;
-
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.utils.CameraRuntimeException;
-import android.hardware.camera2.utils.UncheckedThrow;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.Assert;
-
-public class CameraUtilsRuntimeExceptionTest extends junit.framework.TestCase {
-
- @SmallTest
- public void testCameraRuntimeException1() {
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345);
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertNull(e.getMessage());
- assertNull(e.getCause());
- }
- }
-
- @SmallTest
- public void testCameraRuntimeException2() {
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, "Hello");
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertEquals("Hello", e.getMessage());
- assertNull(e.getCause());
- }
- }
-
- @SmallTest
- public void testCameraRuntimeException3() {
- Throwable cause = new IllegalStateException("For great justice");
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, cause);
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertNull(e.getMessage());
- assertEquals(cause, e.getCause());
- }
- }
-
- @SmallTest
- public void testCameraRuntimeException4() {
- Throwable cause = new IllegalStateException("For great justice");
- try {
- CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, "Hello", cause);
- throw runtimeExc.asChecked();
- } catch (CameraAccessException e) {
- assertEquals(12345, e.getReason());
- assertEquals("Hello", e.getMessage());
- assertEquals(cause, e.getCause());
- }
- }
-}
diff --git a/packages/DocumentsUI/res/drawable/ic_sd_storage.xml b/packages/DocumentsUI/res/drawable/ic_sd_storage.xml
index b0f3cc3..5aeebbb 100644
--- a/packages/DocumentsUI/res/drawable/ic_sd_storage.xml
+++ b/packages/DocumentsUI/res/drawable/ic_sd_storage.xml
@@ -14,8 +14,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/packages/DocumentsUI/res/drawable/ic_usb_storage.xml b/packages/DocumentsUI/res/drawable/ic_usb_storage.xml
new file mode 100644
index 0000000..2a8d024
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/ic_usb_storage.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15 7v4h1v2h-3V5h2l-3,-4,-3 4h2v8H8v-2.07c.7,-.37 1.2,-1.08 1.2,-1.93 0,-1.21,-.99,-2.2,-2.2,-2.2,-1.21 0,-2.2.99,-2.2 2.2 0 .85.5 1.56 1.2 1.93V13c0 1.11.89 2 2 2h3v3.05c-.71.37,-1.2 1.1,-1.2 1.95 0 1.22.99 2.2 2.2 2.2 1.21 0 2.2,-.98 2.2,-2.2 0,-.85,-.49,-1.58,-1.2,-1.95V15h3c1.11 0 2,-.89 2,-2v-2h1V7h-4z"/>
+</vector>
diff --git a/packages/DocumentsUI/res/layout/dialog_delete_confirmation.xml b/packages/DocumentsUI/res/layout/dialog_delete_confirmation.xml
new file mode 100644
index 0000000..990ce0b
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/dialog_delete_confirmation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingTop="30dp"
+ android:gravity="center"
+ android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textColor="@*android:color/primary_text_default_material_light">
+</TextView>
diff --git a/packages/DocumentsUI/res/layout/item_root.xml b/packages/DocumentsUI/res/layout/item_root.xml
index ff80d07..816cb8a 100644
--- a/packages/DocumentsUI/res/layout/item_root.xml
+++ b/packages/DocumentsUI/res/layout/item_root.xml
@@ -27,8 +27,6 @@
<FrameLayout
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
- android:layout_marginStart="@dimen/root_icon_margin"
- android:layout_marginEnd="@dimen/root_icon_margin"
android:duplicateParentState="true">
<ImageView
@@ -55,7 +53,7 @@
android:singleLine="true"
android:ellipsize="end"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@android:style/TextAppearance.Material.Menu"
android:textColor="@color/item_root_primary_text" />
<TextView
@@ -65,7 +63,7 @@
android:singleLine="true"
android:ellipsize="end"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@android:style/TextAppearance.Material.Caption"
android:textColor="@color/item_root_primary_text" />
</LinearLayout>
diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml
index 73571af..79f6fa9 100644
--- a/packages/DocumentsUI/res/menu/activity.xml
+++ b/packages/DocumentsUI/res/menu/activity.xml
@@ -84,10 +84,6 @@
android:showAsAction="never"
android:visible="false" />
<item
- android:id="@+id/menu_advanced"
- android:showAsAction="never"
- android:visible="false" />
- <item
android:id="@+id/menu_settings"
android:title="@string/menu_settings"
android:showAsAction="never"
diff --git a/packages/DocumentsUI/res/values-sw720dp/dimens.xml b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
index 2488fa2..b5d1150 100644
--- a/packages/DocumentsUI/res/values-sw720dp/dimens.xml
+++ b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
@@ -18,4 +18,6 @@
<dimen name="grid_padding_horiz">16dp</dimen>
<dimen name="grid_padding_vert">16dp</dimen>
+ <dimen name="list_item_padding">24dp</dimen>
+
</resources>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index 3dc111a..6e1b30e 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -208,11 +208,9 @@
<string name="allow">Allow</string>
<!-- Text in the button asking user to deny access to a given directory. -->
<string name="deny">Deny</string>
- <!-- Dialog title shown to users when asking if they want to delete files (a confirmation). -->
- <string name="delete_confirmation_title">Delete files?</string>
<!-- Dialog text shown to users when asking if they want to delete files (a confirmation). -->
<plurals name="delete_confirmation_message">
- <item quantity="one">Are you sure you want to delete <xliff:g id="count" example="1">%1$d</xliff:g> file?</item>
- <item quantity="other">Are you sure you want to delete <xliff:g id="count" example="3">%1$d</xliff:g> files?</item>
+ <item quantity="one">Delete <xliff:g id="count" example="1">%1$d</xliff:g> file?</item>
+ <item quantity="other">Delete <xliff:g id="count" example="3">%1$d</xliff:g> files?</item>
</plurals>
</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 699700b..6efe9d1 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -151,7 +151,6 @@
final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
final MenuItem grid = menu.findItem(R.id.menu_grid);
final MenuItem list = menu.findItem(R.id.menu_list);
- final MenuItem advanced = menu.findItem(R.id.menu_advanced);
final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
// Search uses backend ranking; no sorting, recents doesn't support sort.
@@ -163,9 +162,6 @@
grid.setVisible(mState.derivedMode != State.MODE_GRID);
list.setVisible(mState.derivedMode != State.MODE_LIST);
- advanced.setVisible(!mState.forceAdvanced);
- advanced.setTitle(LocalPreferences.getDisplayAdvancedDevices(this)
- ? R.string.menu_advanced_hide : R.string.menu_advanced_show);
fileSize.setTitle(LocalPreferences.getDisplayFileSize(this)
? R.string.menu_file_size_hide : R.string.menu_file_size_show);
@@ -201,10 +197,6 @@
state.forceSize = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_FILESIZE, false);
state.showSize = state.forceSize || LocalPreferences.getDisplayFileSize(this);
- state.forceAdvanced = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
- state.showAdvanced = state.forceAdvanced
- || LocalPreferences.getDisplayAdvancedDevices(this);
-
state.initAcceptMimes(intent);
state.excludedAuthorities = getExcludedAuthorities();
@@ -280,10 +272,6 @@
}
return true;
- case R.id.menu_advanced:
- setDisplayAdvancedDevices(!LocalPreferences.getDisplayAdvancedDevices(this));
- return true;
-
case R.id.menu_file_size:
setDisplayFileSize(!LocalPreferences.getDisplayFileSize(this));
return true;
@@ -435,13 +423,6 @@
return mState;
}
- void setDisplayAdvancedDevices(boolean display) {
- LocalPreferences.setDisplayAdvancedDevices(this, display);
- mState.showAdvanced = mState.forceAdvanced | display;
- RootsFragment.get(getFragmentManager()).onDisplayStateChanged();
- invalidateOptionsMenu();
- }
-
void setDisplayFileSize(boolean display) {
LocalPreferences.setDisplayFileSize(this, display);
mState.showSize = display;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index 40bd754..ebc9082 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -82,6 +82,9 @@
builder.setNegativeButton(android.R.string.cancel, null);
final AlertDialog dialog = builder.create();
+ // Workaround for the problem - virtual keyboard doesn't show on the phone.
+ Shared.ensureKeyboardPresent(context, dialog);
+
editText.setOnEditorActionListener(
new OnEditorActionListener() {
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
index b5d3ea0..2f784cb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
@@ -98,12 +98,10 @@
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- final MenuItem advanced = menu.findItem(R.id.menu_advanced);
final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard);
final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
- advanced.setVisible(false);
createDir.setVisible(false);
pasteFromCb.setEnabled(false);
fileSize.setVisible(false);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
index 170fb89..c7c61c3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
@@ -25,17 +25,9 @@
import com.android.documentsui.model.RootInfo;
public class LocalPreferences {
- private static final String KEY_ADVANCED_DEVICES = "advancedDevices";
private static final String KEY_FILE_SIZE = "fileSize";
private static final String ROOT_VIEW_MODE_PREFIX = "rootViewMode-";
- public static boolean getDisplayAdvancedDevices(Context context) {
- boolean defaultAdvanced = context.getResources()
- .getBoolean(R.bool.config_defaultAdvancedDevices);
- return PreferenceManager.getDefaultSharedPreferences(context)
- .getBoolean(KEY_ADVANCED_DEVICES, defaultAdvanced);
- }
-
public static boolean getDisplayFileSize(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(KEY_FILE_SIZE, false);
@@ -47,11 +39,6 @@
.getInt(createKey(root), fallback);
}
- public static void setDisplayAdvancedDevices(Context context, boolean display) {
- PreferenceManager.getDefaultSharedPreferences(context).edit()
- .putBoolean(KEY_ADVANCED_DEVICES, display).apply();
- }
-
public static void setDisplayFileSize(Context context, boolean display) {
PreferenceManager.getDefaultSharedPreferences(context).edit()
.putBoolean(KEY_FILE_SIZE, display).apply();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index b63fefd..2b7294a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -439,39 +439,27 @@
continue;
}
- if (!state.showAdvanced && root.isAdvanced()) {
- if (DEBUG) Log.d(TAG, "Excluding root because: unwanted advanced device.");
- continue;
- }
-
- // Exclude non-local devices when local only
if (state.localOnly && !root.isLocalOnly()) {
if (DEBUG) Log.d(TAG, "Excluding root because: unwanted non-local device.");
continue;
}
- // Exclude downloads roots as it doesn't support directory creation (actually
- // we just don't show them).
- // TODO: Add flag to check the root supports directory creation.
if (state.directoryCopy && root.isDownloads()) {
if (DEBUG) Log.d(
TAG, "Excluding downloads root because: unsupported directory copy.");
continue;
}
- // Only show empty roots when creating, or in browse mode.
if (state.action == State.ACTION_OPEN && root.isEmpty()) {
if (DEBUG) Log.d(TAG, "Excluding empty root because: ACTION_OPEN.");
continue;
}
- // Only show empty roots when creating, or in browse mode.
if (state.action == State.ACTION_GET_CONTENT && root.isEmpty()) {
if (DEBUG) Log.d(TAG, "Excluding empty root because: ACTION_GET_CONTENT.");
continue;
}
- // Only include roots that serve requested content
final boolean overlap =
MimePredicate.mimeMatches(root.derivedMimeTypes, state.acceptMimes) ||
MimePredicate.mimeMatches(state.acceptMimes, root.derivedMimeTypes);
@@ -482,9 +470,8 @@
continue;
}
- // Exclude roots from the calling package.
if (state.excludedAuthorities.contains(root.authority)) {
- if (DEBUG) Log.d(TAG, "Excluding root because: calling package.");
+ if (DEBUG) Log.d(TAG, "Excluding root because: owned by calling package.");
continue;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index 99c2d80..26900a7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -17,9 +17,12 @@
package com.android.documentsui;
import android.content.Context;
+import android.content.res.Configuration;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
+import android.view.WindowManager;
+import android.app.AlertDialog;
import java.text.Collator;
import java.util.ArrayList;
@@ -155,4 +158,15 @@
return sCollator.compare(lhs, rhs);
}
+
+ public static boolean isHardwareKeyboardAvailable(Context context) {
+ return context.getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS;
+ }
+
+ public static void ensureKeyboardPresent(Context context, AlertDialog dialog) {
+ if (!isHardwareKeyboardAvailable(context)) {
+ dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ }
+ }
+
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java
index 62f9ea7..4f460b4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/State.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/State.java
@@ -82,8 +82,6 @@
public boolean forceSize;
public boolean showSize;
public boolean localOnly;
- public boolean forceAdvanced;
- public boolean showAdvanced;
public boolean restored;
// Indicates that a copy operation (or move) includes a directory.
@@ -181,8 +179,6 @@
out.writeInt(forceSize ? 1 : 0);
out.writeInt(showSize ? 1 : 0);
out.writeInt(localOnly ? 1 : 0);
- out.writeInt(forceAdvanced ? 1 : 0);
- out.writeInt(showAdvanced ? 1 : 0);
out.writeInt(restored ? 1 : 0);
DurableUtils.writeToParcel(out, stack);
out.writeMap(dirState);
@@ -211,8 +207,6 @@
state.forceSize = in.readInt() != 0;
state.showSize = in.readInt() != 0;
state.localOnly = in.readInt() != 0;
- state.forceAdvanced = in.readInt() != 0;
- state.showAdvanced = in.readInt() != 0;
state.restored = in.readInt() != 0;
DurableUtils.readFromParcel(in, state.stack);
in.readMap(state.dirState, loader);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 1348a58..83838d3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -168,6 +168,7 @@
private GridLayoutManager mLayout;
private int mColumnCount = 1; // This will get updated when layout changes.
+ private LayoutInflater mInflater;
private MessageBar mMessageBar;
private View mProgressBar;
@@ -182,13 +183,12 @@
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ mInflater = inflater;
final View view = inflater.inflate(R.layout.fragment_directory, container, false);
mMessageBar = MessageBar.create(getChildFragmentManager());
mProgressBar = view.findViewById(R.id.progressbar);
-
mEmptyView = view.findViewById(android.R.id.empty);
-
mRecView = (RecyclerView) view.findViewById(R.id.dir_list);
mRecView.setRecyclerListener(
new RecyclerListener() {
@@ -708,13 +708,27 @@
new GetDocumentsTask() {
@Override
void onDocumentsReady(final List<DocumentInfo> docs) {
+
+ TextView message =
+ (TextView) mInflater.inflate(R.layout.dialog_delete_confirmation, null);
+ message.setText(
+ Shared.getQuantityString(
+ getActivity(),
+ R.plurals.delete_confirmation_message,
+ docs.size()));
+
+ // This "insta-hides" files that are being deleted, because
+ // the delete operation may be not execute immediately (it
+ // may be queued up on the FileOperationService.)
+ // To hide the files locally, we call the hide method on the adapter
+ // ...which a live object...cannot be parceled.
+ // For that reason, for now, we implement this dialog NOT
+ // as a fragment (which can survive rotation and have its own state),
+ // but as a simple runtime dialog. So rotating a device with an
+ // active delete dialog...results in that dialog disappearing.
+ // We can do better, but don't have cycles for it now.
new AlertDialog.Builder(getActivity())
- .setTitle(R.string.delete_confirmation_title)
- .setMessage(
- Shared.getQuantityString(
- getActivity(),
- R.plurals.delete_confirmation_message,
- docs.size()))
+ .setView(message)
.setPositiveButton(
android.R.string.yes,
new DialogInterface.OnClickListener() {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
index 0930c22..0bbecf9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
@@ -74,13 +74,6 @@
abstract public SparseArray<String> hide(String... ids);
/**
- * Unhides a set of previously hidden items.
- *
- * @param ids A sparse array of IDs from a previous call to {@link #hide}.
- */
- abstract void unhide(SparseArray<String> ids);
-
- /**
* Returns a class that yields the span size for a particular element. This is
* primarily useful in {@link SectionBreakDocumentsAdapterWrapper} where
* we adjust sizes.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
index 11f9aa71..8b619b6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
@@ -123,20 +123,20 @@
mSummary.setVisibility(View.INVISIBLE);
}
- if (docLastModified == -1) {
+ if (docLastModified > 0) {
hasDetails = true;
- mDate.setText(null);
- } else {
mDate.setText(Shared.formatTime(mContext, docLastModified));
+ } else {
+ mDate.setText(null);
}
- if (!state.showSize || docSize == -1) {
+ if (state.showSize && docSize > -1) {
hasDetails = true;
- mSize.setVisibility(View.GONE);
- mDetails.setVisibility(View.GONE);
- } else {
mSize.setVisibility(View.VISIBLE);
mSize.setText(Formatter.formatFileSize(mContext, docSize));
+ } else {
+ mSize.setVisibility(View.GONE);
+ mDetails.setVisibility(View.GONE);
}
mDetails.setVisibility(hasDetails ? View.VISIBLE : View.GONE);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
index 42dba45..2b07339 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
@@ -24,12 +24,12 @@
import android.database.Cursor;
import android.provider.DocumentsContract.Document;
-import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.SparseArray;
import android.view.ViewGroup;
import com.android.documentsui.State;
+
import com.google.common.collect.Sets;
import java.util.ArrayList;
@@ -181,29 +181,6 @@
return hiddenItems;
}
- @VisibleForTesting
- @Override
- public void unhide(SparseArray<String> ids) {
- if (DEBUG) Log.d(TAG, "Unhiding ids: " + ids);
-
- // An ArrayList can shrink at runtime...and in fact
- // it does when we clear it completely.
- // This means we can't call add(pos, id) without
- // first checking the list size.
- List<String> oldIds = mModelIds;
- mModelIds = new ArrayList<>(oldIds.size() + ids.size());
- mModelIds.addAll(oldIds);
-
- // Finally insert the unhidden items.
- for (int i = 0; i < ids.size(); i++) {
- int pos = ids.keyAt(i);
- String id = ids.get(pos);
- mHiddenIds.remove(id);
- mModelIds.add(pos, id);
- notifyItemInserted(pos);
- }
- }
-
@Override
public List<String> getModelIds() {
return mModelIds;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
index 0018d01..884abbb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -92,6 +92,9 @@
final AlertDialog dialog = builder.create();
+ // Workaround for the problem - virtual keyboard doesn't show on the phone.
+ Shared.ensureKeyboardPresent(context, dialog);
+
mEditText.setOnEditorActionListener(
new OnEditorActionListener() {
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
index 3ee5cfc..b698059 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
@@ -169,13 +169,6 @@
}
@Override
- void unhide(SparseArray<String> ids) {
- // NOTE: We hear about these changes and adjust break position
- // in our AdapterDataObserver.
- mDelegate.unhide(ids);
- }
-
- @Override
List<String> getModelIds() {
return mDelegate.getModelIds();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 3897058..3eaf10a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -16,6 +16,7 @@
package com.android.documentsui.model;
+import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.Shared.compareToIgnoreCaseNullable;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
@@ -31,6 +32,7 @@
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.text.TextUtils;
+import android.util.Log;
import com.android.documentsui.IconUtils;
import com.android.documentsui.R;
@@ -47,6 +49,8 @@
* Representation of a {@link Root}.
*/
public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
+
+ private static final String TAG = "RootInfo";
private static final int VERSION_INIT = 1;
private static final int VERSION_DROP_TYPE = 2;
@@ -59,6 +63,8 @@
TYPE_DOWNLOADS,
TYPE_LOCAL,
TYPE_MTP,
+ TYPE_SD,
+ TYPE_USB,
TYPE_OTHER
})
@Retention(RetentionPolicy.SOURCE)
@@ -70,7 +76,9 @@
public static final int TYPE_DOWNLOADS = 5;
public static final int TYPE_LOCAL = 6;
public static final int TYPE_MTP = 7;
- public static final int TYPE_OTHER = 8;
+ public static final int TYPE_SD = 8;
+ public static final int TYPE_USB = 9;
+ public static final int TYPE_OTHER = 10;
public String authority;
public String rootId;
@@ -185,33 +193,40 @@
private void deriveFields() {
derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
- // TODO: remove these special case icons
if (isHome()) {
+ derivedType = TYPE_LOCAL;
derivedIcon = R.drawable.ic_root_documents;
- derivedType = TYPE_LOCAL;
- } else if (isExternalStorage()) {
- derivedIcon = R.drawable.ic_root_smartphone;
- derivedType = TYPE_LOCAL;
- // TODO: Apply SD card icon to SD devices.
- } else if (isDownloads()) {
- derivedIcon = R.drawable.ic_root_download;
- derivedType = TYPE_DOWNLOADS;
- } else if (isImages()) {
- derivedIcon = R.drawable.ic_doc_image;
- derivedType = TYPE_IMAGES;
- } else if (isVideos()) {
- derivedIcon = R.drawable.ic_doc_video;
- derivedType = TYPE_VIDEO;
- } else if (isAudio()) {
- derivedIcon = R.drawable.ic_doc_audio;
- derivedType = TYPE_AUDIO;
- } else if (isRecents()) {
- derivedType = TYPE_RECENTS;
} else if (isMtp()) {
derivedType = TYPE_MTP;
+ derivedIcon = R.drawable.ic_usb_storage;
+ } else if (isUsb()) {
+ derivedType = TYPE_USB;
+ derivedIcon = R.drawable.ic_usb_storage;
+ } else if (isSd()) {
+ derivedType = TYPE_SD;
+ derivedIcon = R.drawable.ic_sd_storage;
+ } else if (isExternalStorage()) {
+ derivedType = TYPE_LOCAL;
+ derivedIcon = R.drawable.ic_root_smartphone;
+ } else if (isDownloads()) {
+ derivedType = TYPE_DOWNLOADS;
+ derivedIcon = R.drawable.ic_root_download;
+ } else if (isImages()) {
+ derivedType = TYPE_IMAGES;
+ derivedIcon = R.drawable.ic_doc_image;
+ } else if (isVideos()) {
+ derivedType = TYPE_VIDEO;
+ derivedIcon = R.drawable.ic_doc_video;
+ } else if (isAudio()) {
+ derivedType = TYPE_AUDIO;
+ derivedIcon = R.drawable.ic_doc_audio;
+ } else if (isRecents()) {
+ derivedType = TYPE_RECENTS;
} else {
derivedType = TYPE_OTHER;
}
+
+ if (DEBUG) Log.d(TAG, "Finished deriving fields: " + this);
}
public Uri getUri() {
@@ -283,10 +298,6 @@
return (flags & Root.FLAG_SUPPORTS_SEARCH) != 0;
}
- public boolean isAdvanced() {
- return (flags & Root.FLAG_ADVANCED) != 0;
- }
-
public boolean isLocalOnly() {
return (flags & Root.FLAG_LOCAL_ONLY) != 0;
}
@@ -295,6 +306,14 @@
return (flags & Root.FLAG_EMPTY) != 0;
}
+ public boolean isSd() {
+ return (flags & Root.FLAG_REMOVABLE_SD) != 0;
+ }
+
+ public boolean isUsb() {
+ return (flags & Root.FLAG_REMOVABLE_USB) != 0;
+ }
+
public Drawable loadIcon(Context context) {
if (derivedIcon != 0) {
return context.getDrawable(derivedIcon);
@@ -362,7 +381,14 @@
@Override
public String toString() {
- return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
+ return "Root{"
+ + "authority=" + authority
+ + ", rootId=" + rootId
+ + ", title=" + title
+ + ", isUsb=" + isUsb()
+ + ", isSd=" + isSd()
+ + ", isMtp=" + isMtp()
+ + "}";
}
public String getDirectoryString() {
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
index 2e81545..e73dd8c 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
@@ -55,7 +55,6 @@
mState = new State();
mState.action = State.ACTION_OPEN;
- mState.showAdvanced = true;
mState.localOnly = false;
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
index 2244be9..adc8141 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
@@ -73,28 +73,6 @@
assertEquals(mModel.getItemCount() - 2, mAdapter.getItemCount());
}
- // Tests that the items can be hidden and unhidden.
- public void testUnhide_ItemCount() {
- List<String> ids = mModel.getModelIds();
- SparseArray<String> hidden = mAdapter.hide(ids.toArray(new String[ids.size()]));
- mAdapter.unhide(hidden);
- assertEquals(mModel.getItemCount(), mAdapter.getItemCount());
- }
-
- // Tests that the items can be hidden and unhidden.
- public void testUnhide_PreservesOrder() {
- List<String> ids = mModel.getModelIds();
- SparseArray<String> hidden = mAdapter.hide(
- ids.get(0), ids.get(1), ids.get(5), ids.get(9));
- mAdapter.unhide(hidden);
-
- // Finally ensure the restored items are in the original order
- // by checking them against the model.
- for (int i = 0; i < mAdapter.getItemCount(); i++) {
- assertEquals(mModel.idForPosition(i), mAdapter.getModelId(i));
- }
- }
-
private final class TestEnvironment implements DocumentsAdapter.Environment {
private final Context testContext;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java
index 267f47d..e170dbb 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java
@@ -61,11 +61,6 @@
}
@Override
- void unhide(SparseArray<String> ids) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public DocumentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
throw new UnsupportedOperationException();
}
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 97527dd..9a51b05 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -34,6 +34,7 @@
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.OnCloseListener;
import android.os.UserHandle;
+import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.provider.DocumentsContract;
@@ -41,6 +42,7 @@
import android.provider.DocumentsContract.Root;
import android.provider.DocumentsProvider;
import android.provider.MediaStore;
+import android.provider.Settings;
import android.support.provider.DocumentArchiveHelper;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -62,6 +64,7 @@
public class ExternalStorageProvider extends DocumentsProvider {
private static final String TAG = "ExternalStorage";
+ private static final boolean DEBUG = false;
private static final boolean LOG_INOTIFY = false;
public static final String AUTHORITY = "com.android.externalstorage.documents";
@@ -136,10 +139,25 @@
if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
// We currently only support a single emulated volume mounted at
// a time, and it's always considered the primary
+ if (DEBUG) Log.d(TAG, "Found primary volume: " + volume);
rootId = ROOT_ID_PRIMARY_EMULATED;
+
if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
- title = getContext().getString(R.string.root_internal_storage);
+ // This is basically the user's primary device storage.
+ // Use device name for the volume since this is likely same thing
+ // the user sees when they mount their phone on another device.
+ String deviceName = Settings.Global.getString(
+ getContext().getContentResolver(), Settings.Global.DEVICE_NAME);
+
+ // Device name should always be set. In case it isn't, though,
+ // fall back to a localized "Internal Storage" string.
+ title = !TextUtils.isEmpty(deviceName)
+ ? deviceName
+ : getContext().getString(R.string.root_internal_storage);
} else {
+ // This should cover all other storage devices, like an SD card
+ // or USB OTG drive plugged in. Using getBestVolumeDescription()
+ // will give us a nice string like "Samsung SD card" or "SanDisk USB drive"
final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
title = mStorageManager.getBestVolumeDescription(privateVol);
}
@@ -167,10 +185,17 @@
root.flags = Root.FLAG_LOCAL_ONLY
| Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD;
+ final DiskInfo disk = volume.getDisk();
+ if (DEBUG) Log.d(TAG, "Disk for root " + rootId + " is " + disk);
+ if (disk != null && disk.isSd()) {
+ root.flags |= Root.FLAG_REMOVABLE_SD;
+ } else if (disk != null && disk.isUsb()) {
+ root.flags |= Root.FLAG_REMOVABLE_USB;
+ }
+
if (volume.isPrimary()) {
// save off the primary volume for subsequent "Home" dir initialization.
primaryVolume = volume;
- root.flags |= Root.FLAG_ADVANCED;
}
// Dunno when this would NOT be the case, but never hurts to be correct.
if (volume.isMountedWritable()) {
@@ -193,8 +218,9 @@
}
}
- // Finally, if primary storage is available we add the "Home" directory,
- // creating it as needed.
+ // Finally, if primary storage is available we add the "Documents" directory.
+ // If I recall correctly the actual directory is created on demand
+ // by calling either getPathForUser, or getInternalPathForUser.
if (primaryVolume != null && primaryVolume.isVisible()) {
final RootInfo root = new RootInfo();
root.rootId = ROOT_ID_HOME;
@@ -211,8 +237,7 @@
root.flags |= Root.FLAG_SUPPORTS_CREATE;
}
- // Create the "Home" directory on disk, but don't the localized root.title
- // since the directories shouldn't be localized.
+ // Create the "Documents" directory on disk (don't use the localized title).
root.visiblePath = new File(
primaryVolume.getPathForUser(userId), Environment.DIRECTORY_DOCUMENTS);
root.path = new File(
diff --git a/packages/SettingsLib/res/drawable/ic_info.xml b/packages/SettingsLib/res/drawable/ic_info.xml
new file mode 100644
index 0000000..afe7e6b
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_info.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?android:attr/colorAccent">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_settings_lock_outline.xml b/packages/SettingsLib/res/drawable/ic_settings_lock_outline.xml
deleted file mode 100644
index b3d7cf9..0000000
--- a/packages/SettingsLib/res/drawable/ic_settings_lock_outline.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="21dp"
- android:height="21dp"
- android:viewportWidth="21.0"
- android:viewportHeight="21.0"
- android:tint="?android:attr/colorAccent">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M8,16c1.1,0,2-0.9,2-2s-0.9-2-2-2s-2,0.9-2,2S6.9,16,8,16zM14,7h-1V5c0-2.8-2.2-5-5-5S3,2.2,3,5v2H2C0.9,7,0,7.9,0,9v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V9C16,7.9,15.1,7,14,7z M4.9,5c0-1.7,1.4-3.1,3.1-3.1s3.1,1.4,3.1,3.1v2H4.9V5z M14,19H2V9h12V19z" />
-</vector>
diff --git a/packages/SettingsLib/res/layout/restricted_icon.xml b/packages/SettingsLib/res/layout/restricted_icon.xml
new file mode 100644
index 0000000..d57fb80
--- /dev/null
+++ b/packages/SettingsLib/res/layout/restricted_icon.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/restricted_icon"
+ android:layout_width="@dimen/restricted_icon_size"
+ android:layout_height="@dimen/restricted_icon_size"
+ android:src="@drawable/ic_info"
+ android:gravity="end|center_vertical" />
\ No newline at end of file
diff --git a/packages/SettingsLib/res/layout/restricted_switch_widget.xml b/packages/SettingsLib/res/layout/restricted_switch_widget.xml
new file mode 100644
index 0000000..6183812
--- /dev/null
+++ b/packages/SettingsLib/res/layout/restricted_switch_widget.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/restricted_icon"
+ android:layout_width="@dimen/restricted_icon_size"
+ android:layout_height="@dimen/restricted_icon_size"
+ android:src="@drawable/ic_info"
+ android:gravity="end|center_vertical" />
+ <!-- Based off frameworks/base/core/res/res/layout/preference_widget_switch.xml -->
+ <Switch xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+android:id/switch_widget"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:clickable="false"
+ android:background="@null" />
+</merge>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 9f78e87..c3b3cfc 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -33,8 +33,8 @@
<dimen name="user_spinner_item_height">56dp</dimen>
<!-- Lock icon for preferences locked by admin -->
- <dimen name="restricted_lock_icon_size">16dp</dimen>
- <dimen name="restricted_lock_icon_padding">4dp</dimen>
+ <dimen name="restricted_icon_size">16dp</dimen>
+ <dimen name="restricted_icon_padding">4dp</dimen>
<dimen name="wifi_preference_badge_padding">8dip</dimen>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 72fa939..ae2c6e7 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -773,6 +773,11 @@
<!-- Summary for settings preference disabled by administrator [CHAR LIMIT=50] -->
<string name="disabled_by_admin_summary_text">Controlled by admin</string>
+ <!-- Summary for switch preference to denote it is switched on [CHAR LIMIT=50] -->
+ <string name="enabled_by_admin">Enabled by administrator</string>
+ <!-- Summary for switch preference to denote it is switched on [CHAR LIMIT=50] -->
+ <string name="disabled_by_admin">Disabled by administrator</string>
+
<!-- Option in navigation drawer that leads to Settings main screen [CHAR LIMIT=30] -->
<string name="home">Home</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java
index c2f885d..4c0450e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java
@@ -49,7 +49,7 @@
mRestrictedPadlock = RestrictedLockUtils.getRestrictedPadlock(context);
mRestrictedPadlockPadding = context.getResources().getDimensionPixelSize(
- R.dimen.restricted_lock_icon_padding);
+ R.dimen.restricted_icon_padding);
}
private final OnItemSelectedListener mItemSelectedListener = new OnItemSelectedListener() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockImageSpan.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockImageSpan.java
index e63130d..360a34c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockImageSpan.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockImageSpan.java
@@ -36,7 +36,7 @@
mContext = context;
mExtraPadding = mContext.getResources().getDimensionPixelSize(
- R.dimen.restricted_lock_icon_padding);
+ R.dimen.restricted_icon_padding);
mRestrictedPadlock = RestrictedLockUtils.getRestrictedPadlock(mContext);
}
@@ -53,7 +53,7 @@
// Add extra padding before the padlock.
float transX = x + mExtraPadding;
- float transY = bottom - drawable.getBounds().bottom - paint.getFontMetricsInt().descent;
+ float transY = (bottom - drawable.getBounds().bottom) / 2.0f;
canvas.translate(transX, transY);
drawable.draw(canvas);
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index 6d29c5f..d0c249f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -49,9 +49,9 @@
* @return drawables for displaying with settings that are locked by a device admin.
*/
public static Drawable getRestrictedPadlock(Context context) {
- Drawable restrictedPadlock = context.getDrawable(R.drawable.ic_settings_lock_outline);
+ Drawable restrictedPadlock = context.getDrawable(R.drawable.ic_info);
final int iconSize = context.getResources().getDimensionPixelSize(
- R.dimen.restricted_lock_icon_size);
+ R.dimen.restricted_icon_size);
restrictedPadlock.setBounds(0, 0, iconSize, iconSize);
return restrictedPadlock;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
index 810f6eb..e69497a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
@@ -23,6 +23,7 @@
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
+import android.view.View;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -36,6 +37,7 @@
public RestrictedPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ setWidgetLayoutResource(R.layout.restricted_icon);
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
@@ -56,6 +58,10 @@
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
+ final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
+ if (restrictedIcon != null) {
+ restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
+ }
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 227b1e8..0c0af24 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -54,7 +54,7 @@
mRestrictedPadlock = RestrictedLockUtils.getRestrictedPadlock(mContext);
mRestrictedPadlockPadding = mContext.getResources().getDimensionPixelSize(
- R.dimen.restricted_lock_icon_padding);
+ R.dimen.restricted_icon_padding);
if (attrs != null) {
final TypedArray attributes = context.obtainStyledAttributes(attrs,
@@ -91,12 +91,8 @@
* Modify PreferenceViewHolder to add padlock if restriction is disabled.
*/
public void onBindViewHolder(PreferenceViewHolder holder) {
- final TextView titleView = (TextView) holder.findViewById(android.R.id.title);
- if (titleView != null) {
- RestrictedLockUtils.setTextViewPadlock(mContext, titleView, mDisabledByAdmin);
- if (mDisabledByAdmin) {
- holder.itemView.setEnabled(true);
- }
+ if (mDisabledByAdmin) {
+ holder.itemView.setEnabled(true);
}
if (mUseAdminDisabledSummary) {
final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 6cae8aa..f381286 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -23,6 +23,8 @@
import android.support.v7.preference.PreferenceViewHolder;
import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -36,6 +38,7 @@
public RestrictedSwitchPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ setWidgetLayoutResource(R.layout.restricted_switch_widget);
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
@@ -56,6 +59,20 @@
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
+ final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
+ final View switchWidget = holder.findViewById(android.R.id.switch_widget);
+ if (restrictedIcon != null) {
+ restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
+ }
+ if (switchWidget != null) {
+ switchWidget.setVisibility(isDisabledByAdmin() ? View.GONE : View.VISIBLE);
+ }
+ final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
+ if (summaryView != null && isDisabledByAdmin()) {
+ summaryView.setText(
+ isChecked() ? R.string.enabled_by_admin : R.string.disabled_by_admin);
+ summaryView.setVisibility(View.VISIBLE);
+ }
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
index 1859207..741b0ea 100644
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
@@ -25,6 +25,12 @@
import android.util.Log;
import android.util.Pair;
import android.util.Xml;
+import android.provider.Settings;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.ContentValues;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.view.InflateException;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;
@@ -42,6 +48,12 @@
// If defined, only returns this suggestion if the feature is supported.
public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
+ // If defined, only display this optional step if an account of that type exists.
+ private static final String META_DATA_REQUIRE_ACCOUNT = "com.android.settings.require_account";
+
+ // If defined and not true, do not should optional step.
+ private static final String META_DATA_IS_SUPPORTED = "com.android.settings.is_supported";
+
/**
* Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
* For instance:
@@ -110,7 +122,10 @@
TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
addCache, null, suggestions, true, false);
for (int i = countBefore; i < suggestions.size(); i++) {
- if (!isAvailable(suggestions.get(i)) || isDismissed(suggestions.get(i))) {
+ if (!isAvailable(suggestions.get(i)) ||
+ !isSupported(suggestions.get(i)) ||
+ !satisfiesRequiredAccount(suggestions.get(i)) ||
+ isDismissed(suggestions.get(i))) {
suggestions.remove(i--);
}
}
@@ -124,7 +139,10 @@
item = last;
}
}
- suggestions.add(item);
+ // If category is marked as done, do not add any item.
+ if (!isCategoryDone(category.category)) {
+ suggestions.add(item);
+ }
}
}
@@ -136,6 +154,41 @@
return true;
}
+ public boolean satisfiesRequiredAccount(Tile suggestion) {
+ String requiredAccountType = suggestion.metaData.getString(META_DATA_REQUIRE_ACCOUNT);
+ if (requiredAccountType == null) {
+ return true;
+ }
+ AccountManager accountManager = AccountManager.get(mContext);
+ Account[] accounts = accountManager.getAccountsByType(requiredAccountType);
+ return accounts.length > 0;
+ }
+
+ public boolean isSupported(Tile suggestion) {
+ int isSupportedResource = suggestion.metaData.getInt(META_DATA_IS_SUPPORTED);
+ try {
+ if (suggestion.intent == null) {
+ return false;
+ }
+ final Resources res = mContext.getPackageManager().getResourcesForActivity(
+ suggestion.intent.getComponent());
+ return isSupportedResource != 0 ? res.getBoolean(isSupportedResource) : true;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Cannot find resources for " + suggestion.intent.getComponent());
+ return false;
+ }
+ }
+
+ public boolean isCategoryDone(String category) {
+ String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
+ return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
+ }
+
+ public void markCategoryDone(String category) {
+ String name = Settings.Secure.COMPLETED_CATEGORY_PREFIX + category;
+ Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
+ }
+
private boolean isDismissed(Tile suggestion) {
Object dismissObj = suggestion.metaData.get(META_DATA_DISMISS_CONTROL);
if (dismissObj == null) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 9842e28..a424d55 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1128,10 +1128,15 @@
private PackageInfo getCallingPackageInfoOrThrow(int userId) {
try {
- return mPackageManager.getPackageInfo(getCallingPackage(), 0, userId);
+ PackageInfo packageInfo = mPackageManager.getPackageInfo(
+ getCallingPackage(), 0, userId);
+ if (packageInfo != null) {
+ return packageInfo;
+ }
} catch (RemoteException e) {
- throw new IllegalStateException("Calling package doesn't exist");
+ /* ignore */
}
+ throw new IllegalStateException("Calling package doesn't exist");
}
private int getGroupParentLocked(int userId) {
diff --git a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
index 814aa8c..49759c5 100644
--- a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
+++ b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
@@ -56,7 +56,7 @@
final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
final RowBuilder row = result.newRow();
row.add(Root.COLUMN_ROOT_ID, DOC_ID_ROOT);
- row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED);
+ row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY);
row.add(Root.COLUMN_ICON, android.R.mipmap.sym_def_app_icon);
row.add(Root.COLUMN_TITLE, getContext().getString(R.string.bugreport_storage_title));
row.add(Root.COLUMN_DOCUMENT_ID, DOC_ID_ROOT);
diff --git a/packages/SystemUI/res/drawable/ic_info.xml b/packages/SystemUI/res/drawable/ic_info.xml
deleted file mode 100644
index 65e7bf5..0000000
--- a/packages/SystemUI/res/drawable/ic_info.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2014 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:pathData="M12.000000,2.000000C6.500000,2.000000 2.000000,6.500000 2.000000,12.000000s4.500000,10.000000 10.000000,10.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000S17.500000,2.000000 12.000000,2.000000zM13.000000,17.000000l-2.000000,0.000000l0.000000,-6.000000l2.000000,0.000000L13.000000,17.000000zM13.000000,9.000000l-2.000000,0.000000L11.000000,7.000000l2.000000,0.000000L13.000000,9.000000z"
- android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/qs_btn_borderless_rect.xml b/packages/SystemUI/res/drawable/qs_btn_borderless_rect.xml
new file mode 100644
index 0000000..03bfd1a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_btn_borderless_rect.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<inset
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetTop="4dp"
+ android:insetBottom="4dp">
+ <ripple
+ android:color="?android:attr/colorControlHighlight" >
+
+ <item android:id="@android:id/mask">
+ <shape>
+ <corners android:radius="@dimen/borderless_button_radius" />
+
+ <solid android:color="@android:color/white" />
+ </shape>
+ </item>
+
+ </ripple>
+</inset>
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 603ebbf..b0dca9a 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -20,22 +20,22 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:id="@+id/tile_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/qs_tile_text"
- android:gravity="center_horizontal"
- android:minLines="2"
- android:padding="0dp"
- android:fontFamily="sans-serif-condensed"
- android:textStyle="normal"
- android:textSize="@dimen/qs_tile_text_size"
- android:clickable="false" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/qs_tile_text"
+ android:gravity="center_horizontal"
+ android:minLines="2"
+ android:padding="0dp"
+ android:fontFamily="sans-serif-condensed"
+ android:textStyle="normal"
+ android:textSize="@dimen/qs_tile_text_size"
+ android:clickable="false" />
<ImageView android:id="@+id/restricted_padlock"
- android:layout_width="@dimen/qs_tile_text_size"
- android:layout_height="@dimen/qs_tile_text_size"
- android:src="@drawable/ic_settings_lock_outline"
- android:layout_marginLeft="@dimen/restricted_padlock_pading"
- android:baselineAlignBottom="true"
- android:scaleType="centerInside"
- android:visibility="gone" />
+ android:layout_width="@dimen/qs_tile_text_size"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/qs_tile_text_size"
+ android:src="@drawable/ic_info"
+ android:layout_marginLeft="@dimen/restricted_padlock_pading"
+ android:scaleType="centerInside"
+ android:visibility="gone" />
</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_user_detail_item.xml b/packages/SystemUI/res/layout/qs_user_detail_item.xml
index a22c360..661d74a 100644
--- a/packages/SystemUI/res/layout/qs_user_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_user_detail_item.xml
@@ -53,10 +53,10 @@
<ImageView
android:id="@+id/restricted_padlock"
android:layout_width="@dimen/qs_detail_item_secondary_text_size"
- android:layout_height="@dimen/qs_detail_item_secondary_text_size"
- android:src="@drawable/ic_settings_lock_outline"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_info"
android:layout_marginLeft="@dimen/restricted_padlock_pading"
- android:baselineAlignBottom="true"
android:scaleType="centerInside"
android:visibility="gone" />
</LinearLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index fbe0207..8a7f90b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -326,9 +326,6 @@
<!-- The minimum amount of top overscroll to go to the quick settings. -->
<dimen name="min_top_overscroll_to_qs">36dp</dimen>
- <!-- The padding to the second card when the notifications collapse. -->
- <dimen name="notification_collapse_second_card_padding">8dp</dimen>
-
<!-- The height of the speed bump view. -->
<dimen name="speed_bump_height">16dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index a51b931..11df681 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -214,7 +214,7 @@
<style name="QSBorderlessButton">
<item name="android:padding">12dp</item>
- <item name="android:background">@drawable/btn_borderless_rect</item>
+ <item name="android:background">@drawable/qs_btn_borderless_rect</item>
<item name="android:gravity">center</item>
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 33f3c30..f6dcc11 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -144,7 +144,9 @@
protected Animator getViewTranslationAnimator(View v, float target,
AnimatorUpdateListener listener) {
ObjectAnimator anim = createTranslationAnimation(v, target);
- anim.addUpdateListener(listener);
+ if (listener != null) {
+ anim.addUpdateListener(listener);
+ }
return anim;
}
@@ -370,6 +372,9 @@
};
Animator anim = getViewTranslationAnimator(animView, newPos, updateListener);
+ if (anim == null) {
+ return;
+ }
if (useAccelerateInterpolator) {
anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
} else {
@@ -411,6 +416,9 @@
};
Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
+ if (anim == null) {
+ return;
+ }
int duration = SNAP_ANIM_LEN;
anim.setDuration(duration);
anim.addListener(new AnimatorListenerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 2c5cb89..8ccf60d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -77,7 +77,9 @@
@Override
public int getOffsetTop(TileRecord tile) {
- return ((ViewGroup) tile.tileView.getParent()).getTop() + getTop();
+ final ViewGroup parent = (ViewGroup) tile.tileView.getParent();
+ if (parent == null) return 0;
+ return parent.getTop() + getTop();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 225c10f..5e02428 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -87,6 +87,7 @@
mToolbar.setOnMenuItemClickListener(this);
mToolbar.getMenu().add(Menu.NONE, MENU_RESET, 0,
mContext.getString(com.android.internal.R.string.reset));
+ mToolbar.setTitle(R.string.qs_edit);
mRecyclerView = (RecyclerView) findViewById(android.R.id.list);
mTileAdapter = new TileAdapter(getContext());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index aba9251..d9b3b3f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -25,7 +25,6 @@
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -277,9 +276,6 @@
return false;
}
}
- if (target.getItemViewType() == TYPE_EDIT && from < mDividerIndex) {
- to++;
- }
move(from, to, mTiles);
mDividerIndex = mTiles.indexOf(null);
notifyItemMoved(from, to);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 39d1447..2e87525 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -172,6 +172,7 @@
}
private void postBindView() {
+ if (mCurrentView == null) return;
mCurrentView.post(new Runnable() {
@Override
public void run() {
@@ -181,6 +182,9 @@
}
private void bindView() {
+ if (mCurrentView == null) {
+ return;
+ }
mDrawable.onBatteryLevelChanged(100, false, false);
mDrawable.onPowerSaveChanged(true);
mDrawable.disableShowPercent();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index c41098f..d7c12ba 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -636,7 +636,7 @@
// Focus the next task
EventBus.getDefault().send(new FocusNextTaskViewEvent(timerIndicatorDuration));
- MetricsLogger.action(this, MetricsEvent.OVERVIEW_PAGE);
+ MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 28b2fae..86b03c8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -568,11 +568,14 @@
// Make sure we inform DividerView before we actually start the activity so we can change
// the resize mode already.
- EventBus.getDefault().send(new DockingTopTaskEvent(dragMode));
- ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds);
- showRecents(false /* triggeredFromAltTab */,
- dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS, false /* animate */,
- true /* reloadTasks*/);
+ if (ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds)) {
+ EventBus.getDefault().send(new DockingTopTaskEvent(dragMode));
+ showRecents(
+ false /* triggeredFromAltTab */,
+ dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS,
+ false /* animate */,
+ true /* reloadTasks*/);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
index d7b9b9e..5eeda72 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
@@ -161,7 +161,7 @@
ssp.startActivityFromRecents(v.getContext(), task.key.id, task.title,
ActivityOptions.makeBasic());
- MetricsLogger.action(v.getContext(), MetricsEvent.OVERVIEW_SELECT,
+ MetricsLogger.action(v.getContext(), MetricsEvent.ACTION_OVERVIEW_SELECT,
task.key.getComponent().toString());
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 4b29c29..7c5a931 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -338,15 +338,18 @@
}
/** Docks an already resumed task to the side of the screen. */
- public void moveTaskToDockedStack(int taskId, int createMode, Rect initialBounds) {
- if (mIam == null) return;
+ public boolean moveTaskToDockedStack(int taskId, int createMode, Rect initialBounds) {
+ if (mIam == null) {
+ return false;
+ }
try {
- mIam.moveTaskToDockedStack(taskId, createMode, true /* onTop */, false /* animate */,
- initialBounds);
+ return mIam.moveTaskToDockedStack(
+ taskId, createMode, true /* onTop */, false /* animate */, initialBounds);
} catch (RemoteException e) {
e.printStackTrace();
}
+ return false;
}
/** Returns the focused stack id. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 0c78e6a..2e7c7f2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -603,7 +603,7 @@
EventBus.getDefault().send(new LaunchTaskEvent(this, mTask, null, INVALID_STACK_ID,
screenPinningRequested));
- MetricsLogger.action(v.getContext(), MetricsEvent.OVERVIEW_SELECT,
+ MetricsLogger.action(v.getContext(), MetricsEvent.ACTION_OVERVIEW_SELECT,
mTask.key.getComponent().toString());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 178838e..469a1fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -194,6 +194,7 @@
// public mode, private notifications, etc
private boolean mLockscreenPublicMode = false;
private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
+ private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
private UserManager mUserManager;
private int mDensity;
@@ -1089,6 +1090,8 @@
@Override
public void onGearDisplayed(ExpandableNotificationRow row) {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_REVEAL_GEAR,
+ row.getStatusBarNotification().getPackageName());
mNotificationGearDisplayed = row;
}
@@ -1302,6 +1305,26 @@
}
/**
+ * Has the given user chosen to allow notifications to be shown even when the lockscreen is in
+ * "public" (secure & locked) mode?
+ */
+ public boolean userAllowsNotificationsInPublic(int userHandle) {
+ if (userHandle == UserHandle.USER_ALL) {
+ return true;
+ }
+
+ if (mUsersAllowingNotifications.indexOfKey(userHandle) < 0) {
+ final boolean allowed = 0 != Settings.Secure.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userHandle);
+ mUsersAllowingNotifications.append(userHandle, allowed);
+ return allowed;
+ }
+
+ return mUsersAllowingNotifications.get(userHandle);
+ }
+
+ /**
* Has the given user chosen to allow their private (full) notifications to be shown even
* when the lockscreen is in "public" (secure & locked) mode?
*/
@@ -1333,13 +1356,30 @@
}
/**
- * Returns true if we're on a secure lockscreen and the user wants to hide "sensitive"
- * notification data. If so, private notifications should show their (possibly
- * auto-generated) publicVersion, and secret notifications should be totally invisible.
+ * Returns true if we're on a secure lockscreen and the user wants to hide notification data.
+ * If so, notifications should be hidden.
*/
@Override // NotificationData.Environment
- public boolean shouldHideSensitiveContents(int userid) {
- return isLockscreenPublicMode() && !userAllowsPrivateNotificationsInPublic(userid);
+ public boolean shouldHideNotifications(int userid) {
+ return isLockscreenPublicMode() && !userAllowsNotificationsInPublic(userid);
+ }
+
+ /**
+ * Returns true if we're on a secure lockscreen and the user wants to hide notifications via
+ * package-specific override.
+ */
+ @Override // NotificationDate.Environment
+ public boolean shouldHideNotifications(String key) {
+ return isLockscreenPublicMode()
+ && mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_SECRET;
+ }
+
+ /**
+ * Returns true if we're on a secure lockscreen.
+ */
+ @Override // NotificationData.Environment
+ public boolean onSecureLockScreen() {
+ return isLockscreenPublicMode();
}
public void onNotificationClear(StatusBarNotification notification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index f446593..84b84e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -684,7 +684,7 @@
mTranslateableViews.remove(mGutsStub);
}
- public void setTranslationForOutline(float translationX) {
+ private void setTranslationForOutline(float translationX) {
setOutlineRect(false, translationX, getTop(), getRight() + translationX, getBottom());
}
@@ -704,6 +704,46 @@
if (mTranslateAnim != null) {
mTranslateAnim.cancel();
}
+ mTranslateAnim = (AnimatorSet) getTranslateViewAnimator(leftTarget,
+ null /* updateListener */);
+ if (mTranslateAnim != null) {
+ mTranslateAnim.start();
+ }
+ }
+
+ @Override
+ public void setTranslation(float translationX) {
+ if (areGutsExposed()) {
+ // Don't translate if guts are showing.
+ return;
+ }
+ // Translate the group of views
+ for (int i = 0; i < mTranslateableViews.size(); i++) {
+ if (mTranslateableViews.get(i) != null) {
+ mTranslateableViews.get(i).setTranslationX(translationX);
+ }
+ }
+ setTranslationForOutline(translationX);
+ if (mSettingsIconRow != null) {
+ mSettingsIconRow.updateSettingsIcons(translationX, getMeasuredWidth());
+ }
+ }
+
+ @Override
+ public float getTranslation() {
+ if (mTranslateableViews != null && mTranslateableViews.size() > 0) {
+ // All of the views in the list should have same translation, just use first one.
+ return mTranslateableViews.get(0).getTranslationX();
+ }
+ return 0;
+ }
+
+ public Animator getTranslateViewAnimator(final float leftTarget,
+ AnimatorUpdateListener listener) {
+ if (areGutsExposed()) {
+ // No translation if guts are exposed.
+ return null;
+ }
AnimatorSet set = new AnimatorSet();
if (mTranslateableViews != null) {
for (int i = 0; i < mTranslateableViews.size(); i++) {
@@ -715,8 +755,15 @@
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setTranslationForOutline((float) animation.getAnimatedValue());
+ if (mSettingsIconRow != null) {
+ mSettingsIconRow.updateSettingsIcons(
+ (float) animation.getAnimatedValue(), getMeasuredWidth());
+ }
}
});
+ if (listener != null) {
+ translateAnim.addUpdateListener(listener);
+ }
}
translateAnim.addListener(new AnimatorListenerAdapter() {
@Override
@@ -730,8 +777,7 @@
set.play(translateAnim);
}
}
- mTranslateAnim = set;
- set.start();
+ return set;
}
public float getSpaceForGear() {
@@ -748,10 +794,6 @@
return mSettingsIconRow;
}
- public ArrayList<View> getContentViews() {
- return mTranslateableViews;
- }
-
public void inflateGuts() {
if (mGuts == null) {
mGutsStub.inflate();
@@ -1169,6 +1211,10 @@
return mMaxExpandHeight;
}
+ public boolean areGutsExposed() {
+ return (mGuts != null && mGuts.areGutsExposed());
+ }
+
@Override
public boolean isContentExpandable() {
NotificationContentView showingLayout = getShowingLayout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 1ff87f5..b2c632b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -283,6 +283,20 @@
public void setBelowSpeedBump(boolean below) {
}
+ /**
+ * Sets the translation of the view.
+ */
+ public void setTranslation(float translation) {
+ setTranslationX(translation);
+ }
+
+ /**
+ * Gets the translation of the view.
+ */
+ public float getTranslation() {
+ return getTranslationX();
+ }
+
public void onHeightReset() {
if (mOnHeightChangedListener != null) {
mOnHeightChangedListener.onReset(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 7c11161..61105f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -92,7 +92,14 @@
= new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
- mAnimate = true;
+ // We need to post since we don't want the notification to animate on the very first
+ // frame
+ post(new Runnable() {
+ @Override
+ public void run() {
+ mAnimate = true;
+ }
+ });
getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 7cb9127..c9fe2bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -353,8 +353,10 @@
return true;
}
- if (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET &&
- mEnvironment.shouldHideSensitiveContents(sbn.getUserId())) {
+ if (mEnvironment.onSecureLockScreen() &&
+ (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET
+ || mEnvironment.shouldHideNotifications(sbn.getUserId())
+ || mEnvironment.shouldHideNotifications(sbn.getKey()))) {
return true;
}
@@ -433,7 +435,9 @@
* Provides access to keyguard state and user settings dependent data.
*/
public interface Environment {
- public boolean shouldHideSensitiveContents(int userid);
+ public boolean onSecureLockScreen();
+ public boolean shouldHideNotifications(int userid);
+ public boolean shouldHideNotifications(String key);
public boolean isDeviceProvisioned();
public boolean isNotificationForCurrentProfiles(StatusBarNotification sbn);
public String getCurrentMediaNotificationKey();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 1c16bdc0..45a24a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -130,7 +130,12 @@
importanceSlider.setVisibility(View.VISIBLE);
importanceButtons.setVisibility(View.GONE);
} else {
- bindToggles(importanceButtons, sbn, systemApp);
+ int userImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
+ try {
+ userImportance =
+ mINotificationManager.getImportance(sbn.getPackageName(), sbn.getUid());
+ } catch (RemoteException e) {}
+ bindToggles(importanceButtons, userImportance, systemApp);
importanceButtons.setVisibility(View.VISIBLE);
importanceSlider.setVisibility(View.GONE);
}
@@ -144,7 +149,7 @@
if (mBlock.isChecked()) {
progress = NotificationListenerService.Ranking.IMPORTANCE_NONE;
} else if (mSilent.isChecked()) {
- progress = NotificationListenerService.Ranking.IMPORTANCE_DEFAULT;
+ progress = NotificationListenerService.Ranking.IMPORTANCE_LOW;
} else {
progress = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
}
@@ -158,7 +163,7 @@
}
}
- private void bindToggles(final View importanceButtons, final StatusBarNotification sbn,
+ private void bindToggles(final View importanceButtons, final int importance,
final boolean systemApp) {
mBlock = (RadioButton) importanceButtons.findViewById(R.id.block_importance);
mSilent = (RadioButton) importanceButtons.findViewById(R.id.silent_importance);
@@ -169,7 +174,11 @@
} else {
mReset.setText(mContext.getString(R.string.do_not_silence_block));
}
- mReset.setChecked(true);
+ if (importance == NotificationListenerService.Ranking.IMPORTANCE_LOW) {
+ mSilent.setChecked(true);
+ } else {
+ mReset.setChecked(true);
+ }
}
private void bindSlider(final View importanceSlider, final StatusBarNotification sbn,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 960e4cf..988d537 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -221,6 +221,7 @@
apply();
applyIconTint();
+ mNC.addSignalCallback(this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 127feba..88b8afa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1397,7 +1397,7 @@
// In Shade, interpolate linearly such that QS is closed whenever panel height is
// minimum QS expansion + minStackHeight
float panelHeightQsCollapsed = mNotificationStackScroller.getIntrinsicPadding()
- + mNotificationStackScroller.getMinStackHeight();
+ + mNotificationStackScroller.getLayoutMinHeight();
float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
t = (expandedHeight - panelHeightQsCollapsed)
/ (panelHeightQsExpanded - panelHeightQsCollapsed);
@@ -1453,7 +1453,7 @@
&& mShadeEmpty) {
notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight()
+ mNotificationStackScroller.getBottomStackPeekSize()
- + mNotificationStackScroller.getCollapseSecondCardPadding();
+ + mNotificationStackScroller.getBottomStackSlowDownHeight();
}
int maxQsHeight = mQsMaxExpansionHeight;
@@ -1468,7 +1468,7 @@
+ notificationHeight;
if (totalHeight > mNotificationStackScroller.getHeight()) {
float fullyCollapsedHeight = maxQsHeight
- + mNotificationStackScroller.getMinStackHeight();
+ + mNotificationStackScroller.getLayoutMinHeight();
totalHeight = Math.max(fullyCollapsedHeight, mNotificationStackScroller.getHeight());
}
return (int) totalHeight;
@@ -1485,7 +1485,7 @@
private float getFadeoutAlpha() {
float alpha = (getNotificationsTopY() + mNotificationStackScroller.getFirstItemMinHeight())
/ (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize()
- - mNotificationStackScroller.getCollapseSecondCardPadding());
+ - mNotificationStackScroller.getBottomStackSlowDownHeight());
alpha = Math.max(0, Math.min(alpha, 1));
alpha = (float) Math.pow(alpha, 0.75);
return alpha;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e739944..ef16388 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -995,7 +995,6 @@
SignalClusterView signalCluster =
(SignalClusterView) containerView.findViewById(R.id.signal_cluster);
if (signalCluster != null) {
- mNetworkController.addSignalCallback(signalCluster);
signalCluster.setSecurityController(mSecurityController);
signalCluster.setNetworkController(mNetworkController);
}
@@ -1597,8 +1596,7 @@
}
private boolean packageHasVisibilityOverride(String key) {
- return mNotificationData.getVisibilityOverride(key)
- != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+ return mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_PRIVATE;
}
private void updateClearAll() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java
index bd36462..159bd41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java
@@ -19,6 +19,7 @@
import android.net.NetworkCapabilities;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import java.util.BitSet;
@@ -46,12 +47,12 @@
}
@Override
- public void notifyListeners() {
+ public void notifyListeners(SignalCallback callback) {
boolean ethernetVisible = mCurrentState.connected;
String contentDescription = getStringIfExists(getContentDescription());
// TODO: wire up data transfer using WifiSignalPoller.
- mCallbackHandler.setEthernetIndicators(new IconState(ethernetVisible, getCurrentIconId(),
+ callback.setEthernetIndicators(new IconState(ethernetVisible, getCurrentIconId(),
contentDescription));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 8fd4d9c..80dcfb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -34,6 +34,7 @@
import com.android.internal.telephony.cdma.EriInfo;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
@@ -198,7 +199,7 @@
}
@Override
- public void notifyListeners() {
+ public void notifyListeners(SignalCallback callback) {
MobileIconGroup icons = getIcons();
String contentDescription = getStringIfExists(getContentDescription());
@@ -231,7 +232,7 @@
|| mCurrentState.iconGroup == TelephonyIcons.ROAMING
|| mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED;
int typeIcon = showDataIcon ? icons.mDataType : 0;
- mCallbackHandler.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
+ callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
mSubscriptionInfo.getSubscriptionId());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 8193b52..40eb71d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -322,16 +322,16 @@
}
public void addSignalCallback(SignalCallback cb) {
- mCallbackHandler.setListening(cb, true);
- mCallbackHandler.setSubs(mCurrentSubscriptions);
- mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode,
+ cb.setSubs(mCurrentSubscriptions);
+ cb.setIsAirplaneMode(new IconState(mAirplaneMode,
TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
- mCallbackHandler.setNoSims(mHasNoSims);
- mWifiSignalController.notifyListeners();
- mEthernetSignalController.notifyListeners();
+ cb.setNoSims(mHasNoSims);
+ mWifiSignalController.notifyListeners(cb);
+ mEthernetSignalController.notifyListeners(cb);
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
- mobileSignalController.notifyListeners();
+ mobileSignalController.notifyListeners(cb);
}
+ mCallbackHandler.setListening(cb, true);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
index c954d08..4cfd1c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.text.format.DateFormat;
import android.util.Log;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import java.io.PrintWriter;
import java.util.BitSet;
@@ -48,7 +49,7 @@
// is aware of current state.
protected final NetworkControllerImpl mNetworkController;
- protected final CallbackHandler mCallbackHandler;
+ private final CallbackHandler mCallbackHandler;
// Save the previous HISTORY_SIZE states for logging.
private final State[] mHistory;
@@ -198,12 +199,16 @@
}
}
+ public final void notifyListeners() {
+ notifyListeners(mCallbackHandler);
+ }
+
/**
* Trigger callbacks based on current state. The callbacks should be completely
* based on current state, and only need to be called in the scenario where
* mCurrentState != mLastState.
*/
- public abstract void notifyListeners();
+ public abstract void notifyListeners(SignalCallback callback);
/**
* Generate a blank T.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index cc98eb6..a6ed04f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -28,6 +28,7 @@
import com.android.internal.util.AsyncChannel;
import com.android.settingslib.wifi.WifiStatusTracker;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import java.util.Objects;
@@ -72,7 +73,7 @@
}
@Override
- public void notifyListeners() {
+ public void notifyListeners(SignalCallback callback) {
// only show wifi in the cluster if connected or if wifi-only
boolean wifiVisible = mCurrentState.enabled
&& (mCurrentState.connected || !mHasMobileData);
@@ -83,7 +84,7 @@
IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
contentDescription);
- mCallbackHandler.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
+ callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
wifiDesc);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 85b1426..aa444f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -48,6 +48,8 @@
import android.view.animation.Interpolator;
import android.widget.OverScroller;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.ExpandHelper;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -363,6 +365,8 @@
@Override
public void onGearTouched(ExpandableNotificationRow row, int x, int y) {
if (mLongPressListener != null) {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_TOUCH_GEAR,
+ row.getStatusBarNotification().getPackageName());
mLongPressListener.onLongPress(row, x, y);
}
}
@@ -418,12 +422,9 @@
.getDimensionPixelSize(R.dimen.notification_divider_height));
mIncreasedPaddingBetweenElements = context.getResources()
.getDimensionPixelSize(R.dimen.notification_divider_height_increased);
-
mBottomStackSlowDownHeight = mStackScrollAlgorithm.getBottomStackSlowDownLength();
mMinTopOverScrollToEscape = getResources().getDimensionPixelSize(
R.dimen.min_top_overscroll_to_qs);
- mCollapseSecondCardPadding = getResources().getDimensionPixelSize(
- R.dimen.notification_collapse_second_card_padding);
}
private void notifyHeightChangeListener(ExpandableView view) {
@@ -509,14 +510,6 @@
}
/**
- * @return whether the height of the layout needs to be adapted, in order to ensure that the
- * last child is not in the bottom stack.
- */
- private boolean needsHeightAdaption() {
- return getNotGoneChildCount() > 1;
- }
-
- /**
* Updates the children views according to the stack scroll algorithm. Call this whenever
* modifications to {@link #mOwnScrollY} are performed to reflect it in the view layout.
*/
@@ -599,7 +592,7 @@
mLastSetStackHeight = height;
setIsExpanded(height > 0.0f);
int newStackHeight = (int) height;
- int minStackHeight = getMinStackHeight();
+ int minStackHeight = getLayoutMinHeight();
int stackHeight;
float paddingOffset;
boolean trackingHeadsUp = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp();
@@ -612,20 +605,7 @@
stackHeight = newStackHeight;
} else {
int translationY;
- if (!trackingHeadsUp) {
- // We did not reach the position yet where we actually start growing,
- // so we translate the stack upwards.
- translationY = (newStackHeight - minStackHeight);
- // A slight parallax effect is introduced in order for the stack to catch up with
- // the top card.
- float partiallyThere = (newStackHeight - mTopPadding - mTopPaddingOverflow)
- / minStackHeight;
- partiallyThere = Math.max(0, partiallyThere);
- translationY += (1 - partiallyThere) * (mBottomStackPeekSize +
- mCollapseSecondCardPadding);
- } else {
- translationY = (int) (height - normalUnfoldPositionStart);
- }
+ translationY = newStackHeight - normalUnfoldPositionStart;
paddingOffset = translationY - mTopPadding;
stackHeight = (int) (height - (translationY - mTopPadding));
}
@@ -668,8 +648,8 @@
return mBottomStackPeekSize;
}
- public int getCollapseSecondCardPadding() {
- return mCollapseSecondCardPadding;
+ public int getBottomStackSlowDownHeight() {
+ return mBottomStackSlowDownHeight;
}
public void setLongPressListener(SwipeHelper.LongPressListener listener) {
@@ -734,6 +714,7 @@
if (targetLeft == 0 && mCurrIconRow != null) {
mCurrIconRow.resetState();
+ mCurrIconRow = null;
if (mGearExposedView != null && mGearExposedView == mTranslatingParentView) {
mGearExposedView = null;
}
@@ -1850,7 +1831,7 @@
boolean ignoreIntrinsicPadding) {
float start = qsHeight;
float stackHeight = getHeight() - start;
- int minStackHeight = getMinStackHeight();
+ int minStackHeight = getLayoutMinHeight();
if (stackHeight <= minStackHeight) {
float overflow = minStackHeight - stackHeight;
stackHeight = minStackHeight;
@@ -1864,11 +1845,16 @@
setStackHeight(mLastSetStackHeight);
}
- public int getMinStackHeight() {
+ public int getLayoutMinHeight() {
final ExpandableView firstChild = getFirstChildNotGone();
- final int firstChildMinHeight = firstChild != null ? firstChild.getMinHeight()
+ int firstChildMinHeight = firstChild != null
+ ? firstChild.getIntrinsicHeight()
: mCollapsedSize;
- return firstChildMinHeight + mBottomStackPeekSize + mCollapseSecondCardPadding;
+ if (mOwnScrollY > 0) {
+ firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
+ }
+ return Math.min(firstChildMinHeight + mBottomStackPeekSize + mBottomStackSlowDownHeight,
+ mMaxLayoutHeight - mTopPadding);
}
public float getTopPaddingOverflow() {
@@ -1880,7 +1866,7 @@
final int firstChildMinHeight = firstChild != null ? (int) firstChild.getMinHeight()
: mCollapsedSize;
return mIntrinsicPadding + firstChildMinHeight + mBottomStackPeekSize
- + mCollapseSecondCardPadding;
+ + mBottomStackSlowDownHeight;
}
private int clampPadding(int desiredPadding) {
@@ -1994,7 +1980,6 @@
}
private void onViewRemovedInternal(View child) {
- mStackScrollAlgorithm.notifyChildrenChanged(this);
if (mChangePositionInProgress) {
// This is only a position change, don't do anything special
return;
@@ -2175,7 +2160,6 @@
private void onViewAddedInternal(View child) {
updateHideSensitiveForChild(child);
- mStackScrollAlgorithm.notifyChildrenChanged(this);
((ExpandableView) child).setOnHeightChangedListener(this);
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
@@ -2643,12 +2627,8 @@
}
public int getEmptyBottomMargin() {
- int emptyMargin = mMaxLayoutHeight - mContentHeight - mBottomStackPeekSize;
- if (needsHeightAdaption()) {
- emptyMargin -= mBottomStackSlowDownHeight;
- } else {
- emptyMargin -= mCollapseSecondCardPadding;
- }
+ int emptyMargin = mMaxLayoutHeight - mContentHeight - mBottomStackPeekSize
+ - mBottomStackSlowDownHeight;
return Math.max(emptyMargin, 0);
}
@@ -2659,12 +2639,10 @@
public void onExpansionStarted() {
mIsExpansionChanging = true;
- mStackScrollAlgorithm.onExpansionStarted(mCurrentStackScrollState);
}
public void onExpansionStopped() {
mIsExpansionChanging = false;
- mStackScrollAlgorithm.onExpansionStopped();
if (!mIsExpanded) {
mOwnScrollY = 0;
@@ -2732,7 +2710,6 @@
if (mIsExpanded && mAnimationsEnabled) {
mRequestViewResizeAnimationOnLayout = true;
}
- mStackScrollAlgorithm.onReset(view);
updateAnimationState(view);
updateChronometerForChild(view);
}
@@ -3163,15 +3140,7 @@
}
public int getDismissViewHeight() {
- int height = mDismissView.getHeight() + mPaddingBetweenElements;
-
- // Hack: Accommodate for additional distance when we only have one notification and the
- // dismiss all button.
- if (getNotGoneChildCount() == 2 && getLastChildNotGone() == mDismissView
- && getFirstChildNotGone() instanceof ActivatableNotificationView) {
- height += mCollapseSecondCardPadding;
- }
- return height;
+ return mDismissView.getHeight() + mPaddingBetweenElements;
}
public int getEmptyShadeViewHeight() {
@@ -3399,7 +3368,6 @@
private static final long GEAR_SHOW_DELAY = 60;
- private ArrayList<View> mTranslatingViews = new ArrayList<>();
private CheckForDrag mCheckForDrag;
private Handler mHandler;
private int mMoveState = MOVE_STATE_UNDEFINED;
@@ -3416,6 +3384,7 @@
// Reset check for drag gesture
mCheckForDrag = null;
+ mCurrIconRow = null;
// Slide back any notifications that might be showing a gear
resetExposedGearView();
@@ -3424,9 +3393,6 @@
// Set the listener for the current row's gear
mCurrIconRow = ((ExpandableNotificationRow) currView).getSettingsRow();
mCurrIconRow.setGearListener(NotificationStackScrollLayout.this);
-
- // And the translating children
- mTranslatingViews = ((ExpandableNotificationRow) currView).getContentViews();
}
mMoveState = MOVE_STATE_UNDEFINED;
}
@@ -3440,15 +3406,12 @@
}
mMoveState = newMoveState;
- if (view instanceof ExpandableNotificationRow) {
- ((ExpandableNotificationRow) view).setTranslationForOutline(translation);
- if (!isPinnedHeadsUp(view)) {
- // Only show the gear if we're not a heads up view.
- checkForDrag();
- if (mCurrIconRow != null) {
- mCurrIconRow.updateSettingsIcons(translation, getSize(view));
- }
- }
+ final boolean gutsExposed = (view instanceof ExpandableNotificationRow)
+ && ((ExpandableNotificationRow) view).areGutsExposed();
+
+ if (!isPinnedHeadsUp(view) && !gutsExposed) {
+ // Only show the gear if we're not a heads up view and guts aren't exposed.
+ checkForDrag();
}
}
@@ -3471,12 +3434,12 @@
(!fromLeft && absTrans >= snapBackThreshold * 0.4f
&& absTrans <= notiThreshold);
- if (pastGear && !isPinnedHeadsUp(animView)) {
+ if (pastGear && !isPinnedHeadsUp(animView)
+ && (animView instanceof ExpandableNotificationRow)) {
// bouncity
final float target = fromLeft ? snapBackThreshold : -snapBackThreshold;
mGearExposedView = mTranslatingParentView;
- if (mGearDisplayedListener != null
- && (animView instanceof ExpandableNotificationRow)) {
+ if (mGearDisplayedListener != null) {
mGearDisplayedListener.onGearDisplayed((ExpandableNotificationRow) animView);
}
super.snapChild(animView, target, velocity);
@@ -3486,38 +3449,16 @@
}
@Override
- public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
- if (mDismissAllInProgress) {
- // When dismissing all, we translate the entire view instead.
- super.onTranslationUpdate(animView, value, canBeDismissed);
- return;
- }
- if (animView instanceof ExpandableNotificationRow) {
- ((ExpandableNotificationRow) animView).setTranslationForOutline(value);
- }
- if (mCurrIconRow != null) {
- mCurrIconRow.updateSettingsIcons(value, getSize(animView));
- }
- }
-
- @Override
public Animator getViewTranslationAnimator(View v, float target,
AnimatorUpdateListener listener) {
if (mDismissAllInProgress) {
// When dismissing all, we translate the entire view instead.
return super.getViewTranslationAnimator(v, target, listener);
+ } else if (v instanceof ExpandableNotificationRow) {
+ return ((ExpandableNotificationRow) v).getTranslateViewAnimator(target, listener);
+ } else {
+ return super.getViewTranslationAnimator(v, target, listener);
}
- ArrayList<Animator> animators = new ArrayList<Animator>();
- for (int i = 0; i < mTranslatingViews.size(); i++) {
- ObjectAnimator anim = createTranslationAnimation(mTranslatingViews.get(i), target);
- animators.add(anim);
- if (i == 0 && listener != null) {
- anim.addUpdateListener(listener);
- }
- }
- AnimatorSet set = new AnimatorSet();
- set.playTogether(animators);
- return set;
}
@Override
@@ -3525,13 +3466,8 @@
if (mDismissAllInProgress) {
// When dismissing all, we translate the entire view instead.
super.setTranslation(v, translate);
- return;
- }
- // Translate the group of views
- for (int i = 0; i < mTranslatingViews.size(); i++) {
- if (mTranslatingViews.get(i) != null) {
- super.setTranslation(mTranslatingViews.get(i), translate);
- }
+ } else {
+ ((ExpandableView) v).setTranslation(translate);
}
}
@@ -3540,15 +3476,11 @@
if (mDismissAllInProgress) {
// When dismissing all, we translate the entire view instead.
return super.getTranslation(v);
+ } else {
+ return ((ExpandableView) v).getTranslation();
}
- // All of the views in the list should have same translation, just use first one.
- if (mTranslatingViews.size() > 0) {
- return super.getTranslation(mTranslatingViews.get(0));
- }
- return 0;
}
-
/**
* Returns the horizontal space in pixels required to display the gear behind a
* notification.
@@ -3603,26 +3535,11 @@
final View prevGearExposedView = mGearExposedView;
mGearExposedView = null;
- AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
- public void onAnimationEnd(Animator animator) {
- if (prevGearExposedView instanceof ExpandableNotificationRow) {
- ((ExpandableNotificationRow) prevGearExposedView).getSettingsRow()
- .resetState();
- }
- }
- };
- AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- if (prevGearExposedView instanceof ExpandableNotificationRow) {
- ((ExpandableNotificationRow) prevGearExposedView)
- .setTranslationForOutline((float) animation.getAnimatedValue());
- }
- }
- };
- Animator set = getViewTranslationAnimator(prevGearExposedView, 0, updateListener);
- set.addListener(listener);
- set.start();
+ Animator anim = getViewTranslationAnimator(prevGearExposedView,
+ 0 /* leftTarget */, null /* updateListener */);
+ if (anim != null) {
+ anim.start();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index eea923f..4c94fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -52,13 +52,8 @@
private StackIndentationFunctor mBottomStackIndentationFunctor;
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
- private boolean mIsExpansionChanging;
- private int mFirstChildMaxHeight;
private boolean mIsExpanded;
- private ExpandableView mFirstChildWhileExpanding;
- private boolean mExpandedOnStart;
private int mBottomStackSlowDownLength;
- private int mCollapseSecondCardPadding;
public StackScrollAlgorithm(Context context) {
initView(context);
@@ -86,8 +81,6 @@
mZBasicHeight = (MAX_ITEMS_IN_BOTTOM_STACK + 1) * mZDistanceBetweenElements;
mBottomStackSlowDownLength = context.getResources()
.getDimensionPixelSize(R.dimen.bottom_stack_slow_down_length);
- mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
- R.dimen.notification_collapse_second_card_padding);
mBottomStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
MAX_ITEMS_IN_BOTTOM_STACK,
mBottomStackPeekSize,
@@ -508,7 +501,7 @@
int childHeight, int minHeight, AmbientState ambientState) {
int bottomStackStart = ambientState.getInnerHeight()
- - mBottomStackPeekSize - mCollapseSecondCardPadding;
+ - mBottomStackPeekSize - mBottomStackSlowDownLength;
int childStart = bottomStackStart - childHeight;
if (childStart < childViewState.yTranslation) {
float newHeight = bottomStackStart - childViewState.yTranslation;
@@ -595,12 +588,9 @@
// The starting position of the bottom stack peek
int bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize -
- mCollapseSecondCardPadding + ambientState.getScrollY();
+ mBottomStackSlowDownLength + ambientState.getScrollY();
// Collapse and expand the first child while the shade is being expanded
- float maxHeight = mIsExpansionChanging && child == mFirstChildWhileExpanding
- ? mFirstChildMaxHeight
- : childHeight;
- childViewState.height = (int) Math.max(Math.min(bottomPeekStart, maxHeight),
+ childViewState.height = (int) Math.max(Math.min(bottomPeekStart, (float) childHeight),
child.getMinHeight());
}
@@ -656,55 +646,6 @@
}
}
- public void onExpansionStarted(StackScrollState currentState) {
- mIsExpansionChanging = true;
- mExpandedOnStart = mIsExpanded;
- ViewGroup hostView = currentState.getHostView();
- updateFirstChildHeightWhileExpanding(hostView);
- }
-
- private void updateFirstChildHeightWhileExpanding(ViewGroup hostView) {
- mFirstChildWhileExpanding = (ExpandableView) findFirstVisibleChild(hostView);
- if (mFirstChildWhileExpanding != null) {
- if (mExpandedOnStart) {
-
- // We are collapsing the shade, so the first child can get as most as high as the
- // current height or the end value of the animation.
- mFirstChildMaxHeight = StackStateAnimator.getFinalActualHeight(
- mFirstChildWhileExpanding);
- } else {
- updateFirstChildMaxSizeToMaxHeight();
- }
- } else {
- mFirstChildMaxHeight = 0;
- }
- }
-
- private void updateFirstChildMaxSizeToMaxHeight() {
- // We are expanding the shade, expand it to its full height.
- if (!isMaxSizeInitialized(mFirstChildWhileExpanding)) {
-
- // This child was not layouted yet, wait for a layout pass
- mFirstChildWhileExpanding
- .addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right,
- int bottom, int oldLeft, int oldTop, int oldRight,
- int oldBottom) {
- if (mFirstChildWhileExpanding != null) {
- mFirstChildMaxHeight = getMaxAllowedChildHeight(
- mFirstChildWhileExpanding);
- } else {
- mFirstChildMaxHeight = 0;
- }
- v.removeOnLayoutChangeListener(this);
- }
- });
- } else {
- mFirstChildMaxHeight = getMaxAllowedChildHeight(mFirstChildWhileExpanding);
- }
- }
-
private boolean isMaxSizeInitialized(ExpandableView child) {
if (child instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
@@ -724,32 +665,10 @@
return null;
}
- public void onExpansionStopped() {
- mIsExpansionChanging = false;
- mFirstChildWhileExpanding = null;
- }
-
public void setIsExpanded(boolean isExpanded) {
this.mIsExpanded = isExpanded;
}
- public void notifyChildrenChanged(final NotificationStackScrollLayout hostView) {
- if (mIsExpansionChanging) {
- hostView.post(new Runnable() {
- @Override
- public void run() {
- updateFirstChildHeightWhileExpanding(hostView);
- }
- });
- }
- }
-
- public void onReset(ExpandableView view) {
- if (view.equals(mFirstChildWhileExpanding)) {
- updateFirstChildMaxSizeToMaxHeight();
- }
- }
-
class StackScrollAlgorithmState {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
index fb7fa4d..fb425ab 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
@@ -25,6 +25,9 @@
import android.widget.TextView;
import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIApplication;
+import com.android.systemui.recents.Recents;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -47,6 +50,7 @@
private TextView mPlayPauseDescriptionTextView;
private View mCloseButtonView;
private View mCloseDescriptionView;
+ private boolean mMovePipToFullscreen;
private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
@Override
@@ -66,6 +70,7 @@
@Override
public void onClick(View v) {
mPipManager.movePipToFullscreen();
+ mMovePipToFullscreen = true;
finish();
}
});
@@ -164,7 +169,9 @@
}
private void restorePipAndFinish() {
- mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
+ if (!mMovePipToFullscreen) {
+ mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
+ }
finish();
}
@@ -214,4 +221,18 @@
mPipManager.suspendPipResizing(
PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
}
+
+ @Override
+ public void finish() {
+ super.finish();
+ if (mPipManager.isRecentsShown() && !mMovePipToFullscreen) {
+ SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
+ for (int i = services.length - 1; i >= 0; i--) {
+ if (services[i] instanceof Recents) {
+ ((Recents) services[i]).showRecents(false, null);
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index ebd5384..60d33fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -32,6 +32,7 @@
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
import org.mockito.ArgumentCaptor;
@@ -100,7 +101,7 @@
// Trigger blank callbacks to always get the current state (some tests don't trigger
// changes from default state).
- mNetworkController.addSignalCallback(null);
+ mNetworkController.addSignalCallback(mock(SignalCallback.class));
mNetworkController.addEmergencyListener(null);
}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 077b121..8171b49 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -24,334 +24,1734 @@
// Known visual elements: views or controls.
enum View {
+ // Unknown view
VIEW_UNKNOWN = 0;
+
+ // OBSOLETE
MAIN_SETTINGS = 1;
+
+ // OPEN: Settings > Accessibility
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCESSIBILITY = 2;
+
+ // OPEN: Settings > Accessibility > Captions
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCESSIBILITY_CAPTION_PROPERTIES = 3;
+
+ // OPEN: Settings > Accessibility > [Service]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCESSIBILITY_SERVICE = 4;
+
+ // OPEN: Settings > Accessibility > Color correction
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
+
+ // OPEN: Settings > Accessibility > Accessibility shortcut
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
+
+ // OPEN: Settings > Accessibility > Magnification gestures
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
+
+ // OPEN: Settings > Accounts
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCOUNT = 8;
+
+ // OPEN: Settings > Accounts > [Single Account Sync Settings]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCOUNTS_ACCOUNT_SYNC = 9;
+
+ // OPEN: Settings > Accounts > Add an account
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
+
+ // OPEN: Settings > Accounts > [List of accounts when more than one]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACCOUNTS_MANAGE_ACCOUNTS = 11;
+
+ // OPEN: Settings > Cellular network settings > APNs
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APN = 12;
+
+ // OPEN: Settings > More > Cellular network settings > APNs > [Edit APN]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APN_EDITOR = 13;
+
+ // OBSOLETE
APP_OPS_DETAILS = 14;
+
+ // OBSOLETE
APP_OPS_SUMMARY = 15;
+
+ // OBSOLETE
APPLICATION = 16;
+
+ // OPEN: Settings > Apps > Configure apps > App links > [App]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_APP_LAUNCH = 17;
+
+ // OBSOLETE
APPLICATIONS_APP_PERMISSION = 18;
+
+ // OPEN: Settings > Internal storage > Apps storage > [App]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_APP_STORAGE = 19;
+
+ // OPEN: Settings > Apps > [App info]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_INSTALLED_APP_DETAILS = 20;
+
+ // OPEN: Settings > Memory > App usage > [App Memory usage]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_PROCESS_STATS_DETAIL = 21;
+
+ // OBSOLETE
APPLICATIONS_PROCESS_STATS_MEM_DETAIL = 22;
+
+ // OPEN: Settings > Memory > App usage
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_PROCESS_STATS_UI = 23;
+
+ // OPEN: Settings > Bluetooth
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
BLUETOOTH = 24;
+
+ // OPEN: Choose Bluetooth device (ex: when sharing)
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
BLUETOOTH_DEVICE_PICKER = 25;
+
+ // OBSOLETE
BLUETOOTH_DEVICE_PROFILES = 26;
+
+ // OPEN: Settings > Security > Choose screen lock
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
CHOOSE_LOCK_GENERIC = 27;
+
+ // OPEN: Settings > Security > Choose screen lock > Choose your password
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
CHOOSE_LOCK_PASSWORD = 28;
+
+ // OPEN: Settings > Security > Choose screen lock > Choose your pattern
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
CHOOSE_LOCK_PATTERN = 29;
+
+ // OPEN: Settings > Security > Choose screen lock > Confirm your password
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
CONFIRM_LOCK_PASSWORD = 30;
+
+ // OPEN: Settings > Security > Choose screen lock > Confirm your pattern
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
CONFIRM_LOCK_PATTERN = 31;
+
+ // OPEN: Settings > Security > Encrypt phone
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
CRYPT_KEEPER = 32;
+
+ // OPEN: Settings > Security > Encrypt phone > Confirm
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
CRYPT_KEEPER_CONFIRM = 33;
+
+ // OPEN: Settings > Search results
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DASHBOARD_SEARCH_RESULTS = 34;
+
+ // OPEN: Settings (Root page)
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DASHBOARD_SUMMARY = 35;
+
+ // OBSOLETE
DATA_USAGE = 36;
+
+ // OPEN: Settings > Data usage
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DATA_USAGE_SUMMARY = 37;
+
+ // OPEN: Settings > Date & time
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DATE_TIME = 38;
+
+ // OPEN: Settings > Developer options
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DEVELOPMENT = 39;
+
+ // OPEN: Settings > About phone
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DEVICEINFO = 40;
+
+ // OPEN: Settings > About phone > Status > IMEI information
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DEVICEINFO_IMEI_INFORMATION = 41;
+
+ // OPEN: Settings > Internal storage
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DEVICEINFO_STORAGE = 42;
+
+ // OPEN: Settings > About phone > Status > SIM status
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DEVICEINFO_SIM_STATUS = 43;
+
+ // OPEN: Settings > About phone > Status
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DEVICEINFO_STATUS = 44;
+
+ // OBSOLETE
DEVICEINFO_USB = 45;
+
+ // OPEN: Settings > Display
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DISPLAY = 46;
+
+ // OPEN: Settings > Display > Daydream
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
DREAM = 47;
+
+ // OPEN: Settings > Security > Screen lock > Secure start-up
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ENCRYPTION = 48;
+
+ // OPEN: Settings > Security > Nexus Imprint
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
FINGERPRINT = 49;
+
+ // OBSOLETE
FINGERPRINT_ENROLL = 50;
+
+ // OPEN: Settings > Battery > History details
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
+
+ // OPEN: Settings > Battery > Battery saver
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
FUELGAUGE_BATTERY_SAVER = 52;
+
+ // OPEN: Settings > Battery > [App Use details]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
FUELGAUGE_POWER_USAGE_DETAIL = 53;
+
+ // OPEN: Settings > Battery
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
FUELGAUGE_POWER_USAGE_SUMMARY = 54;
+
+ // OPEN: Settings > Home
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
HOME = 55;
+
+ // OPEN: Settings > Security > SIM card lock settings
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ICC_LOCK = 56;
+
+ // OPEN: Settings > Language & input
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
INPUTMETHOD_LANGUAGE = 57;
+
+ // OPEN: Settings > Language & input > Physical keyboard
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
INPUTMETHOD_KEYBOARD = 58;
+
+ // OPEN: Settings > Language & input > Spell checker
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
INPUTMETHOD_SPELL_CHECKERS = 59;
+
+ // OBSOLETE
INPUTMETHOD_SUBTYPE_ENABLER = 60;
+
+ // OPEN: Settings > Language & input > Personal dictionary
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
INPUTMETHOD_USER_DICTIONARY = 61;
+
+ // OPEN: Settings > Language & input > Add word
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
+
+ // OPEN: Settings > Location
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
LOCATION = 63;
+
+ // OPEN: Settings > Location > Location mode
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
LOCATION_MODE = 64;
+
+ // OPEN: Settings > Apps
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
MANAGE_APPLICATIONS = 65;
+
+ // OPEN: Settings > Backup & reset > Factory data reset
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
MASTER_CLEAR = 66;
+
+ // OPEN: Settings > Backup & reset > Factory data reset > Confirm
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
MASTER_CLEAR_CONFIRM = 67;
+
+ // OPEN: Settings > Data usage > Network restrictions
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NET_DATA_USAGE_METERED = 68;
+
+ // OPEN: Settings > More > Android Beam
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NFC_BEAM = 69;
+
+ // OPEN: Settings > Tap & pay
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NFC_PAYMENT = 70;
+
+ // OPEN: Settings > Sound & notification
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION = 71;
+
+ // OPEN: Settings > Sound & notification > App notifications > [App]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_APP_NOTIFICATION = 72;
+
+ // OPEN: Settings > Sound & notification > Other sounds
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_OTHER_SOUND = 73;
+
+ // OBSOLETE
NOTIFICATION_REDACTION = 74;
+
+ // OPEN: Settings Widget > Notification log
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_STATION = 75;
+
+ // OPEN: Settings > Sound & notification > Do not disturb
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ZEN_MODE = 76;
+
+ // OPEN: OBSOLETE
OWNER_INFO = 77;
+
+ // OPEN: Print job notification > Print job settings
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
PRINT_JOB_SETTINGS = 78;
+
+ // OPEN: Settings > Printing > [Print Service]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
PRINT_SERVICE_SETTINGS = 79;
+
+ // OPEN: Settings > Printing
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
PRINT_SETTINGS = 80;
+
+ // OPEN: Settings > Backup & reset
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
PRIVACY = 81;
+
+ //OBSOLETE
PROXY_SELECTOR = 82;
+
+ // OPEN: Settings > Backup & reset > Network settings reset
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
RESET_NETWORK = 83;
+
+ // OPEN: Settings > Backup & reset > Network settings reset > Confirm
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
RESET_NETWORK_CONFIRM = 84;
+
+ // OPEN: Settings > Developer Options > Running Services
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
RUNNING_SERVICE_DETAILS = 85;
+
+ // OPEN: Settings > Security > Screen pinning
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
SCREEN_PINNING = 86;
+
+ // OPEN: Settings > Security
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
SECURITY = 87;
+
+ // OPEN: Settings > SIM cards
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
SIM = 88;
+
+ // OBSOLETE
TESTING = 89;
+
+ // OPEN: Settings > More > Tethering & portable hotspot
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TETHER = 90;
+
+ // OPEN: Settings > Security > Trust agents
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TRUST_AGENT = 91;
+
+ // OPEN: Settings > Security > Trusted credentials
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TRUSTED_CREDENTIALS = 92;
+
+ // OPEN: Settings > Language & input > TTS output > [Engine] > Settings
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TTS_ENGINE_SETTINGS = 93;
+
+ // OPEN: Settings > Language & input > Text-to-speech output
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TTS_TEXT_TO_SPEECH = 94;
+
+ // OPEN: Settings > Security > Apps with usage access
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
USAGE_ACCESS = 95;
+
+ // OPEN: Settings > Users
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
USER = 96;
+
+ // OPEN: Settings > Users > [Restricted profile app & content access]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
USERS_APP_RESTRICTIONS = 97;
+
+ // OPEN: Settings > Users > [User settings]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
USER_DETAILS = 98;
+
+ // OBSOLETE
VOICE_INPUT = 99;
+
+ // OPEN: Settings > More > VPN
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
VPN = 100;
+
+ // OPEN: Settings > Display > Choose wallpaper from
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WALLPAPER_TYPE = 101;
+
+ // OPEN: Settings > Display > Cast
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WFD_WIFI_DISPLAY = 102;
+
+ // OPEN: Settings > Wi-Fi
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WIFI = 103;
+
+ // OPEN: Settings > Wi-Fi > Advanced Wi-Fi
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WIFI_ADVANCED = 104;
+
+ // OPEN: Settings > More > Wi-Fi Calling
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WIFI_CALLING = 105;
+
+ // OPEN: Settings > Wi-Fi > Saved networks
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WIFI_SAVED_ACCESS_POINTS = 106;
+
+ // OBSOLETE
WIFI_APITEST = 107;
+
+ // OBSOLETE
WIFI_INFO = 108;
+
+ // OPEN: Settings > Wi-Fi > Advanced Wi-Fi > Wi-Fi Direct
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WIFI_P2P = 109;
+
+ // OPEN: Settings > More
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
WIRELESS = 110;
+
+ // OPEN: Quick Settings Panel
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_PANEL = 111;
+
+ // OPEN: QS Airplane mode tile shown
+ // ACTION: QS Airplane mode tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_AIRPLANEMODE = 112;
+
+ // OPEN: QS Bluetooth tile shown
+ // ACTION: QS Bluetooth tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_BLUETOOTH = 113;
+
+ // OPEN: QS Cast tile shown
+ // ACTION: QS Cast tile tapped
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_CAST = 114;
+
+ // OPEN: QS Cellular tile shown
+ // ACTION: QS Cellular tile tapped
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_CELLULAR = 115;
+
+ // OPEN: QS Color inversion tile shown
+ // ACTION: QS Color inversion tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_COLORINVERSION = 116;
+
+ // OPEN: QS Cellular tile > Cellular detail panel
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_DATAUSAGEDETAIL = 117;
+
+ // OPEN: QS Do not disturb tile shown
+ // ACTION: QS Do not disturb tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_DND = 118;
+
+ // OPEN: QS Flashlight tile shown
+ // ACTION: QS Flashlight tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_FLASHLIGHT = 119;
+
+ // OPEN: QS Hotspot tile shown
+ // ACTION: QS Hotspot tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_HOTSPOT = 120;
+
+ // OPEN: QS 3P tile shown
+ // ACTION: QS 3P tile tapped
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_INTENT = 121;
+
+ // OPEN: QS Location tile shown
+ // ACTION: QS Location tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_LOCATION = 122;
+
+ // OPEN: QS Rotation tile shown
+ // ACTION: QS Rotation tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_ROTATIONLOCK = 123;
+
+ // OBSOLETE
QS_USERDETAILITE = 124;
+
+ // OPEN: QS User list panel
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_USERDETAIL = 125;
+
+ // OPEN: QS WiFi tile shown
+ // ACTION: QS WiFi tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.46
QS_WIFI = 126;
+
+ // OPEN: Notification Panel (including lockscreen)
+ // CATEGORY: NOTIFICATION
+ // OS: 5.1.1
+ // GMS: 7.5.26
NOTIFICATION_PANEL = 127;
+
+ // OPEN: Notification in panel became visible.
+ // PACKAGE: App that posted the notification.
+ // ACTION: Notification is tapped.
+ // PACKAGE: App that posted the notification
+ // DETAIL: Notification is expanded by user.
+ // PACKAGE: App that posted the notification
+ // DISMISS: Notification is dismissed.
+ // PACKAGE: App that posted the notification
+ // SUBTYPE: Dismiss reason from NotificationManagerService.java
+ // CATEGORY: NOTIFICATION
+ // OS: 5.1.1
+ // GMS: 7.5.26
NOTIFICATION_ITEM = 128;
+
+ // ACTION: User tapped notification action
+ // PACKAGE: App that posted the notification
+ // SUBTYPE: Index of action on notification
+ // CATEGORY: NOTIFICATION
+ // OS: 5.0
+ // GMS: 7.5.26
NOTIFICATION_ITEM_ACTION = 129;
+
+ // OPEN: Settings > Apps > Configure apps > App permissions
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_ADVANCED = 130;
+
+ // OPEN: Settings > Location > Scanning
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
LOCATION_SCANNING = 131;
+
+ // OBSOLETE
MANAGE_APPLICATIONS_ALL = 132;
+
+ // OPEN: Settings > Sound & notification > App notifications
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
+
+ // ACTION: Settings > Wi-Fi > Overflow > Add Network
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_WIFI_ADD_NETWORK = 134;
+
+ // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_WIFI_CONNECT = 135;
+
+ // ACTION: Settings > Wi-Fi > Overflow > Refresh
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_WIFI_FORCE_SCAN = 136;
+
+ // ACTION: Settings > Wi-Fi > [Long press network] > Forget network
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_WIFI_FORGET = 137;
+
+ // ACTION: Settings > Wi-Fi > Toggle off
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_WIFI_OFF = 138;
+
+ // ACTION: Settings > Wi-Fi > Toggle on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_WIFI_ON = 139;
+
+ // OBSOLETE
MANAGE_PERMISSIONS = 140;
+
+ // OPEN: Settings > Sound & notification > DND > Priority only allows
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ZEN_MODE_PRIORITY = 141;
+
+ // OPEN: Settings > Sound & notification > DND > Automatic rules
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
+
+ // OPEN: Settings > Apps > Configure apps > App links
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
MANAGE_DOMAIN_URLS = 143;
+
+ // OPEN: Settings > Sound & notification > DND > [Time based rule]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
+
+ // OPEN: Settings > Sound & notification > DND > [External rule]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
+
+ // OPEN: Settings > Sound & notification > DND > [Event rule]
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
+
+ // ACTION: App notification settings > Block Notifications
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_BAN_APP_NOTES = 147;
+
+ // ACTION: Notification shade > Dismiss all button
+ // CATEGORY: NOTIFICATION
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_DISMISS_ALL_NOTES = 148;
+
+ // OPEN: QS Do Not Disturb detail panel
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_DND_DETAILS = 149;
+
+ // OPEN: QS Bluetooth detail panel
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_BLUETOOTH_DETAILS = 150;
+
+ // OPEN: QS Cast detail panel
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_CAST_DETAILS = 151;
+
+ // OPEN: QS Wi-Fi detail panel
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_WIFI_DETAILS = 152;
+
+ // ACTION: QS Wi-Fi detail panel > Wi-Fi toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_WIFI_TOGGLE = 153;
+
+ // ACTION: QS Bluetooth detail panel > Bluetooth toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_BLUETOOTH_TOGGLE = 154;
+
+ // ACTION: QS Cellular detail panel > Cellular toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_CELLULAR_TOGGLE = 155;
+
+ // ACTION: QS User list panel > Select different user
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_SWITCH_USER = 156;
+
+ // ACTION: QS Cast detail panel > Select cast device
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_CAST_SELECT = 157;
+
+ // ACTION: QS Cast detail panel > Disconnect cast device
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_CAST_DISCONNECT = 158;
+
+ // ACTION: Settings > Bluetooth > Toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_BLUETOOTH_TOGGLE = 159;
+
+ // ACTION: Settings > Bluetooth > Overflow > Refresh
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_BLUETOOTH_SCAN = 160;
+
+ // ACTION: Settings > Bluetooth > Overflow > Rename this device
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_BLUETOOTH_RENAME = 161;
+
+ // ACTION: Settings > Bluetooth > Overflow > Show received files
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_BLUETOOTH_FILES = 162;
+
+ // ACTION: QS DND details panel > Increase / Decrease exit time
+ // SUBTYPE: true is increase, false is decrease
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_DND_TIME = 163;
+
+ // ACTION: QS DND details panel > [Exit condition]
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_DND_CONDITION_SELECT = 164;
+
+ // ACTION: QS DND details panel > [DND mode]
+ // SUBTYPE: 1 is priority, 2 is silence, 3 is alarms only
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_DND_ZEN_SELECT = 165;
+
+ // ACTION: QS DND detail panel > DND toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
QS_DND_TOGGLE = 166;
+
+ // ACTION: DND Settings > Priority only allows > Reminder toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ALLOW_REMINDERS = 167;
+
+ // ACTION: DND Settings > Priority only allows > Event toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ALLOW_EVENTS = 168;
+
+ // ACTION: DND Settings > Priority only allows > Messages
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ALLOW_MESSAGES = 169;
+
+ // ACTION: DND Settings > Priority only allows > Calls
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ALLOW_CALLS = 170;
+
+ // ACTION: DND Settings > Priority only allows > Repeat callers toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
+
+ // ACTION: DND Settings > Automatic rules > Add rule
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ADD_RULE = 172;
+
+ // ACTION: DND Settings > Automatic rules > Add rule > OK
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ADD_RULE_OK = 173;
+
+ // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_DELETE_RULE = 174;
+
+ // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule > Delete
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_DELETE_RULE_OK = 175;
+
+ // ACTION: DND Settings > Automatic rules > [Rule] > Toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ZEN_ENABLE_RULE = 176;
+
+ // ACTION: Settings > More > Airplane mode toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_AIRPLANE_TOGGLE = 177;
+
+ // ACTION: Settings > Data usage > Cellular data toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_CELL_DATA_TOGGLE = 178;
+
+ // OPEN: Settings > Sound & notification > Notification access
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ACCESS = 179;
+
+ // OPEN: Settings > Sound & notification > Do Not Disturb access
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
NOTIFICATION_ZEN_MODE_ACCESS = 180;
+
+ // OPEN: Settings > Apps > Configure apps > Default Apps
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_DEFAULT_APPS = 181;
+
+ // OPEN: Settings > Internal storage > Apps storage
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_STORAGE_APPS = 182;
+
+ // OPEN: Settings > Security > Usage access
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
+
+ // OPEN: Settings > Battery > Battery optimization
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_HIGH_POWER_APPS = 184;
+
+ // OBSOLETE
FUELGAUGE_HIGH_POWER_DETAILS = 185;
+
+ // ACTION: Lockscreen > Unlock gesture
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
ACTION_LS_UNLOCK = 186;
+
+ // ACTION: Lockscreen > Pull shade open
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
ACTION_LS_SHADE = 187;
+
+ // ACTION: Lockscreen > Tap on lock, shows hint
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
ACTION_LS_HINT = 188;
+
+ // ACTION: Lockscreen > Camera
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
ACTION_LS_CAMERA = 189;
+
+ // ACTION: Lockscreen > Dialer
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
ACTION_LS_DIALER = 190;
+
+ // ACTION: Lockscreen > Tap on lock, locks phone
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
ACTION_LS_LOCK = 191;
+
+ // ACTION: Lockscreen > Tap on notification, false touch rejection
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
ACTION_LS_NOTE = 192;
+
+ // ACTION: Lockscreen > Swipe down to open quick settings
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.8.22
ACTION_LS_QS = 193;
+
+ // ACTION: Swipe down to open quick settings when unlocked
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.8.22
ACTION_SHADE_QS_PULL = 194;
+
+ // ACTION: Notification shade > Tap to open quick settings
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.8.22
ACTION_SHADE_QS_TAP = 195;
+
+ // OPEN: Lockscreen
+ // SUBTYPE: 0 is unsecure, 1 is secured by password / pattern / PIN
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
LOCKSCREEN = 196;
+
+ // OPEN: Lockscreen > Screen to enter password / pattern / PIN
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
BOUNCER = 197;
+
+ // OPEN: Screen turned on
+ // SUBTYPE: 2 is user action
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.8.22
SCREEN = 198;
+
+ // OPEN: Notification caused sound, vibration, and/or LED blink
+ // SUBTYPE: 1 is buzz, 2 is beep, blink is 4, or'd together
+ // CATEGORY: NOTIFICATION
+ // OS: 5.1.1
+ // GMS: 7.8.53
NOTIFICATION_ALERT = 199;
+
+ // ACTION: Lockscreen > Emergency Call button
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 5.1.1
+ // GMS: 7.5.26
ACTION_EMERGENCY_CALL = 200;
+
+ // OPEN: Settings > Apps > Configure > Default apps > Assist & voice input
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
APPLICATIONS_MANAGE_ASSIST = 201;
+
+ // OPEN: Settings > Memory
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
PROCESS_STATS_SUMMARY = 202;
+
+ // ACTION: Settings > Display > When device is rotated
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ROTATION_LOCK = 203;
+
+ // ACTION: Long press on notification to view controls
+ // CATEGORY: NOTIFICATION
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_NOTE_CONTROLS = 204;
+
+ // ACTION: Notificatoin controls > Info button
+ // CATEGORY: NOTIFICATION
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_NOTE_INFO = 205;
+
+ // ACTION: Notification controls > Settings button
+ // CATEGORY: NOTIFICATION
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_APP_NOTE_SETTINGS = 206;
+
+ // OPEN: Volume Dialog (with hardware buttons)
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
VOLUME_DIALOG = 207;
+
+ // OPEN: Volume dialog > Expanded volume dialog (multiple sliders)
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
VOLUME_DIALOG_DETAILS = 208;
+
+ // ACTION: Volume dialog > Adjust volume slider
+ // SUBTYPE: volume level (0-7)
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_VOLUME_SLIDER = 209;
+
+ // ACTION: Volume dialog > Select non-active stream
+ // SUBTYPE: stream (defined in AudioSystem.java)
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_VOLUME_STREAM = 210;
+
+ // ACTION: Adjust volume with hardware key
+ // SUBTYPE: volume level (0-7)
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_VOLUME_KEY = 211;
+
+ // ACTION: Volume dialog > Mute a stream by tapping icon
+ // SUBTYPE: mute is 1, audible is 2
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_VOLUME_ICON = 212;
+
+ // ACTION: Volume dialog > Change ringer mode by tapping icon
+ // SUBTYPE: 2 is audible, 3 is vibrate
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_RINGER_MODE = 213;
+
+ // ACTION: Chooser shown (share target, file open, etc.)
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ACTIVITY_CHOOSER_SHOWN = 214;
+
+ // ACTION: Chooser > User taps an app target
+ // SUBTYPE: Index of target
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215;
+
+ // ACTION: Chooser > User taps a service target
+ // SUBTYPE: Index of target
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216;
+
+ // ACTION: Chooser > User taps a standard target
+ // SUBTYPE: Index of target
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217;
+
+ // ACTION: QS Brightness Slider (with auto brightness disabled)
+ // SUBTYPE: slider value
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_BRIGHTNESS = 218;
+
+ // ACTION: QS Brightness Slider (with auto brightness enabled)
+ // SUBTYPE: slider value
+ // CATEGORY: QUICK_SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_BRIGHTNESS_AUTO = 219;
+
+ // OPEN: Settings > Display > Brightness Slider
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
BRIGHTNESS_DIALOG = 220;
+
+ // OPEN: Settings > Apps > Configure Apps > Draw over other apps
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
SYSTEM_ALERT_WINDOW_APPS = 221;
+
+ // OPEN: Display has entered dream mode
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
DREAMING = 222;
+
+ // OPEN: Display has entered ambient notification mode
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
DOZING = 223;
+
+ // OPEN: Overview
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
OVERVIEW_ACTIVITY = 224;
+
+ // OPEN: Settings > About phone > Legal information
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ABOUT_LEGAL_SETTINGS = 225;
+
+ // OPEN: Settings > Search > Perform search
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_SEARCH_RESULTS = 226;
+
+ // OPEN: Settings > System UI Tuner
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER = 227;
+
+ // OPEN: Settings > System UI Tuner > Quick Settings
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_QS = 228;
+
+ // OPEN: Settings > System UI Tuner > Demo mode
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_DEMO_MODE = 229;
+
+ // ACTION: Settings > System UI Tuner > Quick Settings > Move tile
+ // PACKAGE: Tile
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_QS_REORDER = 230;
+
+ // ACTION: Settings > System UI Tuner > Quick Settings > Add tile
+ // PACKAGE: Tile
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_QS_ADD = 231;
+
+ // ACTION: Settings > System UI Tuner > Quick Settings > Remove tile
+ // PACKAGE: Tile
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_QS_REMOVE = 232;
+
+ // ACTION: Settings > System UI Tuner > Status bar > Enable icon
+ // PACKAGE: Icon
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_STATUS_BAR_ENABLE = 233;
+
+ // ACTION: Settings > System UI Tuner > Status bar > Disable icon
+ // PACKAGE: Icon
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_STATUS_BAR_DISABLE = 234;
+
+ // ACTION: Settings > System UI Tuner > Demo mode > Enable demo mode
+ // SUBTYPE: false is disabled, true is enabled
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_DEMO_MODE_ENABLED = 235;
+
+ // ACTION: Settings > System UI Tuner > Demo mode > Show demo mode
+ // SUBTYPE: false is disabled, true is enabled
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_DEMO_MODE_ON = 236;
+
+ // ACTION: Settings > System UI Tuner > Show embedded battery percentage
+ // SUBTYPE: 0 is disabled, 1 is enabled
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
TUNER_BATTERY_PERCENTAGE = 237;
+
+ // OPEN: Settings > Developer options > Inactive apps
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.5.26
FUELGAUGE_INACTIVE_APPS = 238;
+
+ // ACTION: Long press home to bring up assistant
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.5.26
ACTION_ASSIST_LONG_PRESS = 239;
+
+ // OPEN: Settings > Security > Nexus Imprint > Add Fingerprint
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLLING = 240;
+
+ // OPEN: Fingerprint Enroll > Find Sensor
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_FIND_SENSOR = 241;
+
+ // OPEN: Fingerprint Enroll > Fingerprint Enrolled!
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLL_FINISH = 242;
+
+ // OPEN: Fingerprint Enroll introduction
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLL_INTRO = 243;
+
+ // OPEN: Fingerprint Enroll onboarding
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLL_ONBOARD = 244;
+
+ // OPEN: Fingerprint Enroll > Let's Start!
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLL_SIDECAR = 245;
+
+ // OPEN: Fingerprint Enroll SUW > Let's Start!
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLLING_SETUP = 246;
+
+ // OPEN: Fingerprint Enroll SUW > Find Sensor
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_FIND_SENSOR_SETUP = 247;
+
+ // OPEN: Fingerprint Enroll SUW > Fingerprint Enrolled!
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLL_FINISH_SETUP = 248;
+
+ // OPEN: Fingerprint Enroll SUW introduction
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLL_INTRO_SETUP = 249;
+
+ // OPEN: Fingerprint Enroll SUW onboarding
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
FINGERPRINT_ENROLL_ONBOARD_SETUP = 250;
+
+ // ACTION: Add fingerprint > Enroll fingerprint
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
ACTION_FINGERPRINT_ENROLL = 251;
+
+ // ACTION: Authenticate using fingerprint
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
ACTION_FINGERPRINT_AUTH = 252;
+
+ // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
ACTION_FINGERPRINT_DELETE = 253;
+
+ // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Rename
+ // CATEGORY: SETTINGS
+ // OS: 6.0
+ // GMS: 7.8.99
ACTION_FINGERPRINT_RENAME = 254;
+
+ // ACTION: Double tap camera shortcut
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.8.99
ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
+
+ // ACTION: Double twist camera shortcut
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: 6.0
+ // GMS: 7.8.99
ACTION_WIGGLE_CAMERA_GESTURE = 256;
+
+ // OPEN: QS Work Mode tile shown
+ // ACTION: QS Work Mode tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: N
+ // GMS: 7.8.99
QS_WORKMODE = 257;
+
+ // OPEN: Settings > Developer Options > Background Check
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
BACKGROUND_CHECK_SUMMARY = 258;
+
+ // OPEN: QS Lock tile shown
+ // ACTION: QS Lock tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: N
+ // GMS: 7.8.99
QS_LOCK_TILE = 259;
+
+ // OPEN: QS User Tile shown
+ // CATEGORY: QUICK_SETTINGS
+ // OS: N
+ // GMS: 7.8.99
QS_USER_TILE = 260;
+
+ // OPEN: QS Battery tile shown
+ // CATEGORY: QUICK_SETTINGS
+ // OS: N
+ // GMS: 7.8.99
QS_BATTERY_TILE = 261;
+
+ // OPEN: Settings > Sound > Do not disturb > Visual interruptions
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS = 262;
+
+ // ACTION: Visual interruptions > No screen interuptions toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF = 263;
- // Dead
+
+ // ACTION: Visual interruptions > No notification light toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_ZEN_ALLOW_LIGHTS = 264;
+
+ // OPEN: Settings > Notifications > [App] > Topic Notifications
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
NOTIFICATION_TOPIC_NOTIFICATION = 265;
+
+ // ACTION: Settings > Apps > Default Apps > Select different SMS app
+ // PACKAGE: Selected SMS app
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_DEFAULT_SMS_APP_CHANGED = 266;
+
+ // OPEN: QS Color modification tile shown
+ // ACTION: QS Color modification tile tapped
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: QUICK_SETTINGS
+ // OS: N
+ // GMS: 7.8.99
QS_COLOR_MATRIX = 267;
+
+ // OPEN: QS Custom tile shown
+ // ACTION: QS Work Mode tile tapped
+ // CATEGORY: QUICK_SETTINGS
+ // OS: N
+ // GMS: 7.8.99
QS_CUSTOM = 268;
+
+ // ACTION: Visual interruptions > Never turn off the screen toggle
+ // SUBTYPE: 0 is off, 1 is on
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_ZEN_ALLOW_WHEN_SCREEN_ON = 269;
- // Logged when the user docks a window from recents by
- // longpressing a task and dragging it to the dock area.
+ // ACTION: Overview > Long-press task, drag to enter split-screen
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
ACTION_WINDOW_DOCK_DRAG_DROP = 270;
- // Logged when the user docks a fullscreen window by long pressing
- // recents which also opens recents on the lower/right side.
+ // ACTION: In App > Long-press Overview button to enter split-screen
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
ACTION_WINDOW_DOCK_LONGPRESS = 271;
- // Logged when the user docks a window by dragging from the navbar
- // which also opens recents on the lower/right side.
+ // ACTION: In App > Swipe Overview button to enter split-screen
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
ACTION_WINDOW_DOCK_SWIPE = 272;
- // Logged when the user launches a profile-specific app and we
- // intercept it with the confirm credentials UI.
+ // ACTION: Launch profile-specific app > Confirm credentials
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
PROFILE_CHALLENGE = 273;
+ // OPEN: QS Battery detail panel
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
QS_BATTERY_DETAIL = 274;
- // Logged when the user goes into the overview history.
+ // OPEN: Overview > History
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
OVERVIEW_HISTORY = 275;
- // Logged when the user pages through overview.
- OVERVIEW_PAGE = 276;
+ // ACTION: Overview > Page by tapping Overview button
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
+ ACTION_OVERVIEW_PAGE = 276;
- // Logged when the user launches a task from overview.
- OVERVIEW_SELECT = 277;
+ // ACTION: Overview > Select app
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
+ ACTION_OVERVIEW_SELECT = 277;
- // Logged when the user views the emergency info.
+ // ACTION: View emergency info
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
ACTION_VIEW_EMERGENCY_INFO = 278;
- // Logged when the user views the edit emergency info activity.
+ // ACTION: Edit emergency info activity
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_EDIT_EMERGENCY_INFO = 279;
- // Logged when the user edits an emergency info field.
+ // ACTION: Edit emergency info field
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_EDIT_EMERGENCY_INFO_FIELD = 280;
- // Logged when the user adds a new emergency contact.
+ // ACTION: Add emergency contact
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_ADD_EMERGENCY_CONTACT = 281;
- // Logged when the user deletes an emergency contact.
+ // ACTION: Delete emergency contact
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_DELETE_EMERGENCY_CONTACT = 282;
- // Logged when the user calls an emergency contact.
+ // ACTION: Call emergency contact
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
ACTION_CALL_EMERGENCY_CONTACT = 283;
- // QS Tile for Data Saver.
+ // OPEN: QS Data Saver tile shown
+ // ACTION: QS Data Saver tile tapped
+ // CATEGORY: QUICK_SETTINGS
QS_DATA_SAVER = 284;
// OPEN: Settings > Security > User credentials
// CATEGORY: Settings
- // OS: 6.1
+ // OS: N
// GMS: 7.8.99
USER_CREDENTIALS = 285;
- // Logged when the user undocks a previously docked window by long pressing recents while in
- // docked mode.
+ // ACTION: In App (splitscreen) > Long-press Overview to exit split-screen
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
ACTION_WINDOW_UNDOCK_LONGPRESS = 286;
// Logged when the user scrolls through overview manually
@@ -370,43 +1770,66 @@
// indicate the user lowered the importance; positive means they increased it.
ACTION_SAVE_IMPORTANCE = 291;
- // Interactive bug report initiated from power menu.
+ // ACTION: Long-press power button, then tap "Take bug report" option.
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE = 292;
- // Full bug report initiated from power menu.
+ // ACTION: Long-press power button, then long-press "Take bug report" option.
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N
+ // GMS: 7.8.99
ACTION_BUGREPORT_FROM_POWER_MENU_FULL = 293;
+ // ACTION: Settings -> Developer Options -> Take bug report -> Interactive report
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
// Interactive bug report initiated from Settings.
ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE = 294;
- // Full bug report initiated from Settings.
+ // ACTION: Settings -> Developer Options -> Take bug report -> Full report
+ // CATEGORY: SETTINGS
+ // OS: N
+ // GMS: 7.8.99
+ // Interactive bug report initiated from Settings.
ACTION_BUGREPORT_FROM_SETTINGS_FULL = 295;
- // Bug report canceled using system notification.
+ // ACTION: User tapped notification action to cancel a bug report
+ // CATEGORY: NOTIFICATION
ACTION_BUGREPORT_NOTIFICATION_ACTION_CANCEL = 296;
- // Bug report details screen open using system notification.
+ // ACTION: User tapped notification action to launch bug report details screen
+ // CATEGORY: NOTIFICATION
ACTION_BUGREPORT_NOTIFICATION_ACTION_DETAILS = 297;
- // Additional Bug report screen shot taken using system notification.
+ // ACTION: User tapped notification action to take adition screenshot on bug report
+ // CATEGORY: NOTIFICATION
ACTION_BUGREPORT_NOTIFICATION_ACTION_SCREENSHOT = 298;
- // Bug report shared by user using system notification.
+ // ACTION: User tapped notification to share bug report
+ // CATEGORY: NOTIFICATION
ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE = 299;
- // User changed bug report name using the details screen.
+ // ACTION: User changed bug report name using the details screen
+ // CATEGORY: GLOBAL_SYSTEM_UI
ACTION_BUGREPORT_DETAILS_NAME_CHANGED = 300;
- // User changed bug report title using the details screen.
+ // ACTION: User changed bug report title using the details screen
+ // CATEGORY: GLOBAL_SYSTEM_UI
ACTION_BUGREPORT_DETAILS_TITLE_CHANGED = 301;
- // User changed bug report description using the details screen.
+ // ACTION: User changed bug report description using the details screen
+ // CATEGORY: GLOBAL_SYSTEM_UI
ACTION_BUGREPORT_DETAILS_DESCRIPTION_CHANGED = 302;
- // Changes made on bug report details screen were saved by user.
+ // ACTION: User tapped Save in the bug report details screen.
+ // CATEGORY: GLOBAL_SYSTEM_UI
ACTION_BUGREPORT_DETAILS_SAVED = 303;
- // Changes made on bug report details screen were canceled by user.
+ // ACTION: User tapped Cancel in the bug report details screen.
+ // CATEGORY: GLOBAL_SYSTEM_UI
ACTION_BUGREPORT_DETAILS_CANCELED = 304;
// Tuner: Open/close calibrate dialog.
@@ -504,6 +1927,14 @@
// access before; action pass package name of calling package.
ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE = 331;
+ // Logged when the user slides a notification and
+ // reveals the gear beneath it.
+ ACTION_REVEAL_GEAR = 332;
+
+ // Logged when the user taps on the gear beneath
+ // a notification.
+ ACTION_TOUCH_GEAR = 333;
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 3bef19e..316e530 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1061,7 +1061,7 @@
type, kind, norm, size);
}
return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind,
- norm, size);
+ norm, size, true);
}
static jlong
@@ -1100,7 +1100,7 @@
jlong id = (jlong)(uintptr_t)rsElementCreate2((RsContext)con,
(const RsElement *)ids, fieldCount,
nameArray, fieldCount * sizeof(size_t), sizeArray,
- (const uint32_t *)arraySizes, fieldCount);
+ (const uint32_t *)arraySizes, fieldCount, true);
free(ids);
free(arraySizes);
@@ -1174,7 +1174,7 @@
}
return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips,
- faces, yuv);
+ faces, yuv, true);
}
static void
@@ -1210,7 +1210,7 @@
}
return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type,
(RsAllocationMipmapControl)mips,
- (uint32_t)usage, (uintptr_t)pointer);
+ (uint32_t)usage, (uintptr_t)pointer, true);
}
static void
@@ -1315,7 +1315,7 @@
const void* ptr = bitmap.getPixels();
jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
(RsType)type, (RsAllocationMipmapControl)mip,
- ptr, bitmap.getSize(), usage);
+ ptr, bitmap.getSize(), usage, true);
bitmap.unlockPixels();
return id;
}
@@ -1331,7 +1331,7 @@
const void* ptr = bitmap.getPixels();
jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
(RsType)type, (RsAllocationMipmapControl)mip,
- (uint32_t)usage, (uintptr_t)ptr);
+ (uint32_t)usage, (uintptr_t)ptr, true);
bitmap.unlockPixels();
return id;
}
@@ -1347,7 +1347,7 @@
const void* ptr = bitmap.getPixels();
jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
(RsType)type, (RsAllocationMipmapControl)mip,
- ptr, bitmap.getSize(), usage);
+ ptr, bitmap.getSize(), usage, true);
bitmap.unlockPixels();
return id;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index acd57b17..9e6c21c 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -655,10 +655,9 @@
userState.mUiAutomationServiceOwner = owner;
userState.mUiAutomationServiceClient = serviceClient;
userState.mUiAutomationFlags = flags;
- userState.mIsAccessibilityEnabled = true;
userState.mInstalledServices.add(accessibilityServiceInfo);
if ((flags & UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) == 0) {
- // Set the temporary state.
+ // Set the temporary state, and use it instead of settings
userState.mIsTouchExplorationEnabled = false;
userState.mIsEnhancedWebAccessibilityEnabled = false;
userState.mIsDisplayMagnificationEnabled = false;
@@ -709,7 +708,6 @@
return;
}
- userState.mIsAccessibilityEnabled = true;
userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
userState.mIsEnhancedWebAccessibilityEnabled = false;
userState.mIsDisplayMagnificationEnabled = false;
@@ -1245,17 +1243,17 @@
}
}
- private void manageServicesLocked(UserState userState) {
+ private void updateServicesLocked(UserState userState) {
Map<ComponentName, Service> componentNameToServiceMap =
userState.mComponentNameToServiceMap;
boolean isUnlocked = mContext.getSystemService(UserManager.class)
.isUserUnlocked(userState.mUserId);
- boolean isEnabled = userState.mIsAccessibilityEnabled;
for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) {
AccessibilityServiceInfo installedService = userState.mInstalledServices.get(i);
ComponentName componentName = ComponentName.unflattenFromString(
installedService.getId());
+
Service service = componentNameToServiceMap.get(componentName);
// Ignore non-encryption-aware services until user is unlocked
@@ -1264,45 +1262,25 @@
continue;
}
- if (isEnabled) {
- // Wait for the binding if it is in process.
- if (userState.mBindingServices.contains(componentName)) {
+ // Wait for the binding if it is in process.
+ if (userState.mBindingServices.contains(componentName)) {
+ continue;
+ }
+ if (userState.mEnabledServices.contains(componentName)) {
+ if (service == null) {
+ service = new Service(userState.mUserId, componentName, installedService);
+ } else if (userState.mBoundServices.contains(service)) {
continue;
}
- if (userState.mEnabledServices.contains(componentName)) {
- if (service == null) {
- service = new Service(userState.mUserId, componentName, installedService);
- } else if (userState.mBoundServices.contains(service)) {
- continue;
- }
- service.bindLocked();
- } else {
- if (service != null) {
- service.unbindLocked();
- }
- }
+ service.bindLocked();
} else {
if (service != null) {
service.unbindLocked();
- } else {
- userState.mBindingServices.remove(componentName);
}
}
}
- // No enabled installed services => disable accessibility to avoid
- // sending accessibility events with no recipient across processes.
- if (isEnabled && isUnlocked && userState.mBoundServices.isEmpty()
- && userState.mBindingServices.isEmpty()) {
- userState.mIsAccessibilityEnabled = false;
- final long identity = Binder.clearCallingIdentity();
- try {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
+ updateAccessibilityEnabledSetting(userState);
}
private void scheduleUpdateClientsIfNeededLocked(UserState userState) {
@@ -1329,7 +1307,8 @@
flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER;
}
// Touch exploration without accessibility makes no sense.
- if (userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) {
+ if (userState.isHandlingAccessibilityEvents()
+ && userState.mIsTouchExplorationEnabled) {
flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION;
}
if (userState.mIsFilterKeyEventsEnabled) {
@@ -1468,25 +1447,17 @@
}
private void updateWindowsForAccessibilityCallbackLocked(UserState userState) {
- if (userState.mIsAccessibilityEnabled) {
- // We observe windows for accessibility only if there is at least
- // one bound service that can retrieve window content that specified
- // it is interested in accessing such windows. For services that are
- // binding we do an update pass after each bind event, so we run this
- // code and register the callback if needed.
- boolean boundServiceCanRetrieveInteractiveWindows = false;
+ // We observe windows for accessibility only if there is at least
+ // one bound service that can retrieve window content that specified
+ // it is interested in accessing such windows. For services that are
+ // binding we do an update pass after each bind event, so we run this
+ // code and register the callback if needed.
- List<Service> boundServices = userState.mBoundServices;
- final int boundServiceCount = boundServices.size();
- for (int i = 0; i < boundServiceCount; i++) {
- Service boundService = boundServices.get(i);
- if (boundService.canRetrieveInteractiveWindowsLocked()) {
- boundServiceCanRetrieveInteractiveWindows = true;
- break;
- }
- }
-
- if (boundServiceCanRetrieveInteractiveWindows) {
+ List<Service> boundServices = userState.mBoundServices;
+ final int boundServiceCount = boundServices.size();
+ for (int i = 0; i < boundServiceCount; i++) {
+ Service boundService = boundServices.get(i);
+ if (boundService.canRetrieveInteractiveWindowsLocked()) {
if (mWindowsForAccessibilityCallback == null) {
mWindowsForAccessibilityCallback = new WindowsForAccessibilityCallback();
mWindowManagerService.setWindowsForAccessibilityCallback(
@@ -1554,37 +1525,30 @@
userState.mIsFilterKeyEventsEnabled = false;
}
- private void updateServicesLocked(UserState userState) {
- if (userState.mIsAccessibilityEnabled) {
- manageServicesLocked(userState);
- } else {
- unbindAllServicesLocked(userState);
- }
- }
-
private boolean readConfigurationForUserStateLocked(UserState userState) {
- boolean somthingChanged = readAccessibilityEnabledSettingLocked(userState);
- somthingChanged |= readInstalledAccessibilityServiceLocked(userState);
- somthingChanged |= readEnabledAccessibilityServicesLocked(userState);
- somthingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState);
- somthingChanged |= readTouchExplorationEnabledSettingLocked(userState);
- somthingChanged |= readHighTextContrastEnabledSettingLocked(userState);
- somthingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
- somthingChanged |= readDisplayMagnificationEnabledSettingLocked(userState);
- somthingChanged |= readAutoclickEnabledSettingLocked(userState);
- somthingChanged |= readDisplayColorAdjustmentSettingsLocked(userState);
- return somthingChanged;
+ boolean somethingChanged = readInstalledAccessibilityServiceLocked(userState);
+ somethingChanged |= readEnabledAccessibilityServicesLocked(userState);
+ somethingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState);
+ somethingChanged |= readTouchExplorationEnabledSettingLocked(userState);
+ somethingChanged |= readHighTextContrastEnabledSettingLocked(userState);
+ somethingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
+ somethingChanged |= readDisplayMagnificationEnabledSettingLocked(userState);
+ somethingChanged |= readAutoclickEnabledSettingLocked(userState);
+ somethingChanged |= readDisplayColorAdjustmentSettingsLocked(userState);
+
+ return somethingChanged;
}
- private boolean readAccessibilityEnabledSettingLocked(UserState userState) {
- final boolean accessibilityEnabled = Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId) == 1;
- if (accessibilityEnabled != userState.mIsAccessibilityEnabled) {
- userState.mIsAccessibilityEnabled = accessibilityEnabled;
- return true;
+ private void updateAccessibilityEnabledSetting(UserState userState) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED,
+ userState.isHandlingAccessibilityEvents() ? 0 : 1,
+ userState.mUserId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- return false;
}
private boolean readTouchExplorationEnabledSettingLocked(UserState userState) {
@@ -1809,7 +1773,7 @@
// Check whether any Accessibility Services are still enabled and, if not, remove flag
// requesting no soft keyboard
final boolean accessibilityRequestingNoIme = userState.mSoftKeyboardShowMode == 1;
- if (accessibilityRequestingNoIme && !userState.mIsAccessibilityEnabled) {
+ if (accessibilityRequestingNoIme && !userState.isHandlingAccessibilityEvents()) {
// No active Accessibility Services can be requesting the soft keyboard to be hidden
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
@@ -1853,7 +1817,6 @@
UserState userState = mUserStates.valueAt(i);
pw.append("User state[attributes:{id=" + userState.mUserId);
pw.append(", currentUser=" + (userState.mUserId == mCurrentUserId));
- pw.append(", accessibilityEnabled=" + userState.mIsAccessibilityEnabled);
pw.append(", touchExplorationEnabled=" + userState.mIsTouchExplorationEnabled);
pw.append(", displayMagnificationEnabled="
+ userState.mIsDisplayMagnificationEnabled);
@@ -2003,7 +1966,7 @@
private void announceNewUserIfNeeded() {
synchronized (mLock) {
UserState userState = getCurrentUserStateLocked();
- if (userState.mIsAccessibilityEnabled) {
+ if (userState.isHandlingAccessibilityEvents()) {
UserManager userManager = (UserManager) mContext.getSystemService(
Context.USER_SERVICE);
String message = mContext.getString(R.string.user_switched,
@@ -4061,7 +4024,6 @@
public int mSoftKeyboardShowMode = 0;
- public boolean mIsAccessibilityEnabled;
public boolean mIsTouchExplorationEnabled;
public boolean mIsTextHighContrastEnabled;
public boolean mIsEnhancedWebAccessibilityEnabled;
@@ -4096,11 +4058,11 @@
public int getClientState() {
int clientState = 0;
- if (mIsAccessibilityEnabled) {
+ if (isHandlingAccessibilityEvents()) {
clientState |= AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED;
}
// Touch exploration relies on enabled accessibility.
- if (mIsAccessibilityEnabled && mIsTouchExplorationEnabled) {
+ if (isHandlingAccessibilityEvents() && mIsTouchExplorationEnabled) {
clientState |= AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED;
}
if (mIsTextHighContrastEnabled) {
@@ -4109,6 +4071,10 @@
return clientState;
}
+ public boolean isHandlingAccessibilityEvents() {
+ return !mBoundServices.isEmpty() || !mBoundServices.isEmpty();
+ }
+
public void onSwitchToAnotherUser() {
// Clear UI test automation state.
if (mUiAutomationService != null) {
@@ -4128,7 +4094,6 @@
// Clear state persisted in settings.
mEnabledServices.clear();
mTouchExplorationGrantedServices.clear();
- mIsAccessibilityEnabled = false;
mIsTouchExplorationEnabled = false;
mIsEnhancedWebAccessibilityEnabled = false;
mIsDisplayMagnificationEnabled = false;
@@ -4155,9 +4120,6 @@
private final class AccessibilityContentObserver extends ContentObserver {
- private final Uri mAccessibilityEnabledUri = Settings.Secure.getUriFor(
- Settings.Secure.ACCESSIBILITY_ENABLED);
-
private final Uri mTouchExplorationEnabledUri = Settings.Secure.getUriFor(
Settings.Secure.TOUCH_EXPLORATION_ENABLED);
@@ -4199,8 +4161,6 @@
}
public void register(ContentResolver contentResolver) {
- contentResolver.registerContentObserver(mAccessibilityEnabledUri,
- false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(mTouchExplorationEnabledUri,
false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(mDisplayMagnificationEnabledUri,
@@ -4240,11 +4200,7 @@
return;
}
- if (mAccessibilityEnabledUri.equals(uri)) {
- if (readAccessibilityEnabledSettingLocked(userState)) {
- onUserStateChangedLocked(userState);
- }
- } else if (mTouchExplorationEnabledUri.equals(uri)) {
+ if (mTouchExplorationEnabledUri.equals(uri)) {
if (readTouchExplorationEnabledSettingLocked(userState)) {
onUserStateChangedLocked(userState);
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 9a9c2bc..8603981 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -16,9 +16,14 @@
package com.android.server.appwidget;
+import static android.content.Context.KEYGUARD_SERVICE;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
+import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
@@ -72,10 +77,12 @@
import android.util.TypedValue;
import android.util.Xml;
import android.view.Display;
+import android.view.View;
import android.view.WindowManager;
import android.widget.RemoteViews;
import com.android.internal.R;
+import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.appwidget.IAppWidgetHost;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
@@ -146,7 +153,7 @@
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
if (DEBUG) {
- Slog.i(TAG, "Received broadcast: " + action);
+ Slog.i(TAG, "Received broadcast: " + action + " on user " + userId);
}
if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
@@ -156,10 +163,10 @@
} else if (Intent.ACTION_USER_STOPPED.equals(action)) {
onUserStopped(userId);
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- reloadWidgetsMaskedStateForUser(userId);
+ reloadWidgetsMaskedStateForGroup(userId);
} else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) {
synchronized (mLock) {
- reloadWidgetProfileUnavailableMaskedStateLocked(userId);
+ reloadWidgetsMaskedState(userId);
}
} else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) {
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
@@ -202,6 +209,7 @@
private final AlarmManager mAlarmManager;
private final UserManager mUserManager;
private final AppOpsManager mAppOpsManager;
+ private final KeyguardManager mKeyguardManager;
private final SecurityPolicy mSecurityPolicy;
@@ -223,6 +231,7 @@
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+ mKeyguardManager = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
mSaveStateHandler = BackgroundThread.getHandler();
mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
mBackupRestoreController = new BackupRestoreController();
@@ -436,48 +445,51 @@
/**
* Reload all widgets' masked state for the given user and its associated profiles, including
* due to user not being available and package suspension.
+ * userId must be the group parent.
*/
- private void reloadWidgetsMaskedStateForUser(int userId) {
- if (!mUserManager.isUserUnlocked(userId) ||
- isProfileWithLockedParent(userId)) {
+ private void reloadWidgetsMaskedStateForGroup(int userId) {
+ if (!mUserManager.isUserUnlocked(userId)) {
return;
}
synchronized (mLock) {
- reloadWidgetPackageSuspensionMaskedStateLocked(userId);
+ reloadWidgetsMaskedState(userId);
List<UserInfo> profiles = mUserManager.getEnabledProfiles(userId);
if (profiles != null) {
for (int i = 0; i < profiles.size(); i++) {
UserInfo user = profiles.get(i);
- reloadWidgetProfileUnavailableMaskedStateLocked(user.id);
- reloadWidgetPackageSuspensionMaskedStateLocked(user.id);
+ reloadWidgetsMaskedState(user.id);
}
}
}
}
- /**
- * Mask/unmask widgets in the given profile, depending on the quiet state
- * or locked state of the profile.
- */
- private void reloadWidgetProfileUnavailableMaskedStateLocked(int profileId) {
+ private void reloadWidgetsMaskedState(int userId) {
final long identity = Binder.clearCallingIdentity();
try {
- if (!isProfileWithUnlockedParent(profileId)) {
- return;
- }
- UserInfo user = mUserManager.getUserInfo(profileId);
- boolean shouldMask = user.isQuietModeEnabled() ||
- !mUserManager.isUserUnlocked(user.getUserHandle());
+ UserInfo user = mUserManager.getUserInfo(userId);
+
+ boolean lockedProfile = !mUserManager.isUserUnlocked(userId);
+ boolean quietProfile = user.isQuietModeEnabled();
final int N = mProviders.size();
for (int i = 0; i < N; i++) {
Provider provider = mProviders.get(i);
int providerUserId = provider.getUserId();
- if (providerUserId != profileId) {
+ if (providerUserId != userId) {
continue;
}
- if (provider.setMaskedByProfileUnavailabledLocked(shouldMask)) {
+
+ boolean changed = provider.setMaskedByLockedProfileLocked(lockedProfile);
+ changed |= provider.setMaskedByQuietProfileLocked(quietProfile);
+ try {
+ boolean suspended = mPackageManager.isPackageSuspendedForUser(
+ provider.info.provider.getPackageName(), provider.getUserId());
+ changed |= provider.setMaskedBySuspendedPackageLocked(suspended);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to query application info", e);
+ }
+ if (changed) {
if (provider.isMaskedLocked()) {
- maskWidgetsViewsLocked(provider);
+ maskWidgetsViewsLocked(provider, null);
} else {
unmaskWidgetsViewsLocked(provider);
}
@@ -489,33 +501,6 @@
}
/**
- * Reload widget's masked state due to package suspension state.
- */
- private void reloadWidgetPackageSuspensionMaskedStateLocked(int profileId) {
- final int N = mProviders.size();
- for (int i = 0; i < N; i++) {
- Provider provider = mProviders.get(i);
- int providerUserId = provider.getUserId();
- if (providerUserId != profileId) {
- continue;
- }
- try {
- boolean suspended = mPackageManager.isPackageSuspendedForUser(
- provider.info.provider.getPackageName(), provider.getUserId());
- if (provider.setMaskedBySuspendedPackageLocked(suspended)) {
- if (provider.isMaskedLocked()) {
- maskWidgetsViewsLocked(provider);
- } else {
- unmaskWidgetsViewsLocked(provider);
- }
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to query application info", e);
- }
- }
- }
-
- /**
* Incrementally update the masked state due to package suspension state.
*/
private void updateWidgetPackageSuspensionMaskedState(String[] packagesArray, boolean suspended,
@@ -535,7 +520,7 @@
}
if (provider.setMaskedBySuspendedPackageLocked(suspended)) {
if (provider.isMaskedLocked()) {
- maskWidgetsViewsLocked(provider);
+ maskWidgetsViewsLocked(provider, null);
} else {
unmaskWidgetsViewsLocked(provider);
}
@@ -544,14 +529,13 @@
}
}
- private Bitmap createMaskedWidgetBitmap(Provider provider) {
+ private Bitmap createMaskedWidgetBitmap(String providerPackage, int providerUserId) {
final long identity = Binder.clearCallingIdentity();
try {
// Load the unbadged application icon and pass it to the widget to appear on
// the masked view.
- final String providerPackage = provider.info.provider.getPackageName();
Context userContext = mContext.createPackageContextAsUser(providerPackage, 0,
- UserHandle.of(provider.getUserId()));
+ UserHandle.of(providerUserId));
PackageManager pm = userContext.getPackageManager();
Drawable icon = pm.getApplicationInfo(providerPackage, 0).loadUnbadgedIcon(pm);
// Create a bitmap of the icon which is what the widget's remoteview requires.
@@ -566,18 +550,73 @@
}
}
- private void maskWidgetsViewsLocked(Provider provider) {
- Bitmap iconBitmap = createMaskedWidgetBitmap(provider);
+ private RemoteViews createMaskedWidgetRemoteViews(Bitmap icon, boolean showBadge,
+ PendingIntent onClickIntent) {
+ RemoteViews views = new RemoteViews(mContext.getPackageName(),
+ R.layout.work_widget_mask_view);
+ if (icon != null) {
+ views.setImageViewBitmap(R.id.work_widget_app_icon, icon);
+ }
+ if (!showBadge) {
+ views.setViewVisibility(R.id.work_widget_badge_icon, View.INVISIBLE);
+ }
+ if (onClickIntent != null) {
+ views.setOnClickPendingIntent(R.id.work_widget_mask_frame, onClickIntent);
+ }
+ return views;
+ }
+
+ /**
+ * Mask the target widget belonging to the specified provider, or all active widgets
+ * of the provider if target widget == null.
+ */
+ private void maskWidgetsViewsLocked(Provider provider, Widget targetWidget) {
+ final int widgetCount = provider.widgets.size();
+ if (widgetCount == 0) {
+ return;
+ }
+ final String providerPackage = provider.info.provider.getPackageName();
+ final int providerUserId = provider.getUserId();
+ Bitmap iconBitmap = createMaskedWidgetBitmap(providerPackage, providerUserId);
if (iconBitmap == null) {
return;
}
+ final boolean showBadge;
+ final Intent onClickIntent;
+ if (provider.maskedBySuspendedPackage) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ UserInfo userInfo = mUserManager.getUserInfo(providerUserId);
+ showBadge = userInfo.isManagedProfile();
+ onClickIntent = UnlaunchableAppActivity.createPackageSuspendedDialogIntent(
+ providerPackage, providerUserId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ } else if (provider.maskedByQuietProfile) {
+ showBadge = true;
+ onClickIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
+ providerUserId);
+ } else /* provider.maskedByLockedProfile */ {
+ showBadge = true;
+ onClickIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null,
+ providerUserId);
+ if (onClickIntent != null) {
+ onClickIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ }
+ }
- final int widgetCount = provider.widgets.size();
for (int j = 0; j < widgetCount; j++) {
Widget widget = provider.widgets.get(j);
- if (widget.replaceWithMaskedViewsLocked(mContext, iconBitmap)) {
- scheduleNotifyUpdateAppWidgetLocked(widget,
- widget.getEffectiveViewsLocked());
+ if (targetWidget != null && targetWidget != widget) continue;
+ PendingIntent intent = null;
+ if (onClickIntent != null) {
+ intent = PendingIntent.getActivity(mContext, widget.appWidgetId,
+ onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+ RemoteViews views = createMaskedWidgetRemoteViews(iconBitmap, showBadge, intent);
+ if (widget.replaceWithMaskedViewsLocked(views)) {
+ scheduleNotifyUpdateAppWidgetLocked(widget, widget.getEffectiveViewsLocked());
}
}
}
@@ -587,8 +626,7 @@
for (int j = 0; j < widgetCount; j++) {
Widget widget = provider.widgets.get(j);
if (widget.clearMaskedViewsLocked()) {
- scheduleNotifyUpdateAppWidgetLocked(widget,
- widget.getEffectiveViewsLocked());
+ scheduleNotifyUpdateAppWidgetLocked(widget, widget.getEffectiveViewsLocked());
}
}
}
@@ -2472,7 +2510,7 @@
}
synchronized (mLock) {
ensureGroupStateLoadedLocked(userId);
- reloadWidgetsMaskedStateForUser(userId);
+ reloadWidgetsMaskedStateForGroup(mSecurityPolicy.getGroupParent(userId));
final int N = mProviders.size();
for (int i = 0; i < N; i++) {
@@ -2614,10 +2652,7 @@
// If we are adding a widget it might be for a provider that
// is currently masked, if so mask the widget.
if (widget.provider.isMaskedLocked()) {
- Bitmap bitmap = createMaskedWidgetBitmap(widget.provider);
- if (bitmap != null) {
- widget.replaceWithMaskedViewsLocked(mContext, bitmap);
- }
+ maskWidgetsViewsLocked(widget.provider, widget);
} else {
widget.clearMaskedViewsLocked();
}
@@ -3610,7 +3645,8 @@
PendingIntent broadcast;
boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
- boolean maskedByProfileUnavailable;
+ boolean maskedByLockedProfile;
+ boolean maskedByQuietProfile;
boolean maskedBySuspendedPackage;
int tag = TAG_UNDEFINED; // for use while saving state (the index)
@@ -3642,22 +3678,29 @@
return "Provider{" + id + (zombie ? " Z" : "") + '}';
}
- // returns true if the provider's masked state is changed as a result
- public boolean setMaskedByProfileUnavailabledLocked(boolean masked) {
- boolean oldMaskedState = isMaskedLocked();
- maskedByProfileUnavailable = masked;
- return isMaskedLocked() != oldMaskedState;
+ // returns true if it's different from previous state.
+ public boolean setMaskedByQuietProfileLocked(boolean masked) {
+ boolean oldState = maskedByQuietProfile;
+ maskedByQuietProfile = masked;
+ return masked != oldState;
}
- // returns true if the provider's masked state is changed as a result
+ // returns true if it's different from previous state.
+ public boolean setMaskedByLockedProfileLocked(boolean masked) {
+ boolean oldState = maskedByLockedProfile;
+ maskedByLockedProfile = masked;
+ return masked != oldState;
+ }
+
+ // returns true if it's different from previous state.
public boolean setMaskedBySuspendedPackageLocked(boolean masked) {
- boolean oldMaskedState = isMaskedLocked();
+ boolean oldState = maskedBySuspendedPackage;
maskedBySuspendedPackage = masked;
- return isMaskedLocked() != oldMaskedState;
+ return masked != oldState;
}
public boolean isMaskedLocked() {
- return maskedByProfileUnavailable || maskedBySuspendedPackage;
+ return maskedByQuietProfile || maskedByLockedProfile || maskedBySuspendedPackage;
}
}
@@ -3814,14 +3857,8 @@
return "AppWidgetId{" + appWidgetId + ':' + host + ':' + provider + '}';
}
- private boolean replaceWithMaskedViewsLocked(Context context, Bitmap icon) {
- if (maskedViews != null) {
- return false;
- }
- maskedViews = new RemoteViews(context.getPackageName(), R.layout.work_widget_mask_view);
- if (icon != null) {
- maskedViews.setImageViewBitmap(R.id.work_widget_app_icon, icon);
- }
+ private boolean replaceWithMaskedViewsLocked(RemoteViews views) {
+ maskedViews = views;
return true;
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 25b6fdd..079b2f2 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -125,6 +125,7 @@
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.PacManager;
import com.android.server.connectivity.PermissionMonitor;
+import com.android.server.connectivity.ApfFilter;
import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.BaseNetworkObserver;
@@ -353,6 +354,13 @@
*/
private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
+ /**
+ * used to push APF program to NetworkAgent
+ * replyTo = NetworkAgent message handler
+ * obj = byte[] of APF program
+ */
+ private static final int EVENT_PUSH_APF_PROGRAM_TO_NETWORK = 32;
+
/** Handler thread used for both of the handlers below. */
@VisibleForTesting
protected final HandlerThread mHandlerThread;
@@ -2190,6 +2198,7 @@
mKeepaliveTracker.handleStopAllKeepalives(nai,
ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
+ if (nai.apfFilter != null) nai.apfFilter.shutdown();
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
synchronized (mNetworkForNetId) {
@@ -2404,6 +2413,13 @@
accept ? 1 : 0, always ? 1: 0, network));
}
+ public void pushApfProgramToNetwork(NetworkAgentInfo nai, byte[] program) {
+ enforceConnectivityInternalPermission();
+ Message msg = mHandler.obtainMessage(EVENT_PUSH_APF_PROGRAM_TO_NETWORK, program);
+ msg.replyTo = nai.messenger;
+ mHandler.sendMessage(msg);
+ }
+
private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
if (DBG) log("handleSetAcceptUnvalidated network=" + network +
" accept=" + accept + " always=" + always);
@@ -2553,6 +2569,16 @@
handleMobileDataAlwaysOn();
break;
}
+ case EVENT_PUSH_APF_PROGRAM_TO_NETWORK: {
+ NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
+ if (nai == null) {
+ loge("EVENT_PUSH_APF_PROGRAM_TO_NETWORK from unknown NetworkAgent");
+ } else {
+ nai.asyncChannel.sendMessage(NetworkAgent.CMD_PUSH_APF_PROGRAM,
+ (byte[]) msg.obj);
+ }
+ break;
+ }
// Sent by KeepaliveTracker to process an app request on the state machine thread.
case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
mKeepaliveTracker.handleStartKeepalive(msg);
@@ -4068,6 +4094,9 @@
if (networkAgent.clatd != null) {
networkAgent.clatd.fixupLinkProperties(oldLp);
}
+ if (networkAgent.apfFilter != null) {
+ networkAgent.apfFilter.updateFilter();
+ }
updateInterfaces(newLp, oldLp, netId);
updateMtu(newLp, oldLp);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index ba2a2e0..6fb0671 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -345,9 +345,9 @@
final int userId = users.get(user).id;
final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
- if (ownerInfo != null) {
+ if (!TextUtils.isEmpty(ownerInfo)) {
setString(OWNER_INFO, ownerInfo, userId);
- Settings.Secure.putStringForUser(cr, ownerInfo, "", userId);
+ Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
}
// Migrate owner info enabled. Note there was a bug where older platforms only
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index 3f0664d..b64c65d 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -23,8 +23,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
+import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -34,10 +36,14 @@
import android.provider.Settings;
import android.util.Log;
import android.util.NtpTrustedTime;
+import android.util.TimeUtils;
import android.util.TrustedTime;
import com.android.internal.telephony.TelephonyIntents;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* Monitors the network time and updates the system time if it is out of sync
* and there hasn't been any NITZ update from the carrier recently.
@@ -48,7 +54,7 @@
* available.
* </p>
*/
-public class NetworkTimeUpdateService {
+public class NetworkTimeUpdateService extends Binder {
private static final String TAG = "NetworkTimeUpdateService";
private static final boolean DBG = false;
@@ -59,6 +65,8 @@
private static final String ACTION_POLL =
"com.android.server.NetworkTimeUpdateService.action.POLL";
+
+ private static final int NETWORK_CHANGE_EVENT_DELAY_MS = 1000;
private static int POLL_REQUEST = 0;
private static final long NOT_SET = -1;
@@ -245,6 +253,7 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
+ if (DBG) Log.d(TAG, "Received " + action);
if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
mNitzTimeSetTime = SystemClock.elapsedRealtime();
} else if (TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE.equals(action)) {
@@ -260,8 +269,11 @@
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
+ if (DBG) Log.d(TAG, "Received CONNECTIVITY_ACTION ");
// Don't bother checking if we have connectivity, NtpTrustedTime does that for us.
- mHandler.obtainMessage(EVENT_NETWORK_CHANGED).sendToTarget();
+ Message message = mHandler.obtainMessage(EVENT_NETWORK_CHANGED);
+ // Send with a short delay to make sure the network is ready for use
+ mHandler.sendMessageDelayed(message, NETWORK_CHANGE_EVENT_DELAY_MS);
}
}
};
@@ -308,4 +320,28 @@
mHandler.obtainMessage(mMsg).sendToTarget();
}
}
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump NetworkTimeUpdateService from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid()
+ + " without permission "
+ + android.Manifest.permission.DUMP);
+ return;
+ }
+ pw.print("PollingIntervalMs: ");
+ TimeUtils.formatDuration(mPollingIntervalMs, pw);
+ pw.print("\nPollingIntervalShorterMs: ");
+ TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
+ pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
+ pw.print("TimeErrorThresholdMs: ");
+ TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
+ pw.println("\nTryAgainCounter: " + mTryAgainCounter);
+ pw.print("LastNtpFetchTime: ");
+ TimeUtils.formatDuration(mLastNtpFetchTime, pw);
+ pw.println();
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index 4f0d4d9..f2bf4f9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -46,6 +46,7 @@
// Available log categories in the activity manager package.
static final boolean DEBUG_ADD_REMOVE = DEBUG_ALL_ACTIVITIES || false;
+ static final boolean DEBUG_ANR = false;
static final boolean DEBUG_APP = DEBUG_ALL_ACTIVITIES || false;
static final boolean DEBUG_BACKUP = DEBUG_ALL || false;
static final boolean DEBUG_BROADCAST = DEBUG_ALL || false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 13c12ea..3dfa58b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -284,6 +284,7 @@
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static com.android.internal.util.XmlUtils.writeLongAttribute;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
@@ -1294,6 +1295,7 @@
boolean mAlwaysFinishActivities = false;
boolean mLenientBackgroundCheck = false;
boolean mForceResizableActivities;
+ boolean mSupportsMultiWindow;
boolean mSupportsFreeformWindowManagement;
boolean mSupportsPictureInPicture;
Rect mDefaultPinnedStackBounds;
@@ -5090,8 +5092,13 @@
int num = firstPids.size();
for (int i = 0; i < num; i++) {
synchronized (observer) {
+ if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
+ + firstPids.get(i));
+ final long sime = SystemClock.elapsedRealtime();
Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
- observer.wait(200); // Wait for write-close, give up after 200msec
+ observer.wait(1000); // Wait for write-close, give up after 1 sec
+ if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
+ + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
}
}
} catch (InterruptedException e) {
@@ -5104,7 +5111,11 @@
int[] pids = Process.getPidsForCommands(nativeProcs);
if (pids != null) {
for (int pid : pids) {
+ if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
+ final long sime = SystemClock.elapsedRealtime();
Debug.dumpNativeBacktraceToFile(pid, tracesPath);
+ if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
+ + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
}
}
}
@@ -5131,13 +5142,20 @@
numProcs++;
try {
synchronized (observer) {
+ if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
+ + stats.pid);
+ final long stime = SystemClock.elapsedRealtime();
Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
- observer.wait(200); // Wait for write-close, give up after 200msec
+ observer.wait(1000); // Wait for write-close, give up after 1 sec
+ if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
+ + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
}
} catch (InterruptedException e) {
Slog.wtf(TAG, e);
}
-
+ } else if (DEBUG_ANR) {
+ Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
+ + stats.pid);
}
}
}
@@ -5359,17 +5377,6 @@
@Override
public void killAllBackgroundProcesses() {
- killAllBackgroundProcesses(-1);
- }
-
- /**
- * Kills all background processes with targetSdkVersion below the specified
- * target SDK version.
- *
- * @param targetSdkVersion the target SDK version below which to kill
- * processes, or {@code -1} to kill all processes
- */
- private void killAllBackgroundProcesses(int targetSdkVersion) {
if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
!= PackageManager.PERMISSION_GRANTED) {
final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
@@ -5393,10 +5400,6 @@
// We don't kill persistent processes.
continue;
}
- if (targetSdkVersion > 0
- && app.info.targetSdkVersion >= targetSdkVersion) {
- continue;
- }
if (app.removed) {
procs.add(app);
} else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
@@ -5421,6 +5424,55 @@
}
}
+ /**
+ * Kills all background processes, except those matching any of the
+ * specified properties.
+ *
+ * @param minTargetSdk the target SDK version at or above which to preserve
+ * processes, or {@code -1} to ignore the target SDK
+ * @param maxProcState the process state at or below which to preserve
+ * processes, or {@code -1} to ignore the process state
+ */
+ private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
+ if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
+ != PackageManager.PERMISSION_GRANTED) {
+ final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ final ArrayList<ProcessRecord> procs = new ArrayList<>();
+ final int NP = mProcessNames.getMap().size();
+ for (int ip = 0; ip < NP; ip++) {
+ final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+ final int NA = apps.size();
+ for (int ia = 0; ia < NA; ia++) {
+ final ProcessRecord app = apps.valueAt(ia);
+ if (app.removed) {
+ procs.add(app);
+ } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
+ && (maxProcState < 0 || app.setProcState > maxProcState)) {
+ app.removed = true;
+ procs.add(app);
+ }
+ }
+ }
+
+ final int N = procs.size();
+ for (int i = 0; i < N; i++) {
+ removeProcessLocked(procs.get(i), false, true, "kill all background except");
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
@Override
public void forceStopPackage(final String packageName, int userId) {
if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
@@ -9493,7 +9545,7 @@
* docked stack. Pass {@code null} to use default bounds.
*/
@Override
- public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
+ public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
Rect initialBounds) {
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
synchronized (this) {
@@ -9502,7 +9554,8 @@
if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
+ " to createMode=" + createMode + " toTop=" + toTop);
mWindowManager.setDockedStackCreateState(createMode, initialBounds);
- mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
+ return mStackSupervisor.moveTaskToStackLocked(
+ taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
"moveTaskToDockedStack", animate);
} finally {
Binder.restoreCallingIdentity(ident);
@@ -10748,12 +10801,13 @@
return;
}
- final long token = Binder.clearCallingIdentity();
- try {
- mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mAppErrors.appNotResponding(host, null, null, false,
+ "ContentProvider not responding");
+ }
+ });
}
public final void installSystemProviders() {
@@ -12336,6 +12390,7 @@
final boolean supportsPictureInPicture =
mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
+ final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
final boolean alwaysFinishActivities =
@@ -12362,8 +12417,15 @@
mLenientBackgroundCheck = lenientBackgroundCheck;
mForceResizableActivities = forceResizable;
mWindowManager.setForceResizableTasks(mForceResizableActivities);
- mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
- mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
+ if (supportsMultiWindow || forceResizable) {
+ mSupportsMultiWindow = true;
+ mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
+ mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
+ } else {
+ mSupportsMultiWindow = false;
+ mSupportsFreeformWindowManagement = false;
+ mSupportsPictureInPicture = false;
+ }
// This happens before any activities are started, so we can
// change mConfiguration in-place.
updateConfigurationLocked(configuration, null, true);
@@ -18055,7 +18117,8 @@
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
if (isDensityChange) {
- killAllBackgroundProcesses(Build.VERSION_CODES.N);
+ killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
+ ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
}
for (int i=mLruProcesses.size()-1; i>=0; i--) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c7fc5e2..c58cad0 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2174,6 +2174,12 @@
*/
ActivityStack moveTaskToStackUncheckedLocked(
TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) {
+
+ if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) {
+ throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't "
+ + "support multi-window task=" + task + " to stackId=" + stackId);
+ }
+
final ActivityRecord r = task.getTopActivity();
final ActivityStack prevStack = task.stack;
final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r);
@@ -2184,8 +2190,6 @@
final boolean wasFront = isFrontStack(prevStack)
&& (prevStack.topRunningActivityLocked() == r);
- final int resizeMode = task.mResizeMode;
-
if (stackId == DOCKED_STACK_ID && !task.isResizeable()) {
// We don't allow moving a unresizeable task to the docked stack since the docked
// stack is used for split-screen mode and will cause things like the docked divider to
@@ -2213,18 +2217,18 @@
return stack;
}
- void moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
+ boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus,
String reason, boolean animate) {
final TaskRecord task = anyTaskForIdLocked(taskId);
if (task == null) {
Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId);
- return;
+ return false;
}
if (task.stack != null && task.stack.mStackId == stackId) {
// You are already in the right stack silly...
Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId);
- return;
+ return true;
}
if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
@@ -2293,6 +2297,8 @@
resumeFocusedStackTopActivityLocked();
showNonResizeableDockToastIfNeeded(task, preferredLaunchStackId, stackId);
+
+ return (preferredLaunchStackId == stackId);
}
boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index bcdc800..46389e2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1772,12 +1772,13 @@
return false;
}
- if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) {
- return true;
+ if (stackId != FULLSCREEN_WORKSPACE_STACK_ID
+ && (!mService.mSupportsMultiWindow || !r.isResizeableOrForced())) {
+ return false;
}
- if (stackId != FULLSCREEN_WORKSPACE_STACK_ID && !r.isResizeableOrForced()) {
- return false;
+ if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) {
+ return true;
}
if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 055935d..6cd7561 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -61,6 +61,7 @@
import java.util.concurrent.Semaphore;
import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityManagerService.MY_PID;
@@ -806,8 +807,10 @@
if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
if (r.persistent) {
firstPids.add(pid);
+ if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
} else {
lastPids.put(pid, Boolean.TRUE);
+ if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5a3639a..f2a9c2c 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -849,7 +849,7 @@
AudioSystem.setForceUse(AudioSystem.FOR_DOCK,
mDockAudioMediaEnabled ?
AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE);
- readEncodedSurroundMode(mContentResolver);
+ sendEncodedSurroundMode(mContentResolver);
}
if (mHdmiManager != null) {
synchronized (mHdmiManager) {
@@ -1023,7 +1023,7 @@
AudioSystem.setMasterMono(masterMono);
}
- private void readEncodedSurroundMode(ContentResolver cr)
+ private void sendEncodedSurroundMode(ContentResolver cr)
{
int encodedSurroundMode = Settings.Global.getInt(
cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
@@ -1102,7 +1102,7 @@
updateRingerModeAffectedStreams();
readDockAudioSettings(cr);
- readEncodedSurroundMode(cr);
+ sendEncodedSurroundMode(cr);
}
mMuteAffectedStreams = System.getIntForUser(cr,
@@ -4642,6 +4642,8 @@
private class SettingsObserver extends ContentObserver {
+ private int mEncodedSurroundMode;
+
SettingsObserver() {
super(new Handler());
mContentResolver.registerContentObserver(Settings.System.getUriFor(
@@ -4650,6 +4652,12 @@
Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
mContentResolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.MASTER_MONO), false, this);
+
+ mEncodedSurroundMode = Settings.Global.getInt(
+ mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
+ Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
+ mContentResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
}
@Override
@@ -4669,7 +4677,33 @@
}
readDockAudioSettings(mContentResolver);
updateMasterMono(mContentResolver);
- readEncodedSurroundMode(mContentResolver);
+ updateEncodedSurroundOutput();
+ }
+ }
+
+ private void updateEncodedSurroundOutput() {
+ int newSurroundMode = Settings.Global.getInt(
+ mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
+ Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
+ // Did it change?
+ if (mEncodedSurroundMode != newSurroundMode) {
+ // Send to AudioPolicyManager
+ sendEncodedSurroundMode(newSurroundMode);
+ synchronized(mConnectedDevices) {
+ // Is HDMI connected?
+ String key = makeDeviceListKey(AudioSystem.DEVICE_OUT_HDMI, "");
+ DeviceListSpec deviceSpec = mConnectedDevices.get(key);
+ if (deviceSpec != null) {
+ // Toggle HDMI to retrigger broadcast with proper formats.
+ setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_HDMI,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "",
+ "android"); // disconnect
+ setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_HDMI,
+ AudioSystem.DEVICE_STATE_AVAILABLE, "", "",
+ "android"); // reconnect
+ }
+ }
+ mEncodedSurroundMode = newSurroundMode;
}
}
}
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index f82454a..cd8eb4e 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -60,10 +60,6 @@
public static final String CAMERA_SERVICE_PROXY_BINDER_NAME = "media.camera.proxy";
- // Event arguments to use with the camera service notifySystemEvent call:
- public static final int NO_EVENT = 0; // NOOP
- public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
-
// State arguments to use with the notifyCameraState call from camera service:
public static final int CAMERA_STATE_OPEN = 0;
public static final int CAMERA_STATE_ACTIVE = 1;
@@ -224,7 +220,7 @@
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
// Some user handles have been added or removed, update mediaserver.
mEnabledCameraUsers = currentUserHandles;
- notifyMediaserverLocked(USER_SWITCHED, currentUserHandles);
+ notifyMediaserverLocked(ICameraService.EVENT_USER_SWITCHED, currentUserHandles);
}
}
@@ -244,7 +240,7 @@
if (mEnabledCameraUsers == null) {
return;
}
- if (notifyMediaserverLocked(USER_SWITCHED, mEnabledCameraUsers)) {
+ if (notifyMediaserverLocked(ICameraService.EVENT_USER_SWITCHED, mEnabledCameraUsers)) {
retries = 0;
}
}
diff --git a/services/core/java/com/android/server/connectivity/ApfFilter.java b/services/core/java/com/android/server/connectivity/ApfFilter.java
new file mode 100644
index 0000000..25c84e1
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/ApfFilter.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import static android.system.OsConstants.*;
+
+import android.net.NetworkUtils;
+import android.net.apf.ApfGenerator;
+import android.net.apf.ApfGenerator.IllegalInstructionException;
+import android.net.apf.ApfGenerator.Register;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.PacketSocketAddress;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.util.HexDump;
+import com.android.server.ConnectivityService;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.Thread;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import libcore.io.IoBridge;
+
+/**
+ * For networks that support packet filtering via APF programs, {@code ApfFilter}
+ * listens for IPv6 ICMPv6 router advertisements (RAs) and generates APF programs to
+ * filter out redundant duplicate ones.
+ *
+ * @hide
+ */
+public class ApfFilter {
+ // Thread to listen for RAs.
+ private class ReceiveThread extends Thread {
+ private final byte[] mPacket = new byte[1514];
+ private final FileDescriptor mSocket;
+ private volatile boolean mStopped;
+
+ public ReceiveThread(FileDescriptor socket) {
+ mSocket = socket;
+ }
+
+ public void halt() {
+ mStopped = true;
+ try {
+ // Interrupts the read() call the thread is blocked in.
+ IoBridge.closeAndSignalBlockedThreads(mSocket);
+ } catch (IOException ignored) {}
+ }
+
+ @Override
+ public void run() {
+ log("begin monitoring");
+ while (!mStopped) {
+ try {
+ int length = Os.read(mSocket, mPacket, 0, mPacket.length);
+ processRa(mPacket, length);
+ } catch (IOException|ErrnoException e) {
+ if (!mStopped) {
+ Log.e(TAG, "Read error", e);
+ }
+ }
+ }
+ }
+ }
+
+ private static final String TAG = "ApfFilter";
+
+ private final ConnectivityService mConnectivityService;
+ private final NetworkAgentInfo mNai;
+ private ReceiveThread mReceiveThread;
+ private String mIfaceName;
+ private long mUniqueCounter;
+
+ private ApfFilter(ConnectivityService connectivityService, NetworkAgentInfo nai) {
+ mConnectivityService = connectivityService;
+ mNai = nai;
+ maybeStartFilter();
+ }
+
+ private void log(String s) {
+ Log.d(TAG, "(" + mNai.network.netId + "): " + s);
+ }
+
+ private long getUniqueNumber() {
+ return mUniqueCounter++;
+ }
+
+ /**
+ * Attempt to start listening for RAs and, if RAs are received, generating and installing
+ * filters to ignore useless RAs.
+ */
+ private void maybeStartFilter() {
+ mIfaceName = mNai.linkProperties.getInterfaceName();
+ if (mIfaceName == null) return;
+ FileDescriptor socket;
+ try {
+ socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
+ PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IPV6,
+ NetworkInterface.getByName(mIfaceName).getIndex());
+ Os.bind(socket, addr);
+ NetworkUtils.attachRaFilter(socket, mNai.networkMisc.apfPacketFormat);
+ } catch(SocketException|ErrnoException e) {
+ Log.e(TAG, "Error filtering raw socket", e);
+ return;
+ }
+ mReceiveThread = new ReceiveThread(socket);
+ mReceiveThread.start();
+ }
+
+ /**
+ * mNai's LinkProperties may have changed, take appropriate action.
+ */
+ public void updateFilter() {
+ // If we're not listening for RAs, try starting.
+ if (mReceiveThread == null) {
+ maybeStartFilter();
+ // If interface name has changed, restart.
+ } else if (!mIfaceName.equals(mNai.linkProperties.getInterfaceName())) {
+ shutdown();
+ maybeStartFilter();
+ }
+ }
+
+ // Returns seconds since Unix Epoch.
+ private static long curTime() {
+ return System.currentTimeMillis() / 1000L;
+ }
+
+ // A class to hold information about an RA.
+ private class Ra {
+ private static final int ETH_HEADER_LEN = 14;
+
+ private static final int IPV6_HEADER_LEN = 40;
+
+ // From RFC4861:
+ private static final int ICMP6_RA_HEADER_LEN = 16;
+ private static final int ICMP6_RA_OPTION_OFFSET =
+ ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
+ private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
+ ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
+ private static final int ICMP6_RA_ROUTER_LIFETIME_LEN = 2;
+ // Prefix information option.
+ private static final int ICMP6_PREFIX_OPTION_TYPE = 3;
+ private static final int ICMP6_PREFIX_OPTION_LEN = 32;
+ private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET = 4;
+ private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN = 4;
+ private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
+ private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN = 4;
+
+ // From RFC6106: Recursive DNS Server option
+ private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
+ // From RFC6106: DNS Search List option
+ private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
+
+ // From RFC4191: Route Information option
+ private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
+ // Above three options all have the same format:
+ private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
+ private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4;
+
+ private final ByteBuffer mPacket;
+ // List of binary ranges that include the whole packet except the lifetimes.
+ // Pairs consist of offset and length.
+ private final ArrayList<Pair<Integer, Integer>> mNonLifetimes =
+ new ArrayList<Pair<Integer, Integer>>();
+ // Minimum lifetime in packet
+ long mMinLifetime;
+ // When the packet was last captured, in seconds since Unix Epoch
+ long mLastSeen;
+
+ /**
+ * Add a binary range of the packet that does not include a lifetime to mNonLifetimes.
+ * Assumes mPacket.position() is as far as we've parsed the packet.
+ * @param lastNonLifetimeStart offset within packet of where the last binary range of
+ * data not including a lifetime.
+ * @param lifetimeOffset offset from mPacket.position() to the next lifetime data.
+ * @param lifetimeLength length of the next lifetime data.
+ * @return offset within packet of where the next binary range of data not including
+ * a lifetime. This can be passed into the next invocation of this function
+ * via {@code lastNonLifetimeStart}.
+ */
+ private int addNonLifetime(int lastNonLifetimeStart, int lifetimeOffset,
+ int lifetimeLength) {
+ lifetimeOffset += mPacket.position();
+ mNonLifetimes.add(new Pair<Integer, Integer>(lastNonLifetimeStart,
+ lifetimeOffset - lastNonLifetimeStart));
+ return lifetimeOffset + lifetimeLength;
+ }
+
+ // Note that this parses RA and may throw IllegalArgumentException (from
+ // Buffer.position(int) ) or IndexOutOfBoundsException (from ByteBuffer.get(int) ) if
+ // parsing encounters something non-compliant with specifications.
+ Ra(byte[] packet, int length) {
+ mPacket = ByteBuffer.allocate(length).put(ByteBuffer.wrap(packet, 0, length));
+ mPacket.clear();
+ mLastSeen = curTime();
+
+ // Parse router lifetime
+ int lastNonLifetimeStart = addNonLifetime(0, ICMP6_RA_ROUTER_LIFETIME_OFFSET,
+ ICMP6_RA_ROUTER_LIFETIME_LEN);
+ // Parse ICMP6 options
+ mPacket.position(ICMP6_RA_OPTION_OFFSET);
+ while (mPacket.hasRemaining()) {
+ int optionType = ((int)mPacket.get(mPacket.position())) & 0xff;
+ int optionLength = (((int)mPacket.get(mPacket.position() + 1)) & 0xff) * 8;
+ switch (optionType) {
+ case ICMP6_PREFIX_OPTION_TYPE:
+ // Parse valid lifetime
+ lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
+ ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
+ ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN);
+ // Parse preferred lifetime
+ lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
+ ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
+ ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN);
+ break;
+ // These three options have the same lifetime offset and size, so process
+ // together:
+ case ICMP6_ROUTE_INFO_OPTION_TYPE:
+ case ICMP6_RDNSS_OPTION_TYPE:
+ case ICMP6_DNSSL_OPTION_TYPE:
+ // Parse lifetime
+ lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
+ ICMP6_4_BYTE_LIFETIME_OFFSET,
+ ICMP6_4_BYTE_LIFETIME_LEN);
+ break;
+ default:
+ // RFC4861 section 4.2 dictates we ignore unknown options for fowards
+ // compatibility.
+ break;
+ }
+ mPacket.position(mPacket.position() + optionLength);
+ }
+ // Mark non-lifetime bytes since last lifetime.
+ addNonLifetime(lastNonLifetimeStart, 0, 0);
+ mMinLifetime = minLifetime(packet, length);
+ }
+
+ // Ignoring lifetimes (which may change) does {@code packet} match this RA?
+ boolean matches(byte[] packet, int length) {
+ if (length != mPacket.limit()) return false;
+ ByteBuffer a = ByteBuffer.wrap(packet);
+ ByteBuffer b = mPacket;
+ for (Pair<Integer, Integer> nonLifetime : mNonLifetimes) {
+ a.clear();
+ b.clear();
+ a.position(nonLifetime.first);
+ b.position(nonLifetime.first);
+ a.limit(nonLifetime.first + nonLifetime.second);
+ b.limit(nonLifetime.first + nonLifetime.second);
+ if (a.compareTo(b) != 0) return false;
+ }
+ return true;
+ }
+
+ // What is the minimum of all lifetimes within {@code packet} in seconds?
+ // Precondition: matches(packet, length) already returned true.
+ long minLifetime(byte[] packet, int length) {
+ long minLifetime = Long.MAX_VALUE;
+ // Wrap packet in ByteBuffer so we can read big-endian values easily
+ ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
+ for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) {
+ int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second;
+ int lifetimeLength = mNonLifetimes.get(i+1).first - offset;
+ long val;
+ switch (lifetimeLength) {
+ case 2: val = byteBuffer.getShort(offset); break;
+ case 4: val = byteBuffer.getInt(offset); break;
+ default: throw new IllegalStateException("bogus lifetime size " + length);
+ }
+ // Mask to size, converting signed to unsigned
+ val &= (1L << (lifetimeLength * 8)) - 1;
+ minLifetime = Math.min(minLifetime, val);
+ }
+ return minLifetime;
+ }
+
+ // How many seconds does this RA's have to live, taking into account the fact
+ // that we might have seen it a while ago.
+ long currentLifetime() {
+ return mMinLifetime - (curTime() - mLastSeen);
+ }
+
+ boolean isExpired() {
+ return currentLifetime() < 0;
+ }
+
+ // Append a filter for this RA to {@code gen}. Jump to DROP_LABEL if it should be dropped.
+ // Jump to the next filter if packet doesn't match this RA.
+ long generateFilter(ApfGenerator gen) throws IllegalInstructionException {
+ String nextFilterLabel = "Ra" + getUniqueNumber();
+ // Skip if packet is not the right size
+ gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
+ gen.addJumpIfR0NotEquals(mPacket.limit(), nextFilterLabel);
+ int filterLifetime = (int)(currentLifetime() / FRACTION_OF_LIFETIME_TO_FILTER);
+ // Skip filter if expired
+ gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
+ gen.addJumpIfR0GreaterThan(filterLifetime, nextFilterLabel);
+ for (int i = 0; i < mNonLifetimes.size(); i++) {
+ // Generate code to match the packet bytes
+ Pair<Integer, Integer> nonLifetime = mNonLifetimes.get(i);
+ gen.addLoadImmediate(Register.R0, nonLifetime.first);
+ gen.addJumpIfBytesNotEqual(Register.R0,
+ Arrays.copyOfRange(mPacket.array(), nonLifetime.first,
+ nonLifetime.first + nonLifetime.second),
+ nextFilterLabel);
+ // Generate code to test the lifetimes haven't gone down too far
+ if ((i + 1) < mNonLifetimes.size()) {
+ Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1);
+ int offset = nonLifetime.first + nonLifetime.second;
+ int length = nextNonLifetime.first - offset;
+ switch (length) {
+ case 4: gen.addLoad32(Register.R0, offset); break;
+ case 2: gen.addLoad16(Register.R0, offset); break;
+ default: throw new IllegalStateException("bogus lifetime size " + length);
+ }
+ gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
+ }
+ }
+ gen.addJump(gen.DROP_LABEL);
+ gen.defineLabel(nextFilterLabel);
+ return filterLifetime;
+ }
+ }
+
+ // Maximum number of RAs to filter for.
+ private static final int MAX_RAS = 10;
+ private ArrayList<Ra> mRas = new ArrayList<Ra>();
+
+ // There is always some marginal benefit to updating the installed APF program when an RA is
+ // seen because we can extend the program's lifetime slightly, but there is some cost to
+ // updating the program, so don't bother unless the program is going to expire soon. This
+ // constant defines "soon" in seconds.
+ private static final long MAX_PROGRAM_LIFETIME_WORTH_REFRESHING = 30;
+ // We don't want to filter an RA for it's whole lifetime as it'll be expired by the time we ever
+ // see a refresh. Using half the lifetime might be a good idea except for the fact that
+ // packets may be dropped, so let's use 6.
+ private static final int FRACTION_OF_LIFETIME_TO_FILTER = 6;
+
+ // When did we last install a filter program? In seconds since Unix Epoch.
+ private long mLastTimeInstalledProgram;
+ // How long should the last installed filter program live for? In seconds.
+ private long mLastInstalledProgramMinLifetime;
+
+ private void installNewProgram() {
+ if (mRas.size() == 0) return;
+ final byte[] program;
+ long programMinLifetime = Long.MAX_VALUE;
+ try {
+ ApfGenerator gen = new ApfGenerator();
+ // This is guaranteed to return true because of the check in maybeInstall.
+ gen.setApfVersion(mNai.networkMisc.apfVersionSupported);
+ // Step 1: Determine how many RA filters we can fit in the program.
+ int ras = 0;
+ for (Ra ra : mRas) {
+ if (ra.isExpired()) continue;
+ ra.generateFilter(gen);
+ if (gen.programLengthOverEstimate() > mNai.networkMisc.maximumApfProgramSize) {
+ // We went too far. Use prior number of RAs in "ras".
+ break;
+ } else {
+ // Yay! this RA filter fits, increment "ras".
+ ras++;
+ }
+ }
+ // Step 2: Generate RA filters
+ gen = new ApfGenerator();
+ // This is guaranteed to return true because of the check in maybeInstall.
+ gen.setApfVersion(mNai.networkMisc.apfVersionSupported);
+ for (Ra ra : mRas) {
+ if (ras-- == 0) break;
+ if (ra.isExpired()) continue;
+ programMinLifetime = Math.min(programMinLifetime, ra.generateFilter(gen));
+ }
+ // Execution will reach the end of the program if no filters match, which will pass the
+ // packet to the AP.
+ program = gen.generate();
+ } catch (IllegalInstructionException e) {
+ Log.e(TAG, "Program failed to generate: ", e);
+ return;
+ }
+ mLastTimeInstalledProgram = curTime();
+ mLastInstalledProgramMinLifetime = programMinLifetime;
+ hexDump("Installing filter: ", program, program.length);
+ mConnectivityService.pushApfProgramToNetwork(mNai, program);
+ }
+
+ // Install a new filter program if the last installed one will die soon.
+ private void maybeInstallNewProgram() {
+ if (mRas.size() == 0) return;
+ // If the current program doesn't expire for a while, don't bother updating.
+ long expiry = mLastTimeInstalledProgram + mLastInstalledProgramMinLifetime;
+ if (expiry < curTime() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING) {
+ installNewProgram();
+ }
+ }
+
+ private void hexDump(String msg, byte[] packet, int length) {
+ log(msg + HexDump.toHexString(packet, 0, length));
+ }
+
+ private void processRa(byte[] packet, int length) {
+ hexDump("Read packet = ", packet, length);
+
+ // Have we seen this RA before?
+ for (int i = 0; i < mRas.size(); i++) {
+ Ra ra = mRas.get(i);
+ if (ra.matches(packet, length)) {
+ log("matched RA");
+ // Update lifetimes.
+ ra.mLastSeen = curTime();
+ ra.mMinLifetime = ra.minLifetime(packet, length);
+
+ // Keep mRas in LRU order so as to prioritize generating filters for recently seen
+ // RAs. LRU prioritizes this because RA filters are generated in order from mRas
+ // until the filter program exceeds the maximum filter program size allowed by the
+ // chipset, so RAs appearing earlier in mRas are more likely to make it into the
+ // filter program.
+ // TODO: consider sorting the RAs in order of increasing expiry time as well.
+ // Swap to front of array.
+ mRas.add(0, mRas.remove(i));
+
+ maybeInstallNewProgram();
+ return;
+ }
+ }
+ // Purge expired RAs.
+ for (int i = 0; i < mRas.size();) {
+ if (mRas.get(i).isExpired()) {
+ log("expired RA");
+ mRas.remove(i);
+ } else {
+ i++;
+ }
+ }
+ // TODO: figure out how to proceed when we've received more then MAX_RAS RAs.
+ if (mRas.size() >= MAX_RAS) return;
+ try {
+ log("adding RA");
+ mRas.add(new Ra(packet, length));
+ } catch (Exception e) {
+ Log.e(TAG, "Error parsing RA: " + e);
+ return;
+ }
+ installNewProgram();
+ }
+
+ /**
+ * Install an {@link ApfFilter} on {@code nai} if {@code nai} supports packet
+ * filtering using APF programs.
+ */
+ public static void maybeInstall(ConnectivityService connectivityService, NetworkAgentInfo nai) {
+ if (nai.networkMisc == null) return;
+ if (nai.networkMisc.apfVersionSupported == 0) return;
+ if (nai.networkMisc.maximumApfProgramSize < 200) {
+ Log.e(TAG, "Uselessly small APF size limit: " + nai.networkMisc.maximumApfProgramSize);
+ return;
+ }
+ // For now only support generating programs for Ethernet frames. If this restriction is
+ // lifted:
+ // 1. the program generator will need its offsets adjusted.
+ // 2. the packet filter attached to our packet socket will need its offset adjusted.
+ if (nai.networkMisc.apfPacketFormat != ARPHRD_ETHER) return;
+ if (!new ApfGenerator().setApfVersion(nai.networkMisc.apfVersionSupported)) {
+ Log.e(TAG, "Unsupported APF version: " + nai.networkMisc.apfVersionSupported);
+ return;
+ }
+ nai.apfFilter = new ApfFilter(connectivityService, nai);
+ }
+
+ public void shutdown() {
+ if (mReceiveThread != null) {
+ log("shuting down");
+ mReceiveThread.halt(); // Also closes socket.
+ mReceiveThread = null;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index a9eaeee..b390884 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,13 +16,11 @@
package com.android.server.connectivity;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-
import java.net.Inet4Address;
import android.content.Context;
import android.net.InterfaceConfiguration;
+import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgent;
@@ -34,6 +32,7 @@
import android.util.Slog;
import com.android.server.net.BaseNetworkObserver;
+import com.android.internal.util.ArrayUtils;
/**
* @hide
@@ -46,6 +45,13 @@
// This must match the interface prefix in clatd.c.
private static final String CLAT_PREFIX = "v4-";
+ // The network types we will start clatd on.
+ private static final int[] NETWORK_TYPES = {
+ ConnectivityManager.TYPE_MOBILE,
+ ConnectivityManager.TYPE_WIFI,
+ ConnectivityManager.TYPE_ETHERNET,
+ };
+
private final INetworkManagementService mNMService;
// ConnectivityService Handler for LinkProperties updates.
@@ -90,7 +96,7 @@
(nai.linkProperties != null) ? nai.linkProperties.hasIPv4Address() : false;
// Only support clat on mobile and wifi for now, because these are the only IPv6-only
// networks we can connect to.
- return connected && !hasIPv4Address && (netType == TYPE_MOBILE || netType == TYPE_WIFI);
+ return connected && !hasIPv4Address && ArrayUtils.contains(NETWORK_TYPES, netType);
}
/**
@@ -221,7 +227,7 @@
}
private void maybeSetIpv6NdOffload(String iface, boolean on) {
- if (mNetwork.networkInfo.getType() != TYPE_WIFI) {
+ if (mNetwork.networkInfo.getType() != ConnectivityManager.TYPE_WIFI) {
return;
}
try {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index c5d38cb..b4c71c1 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -32,6 +32,7 @@
import com.android.internal.util.AsyncChannel;
import com.android.server.ConnectivityService;
import com.android.server.connectivity.NetworkMonitor;
+import com.android.server.connectivity.ApfFilter;
import java.util.ArrayList;
import java.util.Comparator;
@@ -163,6 +164,8 @@
// Used by ConnectivityService to keep track of 464xlat.
public Nat464Xlat clatd;
+ public ApfFilter apfFilter;
+
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
NetworkMisc misc, NetworkRequest defaultRequest, ConnectivityService connService) {
@@ -175,6 +178,7 @@
currentScore = score;
networkMonitor = connService.createNetworkMonitor(context, handler, this, defaultRequest);
networkMisc = misc;
+ apfFilter.maybeInstall(connService, this);
}
/**
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index ed68abe..e08fad4 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1559,11 +1559,11 @@
* called from native code to update SV info
*/
private void reportSvStatus() {
- int svCount = native_read_sv_status(mSvidWithFlags, mSnrs, mSvElevations, mSvAzimuths);
+ int svCount = native_read_sv_status(mSvidWithFlags, mCn0s, mSvElevations, mSvAzimuths);
mListenerHelper.onSvStatusChanged(
svCount,
mSvidWithFlags,
- mSnrs,
+ mCn0s,
mSvElevations,
mSvAzimuths);
@@ -1578,7 +1578,7 @@
}
if (VERBOSE) {
Log.v(TAG, "svid: " + (mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
- " snr: " + mSnrs[i]/10 +
+ " cn0: " + mCn0s[i]/10 +
" elev: " + mSvElevations[i] +
" azimuth: " + mSvAzimuths[i] +
((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
@@ -2402,7 +2402,7 @@
// preallocated arrays, to avoid memory allocation in reportStatus()
private int mSvidWithFlags[] = new int[MAX_SVS];
- private float mSnrs[] = new float[MAX_SVS];
+ private float mCn0s[] = new float[MAX_SVS];
private float mSvElevations[] = new float[MAX_SVS];
private float mSvAzimuths[] = new float[MAX_SVS];
private int mSvCount;
@@ -2424,7 +2424,7 @@
private native void native_delete_aiding_data(int flags);
// returns number of SVs
// mask[0] is ephemeris mask and mask[1] is almanac mask
- private native int native_read_sv_status(int[] prnWithFlags, float[] snrs, float[] elevations,
+ private native int native_read_sv_status(int[] prnWithFlags, float[] cn0s, float[] elevations,
float[] azimuths);
private native int native_read_nmea(byte[] buffer, int bufferSize);
private native void native_inject_location(double latitude, double longitude, float accuracy);
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index d9e8e91..734a8d4 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -72,7 +72,7 @@
status = GnssMeasurementsEvent.STATUS_NOT_SUPPORTED;
break;
case RESULT_GPS_LOCATION_DISABLED:
- status = GnssMeasurementsEvent.STATUS_GPS_LOCATION_DISABLED;
+ status = GnssMeasurementsEvent.STATUS_GNSS_LOCATION_DISABLED;
break;
case RESULT_UNKNOWN:
return null;
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 57bce4b..fdef31f 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -73,7 +73,8 @@
status = GnssNavigationMessageEvent.STATUS_NOT_SUPPORTED;
break;
case RESULT_GPS_LOCATION_DISABLED:
- status = GnssNavigationMessageEvent.STATUS_GPS_LOCATION_DISABLED;
+ status = GnssNavigationMessageEvent
+ .STATUS_GNSS_LOCATION_DISABLED;
break;
case RESULT_UNKNOWN:
return null;
diff --git a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
index 0b3111c..d471e45 100644
--- a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
+++ b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
@@ -75,7 +75,7 @@
public void onSvStatusChanged(
final int svCount,
final int[] prnWithFlags,
- final float[] snrs,
+ final float[] cn0s,
final float[] elevations,
final float[] azimuths) {
Operation operation = new Operation() {
@@ -84,7 +84,7 @@
listener.onSvStatusChanged(
svCount,
prnWithFlags,
- snrs,
+ cn0s,
elevations,
azimuths);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e8d27db..3855579 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1320,7 +1320,7 @@
@Override
public int getImportance(String pkg, int uid) {
- checkCallerIsSystem();
+ enforceSystemOrSystemUI("Caller not system or systemui");
return mRankingHelper.getImportance(pkg, uid);
}
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 94b3b2d..3d2a355 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -180,10 +180,5 @@
return dexoptFlags | DEXOPT_OTA;
}
- @Override
- protected void recordSuccessfulDexopt(Package pkg, String instructionSet) {
- // Never record the dexopt, as it's in the B partition.
- }
-
}
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index a084d86..c9613b4 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -113,15 +113,6 @@
}
/**
- * Determine whether the package should be skipped for the given instruction set. A return
- * value of true means the package will be skipped. A return value of false means that the
- * package will be further investigated, and potentially compiled.
- */
- protected boolean shouldSkipBasedOnISA(PackageParser.Package pkg, String instructionSet) {
- return pkg.mDexOptPerformed.contains(instructionSet);
- }
-
- /**
* Adjust the given dexopt-needed value. Can be overridden to influence the decision to
* optimize or not (and in what way).
*/
@@ -136,13 +127,6 @@
return dexoptFlags;
}
- /**
- * Update the package status after a successful compilation.
- */
- protected void recordSuccessfulDexopt(PackageParser.Package pkg, String instructionSet) {
- pkg.mDexOptPerformed.add(instructionSet);
- }
-
private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
boolean useProfiles, boolean extractOnly) {
final String[] instructionSets = targetInstructionSets != null ?
@@ -159,11 +143,6 @@
boolean performedDexOpt = false;
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
- if (!useProfiles && shouldSkipBasedOnISA(pkg, dexCodeInstructionSet)) {
- // Skip only if we do not use profiles since they might trigger a recompilation.
- continue;
- }
-
for (String path : paths) {
if (useProfiles && isUsedByOtherApps(path)) {
// We cannot use profile guided compilation if the apk was used by another app.
@@ -172,35 +151,44 @@
int dexoptNeeded;
try {
- dexoptNeeded = DexFile.getDexOptNeeded(path, pkg.packageName,
- dexCodeInstructionSet, /* defer */false);
+ int compilationTypeMask = 0;
+ if (extractOnly) {
+ // For extract only, any type of compilation is good.
+ compilationTypeMask = DexFile.COMPILATION_TYPE_FULL
+ | DexFile.COMPILATION_TYPE_PROFILE_GUIDE
+ | DexFile.COMPILATION_TYPE_EXTRACT_ONLY;
+ } else {
+ // Branch taken for profile guide and full compilation.
+ // Profile guide compilation should only recompile a previous
+ // profile compiled/extract only file and should not be attempted if the
+ // apk is already fully compiled. So test against a full compilation type.
+ compilationTypeMask = DexFile.COMPILATION_TYPE_FULL;
+ }
+ dexoptNeeded = DexFile.getDexOptNeeded(path,
+ dexCodeInstructionSet, compilationTypeMask);
} catch (IOException ioe) {
Slog.w(TAG, "IOException reading apk: " + path, ioe);
return DEX_OPT_FAILED;
}
dexoptNeeded = adjustDexoptNeeded(dexoptNeeded);
- if (dexoptNeeded == DexFile.NO_DEXOPT_NEEDED) {
- if (useProfiles) {
- // Profiles may trigger re-compilation. The final decision is taken in
- // installd.
- dexoptNeeded = DexFile.DEX2OAT_NEEDED;
- } else {
- // No dexopt needed and we don't use profiles. Nothing to do.
- continue;
- }
- }
final String dexoptType;
String oatDir = null;
- if (dexoptNeeded == DexFile.DEX2OAT_NEEDED) {
- dexoptType = "dex2oat";
- oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
- } else if (dexoptNeeded == DexFile.PATCHOAT_NEEDED) {
- dexoptType = "patchoat";
- } else if (dexoptNeeded == DexFile.SELF_PATCHOAT_NEEDED) {
- dexoptType = "self patchoat";
- } else {
- throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
+ switch (dexoptNeeded) {
+ case DexFile.NO_DEXOPT_NEEDED:
+ continue;
+ case DexFile.DEX2OAT_NEEDED:
+ dexoptType = "dex2oat";
+ oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
+ break;
+ case DexFile.PATCHOAT_NEEDED:
+ dexoptType = "patchoat";
+ break;
+ case DexFile.SELF_PATCHOAT_NEEDED:
+ dexoptType = "self patchoat";
+ break;
+ default:
+ throw new IllegalStateException("Invalid dexopt:" + dexoptNeeded);
}
@@ -226,15 +214,6 @@
Slog.w(TAG, "Failed to dexopt", e);
}
}
-
- if (!extractOnly) {
- // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
- // either have either succeeded dexopt, or have had getDexOptNeeded tell us
- // it isn't required. We therefore mark that this package doesn't need dexopt unless
- // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
- // it.
- recordSuccessfulDexopt(pkg, dexCodeInstructionSet);
- }
}
// If we've gotten here, we're sure that no error occurred and that we haven't
@@ -317,12 +296,6 @@
}
@Override
- protected boolean shouldSkipBasedOnISA(Package pkg, String instructionSet) {
- // Forced compilation, never skip.
- return false;
- }
-
- @Override
protected int adjustDexoptNeeded(int dexoptNeeded) {
// Ensure compilation, no matter the current state.
// TODO: The return value is wrong when patchoat is needed.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index bafcb64..86f2f97 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -639,9 +639,6 @@
// List of packages names to keep cached, even if they are uninstalled for all users
private List<String> mKeepUninstalledPackages;
- private boolean mUseJitProfiles =
- SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
-
private static class IFVerificationParams {
PackageParser.Package pkg;
boolean replacing;
@@ -2161,10 +2158,12 @@
}
try {
- int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
+ // Shared libraries do not have profiles so we perform a full
+ // AOT compilation (if needed).
+ int dexoptNeeded = DexFile.getDexOptNeeded(
+ lib, dexCodeInstructionSet,
+ DexFile.COMPILATION_TYPE_FULL);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
- // Shared libraries do not have profiles so we perform a full
- // AOT compilation.
mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
StorageManager.UUID_PRIVATE_INTERNAL,
@@ -4234,7 +4233,8 @@
// TODO: remove these terrible hacks
if (actionName.startsWith("android.net.netmon.lingerExpired")
|| actionName.startsWith("com.android.server.sip.SipWakeupTimer")
- || actionName.startsWith("com.android.internal.telephony.data-reconnect")) {
+ || actionName.startsWith("com.android.internal.telephony.data-reconnect")
+ || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
return true;
}
}
@@ -6837,7 +6837,7 @@
// Extract pacakges only if profile-guided compilation is enabled because
// otherwise BackgroundDexOptService will not dexopt them later.
- if (!mUseJitProfiles || !isUpgrade()) {
+ if (!isUpgrade()) {
return;
}
@@ -6919,10 +6919,6 @@
targetInstructionSet = instructionSet != null ? instructionSet :
getPrimaryInstructionSet(p.applicationInfo);
- if (!force && !useProfiles && p.mDexOptPerformed.contains(targetInstructionSet)) {
- // Skip only if we do not use profiles since they might trigger a recompilation.
- return false;
- }
}
long callingId = Binder.clearCallingIdentity();
try {
@@ -13852,21 +13848,17 @@
return;
}
- // Extract package to save the VM unzipping the APK in memory during
- // launch. Only do this if profile-guided compilation is enabled because
- // otherwise BackgroundDexOptService will not dexopt the package later.
- if (mUseJitProfiles) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
- // Do not run PackageDexOptimizer through the local performDexOpt
- // method because `pkg` is not in `mPackages` yet.
- int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
- false /* useProfiles */, true /* extractOnly */);
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
- String msg = "Extracking package failed for " + pkgName;
- res.setError(INSTALL_FAILED_DEXOPT, msg);
- return;
- }
+
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
+ // Do not run PackageDexOptimizer through the local performDexOpt
+ // method because `pkg` is not in `mPackages` yet.
+ int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
+ false /* useProfiles */, true /* extractOnly */);
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
+ String msg = "Extracking package failed for " + pkgName;
+ res.setError(INSTALL_FAILED_DEXOPT, msg);
+ return;
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index f901f95..6218c4e 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -60,6 +60,7 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
import com.android.server.EventLogTags;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
@@ -254,6 +255,9 @@
// True if boot completed occurred. We keep the screen on until this happens.
private boolean mBootCompleted;
+ // Runnables that should be triggered on boot completed
+ private Runnable[] mBootCompletedRunnables;
+
// True if auto-suspend mode is enabled.
// Refer to autosuspend.h.
private boolean mHalAutoSuspendModeEnabled;
@@ -525,6 +529,14 @@
userActivityNoUpdateLocked(
now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
updatePowerStateLocked();
+
+ if (!ArrayUtils.isEmpty(mBootCompletedRunnables)) {
+ Slog.d(TAG, "Posting " + mBootCompletedRunnables.length + " delayed runnables");
+ for (Runnable r : mBootCompletedRunnables) {
+ BackgroundThread.getHandler().post(r);
+ }
+ }
+ mBootCompletedRunnables = null;
}
}
}
@@ -750,6 +762,16 @@
mDirty |= DIRTY_SETTINGS;
}
+ private void postAfterBootCompleted(Runnable r) {
+ if (mBootCompleted) {
+ BackgroundThread.getHandler().post(r);
+ } else {
+ Slog.d(TAG, "Delaying runnable until system is booted");
+ mBootCompletedRunnables = ArrayUtils.appendElement(Runnable.class,
+ mBootCompletedRunnables, r);
+ }
+ }
+
void updateLowPowerModeLocked() {
if (mIsPowered && mLowPowerModeSetting) {
if (DEBUG_SPEW) {
@@ -767,7 +789,7 @@
if (mLowPowerModeEnabled != lowPowerModeEnabled) {
mLowPowerModeEnabled = lowPowerModeEnabled;
powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);
- BackgroundThread.getHandler().post(new Runnable() {
+ postAfterBootCompleted(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index ba0d340..a0a971a 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -882,6 +882,9 @@
wallpaper = mLockWallpaperMap.get(userId);
if (wallpaper == null) {
// It's already gone; we're done.
+ if (DEBUG) {
+ Slog.i(TAG, "Lock wallpaper already cleared");
+ }
return;
}
} else {
@@ -902,14 +905,19 @@
wallpaper.wallpaperFile.delete();
wallpaper.cropFile.delete();
if (which == FLAG_SET_LOCK) {
+ mLockWallpaperMap.remove(userId);
final IWallpaperManagerCallback cb = mKeyguardListener;
if (cb != null) {
+ if (DEBUG) {
+ Slog.i(TAG, "Notifying keyguard of lock wallpaper clear");
+ }
try {
cb.onWallpaperChanged();
} catch (RemoteException e) {
// Oh well it went away; no big deal
}
}
+ saveSettingsLocked(userId);
return;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 40b6b50..e8f1b5d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1902,6 +1902,12 @@
mWinAnimator.hide("saved surface");
mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE;
setHasSurface(false);
+ // The client should have disconnected at this point, but if it doesn't,
+ // we need to make sure it's disconnected. Otherwise when we reuse the surface
+ // the client can't reconnect to the buffer queue, and rendering will fail.
+ if (mWinAnimator.mSurfaceController != null) {
+ mWinAnimator.mSurfaceController.disconnectInTransaction();
+ }
} else {
mWinAnimator.destroySurfaceLocked();
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 2972a24..2cdf471 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -152,6 +152,20 @@
}
}
+ void disconnectInTransaction() {
+ if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+ Slog.i(TAG, "Disconnecting client: " + this);
+ }
+
+ try {
+ if (mSurfaceControl != null) {
+ mSurfaceControl.disconnect();
+ }
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Error disconnecting surface in: " + this, e);
+ }
+ }
+
void setCropInTransaction(Rect clipRect, boolean recoveringMemory) {
if (SHOW_TRANSACTIONS) logSurface(
"CROP " + clipRect.toShortString(), null);
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index c97323c..aa14fff 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -140,7 +140,7 @@
ALOGD("Unknown constellation type with Svid = %d.", info.svid);
info.constellation = GNSS_CONSTELLATION_UNKNOWN;
}
- info.snr = sv_status->sv_list[i].snr;
+ info.c_n0_dbhz = sv_status->sv_list[i].snr;
info.elevation = sv_status->sv_list[i].elevation;
info.azimuth = sv_status->sv_list[i].azimuth;
info.flags = GNSS_SV_FLAGS_NONE;
@@ -698,12 +698,12 @@
}
static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
- jintArray svidWithFlagArray, jfloatArray snrArray, jfloatArray elevArray,
+ jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
jfloatArray azumArray)
{
// this should only be called from within a call to reportSvStatus
jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
- jfloat* snrs = env->GetFloatArrayElements(snrArray, 0);
+ jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
@@ -713,13 +713,13 @@
svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
(info.constellation << CONSTELLATION_TYPE_SHIFT_WIDTH) |
info.flags;
- snrs[i] = info.snr;
+ cn0s[i] = info.c_n0_dbhz;
elev[i] = info.elevation;
azim[i] = info.azimuth;
}
env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
- env->ReleaseFloatArrayElements(snrArray, snrs, 0);
+ env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
env->ReleaseFloatArrayElements(elevArray, elev, 0);
env->ReleaseFloatArrayElements(azumArray, azim, 0);
return (jint) sGnssSvListSize;
@@ -1095,7 +1095,9 @@
JavaObject object(env, "android/location/GnssClock");
GpsClockFlags flags = clock->flags;
- SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
+ SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND,
+ LeapSecond,
+ static_cast<int32_t>(clock->leap_second));
// GnssClock only supports the more effective HW_CLOCK type, so type
// handling and documentation complexity has been removed. To convert the
@@ -1122,18 +1124,18 @@
break;
}
- SET(TimeInNs, clock->time_ns);
+ SET(TimeNanos, clock->time_ns);
SET_IF(GNSS_CLOCK_HAS_TIME_UNCERTAINTY,
- TimeUncertaintyInNs,
+ TimeUncertaintyNanos,
clock->time_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
- SET_IF(GNSS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
+ SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, clock->full_bias_ns);
+ SET_IF(GNSS_CLOCK_HAS_BIAS, BiasNanos, clock->bias_ns);
SET_IF(GNSS_CLOCK_HAS_BIAS_UNCERTAINTY,
- BiasUncertaintyInNs,
+ BiasUncertaintyNanos,
clock->bias_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
+ SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps);
SET_IF(GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY,
- DriftUncertaintyInNsPerSec,
+ DriftUncertaintyNanosPerSecond,
clock->drift_uncertainty_nsps);
return object.get();
@@ -1143,20 +1145,21 @@
JavaObject object(env, "android/location/GnssClock");
GpsClockFlags flags = clock->flags;
- SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
- SET(Type, static_cast<uint8_t>(GPS_CLOCK_TYPE_LOCAL_HW_TIME));
- SET(TimeInNs, clock->time_ns);
+ SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND,
+ LeapSecond,
+ static_cast<int32_t>(clock->leap_second));
+ SET(TimeNanos, clock->time_ns);
SET_IF(GNSS_CLOCK_HAS_TIME_UNCERTAINTY,
- TimeUncertaintyInNs,
+ TimeUncertaintyNanos,
clock->time_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
- SET_IF(GNSS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
+ SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, clock->full_bias_ns);
+ SET_IF(GNSS_CLOCK_HAS_BIAS, BiasNanos, clock->bias_ns);
SET_IF(GNSS_CLOCK_HAS_BIAS_UNCERTAINTY,
- BiasUncertaintyInNs,
+ BiasUncertaintyNanos,
clock->bias_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
+ SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps);
SET_IF(GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY,
- DriftUncertaintyInNsPerSec,
+ DriftUncertaintyNanosPerSecond,
clock->drift_uncertainty_nsps);
SET(HardwareClockDiscontinuityCount, clock->hw_clock_discontinuity_count);
@@ -1168,41 +1171,30 @@
GpsMeasurement* measurement) {
JavaObject object(env, "android/location/GnssMeasurement");
GpsMeasurementFlags flags = measurement->flags;
- SET(Svid, static_cast<int16_t>(measurement->prn));
+ SET(Svid, static_cast<int32_t>(measurement->prn));
if (measurement->prn >= 1 || measurement->prn <= 32) {
- SET(ConstellationType, static_cast<uint8_t>(GNSS_CONSTELLATION_GPS));
+ SET(ConstellationType, static_cast<int32_t>(GNSS_CONSTELLATION_GPS));
} else {
ALOGD("Unknown constellation type with Svid = %d.", measurement->prn);
SET(ConstellationType,
- static_cast<uint8_t>(GNSS_CONSTELLATION_UNKNOWN));
+ static_cast<int32_t>(GNSS_CONSTELLATION_UNKNOWN));
}
- SET(TimeOffsetInNs, measurement->time_offset_ns);
- SET(State, measurement->state);
- SET(ReceivedSvTimeInNs, measurement->received_gps_tow_ns);
- SET(ReceivedSvTimeUncertaintyInNs,
+ SET(TimeOffsetNanos, measurement->time_offset_ns);
+ SET(State, static_cast<int32_t>(measurement->state));
+ SET(ReceivedSvTimeNanos, measurement->received_gps_tow_ns);
+ SET(ReceivedSvTimeUncertaintyNanos,
measurement->received_gps_tow_uncertainty_ns);
- SET(Cn0InDbHz, measurement->c_n0_dbhz);
- SET(PseudorangeRateInMetersPerSec, measurement->pseudorange_rate_mps);
- SET(PseudorangeRateUncertaintyInMetersPerSec,
+ SET(Cn0DbHz, measurement->c_n0_dbhz);
+ SET(PseudorangeRateMetersPerSecond, measurement->pseudorange_rate_mps);
+ SET(PseudorangeRateUncertaintyMetersPerSecond,
measurement->pseudorange_rate_uncertainty_mps);
- SET(AccumulatedDeltaRangeState, measurement->accumulated_delta_range_state);
- SET(AccumulatedDeltaRangeInMeters, measurement->accumulated_delta_range_m);
- SET(AccumulatedDeltaRangeUncertaintyInMeters,
+ SET(AccumulatedDeltaRangeState,
+ static_cast<int32_t>(measurement->accumulated_delta_range_state));
+ SET(AccumulatedDeltaRangeMeters, measurement->accumulated_delta_range_m);
+ SET(AccumulatedDeltaRangeUncertaintyMeters,
measurement->accumulated_delta_range_uncertainty_m);
- SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE,
- PseudorangeInMeters,
- measurement->pseudorange_m);
- SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
- PseudorangeUncertaintyInMeters,
- measurement->pseudorange_uncertainty_m);
- SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE,
- CodePhaseInChips,
- measurement->code_phase_chips);
- SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
- CodePhaseUncertaintyInChips,
- measurement->code_phase_uncertainty_chips);
SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
- CarrierFrequencyInHz,
+ CarrierFrequencyHz,
measurement->carrier_frequency_hz);
SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES,
CarrierCycles,
@@ -1213,33 +1205,8 @@
SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
CarrierPhaseUncertainty,
measurement->carrier_phase_uncertainty);
- SET(LossOfLock, measurement->loss_of_lock);
- SET_IF(GNSS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
- SET_IF(GNSS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
- TimeFromLastBitInMs,
- measurement->time_from_last_bit_ms);
- SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT,
- DopplerShiftInHz,
- measurement->doppler_shift_hz);
- SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
- DopplerShiftUncertaintyInHz,
- measurement->doppler_shift_uncertainty_hz);
SET(MultipathIndicator, measurement->multipath_indicator);
SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
- SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION,
- ElevationInDeg,
- measurement->elevation_deg);
- SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
- ElevationUncertaintyInDeg,
- measurement->elevation_uncertainty_deg);
- SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH,
- AzimuthInDeg,
- measurement->azimuth_deg);
- SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
- AzimuthUncertaintyInDeg,
- measurement->azimuth_uncertainty_deg);
- SET(UsedInFix,
- (flags & GNSS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
return object.get();
}
@@ -1250,34 +1217,23 @@
GpsMeasurementFlags flags = measurement->flags;
SET(Svid, measurement->svid);
- SET(ConstellationType, measurement->constellation);
- SET(TimeOffsetInNs, measurement->time_offset_ns);
- SET(State, measurement->state);
- SET(ReceivedSvTimeInNs, measurement->received_sv_time_in_ns);
- SET(ReceivedSvTimeUncertaintyInNs,
+ SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
+ SET(TimeOffsetNanos, measurement->time_offset_ns);
+ SET(State, static_cast<int32_t>(measurement->state));
+ SET(ReceivedSvTimeNanos, measurement->received_sv_time_in_ns);
+ SET(ReceivedSvTimeUncertaintyNanos,
measurement->received_sv_time_uncertainty_in_ns);
- SET(Cn0InDbHz, measurement->c_n0_dbhz);
- SET(PseudorangeRateInMetersPerSec, measurement->pseudorange_rate_mps);
- SET(PseudorangeRateUncertaintyInMetersPerSec,
+ SET(Cn0DbHz, measurement->c_n0_dbhz);
+ SET(PseudorangeRateMetersPerSecond, measurement->pseudorange_rate_mps);
+ SET(PseudorangeRateUncertaintyMetersPerSecond,
measurement->pseudorange_rate_uncertainty_mps);
- SET(AccumulatedDeltaRangeState, measurement->accumulated_delta_range_state);
- SET(AccumulatedDeltaRangeInMeters, measurement->accumulated_delta_range_m);
- SET(AccumulatedDeltaRangeUncertaintyInMeters,
+ SET(AccumulatedDeltaRangeState,
+ static_cast<int32_t>(measurement->accumulated_delta_range_state));
+ SET(AccumulatedDeltaRangeMeters, measurement->accumulated_delta_range_m);
+ SET(AccumulatedDeltaRangeUncertaintyMeters,
measurement->accumulated_delta_range_uncertainty_m);
- SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE,
- PseudorangeInMeters,
- measurement->pseudorange_m);
- SET_IF(GNSS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
- PseudorangeUncertaintyInMeters,
- measurement->pseudorange_uncertainty_m);
- SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE,
- CodePhaseInChips,
- measurement->code_phase_chips);
- SET_IF(GNSS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
- CodePhaseUncertaintyInChips,
- measurement->code_phase_uncertainty_chips);
SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
- CarrierFrequencyInHz,
+ CarrierFrequencyHz,
measurement->carrier_frequency_hz);
SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES,
CarrierCycles,
@@ -1288,32 +1244,8 @@
SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
CarrierPhaseUncertainty,
measurement->carrier_phase_uncertainty);
- SET_IF(GNSS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
- SET_IF(GNSS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
- TimeFromLastBitInMs,
- measurement->time_from_last_bit_ms);
- SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT,
- DopplerShiftInHz,
- measurement->doppler_shift_hz);
- SET_IF(GNSS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
- DopplerShiftUncertaintyInHz,
- measurement->doppler_shift_uncertainty_hz);
SET(MultipathIndicator, measurement->multipath_indicator);
SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
- SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION,
- ElevationInDeg,
- measurement->elevation_deg);
- SET_IF(GNSS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
- ElevationUncertaintyInDeg,
- measurement->elevation_uncertainty_deg);
- SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH,
- AzimuthInDeg,
- measurement->azimuth_deg);
- SET_IF(GNSS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
- AzimuthUncertaintyInDeg,
- measurement->azimuth_uncertainty_deg);
- SET(UsedInFix,
- (flags & GNSS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
return object.get();
}
@@ -1493,21 +1425,22 @@
return NULL;
}
JavaObject object(env, "android/location/GnssNavigationMessage");
- SET(Svid, static_cast<int16_t>(message->prn));
+ SET(Svid, static_cast<int32_t>(message->prn));
if (message->prn >=1 && message->prn <= 32) {
- SET(ConstellationType, static_cast<uint8_t>(GNSS_CONSTELLATION_GPS));
+ SET(ConstellationType, static_cast<int32_t>(GNSS_CONSTELLATION_GPS));
// Legacy driver doesn't set the higher byte to constellation type
// correctly. Set the higher byte to 'GPS'.
- SET(Type, static_cast<int16_t>(message->type | 0x0100));
+ SET(Type, static_cast<int32_t>(message->type | 0x0100));
} else {
ALOGD("Unknown constellation type with Svid = %d.", message->prn);
SET(ConstellationType,
- static_cast<uint8_t>(GNSS_CONSTELLATION_UNKNOWN));
- SET(Type, static_cast<int16_t>(GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN));
+ static_cast<int32_t>(GNSS_CONSTELLATION_UNKNOWN));
+ SET(Type, static_cast<int32_t>(GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN));
}
- SET(MessageId, message->message_id);
- SET(SubmessageId, message->submessage_id);
+ SET(MessageId, static_cast<int32_t>(message->message_id));
+ SET(SubmessageId, static_cast<int32_t>(message->submessage_id));
object.callSetter("setData", data, dataLength);
+ SET(Status, static_cast<int32_t>(message->status));
return object.get();
}
@@ -1520,11 +1453,12 @@
return NULL;
}
JavaObject object(env, "android/location/GnssNavigationMessage");
- SET(Type, message->type);
- SET(Svid, message->svid);
- SET(MessageId, message->message_id);
- SET(SubmessageId, message->submessage_id);
+ SET(Type, static_cast<int32_t>(message->type));
+ SET(Svid, static_cast<int32_t>(message->svid));
+ SET(MessageId, static_cast<int32_t>(message->message_id));
+ SET(SubmessageId, static_cast<int32_t>(message->submessage_id));
object.callSetter("setData", data, dataLength);
+ SET(Status, static_cast<int32_t>(message->status));
return object.get();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0252ea4..1490109 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5530,7 +5530,8 @@
Preconditions.checkNotNull(packageName, "packageName is null");
final int callingUid = mInjector.binderGetCallingUid();
try {
- int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, 0);
+ int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
+ UserHandle.getUserId(callingUid));
if (uid != callingUid) {
throw new SecurityException("Invalid packageName");
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0ece6aa..9aa2b94 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1036,6 +1036,7 @@
traceBeginAndSlog("StartNetworkTimeUpdateService");
try {
networkTimeUpdater = new NetworkTimeUpdateService(context);
+ ServiceManager.addService("network_time_update_service", networkTimeUpdater);
} catch (Throwable e) {
reportWtf("starting NetworkTimeUpdate service", e);
}
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index c34d4a9..e851c8d 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -518,6 +518,14 @@
throw new UnsupportedOperationException();
}
+ /** @hide */
+ @Override
+ public Drawable getManagedUserBadgedDrawable(Drawable drawable, Rect badgeLocation,
+ int badgeDensity) {
+ throw new UnsupportedOperationException();
+ }
+
+
@Override
public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
throw new UnsupportedOperationException();
diff --git a/tests/HwAccelerationTest/res/drawable/default_wallpaper.png b/tests/HwAccelerationTest/res/drawable/default_wallpaper.png
index 91ad252..187a6c0 100644
--- a/tests/HwAccelerationTest/res/drawable/default_wallpaper.png
+++ b/tests/HwAccelerationTest/res/drawable/default_wallpaper.png
Binary files differ
diff --git a/tests/HwAccelerationTest/res/layout/projection_clipping.xml b/tests/HwAccelerationTest/res/layout/projection_clipping.xml
index 1f2b939..1ea9f9c 100644
--- a/tests/HwAccelerationTest/res/layout/projection_clipping.xml
+++ b/tests/HwAccelerationTest/res/layout/projection_clipping.xml
@@ -3,24 +3,32 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <FrameLayout
+ <ScrollView
+ android:orientation="vertical"
android:translationX="50dp"
android:translationY="50dp"
android:elevation="30dp"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@drawable/round_rect_background">
- <View
- android:id="@+id/clickable1"
- android:layout_width="100dp"
- android:layout_height="100dp"
- android:background="?android:attr/selectableItemBackgroundBorderless"/>
- <View
- android:id="@+id/clickable2"
- android:translationX="50dp"
- android:translationY="10dp"
- android:layout_width="150dp"
- android:layout_height="100dp"
- android:background="?android:attr/selectableItemBackgroundBorderless"/>
- </FrameLayout>
+ <FrameLayout
+ android:layout_width="200dp"
+ android:layout_height="wrap_content">
+ <View
+ android:layout_width="200dp"
+ android:layout_height="2000dp"/>
+ <View
+ android:id="@+id/clickable1"
+ android:layout_width="100dp"
+ android:layout_height="100dp"
+ android:background="?android:attr/selectableItemBackgroundBorderless"/>
+ <View
+ android:id="@+id/clickable2"
+ android:translationX="50dp"
+ android:translationY="10dp"
+ android:layout_width="150dp"
+ android:layout_height="100dp"
+ android:background="?android:attr/selectableItemBackgroundBorderless"/>
+ </FrameLayout>
+ </ScrollView>
</LinearLayout>
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 2a3f143..0da1bb1 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -93,11 +93,7 @@
.setSmallIcon(R.drawable.icon2)
.setContentTitle("Min priority")
.setLights(0xff0000ff, 1, 0)
- .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
- .setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
- getPackageName() + "/raw/ringer"))
.setPriority(Notification.PRIORITY_MIN)
- .setFullScreenIntent(makeIntent2(), false)
.build();
mNM.notify(7000, n);
}
@@ -125,11 +121,7 @@
.setSmallIcon(R.drawable.icon2)
.setContentTitle("Low priority")
.setLights(0xff0000ff, 1, 0)
- .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
- .setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
- getPackageName() + "/raw/ringer"))
.setPriority(Notification.PRIORITY_LOW)
- .setFullScreenIntent(makeIntent2(), false)
.build();
mNM.notify(7002, n);
}
@@ -141,11 +133,7 @@
.setSmallIcon(R.drawable.icon2)
.setContentTitle("Default priority")
.setLights(0xff0000ff, 1, 0)
- .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
- .setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
- getPackageName() + "/raw/ringer"))
.setPriority(Notification.PRIORITY_DEFAULT)
- .setFullScreenIntent(makeIntent2(), false)
.build();
mNM.notify(7004, n);
}
@@ -161,7 +149,6 @@
.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
getPackageName() + "/raw/ringer"))
.setPriority(Notification.PRIORITY_HIGH)
- .setFullScreenIntent(makeIntent2(), false)
.build();
mNM.notify(7006, n);
}
@@ -179,7 +166,7 @@
.setPriority(Notification.PRIORITY_MAX)
.setFullScreenIntent(makeIntent2(), false)
.build();
- mNM.notify(7008, n);
+ mNM.notify(7007, n);
}
},
new Test("Max priority with delay") {
@@ -202,6 +189,64 @@
mNM.notify(7008, n);
}
},
+ new Test("public notification") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("public notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .build();
+ mNM.notify(7009, n);
+ }
+ },
+ new Test("private notification, no public") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("private only notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PRIVATE)
+ .build();
+ mNM.notify(7010, n);
+ }
+ },
+ new Test("private notification, has public") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("private version of notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PRIVATE)
+ .setPublicVersion(new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("public notification of private notification")
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .build())
+ .build();
+ mNM.notify(7011, n);
+ }
+ },
+ new Test("secret notification") {
+ public void run()
+ {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon2)
+ .setContentTitle("secret notification")
+ .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE)
+ .setPriority(Notification.PRIORITY_DEFAULT)
+ .setVisibility(Notification.VISIBILITY_SECRET)
+ .build();
+ mNM.notify(7012, n);
+ }
+ },
new Test("Off") {
public void run() {
PowerManager pm = (PowerManager)NotificationTestList.this.getSystemService(Context.POWER_SERVICE);
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index c2ad9ef..663e1e2 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -40,10 +40,8 @@
built_ext_classes := $(call java-lib-files,ext)
built_ext_data := $(call intermediates-dir-for, \
JAVA_LIBRARIES,ext,,COMMON)/javalib.jar
-built_icudata_dep := $(call java-lib-deps,icu4j-icudata-jarjar)
-built_icudata_data := $(call java-lib-files,icu4j-icudata-jarjar)
-built_icutzdata_dep := $(call java-lib-deps,icu4j-icutzdata-jarjar)
-built_icutzdata_data := $(call java-lib-files,icu4j-icutzdata-jarjar)
+built_icudata_dep := $(call java-lib-deps,icu4j-icudata-host-jarjar,HOST)
+built_icutzdata_dep := $(call java-lib-deps,icu4j-icutzdata-host-jarjar,HOST)
built_layoutlib_create_jar := $(call intermediates-dir-for, \
JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar
@@ -77,8 +75,8 @@
$(built_core_classes) \
$(built_framework_classes) \
$(built_ext_classes) \
- $(built_icudata_data) \
- $(built_icutzdata_data) \
+ $(built_icudata_dep) \
+ $(built_icutzdata_dep) \
$(built_ext_data)
$(hide) ls -l $(built_framework_classes)
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index db4c6dc6..ae42ba6 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -305,6 +305,12 @@
return defValue;
}
+ @Override
+ public ComplexColor getComplexColor(int index) {
+ // TODO: Support GradientColor
+ return getColorStateList(index);
+ }
+
/**
* Retrieve the ColorStateList for the attribute at <var>index</var>.
* The value may be either a single solid color or a reference to
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index c4fbd56..fa880f0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -142,7 +142,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_setBitmap(long canvas, Bitmap bitmap) {
+ public static void native_setBitmap(long canvas, Bitmap bitmap) {
Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
if (canvasDelegate == null || bitmapDelegate==null) {
@@ -153,7 +153,7 @@
}
@LayoutlibDelegate
- /*package*/ static boolean native_isOpaque(long nativeCanvas) {
+ public static boolean native_isOpaque(long nativeCanvas) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -164,10 +164,10 @@
}
@LayoutlibDelegate
- /*package*/ static void native_setHighContrastText(long nativeCanvas, boolean highContrastText){}
+ public static void native_setHighContrastText(long nativeCanvas, boolean highContrastText){}
@LayoutlibDelegate
- /*package*/ static int native_getWidth(long nativeCanvas) {
+ public static int native_getWidth(long nativeCanvas) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -178,7 +178,7 @@
}
@LayoutlibDelegate
- /*package*/ static int native_getHeight(long nativeCanvas) {
+ public static int native_getHeight(long nativeCanvas) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -189,7 +189,7 @@
}
@LayoutlibDelegate
- /*package*/ static int native_save(long nativeCanvas, int saveFlags) {
+ public static int native_save(long nativeCanvas, int saveFlags) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -200,7 +200,7 @@
}
@LayoutlibDelegate
- /*package*/ static int native_saveLayer(long nativeCanvas, float l,
+ public static int native_saveLayer(long nativeCanvas, float l,
float t, float r, float b,
long paint, int layerFlags) {
// get the delegate from the native int.
@@ -219,7 +219,7 @@
}
@LayoutlibDelegate
- /*package*/ static int native_saveLayerAlpha(long nativeCanvas, float l,
+ public static int native_saveLayerAlpha(long nativeCanvas, float l,
float t, float r, float b,
int alpha, int layerFlags) {
// get the delegate from the native int.
@@ -232,7 +232,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_restore(long nativeCanvas, boolean throwOnUnderflow) {
+ public static void native_restore(long nativeCanvas, boolean throwOnUnderflow) {
// FIXME: implement throwOnUnderflow.
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -244,7 +244,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_restoreToCount(long nativeCanvas, int saveCount,
+ public static void native_restoreToCount(long nativeCanvas, int saveCount,
boolean throwOnUnderflow) {
// FIXME: implement throwOnUnderflow.
// get the delegate from the native int.
@@ -257,7 +257,7 @@
}
@LayoutlibDelegate
- /*package*/ static int native_getSaveCount(long nativeCanvas) {
+ public static int native_getSaveCount(long nativeCanvas) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -268,7 +268,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_translate(long nativeCanvas, float dx, float dy) {
+ public static void native_translate(long nativeCanvas, float dx, float dy) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -279,7 +279,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_scale(long nativeCanvas, float sx, float sy) {
+ public static void native_scale(long nativeCanvas, float sx, float sy) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -290,7 +290,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_rotate(long nativeCanvas, float degrees) {
+ public static void native_rotate(long nativeCanvas, float degrees) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -301,7 +301,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_skew(long nativeCanvas, float kx, float ky) {
+ public static void native_skew(long nativeCanvas, float kx, float ky) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -325,7 +325,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_concat(long nCanvas, long nMatrix) {
+ public static void native_concat(long nCanvas, long nMatrix) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
if (canvasDelegate == null) {
@@ -353,7 +353,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_setMatrix(long nCanvas, long nMatrix) {
+ public static void native_setMatrix(long nCanvas, long nMatrix) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
if (canvasDelegate == null) {
@@ -383,7 +383,7 @@
}
@LayoutlibDelegate
- /*package*/ static boolean native_clipRect(long nCanvas,
+ public static boolean native_clipRect(long nCanvas,
float left, float top,
float right, float bottom,
int regionOp) {
@@ -397,7 +397,7 @@
}
@LayoutlibDelegate
- /*package*/ static boolean native_clipPath(long nativeCanvas,
+ public static boolean native_clipPath(long nativeCanvas,
long nativePath,
int regionOp) {
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -414,7 +414,7 @@
}
@LayoutlibDelegate
- /*package*/ static boolean native_clipRegion(long nativeCanvas,
+ public static boolean native_clipRegion(long nativeCanvas,
long nativeRegion,
int regionOp) {
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -431,7 +431,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeSetDrawFilter(long nativeCanvas, long nativeFilter) {
+ public static void nativeSetDrawFilter(long nativeCanvas, long nativeFilter) {
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
return;
@@ -446,7 +446,7 @@
}
@LayoutlibDelegate
- /*package*/ static boolean native_getClipBounds(long nativeCanvas,
+ public static boolean native_getClipBounds(long nativeCanvas,
Rect bounds) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -467,7 +467,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_getCTM(long canvas, long matrix) {
+ public static void native_getCTM(long canvas, long matrix) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
if (canvasDelegate == null) {
@@ -484,13 +484,13 @@
}
@LayoutlibDelegate
- /*package*/ static boolean native_quickReject(long nativeCanvas, long path) {
+ public static boolean native_quickReject(long nativeCanvas, long path) {
// FIXME properly implement quickReject
return false;
}
@LayoutlibDelegate
- /*package*/ static boolean native_quickReject(long nativeCanvas,
+ public static boolean native_quickReject(long nativeCanvas,
float left, float top,
float right, float bottom) {
// FIXME properly implement quickReject
@@ -498,7 +498,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawColor(long nativeCanvas, final int color, final int mode) {
+ public static void native_drawColor(long nativeCanvas, final int color, final int mode) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
@@ -529,14 +529,14 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawPaint(long nativeCanvas, long paint) {
+ public static void native_drawPaint(long nativeCanvas, long paint) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"Canvas.drawPaint is not supported.", null, null /*data*/);
}
@LayoutlibDelegate
- /*package*/ static void native_drawPoint(long nativeCanvas, float x, float y,
+ public static void native_drawPoint(long nativeCanvas, float x, float y,
long nativePaint) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -544,7 +544,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawPoints(long nativeCanvas, float[] pts, int offset, int count,
+ public static void native_drawPoints(long nativeCanvas, float[] pts, int offset, int count,
long nativePaint) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -552,7 +552,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawLine(long nativeCanvas,
+ public static void native_drawLine(long nativeCanvas,
final float startX, final float startY, final float stopX, final float stopY,
long paint) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
@@ -565,7 +565,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawLines(long nativeCanvas,
+ public static void native_drawLines(long nativeCanvas,
final float[] pts, final int offset, final int count,
long nativePaint) {
draw(nativeCanvas, nativePaint, false /*compositeOnly*/,
@@ -581,7 +581,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawRect(long nativeCanvas,
+ public static void native_drawRect(long nativeCanvas,
final float left, final float top, final float right, final float bottom, long paint) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
@@ -607,7 +607,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawOval(long nativeCanvas, final float left,
+ public static void native_drawOval(long nativeCanvas, final float left,
final float top, final float right, final float bottom, long paint) {
if (right > left && bottom > top) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
@@ -634,7 +634,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawCircle(long nativeCanvas,
+ public static void native_drawCircle(long nativeCanvas,
float cx, float cy, float radius, long paint) {
native_drawOval(nativeCanvas,
cx - radius, cy - radius, cx + radius, cy + radius,
@@ -642,7 +642,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawArc(long nativeCanvas,
+ public static void native_drawArc(long nativeCanvas,
final float left, final float top, final float right, final float bottom,
final float startAngle, final float sweep,
final boolean useCenter, long paint) {
@@ -674,7 +674,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawRoundRect(long nativeCanvas,
+ public static void native_drawRoundRect(long nativeCanvas,
final float left, final float top, final float right, final float bottom,
final float rx, final float ry, long paint) {
draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
@@ -704,7 +704,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawPath(long nativeCanvas, long path, long paint) {
+ public static void native_drawPath(long nativeCanvas, long path, long paint) {
final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
if (pathDelegate == null) {
return;
@@ -756,7 +756,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawRegion(long nativeCanvas, long nativeRegion,
+ public static void native_drawRegion(long nativeCanvas, long nativeRegion,
long nativePaint) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -764,7 +764,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawNinePatch(Canvas thisCanvas, long nativeCanvas,
+ public static void native_drawNinePatch(Canvas thisCanvas, long nativeCanvas,
long nativeBitmap, long ninePatch, final float dstLeft, final float dstTop,
final float dstRight, final float dstBottom, long nativePaintOrZero,
final int screenDensity, final int bitmapDensity) {
@@ -811,7 +811,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
+ public static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
float left, float top,
long nativePaintOrZero,
int canvasDensity,
@@ -833,7 +833,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
+ public static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
long nativePaintOrZero, int screenDensity, int bitmapDensity) {
@@ -849,7 +849,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawBitmap(long nativeCanvas, int[] colors,
+ public static void native_drawBitmap(long nativeCanvas, int[] colors,
int offset, int stride, final float x,
final float y, int width, int height,
boolean hasAlpha,
@@ -874,7 +874,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, Bitmap bitmap,
+ public static void nativeDrawBitmapMatrix(long nCanvas, Bitmap bitmap,
long nMatrix, long nPaint) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
@@ -915,7 +915,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeDrawBitmapMesh(long nCanvas, Bitmap bitmap,
+ public static void nativeDrawBitmapMesh(long nCanvas, Bitmap bitmap,
int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
int colorOffset, long nPaint) {
// FIXME
@@ -924,7 +924,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeDrawVertices(long nCanvas, int mode, int n,
+ public static void nativeDrawVertices(long nCanvas, int mode, int n,
float[] verts, int vertOffset,
float[] texs, int texOffset,
int[] colors, int colorOffset,
@@ -936,14 +936,14 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawText(long nativeCanvas, char[] text, int index, int count,
+ public static void native_drawText(long nativeCanvas, char[] text, int index, int count,
float startX, float startY, int flags, long paint, long typeface) {
drawText(nativeCanvas, text, index, count, startX, startY, (flags & 1) != 0,
paint, typeface);
}
@LayoutlibDelegate
- /*package*/ static void native_drawText(long nativeCanvas, String text,
+ public static void native_drawText(long nativeCanvas, String text,
int start, int end, float x, float y, final int flags, long paint,
long typeface) {
int count = end - start;
@@ -954,7 +954,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawTextRun(long nativeCanvas, String text,
+ public static void native_drawTextRun(long nativeCanvas, String text,
int start, int end, int contextStart, int contextEnd,
float x, float y, boolean isRtl, long paint, long typeface) {
int count = end - start;
@@ -965,14 +965,14 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawTextRun(long nativeCanvas, char[] text,
+ public static void native_drawTextRun(long nativeCanvas, char[] text,
int start, int count, int contextStart, int contextCount,
float x, float y, boolean isRtl, long paint, long typeface) {
drawText(nativeCanvas, text, start, count, x, y, isRtl, paint, typeface);
}
@LayoutlibDelegate
- /*package*/ static void native_drawTextOnPath(long nativeCanvas,
+ public static void native_drawTextOnPath(long nativeCanvas,
char[] text, int index,
int count, long path,
float hOffset,
@@ -984,7 +984,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawTextOnPath(long nativeCanvas,
+ public static void native_drawTextOnPath(long nativeCanvas,
String text, long path,
float hOffset,
float vOffset,
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 514d785..839c182 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -223,6 +223,10 @@
return mColorFilter;
}
+ public void setColorFilter(long colorFilterPtr) {
+ mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
+ }
+
/**
* Returns the {@link Shader} delegate or null if none have been set
*
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index e1da27b..08f0cb4 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -572,7 +572,7 @@
return null;
}
- private static void addPath(long destPath, long srcPath, AffineTransform transform) {
+ public static void addPath(long destPath, long srcPath, AffineTransform transform) {
Path_Delegate destPathDelegate = sManager.getDelegate(destPath);
if (destPathDelegate == null) {
return;
@@ -630,7 +630,7 @@
* Fills the given {@link RectF} with the path bounds.
* @param bounds the RectF to be filled.
*/
- private void fillBounds(RectF bounds) {
+ public void fillBounds(RectF bounds) {
Rectangle2D rect = mPath.getBounds2D();
bounds.left = (float)rect.getMinX();
bounds.right = (float)rect.getMaxX();
@@ -644,7 +644,7 @@
* @param x The x-coordinate of the start of a new contour
* @param y The y-coordinate of the start of a new contour
*/
- private void moveTo(float x, float y) {
+ public void moveTo(float x, float y) {
mPath.moveTo(mLastX = x, mLastY = y);
}
@@ -658,7 +658,7 @@
* @param dy The amount to add to the y-coordinate of the end of the
* previous contour, to specify the start of a new contour
*/
- private void rMoveTo(float dx, float dy) {
+ public void rMoveTo(float dx, float dy) {
dx += mLastX;
dy += mLastY;
mPath.moveTo(mLastX = dx, mLastY = dy);
@@ -672,7 +672,7 @@
* @param x The x-coordinate of the end of a line
* @param y The y-coordinate of the end of a line
*/
- private void lineTo(float x, float y) {
+ public void lineTo(float x, float y) {
if (!hasPoints()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
}
@@ -689,7 +689,7 @@
* @param dy The amount to add to the y-coordinate of the previous point on
* this contour, to specify a line
*/
- private void rLineTo(float dx, float dy) {
+ public void rLineTo(float dx, float dy) {
if (!hasPoints()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
}
@@ -714,7 +714,7 @@
* @param x2 The x-coordinate of the end point on a quadratic curve
* @param y2 The y-coordinate of the end point on a quadratic curve
*/
- private void quadTo(float x1, float y1, float x2, float y2) {
+ public void quadTo(float x1, float y1, float x2, float y2) {
mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
}
@@ -732,7 +732,7 @@
* @param dy2 The amount to add to the y-coordinate of the last point on
* this contour, for the end point of a quadratic curve
*/
- private void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
+ public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
if (!hasPoints()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
}
@@ -755,7 +755,7 @@
* @param x3 The x-coordinate of the end point on a cubic curve
* @param y3 The y-coordinate of the end point on a cubic curve
*/
- private void cubicTo(float x1, float y1, float x2, float y2,
+ public void cubicTo(float x1, float y1, float x2, float y2,
float x3, float y3) {
if (!hasPoints()) {
mPath.moveTo(0, 0);
@@ -768,7 +768,7 @@
* current point on this contour. If there is no previous point, then a
* moveTo(0,0) is inserted automatically.
*/
- private void rCubicTo(float dx1, float dy1, float dx2, float dy2,
+ public void rCubicTo(float dx1, float dy1, float dx2, float dy2,
float dx3, float dy3) {
if (!hasPoints()) {
mPath.moveTo(mLastX = 0, mLastY = 0);
@@ -798,7 +798,7 @@
* mod 360.
* @param forceMoveTo If true, always begin a new contour with the arc
*/
- private void arcTo(float left, float top, float right, float bottom, float startAngle,
+ public void arcTo(float left, float top, float right, float bottom, float startAngle,
float sweepAngle,
boolean forceMoveTo) {
Arc2D arc = new Arc2D.Float(left, top, right - left, bottom - top, -startAngle,
@@ -812,7 +812,7 @@
* Close the current contour. If the current point is not equal to the
* first point of the contour, a line segment is automatically added.
*/
- private void close() {
+ public void close() {
mPath.closePath();
}
@@ -831,7 +831,7 @@
* @param bottom The bottom of a rectangle to add to the path
* @param dir The direction to wind the rectangle's contour
*/
- private void addRect(float left, float top, float right, float bottom,
+ public void addRect(float left, float top, float right, float bottom,
int dir) {
moveTo(left, top);
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
new file mode 100644
index 0000000..eef8235
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
@@ -0,0 +1,1122 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.graphics.Canvas_Delegate;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Paint.Cap;
+import android.graphics.Paint.Join;
+import android.graphics.Paint_Delegate;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.graphics.Path_Delegate;
+import android.graphics.Rect;
+import android.graphics.Region.Op;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.MathUtils;
+import android.util.PathParser_Delegate;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+
+import static android.graphics.Canvas.CLIP_SAVE_FLAG;
+import static android.graphics.Canvas.MATRIX_SAVE_FLAG;
+import static android.graphics.Paint.Cap.BUTT;
+import static android.graphics.Paint.Cap.ROUND;
+import static android.graphics.Paint.Cap.SQUARE;
+import static android.graphics.Paint.Join.BEVEL;
+import static android.graphics.Paint.Join.MITER;
+import static android.graphics.Paint.Style;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link VectorDrawable}
+ * <p>
+ * Through the layoutlib_create tool, the original methods of VectorDrawable have been replaced by
+ * calls to methods of the same name in this delegate class.
+ */
+@SuppressWarnings("unused")
+public class VectorDrawable_Delegate {
+ private static final String LOGTAG = VectorDrawable_Delegate.class.getSimpleName();
+ private static final boolean DBG_VECTOR_DRAWABLE = false;
+
+ private static final DelegateManager<VNativeObject> sPathManager =
+ new DelegateManager<>(VNativeObject.class);
+
+ private static <T> T getDelegate(long nativePtr) {
+ //noinspection unchecked
+ T object = (T) sPathManager.getDelegate(nativePtr);
+ assert object != null;
+
+ return object;
+ }
+
+ /**
+ * Obtains styled attributes from the theme, if available, or unstyled resources if the theme is
+ * null.
+ */
+ private static TypedArray obtainAttributes(
+ Resources res, Theme theme, AttributeSet set, int[] attrs) {
+ if (theme == null) {
+ return res.obtainAttributes(set, attrs);
+ }
+ return theme.obtainStyledAttributes(set, attrs, 0, 0);
+ }
+
+ private static int applyAlpha(int color, float alpha) {
+ int alphaBytes = Color.alpha(color);
+ color &= 0x00FFFFFF;
+ color |= ((int) (alphaBytes * alpha)) << 24;
+ return color;
+ }
+
+ @LayoutlibDelegate
+ static long nCreateRenderer(long rootGroupPtr) {
+ VGroup_Delegate rootGroup = getDelegate(rootGroupPtr);
+ return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rootGroup));
+ }
+
+ @LayoutlibDelegate
+ static void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
+ float viewportHeight) {
+ VPathRenderer_Delegate nativePathRenderer = getDelegate(rendererPtr);
+ nativePathRenderer.mViewportWidth = viewportWidth;
+ nativePathRenderer.mViewportHeight = viewportHeight;
+ }
+
+ @LayoutlibDelegate
+ static boolean nSetRootAlpha(long rendererPtr, float alpha) {
+ VPathRenderer_Delegate nativePathRenderer = getDelegate(rendererPtr);
+ nativePathRenderer.setRootAlpha(alpha);
+
+ return true;
+ }
+
+ @LayoutlibDelegate
+ static float nGetRootAlpha(long rendererPtr) {
+ VPathRenderer_Delegate nativePathRenderer = getDelegate(rendererPtr);
+
+ return nativePathRenderer.getRootAlpha();
+ }
+
+ @LayoutlibDelegate
+ static void nSetAllowCaching(long rendererPtr, boolean allowCaching) {
+ // ignored
+ }
+
+ @LayoutlibDelegate
+ static void nDraw(long rendererPtr, long canvasWrapperPtr,
+ long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache) {
+ VPathRenderer_Delegate nativePathRenderer =
+ getDelegate(rendererPtr);
+
+ Canvas_Delegate.native_save(canvasWrapperPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
+ Canvas_Delegate.native_translate(canvasWrapperPtr, bounds.left, bounds.top);
+
+ if (needsMirroring) {
+ Canvas_Delegate.native_translate(canvasWrapperPtr, bounds.width(), 0);
+ Canvas_Delegate.native_scale(canvasWrapperPtr, -1.0f, 1.0f);
+ }
+
+ // At this point, canvas has been translated to the right position.
+ // And we use this bound for the destination rect for the drawBitmap, so
+ // we offset to (0, 0);
+ bounds.offsetTo(0, 0);
+ nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height());
+
+ Canvas_Delegate.native_restore(canvasWrapperPtr, true);
+ }
+
+ @LayoutlibDelegate
+ static long nCreateFullPath() {
+ return sPathManager.addNewDelegate(new VFullPath_Delegate());
+ }
+
+ @LayoutlibDelegate
+ static long nCreateFullPath(long nativeFullPathPtr) {
+ VFullPath_Delegate original = getDelegate(nativeFullPathPtr);
+
+ return sPathManager.addNewDelegate(new VFullPath_Delegate(original));
+ }
+
+ @LayoutlibDelegate
+ static boolean nGetFullPathProperties(long pathPtr, byte[] propertiesData,
+ int length) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+
+ ByteBuffer properties = ByteBuffer.wrap(propertiesData);
+ properties.order(ByteOrder.nativeOrder());
+
+ properties.putFloat(VFullPath_Delegate.STROKE_WIDTH_INDEX * 4, path.getStrokeWidth());
+ properties.putInt(VFullPath_Delegate.STROKE_COLOR_INDEX * 4, path.getStrokeColor());
+ properties.putFloat(VFullPath_Delegate.STROKE_ALPHA_INDEX * 4, path.getStrokeAlpha());
+ properties.putInt(VFullPath_Delegate.FILL_COLOR_INDEX * 4, path.getFillColor());
+ properties.putFloat(VFullPath_Delegate.FILL_ALPHA_INDEX * 4, path.getStrokeAlpha());
+ properties.putFloat(VFullPath_Delegate.TRIM_PATH_START_INDEX * 4, path.getTrimPathStart());
+ properties.putFloat(VFullPath_Delegate.TRIM_PATH_END_INDEX * 4, path.getTrimPathEnd());
+ properties.putFloat(VFullPath_Delegate.TRIM_PATH_OFFSET_INDEX * 4,
+ path.getTrimPathOffset());
+ properties.putInt(VFullPath_Delegate.STROKE_LINE_CAP_INDEX * 4, path.getStrokeLineCap());
+ properties.putInt(VFullPath_Delegate.STROKE_LINE_JOIN_INDEX * 4, path.getStrokeLineJoin());
+ properties.putFloat(VFullPath_Delegate.STROKE_MITER_LIMIT_INDEX * 4,
+ path.getStrokeMiterlimit());
+
+ return true;
+ }
+
+ @LayoutlibDelegate
+ static void nUpdateFullPathProperties(long pathPtr, float strokeWidth,
+ int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart,
+ float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap,
+ int strokeLineJoin) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+
+ path.setStrokeWidth(strokeWidth);
+ path.setStrokeColor(strokeColor);
+ path.setStrokeAlpha(strokeAlpha);
+ path.setFillColor(fillColor);
+ path.setFillAlpha(fillAlpha);
+ path.setTrimPathStart(trimPathStart);
+ path.setTrimPathEnd(trimPathEnd);
+ path.setTrimPathOffset(trimPathOffset);
+ path.setStrokeMiterlimit(strokeMiterLimit);
+ path.setStrokeLineCap(strokeLineCap);
+ path.setStrokeLineJoin(strokeLineJoin);
+ }
+
+ @LayoutlibDelegate
+ static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) {
+
+ }
+
+ @LayoutlibDelegate
+ static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) {
+
+ }
+
+ @LayoutlibDelegate
+ static long nCreateClipPath() {
+ return sPathManager.addNewDelegate(new VClipPath_Delegate());
+ }
+
+ @LayoutlibDelegate
+ static long nCreateClipPath(long clipPathPtr) {
+ VClipPath_Delegate original = getDelegate(clipPathPtr);
+ return sPathManager.addNewDelegate(new VClipPath_Delegate(original));
+ }
+
+ @LayoutlibDelegate
+ static long nCreateGroup() {
+ return sPathManager.addNewDelegate(new VGroup_Delegate());
+ }
+
+ @LayoutlibDelegate
+ static long nCreateGroup(long groupPtr) {
+ VGroup_Delegate original = getDelegate(groupPtr);
+ return sPathManager.addNewDelegate(
+ new VGroup_Delegate(original, new ArrayMap<String, Object>()));
+ }
+
+ @LayoutlibDelegate
+ static void nSetName(long nodePtr, String name) {
+ VNativeObject group = getDelegate(nodePtr);
+ group.setName(name);
+ }
+
+ @LayoutlibDelegate
+ static boolean nGetGroupProperties(long groupPtr, float[] propertiesData,
+ int length) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+
+ FloatBuffer properties = FloatBuffer.wrap(propertiesData);
+
+ properties.put(VGroup_Delegate.ROTATE_INDEX, group.getRotation());
+ properties.put(VGroup_Delegate.PIVOT_X_INDEX, group.getPivotX());
+ properties.put(VGroup_Delegate.PIVOT_Y_INDEX, group.getPivotY());
+ properties.put(VGroup_Delegate.SCALE_X_INDEX, group.getScaleX());
+ properties.put(VGroup_Delegate.SCALE_Y_INDEX, group.getScaleY());
+ properties.put(VGroup_Delegate.TRANSLATE_X_INDEX, group.getTranslateX());
+ properties.put(VGroup_Delegate.TRANSLATE_Y_INDEX, group.getTranslateY());
+
+ return true;
+ }
+ @LayoutlibDelegate
+ static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX,
+ float pivotY, float scaleX, float scaleY, float translateX, float translateY) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+
+ group.setRotation(rotate);
+ group.setPivotX(pivotX);
+ group.setPivotY(pivotY);
+ group.setScaleX(scaleX);
+ group.setScaleY(scaleY);
+ group.setTranslateX(translateX);
+ group.setTranslateY(translateY);
+ }
+
+ @LayoutlibDelegate
+ static void nAddChild(long groupPtr, long nodePtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.mChildren.add(getDelegate(nodePtr));
+ }
+
+ @LayoutlibDelegate
+ static void nSetPathString(long pathPtr, String pathString, int length) {
+ VPath_Delegate path = getDelegate(pathPtr);
+ path.setPathData(PathParser_Delegate.createNodesFromPathData(pathString));
+ }
+
+ /**
+ * The setters and getters below for paths and groups are here temporarily, and will be removed
+ * once the animation in AVD is replaced with RenderNodeAnimator, in which case the animation
+ * will modify these properties in native. By then no JNI hopping would be necessary for VD
+ * during animation, and these setters and getters will be obsolete.
+ */
+ // Setters and getters during animation.
+ @LayoutlibDelegate
+ static float nGetRotation(long groupPtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ return group.getRotation();
+ }
+
+ @LayoutlibDelegate
+ static void nSetRotation(long groupPtr, float rotation) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.setRotation(rotation);
+ }
+
+ @LayoutlibDelegate
+ static float nGetPivotX(long groupPtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ return group.getPivotX();
+ }
+
+ @LayoutlibDelegate
+ static void nSetPivotX(long groupPtr, float pivotX) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.setPivotX(pivotX);
+ }
+
+ @LayoutlibDelegate
+ static float nGetPivotY(long groupPtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ return group.getPivotY();
+ }
+
+ @LayoutlibDelegate
+ static void nSetPivotY(long groupPtr, float pivotY) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.setPivotY(pivotY);
+ }
+
+ @LayoutlibDelegate
+ static float nGetScaleX(long groupPtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ return group.getScaleX();
+ }
+
+ @LayoutlibDelegate
+ static void nSetScaleX(long groupPtr, float scaleX) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.setScaleX(scaleX);
+ }
+
+ @LayoutlibDelegate
+ static float nGetScaleY(long groupPtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ return group.getScaleY();
+ }
+
+ @LayoutlibDelegate
+ static void nSetScaleY(long groupPtr, float scaleY) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.setScaleY(scaleY);
+ }
+
+ @LayoutlibDelegate
+ static float nGetTranslateX(long groupPtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ return group.getTranslateX();
+ }
+
+ @LayoutlibDelegate
+ static void nSetTranslateX(long groupPtr, float translateX) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.setTranslateX(translateX);
+ }
+
+ @LayoutlibDelegate
+ static float nGetTranslateY(long groupPtr) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ return group.getTranslateY();
+ }
+
+ @LayoutlibDelegate
+ static void nSetTranslateY(long groupPtr, float translateY) {
+ VGroup_Delegate group = getDelegate(groupPtr);
+ group.setTranslateY(translateY);
+ }
+
+ @LayoutlibDelegate
+ static void nSetPathData(long pathPtr, long pathDataPtr) {
+ VPath_Delegate path = getDelegate(pathPtr);
+ path.setPathData(PathParser_Delegate.getDelegate(pathDataPtr).getPathDataNodes());
+ }
+
+ @LayoutlibDelegate
+ static float nGetStrokeWidth(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getStrokeWidth();
+ }
+
+ @LayoutlibDelegate
+ static void nSetStrokeWidth(long pathPtr, float width) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setStrokeWidth(width);
+ }
+
+ @LayoutlibDelegate
+ static int nGetStrokeColor(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getStrokeColor();
+ }
+
+ @LayoutlibDelegate
+ static void nSetStrokeColor(long pathPtr, int strokeColor) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setStrokeColor(strokeColor);
+ }
+
+ @LayoutlibDelegate
+ static float nGetStrokeAlpha(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getStrokeAlpha();
+ }
+
+ @LayoutlibDelegate
+ static void nSetStrokeAlpha(long pathPtr, float alpha) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setStrokeAlpha(alpha);
+ }
+
+ @LayoutlibDelegate
+ static int nGetFillColor(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getFillColor();
+ }
+
+ @LayoutlibDelegate
+ static void nSetFillColor(long pathPtr, int fillColor) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setFillColor(fillColor);
+ }
+
+ @LayoutlibDelegate
+ static float nGetFillAlpha(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getFillAlpha();
+ }
+
+ @LayoutlibDelegate
+ static void nSetFillAlpha(long pathPtr, float fillAlpha) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setFillAlpha(fillAlpha);
+ }
+
+ @LayoutlibDelegate
+ static float nGetTrimPathStart(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getTrimPathStart();
+ }
+
+ @LayoutlibDelegate
+ static void nSetTrimPathStart(long pathPtr, float trimPathStart) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setTrimPathStart(trimPathStart);
+ }
+
+ @LayoutlibDelegate
+ static float nGetTrimPathEnd(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getTrimPathEnd();
+ }
+
+ @LayoutlibDelegate
+ static void nSetTrimPathEnd(long pathPtr, float trimPathEnd) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setTrimPathEnd(trimPathEnd);
+ }
+
+ @LayoutlibDelegate
+ static float nGetTrimPathOffset(long pathPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ return path.getTrimPathOffset();
+ }
+
+ @LayoutlibDelegate
+ static void nSetTrimPathOffset(long pathPtr, float trimPathOffset) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setTrimPathOffset(trimPathOffset);
+ }
+
+ /**
+ * Base class for all the internal Delegates that does two functions:
+ * <ol>
+ * <li>Serves as base class to store all the delegates in one {@link DelegateManager}
+ * <li>Provides setName for all the classes. {@link VPathRenderer_Delegate} does actually
+ * not need it
+ * </ol>
+ */
+ private interface VNativeObject {
+ void setName(String name);
+ }
+
+ private static class VClipPath_Delegate extends VPath_Delegate {
+ private VClipPath_Delegate() {
+ // Empty constructor.
+ }
+
+ private VClipPath_Delegate(VClipPath_Delegate copy) {
+ super(copy);
+ }
+
+ @Override
+ public boolean isClipPath() {
+ return true;
+ }
+ }
+
+ private static class VFullPath_Delegate extends VPath_Delegate {
+ // These constants need to be kept in sync with their values in VectorDrawable.VFullPath
+ private static final int STROKE_WIDTH_INDEX = 0;
+ private static final int STROKE_COLOR_INDEX = 1;
+ private static final int STROKE_ALPHA_INDEX = 2;
+ private static final int FILL_COLOR_INDEX = 3;
+ private static final int FILL_ALPHA_INDEX = 4;
+ private static final int TRIM_PATH_START_INDEX = 5;
+ private static final int TRIM_PATH_END_INDEX = 6;
+ private static final int TRIM_PATH_OFFSET_INDEX = 7;
+ private static final int STROKE_LINE_CAP_INDEX = 8;
+ private static final int STROKE_LINE_JOIN_INDEX = 9;
+ private static final int STROKE_MITER_LIMIT_INDEX = 10;
+
+ private static final int LINECAP_BUTT = 0;
+ private static final int LINECAP_ROUND = 1;
+ private static final int LINECAP_SQUARE = 2;
+
+ private static final int LINEJOIN_MITER = 0;
+ private static final int LINEJOIN_ROUND = 1;
+ private static final int LINEJOIN_BEVEL = 2;
+
+ /////////////////////////////////////////////////////
+ // Variables below need to be copied (deep copy if applicable) for mutation.
+
+ int mStrokeColor = Color.TRANSPARENT;
+ float mStrokeWidth = 0;
+
+ int mFillColor = Color.TRANSPARENT;
+ float mStrokeAlpha = 1.0f;
+ float mFillAlpha = 1.0f;
+ float mTrimPathStart = 0;
+ float mTrimPathEnd = 1;
+ float mTrimPathOffset = 0;
+
+ Cap mStrokeLineCap = BUTT;
+ Join mStrokeLineJoin = MITER;
+ float mStrokeMiterlimit = 4;
+
+ private VFullPath_Delegate() {
+ // Empty constructor.
+ }
+
+ private VFullPath_Delegate(VFullPath_Delegate copy) {
+ super(copy);
+
+ mStrokeColor = copy.mStrokeColor;
+ mStrokeWidth = copy.mStrokeWidth;
+ mStrokeAlpha = copy.mStrokeAlpha;
+ mFillColor = copy.mFillColor;
+ mFillAlpha = copy.mFillAlpha;
+ mTrimPathStart = copy.mTrimPathStart;
+ mTrimPathEnd = copy.mTrimPathEnd;
+ mTrimPathOffset = copy.mTrimPathOffset;
+
+ mStrokeLineCap = copy.mStrokeLineCap;
+ mStrokeLineJoin = copy.mStrokeLineJoin;
+ mStrokeMiterlimit = copy.mStrokeMiterlimit;
+ }
+
+ private int getStrokeLineCap() {
+ switch (mStrokeLineCap) {
+ case BUTT:
+ return LINECAP_BUTT;
+ case ROUND:
+ return LINECAP_ROUND;
+ case SQUARE:
+ return LINECAP_SQUARE;
+ default:
+ assert false;
+ }
+
+ return -1;
+ }
+
+ private void setStrokeLineCap(int cap) {
+ switch (cap) {
+ case LINECAP_BUTT:
+ mStrokeLineCap = BUTT;
+ break;
+ case LINECAP_ROUND:
+ mStrokeLineCap = ROUND;
+ break;
+ case LINECAP_SQUARE:
+ mStrokeLineCap = SQUARE;
+ break;
+ default:
+ assert false;
+ }
+ }
+
+ private int getStrokeLineJoin() {
+ switch (mStrokeLineJoin) {
+ case MITER:
+ return LINEJOIN_MITER;
+ case ROUND:
+ return LINEJOIN_ROUND;
+ case BEVEL:
+ return LINEJOIN_BEVEL;
+ default:
+ assert false;
+ }
+
+ return -1;
+ }
+
+ private void setStrokeLineJoin(int join) {
+ switch (join) {
+ case LINEJOIN_BEVEL:
+ mStrokeLineJoin = BEVEL;
+ break;
+ case LINEJOIN_MITER:
+ mStrokeLineJoin = MITER;
+ break;
+ case LINEJOIN_ROUND:
+ mStrokeLineJoin = Join.ROUND;
+ break;
+ default:
+ assert false;
+ }
+ }
+
+ private int getStrokeColor() {
+ return mStrokeColor;
+ }
+
+ private void setStrokeColor(int strokeColor) {
+ mStrokeColor = strokeColor;
+ }
+
+ private float getStrokeWidth() {
+ return mStrokeWidth;
+ }
+
+ private void setStrokeWidth(float strokeWidth) {
+ mStrokeWidth = strokeWidth;
+ }
+
+ private float getStrokeAlpha() {
+ return mStrokeAlpha;
+ }
+
+ private void setStrokeAlpha(float strokeAlpha) {
+ mStrokeAlpha = strokeAlpha;
+ }
+
+ private int getFillColor() {
+ return mFillColor;
+ }
+
+ private void setFillColor(int fillColor) {
+ mFillColor = fillColor;
+ }
+
+ private float getFillAlpha() {
+ return mFillAlpha;
+ }
+
+ private void setFillAlpha(float fillAlpha) {
+ mFillAlpha = fillAlpha;
+ }
+
+ private float getTrimPathStart() {
+ return mTrimPathStart;
+ }
+
+ private void setTrimPathStart(float trimPathStart) {
+ mTrimPathStart = trimPathStart;
+ }
+
+ private float getTrimPathEnd() {
+ return mTrimPathEnd;
+ }
+
+ private void setTrimPathEnd(float trimPathEnd) {
+ mTrimPathEnd = trimPathEnd;
+ }
+
+ private float getTrimPathOffset() {
+ return mTrimPathOffset;
+ }
+
+ private void setTrimPathOffset(float trimPathOffset) {
+ mTrimPathOffset = trimPathOffset;
+ }
+
+ private void setStrokeMiterlimit(float limit) {
+ mStrokeMiterlimit = limit;
+ }
+
+ private float getStrokeMiterlimit() {
+ return mStrokeMiterlimit;
+ }
+ }
+
+ private static class VGroup_Delegate implements VNativeObject {
+ // This constants need to be kept in sync with their definitions in VectorDrawable.Group
+ private static final int ROTATE_INDEX = 0;
+ private static final int PIVOT_X_INDEX = 1;
+ private static final int PIVOT_Y_INDEX = 2;
+ private static final int SCALE_X_INDEX = 3;
+ private static final int SCALE_Y_INDEX = 4;
+ private static final int TRANSLATE_X_INDEX = 5;
+ private static final int TRANSLATE_Y_INDEX = 6;
+
+ /////////////////////////////////////////////////////
+ // Variables below need to be copied (deep copy if applicable) for mutation.
+ final ArrayList<Object> mChildren = new ArrayList<>();
+ // mStackedMatrix is only used temporarily when drawing, it combines all
+ // the parents' local matrices with the current one.
+ private final Matrix mStackedMatrix = new Matrix();
+ // mLocalMatrix is updated based on the update of transformation information,
+ // either parsed from the XML or by animation.
+ private final Matrix mLocalMatrix = new Matrix();
+ private float mRotate = 0;
+ private float mPivotX = 0;
+ private float mPivotY = 0;
+ private float mScaleX = 1;
+ private float mScaleY = 1;
+ private float mTranslateX = 0;
+ private float mTranslateY = 0;
+ private int mChangingConfigurations;
+ private String mGroupName = null;
+
+ private VGroup_Delegate(VGroup_Delegate copy, ArrayMap<String, Object> targetsMap) {
+ mRotate = copy.mRotate;
+ mPivotX = copy.mPivotX;
+ mPivotY = copy.mPivotY;
+ mScaleX = copy.mScaleX;
+ mScaleY = copy.mScaleY;
+ mTranslateX = copy.mTranslateX;
+ mTranslateY = copy.mTranslateY;
+ mGroupName = copy.mGroupName;
+ mChangingConfigurations = copy.mChangingConfigurations;
+ if (mGroupName != null) {
+ targetsMap.put(mGroupName, this);
+ }
+
+ mLocalMatrix.set(copy.mLocalMatrix);
+
+ final ArrayList<Object> children = copy.mChildren;
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < children.size(); i++) {
+ Object copyChild = children.get(i);
+ if (copyChild instanceof VGroup_Delegate) {
+ VGroup_Delegate copyGroup = (VGroup_Delegate) copyChild;
+ mChildren.add(new VGroup_Delegate(copyGroup, targetsMap));
+ } else {
+ VPath_Delegate newPath;
+ if (copyChild instanceof VFullPath_Delegate) {
+ newPath = new VFullPath_Delegate((VFullPath_Delegate) copyChild);
+ } else if (copyChild instanceof VClipPath_Delegate) {
+ newPath = new VClipPath_Delegate((VClipPath_Delegate) copyChild);
+ } else {
+ throw new IllegalStateException("Unknown object in the tree!");
+ }
+ mChildren.add(newPath);
+ if (newPath.mPathName != null) {
+ targetsMap.put(newPath.mPathName, newPath);
+ }
+ }
+ }
+ }
+
+ private VGroup_Delegate() {
+ }
+
+ private void updateLocalMatrix() {
+ // The order we apply is the same as the
+ // RenderNode.cpp::applyViewPropertyTransforms().
+ mLocalMatrix.reset();
+ mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
+ mLocalMatrix.postScale(mScaleX, mScaleY);
+ mLocalMatrix.postRotate(mRotate, 0, 0);
+ mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
+ }
+
+ /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
+ private float getRotation() {
+ return mRotate;
+ }
+
+ private void setRotation(float rotation) {
+ if (rotation != mRotate) {
+ mRotate = rotation;
+ updateLocalMatrix();
+ }
+ }
+
+ private float getPivotX() {
+ return mPivotX;
+ }
+
+ private void setPivotX(float pivotX) {
+ if (pivotX != mPivotX) {
+ mPivotX = pivotX;
+ updateLocalMatrix();
+ }
+ }
+
+ private float getPivotY() {
+ return mPivotY;
+ }
+
+ private void setPivotY(float pivotY) {
+ if (pivotY != mPivotY) {
+ mPivotY = pivotY;
+ updateLocalMatrix();
+ }
+ }
+
+ private float getScaleX() {
+ return mScaleX;
+ }
+
+ private void setScaleX(float scaleX) {
+ if (scaleX != mScaleX) {
+ mScaleX = scaleX;
+ updateLocalMatrix();
+ }
+ }
+
+ private float getScaleY() {
+ return mScaleY;
+ }
+
+ private void setScaleY(float scaleY) {
+ if (scaleY != mScaleY) {
+ mScaleY = scaleY;
+ updateLocalMatrix();
+ }
+ }
+
+ private float getTranslateX() {
+ return mTranslateX;
+ }
+
+ private void setTranslateX(float translateX) {
+ if (translateX != mTranslateX) {
+ mTranslateX = translateX;
+ updateLocalMatrix();
+ }
+ }
+
+ private float getTranslateY() {
+ return mTranslateY;
+ }
+
+ private void setTranslateY(float translateY) {
+ if (translateY != mTranslateY) {
+ mTranslateY = translateY;
+ updateLocalMatrix();
+ }
+ }
+
+ @Override
+ public void setName(String name) {
+ mGroupName = name;
+ }
+ }
+
+ public static class VPath_Delegate implements VNativeObject {
+ protected PathParser_Delegate.PathDataNode[] mNodes = null;
+ String mPathName;
+ int mChangingConfigurations;
+
+ public VPath_Delegate() {
+ // Empty constructor.
+ }
+
+ public VPath_Delegate(VPath_Delegate copy) {
+ mPathName = copy.mPathName;
+ mChangingConfigurations = copy.mChangingConfigurations;
+ mNodes = PathParser_Delegate.deepCopyNodes(copy.mNodes);
+ }
+
+ public void toPath(Path path) {
+ path.reset();
+ if (mNodes != null) {
+ PathParser_Delegate.PathDataNode.nodesToPath(mNodes,
+ Path_Delegate.getDelegate(path.mNativePath));
+ }
+ }
+
+ @Override
+ public void setName(String name) {
+ mPathName = name;
+ }
+
+ public boolean isClipPath() {
+ return false;
+ }
+
+ private void setPathData(PathParser_Delegate.PathDataNode[] nodes) {
+ if (!PathParser_Delegate.canMorph(mNodes, nodes)) {
+ // This should not happen in the middle of animation.
+ mNodes = PathParser_Delegate.deepCopyNodes(nodes);
+ } else {
+ PathParser_Delegate.updateNodes(mNodes, nodes);
+ }
+ }
+ }
+
+ private static class VPathRenderer_Delegate implements VNativeObject {
+ /* Right now the internal data structure is organized as a tree.
+ * Each node can be a group node, or a path.
+ * A group node can have groups or paths as children, but a path node has
+ * no children.
+ * One example can be:
+ * Root Group
+ * / | \
+ * Group Path Group
+ * / \ |
+ * Path Path Path
+ *
+ */
+ // Variables that only used temporarily inside the draw() call, so there
+ // is no need for deep copying.
+ private final Path mPath;
+ private final Path mRenderPath;
+ private final Matrix mFinalPathMatrix = new Matrix();
+ private final VGroup_Delegate mRootGroup;
+ private float mViewportWidth = 0;
+ private float mViewportHeight = 0;
+ private float mRootAlpha = 1.0f;
+ private Paint mStrokePaint;
+ private Paint mFillPaint;
+ private PathMeasure mPathMeasure;
+
+ private VPathRenderer_Delegate(VGroup_Delegate rootGroup) {
+ mRootGroup = rootGroup;
+ mPath = new Path();
+ mRenderPath = new Path();
+ }
+
+ private float getRootAlpha() {
+ return mRootAlpha;
+ }
+
+ private void setRootAlpha(float alpha) {
+ mRootAlpha = alpha;
+ }
+
+ private void drawGroupTree(VGroup_Delegate currentGroup, Matrix currentMatrix,
+ long canvasPtr, int w, int h, long filterPtr) {
+ // Calculate current group's matrix by preConcat the parent's and
+ // and the current one on the top of the stack.
+ // Basically the Mfinal = Mviewport * M0 * M1 * M2;
+ // Mi the local matrix at level i of the group tree.
+ currentGroup.mStackedMatrix.set(currentMatrix);
+ currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
+
+ // Save the current clip information, which is local to this group.
+ Canvas_Delegate.native_save(canvasPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
+ // Draw the group tree in the same order as the XML file.
+ for (int i = 0; i < currentGroup.mChildren.size(); i++) {
+ Object child = currentGroup.mChildren.get(i);
+ if (child instanceof VGroup_Delegate) {
+ VGroup_Delegate childGroup = (VGroup_Delegate) child;
+ drawGroupTree(childGroup, currentGroup.mStackedMatrix,
+ canvasPtr, w, h, filterPtr);
+ } else if (child instanceof VPath_Delegate) {
+ VPath_Delegate childPath = (VPath_Delegate) child;
+ drawPath(currentGroup, childPath, canvasPtr, w, h, filterPtr);
+ }
+ }
+ Canvas_Delegate.native_restore(canvasPtr, true);
+ }
+
+ public void draw(long canvasPtr, long filterPtr, int w, int h) {
+ // Traverse the tree in pre-order to draw.
+ drawGroupTree(mRootGroup, Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr);
+ }
+
+ private void drawPath(VGroup_Delegate VGroup, VPath_Delegate VPath, long canvasPtr,
+ int w,
+ int h,
+ long filterPtr) {
+ final float scaleX = w / mViewportWidth;
+ final float scaleY = h / mViewportHeight;
+ final float minScale = Math.min(scaleX, scaleY);
+ final Matrix groupStackedMatrix = VGroup.mStackedMatrix;
+
+ mFinalPathMatrix.set(groupStackedMatrix);
+ mFinalPathMatrix.postScale(scaleX, scaleY);
+
+ final float matrixScale = getMatrixScale(groupStackedMatrix);
+ if (matrixScale == 0) {
+ // When either x or y is scaled to 0, we don't need to draw anything.
+ return;
+ }
+ VPath.toPath(mPath);
+ final Path path = mPath;
+
+ mRenderPath.reset();
+
+ if (VPath.isClipPath()) {
+ mRenderPath.addPath(path, mFinalPathMatrix);
+ Canvas_Delegate.native_clipPath(canvasPtr, mRenderPath.mNativePath, Op
+ .INTERSECT.nativeInt);
+ } else {
+ VFullPath_Delegate fullPath = (VFullPath_Delegate) VPath;
+ if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
+ float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f;
+ float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f;
+
+ if (mPathMeasure == null) {
+ mPathMeasure = new PathMeasure();
+ }
+ mPathMeasure.setPath(mPath, false);
+
+ float len = mPathMeasure.getLength();
+ start = start * len;
+ end = end * len;
+ path.reset();
+ if (start > end) {
+ mPathMeasure.getSegment(start, len, path, true);
+ mPathMeasure.getSegment(0f, end, path, true);
+ } else {
+ mPathMeasure.getSegment(start, end, path, true);
+ }
+ path.rLineTo(0, 0); // fix bug in measure
+ }
+ mRenderPath.addPath(path, mFinalPathMatrix);
+
+ if (fullPath.mFillColor != Color.TRANSPARENT) {
+ if (mFillPaint == null) {
+ mFillPaint = new Paint();
+ mFillPaint.setStyle(Style.FILL);
+ mFillPaint.setAntiAlias(true);
+ }
+
+ final Paint fillPaint = mFillPaint;
+ fillPaint.setColor(applyAlpha(fullPath.mFillColor, fullPath.mFillAlpha));
+ Paint_Delegate fillPaintDelegate = Paint_Delegate.getDelegate(fillPaint
+ .getNativeInstance
+ ());
+ // mFillPaint can not be null at this point so we will have a delegate
+ assert fillPaintDelegate != null;
+ fillPaintDelegate.setColorFilter(filterPtr);
+ Canvas_Delegate.native_drawPath(canvasPtr, mRenderPath.mNativePath, fillPaint
+ .getNativeInstance());
+ }
+
+ if (fullPath.mStrokeColor != Color.TRANSPARENT) {
+ if (mStrokePaint == null) {
+ mStrokePaint = new Paint();
+ mStrokePaint.setStyle(Style.STROKE);
+ mStrokePaint.setAntiAlias(true);
+ }
+
+ final Paint strokePaint = mStrokePaint;
+ if (fullPath.mStrokeLineJoin != null) {
+ strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin);
+ }
+
+ if (fullPath.mStrokeLineCap != null) {
+ strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
+ }
+
+ strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
+ strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, fullPath.mStrokeAlpha));
+ Paint_Delegate strokePaintDelegate = Paint_Delegate.getDelegate(strokePaint
+ .getNativeInstance());
+ // mStrokePaint can not be null at this point so we will have a delegate
+ assert strokePaintDelegate != null;
+ strokePaintDelegate.setColorFilter(filterPtr);
+ final float finalStrokeScale = minScale * matrixScale;
+ strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale);
+ Canvas_Delegate.native_drawPath(canvasPtr, mRenderPath.mNativePath, strokePaint
+ .getNativeInstance());
+ }
+ }
+ }
+
+ private float getMatrixScale(Matrix groupStackedMatrix) {
+ // Given unit vectors A = (0, 1) and B = (1, 0).
+ // After matrix mapping, we got A' and B'. Let theta = the angel b/t A' and B'.
+ // Therefore, the final scale we want is min(|A'| * sin(theta), |B'| * sin(theta)),
+ // which is (|A'| * |B'| * sin(theta)) / max (|A'|, |B'|);
+ // If max (|A'|, |B'|) = 0, that means either x or y has a scale of 0.
+ //
+ // For non-skew case, which is most of the cases, matrix scale is computing exactly the
+ // scale on x and y axis, and take the minimal of these two.
+ // For skew case, an unit square will mapped to a parallelogram. And this function will
+ // return the minimal height of the 2 bases.
+ float[] unitVectors = new float[]{0, 1, 1, 0};
+ groupStackedMatrix.mapVectors(unitVectors);
+ float scaleX = MathUtils.mag(unitVectors[0], unitVectors[1]);
+ float scaleY = MathUtils.mag(unitVectors[2], unitVectors[3]);
+ float crossProduct = MathUtils.cross(unitVectors[0], unitVectors[1],
+ unitVectors[2], unitVectors[3]);
+ float maxScale = MathUtils.max(scaleX, scaleY);
+
+ float matrixScale = 0;
+ if (maxScale > 0) {
+ matrixScale = MathUtils.abs(crossProduct) / maxScale;
+ }
+ if (DBG_VECTOR_DRAWABLE) {
+ Log.d(LOGTAG, "Scale x " + scaleX + " y " + scaleY + " final " + matrixScale);
+ }
+ return matrixScale;
+ }
+
+ @Override
+ public void setName(String name) {
+ }
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
index d3af837..6c34c70 100644
--- a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
@@ -24,7 +24,6 @@
import android.annotation.NonNull;
import android.graphics.Path_Delegate;
-import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
@@ -52,10 +51,18 @@
@NonNull
private PathDataNode[] mPathDataNodes;
+ public static PathParser_Delegate getDelegate(long nativePtr) {
+ return sManager.getDelegate(nativePtr);
+ }
+
private PathParser_Delegate(@NonNull PathDataNode[] nodes) {
mPathDataNodes = nodes;
}
+ public PathDataNode[] getPathDataNodes() {
+ return mPathDataNodes;
+ }
+
@LayoutlibDelegate
/*package*/ static boolean nParseStringForPath(long pathPtr, @NonNull String pathString, int
stringLength) {
@@ -64,7 +71,7 @@
return false;
}
assert pathString.length() == stringLength;
- PathDataNode.nodesToPath(createNodesFromPathData(pathString), path_delegate.getJavaShape());
+ PathDataNode.nodesToPath(createNodesFromPathData(pathString), path_delegate);
return true;
}
@@ -75,7 +82,7 @@
if (source == null || path_delegate == null) {
return;
}
- PathDataNode.nodesToPath(source.mPathDataNodes, path_delegate.getJavaShape());
+ PathDataNode.nodesToPath(source.mPathDataNodes, path_delegate);
}
@LayoutlibDelegate
@@ -124,8 +131,11 @@
out.mPathDataNodes = new PathDataNode[length];
}
for (int i = 0; i < length; i++) {
+ if (out.mPathDataNodes[i] == null) {
+ out.mPathDataNodes[i] = new PathDataNode(from.mPathDataNodes[i]);
+ }
out.mPathDataNodes[i].interpolatePathDataNode(from.mPathDataNodes[i],
- to.mPathDataNodes[i], fraction);
+ to.mPathDataNodes[i], fraction);
}
return true;
}
@@ -137,9 +147,13 @@
@LayoutlibDelegate
/*package*/ static boolean nCanMorph(long fromDataPtr, long toDataPtr) {
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "morphing path data isn't " +
- "supported", null, null);
- return false;
+ PathParser_Delegate fromPath = PathParser_Delegate.getDelegate(fromDataPtr);
+ PathParser_Delegate toPath = PathParser_Delegate.getDelegate(toDataPtr);
+ if (fromPath == null || toPath == null || fromPath.getPathDataNodes() == null || toPath
+ .getPathDataNodes() == null) {
+ return true;
+ }
+ return PathParser_Delegate.canMorph(fromPath.getPathDataNodes(), toPath.getPathDataNodes());
}
@LayoutlibDelegate
@@ -158,7 +172,7 @@
* @return an array of the PathDataNode.
*/
@NonNull
- private static PathDataNode[] createNodesFromPathData(@NonNull String pathData) {
+ public static PathDataNode[] createNodesFromPathData(@NonNull String pathData) {
int start = 0;
int end = 1;
@@ -186,7 +200,7 @@
* @return a deep copy of the <code>source</code>.
*/
@NonNull
- private static PathDataNode[] deepCopyNodes(@NonNull PathDataNode[] source) {
+ public static PathDataNode[] deepCopyNodes(@NonNull PathDataNode[] source) {
PathDataNode[] copy = new PathDataNode[source.length];
for (int i = 0; i < source.length; i++) {
copy[i] = new PathDataNode(source[i]);
@@ -194,6 +208,45 @@
return copy;
}
+ /**
+ * @param nodesFrom The source path represented in an array of PathDataNode
+ * @param nodesTo The target path represented in an array of PathDataNode
+ * @return whether the <code>nodesFrom</code> can morph into <code>nodesTo</code>
+ */
+ public static boolean canMorph(PathDataNode[] nodesFrom, PathDataNode[] nodesTo) {
+ if (nodesFrom == null || nodesTo == null) {
+ return false;
+ }
+
+ if (nodesFrom.length != nodesTo.length) {
+ return false;
+ }
+
+ for (int i = 0; i < nodesFrom.length; i ++) {
+ if (nodesFrom[i].mType != nodesTo[i].mType
+ || nodesFrom[i].mParams.length != nodesTo[i].mParams.length) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Update the target's data to match the source.
+ * Before calling this, make sure canMorph(target, source) is true.
+ *
+ * @param target The target path represented in an array of PathDataNode
+ * @param source The source path represented in an array of PathDataNode
+ */
+ public static void updateNodes(PathDataNode[] target, PathDataNode[] source) {
+ for (int i = 0; i < source.length; i ++) {
+ target[i].mType = source[i].mType;
+ for (int j = 0; j < source[i].mParams.length; j ++) {
+ target[i].mParams[j] = source[i].mParams[j];
+ }
+ }
+ }
+
private static int nextStart(@NonNull String s, int end) {
char c;
@@ -330,7 +383,7 @@
* Each PathDataNode represents one command in the "d" attribute of the svg file. An array of
* PathDataNode can represent the whole "d" attribute.
*/
- private static class PathDataNode {
+ public static class PathDataNode {
private char mType;
@NonNull
private float[] mParams;
@@ -355,12 +408,13 @@
}
/**
- * Convert an array of PathDataNode to Path.
+ * Convert an array of PathDataNode to Path. Reset the passed path as needed before
+ * calling this method.
*
* @param node The source array of PathDataNode.
* @param path The target Path object.
*/
- private static void nodesToPath(@NonNull PathDataNode[] node, @NonNull Path2D path) {
+ public static void nodesToPath(@NonNull PathDataNode[] node, @NonNull Path_Delegate path) {
float[] current = new float[6];
char previousCommand = 'm';
//noinspection ForLoopReplaceableByForEach
@@ -387,24 +441,32 @@
}
@SuppressWarnings("PointlessArithmeticExpression")
- private static void addCommand(@NonNull Path2D path, float[] current, char cmd,
- char lastCmd, @NonNull float[] val) {
+ private static void addCommand(@NonNull Path_Delegate path, float[] current,
+ char previousCmd, char cmd, @NonNull float[] val) {
int incr = 2;
-
- float cx = current[0];
- float cy = current[1];
- float cpx = current[2];
- float cpy = current[3];
- float loopX = current[4];
- float loopY = current[5];
+ float currentX = current[0];
+ float currentY = current[1];
+ float ctrlPointX = current[2];
+ float ctrlPointY = current[3];
+ float currentSegmentStartX = current[4];
+ float currentSegmentStartY = current[5];
+ float reflectiveCtrlPointX;
+ float reflectiveCtrlPointY;
switch (cmd) {
case 'z':
case 'Z':
- path.closePath();
- cx = loopX;
- cy = loopY;
+ path.close();
+ // Path is closed here, but we need to move the pen to the
+ // closed position. So we cache the segment's starting position,
+ // and restore it here.
+ currentX = currentSegmentStartX;
+ currentY = currentSegmentStartY;
+ ctrlPointX = currentSegmentStartX;
+ ctrlPointY = currentSegmentStartY;
+ path.moveTo(currentX, currentY);
+ break;
case 'm':
case 'M':
case 'l':
@@ -432,185 +494,206 @@
case 'a':
case 'A':
incr = 7;
+ break;
}
for (int k = 0; k < val.length; k += incr) {
- boolean reflectCtrl;
- float tempReflectedX, tempReflectedY;
-
switch (cmd) {
- case 'm':
- cx += val[k + 0];
- cy += val[k + 1];
+ case 'm': // moveto - Start a new sub-path (relative)
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+
if (k > 0) {
// According to the spec, if a moveto is followed by multiple
// pairs of coordinates, the subsequent pairs are treated as
// implicit lineto commands.
- path.lineTo(cx, cy);
+ path.rLineTo(val[k + 0], val[k + 1]);
} else {
- path.moveTo(cx, cy);
- loopX = cx;
- loopY = cy;
+ path.rMoveTo(val[k + 0], val[k + 1]);
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
}
break;
- case 'M':
- cx = val[k + 0];
- cy = val[k + 1];
+ case 'M': // moveto - Start a new sub-path
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+
if (k > 0) {
// According to the spec, if a moveto is followed by multiple
// pairs of coordinates, the subsequent pairs are treated as
// implicit lineto commands.
- path.lineTo(cx, cy);
+ path.lineTo(val[k + 0], val[k + 1]);
} else {
- path.moveTo(cx, cy);
- loopX = cx;
- loopY = cy;
+ path.moveTo(val[k + 0], val[k + 1]);
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
}
break;
- case 'l':
- cx += val[k + 0];
- cy += val[k + 1];
- path.lineTo(cx, cy);
+ case 'l': // lineto - Draw a line from the current point (relative)
+ path.rLineTo(val[k + 0], val[k + 1]);
+ currentX += val[k + 0];
+ currentY += val[k + 1];
break;
- case 'L':
- cx = val[k + 0];
- cy = val[k + 1];
- path.lineTo(cx, cy);
+ case 'L': // lineto - Draw a line from the current point
+ path.lineTo(val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1];
break;
- case 'z':
- case 'Z':
- path.closePath();
- cx = loopX;
- cy = loopY;
+ case 'h': // horizontal lineto - Draws a horizontal line (relative)
+ path.rLineTo(val[k + 0], 0);
+ currentX += val[k + 0];
break;
- case 'h':
- cx += val[k + 0];
- path.lineTo(cx, cy);
+ case 'H': // horizontal lineto - Draws a horizontal line
+ path.lineTo(val[k + 0], currentY);
+ currentX = val[k + 0];
break;
- case 'H':
- path.lineTo(val[k + 0], cy);
- cx = val[k + 0];
+ case 'v': // vertical lineto - Draws a vertical line from the current point (r)
+ path.rLineTo(0, val[k + 0]);
+ currentY += val[k + 0];
break;
- case 'v':
- cy += val[k + 0];
- path.lineTo(cx, cy);
+ case 'V': // vertical lineto - Draws a vertical line from the current point
+ path.lineTo(currentX, val[k + 0]);
+ currentY = val[k + 0];
break;
- case 'V':
- path.lineTo(cx, val[k + 0]);
- cy = val[k + 0];
- break;
- case 'c':
- path.curveTo(cx + val[k + 0], cy + val[k + 1], cx + val[k + 2],
- cy + val[k + 3], cx + val[k + 4], cy + val[k + 5]);
- cpx = cx + val[k + 2];
- cpy = cy + val[k + 3];
- cx += val[k + 4];
- cy += val[k + 5];
- break;
- case 'C':
- path.curveTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
+ case 'c': // curveto - Draws a cubic Bézier curve (relative)
+ path.rCubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
val[k + 4], val[k + 5]);
- cx = val[k + 4];
- cy = val[k + 5];
- cpx = val[k + 2];
- cpy = val[k + 3];
- break;
- case 's':
- reflectCtrl = (lastCmd == 'c' || lastCmd == 's' || lastCmd == 'C' ||
- lastCmd == 'S');
- path.curveTo(reflectCtrl ? 2 * cx - cpx : cx, reflectCtrl ? 2
- * cy - cpy : cy, cx + val[k + 0], cy + val[k + 1], cx
- + val[k + 2], cy + val[k + 3]);
- cpx = cx + val[k + 0];
- cpy = cy + val[k + 1];
- cx += val[k + 2];
- cy += val[k + 3];
+ ctrlPointX = currentX + val[k + 2];
+ ctrlPointY = currentY + val[k + 3];
+ currentX += val[k + 4];
+ currentY += val[k + 5];
+
break;
- case 'S':
- reflectCtrl = (lastCmd == 'c' || lastCmd == 's' || lastCmd == 'C' ||
- lastCmd == 'S');
- path.curveTo(reflectCtrl ? 2 * cx - cpx : cx, reflectCtrl ? 2
- * cy - cpy : cy, val[k + 0], val[k + 1], val[k + 2],
- val[k + 3]);
- cpx = (val[k + 0]);
- cpy = (val[k + 1]);
- cx = val[k + 2];
- cy = val[k + 3];
+ case 'C': // curveto - Draws a cubic Bézier curve
+ path.cubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
+ val[k + 4], val[k + 5]);
+ currentX = val[k + 4];
+ currentY = val[k + 5];
+ ctrlPointX = val[k + 2];
+ ctrlPointY = val[k + 3];
break;
- case 'q':
- path.quadTo(cx + val[k + 0], cy + val[k + 1], cx + val[k + 2],
- cy + val[k + 3]);
- cpx = cx + val[k + 0];
- cpy = cy + val[k + 1];
- // Note that we have to update cpx first, since cx will be updated here.
- cx += val[k + 2];
- cy += val[k + 3];
+ case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
+ reflectiveCtrlPointX = 0;
+ reflectiveCtrlPointY = 0;
+ if (previousCmd == 'c' || previousCmd == 's'
+ || previousCmd == 'C' || previousCmd == 'S') {
+ reflectiveCtrlPointX = currentX - ctrlPointX;
+ reflectiveCtrlPointY = currentY - ctrlPointY;
+ }
+ path.rCubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1],
+ val[k + 2], val[k + 3]);
+
+ ctrlPointX = currentX + val[k + 0];
+ ctrlPointY = currentY + val[k + 1];
+ currentX += val[k + 2];
+ currentY += val[k + 3];
break;
- case 'Q':
+ case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
+ reflectiveCtrlPointX = currentX;
+ reflectiveCtrlPointY = currentY;
+ if (previousCmd == 'c' || previousCmd == 's'
+ || previousCmd == 'C' || previousCmd == 'S') {
+ reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+ reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+ }
+ path.cubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ currentX = val[k + 2];
+ currentY = val[k + 3];
+ break;
+ case 'q': // Draws a quadratic Bézier (relative)
+ path.rQuadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ ctrlPointX = currentX + val[k + 0];
+ ctrlPointY = currentY + val[k + 1];
+ currentX += val[k + 2];
+ currentY += val[k + 3];
+ break;
+ case 'Q': // Draws a quadratic Bézier
path.quadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
- cx = val[k + 2];
- cy = val[k + 3];
- cpx = val[k + 0];
- cpy = val[k + 1];
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ currentX = val[k + 2];
+ currentY = val[k + 3];
break;
- case 't':
- reflectCtrl = (lastCmd == 'q' || lastCmd == 't' || lastCmd == 'Q' ||
- lastCmd == 'T');
- tempReflectedX = reflectCtrl ? 2 * cx - cpx : cx;
- tempReflectedY = reflectCtrl ? 2 * cy - cpy : cy;
- path.quadTo(tempReflectedX, tempReflectedY, cx + val[k + 0],
- cy + val[k + 1]);
- cpx = tempReflectedX;
- cpy = tempReflectedY;
- cx += val[k + 0];
- cy += val[k + 1];
+ case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
+ reflectiveCtrlPointX = 0;
+ reflectiveCtrlPointY = 0;
+ if (previousCmd == 'q' || previousCmd == 't'
+ || previousCmd == 'Q' || previousCmd == 'T') {
+ reflectiveCtrlPointX = currentX - ctrlPointX;
+ reflectiveCtrlPointY = currentY - ctrlPointY;
+ }
+ path.rQuadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1]);
+ ctrlPointX = currentX + reflectiveCtrlPointX;
+ ctrlPointY = currentY + reflectiveCtrlPointY;
+ currentX += val[k + 0];
+ currentY += val[k + 1];
break;
- case 'T':
- reflectCtrl = (lastCmd == 'q' || lastCmd == 't' || lastCmd == 'Q' ||
- lastCmd == 'T');
- tempReflectedX = reflectCtrl ? 2 * cx - cpx : cx;
- tempReflectedY = reflectCtrl ? 2 * cy - cpy : cy;
- path.quadTo(tempReflectedX, tempReflectedY, val[k + 0], val[k + 1]);
- cx = val[k + 0];
- cy = val[k + 1];
- cpx = tempReflectedX;
- cpy = tempReflectedY;
+ case 'T': // Draws a quadratic Bézier curve (reflective control point)
+ reflectiveCtrlPointX = currentX;
+ reflectiveCtrlPointY = currentY;
+ if (previousCmd == 'q' || previousCmd == 't'
+ || previousCmd == 'Q' || previousCmd == 'T') {
+ reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+ reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+ }
+ path.quadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
+ val[k + 0], val[k + 1]);
+ ctrlPointX = reflectiveCtrlPointX;
+ ctrlPointY = reflectiveCtrlPointY;
+ currentX = val[k + 0];
+ currentY = val[k + 1];
break;
- case 'a':
+ case 'a': // Draws an elliptical arc
// (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
- drawArc(path, cx, cy, val[k + 5] + cx, val[k + 6] + cy,
- val[k + 0], val[k + 1], val[k + 2], val[k + 3] != 0,
+ drawArc(path,
+ currentX,
+ currentY,
+ val[k + 5] + currentX,
+ val[k + 6] + currentY,
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
val[k + 4] != 0);
- cx += val[k + 5];
- cy += val[k + 6];
- cpx = cx;
- cpy = cy;
-
+ currentX += val[k + 5];
+ currentY += val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
break;
- case 'A':
- drawArc(path, cx, cy, val[k + 5], val[k + 6], val[k + 0],
- val[k + 1], val[k + 2], val[k + 3] != 0,
+ case 'A': // Draws an elliptical arc
+ drawArc(path,
+ currentX,
+ currentY,
+ val[k + 5],
+ val[k + 6],
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
val[k + 4] != 0);
- cx = val[k + 5];
- cy = val[k + 6];
- cpx = cx;
- cpy = cy;
+ currentX = val[k + 5];
+ currentY = val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
break;
-
}
- lastCmd = cmd;
+ previousCmd = cmd;
}
- current[0] = cx;
- current[1] = cy;
- current[2] = cpx;
- current[3] = cpy;
- current[4] = loopX;
- current[5] = loopY;
-
+ current[0] = currentX;
+ current[1] = currentY;
+ current[2] = ctrlPointX;
+ current[3] = ctrlPointY;
+ current[4] = currentSegmentStartX;
+ current[5] = currentSegmentStartY;
}
- private static void drawArc(@NonNull Path2D p, float x0, float y0, float x1,
+ private static void drawArc(@NonNull Path_Delegate p, float x0, float y0, float x1,
float y1, float a, float b, float theta, boolean isMoreThanHalf,
boolean isPositiveArc) {
@@ -707,7 +790,7 @@
* @param start The start angle of the arc on the ellipse
* @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
*/
- private static void arcToBezier(@NonNull Path2D p, double cx, double cy, double a,
+ private static void arcToBezier(@NonNull Path_Delegate p, double cx, double cy, double a,
double b, double e1x, double e1y, double theta, double start,
double sweep) {
// Taken from equations at:
@@ -744,8 +827,12 @@
double q2x = e2x - alpha * ep2x;
double q2y = e2y - alpha * ep2y;
- p.curveTo((float) q1x, (float) q1y, (float) q2x, (float) q2y,
- (float) e2x, (float) e2y);
+ p.cubicTo((float) q1x,
+ (float) q1y,
+ (float) q2x,
+ (float) q2y,
+ (float) e2x,
+ (float) e2y);
eta1 = eta2;
e1x = e2x;
e1y = e2y;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index 85e2610..4039cdf 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -484,6 +484,12 @@
}
@Override
+ public Drawable getManagedUserBadgedDrawable(Drawable drawable, Rect badgeLocation,
+ int badgeDensity) {
+ return null;
+ }
+
+ @Override
public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
return null;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 99af226..53f1912 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -60,6 +60,7 @@
import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
import android.graphics.Canvas;
+import android.os.Looper;
import android.preference.Preference_Delegate;
import android.view.AttachInfo_Accessor;
import android.view.BridgeInflater;
@@ -1398,6 +1399,14 @@
}
public void dispose() {
+ boolean createdLooper = false;
+ if (Looper.myLooper() == null) {
+ // Detaching the root view from the window will try to stop any running animations.
+ // The stop method checks that it can run in the looper so, if there is no current
+ // looper, we create a temporary one to complete the shutdown.
+ Bridge.prepareThread();
+ createdLooper = true;
+ }
AttachInfo_Accessor.detachFromWindow(mViewRoot);
if (mCanvas != null) {
mCanvas.release();
@@ -1412,5 +1421,9 @@
mImage = null;
mViewRoot = null;
mContentRoot = null;
+
+ if (createdLooper) {
+ Bridge.cleanupThread();
+ }
}
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 8a23e4b..8c3bd2f 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -269,6 +269,7 @@
"android.graphics.SweepGradient",
"android.graphics.Typeface",
"android.graphics.Xfermode",
+ "android.graphics.drawable.VectorDrawable",
"android.os.SystemClock",
"android.os.SystemProperties",
"android.text.AndroidBidi",
@@ -321,7 +322,12 @@
"org.kxml2.io.KXmlParser"
};
+ /**
+ * List of fields for which we will update the visibility to be public. This is sometimes
+ * needed when access from the delegate classes is needed.
+ */
private final static String[] PROMOTED_FIELDS = new String[] {
+ "android.graphics.drawable.VectorDrawable#mVectorState",
"android.view.Choreographer#mLastFrameTimeNanos"
};
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e2dd111..a5bfd3c 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -889,24 +889,6 @@
}
/**
- * Sets whether or not the given network is metered from a network policy
- * point of view. A network should be classified as metered when the user is
- * sensitive to heavy data usage on that connection due to monetary costs,
- * data limitations or battery/performance issues. A typical example would
- * be a wifi connection where the user was being charged for usage.
- * @param netId the integer that identifies the network configuration
- * to the supplicant.
- * @param isMetered True to mark the network as metered.
- * @return {@code true} if the operation succeeded.
- * @hide
- */
- @SystemApi
- public boolean setMetered(int netId, boolean isMetered) {
- // TODO(jjoslin): Implement
- return false;
- }
-
- /**
* Remove the specified network from the list of configured networks.
* This may result in the asynchronous delivery of state change
* events.